Subversion Repositories Kolibri OS

Rev

Rev 9872 | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

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