Subversion Repositories Kolibri OS

Rev

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

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