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