Subversion Repositories Kolibri OS

Rev

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

Rev 2455 Rev 2486
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: 2455 $
8
$Revision: 2486 $
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
 
440
        pushfd
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
-
 
450
        xchg    eax, [unpack_mutex]
-
 
451
        test    eax, eax
-
 
452
        jnz     .wait_lock
441
        cli
453
        pop     eax
-
 
454
 
442
        stdcall unpack, [file], eax
455
        stdcall unpack, [file], eax
-
 
456
 
443
        popfd
457
        mov     [unpack_mutex], 0
-
 
458
 
444
        stdcall kernel_free, [file]
459
        stdcall kernel_free, [file]
445
        mov     eax, [file2]
460
        mov     eax, [file2]
446
        mov     ebx, [file_size]
461
        mov     ebx, [file_size]
447
.exit:
462
.exit:
448
        push    eax
463
        push    eax
449
        lea     edi, [eax+ebx]    ;cleanup remain space
464
        lea     edi, [eax+ebx]    ;cleanup remain space
450
        mov     ecx, 4096         ;from file end
465
        mov     ecx, 4096         ;from file end
451
        and     ebx, 4095
466
        and     ebx, 4095
452
        jz      @f
467
        jz      @f
453
        sub     ecx, ebx
468
        sub     ecx, ebx
454
        xor     eax, eax
469
        xor     eax, eax
455
        cld
470
        cld
456
        rep stosb
471
        rep stosb
457
@@:
472
@@:
458
        mov     ebx, [file_size]
473
        mov     ebx, [file_size]
459
        pop     eax
474
        pop     eax
460
        pop     edi
475
        pop     edi
461
        pop     esi
476
        pop     esi
462
        ret
477
        ret
463
.cleanup:
478
.cleanup:
464
        stdcall kernel_free, [file]
479
        stdcall kernel_free, [file]
465
.fail:
480
.fail:
466
        xor     eax, eax
481
        xor     eax, eax
467
        xor     ebx, ebx
482
        xor     ebx, ebx
468
        pop     edi
483
        pop     edi
469
        pop     esi
484
        pop     esi
470
        ret
485
        ret
471
endp
486
endp
-
 
487
 
-
 
488
iglobal
-
 
489
align 4
-
 
490
unpack_mutex dd 0
-
 
491
endg
472
 
492
 
473
align 4
493
align 4
474
proc get_proc_ex stdcall, proc_name:dword, imports:dword
494
proc get_proc_ex stdcall, proc_name:dword, imports:dword
475
 
495
 
476
.look_up:
496
.look_up:
477
        mov     edx, [imports]
497
        mov     edx, [imports]
478
        test    edx, edx
498
        test    edx, edx
479
        jz      .end
499
        jz      .end
480
        mov     edx, [edx]
500
        mov     edx, [edx]
481
        test    edx, edx
501
        test    edx, edx
482
        jz      .end
502
        jz      .end
483
.next:
503
.next:
484
        mov     eax, [edx]
504
        mov     eax, [edx]
485
        test    eax, eax
505
        test    eax, eax
486
        jz      .next_table
506
        jz      .next_table
487
 
507
 
488
        push    edx
508
        push    edx
489
        stdcall strncmp, eax, [proc_name], 256
509
        stdcall strncmp, eax, [proc_name], 256
490
        pop     edx
510
        pop     edx
491
        test    eax, eax
511
        test    eax, eax
492
        jz      .ok
512
        jz      .ok
493
 
513
 
494
        add     edx, 8
514
        add     edx, 8
495
        jmp     .next
515
        jmp     .next
496
.next_table:
516
.next_table:
497
        add     [imports], 4
517
        add     [imports], 4
498
        jmp     .look_up
518
        jmp     .look_up
499
.ok:
519
.ok:
500
        mov     eax, [edx+4]
520
        mov     eax, [edx+4]
501
        ret
521
        ret
502
.end:
522
.end:
503
        xor     eax, eax
523
        xor     eax, eax
504
        ret
524
        ret
505
endp
525
endp
506
 
526
 
507
align 4
527
align 4
508
proc fix_coff_symbols stdcall uses ebx esi, sec:dword, symbols:dword,\
528
proc fix_coff_symbols stdcall uses ebx esi, sec:dword, symbols:dword,\
509
                      sym_count:dword, strings:dword, imports:dword
529
                      sym_count:dword, strings:dword, imports:dword
510
           locals
530
           locals
511
             retval dd ?
531
             retval dd ?
512
           endl
532
           endl
513
 
533
 
514
        mov     edi, [symbols]
534
        mov     edi, [symbols]
515
        mov     [retval], 1
535
        mov     [retval], 1
516
.fix:
536
.fix:
517
        movzx   ebx, [edi+COFF_SYM.SectionNumber]
537
        movzx   ebx, [edi+COFF_SYM.SectionNumber]
518
        test    ebx, ebx
538
        test    ebx, ebx
519
        jnz     .internal
539
        jnz     .internal
520
        mov     eax, dword [edi+COFF_SYM.Name]
540
        mov     eax, dword [edi+COFF_SYM.Name]
521
        test    eax, eax
541
        test    eax, eax
522
        jnz     @F
542
        jnz     @F
523
 
543
 
524
        mov     edi, [edi+4]
544
        mov     edi, [edi+4]
525
        add     edi, [strings]
545
        add     edi, [strings]
526
@@:
546
@@:
527
        push    edi
547
        push    edi
528
        stdcall get_proc_ex, edi, [imports]
548
        stdcall get_proc_ex, edi, [imports]
529
        pop     edi
549
        pop     edi
530
 
550
 
531
        xor     ebx, ebx
551
        xor     ebx, ebx
532
        test    eax, eax
552
        test    eax, eax
533
        jnz     @F
553
        jnz     @F
534
 
554
 
535
        mov     esi, msg_unresolved
555
        mov     esi, msg_unresolved
536
        call    sys_msg_board_str
556
        call    sys_msg_board_str
537
        mov     esi, edi
557
        mov     esi, edi
538
        call    sys_msg_board_str
558
        call    sys_msg_board_str
539
        mov     esi, msg_CR
559
        mov     esi, msg_CR
540
        call    sys_msg_board_str
560
        call    sys_msg_board_str
541
 
561
 
542
        mov     [retval], 0
562
        mov     [retval], 0
543
@@:
563
@@:
544
        mov     edi, [symbols]
564
        mov     edi, [symbols]
545
        mov     [edi+COFF_SYM.Value], eax
565
        mov     [edi+COFF_SYM.Value], eax
546
        jmp     .next
566
        jmp     .next
547
.internal:
567
.internal:
548
        cmp     bx, -1
568
        cmp     bx, -1
549
        je      .next
569
        je      .next
550
        cmp     bx, -2
570
        cmp     bx, -2
551
        je      .next
571
        je      .next
552
 
572
 
553
        dec     ebx
573
        dec     ebx
554
        shl     ebx, 3
574
        shl     ebx, 3
555
        lea     ebx, [ebx+ebx*4]
575
        lea     ebx, [ebx+ebx*4]
556
        add     ebx, [sec]
576
        add     ebx, [sec]
557
 
577
 
558
        mov     eax, [ebx+COFF_SECTION.VirtualAddress]
578
        mov     eax, [ebx+COFF_SECTION.VirtualAddress]
559
        add     [edi+COFF_SYM.Value], eax
579
        add     [edi+COFF_SYM.Value], eax
560
.next:
580
.next:
561
        add     edi, sizeof.COFF_SYM
581
        add     edi, sizeof.COFF_SYM
562
        mov     [symbols], edi
582
        mov     [symbols], edi
563
        dec     [sym_count]
583
        dec     [sym_count]
564
        jnz     .fix
584
        jnz     .fix
565
        mov     eax, [retval]
585
        mov     eax, [retval]
566
        ret
586
        ret
567
endp
587
endp
568
 
588
 
569
align 4
589
align 4
570
proc fix_coff_relocs stdcall uses ebx esi, coff:dword, sym:dword, \
590
proc fix_coff_relocs stdcall uses ebx esi, coff:dword, sym:dword, \
571
        delta:dword
591
        delta:dword
572
           locals
592
           locals
573
             n_sec     dd ?
593
             n_sec     dd ?
574
           endl
594
           endl
575
 
595
 
576
        mov     eax, [coff]
596
        mov     eax, [coff]
577
        movzx   ebx, [eax+COFF_HEADER.nSections]
597
        movzx   ebx, [eax+COFF_HEADER.nSections]
578
        mov     [n_sec], ebx
598
        mov     [n_sec], ebx
579
        lea     esi, [eax+20]
599
        lea     esi, [eax+20]
580
.fix_sec:
600
.fix_sec:
581
        mov     edi, [esi+COFF_SECTION.PtrReloc]
601
        mov     edi, [esi+COFF_SECTION.PtrReloc]
582
        add     edi, [coff]
602
        add     edi, [coff]
583
 
603
 
584
        movzx   ecx, [esi+COFF_SECTION.NumReloc]
604
        movzx   ecx, [esi+COFF_SECTION.NumReloc]
585
        test    ecx, ecx
605
        test    ecx, ecx
586
        jz      .next
606
        jz      .next
587
.reloc_loop:
607
.reloc_loop:
588
        mov     ebx, [edi+COFF_RELOC.SymIndex]
