Subversion Repositories Kolibri OS

Rev

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

Rev 4418 Rev 5039
1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                              ;;
2
;;                                                              ;;
3
;; Copyright (C) KolibriOS team 2004-2012. All rights reserved. ;;
3
;; Copyright (C) KolibriOS team 2004-2012. 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: 4418 $
8
$Revision: 5039 $
9
 
9
 
10
 
10
 
11
DRV_COMPAT   equ  5  ;minimal required drivers version
11
DRV_COMPAT   equ  5  ;minimal required drivers version
12
DRV_CURRENT  equ  6  ;current drivers model version
12
DRV_CURRENT  equ  6  ;current drivers model version
13
 
13
 
14
DRV_VERSION equ (DRV_COMPAT shl 16) or DRV_CURRENT
14
DRV_VERSION equ (DRV_COMPAT shl 16) or DRV_CURRENT
15
PID_KERNEL  equ 1    ;os_idle thread
15
PID_KERNEL  equ 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
        je      .ok
212
        je      .ok
213
 
213
 
214
        mov     edx, [edx+SRV.fd]
214
        mov     edx, [edx+SRV.fd]
215
        jmp     @B
215
        jmp     @B
216
.not_load:
216
.not_load:
217
        mov     eax, [sz_name]
217
        mov     eax, [sz_name]
218
; Try to load .dll driver first. If not, fallback to .obj.
218
; Try to load .dll driver first. If not, fallback to .obj.
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
        test    eax, eax
239
        test    eax, eax
240
        jnz     .nothing
240
        jnz     .nothing
241
        pop     ebp
241
        pop     ebp
242
        jmp     load_driver
242
        jmp     load_driver
243
.ok:
243
.ok:
244
        mov     eax, edx
244
        mov     eax, edx
245
.nothing:
245
.nothing:
246
        ret
246
        ret
247
endp
247
endp
248
 
248
 
249
reg_service:
249
reg_service:
250
        xor     eax, eax
250
        xor     eax, eax
251
        mov     ecx, [esp+8]
251
        mov     ecx, [esp+8]
252
        jecxz   .nothing
252
        jecxz   .nothing
253
        push    sizeof.SRV
253
        push    sizeof.SRV
254
        push    ecx
254
        push    ecx
255
        pushd   [esp+12]
255
        pushd   [esp+12]
256
        call    reg_service_ex
256
        call    reg_service_ex
257
.nothing:
257
.nothing:
258
        ret     8
258
        ret     8
259
 
259
 
260
reg_usb_driver:
260
reg_usb_driver:
261
        push    sizeof.USBSRV
261
        push    sizeof.USBSRV
262
        pushd   [esp+12]
262
        pushd   [esp+12]
263
        pushd   [esp+12]
263
        pushd   [esp+12]
264
        call    reg_service_ex
264
        call    reg_service_ex
265
        test    eax, eax
265
        test    eax, eax
266
        jz      .nothing
266
        jz      .nothing
267
        mov     ecx, [esp+12]
267
        mov     ecx, [esp+12]
268
        mov     [eax+USBSRV.usb_func], ecx
268
        mov     [eax+USBSRV.usb_func], ecx
269
.nothing:
269
.nothing:
270
        ret     12
270
        ret     12
271
 
271
 
272
proc reg_service_ex stdcall, name:dword, handler:dword, srvsize:dword
272
proc reg_service_ex stdcall, name:dword, handler:dword, srvsize:dword
273
 
273
 
274
        push    ebx
274
        push    ebx
275
 
275
 
276
        xor     eax, eax
276
        xor     eax, eax
277
 
277
 
278
        cmp     [name], eax
278
        cmp     [name], eax
279
        je      .fail
279
        je      .fail
280
 
280
 
281
;        cmp     [handler], eax
281
;        cmp     [handler], eax
282
;        je      .fail
282
;        je      .fail
283
 
283
 
284
        mov     eax, [srvsize]
284
        mov     eax, [srvsize]
285
        call    malloc
285
        call    malloc
286
        test    eax, eax
286
        test    eax, eax
287
        jz      .fail
287
        jz      .fail
288
 
288
 
289
        push    esi
289
        push    esi
290
        push    edi
290
        push    edi
291
        mov     edi, eax
291
        mov     edi, eax
292
        mov     esi, [name]
292
        mov     esi, [name]
293
        movsd
293
        movsd
294
        movsd
294
        movsd
295
        movsd
295
        movsd
296
        movsd
296
        movsd
297
        pop     edi
297
        pop     edi
298
        pop     esi
298
        pop     esi
299
 
299
 
300
        mov     [eax+SRV.magic], ' SRV'
300
        mov     [eax+SRV.magic], ' SRV'
301
        mov     [eax+SRV.size], sizeof.SRV
301
        mov     [eax+SRV.size], sizeof.SRV
302
 
302
 
303
        mov     ebx, srv.fd-SRV.fd
303
        mov     ebx, srv.fd-SRV.fd
304
        mov     edx, [ebx+SRV.fd]
304
        mov     edx, [ebx+SRV.fd]
305
        mov     [eax+SRV.fd], edx
305
        mov     [eax+SRV.fd], edx
306
        mov     [eax+SRV.bk], ebx
306
        mov     [eax+SRV.bk], ebx
307
        mov     [ebx+SRV.fd], eax
307
        mov     [ebx+SRV.fd], eax
308
        mov     [edx+SRV.bk], eax
308
        mov     [edx+SRV.bk], eax
309
 
309
 
310
        mov     ecx, [handler]
310
        mov     ecx, [handler]
311
        mov     [eax+SRV.srv_proc], ecx
311
        mov     [eax+SRV.srv_proc], ecx
312
        pop     ebx
312
        pop     ebx
313
        ret
313
        ret
314
.fail:
314
.fail:
315
        xor     eax, eax
315
        xor     eax, eax
316
        pop     ebx
316
        pop     ebx
317
        ret
317
        ret
318
endp
318
endp
319
 
319
 
320
align 4
320
align 4
321
proc get_proc stdcall, exp:dword, sz_name:dword
321
proc get_proc stdcall, exp:dword, sz_name:dword
322
 
322
 
323
        mov     edx, [exp]
323
        mov     edx, [exp]
324
.next:
324
.next:
325
        mov     eax, [edx]
325
        mov     eax, [edx]
326
        test    eax, eax
326
        test    eax, eax
327
        jz      .end
327
        jz      .end
328
 
328
 
329
        push    edx
329
        push    edx
330
        stdcall strncmp, eax, [sz_name], 16
330
        stdcall strncmp, eax, [sz_name], 16
331
        pop     edx
331
        pop     edx
332
        test    eax, eax
332
        test    eax, eax
333
        jz      .ok
333
        jz      .ok
334
 
334
 
335
        add     edx, 8
335
        add     edx, 8
336
        jmp     .next
336
        jmp     .next
337
.ok:
337
.ok:
338
        mov     eax, [edx+4]
338
        mov     eax, [edx+4]
339
.end:
339
.end:
340
        ret
340
        ret
341
endp
341
endp
342
 
342
 
343
align 4
343
align 4
344
proc get_coff_sym stdcall, pSym:dword,count:dword, sz_sym:dword
344
proc get_coff_sym stdcall, pSym:dword,count:dword, sz_sym:dword
345
 
345
 
346
@@:
346
@@:
347
        stdcall strncmp, [pSym], [sz_sym], 8
347
        stdcall strncmp, [pSym], [sz_sym], 8
348
        test    eax, eax
348
        test    eax, eax
349
        jz      .ok
349
        jz      .ok
350
        add     [pSym], 18
350
        add     [pSym], 18
351
        dec     [count]
351
        dec     [count]
352
        jnz     @b
352
        jnz     @b
353
        xor     eax, eax
353
        xor     eax, eax
354
        ret
354
        ret
355
.ok:
355
.ok:
356
        mov     eax, [pSym]
356
        mov     eax, [pSym]
357
        mov     eax, [eax+8]
357
        mov     eax, [eax+8]
358
        ret
358
        ret
359
endp
359
endp
360
 
360
 
361
align 4
361
align 4
362
proc get_curr_task
362
proc get_curr_task
363
        mov     eax, [CURRENT_TASK]
363
        mov     eax, [CURRENT_TASK]
364
        shl     eax, 8
364
        shl     eax, 8
365
        ret
365
        ret
366
endp
366
endp
367
 
367
 
368
align 4
368
align 4
369
proc get_fileinfo stdcall, file_name:dword, info:dword
369
proc get_fileinfo stdcall, file_name:dword, info:dword
370
           locals
370
           locals
371
             cmd     dd ?
371
             cmd     dd ?
372
             offset  dd ?
372
             offset  dd ?
373
                     dd ?
373
                     dd ?
374
             count   dd ?
374
             count   dd ?
375
             buff    dd ?
375
             buff    dd ?
376
                     db ?
376
                     db ?
377
             name    dd ?
377
             name    dd ?
378
           endl
378
           endl
379
 
379
 
380
        xor     eax, eax
380
        xor     eax, eax
381
        mov     ebx, [file_name]
381
        mov     ebx, [file_name]
382
        mov     ecx, [info]
382
        mov     ecx, [info]
383
 
383
 
384
        mov     [cmd], 5
384
        mov     [cmd], 5
385
        mov     [offset], eax
385
        mov     [offset], eax
386
        mov     [offset+4], eax
386
        mov     [offset+4], eax
387
        mov     [count], eax
387
        mov     [count], eax
388
        mov     [buff], ecx
388
        mov     [buff], ecx
389
        mov     byte [buff+4], al
389
        mov     byte [buff+4], al
390
        mov     [name], ebx
390
        mov     [name], ebx
391
 
391
 
392
        mov     eax, 70
392
        mov     eax, 70
393
        lea     ebx, [cmd]
393
        lea     ebx, [cmd]
394
        int     0x40
394
        int     0x40
395
        ret
395
        ret
396
endp
396
endp
397
 
397
 
398
align 4
398
align 4
399
proc read_file stdcall,file_name:dword, buffer:dword, off:dword,\
399
proc read_file stdcall,file_name:dword, buffer:dword, off:dword,\
400
                                     bytes:dword
400
                                     bytes:dword
401
           locals
401
           locals
402
             cmd     dd ?
402
             cmd     dd ?
403
             offset  dd ?
403
             offset  dd ?
404
                     dd ?
404
                     dd ?
405
             count   dd ?
405
             count   dd ?
406
             buff    dd ?
406
             buff    dd ?
407
                     db ?
407
                     db ?
408
             name    dd ?
408
             name    dd ?
409
           endl
409
           endl
410
 
410
 
411
        xor     eax, eax
411
        xor     eax, eax
412
        mov     ebx, [file_name]
412
        mov     ebx, [file_name]
413
        mov     ecx, [off]
413
        mov     ecx, [off]
414
        mov     edx, [bytes]
414
        mov     edx, [bytes]
415
        mov     esi, [buffer]
415
        mov     esi, [buffer]
416
 
416
 
417
        mov     [cmd], eax
417
        mov     [cmd], eax
418
        mov     [offset], ecx
418
        mov     [offset], ecx
419
        mov     [offset+4], eax
419
        mov     [offset+4], eax
420
        mov     [count], edx
420
        mov     [count], edx
421
        mov     [buff], esi
421
        mov     [buff], esi
422
        mov     byte [buff+4], al
422
        mov     byte [buff+4], al
423
        mov     [name], ebx
423
        mov     [name], ebx
424
 
424
 
425
        pushad
425
        pushad
426
        lea     ebx, [cmd]
426
        lea     ebx, [cmd]
427
        call    file_system_lfn_protected
427
        call    file_system_lfn_protected
428
        popad
428
        popad
429
        ret
429
        ret
430
endp
430
endp
431
 
431
 
432
; description
432
; description
433
;  allocate kernel memory and loads the specified file
433
;  allocate kernel memory and loads the specified file
434
;
434
;
435
; param
435
; param
436
;  file_name= path to file
436
;  file_name= path to file
437
;
437
;
438
; retval
438
; retval
439
;  eax= file image in kernel memory
439
;  eax= file image in kernel memory
440
;  ebx= size of file
440
;  ebx= size of file
441
;
441
;
442
; warging
442
; warging
443
;  You mast call kernel_free() to delete each file
443
;  You mast call kernel_free() to delete each file
444
;  loaded by the load_file() function
444
;  loaded by the load_file() function
445
 
