Subversion Repositories Kolibri OS

Rev

Rev 8869 | Rev 9432 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 8869 Rev 9034
1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                              ;;
2
;;                                                              ;;
3
;; Copyright (C) KolibriOS team 2004-2020. All rights reserved. ;;
3
;; Copyright (C) KolibriOS team 2004-2020. All rights reserved. ;;
4
;;  Distributed under terms of the GNU General Public License.  ;;
4
;;  Distributed under terms of the GNU General Public License.  ;;
5
;;                                                              ;;
5
;;                                                              ;;
6
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
6
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
7
 
7
 
8
$Revision: 8869 $
8
$Revision: 9034 $
9
 
9
 
10
 
10
 
11
DRV_COMPAT   =  5  ;minimal required drivers version
11
DRV_COMPAT   =  5  ;minimal required drivers version
12
DRV_CURRENT  =  6  ;current drivers model version
12
DRV_CURRENT  =  6  ;current drivers model version
13
 
13
 
14
DRV_VERSION = (DRV_COMPAT shl 16) or DRV_CURRENT
14
DRV_VERSION = (DRV_COMPAT shl 16) or DRV_CURRENT
15
PID_KERNEL  = 1    ;os_idle thread
15
PID_KERNEL  = 1    ;os_idle thread
16
 
16
 
17
 
17
 
18
 
18
 
19
align 4
19
align 4
20
proc get_notify stdcall, p_ev:dword
20
proc get_notify stdcall, p_ev:dword
21
 
21
 
22
.wait:
22
.wait:
23
        mov     ebx, [current_slot]
23
        mov     ebx, [current_slot]
24
        test    dword [ebx+APPDATA.event_mask], EVENT_NOTIFY
24
        test    dword [ebx+APPDATA.event_mask], EVENT_NOTIFY
25
        jz      @f
25
        jz      @f
26
        and     dword [ebx+APPDATA.event_mask], not EVENT_NOTIFY
26
        and     dword [ebx+APPDATA.event_mask], not EVENT_NOTIFY
27
        mov     edi, [p_ev]
27
        mov     edi, [p_ev]
28
        mov     dword [edi], EV_INTR
28
        mov     dword [edi], EV_INTR
29
        mov     eax, [ebx+APPDATA.event]
29
        mov     eax, [ebx+APPDATA.event]
30
        mov     dword [edi+4], eax
30
        mov     dword [edi+4], eax
31
        ret
31
        ret
32
@@:
32
@@:
33
        call    change_task
33
        call    change_task
34
        jmp     .wait
34
        jmp     .wait
35
endp
35
endp
36
 
36
 
37
align 4
37
align 4
38
proc pci_read32 stdcall, bus:dword, devfn:dword, reg:dword
38
proc pci_read32 stdcall, bus:dword, devfn:dword, reg:dword
39
        push    ebx
39
        push    ebx
40
        xor     eax, eax
40
        xor     eax, eax
41
        xor     ebx, ebx
41
        xor     ebx, ebx
42
        mov     ah, byte [bus]
42
        mov     ah, byte [bus]
43
        mov     al, 6
43
        mov     al, 6
44
        mov     bh, byte [devfn]
44
        mov     bh, byte [devfn]
45
        mov     bl, byte [reg]
45
        mov     bl, byte [reg]
46
        call    pci_read_reg
46
        call    pci_read_reg
47
        pop     ebx
47
        pop     ebx
48
        ret
48
        ret
49
endp
49
endp
50
 
50
 
51
align 4
51
align 4
52
proc pci_read16 stdcall, bus:dword, devfn:dword, reg:dword
52
proc pci_read16 stdcall, bus:dword, devfn:dword, reg:dword
53
        push    ebx
53
        push    ebx
54
        xor     eax, eax
54
        xor     eax, eax
55
        xor     ebx, ebx
55
        xor     ebx, ebx
56
        mov     ah, byte [bus]
56
        mov     ah, byte [bus]
57
        mov     al, 5
57
        mov     al, 5
58
        mov     bh, byte [devfn]
58
        mov     bh, byte [devfn]
59
        mov     bl, byte [reg]
59
        mov     bl, byte [reg]
60
        call    pci_read_reg
60
        call    pci_read_reg
61
        pop     ebx
61
        pop     ebx
62
        ret
62
        ret
63
endp
63
endp
64
 
64
 
65
align 4
65
align 4
66
proc pci_read8 stdcall, bus:dword, devfn:dword, reg:dword
66
proc pci_read8 stdcall, bus:dword, devfn:dword, reg:dword
67
        push    ebx
67
        push    ebx
68
        xor     eax, eax
68
        xor     eax, eax
69
        xor     ebx, ebx
69
        xor     ebx, ebx
70
        mov     ah, byte [bus]
70
        mov     ah, byte [bus]
71
        mov     al, 4
71
        mov     al, 4
72
        mov     bh, byte [devfn]
72
        mov     bh, byte [devfn]
73
        mov     bl, byte [reg]
73
        mov     bl, byte [reg]
74
        call    pci_read_reg
74
        call    pci_read_reg
75
        pop     ebx
75
        pop     ebx
76
        ret
76
        ret
77
endp
77
endp
78
 
78
 
79
align 4
79
align 4
80
proc pci_write8 stdcall, bus:dword, devfn:dword, reg:dword, val:dword
80
proc pci_write8 stdcall, bus:dword, devfn:dword, reg:dword, val:dword
81
        push    ebx
81
        push    ebx
82
        xor     eax, eax
82
        xor     eax, eax
83
        xor     ebx, ebx
83
        xor     ebx, ebx
84
        mov     ah, byte [bus]
84
        mov     ah, byte [bus]
85
        mov     al, 8
85
        mov     al, 8
86
        mov     bh, byte [devfn]
86
        mov     bh, byte [devfn]
87
        mov     bl, byte [reg]
87
        mov     bl, byte [reg]
88
        mov     ecx, [val]
88
        mov     ecx, [val]
89
        call    pci_write_reg
89
        call    pci_write_reg
90
        pop     ebx
90
        pop     ebx
91
        ret
91
        ret
92
endp
92
endp
93
 
93
 
94
align 4
94
align 4
95
proc pci_write16 stdcall, bus:dword, devfn:dword, reg:dword, val:dword
95
proc pci_write16 stdcall, bus:dword, devfn:dword, reg:dword, val:dword
96
        push    ebx
96
        push    ebx
97
        xor     eax, eax
97
        xor     eax, eax
98
        xor     ebx, ebx
98
        xor     ebx, ebx
99
        mov     ah, byte [bus]
99
        mov     ah, byte [bus]
100
        mov     al, 9
100
        mov     al, 9
101
        mov     bh, byte [devfn]
101
        mov     bh, byte [devfn]
102
        mov     bl, byte [reg]
102
        mov     bl, byte [reg]
103
        mov     ecx, [val]
103
        mov     ecx, [val]
104
        call    pci_write_reg
104
        call    pci_write_reg
105
        pop     ebx
105
        pop     ebx
106
        ret
106
        ret
107
endp
107
endp
108
 
108
 
109
align 4
109
align 4
110
proc pci_write32 stdcall, bus:dword, devfn:dword, reg:dword, val:dword
110
proc pci_write32 stdcall, bus:dword, devfn:dword, reg:dword, val:dword
111
        push    ebx
111
        push    ebx
112
        xor     eax, eax
112
        xor     eax, eax
113
        xor     ebx, ebx
113
        xor     ebx, ebx
114
        mov     ah, byte [bus]
114
        mov     ah, byte [bus]
115
        mov     al, 10
115
        mov     al, 10
116
        mov     bh, byte [devfn]
116
        mov     bh, byte [devfn]
117
        mov     bl, byte [reg]
117
        mov     bl, byte [reg]
118
        mov     ecx, [val]
118
        mov     ecx, [val]
119
        call    pci_write_reg
119
        call    pci_write_reg
120
        pop     ebx
120
        pop     ebx
121
        ret
121
        ret
122
endp
122
endp
123
 
123
 
124
handle     equ  IOCTL.handle
124
handle     equ  IOCTL.handle
125
io_code    equ  IOCTL.io_code
125
io_code    equ  IOCTL.io_code
126
input      equ  IOCTL.input
126
input      equ  IOCTL.input
127
inp_size   equ  IOCTL.inp_size
127
inp_size   equ  IOCTL.inp_size
128
output     equ  IOCTL.output
128
output     equ  IOCTL.output
129
out_size   equ  IOCTL.out_size
129
out_size   equ  IOCTL.out_size
130
 
130
 
131
 
131
 
132
align 4
132
align 4
133
proc srv_handler stdcall, ioctl:dword
133
proc srv_handler stdcall, ioctl:dword
134
        mov     esi, [ioctl]
134
        mov     esi, [ioctl]
135
        test    esi, esi
135
        test    esi, esi
136
        jz      .err
136
        jz      .err
137
 
137
 
138
        mov     edi, [esi+handle]
138
        mov     edi, [esi+handle]
139
        cmp     [edi+SRV.magic], ' SRV'
139
        cmp     [edi+SRV.magic], ' SRV'
140
        jne     .fail
140
        jne     .fail
141
 
141
 
142
        cmp     [edi+SRV.size], sizeof.SRV
142
        cmp     [edi+SRV.size], sizeof.SRV
143
        jne     .fail
143
        jne     .fail
144
 
144
 
145
;        stdcall [edi+SRV.srv_proc], esi
145
;        stdcall [edi+SRV.srv_proc], esi
146
        mov     eax, [edi+SRV.srv_proc]
146
        mov     eax, [edi+SRV.srv_proc]
147
        test    eax, eax
147
        test    eax, eax
148
        jz      .fail
148
        jz      .fail
149
        stdcall eax, esi
149
        stdcall eax, esi
150
        ret
150
        ret
151
.fail:
151
.fail:
152
        xor     eax, eax
152
        xor     eax, eax
153
        not     eax
153
        not     eax
154
        mov     [esi+output], eax
154
        mov     [esi+output], eax
155
        mov     [esi+out_size], 4
155
        mov     [esi+out_size], 4
156
        ret
156
        ret
157
.err:
157
.err:
158
        xor     eax, eax
158
        xor     eax, eax
159
        not     eax
159
        not     eax
160
        ret
160
        ret
161
endp
161
endp
162
 
162
 
163
; param
163
; param
164
;  ecx= io_control
164
;  ecx= io_control
165
;
165
;
166
; retval
166
; retval
167
;  eax= error code
167
;  eax= error code
168
 
168
 
169
align 4
169
align 4
170
srv_handlerEx:
170
srv_handlerEx:
171
        cmp     ecx, OS_BASE
171
        cmp     ecx, OS_BASE
172
        jae     .fail
172
        jae     .fail
173
 
173
 
174
        mov     eax, [ecx+handle]
174
        mov     eax, [ecx+handle]
175
        cmp     [eax+SRV.magic], ' SRV'
175
        cmp     [eax+SRV.magic], ' SRV'
176
        jne     .fail
176
        jne     .fail
177
 
177
 
178
        cmp     [eax+SRV.size], sizeof.SRV
178
        cmp     [eax+SRV.size], sizeof.SRV
179
        jne     .fail
179
        jne     .fail
180
 
180
 
181
;        stdcall [eax+SRV.srv_proc], ecx
181
;        stdcall [eax+SRV.srv_proc], ecx
182
        mov     eax, [eax+SRV.srv_proc]
182
        mov     eax, [eax+SRV.srv_proc]
183
        test    eax, eax
183
        test    eax, eax
184
        jz      .fail
184
        jz      .fail
185
        stdcall eax, ecx
185
        stdcall eax, ecx
186
        ret
186
        ret
187
.fail:
187
.fail:
188
        or      eax, -1
188
        or      eax, -1
189
        ret
189
        ret
190
 
190
 
191
restore  handle
191
restore  handle
192
restore  io_code
192
restore  io_code
193
restore  input
193
restore  input
194
restore  inp_size
194
restore  inp_size
195
restore  output
195
restore  output
196
restore  out_size
196
restore  out_size
197
 
197
 
198
align 4
198
align 4
199
proc get_service stdcall, sz_name:dword
199
proc get_service stdcall, sz_name:dword
200
        mov     eax, [sz_name]
200
        mov     eax, [sz_name]
201
        test    eax, eax
201
        test    eax, eax
202
        jnz     @F
202
        jnz     @F
203
        ret
203
        ret
204
@@:
204
@@:
205
        mov     edx, [srv.fd]
205
        mov     edx, [srv.fd]
206
@@:
206
@@:
207
        cmp     edx, srv.fd-SRV.fd