608
        mov     ebx, [edi+COFF_RELOC.SymIndex]
589
        add     ebx, ebx
609
        add     ebx, ebx
590
        lea     ebx, [ebx+ebx*8]
610
        lea     ebx, [ebx+ebx*8]
591
        add     ebx, [sym]
611
        add     ebx, [sym]
592
 
612
 
593
        mov     edx, [ebx+COFF_SYM.Value]
613
        mov     edx, [ebx+COFF_SYM.Value]
594
 
614
 
595
        cmp     [edi+COFF_RELOC.Type], 6
615
        cmp     [edi+COFF_RELOC.Type], 6
596
        je      .dir_32
616
        je      .dir_32
597
 
617
 
598
        cmp     [edi+COFF_RELOC.Type], 20
618
        cmp     [edi+COFF_RELOC.Type], 20
599
        jne     .next_reloc
619
        jne     .next_reloc
600
.rel_32:
620
.rel_32:
601
        mov     eax, [edi+COFF_RELOC.VirtualAddress]
621
        mov     eax, [edi+COFF_RELOC.VirtualAddress]
602
        add     eax, [esi+COFF_SECTION.VirtualAddress]
622
        add     eax, [esi+COFF_SECTION.VirtualAddress]
603
        sub     edx, eax
623
        sub     edx, eax
604
        sub     edx, 4
624
        sub     edx, 4
605
        jmp     .fix
625
        jmp     .fix
606
.dir_32:
626
.dir_32:
607
        mov     eax, [edi+COFF_RELOC.VirtualAddress]
627
        mov     eax, [edi+COFF_RELOC.VirtualAddress]
608
        add     eax, [esi+COFF_SECTION.VirtualAddress]
628
        add     eax, [esi+COFF_SECTION.VirtualAddress]
609
.fix:
629
.fix:
610
        add     eax, [delta]
630
        add     eax, [delta]
611
        add     [eax], edx
631
        add     [eax], edx
612
.next_reloc:
632
.next_reloc:
613
        add     edi, 10
633
        add     edi, 10
614
        dec     ecx
634
        dec     ecx
615
        jnz     .reloc_loop
635
        jnz     .reloc_loop
616
.next:
636
.next:
617
        add     esi, sizeof.COFF_SECTION
637
        add     esi, sizeof.COFF_SECTION
618
        dec     [n_sec]
638
        dec     [n_sec]
619
        jnz     .fix_sec
639
        jnz     .fix_sec
620
.exit:
640
.exit:
621
        ret
641
        ret
622
endp
642
endp
623
 
643
 
624
align 4
644
align 4
625
proc rebase_coff stdcall uses ebx esi, coff:dword, sym:dword, \
645
proc rebase_coff stdcall uses ebx esi, coff:dword, sym:dword, \
626
        delta:dword
646
        delta:dword
627
           locals
647
           locals
628
             n_sec     dd ?
648
             n_sec     dd ?
629
           endl
649
           endl
630
 
650
 
631
        mov     eax, [coff]
651
        mov     eax, [coff]
632
        movzx   ebx, [eax+COFF_HEADER.nSections]
652
        movzx   ebx, [eax+COFF_HEADER.nSections]
633
        mov     [n_sec], ebx
653
        mov     [n_sec], ebx
634
        lea     esi, [eax+20]
654
        lea     esi, [eax+20]
635
        mov     edx, [delta]
655
        mov     edx, [delta]
636
.fix_sec:
656
.fix_sec:
637
        mov     edi, [esi+COFF_SECTION.PtrReloc]
657
        mov     edi, [esi+COFF_SECTION.PtrReloc]
638
        add     edi, [coff]
658
        add     edi, [coff]
639
 
659
 
640
        movzx   ecx, [esi+COFF_SECTION.NumReloc]
660
        movzx   ecx, [esi+COFF_SECTION.NumReloc]
641
        test    ecx, ecx
661
        test    ecx, ecx
642
        jz      .next
662
        jz      .next
643
.reloc_loop:
663
.reloc_loop:
644
        cmp     [edi+COFF_RELOC.Type], 6
664
        cmp     [edi+COFF_RELOC.Type], 6
645
        jne     .next_reloc
665
        jne     .next_reloc
646
.dir_32:
666
.dir_32:
647
        mov     eax, [edi+COFF_RELOC.VirtualAddress]
667
        mov     eax, [edi+COFF_RELOC.VirtualAddress]
648
        add     eax, [esi+COFF_SECTION.VirtualAddress]
668
        add     eax, [esi+COFF_SECTION.VirtualAddress]
649
        add     [eax+edx], edx
669
        add     [eax+edx], edx
650
.next_reloc:
670
.next_reloc:
651
        add     edi, 10
671
        add     edi, 10
652
        dec     ecx
672
        dec     ecx
653
        jnz     .reloc_loop
673
        jnz     .reloc_loop
654
.next:
674
.next:
655
        add     esi, sizeof.COFF_SECTION
675
        add     esi, sizeof.COFF_SECTION
656
        dec     [n_sec]
676
        dec     [n_sec]
657
        jnz     .fix_sec
677
        jnz     .fix_sec
658
.exit:
678
.exit:
659
        ret
679
        ret
660
endp
680
endp
661
 
681
 
662
align 4
682
align 4
663
proc load_driver stdcall, driver_name:dword
683
proc load_driver stdcall, driver_name:dword
664
           locals
684
           locals
665
             coff      dd ?
685
             coff      dd ?
666
             sym       dd ?
686
             sym       dd ?
667
             strings   dd ?
687
             strings   dd ?
668
             img_size  dd ?
688
             img_size  dd ?
669
             img_base  dd ?
689
             img_base  dd ?
670
             start     dd ?
690
             start     dd ?
671
 
691
 
672
             exports   dd ?   ;fake exports table
692
             exports   dd ?   ;fake exports table
673
                       dd ?
693
                       dd ?
674
             file_name rb 13+16+4+1      ; '/sys/drivers/.obj'
694
             file_name rb 13+16+4+1      ; '/sys/drivers/.obj'
675
           endl
695
           endl
676
 
696
 
677
        lea     edx, [file_name]
697
        lea     edx, [file_name]
678
        mov     dword [edx], '/sys'
698
        mov     dword [edx], '/sys'
679
        mov     dword [edx+4], '/dri'
699
        mov     dword [edx+4], '/dri'
680
        mov     dword [edx+8], 'vers'
700
        mov     dword [edx+8], 'vers'
681
        mov     byte [edx+12], '/'
701
        mov     byte [edx+12], '/'
682
        mov     esi, [driver_name]
702
        mov     esi, [driver_name]
683
.redo:
703
.redo:
684
        lea     edx, [file_name]
704
        lea     edx, [file_name]
685
        lea     edi, [edx+13]
705
        lea     edi, [edx+13]
686
        mov     ecx, 16
706
        mov     ecx, 16
687
@@:
707
@@:
688
        lodsb
708
        lodsb
689
        test    al, al
709
        test    al, al
690
        jz      @f
710
        jz      @f
691
        stosb
711
        stosb
692
        loop    @b
712
        loop    @b
693
@@:
713
@@:
694
        mov     dword [edi], '.obj'
714
        mov     dword [edi], '.obj'
695
        mov     byte [edi+4], 0
715
        mov     byte [edi+4], 0
696
        stdcall load_file, edx
716
        stdcall load_file, edx
697
 
717
 
698
        test    eax, eax
718
        test    eax, eax
699
        jz      .exit
719
        jz      .exit
700
 
720
 
701
        mov     [coff], eax
721
        mov     [coff], eax
702
 
722
 
703
        movzx   ecx, [eax+COFF_HEADER.nSections]
723
        movzx   ecx, [eax+COFF_HEADER.nSections]
704
        xor     ebx, ebx
724
        xor     ebx, ebx
705
 
725
 
706
        lea     edx, [eax+20]
726
        lea     edx, [eax+20]
707
@@:
727
@@:
708
        add     ebx, [edx+COFF_SECTION.SizeOfRawData]
728
        add     ebx, [edx+COFF_SECTION.SizeOfRawData]
709
        add     ebx, 15
729
        add     ebx, 15
710
        and     ebx, not 15
730
        and     ebx, not 15
711
        add     edx, sizeof.COFF_SECTION
731
        add     edx, sizeof.COFF_SECTION
712
        dec     ecx
732
        dec     ecx
713
        jnz     @B
733
        jnz     @B
714
        mov     [img_size], ebx
734
        mov     [img_size], ebx
715
 
735
 
716
        stdcall kernel_alloc, ebx
736
        stdcall kernel_alloc, ebx
717
        test    eax, eax
737
        test    eax, eax
718
        jz      .fail
738
        jz      .fail
719
        mov     [img_base], eax
739
        mov     [img_base], eax
720
 
740
 
721
        mov     edi, eax
741
        mov     edi, eax
722
        xor     eax, eax
742
        xor     eax, eax
723
        mov     ecx, [img_size]
743
        mov     ecx, [img_size]
724
        add     ecx, 4095
744
        add     ecx, 4095
725
        and     ecx, not 4095
745
        and     ecx, not 4095
726
        shr     ecx, 2
746
        shr     ecx, 2
727
        cld
747
        cld
728
        rep stosd
748
        rep stosd
729
 
749
 
730
        mov     edx, [coff]
750
        mov     edx, [coff]