445
 
446
align 4
446
align 4
447
proc load_file stdcall, file_name:dword
447
proc load_file stdcall, file_name:dword
448
           locals
448
           locals
449
             attr       dd ?
449
             attr       dd ?
450
             flags      dd ?
450
             flags      dd ?
451
             cr_time    dd ?
451
             cr_time    dd ?
452
             cr_date    dd ?
452
             cr_date    dd ?
453
             acc_time   dd ?
453
             acc_time   dd ?
454
             acc_date   dd ?
454
             acc_date   dd ?
455
             mod_time   dd ?
455
             mod_time   dd ?
456
             mod_date   dd ?
456
             mod_date   dd ?
457
             file_size  dd ?
457
             file_size  dd ?
458
 
458
 
459
             file       dd ?
459
             file       dd ?
460
             file2      dd ?
460
             file2      dd ?
461
           endl
461
           endl
462
 
462
 
463
        push    esi
463
        push    esi
464
        push    edi
464
        push    edi
465
 
465
 
466
        lea     eax, [attr]
466
        lea     eax, [attr]
467
        stdcall get_fileinfo, [file_name], eax
467
        stdcall get_fileinfo, [file_name], eax
468
        test    eax, eax
468
        test    eax, eax
469
        jnz     .fail
469
        jnz     .fail
470
 
470
 
471
        mov     eax, [file_size]
471
        mov     eax, [file_size]
472
        cmp     eax, 1024*1024*16
472
        cmp     eax, 1024*1024*16
473
        ja      .fail
473
        ja      .fail
474
 
474
 
475
        stdcall kernel_alloc, [file_size]
475
        stdcall kernel_alloc, [file_size]
476
        mov     [file], eax
476
        mov     [file], eax
477
        test    eax, eax
477
        test    eax, eax
478
        jz      .fail
478
        jz      .fail
479
 
479
 
480
        stdcall read_file, [file_name], eax, dword 0, [file_size]
480
        stdcall read_file, [file_name], eax, dword 0, [file_size]
481
        cmp     ebx, [file_size]
481
        cmp     ebx, [file_size]
482
        jne     .cleanup
482
        jne     .cleanup
483
 
483
 
484
        mov     eax, [file]
484
        mov     eax, [file]
485
        cmp     dword [eax], 0x4B43504B
485
        cmp     dword [eax], 0x4B43504B
486
        jne     .exit
486
        jne     .exit
487
        mov     ebx, [eax+4]
487
        mov     ebx, [eax+4]
488
        mov     [file_size], ebx
488
        mov     [file_size], ebx
489
        stdcall kernel_alloc, ebx
489
        stdcall kernel_alloc, ebx
490
 
490
 
491
        test    eax, eax
491
        test    eax, eax
492
        jz      .cleanup
492
        jz      .cleanup
493
 
493
 
494
        mov     [file2], eax
494
        mov     [file2], eax
495
 
495
 
496
        pushad
496
        pushad
497
        mov     ecx, unpack_mutex
497
        mov     ecx, unpack_mutex
498
        call    mutex_lock
498
        call    mutex_lock
499
        popad
499
        popad
500
 
500
 
501
        stdcall unpack, [file], eax
501
        stdcall unpack, [file], eax
502
 
502
 
503
        pushad
503
        pushad
504
        mov     ecx, unpack_mutex
504
        mov     ecx, unpack_mutex
505
        call    mutex_unlock
505
        call    mutex_unlock
506
        popad
506
        popad
507
 
507
 
508
        stdcall kernel_free, [file]
508
        stdcall kernel_free, [file]
509
        mov     eax, [file2]
509
        mov     eax, [file2]
510
        mov     ebx, [file_size]
510
        mov     ebx, [file_size]
511
.exit:
511
.exit:
512
        push    eax
512
        push    eax
513
        lea     edi, [eax+ebx]    ;cleanup remain space
513
        lea     edi, [eax+ebx]    ;cleanup remain space
514
        mov     ecx, 4096         ;from file end
514
        mov     ecx, 4096         ;from file end
515
        and     ebx, 4095
515
        and     ebx, 4095
516
        jz      @f
516
        jz      @f
517
        sub     ecx, ebx
517
        sub     ecx, ebx
518
        xor     eax, eax
518
        xor     eax, eax
519
        cld
519
        cld
520
        rep stosb
520
        rep stosb
521
@@:
521
@@:
522
        mov     ebx, [file_size]
522
        mov     ebx, [file_size]
523
        pop     eax
523
        pop     eax
524
        pop     edi
524
        pop     edi
525
        pop     esi
525
        pop     esi
526
        ret
526
        ret
527
.cleanup:
527
.cleanup:
528
        stdcall kernel_free, [file]
528
        stdcall kernel_free, [file]
529
.fail:
529
.fail:
530
        xor     eax, eax
530
        xor     eax, eax
531
        xor     ebx, ebx
531
        xor     ebx, ebx
532
        pop     edi
532
        pop     edi
533
        pop     esi
533
        pop     esi
534
        ret
534
        ret
535
endp
535
endp
536
 
536
 
537
; description
537
; description
538
;  allocate user memory and loads the specified file
538
;  allocate user memory and loads the specified file
539
;
539
;
540
; param
540
; param
541
;  file_name= path to file
541
;  file_name= path to file
542
;
542
;
543
; retval
543
; retval
544
;  eax= file image in user memory
544
;  eax= file image in user memory
545
;  ebx= size of file
545
;  ebx= size of file
546
;
546
;
547
; warging
547
; warging
548
;  You mast call kernel_free() to delete each file
548
;  You mast call kernel_free() to delete each file
549
;  loaded by the load_file() function
549
;  loaded by the load_file() function
550
 
550
 
551
align 4
551
align 4
552
proc load_file_umode stdcall, file_name:dword
552
proc load_file_umode stdcall, file_name:dword
553
           locals
553
           locals
554
             attr       dd ?
554
             attr       dd ?
555
             flags      dd ?
555
             flags      dd ?
556
             cr_time    dd ?
556
             cr_time    dd ?
557
             cr_date    dd ?
557
             cr_date    dd ?
558
             acc_time   dd ?
558
             acc_time   dd ?
559
             acc_date   dd ?
559
             acc_date   dd ?
560
             mod_time   dd ?
560
             mod_time   dd ?
561
             mod_date   dd ?
561
             mod_date   dd ?
562
             file_size  dd ?
562
             file_size  dd ?
563
 
563
 
564
             km_file    dd ?
564
             km_file    dd ?
565
             um_file    dd ?
565
             um_file    dd ?
566
           endl
566
           endl
567
 
567
 
568
        push    esi
568
        push    esi
569
        push    edi
569
        push    edi
570
        push    ebx
570
        push    ebx
571
 
571
 
572
        lea     eax, [attr]
572
        lea     eax, [attr]
573
        stdcall get_fileinfo, [file_name], eax   ;find file and get info
573
        stdcall get_fileinfo, [file_name], eax   ;find file and get info
574
        test    eax, eax
574
        test    eax, eax
575
        jnz     .err_1
575
        jnz     .err_1
576
 
576
 
577
        mov     eax, [file_size]
577
        mov     eax, [file_size]
578
        cmp     eax, 1024*1024*16                ;to be enough for anybody (c)
578
        cmp     eax, 1024*1024*16                ;to be enough for anybody (c)
579
        ja      .err_1
579
        ja      .err_1
580
                                                 ;it is very likely that the file is packed
580
                                                 ;it is very likely that the file is packed
581
        stdcall kernel_alloc, [file_size]        ;with kpack, so allocate memory from kernel heap
581
        stdcall kernel_alloc, [file_size]        ;with kpack, so allocate memory from kernel heap
582
        mov     [km_file], eax
582
        mov     [km_file], eax
583
        test    eax, eax
583
        test    eax, eax
584
        jz      .err_1
584
        jz      .err_1
585
 
585
 
586
        stdcall read_file, [file_name], eax, dword 0, [file_size]
586
        stdcall read_file, [file_name], eax, dword 0, [file_size]
587
        cmp     ebx, [file_size]
587
        cmp     ebx, [file_size]
588
 
588
 
589
        jne     .err_2
589
        jne     .err_2
590
 
590
 
591
        mov     eax, [km_file]
591
        mov     eax, [km_file]
592
        cmp     dword [eax], 0x4B43504B          ; check kpack signature
592
        cmp     dword [eax], 0x4B43504B          ; check kpack signature
593
        jne     .raw_file
593
        jne     .raw_file
594
 
594
 
595
        mov     ebx, [eax+4]                     ;get real size of file
595
        mov     ebx, [eax+4]                     ;get real size of file
596
        mov     [file_size], ebx
596
        mov     [file_size], ebx
597
        stdcall user_alloc, ebx                  ;and allocate space from user heap
597
        stdcall user_alloc, ebx                  ;and allocate space from user heap
598
        mov     [um_file], eax
598
        mov     [um_file], eax
599
        test    eax, eax
599
        test    eax, eax
600
        jz      .err_2
600
        jz      .err_2
601
 
601
 
602
        mov     edx, [file_size]                 ;preallocate page memory
602
        mov     edx, [file_size]                 ;preallocate page memory
603
        shr     eax, 10
603
        shr     eax, 10
604
        lea     edi, [page_tabs+eax]
604
        lea     edi, [page_tabs+eax]
605
        add     edx, 4095
605
        add     edx, 4095
606
        shr     edx, 12
606
        shr     edx, 12
607
@@:
607
@@:
608
        call    alloc_page
608
        call    alloc_page
609
        test    eax, eax
609
        test    eax, eax
610
        jz      .err_3
610
        jz      .err_3
611
 
611
 
612
        or      eax, PG_UW
612
        or      eax, PG_UW
613
        stosd
613
        stosd
614
        dec     edx
614
        dec     edx
615
        jnz     @B
615
        jnz     @B
616
 
616
 
617
        pushad
617
        pushad
618
        mov     ecx, unpack_mutex
618
        mov     ecx, unpack_mutex
619
        call    mutex_lock
619
        call    mutex_lock
620
 
620
 
621
        stdcall unpack, [km_file], [um_file]
621
        stdcall unpack, [km_file], [um_file]
622
 
622
 
623
        mov     ecx, unpack_mutex
623
        mov     ecx, unpack_mutex
624
        call    mutex_unlock
624
        call    mutex_unlock
625
        popad
625
        popad
626
 
626
 
627
        stdcall kernel_free, [km_file]           ;we don't need packed file anymore
627
        stdcall kernel_free, [km_file]           ;we don't need packed file anymore
628
.exit:
628
.exit:
629
 
629
 
630
        mov     edi, [um_file]
630
        mov     edi, [um_file]
631
        mov     esi, [um_file]
631
        mov     esi, [um_file]
632
        mov     eax, [file_size]
632
        mov     eax, [file_size]
633
        mov     edx, eax
633
        mov     edx, eax
634
 
634
 
635
        add     edi, eax                         ;cleanup remain space
635
        add     edi, eax                         ;cleanup remain space
636
        mov     ecx, 4096                        ;from file end
636
        mov     ecx, 4096                        ;from file end
637
        and     eax, 4095
637
        and     eax, 4095
638
        jz      @f
638
        jz      @f
639
        sub     ecx, eax
639
        sub     ecx, eax
640
        xor     eax, eax
640
        xor     eax, eax
641
        cld
641
        cld
642
        rep stosb
642
        rep stosb
643
@@:
643
@@:
644
        mov     eax, [um_file]
644
        mov     eax, [um_file]
645
 
645
 
646
        pop     ebx
646
        pop     ebx
647
        pop     edi
647
        pop     edi
648
        pop     esi
648
        pop     esi
649
        ret
649
        ret
650
 
650
 
651
.raw_file:                                       ; sometimes we load unpacked file
651
.raw_file:                                       ; sometimes we load unpacked file
652
        stdcall user_alloc, ebx                  ; allocate space from user heap
652
        stdcall user_alloc, ebx                  ; allocate space from user heap
653
        mov     [um_file], eax
653
        mov     [um_file], eax
654
 
654
 
655
        test    eax, eax
655
        test    eax, eax
656
        jz      .err_2
656
        jz      .err_2
657
 
657
 
658
        shr     eax, 10                          ; and remap pages.
658
        shr     eax, 10                          ; and remap pages.
659
 
659
 
660
        mov     ecx, [file_size]
660
        mov     ecx, [file_size]
