Subversion Repositories Kolibri OS

Rev

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

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