731
        movzx   ebx, [edx+COFF_HEADER.nSections]
751
        movzx   ebx, [edx+COFF_HEADER.nSections]
732
        mov     edi, [img_base]
752
        mov     edi, [img_base]
733
        lea     eax, [edx+20]
753
        lea     eax, [edx+20]
734
@@:
754
@@:
735
        mov     [eax+COFF_SECTION.VirtualAddress], edi
755
        mov     [eax+COFF_SECTION.VirtualAddress], edi
736
        mov     esi, [eax+COFF_SECTION.PtrRawData]
756
        mov     esi, [eax+COFF_SECTION.PtrRawData]
737
        test    esi, esi
757
        test    esi, esi
738
        jnz     .copy
758
        jnz     .copy
739
        add     edi, [eax+COFF_SECTION.SizeOfRawData]
759
        add     edi, [eax+COFF_SECTION.SizeOfRawData]
740
        jmp     .next
760
        jmp     .next
741
.copy:
761
.copy:
742
        add     esi, edx
762
        add     esi, edx
743
        mov     ecx, [eax+COFF_SECTION.SizeOfRawData]
763
        mov     ecx, [eax+COFF_SECTION.SizeOfRawData]
744
        cld
764
        cld
745
        rep movsb
765
        rep movsb
746
.next:
766
.next:
747
        add     edi, 15
767
        add     edi, 15
748
        and     edi, not 15
768
        and     edi, not 15
749
        add     eax, sizeof.COFF_SECTION
769
        add     eax, sizeof.COFF_SECTION
750
        dec     ebx
770
        dec     ebx
751
        jnz     @B
771
        jnz     @B
752
 
772
 
753
        mov     ebx, [edx+COFF_HEADER.pSymTable]
773
        mov     ebx, [edx+COFF_HEADER.pSymTable]
754
        add     ebx, edx
774
        add     ebx, edx
755
        mov     [sym], ebx
775
        mov     [sym], ebx
756
        mov     ecx, [edx+COFF_HEADER.nSymbols]
776
        mov     ecx, [edx+COFF_HEADER.nSymbols]
757
        add     ecx, ecx
777
        add     ecx, ecx
758
        lea     ecx, [ecx+ecx*8];ecx*=18 = nSymbols*CSYM_SIZE
778
        lea     ecx, [ecx+ecx*8];ecx*=18 = nSymbols*CSYM_SIZE
759
        add     ecx, [sym]
779
        add     ecx, [sym]
760
        mov     [strings], ecx
780
        mov     [strings], ecx
761
 
781
 
762
        lea     ebx, [exports]
782
        lea     ebx, [exports]
763
        mov     dword [ebx], kernel_export
783
        mov     dword [ebx], kernel_export
764
        mov     dword [ebx+4], 0
784
        mov     dword [ebx+4], 0
765
        lea     eax, [edx+20]
785
        lea     eax, [edx+20]
766
 
786
 
767
        stdcall fix_coff_symbols, eax, [sym], [edx+COFF_HEADER.nSymbols], \
787
        stdcall fix_coff_symbols, eax, [sym], [edx+COFF_HEADER.nSymbols], \
768
                [strings], ebx
788
                [strings], ebx
769
        test    eax, eax
789
        test    eax, eax
770
        jz      .link_fail
790
        jz      .link_fail
771
 
791
 
772
        mov     ebx, [coff]
792
        mov     ebx, [coff]
773
        stdcall fix_coff_relocs, ebx, [sym], 0
793
        stdcall fix_coff_relocs, ebx, [sym], 0
774
 
794
 
775
        stdcall get_coff_sym, [sym], [ebx+COFF_HEADER.nSymbols], szVersion
795
        stdcall get_coff_sym, [sym], [ebx+COFF_HEADER.nSymbols], szVersion
776
        test    eax, eax
796
        test    eax, eax
777
        jz      .link_fail
797
        jz      .link_fail
778
 
798
 
779
        mov     eax, [eax]
799
        mov     eax, [eax]
780
        shr     eax, 16
800
        shr     eax, 16
781
        cmp     eax, DRV_COMPAT
801
        cmp     eax, DRV_COMPAT
782
        jb      .ver_fail
802
        jb      .ver_fail
783
 
803
 
784
        cmp     eax, DRV_CURRENT
804
        cmp     eax, DRV_CURRENT
785
        ja      .ver_fail
805
        ja      .ver_fail
786
 
806
 
787
        mov     ebx, [coff]
807
        mov     ebx, [coff]
788
        stdcall get_coff_sym, [sym], [ebx+COFF_HEADER.nSymbols], szSTART
808
        stdcall get_coff_sym, [sym], [ebx+COFF_HEADER.nSymbols], szSTART
789
        mov     [start], eax
809
        mov     [start], eax
790
 
810
 
791
        stdcall kernel_free, [coff]
811
        stdcall kernel_free, [coff]
792
 
812
 
793
        mov     ebx, [start]
813
        mov     ebx, [start]
794
        stdcall ebx, DRV_ENTRY
814
        stdcall ebx, DRV_ENTRY
795
        test    eax, eax
815
        test    eax, eax
796
        jnz     .ok
816
        jnz     .ok
797
 
817
 
798
        stdcall kernel_free, [img_base]
818
        stdcall kernel_free, [img_base]
799
        cmp     dword [file_name+13], 'SOUN'
819
        cmp     dword [file_name+13], 'SOUN'
800
        jnz     @f
820
        jnz     @f
801
        cmp     dword [file_name+17], 'D.ob'
821
        cmp     dword [file_name+17], 'D.ob'
802
        jnz     @f
822
        jnz     @f
803
        cmp     word [file_name+21], 'j'
823
        cmp     word [file_name+21], 'j'
804
        jnz     @f
824
        jnz     @f
805
        mov     esi, aHDA
825
        mov     esi, aHDA
806
        jmp     .redo
826
        jmp     .redo
807
@@:
827
@@:
808
        xor     eax, eax
828
        xor     eax, eax
809
        ret
829
        ret
810
.ok:
830
.ok:
811
        mov     ebx, [img_base]
831
        mov     ebx, [img_base]
812
        mov     [eax+SRV.base], ebx
832
        mov     [eax+SRV.base], ebx
813
        mov     ecx, [start]
833
        mov     ecx, [start]
814
        mov     [eax+SRV.entry], ecx
834
        mov     [eax+SRV.entry], ecx
815
        ret
835
        ret
816
 
836
 
817
.ver_fail:
837
.ver_fail:
818
        mov     esi, msg_CR
838
        mov     esi, msg_CR
819
        call    sys_msg_board_str
839
        call    sys_msg_board_str
820
        mov     esi, [driver_name]
840
        mov     esi, [driver_name]
821
        call    sys_msg_board_str
841
        call    sys_msg_board_str
822
        mov     esi, msg_CR
842
        mov     esi, msg_CR
823
        call    sys_msg_board_str
843
        call    sys_msg_board_str
824
        mov     esi, msg_version
844
        mov     esi, msg_version
825
        call    sys_msg_board_str
845
        call    sys_msg_board_str
826
        mov     esi, msg_www
846
        mov     esi, msg_www
827
        call    sys_msg_board_str
847
        call    sys_msg_board_str
828
        jmp     .cleanup
848
        jmp     .cleanup
829
 
849
 
830
.link_fail:
850
.link_fail:
831
        mov     esi, msg_module
851
        mov     esi, msg_module
832
        call    sys_msg_board_str
852
        call    sys_msg_board_str
833
        mov     esi, [driver_name]
853
        mov     esi, [driver_name]
834
        call    sys_msg_board_str
854
        call    sys_msg_board_str
835
        mov     esi, msg_CR
855
        mov     esi, msg_CR
836
        call    sys_msg_board_str
856
        call    sys_msg_board_str
837
.cleanup:
857
.cleanup:
838
        stdcall kernel_free, [img_base]
858
        stdcall kernel_free, [img_base]
839
.fail:
859
.fail:
840
        stdcall kernel_free, [coff]
860
        stdcall kernel_free, [coff]
841
.exit:
861
.exit:
842
        xor     eax, eax
862
        xor     eax, eax
843
        ret
863
        ret
844
endp
864
endp
845
 
865
 
846
; in: edx -> COFF_SECTION struct
866
; in: edx -> COFF_SECTION struct
847
; out: eax = alignment as mask for bits to drop
867
; out: eax = alignment as mask for bits to drop
848
coff_get_align:
868
coff_get_align:
849
; Rules:
869
; Rules:
850
; - if alignment is not given, use default = 4K;
870
; - if alignment is not given, use default = 4K;
851
; - if alignment is given and is no more than 4K, use it;
871
; - if alignment is given and is no more than 4K, use it;
852
; - if alignment is more than 4K, revert to 4K.
872
; - if alignment is more than 4K, revert to 4K.
853
        push    ecx
873
        push    ecx
854
        mov     cl, byte [edx+COFF_SECTION.Characteristics+2]
874
        mov     cl, byte [edx+COFF_SECTION.Characteristics+2]
855
        mov     eax, 1
875
        mov     eax, 1
856
        shr     cl, 4
876
        shr     cl, 4
857
        dec     cl
877
        dec     cl
858
        js      .default
878
        js      .default
859
        cmp     cl, 12
879
        cmp     cl, 12
860
        jbe     @f
880
        jbe     @f
