Subversion Repositories Kolibri OS

Rev

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