207
        cmp     edx, srv.fd-SRV.fd
208
        je      .not_load
208
        je      .not_load
209
 
209
 
210
        stdcall strncmp, edx, [sz_name], 16
210
        stdcall strncmp, edx, [sz_name], 16
211
        test    eax, eax
211
        test    eax, eax
212
        mov     eax, edx
212
        mov     eax, edx
213
        je      .nothing
213
        je      .nothing
214
 
214
 
215
        mov     edx, [edx+SRV.fd]
215
        mov     edx, [edx+SRV.fd]
216
        jmp     @B
216
        jmp     @B
217
.not_load:
217
.not_load:
218
        mov     eax, [sz_name]
218
        mov     eax, [sz_name]
219
        push    edi
219
        push    edi
220
        sub     esp, 36
220
        sub     esp, 36
221
        mov     edi, esp
221
        mov     edi, esp
222
        mov     dword [edi], '/sys'
222
        mov     dword [edi], '/sys'
223
        mov     dword [edi+4], '/dri'
223
        mov     dword [edi+4], '/dri'
224
        mov     dword [edi+8], 'vers'
224
        mov     dword [edi+8], 'vers'
225
        mov     byte [edi+12], '/'
225
        mov     byte [edi+12], '/'
226
@@:
226
@@:
227
        mov     dl, [eax]
227
        mov     dl, [eax]
228
        mov     [edi+13], dl
228
        mov     [edi+13], dl
229
        inc     eax
229
        inc     eax
230
        inc     edi
230
        inc     edi
231
        test    dl, dl
231
        test    dl, dl
232
        jnz     @b
232
        jnz     @b
233
        mov     dword [edi+12], '.sys'
233
        mov     dword [edi+12], '.sys'
234
        mov     byte [edi+16], 0
234
        mov     byte [edi+16], 0
235
        mov     edi, esp
235
        mov     edi, esp
236
        stdcall load_pe_driver, edi, 0
236
        stdcall load_pe_driver, edi, 0
237
        add     esp, 36
237
        add     esp, 36
238
        pop     edi
238
        pop     edi
239
.nothing:
239
.nothing:
240
        ret
240
        ret
241
endp
241
endp
242
 
242
 
243
reg_service:
243
reg_service:
244
        xor     eax, eax
244
        xor     eax, eax
245
        mov     ecx, [esp+8]
245
        mov     ecx, [esp+8]
246
        jecxz   .nothing
246
        jecxz   .nothing
247
        push    sizeof.SRV
247
        push    sizeof.SRV
248
        push    ecx
248
        push    ecx
249
        pushd   [esp+12]
249
        pushd   [esp+12]
250
        call    reg_service_ex
250
        call    reg_service_ex
251
.nothing:
251
.nothing:
252
        ret     8
252
        ret     8
253
 
253
 
254
reg_usb_driver:
254
reg_usb_driver:
255
        push    sizeof.USBSRV
255
        push    sizeof.USBSRV
256
        pushd   [esp+12]
256
        pushd   [esp+12]
257
        pushd   [esp+12]
257
        pushd   [esp+12]
258
        call    reg_service_ex
258
        call    reg_service_ex
259
        test    eax, eax
259
        test    eax, eax
260
        jz      .nothing
260
        jz      .nothing
261
        mov     ecx, [esp+12]
261
        mov     ecx, [esp+12]
262
        mov     [eax+USBSRV.usb_func], ecx
262
        mov     [eax+USBSRV.usb_func], ecx
263
.nothing:
263
.nothing:
264
        ret     12
264
        ret     12
265
 
265
 
266
proc reg_service_ex stdcall, name:dword, handler:dword, srvsize:dword
266
proc reg_service_ex stdcall, name:dword, handler:dword, srvsize:dword
267
 
267
 
268
        push    ebx
268
        push    ebx
269
 
269
 
270
        xor     eax, eax
270
        xor     eax, eax
271
 
271
 
272
        cmp     [name], eax
272
        cmp     [name], eax
273
        je      .fail
273
        je      .fail
274
 
274
 
275
;        cmp     [handler], eax
275
;        cmp     [handler], eax
276
;        je      .fail
276
;        je      .fail
277
 
277
 
278
        mov     eax, [srvsize]
278
        mov     eax, [srvsize]
279
        call    malloc
279
        call    malloc
280
        test    eax, eax
280
        test    eax, eax
281
        jz      .fail
281
        jz      .fail
282
 
282
 
283
        push    esi
283
        push    esi
284
        push    edi
284
        push    edi
285
        mov     edi, eax
285
        mov     edi, eax
286
        mov     esi, [name]
286
        mov     esi, [name]
287
        movsd
287
        movsd
288
        movsd
288
        movsd
289
        movsd
289
        movsd
290
        movsd
290
        movsd
291
        pop     edi
291
        pop     edi
292
        pop     esi
292
        pop     esi
293
 
293
 
294
        mov     [eax+SRV.magic], ' SRV'
294
        mov     [eax+SRV.magic], ' SRV'
295
        mov     [eax+SRV.size], sizeof.SRV
295
        mov     [eax+SRV.size], sizeof.SRV
296
 
296
 
297
        mov     ebx, srv.fd-SRV.fd
297
        mov     ebx, srv.fd-SRV.fd
298
        mov     edx, [ebx+SRV.fd]
298
        mov     edx, [ebx+SRV.fd]
299
        mov     [eax+SRV.fd], edx
299
        mov     [eax+SRV.fd], edx
300
        mov     [eax+SRV.bk], ebx
300
        mov     [eax+SRV.bk], ebx
301
        mov     [ebx+SRV.fd], eax
301
        mov     [ebx+SRV.fd], eax
302
        mov     [edx+SRV.bk], eax
302
        mov     [edx+SRV.bk], eax
303
 
303
 
304
        mov     ecx, [handler]
304
        mov     ecx, [handler]
305
        mov     [eax+SRV.srv_proc], ecx
305
        mov     [eax+SRV.srv_proc], ecx
306
        pop     ebx
306
        pop     ebx
307
        ret
307
        ret
308
.fail:
308
.fail:
309
        xor     eax, eax
309
        xor     eax, eax
310
        pop     ebx
310
        pop     ebx
311
        ret
311
        ret
312
endp
312
endp
313
 
313
 
314
align 4
314
align 4
315
proc get_proc stdcall, exp:dword, sz_name:dword
315
proc get_proc stdcall, exp:dword, sz_name:dword
316
 
316
 
317
        mov     edx, [exp]
317
        mov     edx, [exp]
318
.next:
318
.next:
319
        mov     eax, [edx]
319
        mov     eax, [edx]
320
        test    eax, eax
320
        test    eax, eax
321
        jz      .end
321
        jz      .end
322
 
322
 
323
        push    edx
323
        push    edx
324
        stdcall strncmp, eax, [sz_name], 16
324
        stdcall strncmp, eax, [sz_name], 16
325
        pop     edx
325
        pop     edx
326
        test    eax, eax
326
        test    eax, eax
327
        jz      .ok
327
        jz      .ok
328
 
328
 
329
        add     edx, 8
329
        add     edx, 8
330
        jmp     .next
330
        jmp     .next
331
.ok:
331
.ok:
332
        mov     eax, [edx+4]
332
        mov     eax, [edx+4]
333
.end:
333
.end:
334
        ret
334
        ret
335
endp
335
endp
336
 
336
 
337
align 4
337
align 4
338
proc get_coff_sym stdcall, pSym:dword,count:dword, sz_sym:dword
338
proc get_coff_sym stdcall, pSym:dword,count:dword, sz_sym:dword
339
 
339
 
340
@@:
340
@@:
341
        stdcall strncmp, [pSym], [sz_sym], 8
341
        stdcall strncmp, [pSym], [sz_sym], 8
342
        test    eax, eax
342
        test    eax, eax
343
        jz      .ok
343
        jz      .ok
344
        add     [pSym], 18
344
        add     [pSym], 18
345
        dec     [count]
345
        dec     [count]
346
        jnz     @b
346
        jnz     @b
347
        xor     eax, eax
347
        xor     eax, eax
348
        ret
348
        ret
349
.ok:
349
.ok:
350
        mov     eax, [pSym]
350
        mov     eax, [pSym]
351
        mov     eax, [eax+8]
351
        mov     eax, [eax+8]
352
        ret
352
        ret
353
endp
353
endp
354
 
354
 
355
align 4
355
align 4
356
proc get_curr_task
356
proc get_curr_task
357
        mov     eax, [current_slot_idx]
357
        mov     eax, [current_slot_idx]
358
        shl     eax, 8
358
        shl     eax, 8
359
        ret
359
        ret
360
endp
360
endp
361
 
361
 
362
align 4
362
align 4
363
proc get_fileinfo stdcall, file_name:dword, info:dword
363
proc get_fileinfo stdcall, file_name:dword, info:dword
364
           locals
364
           locals
365
             cmd     dd ?
365
             cmd     dd ?
366
             offset  dd ?
366
             offset  dd ?
367
                     dd ?
367
                     dd ?
368
             count   dd ?
368
             count   dd ?
369
             buff    dd ?
369
             buff    dd ?
370
                     db ?
370
                     db ?
371
             name    dd ?
371
             name    dd ?
372
           endl
372
           endl
373
 
373
 
374
        xor     eax, eax
374
        xor     eax, eax
375
        mov     ebx, [file_name]
375
        mov     ebx, [file_name]
376
        mov     ecx, [info]
376
        mov     ecx, [info]
377
 
377
 
378
        mov     [cmd], 5
378
        mov     [cmd], 5
379
        mov     [offset], eax
379
        mov     [offset], eax
380
        mov     [offset+4], eax
380
        mov     [offset+4], eax
381
        mov     [count], eax
381
        mov     [count], eax
382
        mov     [buff], ecx
382
        mov     [buff], ecx
383
        mov     byte [buff+4], al
383
        mov     byte [buff+4], al
384
        mov     [name], ebx
384
        mov     [name], ebx
385
 
385
 
386
        mov     eax, 70
386
        mov     eax, 70
387
        lea     ebx, [cmd]
387
        lea     ebx, [cmd]
388
        pushad
388
        pushad
389
        cld
389
        cld
390
        call    protect_from_terminate
390
        call    protect_from_terminate
391
        call    file_system_lfn
391
        call    file_system_lfn
392
        call    unprotect_from_terminate
392
        call    unprotect_from_terminate
393
        popad
393
        popad
394
        ret
394
        ret
395
endp
395
endp
396
 
396
 
397
align 4
397
align 4
398
proc read_file stdcall,file_name:dword, buffer:dword, off:dword,\
398
proc read_file stdcall,file_name:dword, buffer:dword, off:dword,\
399
                                     bytes:dword
399
                                     bytes:dword
400
           locals
400
           locals
401
             cmd     dd ?
401
             cmd     dd ?
402
             offset  dd ?
402
             offset  dd ?
403
                     dd ?
403
                     dd ?
404
             count   dd ?
404
             count   dd ?
405
             buff    dd ?
405
             buff    dd ?
406
                     db ?
406
                     db ?
407
             name    dd ?
407
             name    dd ?
408
           endl
408
           endl
409
 
409
 
410
        xor     eax, eax
410
        xor     eax, eax
411
        mov     ebx, [file_name]
411
        mov     ebx, [file_name]
412
        mov     ecx, [off]
412
        mov     ecx, [off]
413
        mov     edx, [bytes]
413
        mov     edx, [bytes]
414
        mov     esi, [buffer]
414
        mov     esi, [buffer]
415
 
415
 
416
        mov     [cmd], eax
416
        mov     [cmd], eax
417
        mov     [offset], ecx
417
        mov     [offset], ecx
418
        mov     [offset+4], eax
418
        mov     [offset+4], eax
419
        mov     [count], edx
419
        mov     [count], edx
420
        mov     [buff], esi
420
        mov     [buff], esi
421
        mov     byte [buff+4], al
421
        mov     byte [buff+4], al
422
        mov     [name], ebx
422
        mov     [name], ebx
423
 
423
 
424
        pushad
424
        pushad
425
        lea     ebx, [cmd]
425
        lea     ebx, [cmd]
426
        call    file_system_lfn_protected
426
        call    file_system_lfn_protected
427
        popad
427
        popad
428
        ret
428
        ret
429
endp
429
endp
430
 
430
 
431
; description
431
align 4
432
;  allocate kernel memory and loads the specified file
432
; @brief Allocate kernel memory and loads the specified file
433
;
-
 
434
; param
433
;
435
;  file_name= path to file
434
; @param file_name Path to file
436
;
-
 
437
; retval
435
;
438
;  eax= file image in kernel memory
-
 