661
        add     ecx, 4095
661
        add     ecx, 4095
662
        shr     ecx, 12
662
        shr     ecx, 12
663
 
663
 
664
        mov     esi, [km_file]
664
        mov     esi, [km_file]
665
        shr     esi, 10
665
        shr     esi, 10
666
        add     esi, page_tabs
666
        add     esi, page_tabs
667
 
667
 
668
        lea     edi, [page_tabs+eax]
668
        lea     edi, [page_tabs+eax]
669
 
669
 
670
        cld
670
        cld
671
@@:
671
@@:
672
        lodsd
672
        lodsd
673
        and     eax, 0xFFFFF000
673
        and     eax, 0xFFFFF000
674
        or      eax, PG_UW
674
        or      eax, PG_UW
675
        stosd
675
        stosd
676
        loop    @B
676
        loop    @B
677
 
677
 
678
        stdcall free_kernel_space, [km_file]     ; release allocated kernel space
678
        stdcall free_kernel_space, [km_file]     ; release allocated kernel space
679
        jmp     .exit                            ; physical pages still in use
679
        jmp     .exit                            ; physical pages still in use
680
.err_3:
680
.err_3:
681
        stdcall user_free, [um_file]
681
        stdcall user_free, [um_file]
682
.err_2:
682
.err_2:
683
        stdcall kernel_free, [km_file]
683
        stdcall kernel_free, [km_file]
684
.err_1:
684
.err_1:
685
        xor     eax, eax
685
        xor     eax, eax
686
        xor     edx, edx
686
        xor     edx, edx
687
 
687
 
688
        pop     ebx
688
        pop     ebx
689
        pop     edi
689
        pop     edi
690
        pop     esi
690
        pop     esi
691
        ret
691
        ret
692
endp
692
endp
693
 
693
 
694
 
694
 
695
uglobal
695
uglobal
696
align 4
696
align 4
697
unpack_mutex MUTEX
697
unpack_mutex MUTEX
698
endg
698
endg
699
 
699
 
700
align 4
700
align 4
701
proc get_proc_ex stdcall uses ebx esi, proc_name:dword, imports:dword
701
proc get_proc_ex stdcall uses ebx esi, proc_name:dword, imports:dword
702
        mov     ebx, [imports]
702
        mov     ebx, [imports]
703
        test    ebx, ebx
703
        test    ebx, ebx
704
        jz      .end
704
        jz      .end
705
        xor     esi, esi
705
        xor     esi, esi
706
.look_up:
706
.look_up:
707
 
707
 
708
        mov     eax, [ebx+32]
708
        mov     eax, [ebx+32]
709
        mov     eax, [OS_BASE+eax+esi*4]
709
        mov     eax, [OS_BASE+eax+esi*4]
710
        add     eax, OS_BASE
710
        add     eax, OS_BASE
711
        stdcall strncmp, eax, [proc_name], 256
711
        stdcall strncmp, eax, [proc_name], 256
712
        test    eax, eax
712
        test    eax, eax
713
        jz      .ok
713
        jz      .ok
714
 
714
 
715
        inc     esi
715
        inc     esi
716
        cmp     esi, [ebx+24]
716
        cmp     esi, [ebx+24]
717
        jb      .look_up
717
        jb      .look_up
718
.end:
718
.end:
719
        xor     eax, eax
719
        xor     eax, eax
720
        ret
720
        ret
721
.ok:
721
.ok:
722
        mov     eax, [ebx+28]
722
        mov     eax, [ebx+28]
723
        mov     eax, [OS_BASE+eax+esi*4]
723
        mov     eax, [OS_BASE+eax+esi*4]
724
        add     eax, OS_BASE
724
        add     eax, OS_BASE
725
        ret
725
        ret
726
endp
726
endp
727
 
727
 
728
align 4
728
align 4
729
proc fix_coff_symbols stdcall uses ebx esi, sec:dword, symbols:dword,\
729
proc fix_coff_symbols stdcall uses ebx esi, sec:dword, symbols:dword,\
730
                      sym_count:dword, strings:dword, imports:dword
730
                      sym_count:dword, strings:dword, imports:dword
731
           locals
731
           locals
732
             retval dd ?
732
             retval dd ?
733
           endl
733
           endl
734
 
734
 
735
        mov     edi, [symbols]
735
        mov     edi, [symbols]
736
        mov     [retval], 1
736
        mov     [retval], 1
737
.fix:
737
.fix:
738
        movzx   ebx, [edi+COFF_SYM.SectionNumber]
738
        movzx   ebx, [edi+COFF_SYM.SectionNumber]
739
        test    ebx, ebx
739
        test    ebx, ebx
740
        jnz     .internal
740
        jnz     .internal
741
        mov     eax, dword [edi+COFF_SYM.Name]
741
        mov     eax, dword [edi+COFF_SYM.Name]
742
        test    eax, eax
742
        test    eax, eax
743
        jnz     @F
743
        jnz     @F
744
 
744
 
745
        mov     edi, [edi+4]
745
        mov     edi, [edi+4]
746
        add     edi, [strings]
746
        add     edi, [strings]
747
@@:
747
@@:
748
        push    edi
748
        push    edi
749
        stdcall get_proc_ex, edi, [imports]
749
        stdcall get_proc_ex, edi, [imports]
750
        pop     edi
750
        pop     edi
751
 
751
 
752
        xor     ebx, ebx
752
        xor     ebx, ebx
753
        test    eax, eax
753
        test    eax, eax
754
        jnz     @F
754
        jnz     @F
755
 
755
 
756
        mov     esi, msg_unresolved
756
        mov     esi, msg_unresolved
757
        call    sys_msg_board_str
757
        call    sys_msg_board_str
758
        mov     esi, edi
758
        mov     esi, edi
759
        call    sys_msg_board_str
759
        call    sys_msg_board_str
760
        mov     esi, msg_CR
760
        mov     esi, msg_CR
761
        call    sys_msg_board_str
761
        call    sys_msg_board_str
762
 
762
 
763
        mov     [retval], 0
763
        mov     [retval], 0
764
@@:
764
@@:
765
        mov     edi, [symbols]
765
        mov     edi, [symbols]
766
        mov     [edi+COFF_SYM.Value], eax
766
        mov     [edi+COFF_SYM.Value], eax
767
        jmp     .next
767
        jmp     .next
768
.internal:
768
.internal:
769
        cmp     bx, -1
769
        cmp     bx, -1
770
        je      .next
770
        je      .next
771
        cmp     bx, -2
771
        cmp     bx, -2
772
        je      .next
772
        je      .next
773
 
773
 
774
        dec     ebx
774
        dec     ebx
775
        shl     ebx, 3
775
        shl     ebx, 3
776
        lea     ebx, [ebx+ebx*4]
776
        lea     ebx, [ebx+ebx*4]
777
        add     ebx, [sec]
777
        add     ebx, [sec]
778
 
778
 
779
        mov     eax, [ebx+COFF_SECTION.VirtualAddress]
779
        mov     eax, [ebx+COFF_SECTION.VirtualAddress]
780
        add     [edi+COFF_SYM.Value], eax
780
        add     [edi+COFF_SYM.Value], eax
781
.next:
781
.next:
782
        add     edi, sizeof.COFF_SYM
782
        add     edi, sizeof.COFF_SYM
783
        mov     [symbols], edi
783
        mov     [symbols], edi
784
        dec     [sym_count]
784
        dec     [sym_count]
785
        jnz     .fix
785
        jnz     .fix
786
        mov     eax, [retval]
786
        mov     eax, [retval]
787
        ret
787
        ret
788
endp
788
endp
789
 
789
 
790
align 4
790
align 4
791
proc fix_coff_relocs stdcall uses ebx esi, coff:dword, sym:dword, \
791
proc fix_coff_relocs stdcall uses ebx esi, coff:dword, sym:dword, \
792
        delta:dword
792
        delta:dword
793
           locals
793
           locals
794
             n_sec     dd ?
794
             n_sec     dd ?
795
           endl
795
           endl
796
 
796
 
797
        mov     eax, [coff]
797
        mov     eax, [coff]
798
        movzx   ebx, [eax+COFF_HEADER.nSections]
798
        movzx   ebx, [eax+COFF_HEADER.nSections]
799
        mov     [n_sec], ebx
799
        mov     [n_sec], ebx
800
        lea     esi, [eax+20]
800
        lea     esi, [eax+20]
801
.fix_sec:
801
.fix_sec:
802
        mov     edi, [esi+COFF_SECTION.PtrReloc]
802
        mov     edi, [esi+COFF_SECTION.PtrReloc]
803
        add     edi, [coff]
803
        add     edi, [coff]
804
 
804
 
805
        movzx   ecx, [esi+COFF_SECTION.NumReloc]
805
        movzx   ecx, [esi+COFF_SECTION.NumReloc]
806
        test    ecx, ecx
806
        test    ecx, ecx
807
        jz      .next
807
        jz      .next
808
.reloc_loop:
808
.reloc_loop:
809
        mov     ebx, [edi+COFF_RELOC.SymIndex]
809
        mov     ebx, [edi+COFF_RELOC.SymIndex]
810
        add     ebx, ebx
810
        add     ebx, ebx
811
        lea     ebx, [ebx+ebx*8]
811
        lea     ebx, [ebx+ebx*8]
812
        add     ebx, [sym]
812
        add     ebx, [sym]
813
 
813
 
814
        mov     edx, [ebx+COFF_SYM.Value]
814
        mov     edx, [ebx+COFF_SYM.Value]
815
 
815
 
816
        cmp     [edi+COFF_RELOC.Type], 6
816
        cmp     [edi+COFF_RELOC.Type], 6
817
        je      .dir_32
817
        je      .dir_32
818
 
818
 
819
        cmp     [edi+COFF_RELOC.Type], 20
819
        cmp     [edi+COFF_RELOC.Type], 20
820
        jne     .next_reloc
820
        jne     .next_reloc
821
.rel_32:
821
.rel_32:
822
        mov     eax, [edi+COFF_RELOC.VirtualAddress]
822
        mov     eax, [edi+COFF_RELOC.VirtualAddress]
823
        add     eax, [esi+COFF_SECTION.VirtualAddress]
823
        add     eax, [esi+COFF_SECTION.VirtualAddress]
824
        sub     edx, eax
824
        sub     edx, eax
825
        sub     edx, 4
825
        sub     edx, 4
826
        jmp     .fix
826
        jmp     .fix
827
.dir_32:
827
.dir_32:
828
        mov     eax, [edi+COFF_RELOC.VirtualAddress]
828
        mov     eax, [edi+COFF_RELOC.VirtualAddress]
829
        add     eax, [esi+COFF_SECTION.VirtualAddress]
829
        add     eax, [esi+COFF_SECTION.VirtualAddress]
830
.fix:
830
.fix:
831
        add     eax, [delta]
831
        add     eax, [delta]
832
        add     [eax], edx
832
        add     [eax], edx
833
.next_reloc:
833
.next_reloc:
834
        add     edi, 10
834
        add     edi, 10
835
        dec     ecx
835
        dec     ecx
836
        jnz     .reloc_loop
836
        jnz     .reloc_loop
837
.next:
837
.next:
838
        add     esi, sizeof.COFF_SECTION
838
        add     esi, sizeof.COFF_SECTION
839
        dec     [n_sec]
839
        dec     [n_sec]
840
        jnz     .fix_sec
840
        jnz     .fix_sec
841
.exit:
841
.exit:
842
        ret
842
        ret
843
endp
843
endp
844
 
844
 
845
align 4
845
align 4
846
proc rebase_coff stdcall uses ebx esi, coff:dword, sym:dword, \
846
proc rebase_coff stdcall uses ebx esi, coff:dword, sym:dword, \
847
        delta:dword
847
        delta:dword
848
           locals
848
           locals
849
             n_sec     dd ?
849
             n_sec     dd ?
850
           endl
850
           endl
851
 
851
 
852
        mov     eax, [coff]
852
        mov     eax, [coff]
853
        movzx   ebx, [eax+COFF_HEADER.nSections]
853
        movzx   ebx, [eax+COFF_HEADER.nSections]
854
        mov     [n_sec], ebx
854
        mov     [n_sec], ebx
855
        lea     esi, [eax+20]
855
        lea     esi, [eax+20]
856
        mov     edx, [delta]
856
        mov     edx, [delta]
857
.fix_sec:
857
.fix_sec:
858
        mov     edi, [esi+COFF_SECTION.PtrReloc]
