Subversion Repositories Kolibri OS

Rev

Rev 1289 | Rev 1296 | 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: 1292 $
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
336
;  ebx= io_control
337
;
338
; retval
339
;  eax= error code
340
 
164 serge 341
align 4
377 serge 342
srv_handlerEx:
672 hidnplayr 343
	   cmp ebx, OS_BASE
344
	   jae .fail
164 serge 345
 
672 hidnplayr 346
	   mov eax, [ebx+handle]
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
 
672 hidnplayr 353
	   stdcall [eax+SRV.srv_proc], ebx
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
164 serge 600
 
672 hidnplayr 601
	   stdcall read_file, [file_name], eax, dword 0, [file_size]
602
	   cmp ebx, [file_size]
603
	   jne .cleanup
211 serge 604
 
672 hidnplayr 605
	   mov eax, [file]
606
	   cmp dword [eax], 0x4B43504B
607
	   jne .exit
608
	   mov ebx, [eax+4]
609
	   mov [file_size], ebx
610
	   stdcall kernel_alloc, ebx
211 serge 611
 
672 hidnplayr 612
	   test eax, eax
613
	   jz .cleanup
211 serge 614
 
672 hidnplayr 615
	   mov [file2], eax
1275 serge 616
       pushfd
617
       cli
672 hidnplayr 618
	   stdcall unpack, [file], eax
1275 serge 619
       popfd
672 hidnplayr 620
	   stdcall kernel_free, [file]
621
	   mov eax, [file2]
622
	   mov ebx, [file_size]
211 serge 623
.exit:
672 hidnplayr 624
	   push eax
625
	   lea edi, [eax+ebx]	  ;cleanup remain space
626
	   mov ecx, 4096	  ;from file end
627
	   and ebx, 4095
628
	   jz  @f
629
	   sub ecx, ebx
630
	   xor eax, eax
631
	   cld
632
	   rep stosb
521 diamond 633
@@:
672 hidnplayr 634
	   mov ebx, [file_size]
635
	   pop eax
636
	   pop edi
637
	   pop esi
638
	   ret
188 serge 639
.cleanup:
672 hidnplayr 640
	   stdcall kernel_free, [file]
188 serge 641
.fail:
672 hidnplayr 642
	   xor eax, eax
643
	   xor ebx, ebx
644
	   pop edi
645
	   pop esi
646
	   ret
188 serge 647
endp
164 serge 648
 
188 serge 649
align 4
650
proc get_proc_ex stdcall, proc_name:dword, imports:dword
651
 
652
.look_up:
672 hidnplayr 653
	   mov edx, [imports]
654
	   test edx, edx
655
	   jz .end
656
	   mov edx, [edx]
657
	   test edx, edx
658
	   jz .end
188 serge 659
.next:
672 hidnplayr 660
	   mov eax, [edx]
661
	   test eax, eax
662
	   jz .next_table
164 serge 663
 
672 hidnplayr 664
	   push edx
916 serge 665
       stdcall strncmp, eax, [proc_name], 256
672 hidnplayr 666
	   pop edx
667
	   test eax, eax
668
	   jz .ok
164 serge 669
 
672 hidnplayr 670
	   add edx,8
671
	   jmp .next
188 serge 672
.next_table:
672 hidnplayr 673
	   add [imports], 4
674
	   jmp .look_up
188 serge 675
.ok:
672 hidnplayr 676
	   mov eax, [edx+4]
677
	   ret
188 serge 678
.end:
672 hidnplayr 679
	   xor eax, eax
680
	   ret
188 serge 681
endp
164 serge 682
 
188 serge 683
align 4
1289 diamond 684
proc fix_coff_symbols stdcall uses ebx esi, sec:dword, symbols:dword,\
672 hidnplayr 685
		      sym_count:dword, strings:dword, imports:dword
686
	   locals
687
	     retval dd ?
688
	   endl
164 serge 689
 
672 hidnplayr 690
	   mov edi, [symbols]
691
	   mov [retval], 1
188 serge 692
.fix:
672 hidnplayr 693
	   movzx ebx, [edi+CSYM.SectionNumber]
694
	   test ebx, ebx
695
	   jnz .internal
696
	   mov eax, dword [edi+CSYM.Name]
697
	   test eax, eax
698
	   jnz @F
164 serge 699
 
672 hidnplayr 700
	   mov edi, [edi+4]
701
	   add edi, [strings]
188 serge 702
@@:
672 hidnplayr 703
	   push edi
704
	   stdcall get_proc_ex, edi,[imports]
705
	   pop edi
164 serge 706
 
672 hidnplayr 707
	   xor ebx, ebx
708
	   test eax, eax
709
	   jnz @F
164 serge 710
 
672 hidnplayr 711
	   mov esi, msg_unresolved
712
	   call sys_msg_board_str
713
	   mov esi, edi
714
	   call sys_msg_board_str
715
	   mov esi, msg_CR
716
	   call sys_msg_board_str
164 serge 717
 
672 hidnplayr 718
	   mov [retval],0
188 serge 719
@@:
672 hidnplayr 720
	   mov edi, [symbols]
721
	   mov [edi+CSYM.Value], eax
722
	   jmp .next
188 serge 723
.internal:
672 hidnplayr 724
	   cmp bx, -1
725
	   je .next
726
	   cmp bx, -2
727
	   je .next
541 serge 728
 
672 hidnplayr 729
	   dec ebx
