Subversion Repositories Kolibri OS

Rev

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