439
;  ebx= size of file
436
; @returns File image in kernel memory in `eax` and size of file in `ebx`
440
;
-
 
441
; warging
437
;
442
;  You mast call kernel_free() to delete each file
438
; @warning You must call kernel_free() to delete each file loaded by the
443
;  loaded by the load_file() function
-
 
444
 
-
 
445
align 4
439
;          load_file() function
446
proc load_file stdcall, file_name:dword
440
proc load_file stdcall, file_name:dword
447
           locals
441
           locals
448
             attr       dd ?
442
             attr       dd ?
449
             flags      dd ?
443
             flags      dd ?
450
             cr_time    dd ?
444
             cr_time    dd ?
451
             cr_date    dd ?
445
             cr_date    dd ?
452
             acc_time   dd ?
446
             acc_time   dd ?
453
             acc_date   dd ?
447
             acc_date   dd ?
454
             mod_time   dd ?
448
             mod_time   dd ?
455
             mod_date   dd ?
449
             mod_date   dd ?
456
             file_size  dd ?
450
             file_size  dd ?
457
 
451
 
458
             file       dd ?
452
             file       dd ?
459
             file2      dd ?
453
             file2      dd ?
460
           endl
454
           endl
461
 
455
 
462
        push    esi
456
        push    esi
463
        push    edi
457
        push    edi
464
 
458
 
465
        lea     eax, [attr]
459
        lea     eax, [attr]
466
        stdcall get_fileinfo, [file_name], eax
460
        stdcall get_fileinfo, [file_name], eax
467
        test    eax, eax
461
        test    eax, eax
468
        jnz     .fail
462
        jnz     .fail
469
 
463
 
470
        mov     eax, [file_size]
464
        mov     eax, [file_size]
471
        cmp     eax, 1024*1024*16
465
        cmp     eax, 1024*1024*16
472
        ja      .fail
466
        ja      .fail
473
 
467
 
474
        stdcall kernel_alloc, [file_size]
468
        stdcall kernel_alloc, [file_size]
475
        mov     [file], eax
469
        mov     [file], eax
476
        test    eax, eax
470
        test    eax, eax
477
        jz      .fail
471
        jz      .fail
478
 
472
 
479
        stdcall read_file, [file_name], eax, dword 0, [file_size]
473
        stdcall read_file, [file_name], eax, dword 0, [file_size]
480
        cmp     ebx, [file_size]
474
        cmp     ebx, [file_size]
481
        jne     .cleanup
475
        jne     .cleanup
482
 
476
 
483
        mov     eax, [file]
477
        mov     eax, [file]
484
        cmp     dword [eax], 'KPCK'
478
        cmp     dword [eax], 'KPCK'
485
        jne     .exit
479
        jne     .exit
486
        mov     ebx, [eax+4]
480
        mov     ebx, [eax+4]
487
        mov     [file_size], ebx
481
        mov     [file_size], ebx
488
        stdcall kernel_alloc, ebx
482
        stdcall kernel_alloc, ebx
489
 
483
 
490
        test    eax, eax
484
        test    eax, eax
491
        jz      .cleanup
485
        jz      .cleanup
492
 
486
 
493
        mov     [file2], eax
487
        mov     [file2], eax
494
 
488
 
495
        pushad
489
        pushad
496
        mov     ecx, unpack_mutex
490
        mov     ecx, unpack_mutex
497
        call    mutex_lock
491
        call    mutex_lock
498
        popad
492
        popad
499
 
493
 
500
        stdcall unpack, [file], eax
494
        stdcall unpack, [file], eax
501
 
495
 
502
        pushad
496
        pushad
503
        mov     ecx, unpack_mutex
497
        mov     ecx, unpack_mutex
504
        call    mutex_unlock
498
        call    mutex_unlock
505
        popad
499
        popad
506
 
500
 
507
        stdcall kernel_free, [file]
501
        stdcall kernel_free, [file]
508
        mov     eax, [file2]
502
        mov     eax, [file2]
509
        mov     ebx, [file_size]
503
        mov     ebx, [file_size]
510
.exit:
504
.exit:
511
        push    eax
505
        push    eax
512
        lea     edi, [eax+ebx]    ;cleanup remain space
506
        lea     edi, [eax+ebx]    ;cleanup remain space
513
        mov     ecx, 4096         ;from file end
507
        mov     ecx, 4096         ;from file end
514
        and     ebx, 4095
508
        and     ebx, 4095
515
        jz      @f
509
        jz      @f
516
        sub     ecx, ebx
510
        sub     ecx, ebx
517
        xor     eax, eax
511
        xor     eax, eax
518
        cld
512
        cld
519
        rep stosb
513
        rep stosb
520
@@:
514
@@:
521
        mov     ebx, [file_size]
515
        mov     ebx, [file_size]
522
        pop     eax
516
        pop     eax
523
        pop     edi
517
        pop     edi
524
        pop     esi
518
        pop     esi
525
        ret
519
        ret
526
.cleanup:
520
.cleanup:
527
        stdcall kernel_free, [file]
521
        stdcall kernel_free, [file]
528
.fail:
522
.fail:
529
        xor     eax, eax
523
        xor     eax, eax
530
        xor     ebx, ebx
524
        xor     ebx, ebx
531
        pop     edi
525
        pop     edi
532
        pop     esi
526
        pop     esi
533
        ret
527
        ret
534
endp
528
endp
535
 
529
 
536
; description
530
; description
537
;  allocate user memory and loads the specified file
531
;  allocate user memory and loads the specified file
538
;
532
;
539
; param
533
; param
540
;  file_name= path to file
534
;  file_name= path to file
541
;
535
;
542
; retval
536
; retval
543
;  eax= file image in user memory
537
;  eax= file image in user memory
544
;  ebx= size of file
538
;  ebx= size of file
545
;
539
;
546
; warging
540
; warging
547
;  You mast call kernel_free() to delete each file
541
;  You mast call kernel_free() to delete each file
548
;  loaded by the load_file() function
542
;  loaded by the load_file() function
549
 
543
 
550
align 4
544
align 4
551
proc load_file_umode stdcall, file_name:dword
545
proc load_file_umode stdcall, file_name:dword
552
           locals
546
           locals
553
             attr       dd ?
547
             attr       dd ?
554
             flags      dd ?
548
             flags      dd ?
555
             cr_time    dd ?
549
             cr_time    dd ?
556
             cr_date    dd ?
550
             cr_date    dd ?
557
             acc_time   dd ?
551
             acc_time   dd ?
558
             acc_date   dd ?
552
             acc_date   dd ?
559
             mod_time   dd ?
553
             mod_time   dd ?
560
             mod_date   dd ?
554
             mod_date   dd ?
561
             file_size  dd ?
555
             file_size  dd ?
562
 
556
 
563
             km_file    dd ?
557
             km_file    dd ?
564
             um_file    dd ?
558
             um_file    dd ?
565
           endl
559
           endl
566
 
560
 
567
        push    esi
561
        push    esi
568
        push    edi
562
        push    edi
569
        push    ebx
563
        push    ebx
570
 
564
 
571
        lea     eax, [attr]
565
        lea     eax, [attr]
572
        stdcall get_fileinfo, [file_name], eax   ;find file and get info
566
        stdcall get_fileinfo, [file_name], eax   ;find file and get info
573
        test    eax, eax
567
        test    eax, eax
574
        jnz     .err_1
568
        jnz     .err_1
575
 
569
 
576
        mov     eax, [file_size]
570
        mov     eax, [file_size]
577
        cmp     eax, 1024*1024*16                ;to be enough for anybody (c)
571
        cmp     eax, 1024*1024*16                ;to be enough for anybody (c)
578
        ja      .err_1
572
        ja      .err_1
579
                                                 ;it is very likely that the file is packed
573
                                                 ;it is very likely that the file is packed
580
        stdcall kernel_alloc, [file_size]        ;with kpack, so allocate memory from kernel heap
574
        stdcall kernel_alloc, [file_size]        ;with kpack, so allocate memory from kernel heap
581
        mov     [km_file], eax
575
        mov     [km_file], eax
582
        test    eax, eax
576
        test    eax, eax
583
        jz      .err_1
577
        jz      .err_1
584
 
578
 
585
        stdcall read_file, [file_name], eax, dword 0, [file_size]
579
        stdcall read_file, [file_name], eax, dword 0, [file_size]
586
        cmp     ebx, [file_size]
580
        cmp     ebx, [file_size]
587
 
581
 
588
        jne     .err_2
582
        jne     .err_2
589
 
583
 
590
        mov     eax, [km_file]
584
        mov     eax, [km_file]
591
        cmp     dword [eax], 'KPCK'              ; check kpack signature
585
        cmp     dword [eax], 'KPCK'              ; check kpack signature
592
        jne     .raw_file
586
        jne     .raw_file
593
 
587
 
594
        mov     ebx, [eax+4]                     ;get real size of file
588
        mov     ebx, [eax+4]                     ;get real size of file
595
        mov     [file_size], ebx
589
        mov     [file_size], ebx
596
        stdcall user_alloc, ebx                  ;and allocate space from user heap
590
        stdcall user_alloc, ebx                  ;and allocate space from user heap
597
        mov     [um_file], eax
591
        mov     [um_file], eax
598
        test    eax, eax
592
        test    eax, eax
599
        jz      .err_2
593
        jz      .err_2
600
 
594
 
601
        mov     edx, [file_size]                 ;preallocate page memory
595
        mov     edx, [file_size]                 ;preallocate page memory
602
        shr     eax, 10
596
        shr     eax, 10
603
        lea     edi, [page_tabs+eax]
597
        lea     edi, [page_tabs+eax]
604
        add     edx, 4095
598
        add     edx, 4095
605
        shr     edx, 12
599
        shr     edx, 12
606
@@:
600
@@:
607
        call    alloc_page
601
        call    alloc_page
608
        test    eax, eax
602
        test    eax, eax
609
        jz      .err_3
603
        jz      .err_3
610
 
604
 
611
        or      eax, PG_UWR
605
        or      eax, PG_UWR
612
        stosd
606
        stosd
613
        dec     edx
607
        dec     edx
614
        jnz     @B
608
        jnz     @B
615
 
609
 
616
        pushad
610
        pushad
617
        mov     ecx, unpack_mutex
611
        mov     ecx, unpack_mutex
618
        call    mutex_lock
612
        call    mutex_lock
619
 
613
 
620
        stdcall unpack, [km_file], [um_file]
614
        stdcall unpack, [km_file], [um_file]
621
 
615
 
622
        mov     ecx, unpack_mutex
616
        mov     ecx, unpack_mutex
623
        call    mutex_unlock
617
        call    mutex_unlock
624
        popad
618
        popad
625
 
619
 
626
        stdcall kernel_free, [km_file]           ;we don't need packed file anymore
620
        stdcall kernel_free, [km_file]           ;we don't need packed file anymore
627
.exit:
621
.exit:
628
 
622
 
629
        mov     edi, [um_file]
623
        mov     edi, [um_file]
630
        mov     esi, [um_file]
624
        mov     esi, [um_file]
631
        mov     eax, [file_size]
625
        mov     eax, [file_size]
632
        mov     edx, eax
626
        mov     edx, eax
633
 
627
 
634
        add     edi, eax                         ;cleanup remain space
628
        add     edi, eax                         ;cleanup remain space
635
        mov     ecx, 4096                        ;from file end
629
        mov     ecx, 4096                        ;from file end
636
        and     eax, 4095
630
        and     eax, 4095
637
        jz      @f
631
        jz      @f
638
        sub     ecx, eax
632
        sub     ecx, eax
639
        xor     eax, eax
633
        xor     eax, eax
640
        cld
634
        cld
641
        rep stosb
635
        rep stosb
642
@@:
636
@@:
643
        mov     eax, [um_file]
637
        mov     eax, [um_file]
644
 
638
 
645
        pop     ebx
639
        pop     ebx
646
        pop     edi
640
        pop     edi
647
        pop     esi
641
        pop     esi
648
        ret
642
        ret
649
 
643
 
650
.raw_file:                                       ; sometimes we load unpacked file
644
.raw_file:                                       ; sometimes we load unpacked file
651
        stdcall user_alloc, ebx                  ; allocate space from user heap
645
        stdcall user_alloc, ebx                  ; allocate space from user heap
652
        mov     [um_file], eax
646
        mov     [um_file], eax
653
 
647
 
654
        test    eax, eax
648
        test    eax, eax
655
        jz      .err_2
649
        jz      .err_2
656
 
650
 
657
        shr     eax, 10                          ; and remap pages.
651
        shr     eax, 10                          ; and remap pages.