730
	   shl ebx, 3
731
	   lea ebx, [ebx+ebx*4]
732
	   add ebx, [sec]
188 serge 733
 
672 hidnplayr 734
	   mov eax, [ebx+CFS.VirtualAddress]
735
	   add [edi+CSYM.Value], eax
188 serge 736
.next:
672 hidnplayr 737
	   add edi, CSYM_SIZE
738
	   mov [symbols], edi
739
	   dec [sym_count]
740
	   jnz .fix
741
	   mov eax, [retval]
742
	   ret
164 serge 743
endp
744
 
745
align 4
1289 diamond 746
proc fix_coff_relocs stdcall uses ebx esi, coff:dword, sym:dword, \
747
	delta:dword
164 serge 748
	   locals
672 hidnplayr 749
	     n_sec     dd ?
164 serge 750
	   endl
751
 
672 hidnplayr 752
	   mov eax, [coff]
753
	   movzx ebx, [eax+CFH.nSections]
754
	   mov [n_sec], ebx
1289 diamond 755
	   lea esi, [eax+20]
188 serge 756
.fix_sec:
164 serge 757
	   mov edi, [esi+CFS.PtrReloc]
672 hidnplayr 758
	   add edi, [coff]
164 serge 759
 
672 hidnplayr 760
	   movzx ecx, [esi+CFS.NumReloc]
761
	   test ecx, ecx
762
	   jz .next
1289 diamond 763
.reloc_loop:
164 serge 764
	   mov ebx, [edi+CRELOC.SymIndex]
765
	   add ebx,ebx
766
	   lea ebx,[ebx+ebx*8]
672 hidnplayr 767
	   add ebx, [sym]
164 serge 768
 
672 hidnplayr 769
	   mov edx, [ebx+CSYM.Value]
164 serge 770
 
672 hidnplayr 771
	   cmp [edi+CRELOC.Type], 6
772
	   je .dir_32
164 serge 773
 
672 hidnplayr 774
	   cmp [edi+CRELOC.Type], 20
775
	   jne .next_reloc
188 serge 776
.rel_32:
164 serge 777
	   mov eax, [edi+CRELOC.VirtualAddress]
672 hidnplayr 778
	   add eax, [esi+CFS.VirtualAddress]
779
	   sub edx, eax
780
	   sub edx, 4
781
	   jmp .fix
188 serge 782
.dir_32:
783
	   mov eax, [edi+CRELOC.VirtualAddress]
672 hidnplayr 784
	   add eax, [esi+CFS.VirtualAddress]
188 serge 785
.fix:
1289 diamond 786
	   add eax, [delta]
672 hidnplayr 787
	   add [eax], edx
1289 diamond 788
.next_reloc:
672 hidnplayr 789
	   add edi, 10
790
	   dec ecx
1289 diamond 791
	   jnz .reloc_loop
188 serge 792
.next:
1289 diamond 793
	   add esi, COFF_SECTION_SIZE
672 hidnplayr 794
	   dec [n_sec]
795
	   jnz .fix_sec
164 serge 796
.exit:
797
	   ret
798
endp
799
 
1289 diamond 800
proc rebase_coff stdcall uses ebx esi, coff:dword, sym:dword, \
801
	delta:dword
802
	   locals
803
	     n_sec     dd ?
804
	   endl
805
 
806
	   mov eax, [coff]
807
	   movzx ebx, [eax+CFH.nSections]
808
	   mov [n_sec], ebx
809
	   lea esi, [eax+20]
810
	   mov edx, [delta]
811
.fix_sec:
812
	   mov edi, [esi+CFS.PtrReloc]
813
	   add edi, [coff]
814
 
815
	   movzx ecx, [esi+CFS.NumReloc]
816
	   test ecx, ecx
817
	   jz .next
818
.reloc_loop:
819
	   cmp [edi+CRELOC.Type], 6
820
	   jne .next_reloc
821
.dir_32:
822
	   mov eax, [edi+CRELOC.VirtualAddress]
823
	   add eax, [esi+CFS.VirtualAddress]
824
	   add [eax+edx], edx
825
.next_reloc:
826
	   add edi, 10
827
	   dec ecx
828
	   jnz .reloc_loop
829
.next:
830
	   add esi, COFF_SECTION_SIZE
831
	   dec [n_sec]
832
	   jnz .fix_sec
833
.exit:
834
	   ret
835
endp
836
 
188 serge 837
align 4
346 diamond 838
proc load_driver stdcall, driver_name:dword
672 hidnplayr 839
	   locals
840
	     coff      dd ?
841
	     sym       dd ?
842
	     strings   dd ?
843
	     img_size  dd ?
844
	     img_base  dd ?
845
	     start     dd ?
188 serge 846
 
672 hidnplayr 847
	     exports   dd ?   ;fake exports table
848
		       dd ?
849
	     file_name rb 13+16+4+1	 ; '/sys/drivers/.obj'
850
	   endl
188 serge 851
 
672 hidnplayr 852
	   lea	   edx, [file_name]
853
	   mov	   dword [edx], '/sys'
854
	   mov	   dword [edx+4], '/dri'
855
	   mov	   dword [edx+8], 'vers'
856
	   mov	   byte [edx+12], '/'
857
	   mov	   esi, [driver_name]
1018 diamond 858
.redo:
859
           lea     edx, [file_name]
672 hidnplayr 860
	   lea	   edi, [edx+13]