861
.default:
881
.default:
862
        mov     cl, 12
882
        mov     cl, 12
863
@@:
883
@@:
864
        shl     eax, cl
884
        shl     eax, cl
865
        pop     ecx
885
        pop     ecx
866
        dec     eax
886
        dec     eax
867
        ret
887
        ret
868
 
888
 
869
align 4
889
align 4
870
proc load_library stdcall, file_name:dword
890
proc load_library stdcall, file_name:dword
871
           locals
891
           locals
872
             fullname  rb 260
892
             fullname  rb 260
873
             fileinfo  rb 40
893
             fileinfo  rb 40
874
             coff      dd ?
894
             coff      dd ?
875
             img_base  dd ?
895
             img_base  dd ?
876
           endl
896
           endl
877
 
897
 
878
        cli
898
        cli
879
 
899
 
880
; resolve file name
900
; resolve file name
881
        mov     ebx, [file_name]
901
        mov     ebx, [file_name]
882
        lea     edi, [fullname+1]
902
        lea     edi, [fullname+1]
883
        mov     byte [edi-1], '/'
903
        mov     byte [edi-1], '/'
884
        stdcall get_full_file_name, edi, 259
904
        stdcall get_full_file_name, edi, 259
885
        test    al, al
905
        test    al, al
886
        jz      .fail
906
        jz      .fail
887
 
907
 
888
; scan for required DLL in list of already loaded for this process,
908
; scan for required DLL in list of already loaded for this process,
889
; ignore timestamp
909
; ignore timestamp
890
        mov     esi, [CURRENT_TASK]
910
        mov     esi, [CURRENT_TASK]
891
        shl     esi, 8
911
        shl     esi, 8
892
        lea     edi, [fullname]
912
        lea     edi, [fullname]
893
        mov     ebx, [esi+SLOT_BASE+APPDATA.dlls_list_ptr]
913
        mov     ebx, [esi+SLOT_BASE+APPDATA.dlls_list_ptr]
894
        test    ebx, ebx
914
        test    ebx, ebx
895
        jz      .not_in_process
915
        jz      .not_in_process
896
        mov     esi, [ebx+HDLL.fd]
916
        mov     esi, [ebx+HDLL.fd]
897
.scan_in_process:
917
.scan_in_process:
898
        cmp     esi, ebx
918
        cmp     esi, ebx
899
        jz      .not_in_process
919
        jz      .not_in_process
900
        mov     eax, [esi+HDLL.parent]
920
        mov     eax, [esi+HDLL.parent]
901
        add     eax, DLLDESCR.name
921
        add     eax, DLLDESCR.name
902
        stdcall strncmp, eax, edi, -1
922
        stdcall strncmp, eax, edi, -1
903
        test    eax, eax
923
        test    eax, eax
904
        jnz     .next_in_process
924
        jnz     .next_in_process
905
; simple variant: load DLL which is already loaded in this process
925
; simple variant: load DLL which is already loaded in this process
906
; just increment reference counters and return address of exports table
926
; just increment reference counters and return address of exports table
907
        inc     [esi+HDLL.refcount]
927
        inc     [esi+HDLL.refcount]
908
        mov     ecx, [esi+HDLL.parent]
928
        mov     ecx, [esi+HDLL.parent]
909
        inc     [ecx+DLLDESCR.refcount]
929
        inc     [ecx+DLLDESCR.refcount]
910
        mov     eax, [ecx+DLLDESCR.exports]
930
        mov     eax, [ecx+DLLDESCR.exports]
911
        sub     eax, [ecx+DLLDESCR.defaultbase]
931
        sub     eax, [ecx+DLLDESCR.defaultbase]
912
        add     eax, [esi+HDLL.base]
932
        add     eax, [esi+HDLL.base]
913
        ret
933
        ret
914
.next_in_process:
934
.next_in_process:
915
        mov     esi, [esi+HDLL.fd]
935
        mov     esi, [esi+HDLL.fd]
916
        jmp     .scan_in_process
936
        jmp     .scan_in_process
917
.not_in_process:
937
.not_in_process:
918
 
938
 
919
; scan in full list, compare timestamp
939
; scan in full list, compare timestamp
920
        lea     eax, [fileinfo]
940
        lea     eax, [fileinfo]
921
        stdcall get_fileinfo, edi, eax
941
        stdcall get_fileinfo, edi, eax
922
        test    eax, eax
942
        test    eax, eax
923
        jnz     .fail
943
        jnz     .fail
924
        mov     esi, [dll_list.fd]
944
        mov     esi, [dll_list.fd]
925
.scan_for_dlls:
945
.scan_for_dlls:
926
        cmp     esi, dll_list
946
        cmp     esi, dll_list
927
        jz      .load_new
947
        jz      .load_new
928
        lea     eax, [esi+DLLDESCR.name]
948
        lea     eax, [esi+DLLDESCR.name]
929
        stdcall strncmp, eax, edi, -1
949
        stdcall strncmp, eax, edi, -1
930
        test    eax, eax
950
        test    eax, eax
931
        jnz     .continue_scan
951
        jnz     .continue_scan
932
.test_prev_dll:
952
.test_prev_dll:
933
        mov     eax, dword [fileinfo+24]; last modified time
953
        mov     eax, dword [fileinfo+24]; last modified time
934
        mov     edx, dword [fileinfo+28]; last modified date
954
        mov     edx, dword [fileinfo+28]; last modified date
935
        cmp     dword [esi+DLLDESCR.timestamp], eax
955
        cmp     dword [esi+DLLDESCR.timestamp], eax
936
        jnz     .continue_scan
956
        jnz     .continue_scan
937
        cmp     dword [esi+DLLDESCR.timestamp+4], edx
957
        cmp     dword [esi+DLLDESCR.timestamp+4], edx
938
        jz      .dll_already_loaded
958
        jz      .dll_already_loaded
939
.continue_scan:
959
.continue_scan:
940
        mov     esi, [esi+DLLDESCR.fd]
960
        mov     esi, [esi+DLLDESCR.fd]
941
        jmp     .scan_for_dlls
961
        jmp     .scan_for_dlls
942
 
962
 
943
; new DLL
963
; new DLL
944
.load_new:
964
.load_new:
945
; load file
965
; load file
946
        stdcall load_file, edi
966
        stdcall load_file, edi
947
        test    eax, eax
967
        test    eax, eax
948
        jz      .fail
968
        jz      .fail
949
        mov     [coff], eax
969
        mov     [coff], eax
950
        mov     dword [fileinfo+32], ebx
970
        mov     dword [fileinfo+32], ebx
951
 
971
 
952
; allocate DLLDESCR struct; size is DLLDESCR.sizeof plus size of DLL name
972
; allocate DLLDESCR struct; size is DLLDESCR.sizeof plus size of DLL name
953
        mov     esi, edi
973
        mov     esi, edi
954
        mov     ecx, -1
974
        mov     ecx, -1
955
        xor     eax, eax
975
        xor     eax, eax
956
        repnz scasb
976
        repnz scasb
957
        not     ecx
977
        not     ecx
958
        lea     eax, [ecx+sizeof.DLLDESCR]
978
        lea     eax, [ecx+sizeof.DLLDESCR]
959
        push    ecx
979
        push    ecx
960
        call    malloc
980
        call    malloc
961
        pop     ecx
981
        pop     ecx
962
        test    eax, eax
982
        test    eax, eax
963
        jz      .fail_and_free_coff
983
        jz      .fail_and_free_coff
964
; save timestamp
984
; save timestamp
965
        lea     edi, [eax+DLLDESCR.name]
985
        lea     edi, [eax+DLLDESCR.name]
966
        rep movsb
986
        rep movsb
967
        mov     esi, eax
987
        mov     esi, eax
968
        mov     eax, dword [fileinfo+24]
988
        mov     eax, dword [fileinfo+24]
969
        mov     dword [esi+DLLDESCR.timestamp], eax
989
        mov     dword [esi+DLLDESCR.timestamp], eax
970
        mov     eax, dword [fileinfo+28]
990
        mov     eax, dword [fileinfo+28]
971
        mov     dword [esi+DLLDESCR.timestamp+4], eax
991
        mov     dword [esi+DLLDESCR.timestamp+4], eax
972
; initialize DLLDESCR struct
992
; initialize DLLDESCR struct
973
        and     dword [esi+DLLDESCR.refcount], 0; no HDLLs yet; later it will be incremented
993
        and     dword [esi+DLLDESCR.refcount], 0; no HDLLs yet; later it will be incremented
974
        mov     [esi+DLLDESCR.fd], dll_list
994
        mov     [esi+DLLDESCR.fd], dll_list
975
        mov     eax, [dll_list.bk]
995
        mov     eax, [dll_list.bk]
976
        mov     [dll_list.bk], esi
996
        mov     [dll_list.bk], esi
977
        mov     [esi+DLLDESCR.bk], eax
997
        mov     [esi+DLLDESCR.bk], eax
978
        mov     [eax+DLLDESCR.fd], esi
998
        mov     [eax+DLLDESCR.fd], esi
979
 
999
 
980
; calculate size of loaded DLL
1000
; calculate size of loaded DLL
981
        mov     edx, [coff]
1001
        mov     edx, [coff]
982
        movzx   ecx, [edx+COFF_HEADER.nSections]
1002
        movzx   ecx, [edx+COFF_HEADER.nSections]