658
 
652
 
659
        mov     ecx, [file_size]
653
        mov     ecx, [file_size]
660
        add     ecx, 4095
654
        add     ecx, 4095
661
        shr     ecx, 12
655
        shr     ecx, 12
662
 
656
 
663
        mov     esi, [km_file]
657
        mov     esi, [km_file]
664
        shr     esi, 10
658
        shr     esi, 10
665
        add     esi, page_tabs
659
        add     esi, page_tabs
666
 
660
 
667
        lea     edi, [page_tabs+eax]
661
        lea     edi, [page_tabs+eax]
668
 
662
 
669
        cld
663
        cld
670
@@:
664
@@:
671
        lodsd
665
        lodsd
672
        and     eax, 0xFFFFF000
666
        and     eax, 0xFFFFF000
673
        or      eax, PG_UWR
667
        or      eax, PG_UWR
674
        stosd
668
        stosd
675
        loop    @B
669
        loop    @B
676
 
670
 
677
        stdcall free_kernel_space, [km_file]     ; release allocated kernel space
671
        stdcall free_kernel_space, [km_file]     ; release allocated kernel space
678
        jmp     .exit                            ; physical pages still in use
672
        jmp     .exit                            ; physical pages still in use
679
.err_3:
673
.err_3:
680
        stdcall user_free, [um_file]
674
        stdcall user_free, [um_file]
681
.err_2:
675
.err_2:
682
        stdcall kernel_free, [km_file]
676
        stdcall kernel_free, [km_file]
683
.err_1:
677
.err_1:
684
        xor     eax, eax
678
        xor     eax, eax
685
        xor     edx, edx
679
        xor     edx, edx
686
 
680
 
687
        pop     ebx
681
        pop     ebx
688
        pop     edi
682
        pop     edi
689
        pop     esi
683
        pop     esi
690
        ret
684
        ret
691
endp
685
endp
692
 
686
 
693
 
687
 
694
uglobal
688
uglobal
695
align 4
689
align 4
696
unpack_mutex MUTEX
690
unpack_mutex MUTEX
697
endg
691
endg
698
 
692
 
699
align 4
693
align 4
700
proc get_proc_ex stdcall uses ebx esi, proc_name:dword, imports:dword
694
proc get_proc_ex stdcall uses ebx esi, proc_name:dword, imports:dword
701
        mov     ebx, [imports]
695
        mov     ebx, [imports]
702
        test    ebx, ebx
696
        test    ebx, ebx
703
        jz      .end
697
        jz      .end
704
        xor     esi, esi
698
        xor     esi, esi
705
.look_up:
699
.look_up:
706
 
700
 
707
        mov     eax, [ebx+32]
701
        mov     eax, [ebx+32]
708
        mov     eax, [OS_BASE+eax+esi*4]
702
        mov     eax, [OS_BASE+eax+esi*4]
709
        add     eax, OS_BASE
703
        add     eax, OS_BASE
710
        stdcall strncmp, eax, [proc_name], 256
704
        stdcall strncmp, eax, [proc_name], 256
711
        test    eax, eax
705
        test    eax, eax
712
        jz      .ok
706
        jz      .ok
713
 
707
 
714
        inc     esi
708
        inc     esi
715
        cmp     esi, [ebx+24]
709
        cmp     esi, [ebx+24]
716
        jb      .look_up
710
        jb      .look_up
717
.end:
711
.end:
718
        xor     eax, eax
712
        xor     eax, eax
719
        ret
713
        ret
720
.ok:
714
.ok:
721
        mov     eax, [ebx+28]
715
        mov     eax, [ebx+28]
722
        mov     eax, [OS_BASE+eax+esi*4]
716
        mov     eax, [OS_BASE+eax+esi*4]
723
        add     eax, OS_BASE
717
        add     eax, OS_BASE
724
        ret
718
        ret
725
endp
719
endp
726
 
720
 
727
align 4
721
align 4
728
proc fix_coff_symbols stdcall uses ebx esi, sec:dword, symbols:dword,\
722
proc fix_coff_symbols stdcall uses ebx esi, sec:dword, symbols:dword,\
729
                      sym_count:dword, strings:dword, imports:dword
723
                      sym_count:dword, strings:dword, imports:dword
730
           locals
724
           locals
731
             retval dd ?
725
             retval dd ?
732
           endl
726
           endl
733
 
727
 
734
        mov     edi, [symbols]
728
        mov     edi, [symbols]
735
        mov     [retval], 1
729
        mov     [retval], 1
736
.fix:
730
.fix:
737
        movzx   ebx, [edi+COFF_SYM.SectionNumber]
731
        movzx   ebx, [edi+COFF_SYM.SectionNumber]
738
        test    ebx, ebx
732
        test    ebx, ebx
739
        jnz     .internal
733
        jnz     .internal
740
        mov     eax, dword [edi+COFF_SYM.Name]
734
        mov     eax, dword [edi+COFF_SYM.Name]
741
        test    eax, eax
735
        test    eax, eax
742
        jnz     @F
736
        jnz     @F
743
 
737
 
744
        mov     edi, [edi+4]
738
        mov     edi, [edi+4]
745
        add     edi, [strings]
739
        add     edi, [strings]
746
@@:
740
@@:
747
        push    edi
741
        push    edi
748
        stdcall get_proc_ex, edi, [imports]
742
        stdcall get_proc_ex, edi, [imports]
749
        pop     edi
743
        pop     edi
750
 
744
 
751
        xor     ebx, ebx
745
        xor     ebx, ebx
752
        test    eax, eax
746
        test    eax, eax
753
        jnz     @F
747
        jnz     @F
754
 
748
 
755
        ; disable debug msg
749
        ; disable debug msg
756
        ;mov     esi, msg_unresolved
750
        ;mov     esi, msg_unresolved
757
        ;call    sys_msg_board_str
751
        ;call    sys_msg_board_str
758
        ;mov     esi, edi
752
        ;mov     esi, edi
759
        ;call    sys_msg_board_str
753
        ;call    sys_msg_board_str
760
        ;mov     esi, msg_CR
754
        ;mov     esi, msg_CR
761
        ;call    sys_msg_board_str
755
        ;call    sys_msg_board_str
762
 
756
 
763
        mov     [retval], 0
757
        mov     [retval], 0
764
@@:
758
@@:
765
        mov     edi, [symbols]
759
        mov     edi, [symbols]
766
        mov     [edi+COFF_SYM.Value], eax
760
        mov     [edi+COFF_SYM.Value], eax
767
        jmp     .next
761
        jmp     .next
768
.internal:
762
.internal:
769
        cmp     bx, -1
763
        cmp     bx, -1
770
        je      .next
764
        je      .next
771
        cmp     bx, -2
765
        cmp     bx, -2
772
        je      .next
766
        je      .next
773
 
767
 
774
        dec     ebx
768
        dec     ebx
775
        shl     ebx, 3
769
        shl     ebx, 3
776
        lea     ebx, [ebx+ebx*4]
770
        lea     ebx, [ebx+ebx*4]
777
        add     ebx, [sec]
771
        add     ebx, [sec]
778
 
772
 
779
        mov     eax, [ebx+COFF_SECTION.VirtualAddress]
773
        mov     eax, [ebx+COFF_SECTION.VirtualAddress]
780
        add     [edi+COFF_SYM.Value], eax
774
        add     [edi+COFF_SYM.Value], eax
781
.next:
775
.next:
782
        add     edi, sizeof.COFF_SYM
776
        add     edi, sizeof.COFF_SYM
783
        mov     [symbols], edi
777
        mov     [symbols], edi
784
        dec     [sym_count]
778
        dec     [sym_count]
785
        jnz     .fix
779
        jnz     .fix
786
        mov     eax, [retval]
780
        mov     eax, [retval]
787
        ret
781
        ret
788
endp
782
endp
789
 
783
 
790
align 4
784
align 4
791
proc fix_coff_relocs stdcall uses ebx esi, coff:dword, sym:dword, \
785
proc fix_coff_relocs stdcall uses ebx esi, coff:dword, sym:dword, \
792
        delta:dword
786
        delta:dword
793
           locals
787
           locals
794
             n_sec     dd ?
788
             n_sec     dd ?
795
           endl
789
           endl
796
 
790
 
797
        mov     eax, [coff]
791
        mov     eax, [coff]
798
        movzx   ebx, [eax+COFF_HEADER.nSections]
792
        movzx   ebx, [eax+COFF_HEADER.nSections]
799
        mov     [n_sec], ebx
793
        mov     [n_sec], ebx
800
        lea     esi, [eax+20]
794
        lea     esi, [eax+20]
801
.fix_sec:
795
.fix_sec:
802
        mov     edi, [esi+COFF_SECTION.PtrReloc]
796
        mov     edi, [esi+COFF_SECTION.PtrReloc]
803
        add     edi, [coff]
797
        add     edi, [coff]
804
 
798
 
805
        movzx   ecx, [esi+COFF_SECTION.NumReloc]
799
        movzx   ecx, [esi+COFF_SECTION.NumReloc]
806
        test    ecx, ecx
800
        test    ecx, ecx
807
        jz      .next
801
        jz      .next
808
.reloc_loop:
802
.reloc_loop:
809
        mov     ebx, [edi+COFF_RELOC.SymIndex]
803
        mov     ebx, [edi+COFF_RELOC.SymIndex]
810
        add     ebx, ebx
804
        add     ebx, ebx
811
        lea     ebx, [ebx+ebx*8]
805
        lea     ebx, [ebx+ebx*8]
812
        add     ebx, [sym]
806
        add     ebx, [sym]
813
 
807
 
814
        mov     edx, [ebx+COFF_SYM.Value]
808
        mov     edx, [ebx+COFF_SYM.Value]
815
 
809
 
816
        cmp     [edi+COFF_RELOC.Type], 6
810
        cmp     [edi+COFF_RELOC.Type], 6
817
        je      .dir_32
811
        je      .dir_32
818
 
812
 
819
        cmp     [edi+COFF_RELOC.Type], 20
813
        cmp     [edi+COFF_RELOC.Type], 20
820
        jne     .next_reloc
814
        jne     .next_reloc
821
.rel_32:
815
.rel_32:
822
        mov     eax, [edi+COFF_RELOC.VirtualAddress]
816
        mov     eax, [edi+COFF_RELOC.VirtualAddress]
823
        add     eax, [esi+COFF_SECTION.VirtualAddress]
817
        add     eax, [esi+COFF_SECTION.VirtualAddress]
824
        sub     edx, eax
818
        sub     edx, eax
825
        sub     edx, 4
819
        sub     edx, 4
826
        jmp     .fix
820
        jmp     .fix
827
.dir_32:
821
.dir_32:
828
        mov     eax, [edi+COFF_RELOC.VirtualAddress]
822
        mov     eax, [edi+COFF_RELOC.VirtualAddress]
829
        add     eax, [esi+COFF_SECTION.VirtualAddress]
823
        add     eax, [esi+COFF_SECTION.VirtualAddress]
830
.fix:
824
.fix:
831
        add     eax, [delta]
825
        add     eax, [delta]
832
        add     [eax], edx
826
        add     [eax], edx
833
.next_reloc:
827
.next_reloc:
834
        add     edi, 10
828
        add     edi, 10
835
        dec     ecx
829
        dec     ecx
836
        jnz     .reloc_loop
830
        jnz     .reloc_loop
837
.next:
831
.next:
838
        add     esi, sizeof.COFF_SECTION
832
        add     esi, sizeof.COFF_SECTION
839
        dec     [n_sec]
833
        dec     [n_sec]
840
        jnz     .fix_sec
834
        jnz     .fix_sec
841
.exit:
835
.exit:
842
        ret
836
        ret
843
endp
837
endp
844
 
838
 
845
align 4
839
align 4
846
proc rebase_coff stdcall uses ebx esi, coff:dword, sym:dword, \
840
proc rebase_coff stdcall uses ebx esi, coff:dword, sym:dword, \
847
        delta:dword
841
        delta:dword
848
           locals
842
           locals
849
             n_sec     dd ?
843
             n_sec     dd ?
850
           endl
844
           endl
851
 
845
 
852
        mov     eax, [coff]
846
        mov     eax, [coff]
853
        movzx   ebx, [eax+COFF_HEADER.nSections]
847
        movzx   ebx, [eax+COFF_HEADER.nSections]
854
        mov     [n_sec], ebx
848
        mov     [n_sec], ebx
855
        lea     esi, [eax+20]
849
        lea     esi, [eax+20]
856
        mov     edx, [delta]
850
        mov     edx, [delta]