861
	   mov	   ecx, 16
346 diamond 862
@@:
672 hidnplayr 863
	   lodsb
864
	   test    al, al
865
	   jz	   @f
866
	   stosb
867
	   loop    @b
346 diamond 868
@@:
672 hidnplayr 869
	   mov	   dword [edi], '.obj'
870
	   mov	   byte [edi+4], 0
871
	   stdcall load_file, edx
214 serge 872
 
672 hidnplayr 873
	   test eax, eax
874
	   jz .exit
188 serge 875
 
672 hidnplayr 876
	   mov [coff], eax
188 serge 877
 
672 hidnplayr 878
	   movzx ecx, [eax+CFH.nSections]
879
	   xor ebx, ebx
188 serge 880
 
672 hidnplayr 881
	   lea edx, [eax+20]
188 serge 882
@@:
672 hidnplayr 883
	   add ebx, [edx+CFS.SizeOfRawData]
884
	   add ebx, 15
885
	   and ebx, not 15
886
	   add edx, COFF_SECTION_SIZE
887
	   dec ecx
888
	   jnz @B
889
	   mov [img_size], ebx
188 serge 890
 
672 hidnplayr 891
	   stdcall kernel_alloc, ebx
892
	   test eax, eax
893
	   jz .fail
894
	   mov [img_base], eax
188 serge 895
 
672 hidnplayr 896
	   mov edi, eax
897
	   xor eax, eax
898
	   mov ecx, [img_size]
899
	   add ecx, 4095
900
	   and ecx, not 4095
901
	   shr ecx, 2
902
	   cld
903
	   rep stosd
188 serge 904
 
672 hidnplayr 905
	   mov edx, [coff]
906
	   movzx ebx, [edx+CFH.nSections]
907
	   mov edi, [img_base]
908
	   lea eax, [edx+20]
188 serge 909
@@:
672 hidnplayr 910
	   mov [eax+CFS.VirtualAddress], edi
911
	   mov esi, [eax+CFS.PtrRawData]
912
	   test esi, esi
913
	   jnz .copy
914
	   add edi, [eax+CFS.SizeOfRawData]
915
	   jmp .next
188 serge 916
.copy:
672 hidnplayr 917
	   add esi, edx
918
	   mov ecx, [eax+CFS.SizeOfRawData]
919
	   cld
920
	   rep movsb
188 serge 921
.next:
672 hidnplayr 922
	   add edi, 15
923
	   and edi, not 15
924
	   add eax, COFF_SECTION_SIZE
925
	   dec ebx
926
	   jnz @B
188 serge 927
 
672 hidnplayr 928
	   mov ebx, [edx+CFH.pSymTable]
929
	   add ebx, edx
930
	   mov [sym], ebx
931
	   mov ecx, [edx+CFH.nSymbols]
932
	   add ecx,ecx
933
	   lea ecx,[ecx+ecx*8] ;ecx*=18 = nSymbols*CSYM_SIZE
934
	   add ecx, [sym]
935
	   mov [strings], ecx
188 serge 936
 
672 hidnplayr 937
	   lea ebx, [exports]
938
	   mov dword [ebx], kernel_export
939
	   mov dword [ebx+4], 0
940
	   lea eax, [edx+20]
188 serge 941
 
672 hidnplayr 942
	   stdcall fix_coff_symbols, eax, [sym], [edx+CFH.nSymbols],\
943
				     [strings], ebx
944
	   test eax, eax
945
	   jz .link_fail
188 serge 946
 
672 hidnplayr 947
	   mov ebx, [coff]
1289 diamond 948
	   stdcall fix_coff_relocs, ebx, [sym], 0
188 serge 949
 
672 hidnplayr 950
	   stdcall get_coff_sym,[sym],[ebx+CFH.nSymbols],szVersion
951
	   test eax, eax
952
	   jz .link_fail
227 serge 953
 
672 hidnplayr 954
	   mov eax, [eax]
955
	   shr eax, 16
956
	   cmp eax, DRV_COMPAT
957
	   jb .ver_fail
227 serge 958
 
672 hidnplayr 959
	   cmp eax, DRV_CURRENT
960
	   ja .ver_fail
227 serge 961
 
672 hidnplayr 962
	   mov ebx, [coff]
963
	   stdcall get_coff_sym,[sym],[ebx+CFH.nSymbols],szSTART
964
	   mov [start], eax
188 serge 965
 
672 hidnplayr 966
	   stdcall kernel_free, [coff]
188 serge 967
 
672 hidnplayr 968
	   mov ebx, [start]
969
	   stdcall ebx, DRV_ENTRY
970
	   test eax, eax
971
	   jnz .ok
188 serge 972
 
672 hidnplayr 973
	   stdcall kernel_free, [img_base]
1018 diamond 974
           cmp     dword [file_name+13], 'SOUN'
975
           jnz     @f
976
           cmp     dword [file_name+17], 'D.ob'
977
           jnz     @f
978
           cmp     word [file_name+21], 'j'
979
           jnz     @f
980
           mov     esi, aSis
981
           jmp     .redo
982
@@:
672 hidnplayr 983
	   xor eax, eax
984
	   ret
188 serge 985
.ok:
672 hidnplayr 986
	   mov ebx, [img_base]
987
	   mov [eax+SRV.base], ebx
988
	   mov ecx, [start]
989
	   mov [eax+SRV.entry], ecx