983
        xor     ebx, ebx
1003
        xor     ebx, ebx
984
 
1004
 
985
        add     edx, 20
1005
        add     edx, 20
986
@@:
1006
@@:
987
        call    coff_get_align
1007
        call    coff_get_align
988
        add     ebx, eax
1008
        add     ebx, eax
989
        not     eax
1009
        not     eax
990
        and     ebx, eax
1010
        and     ebx, eax
991
        add     ebx, [edx+COFF_SECTION.SizeOfRawData]
1011
        add     ebx, [edx+COFF_SECTION.SizeOfRawData]
992
        add     edx, sizeof.COFF_SECTION
1012
        add     edx, sizeof.COFF_SECTION
993
        dec     ecx
1013
        dec     ecx
994
        jnz     @B
1014
        jnz     @B
995
; it must be nonzero and not too big
1015
; it must be nonzero and not too big
996
        mov     [esi+DLLDESCR.size], ebx
1016
        mov     [esi+DLLDESCR.size], ebx
997
        test    ebx, ebx
1017
        test    ebx, ebx
998
        jz      .fail_and_free_dll
1018
        jz      .fail_and_free_dll
999
        cmp     ebx, MAX_DEFAULT_DLL_ADDR-MIN_DEFAULT_DLL_ADDR
1019
        cmp     ebx, MAX_DEFAULT_DLL_ADDR-MIN_DEFAULT_DLL_ADDR
1000
        ja      .fail_and_free_dll
1020
        ja      .fail_and_free_dll
1001
; allocate memory for kernel-side image
1021
; allocate memory for kernel-side image
1002
        stdcall kernel_alloc, ebx
1022
        stdcall kernel_alloc, ebx
1003
        test    eax, eax
1023
        test    eax, eax
1004
        jz      .fail_and_free_dll
1024
        jz      .fail_and_free_dll
1005
        mov     [esi+DLLDESCR.data], eax
1025
        mov     [esi+DLLDESCR.data], eax
1006
; calculate preferred base address
1026
; calculate preferred base address
1007
        add     ebx, 0x1FFF
1027
        add     ebx, 0x1FFF
1008
        and     ebx, not 0xFFF
1028
        and     ebx, not 0xFFF
1009
        mov     ecx, [dll_cur_addr]
1029
        mov     ecx, [dll_cur_addr]
1010
        lea     edx, [ecx+ebx]
1030
        lea     edx, [ecx+ebx]
1011
        cmp     edx, MAX_DEFAULT_DLL_ADDR
1031
        cmp     edx, MAX_DEFAULT_DLL_ADDR
1012
        jb      @f
1032
        jb      @f
1013
        mov     ecx, MIN_DEFAULT_DLL_ADDR
1033
        mov     ecx, MIN_DEFAULT_DLL_ADDR
1014
        lea     edx, [ecx+ebx]
1034
        lea     edx, [ecx+ebx]
1015
@@:
1035
@@:
1016
        mov     [esi+DLLDESCR.defaultbase], ecx
1036
        mov     [esi+DLLDESCR.defaultbase], ecx
1017
        mov     [dll_cur_addr], edx
1037
        mov     [dll_cur_addr], edx
1018
 
1038
 
1019
; copy sections and set correct values for VirtualAddress'es in headers
1039
; copy sections and set correct values for VirtualAddress'es in headers
1020
        push    esi
1040
        push    esi
1021
        mov     edx, [coff]
1041
        mov     edx, [coff]
1022
        movzx   ebx, [edx+COFF_HEADER.nSections]
1042
        movzx   ebx, [edx+COFF_HEADER.nSections]
1023
        mov     edi, eax
1043
        mov     edi, eax
1024
        add     edx, 20
1044
        add     edx, 20
1025
        cld
1045
        cld
1026
@@:
1046
@@:
1027
        call    coff_get_align
1047
        call    coff_get_align
1028
        add     ecx, eax
1048
        add     ecx, eax
1029
        add     edi, eax
1049
        add     edi, eax
1030
        not     eax
1050
        not     eax
1031
        and     ecx, eax
1051
        and     ecx, eax
1032
        and     edi, eax
1052
        and     edi, eax
1033
        mov     [edx+COFF_SECTION.VirtualAddress], ecx
1053
        mov     [edx+COFF_SECTION.VirtualAddress], ecx
1034
        add     ecx, [edx+COFF_SECTION.SizeOfRawData]
1054
        add     ecx, [edx+COFF_SECTION.SizeOfRawData]
1035
        mov     esi, [edx+COFF_SECTION.PtrRawData]
1055
        mov     esi, [edx+COFF_SECTION.PtrRawData]
1036
        push    ecx
1056
        push    ecx
1037
        mov     ecx, [edx+COFF_SECTION.SizeOfRawData]
1057
        mov     ecx, [edx+COFF_SECTION.SizeOfRawData]
1038
        test    esi, esi
1058
        test    esi, esi
1039
        jnz     .copy
1059
        jnz     .copy
1040
        xor     eax, eax
1060
        xor     eax, eax
1041
        rep stosb
1061
        rep stosb
1042
        jmp     .next
1062
        jmp     .next
1043
.copy:
1063
.copy:
1044
        add     esi, [coff]
1064
        add     esi, [coff]
1045
        rep movsb
1065
        rep movsb
1046
.next:
1066
.next:
1047
        pop     ecx
1067
        pop     ecx
1048
        add     edx, sizeof.COFF_SECTION
1068
        add     edx, sizeof.COFF_SECTION
1049
        dec     ebx
1069
        dec     ebx
1050
        jnz     @B
1070
        jnz     @B
1051
        pop     esi
1071
        pop     esi
1052
 
1072
 
1053
; save some additional data from COFF file
1073
; save some additional data from COFF file
1054
; later we will use COFF header, headers for sections and symbol table
1074
; later we will use COFF header, headers for sections and symbol table
1055
; and also relocations table for all sections
1075
; and also relocations table for all sections
1056
        mov     edx, [coff]
1076
        mov     edx, [coff]
1057
        mov     ebx, [edx+COFF_HEADER.pSymTable]
1077
        mov     ebx, [edx+COFF_HEADER.pSymTable]
1058
        mov     edi, dword [fileinfo+32]
1078
        mov     edi, dword [fileinfo+32]
1059
        sub     edi, ebx
1079
        sub     edi, ebx
1060
        jc      .fail_and_free_data
1080
        jc      .fail_and_free_data
1061
        mov     [esi+DLLDESCR.symbols_lim], edi
1081
        mov     [esi+DLLDESCR.symbols_lim], edi
1062
        add     ebx, edx
1082
        add     ebx, edx
1063
        movzx   ecx, [edx+COFF_HEADER.nSections]
1083
        movzx   ecx, [edx+COFF_HEADER.nSections]
1064
        lea     ecx, [ecx*5]
1084
        lea     ecx, [ecx*5]
1065
        lea     edi, [edi+ecx*8+20]
1085
        lea     edi, [edi+ecx*8+20]
1066
        add     edx, 20
1086
        add     edx, 20
1067
@@:
1087
@@:
1068
        movzx   eax, [edx+COFF_SECTION.NumReloc]
1088
        movzx   eax, [edx+COFF_SECTION.NumReloc]
1069
        lea     eax, [eax*5]
1089
        lea     eax, [eax*5]
1070
        lea     edi, [edi+eax*2]
1090
        lea     edi, [edi+eax*2]
1071
        add     edx, sizeof.COFF_SECTION
1091
        add     edx, sizeof.COFF_SECTION
1072
        sub     ecx, 5
1092
        sub     ecx, 5
1073
        jnz     @b
1093
        jnz     @b
1074
        stdcall kernel_alloc, edi
1094
        stdcall kernel_alloc, edi
1075
        test    eax, eax
1095
        test    eax, eax
1076
        jz      .fail_and_free_data
1096
        jz      .fail_and_free_data
1077
        mov     edx, [coff]
1097
        mov     edx, [coff]
1078
        movzx   ecx, [edx+COFF_HEADER.nSections]
1098
        movzx   ecx, [edx+COFF_HEADER.nSections]
1079
        lea     ecx, [ecx*5]
1099
        lea     ecx, [ecx*5]
1080
        lea     ecx, [ecx*2+5]
1100
        lea     ecx, [ecx*2+5]
1081
        mov     [esi+DLLDESCR.coff_hdr], eax
1101
        mov     [esi+DLLDESCR.coff_hdr], eax
1082
        push    esi
1102
        push    esi
1083
        mov     esi, edx
1103
        mov     esi, edx
1084
        mov     edi, eax
1104
        mov     edi, eax
1085
        rep movsd
1105
        rep movsd
1086
        pop     esi
1106
        pop     esi
1087
        mov     [esi+DLLDESCR.symbols_ptr], edi
1107
        mov     [esi+DLLDESCR.symbols_ptr], edi
1088
        push    esi
1108
        push    esi
1089
        mov     ecx, [edx+COFF_HEADER.nSymbols]
1109
        mov     ecx, [edx+COFF_HEADER.nSymbols]
1090
        mov     [esi+DLLDESCR.symbols_num], ecx
1110
        mov     [esi+DLLDESCR.symbols_num], ecx
1091
        mov     ecx, [esi+DLLDESCR.symbols_lim]
1111
        mov     ecx, [esi+DLLDESCR.symbols_lim]