857
.fix_sec:
851
.fix_sec:
858
        mov     edi, [esi+COFF_SECTION.PtrReloc]
852
        mov     edi, [esi+COFF_SECTION.PtrReloc]
859
        add     edi, [coff]
853
        add     edi, [coff]
860
 
854
 
861
        movzx   ecx, [esi+COFF_SECTION.NumReloc]
855
        movzx   ecx, [esi+COFF_SECTION.NumReloc]
862
        test    ecx, ecx
856
        test    ecx, ecx
863
        jz      .next
857
        jz      .next
864
.reloc_loop:
858
.reloc_loop:
865
        cmp     [edi+COFF_RELOC.Type], 6
859
        cmp     [edi+COFF_RELOC.Type], 6
866
        jne     .next_reloc
860
        jne     .next_reloc
867
.dir_32:
861
.dir_32:
868
        mov     eax, [edi+COFF_RELOC.VirtualAddress]
862
        mov     eax, [edi+COFF_RELOC.VirtualAddress]
869
        add     eax, [esi+COFF_SECTION.VirtualAddress]
863
        add     eax, [esi+COFF_SECTION.VirtualAddress]
870
        add     [eax+edx], edx
864
        add     [eax+edx], edx
871
.next_reloc:
865
.next_reloc:
872
        add     edi, 10
866
        add     edi, 10
873
        dec     ecx
867
        dec     ecx
874
        jnz     .reloc_loop
868
        jnz     .reloc_loop
875
.next:
869
.next:
876
        add     esi, sizeof.COFF_SECTION
870
        add     esi, sizeof.COFF_SECTION
877
        dec     [n_sec]
871
        dec     [n_sec]
878
        jnz     .fix_sec
872
        jnz     .fix_sec
879
.exit:
873
.exit:
880
        ret
874
        ret
881
endp
875
endp
882
 
876
 
883
; in: edx -> COFF_SECTION struct
877
; in: edx -> COFF_SECTION struct
884
; out: eax = alignment as mask for bits to drop
878
; out: eax = alignment as mask for bits to drop
885
coff_get_align:
879
coff_get_align:
886
; Rules:
880
; Rules:
887
; - if alignment is not given, use default = 4K;
881
; - if alignment is not given, use default = 4K;
888
; - if alignment is given and is no more than 4K, use it;
882
; - if alignment is given and is no more than 4K, use it;
889
; - if alignment is more than 4K, revert to 4K.
883
; - if alignment is more than 4K, revert to 4K.
890
        push    ecx
884
        push    ecx
891
        mov     cl, byte [edx+COFF_SECTION.Characteristics+2]
885
        mov     cl, byte [edx+COFF_SECTION.Characteristics+2]
892
        mov     eax, 1
886
        mov     eax, 1
893
        shr     cl, 4
887
        shr     cl, 4
894
        dec     cl
888
        dec     cl
895
        js      .default
889
        js      .default
896
        cmp     cl, 12
890
        cmp     cl, 12
897
        jbe     @f
891
        jbe     @f
898
.default:
892
.default:
899
        mov     cl, 12
893
        mov     cl, 12
900
@@:
894
@@:
901
        shl     eax, cl
895
        shl     eax, cl
902
        pop     ecx
896
        pop     ecx
903
        dec     eax
897
        dec     eax
904
        ret
898
        ret
905
 
899
 
906
align 4
900
align 4
907
proc load_library stdcall, file_name:dword, encoding:dword
901
proc load_library stdcall, file_name:dword, encoding:dword
908
    locals
902
    locals
909
        fullname    dd  ?
903
        fullname    dd  ?
910
        fileinfo    rb  40
904
        fileinfo    rb  40
911
        coff        dd  ?
905
        coff        dd  ?
912
        img_base    dd  ?
906
        img_base    dd  ?
913
    endl
907
    endl
914
 
908
 
915
; resolve file name
909
; resolve file name
916
        stdcall kernel_alloc, maxPathLength
910
        stdcall kernel_alloc, maxPathLength
917
        mov     [fullname], eax
911
        mov     [fullname], eax
918
        mov     edi, eax
912
        mov     edi, eax
919
        mov     esi, [file_name]
913
        mov     esi, [file_name]
920
        mov     eax, [encoding]
914
        mov     eax, [encoding]
921
        push    ebp
915
        push    ebp
922
        call    getFullPath
916
        call    getFullPath
923
        pop     ebp
917
        pop     ebp
924
        test    eax, eax
918
        test    eax, eax
925
        jz      .fail
919
        jz      .fail
926
; scan for required DLL in list of already loaded for this process,
920
; scan for required DLL in list of already loaded for this process,
927
; ignore timestamp
921
; ignore timestamp
928
        cli
922
        cli
929
        mov     esi, [current_process]
923
        mov     esi, [current_process]
930
        mov     edi, [fullname]
924
        mov     edi, [fullname]
931
        mov     ebx, [esi+PROC.dlls_list_ptr]
925
        mov     ebx, [esi+PROC.dlls_list_ptr]
932
        test    ebx, ebx
926
        test    ebx, ebx
933
        jz      .not_in_process
927
        jz      .not_in_process
934
        mov     esi, [ebx+HDLL.fd]
928
        mov     esi, [ebx+HDLL.fd]
935
.scan_in_process:
929
.scan_in_process:
936
        cmp     esi, ebx
930
        cmp     esi, ebx
937
        jz      .not_in_process
931
        jz      .not_in_process
938
        mov     eax, [esi+HDLL.parent]
932
        mov     eax, [esi+HDLL.parent]
939
        add     eax, DLLDESCR.name
933
        add     eax, DLLDESCR.name
940
        stdcall strncmp, eax, edi, -1
934
        stdcall strncmp, eax, edi, -1
941
        test    eax, eax
935
        test    eax, eax
942
        jnz     .next_in_process
936
        jnz     .next_in_process
943
; simple variant: load DLL which is already loaded in this process
937
; simple variant: load DLL which is already loaded in this process
944
; just increment reference counters and return address of exports table
938
; just increment reference counters and return address of exports table
945
        inc     [esi+HDLL.refcount]
939
        inc     [esi+HDLL.refcount]
946
        mov     ecx, [esi+HDLL.parent]
940
        mov     ecx, [esi+HDLL.parent]
947
        inc     [ecx+DLLDESCR.refcount]
941
        inc     [ecx+DLLDESCR.refcount]
948
        mov     eax, [ecx+DLLDESCR.exports]
942
        mov     eax, [ecx+DLLDESCR.exports]
949
        sub     eax, [ecx+DLLDESCR.defaultbase]
943
        sub     eax, [ecx+DLLDESCR.defaultbase]
950
        add     eax, [esi+HDLL.base]
944
        add     eax, [esi+HDLL.base]
951
        sti
945
        sti
952
        push    eax
946
        push    eax
953
        stdcall kernel_free, [fullname]
947
        stdcall kernel_free, [fullname]
954
        pop     eax
948
        pop     eax
955
        ret
949
        ret
956
 
950
 
957
.next_in_process:
951
.next_in_process:
958
        mov     esi, [esi+HDLL.fd]
952
        mov     esi, [esi+HDLL.fd]
959
        jmp     .scan_in_process
953
        jmp     .scan_in_process
960
 
954
 
961
.not_in_process:
955
.not_in_process:
962
; scan in full list, compare timestamp
956
; scan in full list, compare timestamp
963
        sti
957
        sti
964
        lea     eax, [fileinfo]
958
        lea     eax, [fileinfo]
965
        stdcall get_fileinfo, edi, eax
959
        stdcall get_fileinfo, edi, eax
966
        test    eax, eax
960
        test    eax, eax
967
        jnz     .fail
961
        jnz     .fail
968
        cli
962
        cli
969
        mov     esi, [dll_list.fd]
963
        mov     esi, [dll_list.fd]
970
.scan_for_dlls:
964
.scan_for_dlls:
971
        cmp     esi, dll_list
965
        cmp     esi, dll_list
972
        jz      .load_new
966
        jz      .load_new
973
        lea     eax, [esi+DLLDESCR.name]
967
        lea     eax, [esi+DLLDESCR.name]
974
        stdcall strncmp, eax, edi, -1
968
        stdcall strncmp, eax, edi, -1
975
        test    eax, eax
969
        test    eax, eax
976
        jnz     .continue_scan
970
        jnz     .continue_scan
977
.test_prev_dll:
971
.test_prev_dll:
978
        mov     eax, dword [fileinfo+24]; last modified time
972
        mov     eax, dword [fileinfo+24]; last modified time
979
        mov     edx, dword [fileinfo+28]; last modified date
973
        mov     edx, dword [fileinfo+28]; last modified date
980
        cmp     dword [esi+DLLDESCR.timestamp], eax
974
        cmp     dword [esi+DLLDESCR.timestamp], eax
981
        jnz     .continue_scan
975
        jnz     .continue_scan
982
        cmp     dword [esi+DLLDESCR.timestamp+4], edx
976
        cmp     dword [esi+DLLDESCR.timestamp+4], edx
983
        jz      .dll_already_loaded
977
        jz      .dll_already_loaded
984
.continue_scan:
978
.continue_scan:
985
        mov     esi, [esi+DLLDESCR.fd]
979
        mov     esi, [esi+DLLDESCR.fd]
986
        jmp     .scan_for_dlls
980
        jmp     .scan_for_dlls
987
 
981
 
988
; new DLL
982
; new DLL
989
.load_new:
983
.load_new:
990
        sti
984
        sti
991
; load file
985
; load file
992
        stdcall load_file, edi
986
        stdcall load_file, edi
993
        test    eax, eax
987
        test    eax, eax
994
        jz      .fail
988
        jz      .fail
995
        mov     [coff], eax
989
        mov     [coff], eax
996
        mov     dword [fileinfo+32], ebx
990
        mov     dword [fileinfo+32], ebx
997
 
991
 
998
; allocate DLLDESCR struct; size is DLLDESCR.sizeof plus size of DLL name
992
; allocate DLLDESCR struct; size is DLLDESCR.sizeof plus size of DLL name
999
        mov     esi, edi
993
        mov     esi, edi
1000
        mov     ecx, -1
994
        mov     ecx, -1
1001
        xor     eax, eax
995
        xor     eax, eax
1002
        repnz scasb
996
        repnz scasb
1003
        not     ecx
997
        not     ecx
1004
        lea     eax, [ecx+sizeof.DLLDESCR]
998
        lea     eax, [ecx+sizeof.DLLDESCR]
1005
        push    ecx
999
        push    ecx
1006
        call    malloc
1000
        call    malloc
1007
        pop     ecx
1001
        pop     ecx
1008
        test    eax, eax
1002
        test    eax, eax
1009
        jz      .fail_and_free_coff
1003
        jz      .fail_and_free_coff
1010
; save timestamp
1004
; save timestamp
1011
        lea     edi, [eax+DLLDESCR.name]
1005
        lea     edi, [eax+DLLDESCR.name]
1012
        rep movsb
1006
        rep movsb
1013
        mov     esi, eax
1007
        mov     esi, eax
1014
        mov     eax, dword [fileinfo+24]
1008
        mov     eax, dword [fileinfo+24]
1015
        mov     dword [esi+DLLDESCR.timestamp], eax
1009
        mov     dword [esi+DLLDESCR.timestamp], eax
1016
        mov     eax, dword [fileinfo+28]
1010
        mov     eax, dword [fileinfo+28]
1017
        mov     dword [esi+DLLDESCR.timestamp+4], eax
1011
        mov     dword [esi+DLLDESCR.timestamp+4], eax
1018
 
1012
 
1019
; calculate size of loaded DLL
1013
; calculate size of loaded DLL
1020
        mov     edx, [coff]
1014
        mov     edx, [coff]
1021
        movzx   ecx, [edx+COFF_HEADER.nSections]
1015
        movzx   ecx, [edx+COFF_HEADER.nSections]
1022
        xor     ebx, ebx
1016
        xor     ebx, ebx
1023
 
1017
 
1024
        add     edx, 20
1018
        add     edx, 20
1025
@@:
1019
@@:
1026
        call    coff_get_align
1020
        call    coff_get_align
1027
        add     ebx, eax
1021
        add     ebx, eax
1028
        not     eax
1022
        not     eax
1029
        and     ebx, eax
1023
        and     ebx, eax
1030
        add     ebx, [edx+COFF_SECTION.SizeOfRawData]
1024
        add     ebx, [edx+COFF_SECTION.SizeOfRawData]
1031
        add     edx, sizeof.COFF_SECTION
1025
        add     edx, sizeof.COFF_SECTION
1032
        dec     ecx
1026
        dec     ecx
1033
        jnz     @B