858
        mov     edi, [esi+COFF_SECTION.PtrReloc]
859
        add     edi, [coff]
859
        add     edi, [coff]
860
 
860
 
861
        movzx   ecx, [esi+COFF_SECTION.NumReloc]
861
        movzx   ecx, [esi+COFF_SECTION.NumReloc]
862
        test    ecx, ecx
862
        test    ecx, ecx
863
        jz      .next
863
        jz      .next
864
.reloc_loop:
864
.reloc_loop:
865
        cmp     [edi+COFF_RELOC.Type], 6
865
        cmp     [edi+COFF_RELOC.Type], 6
866
        jne     .next_reloc
866
        jne     .next_reloc
867
.dir_32:
867
.dir_32:
868
        mov     eax, [edi+COFF_RELOC.VirtualAddress]
868
        mov     eax, [edi+COFF_RELOC.VirtualAddress]
869
        add     eax, [esi+COFF_SECTION.VirtualAddress]
869
        add     eax, [esi+COFF_SECTION.VirtualAddress]
870
        add     [eax+edx], edx
870
        add     [eax+edx], edx
871
.next_reloc:
871
.next_reloc:
872
        add     edi, 10
872
        add     edi, 10
873
        dec     ecx
873
        dec     ecx
874
        jnz     .reloc_loop
874
        jnz     .reloc_loop
875
.next:
875
.next:
876
        add     esi, sizeof.COFF_SECTION
876
        add     esi, sizeof.COFF_SECTION
877
        dec     [n_sec]
877
        dec     [n_sec]
878
        jnz     .fix_sec
878
        jnz     .fix_sec
879
.exit:
879
.exit:
880
        ret
880
        ret
881
endp
881
endp
882
 
882
 
883
align 4
883
align 4
884
proc load_driver stdcall, driver_name:dword
884
proc load_driver stdcall, driver_name:dword
885
           locals
885
           locals
886
             coff      dd ?
886
             coff      dd ?
887
             sym       dd ?
887
             sym       dd ?
888
             strings   dd ?
888
             strings   dd ?
889
             img_size  dd ?
889
             img_size  dd ?
890
             img_base  dd ?
890
             img_base  dd ?
891
             start     dd ?
891
             start     dd ?
892
 
892
 
893
             file_name rb 13+16+4+1      ; '/sys/drivers/.obj'
893
             file_name rb 13+16+4+1      ; '/sys/drivers/.obj'
894
           endl
894
           endl
895
 
895
 
896
        lea     edx, [file_name]
896
        lea     edx, [file_name]
897
        mov     dword [edx], '/sys'
897
        mov     dword [edx], '/sys'
898
        mov     dword [edx+4], '/dri'
898
        mov     dword [edx+4], '/dri'
899
        mov     dword [edx+8], 'vers'
899
        mov     dword [edx+8], 'vers'
900
        mov     byte [edx+12], '/'
900
        mov     byte [edx+12], '/'
901
        mov     esi, [driver_name]
901
        mov     esi, [driver_name]
902
.redo:
902
.redo:
903
        lea     edx, [file_name]
903
        lea     edx, [file_name]
904
        lea     edi, [edx+13]
904
        lea     edi, [edx+13]
905
        mov     ecx, 16
905
        mov     ecx, 16
906
@@:
906
@@:
907
        lodsb
907
        lodsb
908
        test    al, al
908
        test    al, al
909
        jz      @f
909
        jz      @f
910
        stosb
910
        stosb
911
        loop    @b
911
        loop    @b
912
@@:
912
@@:
913
        mov     dword [edi], '.obj'
913
        mov     dword [edi], '.obj'
914
        mov     byte [edi+4], 0
914
        mov     byte [edi+4], 0
915
        stdcall load_file, edx
915
        stdcall load_file, edx
916
 
916
 
917
        test    eax, eax
917
        test    eax, eax
918
        jz      .exit
918
        jz      .exit
-
 
919
 
-
 
920
        lea     edx, [file_name]
919
 
921
        DEBUGF 1,'K : driver %s is COFF, deprecated\n',edx
920
        mov     [coff], eax
922
        mov     [coff], eax
921
 
923
 
922
        movzx   ecx, [eax+COFF_HEADER.nSections]
924
        movzx   ecx, [eax+COFF_HEADER.nSections]
923
        xor     ebx, ebx
925
        xor     ebx, ebx
924
 
926
 
925
        lea     edx, [eax+20]
927
        lea     edx, [eax+20]
926
@@:
928
@@:
927
        add     ebx, [edx+COFF_SECTION.SizeOfRawData]
929
        add     ebx, [edx+COFF_SECTION.SizeOfRawData]
928
        add     ebx, 15
930
        add     ebx, 15
929
        and     ebx, not 15
931
        and     ebx, not 15
930
        add     edx, sizeof.COFF_SECTION
932
        add     edx, sizeof.COFF_SECTION
931
        dec     ecx
933
        dec     ecx
932
        jnz     @B
934
        jnz     @B
933
        mov     [img_size], ebx
935
        mov     [img_size], ebx
934
 
936
 
935
        stdcall kernel_alloc, ebx
937
        stdcall kernel_alloc, ebx
936
        test    eax, eax
938
        test    eax, eax
937
        jz      .fail
939
        jz      .fail
938
        mov     [img_base], eax
940
        mov     [img_base], eax
939
 
941
 
940
        mov     edi, eax
942
        mov     edi, eax
941
        xor     eax, eax
943
        xor     eax, eax
942
        mov     ecx, [img_size]
944
        mov     ecx, [img_size]
943
        add     ecx, 4095
945
        add     ecx, 4095
944
        and     ecx, not 4095
946
        and     ecx, not 4095
945
        shr     ecx, 2
947
        shr     ecx, 2
946
        cld
948
        cld
947
        rep stosd
949
        rep stosd
948
 
950
 
949
        mov     edx, [coff]
951
        mov     edx, [coff]
950
        movzx   ebx, [edx+COFF_HEADER.nSections]
952
        movzx   ebx, [edx+COFF_HEADER.nSections]
951
        mov     edi, [img_base]
953
        mov     edi, [img_base]
952
        lea     eax, [edx+20]
954
        lea     eax, [edx+20]
953
@@:
955
@@:
954
        mov     [eax+COFF_SECTION.VirtualAddress], edi
956
        mov     [eax+COFF_SECTION.VirtualAddress], edi
955
        mov     esi, [eax+COFF_SECTION.PtrRawData]
957
        mov     esi, [eax+COFF_SECTION.PtrRawData]
956
        test    esi, esi
958
        test    esi, esi
957
        jnz     .copy
959
        jnz     .copy
958
        add     edi, [eax+COFF_SECTION.SizeOfRawData]
960
        add     edi, [eax+COFF_SECTION.SizeOfRawData]
959
        jmp     .next
961
        jmp     .next
960
.copy:
962
.copy:
961
        add     esi, edx
963
        add     esi, edx
962
        mov     ecx, [eax+COFF_SECTION.SizeOfRawData]
964
        mov     ecx, [eax+COFF_SECTION.SizeOfRawData]
963
        cld
965
        cld
964
        rep movsb
966
        rep movsb
965
.next:
967
.next:
966
        add     edi, 15
968
        add     edi, 15
967
        and     edi, not 15
969
        and     edi, not 15
968
        add     eax, sizeof.COFF_SECTION
970
        add     eax, sizeof.COFF_SECTION
969
        dec     ebx
971
        dec     ebx
970
        jnz     @B
972
        jnz     @B
971
 
973
 
972
        mov     ebx, [edx+COFF_HEADER.pSymTable]
974
        mov     ebx, [edx+COFF_HEADER.pSymTable]
973
        add     ebx, edx
975
        add     ebx, edx
974
        mov     [sym], ebx
976
        mov     [sym], ebx
975
        mov     ecx, [edx+COFF_HEADER.nSymbols]
977
        mov     ecx, [edx+COFF_HEADER.nSymbols]
976
        add     ecx, ecx
978
        add     ecx, ecx
977
        lea     ecx, [ecx+ecx*8];ecx*=18 = nSymbols*CSYM_SIZE
979
        lea     ecx, [ecx+ecx*8];ecx*=18 = nSymbols*CSYM_SIZE
978
        add     ecx, [sym]
980
        add     ecx, [sym]
979
        mov     [strings], ecx
981
        mov     [strings], ecx
980
 
982
 
981
        lea     eax, [edx+20]
983
        lea     eax, [edx+20]
982
 
984
 
983
        stdcall fix_coff_symbols, eax, [sym], [edx+COFF_HEADER.nSymbols], \
985
        stdcall fix_coff_symbols, eax, [sym], [edx+COFF_HEADER.nSymbols], \
984
                [strings], __exports
986
                [strings], __exports
985
        test    eax, eax
987
        test    eax, eax
986
        jz      .link_fail
988
        jz      .link_fail
987
 
989
 
988
        mov     ebx, [coff]
990
        mov     ebx, [coff]
989
        stdcall fix_coff_relocs, ebx, [sym], 0
991
        stdcall fix_coff_relocs, ebx, [sym], 0
990
 
992
 
991
        stdcall get_coff_sym, [sym], [ebx+COFF_HEADER.nSymbols], szVersion
993
        stdcall get_coff_sym, [sym], [ebx+COFF_HEADER.nSymbols], szVersion
992
        test    eax, eax
994
        test    eax, eax
993
        jz      .link_fail
995
        jz      .link_fail
994
 
996
 
995
        mov     eax, [eax]
997
        mov     eax, [eax]
996
        shr     eax, 16
998
        shr     eax, 16
997
        cmp     eax, DRV_COMPAT
999
        cmp     eax, DRV_COMPAT
998
        jb      .ver_fail
1000
        jb      .ver_fail
999
 
1001
 
1000
        cmp     eax, DRV_CURRENT
1002
        cmp     eax, DRV_CURRENT
1001
        ja      .ver_fail
1003
        ja      .ver_fail
1002
 
1004
 
1003
        mov     ebx, [coff]
1005
        mov     ebx, [coff]
1004
        stdcall get_coff_sym, [sym], [ebx+COFF_HEADER.nSymbols], szSTART
1006
        stdcall get_coff_sym, [sym], [ebx+COFF_HEADER.nSymbols], szSTART
1005
        mov     [start], eax
1007
        mov     [start], eax
1006
 
1008
 
1007
        stdcall kernel_free, [coff]
1009
        stdcall kernel_free, [coff]
1008
 
1010
 
1009
        mov     ebx, [start]
1011
        mov     ebx, [start]
1010
        stdcall ebx, DRV_ENTRY
1012
        stdcall ebx, DRV_ENTRY
1011
        test    eax, eax
1013
        test    eax, eax
1012
        jnz     .ok
1014
        jnz     .ok
1013
 
1015
 
1014
        stdcall kernel_free, [img_base]
1016
        stdcall kernel_free, [img_base]
1015
 
1017
 
1016
        xor     eax, eax
1018
        xor     eax, eax
1017
        ret
1019
        ret
1018
.ok:
1020
.ok:
1019
        mov     ebx, [img_base]
1021
        mov     ebx, [img_base]
1020
        mov     [eax+SRV.base], ebx
1022
        mov     [eax+SRV.base], ebx
1021
        mov     ecx, [start]
1023
        mov     ecx, [start]
1022
        mov     [eax+SRV.entry], ecx
1024
        mov     [eax+SRV.entry], ecx
1023
        ret
1025
        ret
1024
 
1026
 
1025
.ver_fail:
1027
.ver_fail:
1026
        mov     esi, msg_CR
1028
        mov     esi, msg_CR
1027
        call    sys_msg_board_str
1029
        call    sys_msg_board_str
1028
        mov     esi, [driver_name]
1030
        mov     esi, [driver_name]
1029
        call    sys_msg_board_str
1031
        call    sys_msg_board_str
1030
        mov     esi, msg_CR
1032
        mov     esi, msg_CR
1031
        call    sys_msg_board_str
1033
        call    sys_msg_board_str
1032
        mov     esi, msg_version
1034
        mov     esi, msg_version
1033
        call    sys_msg_board_str
1035
        call    sys_msg_board_str
1034
        mov     esi, msg_www
1036
        mov     esi, msg_www
1035
        call    sys_msg_board_str
1037
        call    sys_msg_board_str
1036
        jmp     .cleanup