1092
        mov     esi, ebx
1112
        mov     esi, ebx
1093
        rep movsb
1113
        rep movsb
1094
        pop     esi
1114
        pop     esi
1095
        mov     ebx, [esi+DLLDESCR.coff_hdr]
1115
        mov     ebx, [esi+DLLDESCR.coff_hdr]
1096
        push    esi
1116
        push    esi
1097
        movzx   eax, [edx+COFF_HEADER.nSections]
1117
        movzx   eax, [edx+COFF_HEADER.nSections]
1098
        lea     edx, [ebx+20]
1118
        lea     edx, [ebx+20]
1099
@@:
1119
@@:
1100
        movzx   ecx, [edx+COFF_SECTION.NumReloc]
1120
        movzx   ecx, [edx+COFF_SECTION.NumReloc]
1101
        lea     ecx, [ecx*5]
1121
        lea     ecx, [ecx*5]
1102
        mov     esi, [edx+COFF_SECTION.PtrReloc]
1122
        mov     esi, [edx+COFF_SECTION.PtrReloc]
1103
        mov     [edx+COFF_SECTION.PtrReloc], edi
1123
        mov     [edx+COFF_SECTION.PtrReloc], edi
1104
        sub     [edx+COFF_SECTION.PtrReloc], ebx
1124
        sub     [edx+COFF_SECTION.PtrReloc], ebx
1105
        add     esi, [coff]
1125
        add     esi, [coff]
1106
        shr     ecx, 1
1126
        shr     ecx, 1
1107
        rep movsd
1127
        rep movsd
1108
        adc     ecx, ecx
1128
        adc     ecx, ecx
1109
        rep movsw
1129
        rep movsw
1110
        add     edx, sizeof.COFF_SECTION
1130
        add     edx, sizeof.COFF_SECTION
1111
        dec     eax
1131
        dec     eax
1112
        jnz     @b
1132
        jnz     @b
1113
        pop     esi
1133
        pop     esi
1114
 
1134
 
1115
; fixup symbols
1135
; fixup symbols
1116
        mov     edx, ebx
1136
        mov     edx, ebx
1117
        mov     eax, [ebx+COFF_HEADER.nSymbols]
1137
        mov     eax, [ebx+COFF_HEADER.nSymbols]
1118
        add     edx, 20
1138
        add     edx, 20
1119
        mov     ecx, [esi+DLLDESCR.symbols_num]
1139
        mov     ecx, [esi+DLLDESCR.symbols_num]
1120
        lea     ecx, [ecx*9]
1140
        lea     ecx, [ecx*9]
1121
        add     ecx, ecx
1141
        add     ecx, ecx
1122
        add     ecx, [esi+DLLDESCR.symbols_ptr]
1142
        add     ecx, [esi+DLLDESCR.symbols_ptr]
1123
 
1143
 
1124
        stdcall fix_coff_symbols, edx, [esi+DLLDESCR.symbols_ptr], eax, \
1144
        stdcall fix_coff_symbols, edx, [esi+DLLDESCR.symbols_ptr], eax, \
1125
                ecx, 0
1145
                ecx, 0
1126
;          test eax, eax
1146
;          test eax, eax
1127
;          jnz @F
1147
;          jnz @F
1128
;
1148
;
1129
;@@:
1149
;@@:
1130
 
1150
 
1131
        stdcall get_coff_sym, [esi+DLLDESCR.symbols_ptr], [ebx+COFF_HEADER.nSymbols], szEXPORTS
1151
        stdcall get_coff_sym, [esi+DLLDESCR.symbols_ptr], [ebx+COFF_HEADER.nSymbols], szEXPORTS
1132
        test    eax, eax
1152
        test    eax, eax
1133
        jnz     @F
1153
        jnz     @F
1134
 
1154
 
1135
        stdcall get_coff_sym, [esi+DLLDESCR.symbols_ptr], [ebx+COFF_HEADER.nSymbols], sz_EXPORTS
1155
        stdcall get_coff_sym, [esi+DLLDESCR.symbols_ptr], [ebx+COFF_HEADER.nSymbols], sz_EXPORTS
1136
@@:
1156
@@:
1137
        mov     [esi+DLLDESCR.exports], eax
1157
        mov     [esi+DLLDESCR.exports], eax
1138
 
1158
 
1139
; fix relocs in the hidden copy in kernel memory to default address
1159
; fix relocs in the hidden copy in kernel memory to default address
1140
; it is first fix; usually this will be enough, but second fix
1160
; it is first fix; usually this will be enough, but second fix
1141
; can be necessary if real load address will not equal assumption
1161
; can be necessary if real load address will not equal assumption
1142
        mov     eax, [esi+DLLDESCR.data]
1162
        mov     eax, [esi+DLLDESCR.data]
1143
        sub     eax, [esi+DLLDESCR.defaultbase]
1163
        sub     eax, [esi+DLLDESCR.defaultbase]
1144
        stdcall fix_coff_relocs, ebx, [esi+DLLDESCR.symbols_ptr], eax
1164
        stdcall fix_coff_relocs, ebx, [esi+DLLDESCR.symbols_ptr], eax
1145
 
1165
 
1146
        stdcall kernel_free, [coff]
1166
        stdcall kernel_free, [coff]
1147
 
1167
 
1148
.dll_already_loaded:
1168
.dll_already_loaded:
1149
        inc     [esi+DLLDESCR.refcount]
1169
        inc     [esi+DLLDESCR.refcount]
1150
        push    esi
1170
        push    esi
1151
        call    init_heap
1171
        call    init_heap
1152
        pop     esi
1172
        pop     esi
1153
 
1173
 
1154
        mov     edi, [esi+DLLDESCR.size]
1174
        mov     edi, [esi+DLLDESCR.size]
1155
        stdcall user_alloc_at, [esi+DLLDESCR.defaultbase], edi
1175
        stdcall user_alloc_at, [esi+DLLDESCR.defaultbase], edi
1156
        test    eax, eax
1176
        test    eax, eax
1157
        jnz     @f
1177
        jnz     @f
1158
        stdcall user_alloc, edi
1178
        stdcall user_alloc, edi
1159
        test    eax, eax
1179
        test    eax, eax
1160
        jz      .fail_and_dereference
1180
        jz      .fail_and_dereference
1161
@@:
1181
@@:
1162
        mov     [img_base], eax
1182
        mov     [img_base], eax
1163
        mov     eax, sizeof.HDLL
1183
        mov     eax, sizeof.HDLL
1164
        call    malloc
1184
        call    malloc
1165
        test    eax, eax
1185
        test    eax, eax
1166
        jz      .fail_and_free_user
1186
        jz      .fail_and_free_user
1167
        mov     ebx, [CURRENT_TASK]
1187
        mov     ebx, [CURRENT_TASK]
1168
        shl     ebx, 5
1188
        shl     ebx, 5
1169
        mov     edx, [CURRENT_TASK+ebx+TASKDATA.pid]
1189
        mov     edx, [CURRENT_TASK+ebx+TASKDATA.pid]
1170
        mov     [eax+HDLL.pid], edx
1190
        mov     [eax+HDLL.pid], edx
1171
        push    eax
1191
        push    eax
1172
        call    init_dlls_in_thread
1192
        call    init_dlls_in_thread
1173
        pop     ebx
1193
        pop     ebx
1174
        test    eax, eax
1194
        test    eax, eax
1175
        jz      .fail_and_free_user
1195
        jz      .fail_and_free_user
1176
        mov     edx, [eax+HDLL.fd]
1196
        mov     edx, [eax+HDLL.fd]
1177
        mov     [ebx+HDLL.fd], edx
1197
        mov     [ebx+HDLL.fd], edx
1178
        mov     [ebx+HDLL.bk], eax
1198
        mov     [ebx+HDLL.bk], eax
1179
        mov     [eax+HDLL.fd], ebx
1199
        mov     [eax+HDLL.fd], ebx
1180
        mov     [edx+HDLL.bk], ebx
1200
        mov     [edx+HDLL.bk], ebx
1181
        mov     eax, ebx
1201
        mov     eax, ebx
1182
        mov     ebx, [img_base]
1202
        mov     ebx, [img_base]
1183
        mov     [eax+HDLL.base], ebx
1203
        mov     [eax+HDLL.base], ebx
1184
        mov     [eax+HDLL.size], edi
1204
        mov     [eax+HDLL.size], edi
1185
        mov     [eax+HDLL.refcount], 1
1205
        mov     [eax+HDLL.refcount], 1
1186
        mov     [eax+HDLL.parent], esi
1206
        mov     [eax+HDLL.parent], esi
1187
        mov     edx, ebx
1207
        mov     edx, ebx
1188
        shr     edx, 12
1208
        shr     edx, 12
1189
        or      dword [page_tabs+(edx-1)*4], DONT_FREE_BLOCK
1209
        or      dword [page_tabs+(edx-1)*4], DONT_FREE_BLOCK
1190
; copy entries of page table from kernel-side image to usermode
1210
; copy entries of page table from kernel-side image to usermode
1191
; use copy-on-write for user-mode image, so map as readonly
1211
; use copy-on-write for user-mode image, so map as readonly
1192
        xor     edi, edi
1212
        xor     edi, edi
1193
        mov     ecx, [esi+DLLDESCR.data]
1213
        mov     ecx, [esi+DLLDESCR.data]
1194
        shr     ecx, 12
