Subversion Repositories Kolibri OS

Rev

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