Subversion Repositories Kolibri OS

Rev

Rev 2486 | Rev 2500 | Go to most recent revision | Only display areas with differences | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

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