Subversion Repositories Kolibri OS

Rev

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/.obj'
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