Subversion Repositories Kolibri OS

Rev

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

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