Subversion Repositories Kolibri OS

Rev

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

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