990
	   ret
227 serge 991
 
992
.ver_fail:
672 hidnplayr 993
	   mov esi, msg_CR
994
	   call sys_msg_board_str
995
	   mov esi, [driver_name]
996
	   call sys_msg_board_str
997
	   mov esi, msg_CR
998
	   call sys_msg_board_str
999
	   mov esi, msg_version
1000
	   call sys_msg_board_str
1001
	   mov esi, msg_www
1002
	   call sys_msg_board_str
1003
	   jmp .cleanup
227 serge 1004
 
1005
.link_fail:
672 hidnplayr 1006
	   mov esi, msg_module
1007
	   call sys_msg_board_str
1008
	   mov esi, [driver_name]
1009
	   call sys_msg_board_str
1010
	   mov esi, msg_CR
1011
	   call sys_msg_board_str
227 serge 1012
.cleanup:
672 hidnplayr 1013
	   stdcall kernel_free,[img_base]
188 serge 1014
.fail:
672 hidnplayr 1015
	   stdcall kernel_free, [coff]
227 serge 1016
.exit:
672 hidnplayr 1017
	   xor eax, eax
1018
	   ret
164 serge 1019
endp
1020
 
198 serge 1021
align 4
1022
proc load_library stdcall, file_name:dword
672 hidnplayr 1023
	   locals
1289 diamond 1024
	     fullname  rb 260
1025
	     fileinfo  rb 40
672 hidnplayr 1026
	     coff      dd ?
1027
	     img_base  dd ?
1028
	   endl
198 serge 1029
 
672 hidnplayr 1030
	   cli
198 serge 1031
 
1289 diamond 1032
; resolve file name
1033
	   mov ebx, [file_name]
1034
	   lea edi, [fullname+1]
1035
	   mov byte [edi-1], '/'
1036
	   stdcall get_full_file_name, edi, 259
1037
	   test al, al
1038
	   jz .fail
1039
 
1040
; scan for required DLL in list of already loaded for this process,
1041
; ignore timestamp
1042
	   mov esi, [CURRENT_TASK]
1043
	   shl esi, 8
1044
	   lea ebx, [esi+SLOT_BASE+APP_OBJ_OFFSET]
1045
	   mov esi, [ebx+APPOBJ.fd]
1046
	   lea edi, [fullname]
1047
.scan_in_process:
1048
	   cmp esi, ebx
1049
	   jz .not_in_process
1050
	   cmp dword [esi+APPOBJ.magic], 'HDLL'
1051
	   jnz .next_in_process
1052
	   mov eax, [esi+HDLL.parent]
1053
	   add eax, DLLDESCR.name
1054
	   stdcall strncmp, eax, edi, -1
672 hidnplayr 1055
	   test eax, eax
1289 diamond 1056
	   jnz .next_in_process
1057
; simple variant: load DLL which is already loaded in this process
1058
; just increment reference counters and return address of exports table
1059
	   inc [esi+HDLL.refcount]
1060
	   mov ecx, [esi+HDLL.parent]
1061
	   inc [ecx+DLLDESCR.refcount]
1062
	   mov eax, [ecx+DLLDESCR.exports]
1063
	   sub eax, [ecx+DLLDESCR.defaultbase]
1064
	   add eax, [esi+HDLL.base]
1065
	   ret
1066
.next_in_process:
1067
	   mov esi, [esi+APPOBJ.fd]
1068
	   jmp .scan_in_process
1069
.not_in_process:
1070
 
1071
; scan in full list, compare timestamp
1072
	   lea eax, [fileinfo]
1073
	   stdcall get_fileinfo, edi, eax
1074
	   test eax, eax
1075
	   jnz .fail
1076
	   mov esi, [dll_list.fd]
1077
.scan_for_dlls:
1078
	   cmp esi, dll_list
1079
	   jz .load_new
1080
	   lea eax, [esi+DLLDESCR.name]
1081
	   stdcall strncmp, eax, edi, -1
1082
	   test eax, eax
1083
	   jnz .continue_scan
1084
.test_prev_dll:
1085
	   mov eax, dword [fileinfo+24]	; last modified time
1086
	   mov edx, dword [fileinfo+28]	; last modified date
1087
	   cmp dword [esi+DLLDESCR.timestamp], eax
1088
	   jnz .continue_scan
1089
	   cmp dword [esi+DLLDESCR.timestamp+4], edx
1090
	   jz .dll_already_loaded
1091
.continue_scan:
1092
	   mov esi, [esi+DLLDESCR.fd]
1093
	   jmp .scan_for_dlls
1094
 
1095
; new DLL
1096
.load_new:
1097
; load file
1098
	   stdcall load_file, edi
1099
	   test eax, eax
672 hidnplayr 1100
	   jz .fail
1289 diamond 1101
	   mov [coff], eax
1102
	   mov dword [fileinfo+32], ebx
198 serge 1103
 
1289 diamond 1104
; allocate DLLDESCR struct; size is DLLDESCR.sizeof plus size of DLL name
1105
	   mov esi, edi
1106
	   mov ecx, -1
1107
	   xor eax, eax
1108
	   repnz scasb
1109
	   not ecx
1110
	   lea eax, [ecx+DLLDESCR.sizeof]
1111
	   push ecx
1112
	   call malloc
1113
	   pop ecx
1114
	   test eax, eax
1115
	   jz .fail_and_free_coff
