Subversion Repositories Kolibri OS

Rev

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

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