Subversion Repositories Kolibri OS

Rev

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

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