1027
        jnz     @B
1034
; it must be nonzero and not too big
1028
; it must be nonzero and not too big
1035
        mov     [esi+DLLDESCR.size], ebx
1029
        mov     [esi+DLLDESCR.size], ebx
1036
        test    ebx, ebx
1030
        test    ebx, ebx
1037
        jz      .fail_and_free_dll
1031
        jz      .fail_and_free_dll
1038
        cmp     ebx, MAX_DEFAULT_DLL_ADDR-MIN_DEFAULT_DLL_ADDR
1032
        cmp     ebx, MAX_DEFAULT_DLL_ADDR-MIN_DEFAULT_DLL_ADDR
1039
        ja      .fail_and_free_dll
1033
        ja      .fail_and_free_dll
1040
; allocate memory for kernel-side image
1034
; allocate memory for kernel-side image
1041
        stdcall kernel_alloc, ebx
1035
        stdcall kernel_alloc, ebx
1042
        test    eax, eax
1036
        test    eax, eax
1043
        jz      .fail_and_free_dll
1037
        jz      .fail_and_free_dll
1044
        mov     [esi+DLLDESCR.data], eax
1038
        mov     [esi+DLLDESCR.data], eax
1045
; calculate preferred base address
1039
; calculate preferred base address
1046
        add     ebx, 0x1FFF
1040
        add     ebx, 0x1FFF
1047
        and     ebx, not 0xFFF
1041
        and     ebx, not 0xFFF
1048
        mov     ecx, [dll_cur_addr]
1042
        mov     ecx, [dll_cur_addr]
1049
        lea     edx, [ecx+ebx]
1043
        lea     edx, [ecx+ebx]
1050
        cmp     edx, MAX_DEFAULT_DLL_ADDR
1044
        cmp     edx, MAX_DEFAULT_DLL_ADDR
1051
        jb      @f
1045
        jb      @f
1052
        mov     ecx, MIN_DEFAULT_DLL_ADDR
1046
        mov     ecx, MIN_DEFAULT_DLL_ADDR
1053
        lea     edx, [ecx+ebx]
1047
        lea     edx, [ecx+ebx]
1054
@@:
1048
@@:
1055
        mov     [esi+DLLDESCR.defaultbase], ecx
1049
        mov     [esi+DLLDESCR.defaultbase], ecx
1056
        mov     [dll_cur_addr], edx
1050
        mov     [dll_cur_addr], edx
1057
 
1051
 
1058
; copy sections and set correct values for VirtualAddress'es in headers
1052
; copy sections and set correct values for VirtualAddress'es in headers
1059
        push    esi
1053
        push    esi
1060
        mov     edx, [coff]
1054
        mov     edx, [coff]
1061
        movzx   ebx, [edx+COFF_HEADER.nSections]
1055
        movzx   ebx, [edx+COFF_HEADER.nSections]
1062
        mov     edi, eax
1056
        mov     edi, eax
1063
        add     edx, 20
1057
        add     edx, 20
1064
        cld
1058
        cld
1065
@@:
1059
@@:
1066
        call    coff_get_align
1060
        call    coff_get_align
1067
        add     ecx, eax
1061
        add     ecx, eax
1068
        add     edi, eax
1062
        add     edi, eax
1069
        not     eax
1063
        not     eax
1070
        and     ecx, eax
1064
        and     ecx, eax
1071
        and     edi, eax
1065
        and     edi, eax
1072
        mov     [edx+COFF_SECTION.VirtualAddress], ecx
1066
        mov     [edx+COFF_SECTION.VirtualAddress], ecx
1073
        add     ecx, [edx+COFF_SECTION.SizeOfRawData]
1067
        add     ecx, [edx+COFF_SECTION.SizeOfRawData]
1074
        mov     esi, [edx+COFF_SECTION.PtrRawData]
1068
        mov     esi, [edx+COFF_SECTION.PtrRawData]
1075
        push    ecx
1069
        push    ecx
1076
        mov     ecx, [edx+COFF_SECTION.SizeOfRawData]
1070
        mov     ecx, [edx+COFF_SECTION.SizeOfRawData]
1077
        test    esi, esi
1071
        test    esi, esi
1078
        jnz     .copy
1072
        jnz     .copy
1079
        xor     eax, eax
1073
        xor     eax, eax
1080
        rep stosb
1074
        rep stosb
1081
        jmp     .next
1075
        jmp     .next
1082
.copy:
1076
.copy:
1083
        add     esi, [coff]
1077
        add     esi, [coff]
1084
        rep movsb
1078
        rep movsb
1085
.next:
1079
.next:
1086
        pop     ecx
1080
        pop     ecx
1087
        add     edx, sizeof.COFF_SECTION
1081
        add     edx, sizeof.COFF_SECTION
1088
        dec     ebx
1082
        dec     ebx
1089
        jnz     @B
1083
        jnz     @B
1090
        pop     esi
1084
        pop     esi
1091
 
1085
 
1092
; save some additional data from COFF file
1086
; save some additional data from COFF file
1093
; later we will use COFF header, headers for sections and symbol table
1087
; later we will use COFF header, headers for sections and symbol table
1094
; and also relocations table for all sections
1088
; and also relocations table for all sections
1095
        mov     edx, [coff]
1089
        mov     edx, [coff]
1096
        mov     ebx, [edx+COFF_HEADER.pSymTable]
1090
        mov     ebx, [edx+COFF_HEADER.pSymTable]
1097
        mov     edi, dword [fileinfo+32]
1091
        mov     edi, dword [fileinfo+32]
1098
        sub     edi, ebx
1092
        sub     edi, ebx
1099
        jc      .fail_and_free_data
1093
        jc      .fail_and_free_data
1100
        mov     [esi+DLLDESCR.symbols_lim], edi
1094
        mov     [esi+DLLDESCR.symbols_lim], edi
1101
        add     ebx, edx
1095
        add     ebx, edx
1102
        movzx   ecx, [edx+COFF_HEADER.nSections]
1096
        movzx   ecx, [edx+COFF_HEADER.nSections]
1103
        lea     ecx, [ecx*5]
1097
        lea     ecx, [ecx*5]
1104
        lea     edi, [edi+ecx*8+20]
1098
        lea     edi, [edi+ecx*8+20]
1105
        add     edx, 20
1099
        add     edx, 20
1106
@@:
1100
@@:
1107
        movzx   eax, [edx+COFF_SECTION.NumReloc]
1101
        movzx   eax, [edx+COFF_SECTION.NumReloc]
1108
        lea     eax, [eax*5]
1102
        lea     eax, [eax*5]
1109
        lea     edi, [edi+eax*2]
1103
        lea     edi, [edi+eax*2]
1110
        add     edx, sizeof.COFF_SECTION
1104
        add     edx, sizeof.COFF_SECTION
1111
        sub     ecx, 5
1105
        sub     ecx, 5
1112
        jnz     @b
1106
        jnz     @b
1113
        stdcall kernel_alloc, edi
1107
        stdcall kernel_alloc, edi
1114
        test    eax, eax
1108
        test    eax, eax
1115
        jz      .fail_and_free_data
1109
        jz      .fail_and_free_data
1116
        mov     edx, [coff]
1110
        mov     edx, [coff]
1117
        movzx   ecx, [edx+COFF_HEADER.nSections]
1111
        movzx   ecx, [edx+COFF_HEADER.nSections]
1118
        lea     ecx, [ecx*5]
1112
        lea     ecx, [ecx*5]
1119
        lea     ecx, [ecx*2+5]
1113
        lea     ecx, [ecx*2+5]
1120
        mov     [esi+DLLDESCR.coff_hdr], eax
1114
        mov     [esi+DLLDESCR.coff_hdr], eax
1121
        push    esi
1115
        push    esi
1122
        mov     esi, edx
1116
        mov     esi, edx
1123
        mov     edi, eax
1117
        mov     edi, eax
1124
        rep movsd
1118
        rep movsd
1125
        pop     esi
1119
        pop     esi
1126
        mov     [esi+DLLDESCR.symbols_ptr], edi
1120
        mov     [esi+DLLDESCR.symbols_ptr], edi
1127
        push    esi
1121
        push    esi
1128
        mov     ecx, [edx+COFF_HEADER.nSymbols]
1122
        mov     ecx, [edx+COFF_HEADER.nSymbols]
1129
        mov     [esi+DLLDESCR.symbols_num], ecx
1123
        mov     [esi+DLLDESCR.symbols_num], ecx
1130
        mov     ecx, [esi+DLLDESCR.symbols_lim]
1124
        mov     ecx, [esi+DLLDESCR.symbols_lim]
1131
        mov     esi, ebx
1125
        mov     esi, ebx
1132
        rep movsb
1126
        rep movsb
1133
        pop     esi
1127
        pop     esi
1134
        mov     ebx, [esi+DLLDESCR.coff_hdr]
1128
        mov     ebx, [esi+DLLDESCR.coff_hdr]
1135
        push    esi
1129
        push    esi
1136
        movzx   eax, [edx+COFF_HEADER.nSections]
1130
        movzx   eax, [edx+COFF_HEADER.nSections]
1137
        lea     edx, [ebx+20]
1131
        lea     edx, [ebx+20]
1138
@@:
1132
@@:
1139
        movzx   ecx, [edx+COFF_SECTION.NumReloc]
1133
        movzx   ecx, [edx+COFF_SECTION.NumReloc]
1140
        lea     ecx, [ecx*5]
1134
        lea     ecx, [ecx*5]
1141
        mov     esi, [edx+COFF_SECTION.PtrReloc]
1135
        mov     esi, [edx+COFF_SECTION.PtrReloc]
1142
        mov     [edx+COFF_SECTION.PtrReloc], edi
1136
        mov     [edx+COFF_SECTION.PtrReloc], edi
1143
        sub     [edx+COFF_SECTION.PtrReloc], ebx
1137
        sub     [edx+COFF_SECTION.PtrReloc], ebx
1144
        add     esi, [coff]
1138
        add     esi, [coff]
1145
        shr     ecx, 1
1139
        shr     ecx, 1
1146
        rep movsd
1140
        rep movsd
1147
        adc     ecx, ecx
1141
        adc     ecx, ecx
1148
        rep movsw
1142
        rep movsw
1149
        add     edx, sizeof.COFF_SECTION
1143
        add     edx, sizeof.COFF_SECTION
1150
        dec     eax
1144
        dec     eax
1151
        jnz     @b
1145
        jnz     @b
1152
        pop     esi
1146
        pop     esi
1153
 
1147
 
1154
; fixup symbols
1148
; fixup symbols
1155
        mov     edx, ebx
1149
        mov     edx, ebx
1156
        mov     eax, [ebx+COFF_HEADER.nSymbols]
1150
        mov     eax, [ebx+COFF_HEADER.nSymbols]
1157
        add     edx, 20
1151
        add     edx, 20
1158
        mov     ecx, [esi+DLLDESCR.symbols_num]
1152
        mov     ecx, [esi+DLLDESCR.symbols_num]
1159
        lea     ecx, [ecx*9]
1153
        lea     ecx, [ecx*9]
1160
        add     ecx, ecx
1154
        add     ecx, ecx
1161
        add     ecx, [esi+DLLDESCR.symbols_ptr]
1155
        add     ecx, [esi+DLLDESCR.symbols_ptr]
1162
 
1156
 
1163
        stdcall fix_coff_symbols, edx, [esi+DLLDESCR.symbols_ptr], eax, \
1157
        stdcall fix_coff_symbols, edx, [esi+DLLDESCR.symbols_ptr], eax, \
1164
                ecx, 0
1158
                ecx, 0
1165
;          test eax, eax
1159
;          test eax, eax
1166
;          jnz @F
1160
;          jnz @F
1167
;
1161
;
1168
;@@:
1162
;@@:
1169
 
1163
 
1170
        stdcall get_coff_sym, [esi+DLLDESCR.symbols_ptr], [ebx+COFF_HEADER.nSymbols], szEXPORTS
1164
        stdcall get_coff_sym, [esi+DLLDESCR.symbols_ptr], [ebx+COFF_HEADER.nSymbols], szEXPORTS
1171
        test    eax, eax
1165
        test    eax, eax
1172
        jnz     @F
1166
        jnz     @F
1173
 
1167
 
1174
        stdcall get_coff_sym, [esi+DLLDESCR.symbols_ptr], [ebx+COFF_HEADER.nSymbols], sz_EXPORTS
1168
        stdcall get_coff_sym, [esi+DLLDESCR.symbols_ptr], [ebx+COFF_HEADER.nSymbols], sz_EXPORTS
1175
@@:
1169
@@:
1176
        mov     [esi+DLLDESCR.exports], eax