1038
        jmp     .cleanup
1037
 
1039
 
1038
.link_fail:
1040
.link_fail:
1039
        mov     esi, msg_module
1041
        mov     esi, msg_module
1040
        call    sys_msg_board_str
1042
        call    sys_msg_board_str
1041
        mov     esi, [driver_name]
1043
        mov     esi, [driver_name]
1042
        call    sys_msg_board_str
1044
        call    sys_msg_board_str
1043
        mov     esi, msg_CR
1045
        mov     esi, msg_CR
1044
        call    sys_msg_board_str
1046
        call    sys_msg_board_str
1045
.cleanup:
1047
.cleanup:
1046
        stdcall kernel_free, [img_base]
1048
        stdcall kernel_free, [img_base]
1047
.fail:
1049
.fail:
1048
        stdcall kernel_free, [coff]
1050
        stdcall kernel_free, [coff]
1049
.exit:
1051
.exit:
1050
        xor     eax, eax
1052
        xor     eax, eax
1051
        ret
1053
        ret
1052
endp
1054
endp
1053
 
1055
 
1054
; in: edx -> COFF_SECTION struct
1056
; in: edx -> COFF_SECTION struct
1055
; out: eax = alignment as mask for bits to drop
1057
; out: eax = alignment as mask for bits to drop
1056
coff_get_align:
1058
coff_get_align:
1057
; Rules:
1059
; Rules:
1058
; - if alignment is not given, use default = 4K;
1060
; - if alignment is not given, use default = 4K;
1059
; - if alignment is given and is no more than 4K, use it;
1061
; - if alignment is given and is no more than 4K, use it;
1060
; - if alignment is more than 4K, revert to 4K.
1062
; - if alignment is more than 4K, revert to 4K.
1061
        push    ecx
1063
        push    ecx
1062
        mov     cl, byte [edx+COFF_SECTION.Characteristics+2]
1064
        mov     cl, byte [edx+COFF_SECTION.Characteristics+2]
1063
        mov     eax, 1
1065
        mov     eax, 1
1064
        shr     cl, 4
1066
        shr     cl, 4
1065
        dec     cl
1067
        dec     cl
1066
        js      .default
1068
        js      .default
1067
        cmp     cl, 12
1069
        cmp     cl, 12
1068
        jbe     @f
1070
        jbe     @f
1069
.default:
1071
.default:
1070
        mov     cl, 12
1072
        mov     cl, 12
1071
@@:
1073
@@:
1072
        shl     eax, cl
1074
        shl     eax, cl
1073
        pop     ecx
1075
        pop     ecx
1074
        dec     eax
1076
        dec     eax
1075
        ret
1077
        ret
1076
 
1078
 
1077
align 4
1079
align 4
1078
proc load_library stdcall, file_name:dword
1080
proc load_library stdcall, file_name:dword
1079
           locals
1081
           locals
1080
             fullname  rb 260
1082
             fullname  rb 260
1081
             fileinfo  rb 40
1083
             fileinfo  rb 40
1082
             coff      dd ?
1084
             coff      dd ?
1083
             img_base  dd ?
1085
             img_base  dd ?
1084
           endl
1086
           endl
1085
 
1087
 
1086
; resolve file name
1088
; resolve file name
1087
        mov     ebx, [file_name]
1089
        mov     ebx, [file_name]
1088
        lea     edi, [fullname+1]
1090
        lea     edi, [fullname+1]
1089
        mov     byte [edi-1], '/'
1091
        mov     byte [edi-1], '/'
1090
        stdcall get_full_file_name, edi, 259
1092
        stdcall get_full_file_name, edi, 259
1091
        test    al, al
1093
        test    al, al
1092
        jz      .fail
1094
        jz      .fail
1093
 
1095
 
1094
; scan for required DLL in list of already loaded for this process,
1096
; scan for required DLL in list of already loaded for this process,
1095
; ignore timestamp
1097
; ignore timestamp
1096
        cli
1098
        cli
1097
 
1099
 
1098
        mov     esi, [CURRENT_TASK]
1100
        mov     esi, [CURRENT_TASK]
1099
        shl     esi, 8
1101
        shl     esi, 8
1100
        lea     edi, [fullname]
1102
        lea     edi, [fullname]
1101
        mov     ebx, [esi+SLOT_BASE+APPDATA.dlls_list_ptr]
1103
        mov     ebx, [esi+SLOT_BASE+APPDATA.dlls_list_ptr]
1102
        test    ebx, ebx
1104
        test    ebx, ebx
1103
        jz      .not_in_process
1105
        jz      .not_in_process
1104
        mov     esi, [ebx+HDLL.fd]
1106
        mov     esi, [ebx+HDLL.fd]
1105
.scan_in_process:
1107
.scan_in_process:
1106
        cmp     esi, ebx
1108
        cmp     esi, ebx
1107
        jz      .not_in_process
1109
        jz      .not_in_process
1108
        mov     eax, [esi+HDLL.parent]
1110
        mov     eax, [esi+HDLL.parent]
1109
        add     eax, DLLDESCR.name
1111
        add     eax, DLLDESCR.name
1110
        stdcall strncmp, eax, edi, -1
1112
        stdcall strncmp, eax, edi, -1
1111
        test    eax, eax
1113
        test    eax, eax
1112
        jnz     .next_in_process
1114
        jnz     .next_in_process
1113
; simple variant: load DLL which is already loaded in this process
1115
; simple variant: load DLL which is already loaded in this process
1114
; just increment reference counters and return address of exports table
1116
; just increment reference counters and return address of exports table
1115
        inc     [esi+HDLL.refcount]
1117
        inc     [esi+HDLL.refcount]
1116
        mov     ecx, [esi+HDLL.parent]
1118
        mov     ecx, [esi+HDLL.parent]
1117
        inc     [ecx+DLLDESCR.refcount]
1119
        inc     [ecx+DLLDESCR.refcount]
1118
        mov     eax, [ecx+DLLDESCR.exports]
1120
        mov     eax, [ecx+DLLDESCR.exports]
1119
        sub     eax, [ecx+DLLDESCR.defaultbase]
1121
        sub     eax, [ecx+DLLDESCR.defaultbase]
1120
        add     eax, [esi+HDLL.base]
1122
        add     eax, [esi+HDLL.base]
1121
        sti
1123
        sti
1122
        ret
1124
        ret
1123
.next_in_process:
1125
.next_in_process:
1124
        mov     esi, [esi+HDLL.fd]
1126
        mov     esi, [esi+HDLL.fd]
1125
        jmp     .scan_in_process
1127
        jmp     .scan_in_process
1126
.not_in_process:
1128
.not_in_process:
1127
 
1129
 
1128
; scan in full list, compare timestamp
1130
; scan in full list, compare timestamp
1129
        sti
1131
        sti
1130
        lea     eax, [fileinfo]
1132
        lea     eax, [fileinfo]
1131
        stdcall get_fileinfo, edi, eax
1133
        stdcall get_fileinfo, edi, eax
1132
        test    eax, eax
1134
        test    eax, eax
1133
        jnz     .fail
1135
        jnz     .fail
1134
        cli
1136
        cli
1135
        mov     esi, [dll_list.fd]
1137
        mov     esi, [dll_list.fd]
1136
.scan_for_dlls:
1138
.scan_for_dlls:
1137
        cmp     esi, dll_list
1139
        cmp     esi, dll_list
1138
        jz      .load_new
1140
        jz      .load_new
1139
        lea     eax, [esi+DLLDESCR.name]
1141
        lea     eax, [esi+DLLDESCR.name]
1140
        stdcall strncmp, eax, edi, -1
1142
        stdcall strncmp, eax, edi, -1
1141
        test    eax, eax
1143
        test    eax, eax
1142
        jnz     .continue_scan
1144
        jnz     .continue_scan
1143
.test_prev_dll:
1145
.test_prev_dll:
1144
        mov     eax, dword [fileinfo+24]; last modified time
1146
        mov     eax, dword [fileinfo+24]; last modified time
1145
        mov     edx, dword [fileinfo+28]; last modified date
1147
        mov     edx, dword [fileinfo+28]; last modified date
1146
        cmp     dword [esi+DLLDESCR.timestamp], eax
1148
        cmp     dword [esi+DLLDESCR.timestamp], eax
1147
        jnz     .continue_scan
1149
        jnz     .continue_scan
1148
        cmp     dword [esi+DLLDESCR.timestamp+4], edx
1150
        cmp     dword [esi+DLLDESCR.timestamp+4], edx
1149
        jz      .dll_already_loaded
1151
        jz      .dll_already_loaded
1150
.continue_scan:
1152
.continue_scan:
1151
        mov     esi, [esi+DLLDESCR.fd]
1153
        mov     esi, [esi+DLLDESCR.fd]
1152
        jmp     .scan_for_dlls
1154
        jmp     .scan_for_dlls
1153
 
1155
 
1154
; new DLL
1156
; new DLL
1155
.load_new:
1157
.load_new:
1156
        sti
1158
        sti
1157
; load file
1159
; load file
1158
        stdcall load_file, edi
1160
        stdcall load_file, edi
1159
        test    eax, eax
1161
        test    eax, eax
1160
        jz      .fail
1162
        jz      .fail
1161
        mov     [coff], eax
1163
        mov     [coff], eax
1162
        mov     dword [fileinfo+32], ebx
1164
        mov     dword [fileinfo+32], ebx
1163
 
1165
 
1164
; allocate DLLDESCR struct; size is DLLDESCR.sizeof plus size of DLL name
1166
; allocate DLLDESCR struct; size is DLLDESCR.sizeof plus size of DLL name
1165
        mov     esi, edi
1167
        mov     esi, edi
1166
        mov     ecx, -1
1168
        mov     ecx, -1
1167
        xor     eax, eax
1169
        xor     eax, eax
1168
        repnz scasb
1170
        repnz scasb
1169
        not     ecx
1171
        not     ecx
1170
        lea     eax, [ecx+sizeof.DLLDESCR]
1172
        lea     eax, [ecx+sizeof.DLLDESCR]
1171
        push    ecx
1173
        push    ecx
1172
        call    malloc
1174
        call    malloc
1173
        pop     ecx
1175
        pop     ecx
1174
        test    eax, eax
1176
        test    eax, eax
1175
        jz      .fail_and_free_coff
1177
        jz      .fail_and_free_coff
1176
; save timestamp
1178
; save timestamp
1177
        lea     edi, [eax+DLLDESCR.name]
1179
        lea     edi, [eax+DLLDESCR.name]
1178
        rep movsb
1180
        rep movsb
1179
        mov     esi, eax
1181
        mov     esi, eax
1180
        mov     eax, dword [fileinfo+24]
1182
        mov     eax, dword [fileinfo+24]
1181
        mov     dword [esi+DLLDESCR.timestamp], eax
1183
        mov     dword [esi+DLLDESCR.timestamp], eax
1182
        mov     eax, dword [fileinfo+28]
1184
        mov     eax, dword [fileinfo+28]
1183
        mov     dword [esi+DLLDESCR.timestamp+4], eax
1185
        mov     dword [esi+DLLDESCR.timestamp+4], eax
1184
 
1186
 
1185
; calculate size of loaded DLL
1187
; calculate size of loaded DLL
1186
        mov     edx, [coff]
1188
        mov     edx, [coff]
1187
        movzx   ecx, [edx+COFF_HEADER.nSections]
1189
        movzx   ecx, [edx+COFF_HEADER.nSections]
1188
        xor     ebx, ebx
1190
        xor     ebx, ebx
1189
 
1191
 
1190
        add     edx, 20
1192
        add     edx, 20
1191
@@:
1193
@@:
1192
        call    coff_get_align
1194
        call    coff_get_align
1193
        add     ebx, eax
1195
        add     ebx, eax
1194
        not     eax
1196
        not     eax
1195
        and     ebx, eax
1197
        and     ebx, eax
1196
        add     ebx, [edx+COFF_SECTION.SizeOfRawData]
1198
        add     ebx, [edx+COFF_SECTION.SizeOfRawData]
1197
        add     edx, sizeof.COFF_SECTION
1199
        add     edx, sizeof.COFF_SECTION
1198
        dec     ecx
1200
        dec     ecx
1199
        jnz     @B
1201
        jnz     @B
1200
; it must be nonzero and not too big
1202
; it must be nonzero and not too big
1201
        mov     [esi+DLLDESCR.size], ebx