1214
        shr     ecx, 12
1195
.map_pages_loop:
1215
.map_pages_loop:
1196
        mov     eax, [page_tabs+ecx*4]
1216
        mov     eax, [page_tabs+ecx*4]
1197
        and     eax, not 0xFFF
1217
        and     eax, not 0xFFF
1198
        or      al, PG_USER
1218
        or      al, PG_USER
1199
        xchg    eax, [page_tabs+edx*4]
1219
        xchg    eax, [page_tabs+edx*4]
1200
        test    al, 1
1220
        test    al, 1
1201
        jz      @f
1221
        jz      @f
1202
        call    free_page
1222
        call    free_page
1203
@@:
1223
@@:
1204
        invlpg  [ebx+edi]
1224
        invlpg  [ebx+edi]
1205
        inc     ecx
1225
        inc     ecx
1206
        inc     edx
1226
        inc     edx
1207
        add     edi, 0x1000
1227
        add     edi, 0x1000
1208
        cmp     edi, [esi+DLLDESCR.size]
1228
        cmp     edi, [esi+DLLDESCR.size]
1209
        jb      .map_pages_loop
1229
        jb      .map_pages_loop
1210
 
1230
 
1211
; if real user-mode base is not equal to preferred base, relocate image
1231
; if real user-mode base is not equal to preferred base, relocate image
1212
        sub     ebx, [esi+DLLDESCR.defaultbase]
1232
        sub     ebx, [esi+DLLDESCR.defaultbase]
1213
        jz      @f
1233
        jz      @f
1214
        stdcall rebase_coff, [esi+DLLDESCR.coff_hdr], [esi+DLLDESCR.symbols_ptr], ebx
1234
        stdcall rebase_coff, [esi+DLLDESCR.coff_hdr], [esi+DLLDESCR.symbols_ptr], ebx
1215
@@:
1235
@@:
1216
 
1236
 
1217
        mov     eax, [esi+DLLDESCR.exports]
1237
        mov     eax, [esi+DLLDESCR.exports]
1218
        sub     eax, [esi+DLLDESCR.defaultbase]
1238
        sub     eax, [esi+DLLDESCR.defaultbase]
1219
        add     eax, [img_base]
1239
        add     eax, [img_base]
1220
        ret
1240
        ret
1221
.fail_and_free_data:
1241
.fail_and_free_data:
1222
        stdcall kernel_free, [esi+DLLDESCR.data]
1242
        stdcall kernel_free, [esi+DLLDESCR.data]
1223
.fail_and_free_dll:
1243
.fail_and_free_dll:
1224
        mov     eax, esi
1244
        mov     eax, esi
1225
        call    free
1245
        call    free
1226
.fail_and_free_coff:
1246
.fail_and_free_coff:
1227
        stdcall kernel_free, [coff]
1247
        stdcall kernel_free, [coff]
1228
.fail:
1248
.fail:
1229
        xor     eax, eax
1249
        xor     eax, eax
1230
        ret
1250
        ret
1231
.fail_and_free_user:
1251
.fail_and_free_user:
1232
        stdcall user_free, [img_base]
1252
        stdcall user_free, [img_base]
1233
.fail_and_dereference:
1253
.fail_and_dereference:
1234
        mov     eax, 1  ; delete 1 reference
1254
        mov     eax, 1  ; delete 1 reference
1235
        call    dereference_dll
1255
        call    dereference_dll
1236
        xor     eax, eax
1256
        xor     eax, eax
1237
        ret
1257
        ret
1238
endp
1258
endp
1239
 
1259
 
1240
; initialize [APPDATA.dlls_list_ptr] for given thread
1260
; initialize [APPDATA.dlls_list_ptr] for given thread
1241
; DLL is per-process object, so APPDATA.dlls_list_ptr must be
1261
; DLL is per-process object, so APPDATA.dlls_list_ptr must be
1242
; kept in sync for all threads of one process.
1262
; kept in sync for all threads of one process.
1243
; out: eax = APPDATA.dlls_list_ptr if all is OK,
1263
; out: eax = APPDATA.dlls_list_ptr if all is OK,
1244
; NULL if memory allocation failed
1264
; NULL if memory allocation failed
1245
init_dlls_in_thread:
1265
init_dlls_in_thread:
1246
        mov     ebx, [current_slot]
1266
        mov     ebx, [current_slot]
1247
        mov     eax, [ebx+APPDATA.dlls_list_ptr]
1267
        mov     eax, [ebx+APPDATA.dlls_list_ptr]
1248
        test    eax, eax
1268
        test    eax, eax
1249
        jnz     .ret
1269
        jnz     .ret
1250
        push    [ebx+APPDATA.dir_table]
1270
        push    [ebx+APPDATA.dir_table]
1251
        mov     eax, 8
1271
        mov     eax, 8
1252
        call    malloc
1272
        call    malloc
1253
        pop     edx
1273
        pop     edx
1254
        test    eax, eax
1274
        test    eax, eax
1255
        jz      .ret
1275
        jz      .ret
1256
        mov     [eax], eax
1276
        mov     [eax], eax
1257
        mov     [eax+4], eax
1277
        mov     [eax+4], eax
1258
        mov     ecx, [TASK_COUNT]
1278
        mov     ecx, [TASK_COUNT]
1259
        mov     ebx, SLOT_BASE+256
1279
        mov     ebx, SLOT_BASE+256
1260
.set:
1280
.set:
1261
        cmp     [ebx+APPDATA.dir_table], edx
1281
        cmp     [ebx+APPDATA.dir_table], edx
1262
        jnz     @f
1282
        jnz     @f
1263
        mov     [ebx+APPDATA.dlls_list_ptr], eax
1283
        mov     [ebx+APPDATA.dlls_list_ptr], eax
1264
@@:
1284
@@:
1265
        add     ebx, 256
1285
        add     ebx, 256
1266
        dec     ecx
1286
        dec     ecx
1267
        jnz     .set
1287
        jnz     .set
1268
.ret:
1288
.ret:
1269
        ret
1289
        ret
1270
 
1290
 
1271
; in: eax = number of references to delete, esi -> DLLDESCR struc
1291
; in: eax = number of references to delete, esi -> DLLDESCR struc
1272
dereference_dll:
1292
dereference_dll:
1273
        sub     [esi+DLLDESCR.refcount], eax
1293
        sub     [esi+DLLDESCR.refcount], eax
1274
        jnz     .ret
1294
        jnz     .ret
1275
        mov     eax, [esi+DLLDESCR.fd]
1295
        mov     eax, [esi+DLLDESCR.fd]
1276
        mov     edx, [esi+DLLDESCR.bk]
1296
        mov     edx, [esi+DLLDESCR.bk]
1277
        mov     [eax+DLLDESCR.bk], edx
1297
        mov     [eax+DLLDESCR.bk], edx
1278
        mov     [edx+DLLDESCR.fd], eax
1298
        mov     [edx+DLLDESCR.fd], eax
1279
        stdcall kernel_free, [esi+DLLDESCR.coff_hdr]
1299
        stdcall kernel_free, [esi+DLLDESCR.coff_hdr]
1280
        stdcall kernel_free, [esi+DLLDESCR.data]
1300
        stdcall kernel_free, [esi+DLLDESCR.data]
1281
        mov     eax, esi
1301
        mov     eax, esi
1282
        call    free
1302
        call    free
1283
.ret:
1303
.ret:
1284
        ret
1304
        ret
1285
 
1305
 
1286
destroy_hdll:
1306
destroy_hdll:
1287
        push    ebx ecx esi edi
1307
        push    ebx ecx esi edi
1288
        push    eax
1308
        push    eax
1289
        mov     ebx, [eax+HDLL.base]
1309
        mov     ebx, [eax+HDLL.base]
1290
        mov     esi, [eax+HDLL.parent]
1310
        mov     esi, [eax+HDLL.parent]
1291
        mov     edx, [esi+DLLDESCR.size]
1311
        mov     edx, [esi+DLLDESCR.size]
1292
; The following actions require the context of application where HDLL is mapped.
1312
; The following actions require the context of application where HDLL is mapped.
1293
; However, destroy_hdll can be called in the context of OS thread when
1313
; However, destroy_hdll can be called in the context of OS thread when
1294
; cleaning up objects created by the application which is destroyed.
1314
; cleaning up objects created by the application which is destroyed.
1295
; So remember current cr3 and set it to page table of target.
1315
; So remember current cr3 and set it to page table of target.
1296
        mov     eax, [ecx+APPDATA.dir_table]
1316
        mov     eax, [ecx+APPDATA.dir_table]
1297
; Because we cheat with cr3, disable interrupts: task switch would restore
1317
; Because we cheat with cr3, disable interrupts: task switch would restore
1298
; page table from APPDATA of current thread.
1318
; page table from APPDATA of current thread.
1299
; Also set [current_slot] because it is used by user_free.
1319
; Also set [current_slot] because it is used by user_free.
1300
        pushf
1320
        pushf
1301
        cli
1321
        cli
1302
        push    [current_slot]
1322
        push    [current_slot]
1303
        mov     [current_slot], ecx
1323
        mov     [current_slot], ecx
1304
        mov     ecx, cr3
1324
        mov     ecx, cr3
1305
        push    ecx
1325
        push    ecx
1306
        mov     cr3, eax
1326
        mov     cr3, eax