1170
        mov     [esi+DLLDESCR.exports], eax
1177
 
1171
 
1178
; fix relocs in the hidden copy in kernel memory to default address
1172
; fix relocs in the hidden copy in kernel memory to default address
1179
; it is first fix; usually this will be enough, but second fix
1173
; it is first fix; usually this will be enough, but second fix
1180
; can be necessary if real load address will not equal assumption
1174
; can be necessary if real load address will not equal assumption
1181
        mov     eax, [esi+DLLDESCR.data]
1175
        mov     eax, [esi+DLLDESCR.data]
1182
        sub     eax, [esi+DLLDESCR.defaultbase]
1176
        sub     eax, [esi+DLLDESCR.defaultbase]
1183
        stdcall fix_coff_relocs, ebx, [esi+DLLDESCR.symbols_ptr], eax
1177
        stdcall fix_coff_relocs, ebx, [esi+DLLDESCR.symbols_ptr], eax
1184
 
1178
 
1185
        stdcall kernel_free, [coff]
1179
        stdcall kernel_free, [coff]
1186
 
1180
 
1187
        cli
1181
        cli
1188
; initialize DLLDESCR struct
1182
; initialize DLLDESCR struct
1189
        and     dword [esi+DLLDESCR.refcount], 0; no HDLLs yet; later it will be incremented
1183
        and     dword [esi+DLLDESCR.refcount], 0; no HDLLs yet; later it will be incremented
1190
        mov     [esi+DLLDESCR.fd], dll_list
1184
        mov     [esi+DLLDESCR.fd], dll_list
1191
        mov     eax, [dll_list.bk]
1185
        mov     eax, [dll_list.bk]
1192
        mov     [dll_list.bk], esi
1186
        mov     [dll_list.bk], esi
1193
        mov     [esi+DLLDESCR.bk], eax
1187
        mov     [esi+DLLDESCR.bk], eax
1194
        mov     [eax+DLLDESCR.fd], esi
1188
        mov     [eax+DLLDESCR.fd], esi
1195
.dll_already_loaded:
1189
.dll_already_loaded:
1196
        stdcall kernel_free, [fullname]
1190
        stdcall kernel_free, [fullname]
1197
        inc     [esi+DLLDESCR.refcount]
1191
        inc     [esi+DLLDESCR.refcount]
1198
        push    esi
1192
        push    esi
1199
        call    init_heap
1193
        call    init_heap
1200
        pop     esi
1194
        pop     esi
1201
        mov     edi, [esi+DLLDESCR.size]
1195
        mov     edi, [esi+DLLDESCR.size]
1202
        stdcall user_alloc_at, [esi+DLLDESCR.defaultbase], edi
1196
        stdcall user_alloc_at, [esi+DLLDESCR.defaultbase], edi
1203
        test    eax, eax
1197
        test    eax, eax
1204
        jnz     @f
1198
        jnz     @f
1205
        stdcall user_alloc, edi
1199
        stdcall user_alloc, edi
1206
        test    eax, eax
1200
        test    eax, eax
1207
        jz      .fail_and_dereference
1201
        jz      .fail_and_dereference
1208
@@:
1202
@@:
1209
        mov     [img_base], eax
1203
        mov     [img_base], eax
1210
        mov     eax, sizeof.HDLL
1204
        mov     eax, sizeof.HDLL
1211
        call    malloc
1205
        call    malloc
1212
        test    eax, eax
1206
        test    eax, eax
1213
        jz      .fail_and_free_user
1207
        jz      .fail_and_free_user
1214
        mov     ebx, [current_slot_idx]
1208
        mov     ebx, [current_slot_idx]
1215
        shl     ebx, 5
1209
        shl     ebx, 5
1216
        mov     edx, [TASK_TABLE+ebx+TASKDATA.pid]
1210
        mov     edx, [TASK_TABLE+ebx+TASKDATA.pid]
1217
        mov     [eax+HDLL.pid], edx
1211
        mov     [eax+HDLL.pid], edx
1218
        push    eax
1212
        push    eax
1219
        call    init_dlls_in_thread
1213
        call    init_dlls_in_thread
1220
        pop     ebx
1214
        pop     ebx
1221
        test    eax, eax
1215
        test    eax, eax
1222
        jz      .fail_and_free_user
1216
        jz      .fail_and_free_user
1223
        mov     edx, [eax+HDLL.fd]
1217
        mov     edx, [eax+HDLL.fd]
1224
        mov     [ebx+HDLL.fd], edx
1218
        mov     [ebx+HDLL.fd], edx
1225
        mov     [ebx+HDLL.bk], eax
1219
        mov     [ebx+HDLL.bk], eax
1226
        mov     [eax+HDLL.fd], ebx
1220
        mov     [eax+HDLL.fd], ebx
1227
        mov     [edx+HDLL.bk], ebx
1221
        mov     [edx+HDLL.bk], ebx
1228
        mov     eax, ebx
1222
        mov     eax, ebx
1229
        mov     ebx, [img_base]
1223
        mov     ebx, [img_base]
1230
        mov     [eax+HDLL.base], ebx
1224
        mov     [eax+HDLL.base], ebx
1231
        mov     [eax+HDLL.size], edi
1225
        mov     [eax+HDLL.size], edi
1232
        mov     [eax+HDLL.refcount], 1
1226
        mov     [eax+HDLL.refcount], 1
1233
        mov     [eax+HDLL.parent], esi
1227
        mov     [eax+HDLL.parent], esi
1234
        mov     edx, ebx
1228
        mov     edx, ebx
1235
        shr     edx, 12
1229
        shr     edx, 12
1236
        or      dword [page_tabs+(edx-1)*4], MEM_BLOCK_DONT_FREE
1230
        or      dword [page_tabs+(edx-1)*4], MEM_BLOCK_DONT_FREE
1237
; copy entries of page table from kernel-side image to usermode
1231
; copy entries of page table from kernel-side image to usermode
1238
; use copy-on-write for user-mode image, so map as readonly
1232
; use copy-on-write for user-mode image, so map as readonly
1239
        xor     edi, edi
1233
        xor     edi, edi
1240
        mov     ecx, [esi+DLLDESCR.data]
1234
        mov     ecx, [esi+DLLDESCR.data]
1241
        shr     ecx, 12
1235
        shr     ecx, 12
1242
.map_pages_loop:
1236
.map_pages_loop:
1243
        mov     eax, [page_tabs+ecx*4]
1237
        mov     eax, [page_tabs+ecx*4]
1244
        and     eax, not 0xFFF
1238
        and     eax, not 0xFFF
1245
        or      al, PG_UR
1239
        or      al, PG_UR
1246
        xchg    eax, [page_tabs+edx*4]
1240
        xchg    eax, [page_tabs+edx*4]
1247
        test    al, 1
1241
        test    al, 1
1248
        jz      @f
1242
        jz      @f
1249
        call    free_page
1243
        call    free_page
1250
@@:
1244
@@:
1251
        invlpg  [ebx+edi]
1245
        invlpg  [ebx+edi]
1252
        inc     ecx
1246
        inc     ecx
1253
        inc     edx
1247
        inc     edx
1254
        add     edi, 0x1000
1248
        add     edi, 0x1000
1255
        cmp     edi, [esi+DLLDESCR.size]
1249
        cmp     edi, [esi+DLLDESCR.size]
1256
        jb      .map_pages_loop
1250
        jb      .map_pages_loop
1257
 
1251
 
1258
; if real user-mode base is not equal to preferred base, relocate image
1252
; if real user-mode base is not equal to preferred base, relocate image
1259
        sub     ebx, [esi+DLLDESCR.defaultbase]
1253
        sub     ebx, [esi+DLLDESCR.defaultbase]
1260
        jz      @f
1254
        jz      @f
1261
        stdcall rebase_coff, [esi+DLLDESCR.coff_hdr], [esi+DLLDESCR.symbols_ptr], ebx
1255
        stdcall rebase_coff, [esi+DLLDESCR.coff_hdr], [esi+DLLDESCR.symbols_ptr], ebx
1262
@@:
1256
@@:
1263
 
1257
 
1264
        mov     eax, [esi+DLLDESCR.exports]
1258
        mov     eax, [esi+DLLDESCR.exports]
1265
        sub     eax, [esi+DLLDESCR.defaultbase]
1259
        sub     eax, [esi+DLLDESCR.defaultbase]
1266
        add     eax, [img_base]
1260
        add     eax, [img_base]
1267
        sti
1261
        sti
1268
        ret
1262
        ret
1269
 
1263
 
1270
.fail_and_free_data:
1264
.fail_and_free_data:
1271
        stdcall kernel_free, [esi+DLLDESCR.data]
1265
        stdcall kernel_free, [esi+DLLDESCR.data]
1272
.fail_and_free_dll:
1266
.fail_and_free_dll:
1273
        mov     eax, esi
1267
        mov     eax, esi
1274
        call    free
1268
        call    free
1275
.fail_and_free_coff:
1269
.fail_and_free_coff:
1276
        stdcall kernel_free, [coff]
1270
        stdcall kernel_free, [coff]
1277
.fail:
1271
.fail:
1278
        stdcall kernel_free, [fullname]
1272
        stdcall kernel_free, [fullname]
1279
        xor     eax, eax
1273
        xor     eax, eax
1280
        ret
1274
        ret
1281
 
1275
 
1282
.fail_and_free_user:
1276
.fail_and_free_user:
1283
        stdcall user_free, [img_base]
1277
        stdcall user_free, [img_base]
1284
.fail_and_dereference:
1278
.fail_and_dereference:
1285
        mov     eax, 1  ; delete 1 reference
1279
        mov     eax, 1  ; delete 1 reference
1286
        call    dereference_dll
1280
        call    dereference_dll
1287
        sti
1281
        sti
1288
        xor     eax, eax
1282
        xor     eax, eax
1289
        ret
1283
        ret
1290
endp
1284
endp
1291
 
1285
 
1292
; initialize [APPDATA.dlls_list_ptr] for given thread
1286
; initialize [APPDATA.dlls_list_ptr] for given thread
1293
; DLL is per-process object, so APPDATA.dlls_list_ptr must be
1287
; DLL is per-process object, so APPDATA.dlls_list_ptr must be
1294
; kept in sync for all threads of one process.
1288
; kept in sync for all threads of one process.
1295
; out: eax = APPDATA.dlls_list_ptr if all is OK,
1289
; out: eax = APPDATA.dlls_list_ptr if all is OK,
1296
; NULL if memory allocation failed
1290
; NULL if memory allocation failed
1297
init_dlls_in_thread:
1291
init_dlls_in_thread:
1298
        mov     ebx, [current_process]
1292
        mov     ebx, [current_process]
1299
        mov     eax, [ebx+PROC.dlls_list_ptr]
1293
        mov     eax, [ebx+PROC.dlls_list_ptr]
1300
        test    eax, eax
1294
        test    eax, eax
1301
        jnz     .ret
1295
        jnz     .ret
1302
 
1296
 
1303
        mov     eax, 8
1297
        mov     eax, 8
1304
        call    malloc                               ; FIXME
1298
        call    malloc                               ; FIXME
1305
        test    eax, eax
1299
        test    eax, eax
1306
        jz      .ret
1300
        jz      .ret
1307
 
1301
 
1308
        mov     [eax], eax
1302
        mov     [eax], eax
1309
        mov     [eax+4], eax
1303
        mov     [eax+4], eax
1310
 
1304
 
1311
        mov     ebx, [current_process]
1305
        mov     ebx, [current_process]
1312
        mov     [ebx+PROC.dlls_list_ptr], eax
1306
        mov     [ebx+PROC.dlls_list_ptr], eax
1313
.ret:
1307
.ret:
1314
        ret
1308
        ret
1315
 
1309
 
1316
; in: eax = number of references to delete, esi -> DLLDESCR struc
1310
; in: eax = number of references to delete, esi -> DLLDESCR struc
1317
dereference_dll:
1311
dereference_dll:
1318
        sub     [esi+DLLDESCR.refcount], eax
1312
        sub     [esi+DLLDESCR.refcount], eax
1319
        jnz     .ret
1313
        jnz     .ret
1320
        mov     eax, [esi+DLLDESCR.fd]
1314
        mov     eax, [esi+DLLDESCR.fd]
1321
        mov     edx, [esi+DLLDESCR.bk]
1315
        mov     edx, [esi+DLLDESCR.bk]
1322
        mov     [eax+DLLDESCR.bk], edx
1316
        mov     [eax+DLLDESCR.bk], edx
1323
        mov     [edx+DLLDESCR.fd], eax