1203
        mov     [esi+DLLDESCR.size], ebx
1202
        test    ebx, ebx
1204
        test    ebx, ebx
1203
        jz      .fail_and_free_dll
1205
        jz      .fail_and_free_dll
1204
        cmp     ebx, MAX_DEFAULT_DLL_ADDR-MIN_DEFAULT_DLL_ADDR
1206
        cmp     ebx, MAX_DEFAULT_DLL_ADDR-MIN_DEFAULT_DLL_ADDR
1205
        ja      .fail_and_free_dll
1207
        ja      .fail_and_free_dll
1206
; allocate memory for kernel-side image
1208
; allocate memory for kernel-side image
1207
        stdcall kernel_alloc, ebx
1209
        stdcall kernel_alloc, ebx
1208
        test    eax, eax
1210
        test    eax, eax
1209
        jz      .fail_and_free_dll
1211
        jz      .fail_and_free_dll
1210
        mov     [esi+DLLDESCR.data], eax
1212
        mov     [esi+DLLDESCR.data], eax
1211
; calculate preferred base address
1213
; calculate preferred base address
1212
        add     ebx, 0x1FFF
1214
        add     ebx, 0x1FFF
1213
        and     ebx, not 0xFFF
1215
        and     ebx, not 0xFFF
1214
        mov     ecx, [dll_cur_addr]
1216
        mov     ecx, [dll_cur_addr]
1215
        lea     edx, [ecx+ebx]
1217
        lea     edx, [ecx+ebx]
1216
        cmp     edx, MAX_DEFAULT_DLL_ADDR
1218
        cmp     edx, MAX_DEFAULT_DLL_ADDR
1217
        jb      @f
1219
        jb      @f
1218
        mov     ecx, MIN_DEFAULT_DLL_ADDR
1220
        mov     ecx, MIN_DEFAULT_DLL_ADDR
1219
        lea     edx, [ecx+ebx]
1221
        lea     edx, [ecx+ebx]
1220
@@:
1222
@@:
1221
        mov     [esi+DLLDESCR.defaultbase], ecx
1223
        mov     [esi+DLLDESCR.defaultbase], ecx
1222
        mov     [dll_cur_addr], edx
1224
        mov     [dll_cur_addr], edx
1223
 
1225
 
1224
; copy sections and set correct values for VirtualAddress'es in headers
1226
; copy sections and set correct values for VirtualAddress'es in headers
1225
        push    esi
1227
        push    esi
1226
        mov     edx, [coff]
1228
        mov     edx, [coff]
1227
        movzx   ebx, [edx+COFF_HEADER.nSections]
1229
        movzx   ebx, [edx+COFF_HEADER.nSections]
1228
        mov     edi, eax
1230
        mov     edi, eax
1229
        add     edx, 20
1231
        add     edx, 20
1230
        cld
1232
        cld
1231
@@:
1233
@@:
1232
        call    coff_get_align
1234
        call    coff_get_align
1233
        add     ecx, eax
1235
        add     ecx, eax
1234
        add     edi, eax
1236
        add     edi, eax
1235
        not     eax
1237
        not     eax
1236
        and     ecx, eax
1238
        and     ecx, eax
1237
        and     edi, eax
1239
        and     edi, eax
1238
        mov     [edx+COFF_SECTION.VirtualAddress], ecx
1240
        mov     [edx+COFF_SECTION.VirtualAddress], ecx
1239
        add     ecx, [edx+COFF_SECTION.SizeOfRawData]
1241
        add     ecx, [edx+COFF_SECTION.SizeOfRawData]
1240
        mov     esi, [edx+COFF_SECTION.PtrRawData]
1242
        mov     esi, [edx+COFF_SECTION.PtrRawData]
1241
        push    ecx
1243
        push    ecx
1242
        mov     ecx, [edx+COFF_SECTION.SizeOfRawData]
1244
        mov     ecx, [edx+COFF_SECTION.SizeOfRawData]
1243
        test    esi, esi
1245
        test    esi, esi
1244
        jnz     .copy
1246
        jnz     .copy
1245
        xor     eax, eax
1247
        xor     eax, eax
1246
        rep stosb
1248
        rep stosb
1247
        jmp     .next
1249
        jmp     .next
1248
.copy:
1250
.copy:
1249
        add     esi, [coff]
1251
        add     esi, [coff]
1250
        rep movsb
1252
        rep movsb
1251
.next:
1253
.next:
1252
        pop     ecx
1254
        pop     ecx
1253
        add     edx, sizeof.COFF_SECTION
1255
        add     edx, sizeof.COFF_SECTION
1254
        dec     ebx
1256
        dec     ebx
1255
        jnz     @B
1257
        jnz     @B
1256
        pop     esi
1258
        pop     esi
1257
 
1259
 
1258
; save some additional data from COFF file
1260
; save some additional data from COFF file
1259
; later we will use COFF header, headers for sections and symbol table
1261
; later we will use COFF header, headers for sections and symbol table
1260
; and also relocations table for all sections
1262
; and also relocations table for all sections
1261
        mov     edx, [coff]
1263
        mov     edx, [coff]
1262
        mov     ebx, [edx+COFF_HEADER.pSymTable]
1264
        mov     ebx, [edx+COFF_HEADER.pSymTable]
1263
        mov     edi, dword [fileinfo+32]
1265
        mov     edi, dword [fileinfo+32]
1264
        sub     edi, ebx
1266
        sub     edi, ebx
1265
        jc      .fail_and_free_data
1267
        jc      .fail_and_free_data
1266
        mov     [esi+DLLDESCR.symbols_lim], edi
1268
        mov     [esi+DLLDESCR.symbols_lim], edi
1267
        add     ebx, edx
1269
        add     ebx, edx
1268
        movzx   ecx, [edx+COFF_HEADER.nSections]
1270
        movzx   ecx, [edx+COFF_HEADER.nSections]
1269
        lea     ecx, [ecx*5]
1271
        lea     ecx, [ecx*5]
1270
        lea     edi, [edi+ecx*8+20]
1272
        lea     edi, [edi+ecx*8+20]
1271
        add     edx, 20
1273
        add     edx, 20
1272
@@:
1274
@@:
1273
        movzx   eax, [edx+COFF_SECTION.NumReloc]
1275
        movzx   eax, [edx+COFF_SECTION.NumReloc]
1274
        lea     eax, [eax*5]
1276
        lea     eax, [eax*5]
1275
        lea     edi, [edi+eax*2]
1277
        lea     edi, [edi+eax*2]
1276
        add     edx, sizeof.COFF_SECTION
1278
        add     edx, sizeof.COFF_SECTION
1277
        sub     ecx, 5
1279
        sub     ecx, 5
1278
        jnz     @b
1280
        jnz     @b
1279
        stdcall kernel_alloc, edi
1281
        stdcall kernel_alloc, edi
1280
        test    eax, eax
1282
        test    eax, eax
1281
        jz      .fail_and_free_data
1283
        jz      .fail_and_free_data
1282
        mov     edx, [coff]
1284
        mov     edx, [coff]
1283
        movzx   ecx, [edx+COFF_HEADER.nSections]
1285
        movzx   ecx, [edx+COFF_HEADER.nSections]
1284
        lea     ecx, [ecx*5]
1286
        lea     ecx, [ecx*5]
1285
        lea     ecx, [ecx*2+5]
1287
        lea     ecx, [ecx*2+5]
1286
        mov     [esi+DLLDESCR.coff_hdr], eax
1288
        mov     [esi+DLLDESCR.coff_hdr], eax
1287
        push    esi
1289
        push    esi
1288
        mov     esi, edx
1290
        mov     esi, edx
1289
        mov     edi, eax
1291
        mov     edi, eax
1290
        rep movsd
1292
        rep movsd
1291
        pop     esi
1293
        pop     esi
1292
        mov     [esi+DLLDESCR.symbols_ptr], edi
1294
        mov     [esi+DLLDESCR.symbols_ptr], edi
1293
        push    esi
1295
        push    esi
1294
        mov     ecx, [edx+COFF_HEADER.nSymbols]
1296
        mov     ecx, [edx+COFF_HEADER.nSymbols]
1295
        mov     [esi+DLLDESCR.symbols_num], ecx
1297
        mov     [esi+DLLDESCR.symbols_num], ecx
1296
        mov     ecx, [esi+DLLDESCR.symbols_lim]
1298
        mov     ecx, [esi+DLLDESCR.symbols_lim]
1297
        mov     esi, ebx
1299
        mov     esi, ebx
1298
        rep movsb
1300
        rep movsb
1299
        pop     esi
1301
        pop     esi
1300
        mov     ebx, [esi+DLLDESCR.coff_hdr]
1302
        mov     ebx, [esi+DLLDESCR.coff_hdr]
1301
        push    esi
1303
        push    esi
1302
        movzx   eax, [edx+COFF_HEADER.nSections]
1304
        movzx   eax, [edx+COFF_HEADER.nSections]
1303
        lea     edx, [ebx+20]
1305
        lea     edx, [ebx+20]
1304
@@:
1306
@@:
1305
        movzx   ecx, [edx+COFF_SECTION.NumReloc]
1307
        movzx   ecx, [edx+COFF_SECTION.NumReloc]
1306
        lea     ecx, [ecx*5]
1308
        lea     ecx, [ecx*5]
1307
        mov     esi, [edx+COFF_SECTION.PtrReloc]
1309
        mov     esi, [edx+COFF_SECTION.PtrReloc]
1308
        mov     [edx+COFF_SECTION.PtrReloc], edi
1310
        mov     [edx+COFF_SECTION.PtrReloc], edi
1309
        sub     [edx+COFF_SECTION.PtrReloc], ebx
1311
        sub     [edx+COFF_SECTION.PtrReloc], ebx
1310
        add     esi, [coff]
1312
        add     esi, [coff]
1311
        shr     ecx, 1
1313
        shr     ecx, 1
1312
        rep movsd
1314
        rep movsd
1313
        adc     ecx, ecx
1315
        adc     ecx, ecx
1314
        rep movsw
1316
        rep movsw
1315
        add     edx, sizeof.COFF_SECTION
1317
        add     edx, sizeof.COFF_SECTION
1316
        dec     eax
1318
        dec     eax
1317
        jnz     @b
1319
        jnz     @b
1318
        pop     esi
1320
        pop     esi
1319
 
1321
 
1320
; fixup symbols
1322
; fixup symbols
1321
        mov     edx, ebx
1323
        mov     edx, ebx
1322
        mov     eax, [ebx+COFF_HEADER.nSymbols]
1324
        mov     eax, [ebx+COFF_HEADER.nSymbols]
1323
        add     edx, 20
1325
        add     edx, 20
1324
        mov     ecx, [esi+DLLDESCR.symbols_num]
1326
        mov     ecx, [esi+DLLDESCR.symbols_num]
1325
        lea     ecx, [ecx*9]
1327
        lea     ecx, [ecx*9]
1326
        add     ecx, ecx
1328
        add     ecx, ecx
1327
        add     ecx, [esi+DLLDESCR.symbols_ptr]
1329
        add     ecx, [esi+DLLDESCR.symbols_ptr]
1328
 
1330
 
1329
        stdcall fix_coff_symbols, edx, [esi+DLLDESCR.symbols_ptr], eax, \
1331
        stdcall fix_coff_symbols, edx, [esi+DLLDESCR.symbols_ptr], eax, \
1330
                ecx, 0
1332
                ecx, 0
1331
;          test eax, eax
1333
;          test eax, eax
1332
;          jnz @F
1334
;          jnz @F
1333
;
1335
;
1334
;@@:
1336
;@@:
1335
 
1337
 
1336
        stdcall get_coff_sym, [esi+DLLDESCR.symbols_ptr], [ebx+COFF_HEADER.nSymbols], szEXPORTS
1338
        stdcall get_coff_sym, [esi+DLLDESCR.symbols_ptr], [ebx+COFF_HEADER.nSymbols], szEXPORTS
1337
        test    eax, eax
1339
        test    eax, eax
1338
        jnz     @F
1340
        jnz     @F
1339
 
1341
 
1340
        stdcall get_coff_sym, [esi+DLLDESCR.symbols_ptr], [ebx+COFF_HEADER.nSymbols], sz_EXPORTS
1342
        stdcall get_coff_sym, [esi+DLLDESCR.symbols_ptr], [ebx+COFF_HEADER.nSymbols], sz_EXPORTS