1116
; save timestamp
1117
	   lea edi, [eax+DLLDESCR.name]
1118
	   rep movsb
1119
	   mov esi, eax
1120
	   mov eax, dword [fileinfo+24]
1121
	   mov dword [esi+DLLDESCR.timestamp], eax
1122
	   mov eax, dword [fileinfo+28]
1123
	   mov dword [esi+DLLDESCR.timestamp+4], eax
1124
; initialize DLLDESCR struct
1125
	   and dword [esi+DLLDESCR.refcount], 0 ; no HDLLs yet; later it will be incremented
1126
	   mov [esi+DLLDESCR.fd], dll_list
1127
	   mov eax, [dll_list.bk]
1128
	   mov [dll_list.bk], esi
1129
	   mov [esi+DLLDESCR.bk], eax
1130
	   mov [eax+DLLDESCR.fd], esi
1131
 
1132
; calculate size of loaded DLL
1133
	   mov edx, [coff]
1134
	   movzx ecx, [edx+CFH.nSections]
672 hidnplayr 1135
	   xor ebx, ebx
198 serge 1136
 
1289 diamond 1137
	   add edx, 20
198 serge 1138
@@:
672 hidnplayr 1139
	   add ebx, [edx+CFS.SizeOfRawData]
1140
	   add ebx, 15
1141
	   and ebx, not 15
1142
	   add edx, COFF_SECTION_SIZE
1143
	   dec ecx
1144
	   jnz @B
1289 diamond 1145
; it must be nonzero and not too big
1146
	   mov [esi+DLLDESCR.size], ebx
1147
	   test ebx, ebx
1148
	   jz .fail_and_free_dll
1149
	   cmp ebx, MAX_DEFAULT_DLL_ADDR-MIN_DEFAULT_DLL_ADDR
1150
	   ja .fail_and_free_dll
1151
; allocate memory for kernel-side image
1152
	   stdcall kernel_alloc, ebx
672 hidnplayr 1153
	   test eax, eax
1289 diamond 1154
	   jz .fail_and_free_dll
1155
	   mov [esi+DLLDESCR.data], eax
1156
; calculate preferred base address
1157
	   add ebx, 0x1FFF
1158
	   and ebx, not 0xFFF
1159
	   mov ecx, [dll_cur_addr]
1160
	   lea edx, [ecx+ebx]
1161
	   cmp edx, MAX_DEFAULT_DLL_ADDR
1162
	   jb @f
1163
	   mov ecx, MIN_DEFAULT_DLL_ADDR
1164
	   lea edx, [ecx+ebx]
1165
@@:
1166
	   mov [esi+DLLDESCR.defaultbase], ecx
1167
	   mov [dll_cur_addr], edx
198 serge 1168
 
1289 diamond 1169
; copy sections and set correct values for VirtualAddress'es in headers
1170
	   push esi
672 hidnplayr 1171
	   mov edx, [coff]
1172
	   movzx ebx, [edx+CFH.nSections]
1289 diamond 1173
	   mov edi, eax
1174
	   add edx, 20
1175
	   xor eax, eax
1176
	   cld
198 serge 1177
@@:
1289 diamond 1178
	   mov [edx+CFS.VirtualAddress], ecx
1179
	   add ecx, [edx+CFS.SizeOfRawData]
1180
	   mov esi, [edx+CFS.PtrRawData]
1181
	   push ecx
1182
	   mov ecx, [edx+CFS.SizeOfRawData]
672 hidnplayr 1183
	   test esi, esi
1184
	   jnz .copy
1289 diamond 1185
	   rep stosb
672 hidnplayr 1186
	   jmp .next
198 serge 1187
.copy:
1289 diamond 1188
	   add esi, [coff]
672 hidnplayr 1189
	   rep movsb
198 serge 1190
.next:
1289 diamond 1191
           pop ecx
672 hidnplayr 1192
	   add edi, 15 ;-new_app_base
1289 diamond 1193
	   add ecx, 15
672 hidnplayr 1194
	   and edi, -16
1289 diamond 1195
	   and ecx, -16
1196
	   add edx, COFF_SECTION_SIZE
672 hidnplayr 1197
	   dec ebx
1198
	   jnz @B
1289 diamond 1199
	   pop esi
198 serge 1200
 
1289 diamond 1201
; save some additional data from COFF file
1202
; later we will use COFF header, headers for sections and symbol table
1203
; and also relocations table for all sections
1204
	   mov edx, [coff]
672 hidnplayr 1205
	   mov ebx, [edx+CFH.pSymTable]
1289 diamond 1206
	   mov edi, dword [fileinfo+32]
1207
	   sub edi, ebx
1208
	   jc .fail_and_free_data
1209
	   mov [esi+DLLDESCR.symbols_lim], edi
672 hidnplayr 1210
	   add ebx, edx
1289 diamond 1211
	   movzx ecx, [edx+CFH.nSections]
1212
	   lea ecx, [ecx*5]
1213
	   lea edi, [edi+ecx*8+20]
1214
	   add edx, 20
1215
@@:
1216
	   movzx eax, [edx+CFS.NumReloc]
1217
	   lea eax, [eax*5]
1218
	   lea edi, [edi+eax*2]
1219
	   add edx, COFF_SECTION_SIZE
1220
	   sub ecx, 5
1221
	   jnz @b
1222
	   stdcall kernel_alloc, edi
1223
	   test eax, eax
