Subversion Repositories Kolibri OS

Rev

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