1341
@@:
1343
@@:
1342
        mov     [esi+DLLDESCR.exports], eax
1344
        mov     [esi+DLLDESCR.exports], eax
1343
 
1345
 
1344
; fix relocs in the hidden copy in kernel memory to default address
1346
; fix relocs in the hidden copy in kernel memory to default address
1345
; it is first fix; usually this will be enough, but second fix
1347
; it is first fix; usually this will be enough, but second fix
1346
; can be necessary if real load address will not equal assumption
1348
; can be necessary if real load address will not equal assumption
1347
        mov     eax, [esi+DLLDESCR.data]
1349
        mov     eax, [esi+DLLDESCR.data]
1348
        sub     eax, [esi+DLLDESCR.defaultbase]
1350
        sub     eax, [esi+DLLDESCR.defaultbase]
1349
        stdcall fix_coff_relocs, ebx, [esi+DLLDESCR.symbols_ptr], eax
1351
        stdcall fix_coff_relocs, ebx, [esi+DLLDESCR.symbols_ptr], eax
1350
 
1352
 
1351
        stdcall kernel_free, [coff]
1353
        stdcall kernel_free, [coff]
1352
 
1354
 
1353
        cli
1355
        cli
1354
; initialize DLLDESCR struct
1356
; initialize DLLDESCR struct
1355
        and     dword [esi+DLLDESCR.refcount], 0; no HDLLs yet; later it will be incremented
1357
        and     dword [esi+DLLDESCR.refcount], 0; no HDLLs yet; later it will be incremented
1356
        mov     [esi+DLLDESCR.fd], dll_list
1358
        mov     [esi+DLLDESCR.fd], dll_list
1357
        mov     eax, [dll_list.bk]
1359
        mov     eax, [dll_list.bk]
1358
        mov     [dll_list.bk], esi
1360
        mov     [dll_list.bk], esi
1359
        mov     [esi+DLLDESCR.bk], eax
1361
        mov     [esi+DLLDESCR.bk], eax
1360
        mov     [eax+DLLDESCR.fd], esi
1362
        mov     [eax+DLLDESCR.fd], esi
1361
.dll_already_loaded:
1363
.dll_already_loaded:
1362
        inc     [esi+DLLDESCR.refcount]
1364
        inc     [esi+DLLDESCR.refcount]
1363
        push    esi
1365
        push    esi
1364
        call    init_heap
1366
        call    init_heap
1365
        pop     esi
1367
        pop     esi
1366
 
1368
 
1367
        mov     edi, [esi+DLLDESCR.size]
1369
        mov     edi, [esi+DLLDESCR.size]
1368
        stdcall user_alloc_at, [esi+DLLDESCR.defaultbase], edi
1370
        stdcall user_alloc_at, [esi+DLLDESCR.defaultbase], edi
1369
        test    eax, eax
1371
        test    eax, eax
1370
        jnz     @f
1372
        jnz     @f
1371
        stdcall user_alloc, edi
1373
        stdcall user_alloc, edi
1372
        test    eax, eax
1374
        test    eax, eax
1373
        jz      .fail_and_dereference
1375
        jz      .fail_and_dereference
1374
@@:
1376
@@:
1375
        mov     [img_base], eax
1377
        mov     [img_base], eax
1376
        mov     eax, sizeof.HDLL
1378
        mov     eax, sizeof.HDLL
1377
        call    malloc
1379
        call    malloc
1378
        test    eax, eax
1380
        test    eax, eax
1379
        jz      .fail_and_free_user
1381
        jz      .fail_and_free_user
1380
        mov     ebx, [CURRENT_TASK]
1382
        mov     ebx, [CURRENT_TASK]
1381
        shl     ebx, 5
1383
        shl     ebx, 5
1382
        mov     edx, [CURRENT_TASK+ebx+TASKDATA.pid]
1384
        mov     edx, [CURRENT_TASK+ebx+TASKDATA.pid]
1383
        mov     [eax+HDLL.pid], edx
1385
        mov     [eax+HDLL.pid], edx
1384
        push    eax
1386
        push    eax
1385
        call    init_dlls_in_thread
1387
        call    init_dlls_in_thread
1386
        pop     ebx
1388
        pop     ebx
1387
        test    eax, eax
1389
        test    eax, eax
1388
        jz      .fail_and_free_user
1390
        jz      .fail_and_free_user
1389
        mov     edx, [eax+HDLL.fd]
1391
        mov     edx, [eax+HDLL.fd]
1390
        mov     [ebx+HDLL.fd], edx
1392
        mov     [ebx+HDLL.fd], edx
1391
        mov     [ebx+HDLL.bk], eax
1393
        mov     [ebx+HDLL.bk], eax
1392
        mov     [eax+HDLL.fd], ebx
1394
        mov     [eax+HDLL.fd], ebx
1393
        mov     [edx+HDLL.bk], ebx
1395
        mov     [edx+HDLL.bk], ebx
1394
        mov     eax, ebx
1396
        mov     eax, ebx
1395
        mov     ebx, [img_base]
1397
        mov     ebx, [img_base]
1396
        mov     [eax+HDLL.base], ebx
1398
        mov     [eax+HDLL.base], ebx
1397
        mov     [eax+HDLL.size], edi
1399
        mov     [eax+HDLL.size], edi
1398
        mov     [eax+HDLL.refcount], 1
1400
        mov     [eax+HDLL.refcount], 1
1399
        mov     [eax+HDLL.parent], esi
1401
        mov     [eax+HDLL.parent], esi
1400
        mov     edx, ebx
1402
        mov     edx, ebx
1401
        shr     edx, 12
1403
        shr     edx, 12
1402
        or      dword [page_tabs+(edx-1)*4], DONT_FREE_BLOCK
1404
        or      dword [page_tabs+(edx-1)*4], DONT_FREE_BLOCK
1403
; copy entries of page table from kernel-side image to usermode
1405
; copy entries of page table from kernel-side image to usermode
1404
; use copy-on-write for user-mode image, so map as readonly
1406
; use copy-on-write for user-mode image, so map as readonly
1405
        xor     edi, edi
1407
        xor     edi, edi
1406
        mov     ecx, [esi+DLLDESCR.data]
1408
        mov     ecx, [esi+DLLDESCR.data]
1407
        shr     ecx, 12
1409
        shr     ecx, 12
1408
.map_pages_loop:
1410
.map_pages_loop:
1409
        mov     eax, [page_tabs+ecx*4]
1411
        mov     eax, [page_tabs+ecx*4]
1410
        and     eax, not 0xFFF
1412
        and     eax, not 0xFFF
1411
        or      al, PG_USER
1413
        or      al, PG_USER
1412
        xchg    eax, [page_tabs+edx*4]
1414
        xchg    eax, [page_tabs+edx*4]
1413
        test    al, 1
1415
        test    al, 1
1414
        jz      @f
1416
        jz      @f
1415
        call    free_page
1417
        call    free_page
1416
@@:
1418
@@:
1417
        invlpg  [ebx+edi]
1419
        invlpg  [ebx+edi]
1418
        inc     ecx
1420
        inc     ecx
1419
        inc     edx
1421
        inc     edx
1420
        add     edi, 0x1000
1422
        add     edi, 0x1000
1421
        cmp     edi, [esi+DLLDESCR.size]
1423
        cmp     edi, [esi+DLLDESCR.size]
1422
        jb      .map_pages_loop
1424
        jb      .map_pages_loop
1423
 
1425
 
1424
; if real user-mode base is not equal to preferred base, relocate image
1426
; if real user-mode base is not equal to preferred base, relocate image
1425
        sub     ebx, [esi+DLLDESCR.defaultbase]
1427
        sub     ebx, [esi+DLLDESCR.defaultbase]
1426
        jz      @f
1428
        jz      @f
1427
        stdcall rebase_coff, [esi+DLLDESCR.coff_hdr], [esi+DLLDESCR.symbols_ptr], ebx
1429
        stdcall rebase_coff, [esi+DLLDESCR.coff_hdr], [esi+DLLDESCR.symbols_ptr], ebx
1428
@@:
1430
@@:
1429
 
1431
 
1430
        mov     eax, [esi+DLLDESCR.exports]
1432
        mov     eax, [esi+DLLDESCR.exports]
1431
        sub     eax, [esi+DLLDESCR.defaultbase]
1433
        sub     eax, [esi+DLLDESCR.defaultbase]
1432
        add     eax, [img_base]
1434
        add     eax, [img_base]
1433
        sti
1435
        sti
1434
        ret
1436
        ret
1435
.fail_and_free_data:
1437
.fail_and_free_data:
1436
        stdcall kernel_free, [esi+DLLDESCR.data]
1438
        stdcall kernel_free, [esi+DLLDESCR.data]
1437
.fail_and_free_dll:
1439
.fail_and_free_dll:
1438
        mov     eax, esi
1440
        mov     eax, esi
1439
        call    free
1441
        call    free
1440
.fail_and_free_coff:
1442
.fail_and_free_coff:
1441
        stdcall kernel_free, [coff]
1443
        stdcall kernel_free, [coff]
1442
.fail:
1444
.fail:
1443
        xor     eax, eax
1445
        xor     eax, eax
1444
        ret
1446
        ret
1445
.fail_and_free_user:
1447
.fail_and_free_user:
1446
        stdcall user_free, [img_base]
1448
        stdcall user_free, [img_base]
1447
.fail_and_dereference:
1449
.fail_and_dereference:
1448
        mov     eax, 1  ; delete 1 reference
1450
        mov     eax, 1  ; delete 1 reference
1449
        call    dereference_dll
1451
        call    dereference_dll
1450
        sti
1452
        sti
1451
        xor     eax, eax
1453
        xor     eax, eax
1452
        ret
1454
        ret
1453
endp
1455
endp
1454
 
1456
 
1455
; initialize [APPDATA.dlls_list_ptr] for given thread
1457
; initialize [APPDATA.dlls_list_ptr] for given thread
1456
; DLL is per-process object, so APPDATA.dlls_list_ptr must be
1458
; DLL is per-process object, so APPDATA.dlls_list_ptr must be
1457
; kept in sync for all threads of one process.
1459
; kept in sync for all threads of one process.
1458
; out: eax = APPDATA.dlls_list_ptr if all is OK,
1460
; out: eax = APPDATA.dlls_list_ptr if all is OK,
1459
; NULL if memory allocation failed
1461
; NULL if memory allocation failed
1460
init_dlls_in_thread:
1462
init_dlls_in_thread:
1461
        mov     ebx, [current_slot]
1463
        mov     ebx, [current_slot]
1462
        mov     eax, [ebx+APPDATA.dlls_list_ptr]
1464
        mov     eax, [ebx+APPDATA.dlls_list_ptr]
1463
        test    eax, eax
1465
        test    eax, eax
1464
        jnz     .ret
1466
        jnz     .ret
1465
        push    [ebx+APPDATA.dir_table]
1467
        push    [ebx+APPDATA.dir_table]
1466
        mov     eax, 8
1468
        mov     eax, 8
1467
        call    malloc
1469
        call    malloc
1468
        pop     edx
1470
        pop     edx
1469
        test    eax, eax
1471
        test    eax, eax
1470
        jz      .ret
1472
        jz      .ret
1471
        mov     [eax], eax
1473
        mov     [eax], eax
1472
        mov     [eax+4], eax
1474
        mov     [eax+4], eax
1473
        mov     ecx, [TASK_COUNT]
1475
        mov     ecx, [TASK_COUNT]
1474
        mov     ebx, SLOT_BASE+256
1476
        mov     ebx, SLOT_BASE+256
1475
.set:
1477
.set:
1476
        cmp     [ebx+APPDATA.dir_table], edx
1478
        cmp     [ebx+APPDATA.dir_table], edx
1477
        jnz     @f
1479
        jnz     @f
1478
        mov     [ebx+APPDATA.dlls_list_ptr], eax
1480
        mov     [ebx+APPDATA.dlls_list_ptr], eax
1479
@@:
1481
@@:
1480
        add     ebx, 256
1482
        add     ebx, 256
1481
        dec     ecx
1483
        dec     ecx
1482
        jnz     .set
1484
        jnz     .set
1483
.ret:
1485
.ret:
1484
        ret
1486
        ret
1485
 
1487
 
1486
; in: eax = number of references to delete, esi -> DLLDESCR struc
1488
; in: eax = number of references to delete, esi -> DLLDESCR struc
1487
dereference_dll:
1489
dereference_dll:
1488
        sub     [esi+DLLDESCR.refcount], eax