1224
	   jz  .fail_and_free_data
1225
	   mov edx, [coff]
1226
	   movzx ecx, [edx+CFH.nSections]
1227
	   lea ecx, [ecx*5]
1228
	   lea ecx, [ecx*2+5]
1229
	   mov [esi+DLLDESCR.coff_hdr], eax
1230
	   push esi
1231
	   mov esi, edx
1232
	   mov edi, eax
1233
	   rep movsd
1234
	   pop esi
1235
	   mov [esi+DLLDESCR.symbols_ptr], edi
1236
	   push esi
672 hidnplayr 1237
	   mov ecx, [edx+CFH.nSymbols]
1289 diamond 1238
	   mov [esi+DLLDESCR.symbols_num], ecx
1239
	   mov ecx, [esi+DLLDESCR.symbols_lim]
1240
	   mov esi, ebx
1241
	   rep movsb
1242
	   pop esi
1243
	   mov ebx, [esi+DLLDESCR.coff_hdr]
1244
	   push esi
1245
	   movzx eax, [edx+CFH.nSections]
1246
	   lea edx, [ebx+20]
1247
@@:
1248
           movzx ecx, [edx+CFS.NumReloc]
1249
           lea ecx, [ecx*5]
1250
           mov esi, [edx+CFS.PtrReloc]
1251
           mov [edx+CFS.PtrReloc], edi
1252
           sub [edx+CFS.PtrReloc], ebx
1253
           add esi, [coff]
1254
           shr ecx, 1
1255
           rep movsd
1256
           adc ecx, ecx
1257
           rep movsw
1258
           add edx, COFF_SECTION_SIZE
1259
           dec eax
1260
           jnz @b
1261
	   pop esi
198 serge 1262
 
1289 diamond 1263
; fixup symbols
1264
	   mov edx, ebx
1265
	   mov eax, [ebx+CFH.nSymbols]
1266
	   add edx, 20
1267
	   mov ecx, [esi+DLLDESCR.symbols_num]
1268
	   lea ecx, [ecx*9]
1269
	   add ecx, ecx
1270
	   add ecx, [esi+DLLDESCR.symbols_ptr]
198 serge 1271
 
1289 diamond 1272
	   stdcall fix_coff_symbols, edx, [esi+DLLDESCR.symbols_ptr], eax,\
1273
				     ecx, 0
1274
;	   test eax, eax
1275
;	   jnz @F
1276
;
1277
;@@:
1278
 
1279
	   stdcall get_coff_sym,[esi+DLLDESCR.symbols_ptr],[ebx+CFH.nSymbols],szEXPORTS
672 hidnplayr 1280
	   test eax, eax
1281
	   jnz @F
198 serge 1282
 
1289 diamond 1283
	   stdcall get_coff_sym,[esi+DLLDESCR.symbols_ptr],[ebx+CFH.nSymbols],sz_EXPORTS
198 serge 1284
@@:
1289 diamond 1285
	   mov [esi+DLLDESCR.exports], eax
198 serge 1286
 
1289 diamond 1287
; fix relocs in the hidden copy in kernel memory to default address
1288
; it is first fix; usually this will be enough, but second fix
1289
; can be necessary if real load address will not equal assumption
1290
	   mov eax, [esi+DLLDESCR.data]
1291
	   sub eax, [esi+DLLDESCR.defaultbase]
1292
	   stdcall fix_coff_relocs, ebx, [esi+DLLDESCR.symbols_ptr], eax
198 serge 1293
 
1289 diamond 1294
	   stdcall kernel_free, [coff]
916 serge 1295
 
1289 diamond 1296
.dll_already_loaded:
1297
	   inc [esi+DLLDESCR.refcount]
1298
	   push esi
1299
	   call init_heap
1300
	   pop  esi
1301
 
1302
	   mov edi, [esi+DLLDESCR.size]
1303
	   stdcall user_alloc_at, [esi+DLLDESCR.defaultbase], edi
1304
	   test eax, eax
1305
	   jnz @f
1306
	   stdcall user_alloc, edi
1307
	   test eax, eax
1308
	   jz  .fail_and_dereference
917 diamond 1309
@@:
1289 diamond 1310
	   mov [img_base], eax
1311
	   mov ebx, [CURRENT_TASK]
1312
	   shl ebx, 5
1292 diamond 1313
	   mov ebx, [CURRENT_TASK+ebx+TASKDATA.pid]
1289 diamond 1314
	   mov eax, HDLL.sizeof
1315
	   call create_kernel_object
1316
	   test eax, eax
1317
	   jz .fail_and_free_user
1318
	   mov [eax+APPOBJ.magic], 'HDLL'
1319
	   mov [eax+APPOBJ.destroy], destroy_hdll
1320
	   mov ebx, [img_base]
1321
	   mov [eax+HDLL.base], ebx
1322
	   mov [eax+HDLL.size], edi
1323
	   mov [eax+HDLL.refcount], 1
1324
	   mov [eax+HDLL.parent], esi
1325
	   mov edx, ebx
1326
	   shr edx, 12
1327
	   or dword [page_tabs+(edx-1)*4], DONT_FREE_BLOCK
1328
; copy entries of page table from kernel-side image to usermode
1329
; use copy-on-write for user-mode image, so map as readonly
1330
	   xor edi, edi
1331
	   mov ecx, [esi+DLLDESCR.data]
1332
	   shr ecx, 12