1317
        mov     [edx+DLLDESCR.fd], eax
1324
        stdcall kernel_free, [esi+DLLDESCR.coff_hdr]
1318
        stdcall kernel_free, [esi+DLLDESCR.coff_hdr]
1325
        stdcall kernel_free, [esi+DLLDESCR.data]
1319
        stdcall kernel_free, [esi+DLLDESCR.data]
1326
        mov     eax, esi
1320
        mov     eax, esi
1327
        call    free
1321
        call    free
1328
.ret:
1322
.ret:
1329
        ret
1323
        ret
1330
 
1324
 
1331
destroy_hdll:
1325
destroy_hdll:
1332
        push    ebx ecx esi edi
1326
        push    ebx ecx esi edi
1333
        mov     ebx, [eax+HDLL.base]
1327
        mov     ebx, [eax+HDLL.base]
1334
        mov     esi, [eax+HDLL.parent]
1328
        mov     esi, [eax+HDLL.parent]
1335
        mov     edx, [esi+DLLDESCR.size]
1329
        mov     edx, [esi+DLLDESCR.size]
1336
 
1330
 
1337
        push    eax
1331
        push    eax
1338
        mov     esi, [eax+HDLL.parent]
1332
        mov     esi, [eax+HDLL.parent]
1339
        mov     eax, [eax+HDLL.refcount]
1333
        mov     eax, [eax+HDLL.refcount]
1340
        call    dereference_dll
1334
        call    dereference_dll
1341
        pop     eax
1335
        pop     eax
1342
        mov     edx, [eax+HDLL.bk]
1336
        mov     edx, [eax+HDLL.bk]
1343
        mov     ebx, [eax+HDLL.fd]
1337
        mov     ebx, [eax+HDLL.fd]
1344
        mov     [ebx+HDLL.bk], edx
1338
        mov     [ebx+HDLL.bk], edx
1345
        mov     [edx+HDLL.fd], ebx
1339
        mov     [edx+HDLL.fd], ebx
1346
        call    free
1340
        call    free
1347
        pop     edi esi ecx ebx
1341
        pop     edi esi ecx ebx
1348
        ret
1342
        ret
1349
 
1343
 
1350
; ecx -> APPDATA for slot, esi = dlls_list_ptr
1344
; ecx -> APPDATA for slot, esi = dlls_list_ptr
1351
destroy_all_hdlls:
1345
destroy_all_hdlls:
1352
        test    esi, esi
1346
        test    esi, esi
1353
        jz      .ret
1347
        jz      .ret
1354
.loop:
1348
.loop:
1355
        mov     eax, [esi+HDLL.fd]
1349
        mov     eax, [esi+HDLL.fd]
1356
        cmp     eax, esi
1350
        cmp     eax, esi
1357
        jz      free
1351
        jz      free
1358
        call    destroy_hdll
1352
        call    destroy_hdll
1359
        jmp     .loop
1353
        jmp     .loop
1360
.ret:
1354
.ret:
1361
        ret
1355
        ret
1362
 
1356
 
1363
align 4
1357
align 4
1364
stop_all_services:
1358
stop_all_services:
1365
        push    ebp
1359
        push    ebp
1366
        mov     edx, [srv.fd]
1360
        mov     edx, [srv.fd]
1367
.next:
1361
.next:
1368
        cmp     edx, srv.fd-SRV.fd
1362
        cmp     edx, srv.fd-SRV.fd
1369
        je      .done
1363
        je      .done
1370
        cmp     [edx+SRV.magic], ' SRV'
1364
        cmp     [edx+SRV.magic], ' SRV'
1371
        jne     .next
1365
        jne     .next
1372
        cmp     [edx+SRV.size], sizeof.SRV
1366
        cmp     [edx+SRV.size], sizeof.SRV
1373
        jne     .next
1367
        jne     .next
1374
 
1368
 
1375
        mov     ebx, [edx+SRV.entry]
1369
        mov     ebx, [edx+SRV.entry]
1376
        mov     edx, [edx+SRV.fd]
1370
        mov     edx, [edx+SRV.fd]
1377
        test    ebx, ebx
1371
        test    ebx, ebx
1378
        jz      .next
1372
        jz      .next
1379
 
1373
 
1380
        push    edx
1374
        push    edx
1381
        mov     ebp, esp
1375
        mov     ebp, esp
1382
        push    0
1376
        push    0
1383
        push    -1
1377
        push    -1
1384
        call    ebx
1378
        call    ebx
1385
        mov     esp, ebp
1379
        mov     esp, ebp
1386
        pop     edx
1380
        pop     edx
1387
        jmp     .next
1381
        jmp     .next
1388
.done:
1382
.done:
1389
        pop     ebp
1383
        pop     ebp
1390
        ret
1384
        ret
1391
 
1385
 
1392
; param
1386
; param
1393
;  eax= size
1387
;  eax= size
1394
;  ebx= pid
1388
;  ebx= pid
1395
 
1389
 
1396
align 4
1390
align 4
1397
create_kernel_object:
1391
create_kernel_object:
1398
 
1392
 
1399
        push    ebx
1393
        push    ebx
1400
        call    malloc
1394
        call    malloc
1401
        pop     ebx
1395
        pop     ebx
1402
        test    eax, eax
1396
        test    eax, eax
1403
        jz      .fail
1397
        jz      .fail
1404
 
1398
 
1405
        mov     ecx, [current_slot]
1399
        mov     ecx, [current_slot]
1406
        add     ecx, APP_OBJ_OFFSET
1400
        add     ecx, APP_OBJ_OFFSET
1407
 
1401
 
1408
        pushfd
1402
        pushfd
1409
        cli
1403
        cli
1410
        mov     edx, [ecx+APPOBJ.fd]
1404
        mov     edx, [ecx+APPOBJ.fd]
1411
        mov     [eax+APPOBJ.fd], edx
1405
        mov     [eax+APPOBJ.fd], edx
1412
        mov     [eax+APPOBJ.bk], ecx
1406
        mov     [eax+APPOBJ.bk], ecx
1413
        mov     [eax+APPOBJ.pid], ebx
1407
        mov     [eax+APPOBJ.pid], ebx
1414
 
1408
 
1415
        mov     [ecx+APPOBJ.fd], eax
1409
        mov     [ecx+APPOBJ.fd], eax
1416
        mov     [edx+APPOBJ.bk], eax
1410
        mov     [edx+APPOBJ.bk], eax
1417
        popfd
1411
        popfd
1418
.fail:
1412
.fail:
1419
        ret
1413
        ret
1420
 
1414
 
1421
; param
1415
; param
1422
;  eax= object
1416
;  eax= object
1423
 
1417
 
1424
align 4
1418
align 4
1425
destroy_kernel_object:
1419
destroy_kernel_object:
1426
 
1420
 
1427
        pushfd
1421
        pushfd
1428
        cli
1422
        cli
1429
        mov     ebx, [eax+APPOBJ.fd]
1423
        mov     ebx, [eax+APPOBJ.fd]
1430
        mov     ecx, [eax+APPOBJ.bk]
1424
        mov     ecx, [eax+APPOBJ.bk]
1431
        mov     [ebx+APPOBJ.bk], ecx
1425
        mov     [ebx+APPOBJ.bk], ecx
1432
        mov     [ecx+APPOBJ.fd], ebx
1426
        mov     [ecx+APPOBJ.fd], ebx
1433
        popfd
1427
        popfd
1434
 
1428
 
1435
        xor     edx, edx       ;clear common header
1429
        xor     edx, edx       ;clear common header
1436
        mov     [eax], edx
1430
        mov     [eax], edx
1437
        mov     [eax+4], edx
1431
        mov     [eax+4], edx
1438
        mov     [eax+8], edx
1432
        mov     [eax+8], edx
1439
        mov     [eax+12], edx
1433
        mov     [eax+12], edx
1440
        mov     [eax+16], edx
1434
        mov     [eax+16], edx
1441
 
1435
 
1442
        call    free           ;release object memory
1436
        call    free           ;release object memory
1443
        ret
1437
        ret
1444
 
1438
 
1445
 
1439
 
1446
;void* __fastcall create_object(size_t size)
1440
;void* __fastcall create_object(size_t size)
1447
; param
1441
; param
1448
;  ecx= size
1442
;  ecx= size
1449
 
1443
 
1450
align 4
1444
align 4
1451
create_object:
1445
create_object:
1452
 
1446
 
1453
        push    esi
1447
        push    esi
1454
        push    edi
1448
        push    edi
1455
        pushfd
1449
        pushfd
1456
        cli
1450
        cli
1457
 
1451
 
1458
        mov     esi, [current_process]
1452
        mov     esi, [current_process]
1459
        mov     eax, [esi+PROC.ht_free]
1453
        mov     eax, [esi+PROC.ht_free]
1460
        mov     edi, [esi+PROC.ht_next]
1454
        mov     edi, [esi+PROC.ht_next]
1461
        dec     eax
1455
        dec     eax
1462
        js      .err0
1456
        js      .err0
1463
 
1457
 
1464
        mov     [esi+PROC.ht_free], eax
1458
        mov     [esi+PROC.ht_free], eax
1465
        mov     eax, [esi+PROC.htab+edi*4]
1459
        mov     eax, [esi+PROC.htab+edi*4]
1466
        mov     [esi+PROC.ht_next], eax
1460
        mov     [esi+PROC.ht_next], eax
1467
        popfd
1461
        popfd
1468
 
1462
 
1469
        mov     eax, ecx
1463
        mov     eax, ecx
1470
        call    malloc
1464
        call    malloc
1471
        test    eax, eax
1465
        test    eax, eax
1472
        jz      .err1
1466
        jz      .err1
1473
 
1467
 
1474
        mov     [eax+FUTEX.handle], edi
1468
        mov     [eax+FUTEX.handle], edi
1475
        mov     [esi+PROC.htab+edi*4], eax
1469
        mov     [esi+PROC.htab+edi*4], eax
1476
        pop     edi
1470
        pop     edi
1477
        pop     esi
1471
        pop     esi
1478
        ret
1472
        ret
1479
 
1473
 
1480
.err1:
1474
.err1:
1481
        pushfd
1475
        pushfd
1482
        cli
1476
        cli
1483
 
1477
 
1484
        mov     eax, [esi+PROC.ht_next]
1478
        mov     eax, [esi+PROC.ht_next]
1485
        mov     [esi+PROC.htab+edi*4], eax
1479
        mov     [esi+PROC.htab+edi*4], eax
1486
        mov     [esi+PROC.ht_next], edi
1480
        mov     [esi+PROC.ht_next], edi
1487
        inc     [esi+PROC.ht_free]
1481
        inc     [esi+PROC.ht_free]
1488
.err0:
1482
.err0:
1489
        popfd
1483
        popfd
1490
        pop     edi
1484
        pop     edi
1491
        pop     esi
1485
        pop     esi
1492
        xor     eax, eax
1486
        xor     eax, eax
1493
        ret
1487
        ret
1494
 
1488
 
1495
 
1489
 
1496
;int __fastcall destroy_object(struct object *obj)
1490
;int __fastcall destroy_object(struct object *obj)
1497
 
1491
 
1498
align 4
1492
align 4
1499
destroy_object:
1493
destroy_object:
1500
        push    esi
1494
        push    esi
1501
        mov     esi, [current_process]
1495
        mov     esi, [current_process]
1502
        mov     edx, [ecx+FUTEX.handle]
1496
        mov     edx, [ecx+FUTEX.handle]
1503
 
1497
 
1504
        pushfd
1498
        pushfd
1505
        cli
1499
        cli
1506
 
1500
 
1507
        mov     eax, [esi+PROC.ht_next]
1501
        mov     eax, [esi+PROC.ht_next]
1508
        mov     [esi+PROC.htab+edx*4], eax
1502
        mov     [esi+PROC.htab+edx*4], eax
1509
        mov     [esi+PROC.ht_next], edx
1503
        mov     [esi+PROC.ht_next], edx
1510
        inc     [esi+PROC.ht_free]
1504
        inc     [esi+PROC.ht_free]
1511
 
1505
 
1512
        popfd
1506
        popfd
1513
        pop     esi
1507
        pop     esi
1514
 
1508
 
1515
        mov     eax, ecx
1509
        mov     eax, ecx
1516
        call    free
1510
        call    free
1517
        xor     eax, eax
1511
        xor     eax, eax
1518
        ret
1512
        ret
1519
.fail:
1513
.fail:
1520
        popfd
1514
        popfd
1521
        pop     esi
1515
        pop     esi
1522
        mov     eax, -1
1516
        mov     eax, -1
1523
        ret
1517
        ret