1490
        sub     [esi+DLLDESCR.refcount], eax
1489
        jnz     .ret
1491
        jnz     .ret
1490
        mov     eax, [esi+DLLDESCR.fd]
1492
        mov     eax, [esi+DLLDESCR.fd]
1491
        mov     edx, [esi+DLLDESCR.bk]
1493
        mov     edx, [esi+DLLDESCR.bk]
1492
        mov     [eax+DLLDESCR.bk], edx
1494
        mov     [eax+DLLDESCR.bk], edx
1493
        mov     [edx+DLLDESCR.fd], eax
1495
        mov     [edx+DLLDESCR.fd], eax
1494
        stdcall kernel_free, [esi+DLLDESCR.coff_hdr]
1496
        stdcall kernel_free, [esi+DLLDESCR.coff_hdr]
1495
        stdcall kernel_free, [esi+DLLDESCR.data]
1497
        stdcall kernel_free, [esi+DLLDESCR.data]
1496
        mov     eax, esi
1498
        mov     eax, esi
1497
        call    free
1499
        call    free
1498
.ret:
1500
.ret:
1499
        ret
1501
        ret
1500
 
1502
 
1501
destroy_hdll:
1503
destroy_hdll:
1502
        push    ebx ecx esi edi
1504
        push    ebx ecx esi edi
1503
        push    eax
1505
        push    eax
1504
        mov     ebx, [eax+HDLL.base]
1506
        mov     ebx, [eax+HDLL.base]
1505
        mov     esi, [eax+HDLL.parent]
1507
        mov     esi, [eax+HDLL.parent]
1506
        mov     edx, [esi+DLLDESCR.size]
1508
        mov     edx, [esi+DLLDESCR.size]
1507
; The following actions require the context of application where HDLL is mapped.
1509
; The following actions require the context of application where HDLL is mapped.
1508
; However, destroy_hdll can be called in the context of OS thread when
1510
; However, destroy_hdll can be called in the context of OS thread when
1509
; cleaning up objects created by the application which is destroyed.
1511
; cleaning up objects created by the application which is destroyed.
1510
; So remember current cr3 and set it to page table of target.
1512
; So remember current cr3 and set it to page table of target.
1511
        mov     eax, [ecx+APPDATA.dir_table]
1513
        mov     eax, [ecx+APPDATA.dir_table]
1512
; Because we cheat with cr3, disable interrupts: task switch would restore
1514
; Because we cheat with cr3, disable interrupts: task switch would restore
1513
; page table from APPDATA of current thread.
1515
; page table from APPDATA of current thread.
1514
; Also set [current_slot] because it is used by user_free.
1516
; Also set [current_slot] because it is used by user_free.
1515
        pushf
1517
        pushf
1516
        cli
1518
        cli
1517
        push    [current_slot]
1519
        push    [current_slot]
1518
        mov     [current_slot], ecx
1520
        mov     [current_slot], ecx
1519
        mov     ecx, cr3
1521
        mov     ecx, cr3
1520
        push    ecx
1522
        push    ecx
1521
        mov     cr3, eax
1523
        mov     cr3, eax
1522
        push    ebx     ; argument for user_free
1524
        push    ebx     ; argument for user_free
1523
        mov     eax, ebx
1525
        mov     eax, ebx
1524
        shr     ebx, 12
1526
        shr     ebx, 12
1525
        push    ebx
1527
        push    ebx
1526
        mov     esi, [esi+DLLDESCR.data]
1528
        mov     esi, [esi+DLLDESCR.data]
1527
        shr     esi, 12
1529
        shr     esi, 12
1528
.unmap_loop:
1530
.unmap_loop:
1529
        push    eax
1531
        push    eax
1530
        mov     eax, 2
1532
        mov     eax, 2
1531
        xchg    eax, [page_tabs+ebx*4]
1533
        xchg    eax, [page_tabs+ebx*4]
1532
        mov     ecx, [page_tabs+esi*4]
1534
        mov     ecx, [page_tabs+esi*4]
1533
        and     eax, not 0xFFF
1535
        and     eax, not 0xFFF
1534
        and     ecx, not 0xFFF
1536
        and     ecx, not 0xFFF
1535
        cmp     eax, ecx
1537
        cmp     eax, ecx
1536
        jz      @f
1538
        jz      @f
1537
        call    free_page
1539
        call    free_page
1538
@@:
1540
@@:
1539
        pop     eax
1541
        pop     eax
1540
        invlpg  [eax]
1542
        invlpg  [eax]
1541
        add     eax, 0x1000
1543
        add     eax, 0x1000
1542
        inc     ebx
1544
        inc     ebx
1543
        inc     esi
1545
        inc     esi
1544
        sub     edx, 0x1000
1546
        sub     edx, 0x1000
1545
        ja      .unmap_loop
1547
        ja      .unmap_loop
1546
        pop     ebx
1548
        pop     ebx
1547
        and     dword [page_tabs+(ebx-1)*4], not DONT_FREE_BLOCK
1549
        and     dword [page_tabs+(ebx-1)*4], not DONT_FREE_BLOCK
1548
        call    user_free
1550
        call    user_free
1549
; Restore context.
1551
; Restore context.
1550
        pop     eax
1552
        pop     eax
1551
        mov     cr3, eax
1553
        mov     cr3, eax
1552
        pop     [current_slot]
1554
        pop     [current_slot]
1553
        popf
1555
        popf
1554
; Ok, cheating is done.
1556
; Ok, cheating is done.
1555
        pop     eax
1557
        pop     eax
1556
        push    eax
1558
        push    eax
1557
        mov     esi, [eax+HDLL.parent]
1559
        mov     esi, [eax+HDLL.parent]
1558
        mov     eax, [eax+HDLL.refcount]
1560
        mov     eax, [eax+HDLL.refcount]
1559
        call    dereference_dll
1561
        call    dereference_dll
1560
        pop     eax
1562
        pop     eax
1561
        mov     edx, [eax+HDLL.bk]
1563
        mov     edx, [eax+HDLL.bk]
1562
        mov     ebx, [eax+HDLL.fd]
1564
        mov     ebx, [eax+HDLL.fd]
1563
        mov     [ebx+HDLL.bk], edx
1565
        mov     [ebx+HDLL.bk], edx
1564
        mov     [edx+HDLL.fd], ebx
1566
        mov     [edx+HDLL.fd], ebx
1565
        call    free
1567
        call    free
1566
        pop     edi esi ecx ebx
1568
        pop     edi esi ecx ebx
1567
        ret
1569
        ret
1568
 
1570
 
1569
; ecx -> APPDATA for slot, esi = dlls_list_ptr
1571
; ecx -> APPDATA for slot, esi = dlls_list_ptr
1570
destroy_all_hdlls:
1572
destroy_all_hdlls:
1571
        test    esi, esi
1573
        test    esi, esi
1572
        jz      .ret
1574
        jz      .ret
1573
.loop:
1575
.loop:
1574
        mov     eax, [esi+HDLL.fd]
1576
        mov     eax, [esi+HDLL.fd]
1575
        cmp     eax, esi
1577
        cmp     eax, esi
1576
        jz      free
1578
        jz      free
1577
        call    destroy_hdll
1579
        call    destroy_hdll
1578
        jmp     .loop
1580
        jmp     .loop
1579
.ret:
1581
.ret:
1580
        ret
1582
        ret
1581
 
1583
 
1582
align 4
1584
align 4
1583
stop_all_services:
1585
stop_all_services:
1584
        push    ebp
1586
        push    ebp
1585
        mov     edx, [srv.fd]
1587
        mov     edx, [srv.fd]
1586
.next:
1588
.next:
1587
        cmp     edx, srv.fd-SRV.fd
1589
        cmp     edx, srv.fd-SRV.fd
1588
        je      .done
1590
        je      .done
1589
        cmp     [edx+SRV.magic], ' SRV'
1591
        cmp     [edx+SRV.magic], ' SRV'
1590
        jne     .next
1592
        jne     .next
1591
        cmp     [edx+SRV.size], sizeof.SRV
1593
        cmp     [edx+SRV.size], sizeof.SRV
1592
        jne     .next
1594
        jne     .next
1593
 
1595
 
1594
        mov     ebx, [edx+SRV.entry]
1596
        mov     ebx, [edx+SRV.entry]
1595
        mov     edx, [edx+SRV.fd]
1597
        mov     edx, [edx+SRV.fd]
1596
        test    ebx, ebx
1598
        test    ebx, ebx
1597
        jz      .next
1599
        jz      .next
1598
 
1600
 
1599
        push    edx
1601
        push    edx
1600
        mov     ebp, esp
1602
        mov     ebp, esp
1601
        push    0
1603
        push    0
1602
        push    -1
1604
        push    -1
1603
        call    ebx
1605
        call    ebx
1604
        mov     esp, ebp
1606
        mov     esp, ebp
1605
        pop     edx
1607
        pop     edx
1606
        jmp     .next
1608
        jmp     .next
1607
.done:
1609
.done:
1608
        pop     ebp
1610
        pop     ebp
1609
        ret
1611
        ret
1610
 
1612
 
1611
; param
1613
; param
1612
;  eax= size
1614
;  eax= size
1613
;  ebx= pid
1615
;  ebx= pid
1614
 
1616
 
1615
align 4
1617
align 4
1616
create_kernel_object:
1618
create_kernel_object:
1617
 
1619
 
1618
        push    ebx
1620
        push    ebx
1619
        call    malloc
1621
        call    malloc
1620
        pop     ebx
1622
        pop     ebx
1621
        test    eax, eax
1623
        test    eax, eax
1622
        jz      .fail
1624
        jz      .fail
1623
 
1625
 
1624
        mov     ecx, [current_slot]
1626
        mov     ecx, [current_slot]
1625
        add     ecx, APP_OBJ_OFFSET
1627
        add     ecx, APP_OBJ_OFFSET
1626
 
1628
 
1627
        pushfd
1629
        pushfd
1628
        cli
1630
        cli
1629
        mov     edx, [ecx+APPOBJ.fd]
1631
        mov     edx, [ecx+APPOBJ.fd]
1630
        mov     [eax+APPOBJ.fd], edx
1632
        mov     [eax+APPOBJ.fd], edx
1631
        mov     [eax+APPOBJ.bk], ecx
1633
        mov     [eax+APPOBJ.bk], ecx
1632
        mov     [eax+APPOBJ.pid], ebx
1634
        mov     [eax+APPOBJ.pid], ebx
1633
 
1635
 
1634
        mov     [ecx+APPOBJ.fd], eax
1636
        mov     [ecx+APPOBJ.fd], eax
1635
        mov     [edx+APPOBJ.bk], eax
1637
        mov     [edx+APPOBJ.bk], eax
1636
        popfd
1638
        popfd
1637
.fail:
1639
.fail:
1638
        ret
1640
        ret
1639
 
1641
 
1640
; param
1642
; param
1641
;  eax= object
1643
;  eax= object
1642
 
1644
 
1643
align 4
1645
align 4
1644
destroy_kernel_object:
1646
destroy_kernel_object:
1645
 
1647
 
1646
        pushfd
1648
        pushfd
1647
        cli
1649
        cli
1648
        mov     ebx, [eax+APPOBJ.fd]
1650
        mov     ebx, [eax+APPOBJ.fd]
1649
        mov     ecx, [eax+APPOBJ.bk]
1651
        mov     ecx, [eax+APPOBJ.bk]
1650
        mov     [ebx+APPOBJ.bk], ecx
1652
        mov     [ebx+APPOBJ.bk], ecx
1651
        mov     [ecx+APPOBJ.fd], ebx
1653
        mov     [ecx+APPOBJ.fd], ebx
1652
        popfd
1654
        popfd
1653
 
1655
 
1654
        xor     edx, edx       ;clear common header
1656
        xor     edx, edx       ;clear common header
1655
        mov     [eax], edx
1657
        mov     [eax], edx
1656
        mov     [eax+4], edx
1658
        mov     [eax+4], edx
1657
        mov     [eax+8], edx
1659
        mov     [eax+8], edx
1658
        mov     [eax+12], edx
1660
        mov     [eax+12], edx
1659
        mov     [eax+16], edx
1661
        mov     [eax+16], edx
1660
 
1662
 
1661
        call    free           ;release object memory
1663
        call    free           ;release object memory
1662
        ret
1664
        ret