1333
.map_pages_loop:
1334
	   mov eax, [page_tabs+ecx*4]
1335
	   and eax, not 0xFFF
1336
	   or al, PG_USER
1337
	   xchg eax, [page_tabs+edx*4]
1338
	   test al, 1
1339
	   jz @f
1340
	   call free_page
1341
@@:
1342
	   invlpg [ebx+edi]
1343
	   inc ecx
1344
	   inc edx
1345
	   add edi, 0x1000
1346
	   cmp edi, [esi+DLLDESCR.size]
1347
	   jb .map_pages_loop
1348
 
1349
; if real user-mode base is not equal to preferred base, relocate image
1350
	   mov ebx, [img_base]
1351
	   sub ebx, [esi+DLLDESCR.defaultbase]
1352
	   jz @f
1353
	   stdcall rebase_coff, [esi+DLLDESCR.coff_hdr], [esi+DLLDESCR.symbols_ptr], ebx
1354
@@:
1355
 
1356
	   mov eax, [esi+DLLDESCR.exports]
1357
	   sub eax, [esi+DLLDESCR.defaultbase]
1358
	   add eax, [img_base]
1359
	   ret
1360
.fail_and_free_data:
1361
	   stdcall kernel_free, [esi+DLLDESCR.data]
1362
.fail_and_free_dll:
1363
	   mov eax, esi
1364
	   call free
1365
.fail_and_free_coff:
672 hidnplayr 1366
	   stdcall kernel_free, [coff]
198 serge 1367
.fail:
672 hidnplayr 1368
	   xor eax, eax
1369
	   ret
1289 diamond 1370
.fail_and_free_user:
1371
	   stdcall user_free, [img_base]
1372
.fail_and_dereference:
1373
	   mov eax, 1	; delete 1 reference
1374
	   call dereference_dll
1375
	   xor eax, eax
1376
	   ret
198 serge 1377
endp
1378
 
1289 diamond 1379
; in: eax = number of references to delete, esi -> DLLDESCR struc
1380
dereference_dll:
1381
	sub	[esi+DLLDESCR.refcount], eax
1382
	jnz	.ret
1383
	mov	eax, [esi+DLLDESCR.fd]
1384
	mov	edx, [esi+DLLDESCR.bk]
1385
	mov	[eax+DLLDESCR.bk], edx
1386
	mov	[edx+DLLDESCR.fd], eax
1292 diamond 1387
	stdcall	kernel_free, [esi+DLLDESCR.coff_hdr]
1289 diamond 1388
	stdcall	kernel_free, [esi+DLLDESCR.data]
1389
	mov	eax, esi
1390
	call	free
1391
.ret:
1392
	ret
1393
 
1394
destroy_hdll:
1395
	push	ebx esi edi
1396
	push	eax
1397
	mov	ebx, [eax+HDLL.base]
1398
	mov	esi, [eax+HDLL.parent]
1399
	mov	edx, [esi+DLLDESCR.size]
1292 diamond 1400
; The following actions require the context of application where HDLL is mapped.
1401
; However, destroy_hdll can be called in the context of OS thread when
1402
; cleaning up objects created by the application which is destroyed.
1403
; So remember current cr3 and set it to page table of target.
1404
	mov	eax, [eax+HDLL.pid]
1405
	call	pid_to_slot
1406
	shl	eax, 8
1407
	add	eax, SLOT_BASE
1408
	mov	ecx, [eax+APPDATA.dir_table]
1409
; Because we cheat with cr3, disable interrupts: task switch would restore
1410
; page table from APPDATA of current thread.
1411
; Also set [current_slot] because it is used by user_free.
1412
	pushf
1413
	cli
1414
	push	[current_slot]
1415
	mov	[current_slot], eax
1416
	mov	eax, cr3
1417
	push	eax
1418
	mov	cr3, ecx
1419
	push	ebx	; argument for user_free
1289 diamond 1420
	mov	eax, ebx
1421
	shr	ebx, 12
1422
	push	ebx
1423
	mov	esi, [esi+DLLDESCR.data]
1424
	shr	esi, 12
1425
.unmap_loop:
1426
	push	eax
1427
	mov	eax, 2
1428
	xchg	eax, [page_tabs+ebx*4]
1292 diamond 1429
	mov	ecx, [page_tabs+esi*4]
1430
	and	eax, not 0xFFF
1431
	and	ecx, not 0xFFF
1432
	cmp	eax, ecx
1433
	jz	@f
1289 diamond 1434
	call	free_page
1435
@@:
1436
	pop	eax
1437
	invlpg	[eax]
1438
	add	eax, 0x1000
1439
	inc	ebx
1440
	inc	esi
1441
	sub	edx, 0x1000
1442
	ja	.unmap_loop
1292 diamond 1443
	pop	ebx
1289 diamond 1444
	and	dword [page_tabs+(ebx-1)*4], not DONT_FREE_BLOCK
1292 diamond 1445
	call	user_free
1446
; Restore context.
1447
	pop	eax
1448
	mov	cr3, eax
1449
	pop	[current_slot]
1450
	popf
1451
; Ok, cheating is done.
1452
	pop	eax
1453
	push	eax
1289 diamond 1454
	mov	esi, [eax+HDLL.parent]
1455
	mov	eax, [eax+HDLL.refcount]
1456
	call	dereference_dll
1457
	pop	eax
1458
	call	destroy_kernel_object
1459
	pop	edi esi ebx
