Subversion Repositories Kolibri OS

Rev

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