1307
        push    ebx     ; argument for user_free
1327
        push    ebx     ; argument for user_free
1308
        mov     eax, ebx
1328
        mov     eax, ebx
1309
        shr     ebx, 12
1329
        shr     ebx, 12
1310
        push    ebx
1330
        push    ebx
1311
        mov     esi, [esi+DLLDESCR.data]
1331
        mov     esi, [esi+DLLDESCR.data]
1312
        shr     esi, 12
1332
        shr     esi, 12
1313
.unmap_loop:
1333
.unmap_loop:
1314
        push    eax
1334
        push    eax
1315
        mov     eax, 2
1335
        mov     eax, 2
1316
        xchg    eax, [page_tabs+ebx*4]
1336
        xchg    eax, [page_tabs+ebx*4]
1317
        mov     ecx, [page_tabs+esi*4]
1337
        mov     ecx, [page_tabs+esi*4]
1318
        and     eax, not 0xFFF
1338
        and     eax, not 0xFFF
1319
        and     ecx, not 0xFFF
1339
        and     ecx, not 0xFFF
1320
        cmp     eax, ecx
1340
        cmp     eax, ecx
1321
        jz      @f
1341
        jz      @f
1322
        call    free_page
1342
        call    free_page
1323
@@:
1343
@@:
1324
        pop     eax
1344
        pop     eax
1325
        invlpg  [eax]
1345
        invlpg  [eax]
1326
        add     eax, 0x1000
1346
        add     eax, 0x1000
1327
        inc     ebx
1347
        inc     ebx
1328
        inc     esi
1348
        inc     esi
1329
        sub     edx, 0x1000
1349
        sub     edx, 0x1000
1330
        ja      .unmap_loop
1350
        ja      .unmap_loop
1331
        pop     ebx
1351
        pop     ebx
1332
        and     dword [page_tabs+(ebx-1)*4], not DONT_FREE_BLOCK
1352
        and     dword [page_tabs+(ebx-1)*4], not DONT_FREE_BLOCK
1333
        call    user_free
1353
        call    user_free
1334
; Restore context.
1354
; Restore context.
1335
        pop     eax
1355
        pop     eax
1336
        mov     cr3, eax
1356
        mov     cr3, eax
1337
        pop     [current_slot]
1357
        pop     [current_slot]
1338
        popf
1358
        popf
1339
; Ok, cheating is done.
1359
; Ok, cheating is done.
1340
        pop     eax
1360
        pop     eax
1341
        push    eax
1361
        push    eax
1342
        mov     esi, [eax+HDLL.parent]
1362
        mov     esi, [eax+HDLL.parent]
1343
        mov     eax, [eax+HDLL.refcount]
1363
        mov     eax, [eax+HDLL.refcount]
1344
        call    dereference_dll
1364
        call    dereference_dll
1345
        pop     eax
1365
        pop     eax
1346
        mov     edx, [eax+HDLL.bk]
1366
        mov     edx, [eax+HDLL.bk]
1347
        mov     ebx, [eax+HDLL.fd]
1367
        mov     ebx, [eax+HDLL.fd]
1348
        mov     [ebx+HDLL.bk], edx
1368
        mov     [ebx+HDLL.bk], edx
1349
        mov     [edx+HDLL.fd], ebx
1369
        mov     [edx+HDLL.fd], ebx
1350
        call    free
1370
        call    free
1351
        pop     edi esi ecx ebx
1371
        pop     edi esi ecx ebx
1352
        ret
1372
        ret
1353
 
1373
 
1354
; ecx -> APPDATA for slot, esi = dlls_list_ptr
1374
; ecx -> APPDATA for slot, esi = dlls_list_ptr
1355
destroy_all_hdlls:
1375
destroy_all_hdlls:
1356
        test    esi, esi
1376
        test    esi, esi
1357
        jz      .ret
1377
        jz      .ret
1358
.loop:
1378
.loop:
1359
        mov     eax, [esi+HDLL.fd]
1379
        mov     eax, [esi+HDLL.fd]
1360
        cmp     eax, esi
1380
        cmp     eax, esi
1361
        jz      free
1381
        jz      free
1362
        call    destroy_hdll
1382
        call    destroy_hdll
1363
        jmp     .loop
1383
        jmp     .loop
1364
.ret:
1384
.ret:
1365
        ret
1385
        ret
1366
 
1386
 
1367
align 4
1387
align 4
1368
stop_all_services:
1388
stop_all_services:
1369
        push    ebp
1389
        push    ebp
1370
        mov     edx, [srv.fd]
1390
        mov     edx, [srv.fd]
1371
.next:
1391
.next:
1372
        cmp     edx, srv.fd-SRV.fd
1392
        cmp     edx, srv.fd-SRV.fd
1373
        je      .done
1393
        je      .done
1374
        cmp     [edx+SRV.magic], ' SRV'
1394
        cmp     [edx+SRV.magic], ' SRV'
1375
        jne     .next
1395
        jne     .next
1376
        cmp     [edx+SRV.size], sizeof.SRV
1396
        cmp     [edx+SRV.size], sizeof.SRV
1377
        jne     .next
1397
        jne     .next
1378
 
1398
 
1379
        mov     ebx, [edx+SRV.entry]
1399
        mov     ebx, [edx+SRV.entry]
1380
        mov     edx, [edx+SRV.fd]
1400
        mov     edx, [edx+SRV.fd]
1381
        test    ebx, ebx
1401
        test    ebx, ebx
1382
        jz      .next
1402
        jz      .next
1383
 
1403
 
1384
        push    edx
1404
        push    edx
1385
        mov     ebp, esp
1405
        mov     ebp, esp
1386
        push    0
1406
        push    0
1387
        push    -1
1407
        push    -1
1388
        call    ebx
1408
        call    ebx
1389
        mov     esp, ebp
1409
        mov     esp, ebp
1390
        pop     edx
1410
        pop     edx
1391
        jmp     .next
1411
        jmp     .next
1392
.done:
1412
.done:
1393
        pop     ebp
1413
        pop     ebp
1394
        ret
1414
        ret
1395
 
1415
 
1396
; param
1416
; param
1397
;  eax= size
1417
;  eax= size
1398
;  ebx= pid
1418
;  ebx= pid
1399
 
1419
 
1400
align 4
1420
align 4
1401
create_kernel_object:
1421
create_kernel_object:
1402
 
1422
 
1403
        push    ebx
1423
        push    ebx
1404
        call    malloc
1424
        call    malloc
1405
        pop     ebx
1425
        pop     ebx
1406
        test    eax, eax
1426
        test    eax, eax
1407
        jz      .fail
1427
        jz      .fail
1408
 
1428
 
1409
        mov     ecx, [current_slot]
1429
        mov     ecx, [current_slot]
1410
        add     ecx, APP_OBJ_OFFSET
1430
        add     ecx, APP_OBJ_OFFSET
1411
 
1431
 
1412
        pushfd
1432
        pushfd
1413
        cli
1433
        cli
1414
        mov     edx, [ecx+APPOBJ.fd]
1434
        mov     edx, [ecx+APPOBJ.fd]
1415
        mov     [eax+APPOBJ.fd], edx
1435
        mov     [eax+APPOBJ.fd], edx
1416
        mov     [eax+APPOBJ.bk], ecx
1436
        mov     [eax+APPOBJ.bk], ecx
1417
        mov     [eax+APPOBJ.pid], ebx
1437
        mov     [eax+APPOBJ.pid], ebx
1418
 
1438
 
1419
        mov     [ecx+APPOBJ.fd], eax
1439
        mov     [ecx+APPOBJ.fd], eax
1420
        mov     [edx+APPOBJ.bk], eax
1440
        mov     [edx+APPOBJ.bk], eax
1421
        popfd
1441
        popfd
1422
.fail:
1442
.fail:
1423
        ret
1443
        ret
1424
 
1444
 
1425
; param
1445
; param
1426
;  eax= object
1446
;  eax= object
1427
 
1447
 
1428
align 4
1448
align 4
1429
destroy_kernel_object:
1449
destroy_kernel_object:
1430
 
1450
 
1431
        pushfd
1451
        pushfd
1432
        cli
1452
        cli
1433
        mov     ebx, [eax+APPOBJ.fd]
1453
        mov     ebx, [eax+APPOBJ.fd]
1434
        mov     ecx, [eax+APPOBJ.bk]
1454
        mov     ecx, [eax+APPOBJ.bk]
1435
        mov     [ebx+APPOBJ.bk], ecx
1455
        mov     [ebx+APPOBJ.bk], ecx
1436
        mov     [ecx+APPOBJ.fd], ebx
1456
        mov     [ecx+APPOBJ.fd], ebx
1437
        popfd
1457
        popfd
1438
 
1458
 
1439
        xor     edx, edx       ;clear common header
1459
        xor     edx, edx       ;clear common header
1440
        mov     [eax], edx
1460
        mov     [eax], edx
1441
        mov     [eax+4], edx
1461
        mov     [eax+4], edx
1442
        mov     [eax+8], edx
1462
        mov     [eax+8], edx
1443
        mov     [eax+12], edx
1463
        mov     [eax+12], edx
1444
        mov     [eax+16], edx
1464
        mov     [eax+16], edx
1445
 
1465
 
1446
        call    free           ;release object memory
1466
        call    free           ;release object memory
1447
        ret
1467
        ret