1460
	ret
1461
 
214 serge 1462
align 4
1275 serge 1463
stop_all_services:
1464
       push ebp
672 hidnplayr 1465
	   mov edx, [srv.fd]
214 serge 1466
.next:
672 hidnplayr 1467
	   cmp edx,  srv.fd-SRV_FD_OFFSET
1468
	   je .done
1469
	   cmp [edx+SRV.magic], ' SRV'
1470
	   jne .next
1275 serge 1471
       cmp [edx+SRV.size], SRV.sizeof
672 hidnplayr 1472
	   jne .next
732 serge 1473
 
769 Rus 1474
	   mov ebx, [edx+SRV.entry]
672 hidnplayr 1475
	   mov edx, [edx+SRV.fd]
769 Rus 1476
	   test ebx, ebx
1477
	   jz .next
732 serge 1478
 
769 Rus 1479
	   push edx
672 hidnplayr 1480
	   stdcall ebx, dword -1
1481
	   pop edx
1482
	   jmp .next
278 serge 1483
.done:
1275 serge 1484
       pop ebp
672 hidnplayr 1485
	   ret
198 serge 1486
 
281 serge 1487
; param
291 serge 1488
;  eax= size
1489
;  ebx= pid
214 serge 1490
 
281 serge 1491
align 4
1492
create_kernel_object:
1493
 
672 hidnplayr 1494
	   push ebx
1495
	   call malloc
1496
	   pop ebx
1497
	   test eax, eax
1498
	   jz .fail
281 serge 1499
 
672 hidnplayr 1500
	   mov ecx,[current_slot]
1501
	   add ecx, APP_OBJ_OFFSET
281 serge 1502
 
672 hidnplayr 1503
	   pushfd
1504
	   cli
1505
	   mov edx, [ecx+APPOBJ.fd]
1506
	   mov [eax+APPOBJ.fd], edx
1507
	   mov [eax+APPOBJ.bk], ecx
1508
	   mov [eax+APPOBJ.pid], ebx
281 serge 1509
 
672 hidnplayr 1510
	   mov [ecx+APPOBJ.fd], eax
1511
	   mov [edx+APPOBJ.bk], eax
1512
	   popfd
281 serge 1513
.fail:
672 hidnplayr 1514
	   ret
281 serge 1515
 
1516
; param
1517
;  eax= object
1518
 
1519
align 4
1520
destroy_kernel_object:
1521
 
672 hidnplayr 1522
	   pushfd
1523
	   cli
1524
	   mov ebx, [eax+APPOBJ.fd]
1525
	   mov ecx, [eax+APPOBJ.bk]
1526
	   mov [ebx+APPOBJ.bk], ecx
1527
	   mov [ecx+APPOBJ.fd], ebx
1528
	   popfd
281 serge 1529
 
672 hidnplayr 1530
	   xor edx, edx        ;clear common header
1531
	   mov [eax], edx
1532
	   mov [eax+4], edx
1533
	   mov [eax+8], edx
1534
	   mov [eax+12], edx
1535
	   mov [eax+16], edx
281 serge 1536
 
672 hidnplayr 1537
	   call free	       ;release object memory
1538
	   ret
281 serge 1539
 
1540
 
164 serge 1541
 
465 serge 1542
if 0
164 serge 1543
 
465 serge 1544
irq:
188 serge 1545
 
465 serge 1546
.irq0:
672 hidnplayr 1547
	   pusfd
1548
	   pushad
1549
	   push IRQ_0
1550
	   jmp .master
465 serge 1551
.irq_1:
672 hidnplayr 1552
	   pusfd
1553
	   pushad
1554
	   push IRQ_1
1555
	   jmp .master
465 serge 1556
 
1557
.master:
672 hidnplayr 1558
	   mov ax, app_data
1559
	   mov ds, eax
1560
	   mov es, eax
1561
	   mov ebx, [esp+4]  ;IRQ_xx
1562
	   mov eax, [irq_handlers+ebx+4]
1563
	   call intr_handler
1564
	   mov ecx, [esp+4]
1565
	   cmp [irq_actids+ecx*4], 0
1566
	   je @F
1567
	   in al, 0x21
1568
	   bts eax, ecx
1569
	   out 0x21, al
1570
	   mov al, 0x20
1571
	   out 0x20, al
1572
	   jmp .restart
465 serge 1573
 
1574
.slave:
672 hidnplayr 1575
	   mov ax, app_data
1576
	   mov ds, eax
1577
	   mov es, eax
1578
	   mov ebx, [esp+4]  ;IRQ_xx
1579
	   mov eax, [irq_handlers+ebx+4]
1580
	   call intr_handler
1581
	   mov ecx, [esp+4]
1582
	   sub ecx, 8
1583
	   cmp [irq_actids+ecx*4], 0
1584
	   je @F
1585
	   in al, 0xA1
1586
	   bts eax, ecx
1587
	   out 0xA1, al
1588
	   mov al, 0x20
1589
	   out 0xA0, al
1590
	   out 0x20, al
465 serge 1591
.restart:
672 hidnplayr 1592
	   mov ebx, [next_slot]
1593
	   test ebx, ebx
1594
	   jz @F
1595
	   mov [next_task],0
1596
	   mov esi, [prev_slot]
1597
	   call do_change_task
1598
	   add esp, 4
1599
	   iretd
465 serge 1600
 
1601
end if
1602