Subversion Repositories Kolibri OS

Rev

Rev 1345 | 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: 1376 $
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
1376 clevermous 215
	   push ebx edx
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
1376 clevermous 223
	   pop edx ebx
164 serge 224
	   ret
225
endp
226
 
227
align 4
557 serge 228
proc pci_read16 stdcall, bus:dword, devfn:dword, reg:dword
1376 clevermous 229
	   push ebx edx
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
1376 clevermous 237
	   pop edx ebx
557 serge 238
	   ret
239
endp
240
 
241
align 4
164 serge 242
proc pci_read8 stdcall, bus:dword, devfn:dword, reg:dword
1376 clevermous 243
	   push ebx edx
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
1376 clevermous 251
	   pop edx ebx
164 serge 252
	   ret
253
endp
254
 
255
align 4
256
proc pci_write8 stdcall, bus:dword, devfn:dword, reg:dword, val:dword
1376 clevermous 257
	   push ebx edx
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
1376 clevermous 266
	   pop edx 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
1376 clevermous 272
	   push ebx edx
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
1376 clevermous 281
	   pop edx 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
1376 clevermous 287
	   push ebx edx
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
1376 clevermous 296
	   pop edx 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
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
 
1296 diamond 1021
; in: edx -> COFF_SECTION struct
1022
; out: eax = alignment as mask for bits to drop
1023
coff_get_align:
1024
; Rules:
1025
; - if alignment is not given, use default = 4K;
1026
; - if alignment is given and is no more than 4K, use it;
1027
; - if alignment is more than 4K, revert to 4K.
1028
	push	ecx
1029
	mov	cl, byte [edx+CFS.Characteristics+2]
1030
	mov	eax, 1
1031
	shr	cl, 4
1032
	dec	cl
1033
	js	.default
1034
	cmp	cl, 12
1035
	jbe	@f
1036
.default:
1037
	mov	cl, 12
1038
@@:
1039
	shl	eax, cl
1040
	pop	ecx
1041
	dec	eax
1042
	ret
1043
 
198 serge 1044
align 4
1045
proc load_library stdcall, file_name:dword
672 hidnplayr 1046
	   locals
1289 diamond 1047
	     fullname  rb 260
1048
	     fileinfo  rb 40
672 hidnplayr 1049
	     coff      dd ?
1050
	     img_base  dd ?
1051
	   endl
198 serge 1052
 
672 hidnplayr 1053
	   cli
198 serge 1054
 
1289 diamond 1055
; resolve file name
1056
	   mov ebx, [file_name]
1057
	   lea edi, [fullname+1]
1058
	   mov byte [edi-1], '/'
1059
	   stdcall get_full_file_name, edi, 259
1060
	   test al, al
1061
	   jz .fail
1062
 
1063
; scan for required DLL in list of already loaded for this process,
1064
; ignore timestamp
1065
	   mov esi, [CURRENT_TASK]
1066
	   shl esi, 8
1067
	   lea edi, [fullname]
1311 diamond 1068
	   mov ebx, [esi+SLOT_BASE+APPDATA.dlls_list_ptr]
1069
	   test ebx, ebx
1070
	   jz  .not_in_process
1071
	   mov esi, [ebx+HDLL.fd]
1289 diamond 1072
.scan_in_process:
1073
	   cmp esi, ebx
1074
	   jz .not_in_process
1075
	   mov eax, [esi+HDLL.parent]
1076
	   add eax, DLLDESCR.name
1077
	   stdcall strncmp, eax, edi, -1
672 hidnplayr 1078
	   test eax, eax
1289 diamond 1079
	   jnz .next_in_process
1080
; simple variant: load DLL which is already loaded in this process
1081
; just increment reference counters and return address of exports table
1082
	   inc [esi+HDLL.refcount]
1083
	   mov ecx, [esi+HDLL.parent]
1084
	   inc [ecx+DLLDESCR.refcount]
1085
	   mov eax, [ecx+DLLDESCR.exports]
1086
	   sub eax, [ecx+DLLDESCR.defaultbase]
1087
	   add eax, [esi+HDLL.base]
1088
	   ret
1089
.next_in_process:
1311 diamond 1090
	   mov esi, [esi+HDLL.fd]
1289 diamond 1091
	   jmp .scan_in_process
1092
.not_in_process:
1093
 
1094
; scan in full list, compare timestamp
1095
	   lea eax, [fileinfo]
1096
	   stdcall get_fileinfo, edi, eax
1097
	   test eax, eax
1098
	   jnz .fail
1099
	   mov esi, [dll_list.fd]
1100
.scan_for_dlls:
1101
	   cmp esi, dll_list
1102
	   jz .load_new
1103
	   lea eax, [esi+DLLDESCR.name]
1104
	   stdcall strncmp, eax, edi, -1
1105
	   test eax, eax
1106
	   jnz .continue_scan
1107
.test_prev_dll:
1108
	   mov eax, dword [fileinfo+24]	; last modified time
1109
	   mov edx, dword [fileinfo+28]	; last modified date
1110
	   cmp dword [esi+DLLDESCR.timestamp], eax
1111
	   jnz .continue_scan
1112
	   cmp dword [esi+DLLDESCR.timestamp+4], edx
1113
	   jz .dll_already_loaded
1114
.continue_scan:
1115
	   mov esi, [esi+DLLDESCR.fd]
1116
	   jmp .scan_for_dlls
1117
 
1118
; new DLL
1119
.load_new:
1120
; load file
1121
	   stdcall load_file, edi
1122
	   test eax, eax
672 hidnplayr 1123
	   jz .fail
1289 diamond 1124
	   mov [coff], eax
1125
	   mov dword [fileinfo+32], ebx
198 serge 1126
 
1289 diamond 1127
; allocate DLLDESCR struct; size is DLLDESCR.sizeof plus size of DLL name
1128
	   mov esi, edi
1129
	   mov ecx, -1
1130
	   xor eax, eax
1131
	   repnz scasb
1132
	   not ecx
1133
	   lea eax, [ecx+DLLDESCR.sizeof]
1134
	   push ecx
1135
	   call malloc
1136
	   pop ecx
1137
	   test eax, eax
1138
	   jz .fail_and_free_coff
1139
; save timestamp
1140
	   lea edi, [eax+DLLDESCR.name]
1141
	   rep movsb
1142
	   mov esi, eax
1143
	   mov eax, dword [fileinfo+24]
1144
	   mov dword [esi+DLLDESCR.timestamp], eax
1145
	   mov eax, dword [fileinfo+28]
1146
	   mov dword [esi+DLLDESCR.timestamp+4], eax
1147
; initialize DLLDESCR struct
1148
	   and dword [esi+DLLDESCR.refcount], 0 ; no HDLLs yet; later it will be incremented
1149
	   mov [esi+DLLDESCR.fd], dll_list
1150
	   mov eax, [dll_list.bk]
1151
	   mov [dll_list.bk], esi
1152
	   mov [esi+DLLDESCR.bk], eax
1153
	   mov [eax+DLLDESCR.fd], esi
1154
 
1155
; calculate size of loaded DLL
1156
	   mov edx, [coff]
1157
	   movzx ecx, [edx+CFH.nSections]
672 hidnplayr 1158
	   xor ebx, ebx
198 serge 1159
 
1289 diamond 1160
	   add edx, 20
198 serge 1161
@@:
1296 diamond 1162
	   call coff_get_align
1163
	   add ebx, eax
1164
	   not eax
1165
	   and ebx, eax
672 hidnplayr 1166
	   add ebx, [edx+CFS.SizeOfRawData]
1167
	   add edx, COFF_SECTION_SIZE
1168
	   dec ecx
1169
	   jnz @B
1289 diamond 1170
; it must be nonzero and not too big
1171
	   mov [esi+DLLDESCR.size], ebx
1172
	   test ebx, ebx
1173
	   jz .fail_and_free_dll
1174
	   cmp ebx, MAX_DEFAULT_DLL_ADDR-MIN_DEFAULT_DLL_ADDR
1175
	   ja .fail_and_free_dll
1176
; allocate memory for kernel-side image
1177
	   stdcall kernel_alloc, ebx
672 hidnplayr 1178
	   test eax, eax
1289 diamond 1179
	   jz .fail_and_free_dll
1180
	   mov [esi+DLLDESCR.data], eax
1181
; calculate preferred base address
1182
	   add ebx, 0x1FFF
1183
	   and ebx, not 0xFFF
1184
	   mov ecx, [dll_cur_addr]
1185
	   lea edx, [ecx+ebx]
1186
	   cmp edx, MAX_DEFAULT_DLL_ADDR
1187
	   jb @f
1188
	   mov ecx, MIN_DEFAULT_DLL_ADDR
1189
	   lea edx, [ecx+ebx]
1190
@@:
1191
	   mov [esi+DLLDESCR.defaultbase], ecx
1192
	   mov [dll_cur_addr], edx
198 serge 1193
 
1289 diamond 1194
; copy sections and set correct values for VirtualAddress'es in headers
1195
	   push esi
672 hidnplayr 1196
	   mov edx, [coff]
1197
	   movzx ebx, [edx+CFH.nSections]
1289 diamond 1198
	   mov edi, eax
1199
	   add edx, 20
1200
	   cld
198 serge 1201
@@:
1296 diamond 1202
	   call coff_get_align
1203
	   add ecx, eax
1204
	   add edi, eax
1205
	   not eax
1206
	   and ecx, eax
1207
	   and edi, eax
1289 diamond 1208
	   mov [edx+CFS.VirtualAddress], ecx
1209
	   add ecx, [edx+CFS.SizeOfRawData]
1210
	   mov esi, [edx+CFS.PtrRawData]
1211
	   push ecx
1212
	   mov ecx, [edx+CFS.SizeOfRawData]
672 hidnplayr 1213
	   test esi, esi
1214
	   jnz .copy
1296 diamond 1215
	   xor eax, eax
1289 diamond 1216
	   rep stosb
672 hidnplayr 1217
	   jmp .next
198 serge 1218
.copy:
1289 diamond 1219
	   add esi, [coff]
672 hidnplayr 1220
	   rep movsb
198 serge 1221
.next:
1289 diamond 1222
           pop ecx
1223
	   add edx, COFF_SECTION_SIZE
672 hidnplayr 1224
	   dec ebx
1225
	   jnz @B
1289 diamond 1226
	   pop esi
198 serge 1227
 
1289 diamond 1228
; save some additional data from COFF file
1229
; later we will use COFF header, headers for sections and symbol table
1230
; and also relocations table for all sections
1231
	   mov edx, [coff]
672 hidnplayr 1232
	   mov ebx, [edx+CFH.pSymTable]
1289 diamond 1233
	   mov edi, dword [fileinfo+32]
1234
	   sub edi, ebx
1235
	   jc .fail_and_free_data
1236
	   mov [esi+DLLDESCR.symbols_lim], edi
672 hidnplayr 1237
	   add ebx, edx
1289 diamond 1238
	   movzx ecx, [edx+CFH.nSections]
1239
	   lea ecx, [ecx*5]
1240
	   lea edi, [edi+ecx*8+20]
1241
	   add edx, 20
1242
@@:
1243
	   movzx eax, [edx+CFS.NumReloc]
1244
	   lea eax, [eax*5]
1245
	   lea edi, [edi+eax*2]
1246
	   add edx, COFF_SECTION_SIZE
1247
	   sub ecx, 5
1248
	   jnz @b
1249
	   stdcall kernel_alloc, edi
1250
	   test eax, eax
1251
	   jz  .fail_and_free_data
1252
	   mov edx, [coff]
1253
	   movzx ecx, [edx+CFH.nSections]
1254
	   lea ecx, [ecx*5]
1255
	   lea ecx, [ecx*2+5]
1256
	   mov [esi+DLLDESCR.coff_hdr], eax
1257
	   push esi
1258
	   mov esi, edx
1259
	   mov edi, eax
1260
	   rep movsd
1261
	   pop esi
1262
	   mov [esi+DLLDESCR.symbols_ptr], edi
1263
	   push esi
672 hidnplayr 1264
	   mov ecx, [edx+CFH.nSymbols]
1289 diamond 1265
	   mov [esi+DLLDESCR.symbols_num], ecx
1266
	   mov ecx, [esi+DLLDESCR.symbols_lim]
1267
	   mov esi, ebx
1268
	   rep movsb
1269
	   pop esi
1270
	   mov ebx, [esi+DLLDESCR.coff_hdr]
1271
	   push esi
1272
	   movzx eax, [edx+CFH.nSections]
1273
	   lea edx, [ebx+20]
1274
@@:
1275
           movzx ecx, [edx+CFS.NumReloc]
1276
           lea ecx, [ecx*5]
1277
           mov esi, [edx+CFS.PtrReloc]
1278
           mov [edx+CFS.PtrReloc], edi
1279
           sub [edx+CFS.PtrReloc], ebx
1280
           add esi, [coff]
1281
           shr ecx, 1
1282
           rep movsd
1283
           adc ecx, ecx
1284
           rep movsw
1285
           add edx, COFF_SECTION_SIZE
1286
           dec eax
1287
           jnz @b
1288
	   pop esi
198 serge 1289
 
1289 diamond 1290
; fixup symbols
1291
	   mov edx, ebx
1292
	   mov eax, [ebx+CFH.nSymbols]
1293
	   add edx, 20
1294
	   mov ecx, [esi+DLLDESCR.symbols_num]
1295
	   lea ecx, [ecx*9]
1296
	   add ecx, ecx
1297
	   add ecx, [esi+DLLDESCR.symbols_ptr]
198 serge 1298
 
1289 diamond 1299
	   stdcall fix_coff_symbols, edx, [esi+DLLDESCR.symbols_ptr], eax,\
1300
				     ecx, 0
1301
;	   test eax, eax
1302
;	   jnz @F
1303
;
1304
;@@:
1305
 
1306
	   stdcall get_coff_sym,[esi+DLLDESCR.symbols_ptr],[ebx+CFH.nSymbols],szEXPORTS
672 hidnplayr 1307
	   test eax, eax
1308
	   jnz @F
198 serge 1309
 
1289 diamond 1310
	   stdcall get_coff_sym,[esi+DLLDESCR.symbols_ptr],[ebx+CFH.nSymbols],sz_EXPORTS
198 serge 1311
@@:
1289 diamond 1312
	   mov [esi+DLLDESCR.exports], eax
198 serge 1313
 
1289 diamond 1314
; fix relocs in the hidden copy in kernel memory to default address
1315
; it is first fix; usually this will be enough, but second fix
1316
; can be necessary if real load address will not equal assumption
1317
	   mov eax, [esi+DLLDESCR.data]
1318
	   sub eax, [esi+DLLDESCR.defaultbase]
1319
	   stdcall fix_coff_relocs, ebx, [esi+DLLDESCR.symbols_ptr], eax
198 serge 1320
 
1289 diamond 1321
	   stdcall kernel_free, [coff]
916 serge 1322
 
1289 diamond 1323
.dll_already_loaded:
1324
	   inc [esi+DLLDESCR.refcount]
1325
	   push esi
1326
	   call init_heap
1327
	   pop  esi
1328
 
1329
	   mov edi, [esi+DLLDESCR.size]
1330
	   stdcall user_alloc_at, [esi+DLLDESCR.defaultbase], edi
1331
	   test eax, eax
1332
	   jnz @f
1333
	   stdcall user_alloc, edi
1334
	   test eax, eax
1335
	   jz  .fail_and_dereference
917 diamond 1336
@@:
1289 diamond 1337
	   mov [img_base], eax
1311 diamond 1338
	   mov eax, HDLL.sizeof
1339
	   call malloc
1340
	   test eax, eax
1341
	   jz  .fail_and_free_user
1289 diamond 1342
	   mov ebx, [CURRENT_TASK]
1343
	   shl ebx, 5
1311 diamond 1344
	   mov edx, [CURRENT_TASK+ebx+TASKDATA.pid]
1345
	   mov [eax+HDLL.pid], edx
1346
	   push eax
1347
	   call init_dlls_in_thread
1348
	   pop  ebx
1289 diamond 1349
	   test eax, eax
1311 diamond 1350
	   jz  .fail_and_free_user
1351
	   mov edx, [eax+HDLL.fd]
1352
	   mov [ebx+HDLL.fd], edx
1353
	   mov [ebx+HDLL.bk], eax
1354
	   mov [eax+HDLL.fd], ebx
1355
	   mov [edx+HDLL.bk], ebx
1356
	   mov eax, ebx
1289 diamond 1357
	   mov ebx, [img_base]
1358
	   mov [eax+HDLL.base], ebx
1359
	   mov [eax+HDLL.size], edi
1360
	   mov [eax+HDLL.refcount], 1
1361
	   mov [eax+HDLL.parent], esi
1362
	   mov edx, ebx
1363
	   shr edx, 12
1364
	   or dword [page_tabs+(edx-1)*4], DONT_FREE_BLOCK
1365
; copy entries of page table from kernel-side image to usermode
1366
; use copy-on-write for user-mode image, so map as readonly
1367
	   xor edi, edi
1368
	   mov ecx, [esi+DLLDESCR.data]
1369
	   shr ecx, 12
1370
.map_pages_loop:
1371
	   mov eax, [page_tabs+ecx*4]
1372
	   and eax, not 0xFFF
1373
	   or al, PG_USER
1374
	   xchg eax, [page_tabs+edx*4]
1375
	   test al, 1
1376
	   jz @f
1377
	   call free_page
1378
@@:
1379
	   invlpg [ebx+edi]
1380
	   inc ecx
1381
	   inc edx
1382
	   add edi, 0x1000
1383
	   cmp edi, [esi+DLLDESCR.size]
1384
	   jb .map_pages_loop
1385
 
1386
; if real user-mode base is not equal to preferred base, relocate image
1387
	   sub ebx, [esi+DLLDESCR.defaultbase]
1388
	   jz @f
1389
	   stdcall rebase_coff, [esi+DLLDESCR.coff_hdr], [esi+DLLDESCR.symbols_ptr], ebx
1390
@@:
1391
 
1392
	   mov eax, [esi+DLLDESCR.exports]
1393
	   sub eax, [esi+DLLDESCR.defaultbase]
1394
	   add eax, [img_base]
1395
	   ret
1396
.fail_and_free_data:
1397
	   stdcall kernel_free, [esi+DLLDESCR.data]
1398
.fail_and_free_dll:
1399
	   mov eax, esi
1400
	   call free
1401
.fail_and_free_coff:
672 hidnplayr 1402
	   stdcall kernel_free, [coff]
198 serge 1403
.fail:
672 hidnplayr 1404
	   xor eax, eax
1405
	   ret
1289 diamond 1406
.fail_and_free_user:
1407
	   stdcall user_free, [img_base]
1408
.fail_and_dereference:
1409
	   mov eax, 1	; delete 1 reference
1410
	   call dereference_dll
1411
	   xor eax, eax
1412
	   ret
198 serge 1413
endp
1414
 
1311 diamond 1415
; initialize [APPDATA.dlls_list_ptr] for given thread
1416
; DLL is per-process object, so APPDATA.dlls_list_ptr must be
1417
; kept in sync for all threads of one process.
1418
; out: eax = APPDATA.dlls_list_ptr if all is OK,
1419
; NULL if memory allocation failed
1420
init_dlls_in_thread:
1421
	mov	ebx, [current_slot]
1422
	mov	eax, [ebx+APPDATA.dlls_list_ptr]
1423
	test	eax, eax
1424
	jnz	.ret
1425
	push	[ebx+APPDATA.dir_table]
1426
	mov	eax, 8
1427
	call	malloc
1428
	pop	edx
1429
	test	eax, eax
1430
	jz	.ret
1431
	mov	[eax], eax
1432
	mov	[eax+4], eax
1433
	mov	ecx, [TASK_COUNT]
1434
	mov	ebx, SLOT_BASE+256
1435
.set:
1436
	cmp	[ebx+APPDATA.dir_table], edx
1437
	jnz	@f
1438
	mov	[ebx+APPDATA.dlls_list_ptr], eax
1439
@@:
1440
	add	ebx, 256
1441
	dec	ecx
1442
	jnz	.set
1443
.ret:
1444
	ret
1445
 
1289 diamond 1446
; in: eax = number of references to delete, esi -> DLLDESCR struc
1447
dereference_dll:
1448
	sub	[esi+DLLDESCR.refcount], eax
1449
	jnz	.ret
1450
	mov	eax, [esi+DLLDESCR.fd]
1451
	mov	edx, [esi+DLLDESCR.bk]
1452
	mov	[eax+DLLDESCR.bk], edx
1453
	mov	[edx+DLLDESCR.fd], eax
1292 diamond 1454
	stdcall	kernel_free, [esi+DLLDESCR.coff_hdr]
1289 diamond 1455
	stdcall	kernel_free, [esi+DLLDESCR.data]
1456
	mov	eax, esi
1457
	call	free
1458
.ret:
1459
	ret
1460
 
1461
destroy_hdll:
1311 diamond 1462
	push	ebx ecx esi edi
1289 diamond 1463
	push	eax
1464
	mov	ebx, [eax+HDLL.base]
1465
	mov	esi, [eax+HDLL.parent]
1466
	mov	edx, [esi+DLLDESCR.size]
1292 diamond 1467
; The following actions require the context of application where HDLL is mapped.
1468
; However, destroy_hdll can be called in the context of OS thread when
1469
; cleaning up objects created by the application which is destroyed.
1470
; So remember current cr3 and set it to page table of target.
1311 diamond 1471
	mov	eax, [ecx+APPDATA.dir_table]
1292 diamond 1472
; Because we cheat with cr3, disable interrupts: task switch would restore
1473
; page table from APPDATA of current thread.
1474
; Also set [current_slot] because it is used by user_free.
1475
	pushf
1476
	cli
1477
	push	[current_slot]
1311 diamond 1478
	mov	[current_slot], ecx
1479
	mov	ecx, cr3
1480
	push	ecx
1481
	mov	cr3, eax
1292 diamond 1482
	push	ebx	; argument for user_free
1289 diamond 1483
	mov	eax, ebx
1484
	shr	ebx, 12
1485
	push	ebx
1486
	mov	esi, [esi+DLLDESCR.data]
1487
	shr	esi, 12
1488
.unmap_loop:
1489
	push	eax
1490
	mov	eax, 2
1491
	xchg	eax, [page_tabs+ebx*4]
1292 diamond 1492
	mov	ecx, [page_tabs+esi*4]
1493
	and	eax, not 0xFFF
1494
	and	ecx, not 0xFFF
1495
	cmp	eax, ecx
1496
	jz	@f
1289 diamond 1497
	call	free_page
1498
@@:
1499
	pop	eax
1500
	invlpg	[eax]
1501
	add	eax, 0x1000
1502
	inc	ebx
1503
	inc	esi
1504
	sub	edx, 0x1000
1505
	ja	.unmap_loop
1292 diamond 1506
	pop	ebx
1289 diamond 1507
	and	dword [page_tabs+(ebx-1)*4], not DONT_FREE_BLOCK
1292 diamond 1508
	call	user_free
1509
; Restore context.
1510
	pop	eax
1511
	mov	cr3, eax
1512
	pop	[current_slot]
1513
	popf
1514
; Ok, cheating is done.
1515
	pop	eax
1516
	push	eax
1289 diamond 1517
	mov	esi, [eax+HDLL.parent]
1518
	mov	eax, [eax+HDLL.refcount]
1519
	call	dereference_dll
1520
	pop	eax
1311 diamond 1521
	mov	edx, [eax+HDLL.bk]
1522
	mov	ebx, [eax+HDLL.fd]
1523
	mov	[ebx+HDLL.bk], edx
1524
	mov	[edx+HDLL.fd], ebx
1525
	call	free
1526
	pop	edi esi ecx ebx
1289 diamond 1527
	ret
1528
 
1311 diamond 1529
; ecx -> APPDATA for slot, esi = dlls_list_ptr
1530
destroy_all_hdlls:
1531
	test	esi, esi
1532
	jz	.ret
1533
.loop:
1534
	mov	eax, [esi+HDLL.fd]
1535
	cmp	eax, esi
1536
	jz	free
1537
	call	destroy_hdll
1538
	jmp	.loop
1539
.ret:
1540
	ret
1541
 
214 serge 1542
align 4
1275 serge 1543
stop_all_services:
1544
       push ebp
672 hidnplayr 1545
	   mov edx, [srv.fd]
214 serge 1546
.next:
672 hidnplayr 1547
	   cmp edx,  srv.fd-SRV_FD_OFFSET
1548
	   je .done
1549
	   cmp [edx+SRV.magic], ' SRV'
1550
	   jne .next
1275 serge 1551
       cmp [edx+SRV.size], SRV.sizeof
672 hidnplayr 1552
	   jne .next
732 serge 1553
 
769 Rus 1554
	   mov ebx, [edx+SRV.entry]
672 hidnplayr 1555
	   mov edx, [edx+SRV.fd]
769 Rus 1556
	   test ebx, ebx
1557
	   jz .next
732 serge 1558
 
769 Rus 1559
	   push edx
1316 serge 1560
       mov ebp, esp
1561
       push  0
1562
       push -1
1563
       call ebx
1564
       mov esp, ebp
672 hidnplayr 1565
	   pop edx
1566
	   jmp .next
278 serge 1567
.done:
1275 serge 1568
       pop ebp
672 hidnplayr 1569
	   ret
198 serge 1570
 
281 serge 1571
; param
291 serge 1572
;  eax= size
1573
;  ebx= pid
214 serge 1574
 
281 serge 1575
align 4
1576
create_kernel_object:
1577
 
672 hidnplayr 1578
	   push ebx
1579
	   call malloc
1580
	   pop ebx
1581
	   test eax, eax
1582
	   jz .fail
281 serge 1583
 
672 hidnplayr 1584
	   mov ecx,[current_slot]
1585
	   add ecx, APP_OBJ_OFFSET
281 serge 1586
 
672 hidnplayr 1587
	   pushfd
1588
	   cli
1589
	   mov edx, [ecx+APPOBJ.fd]
1590
	   mov [eax+APPOBJ.fd], edx
1591
	   mov [eax+APPOBJ.bk], ecx
1592
	   mov [eax+APPOBJ.pid], ebx
281 serge 1593
 
672 hidnplayr 1594
	   mov [ecx+APPOBJ.fd], eax
1595
	   mov [edx+APPOBJ.bk], eax
1596
	   popfd
281 serge 1597
.fail:
672 hidnplayr 1598
	   ret
281 serge 1599
 
1600
; param
1601
;  eax= object
1602
 
1603
align 4
1604
destroy_kernel_object:
1605
 
672 hidnplayr 1606
	   pushfd
1607
	   cli
1608
	   mov ebx, [eax+APPOBJ.fd]
1609
	   mov ecx, [eax+APPOBJ.bk]
1610
	   mov [ebx+APPOBJ.bk], ecx
1611
	   mov [ecx+APPOBJ.fd], ebx
1612
	   popfd
281 serge 1613
 
672 hidnplayr 1614
	   xor edx, edx        ;clear common header
1615
	   mov [eax], edx
1616
	   mov [eax+4], edx
1617
	   mov [eax+8], edx
1618
	   mov [eax+12], edx
1619
	   mov [eax+16], edx
281 serge 1620
 
672 hidnplayr 1621
	   call free	       ;release object memory
1622
	   ret
281 serge 1623
 
1624
 
164 serge 1625
 
465 serge 1626
if 0
164 serge 1627
 
465 serge 1628
irq:
188 serge 1629
 
465 serge 1630
.irq0:
672 hidnplayr 1631
	   pusfd
1632
	   pushad
1633
	   push IRQ_0
1634
	   jmp .master
465 serge 1635
.irq_1:
672 hidnplayr 1636
	   pusfd
1637
	   pushad
1638
	   push IRQ_1
1639
	   jmp .master
465 serge 1640
 
1641
.master:
672 hidnplayr 1642
	   mov ax, app_data
1643
	   mov ds, eax
1644
	   mov es, eax
1645
	   mov ebx, [esp+4]  ;IRQ_xx
1646
	   mov eax, [irq_handlers+ebx+4]
1647
	   call intr_handler
1648
	   mov ecx, [esp+4]
1649
	   cmp [irq_actids+ecx*4], 0
1650
	   je @F
1651
	   in al, 0x21
1652
	   bts eax, ecx
1653
	   out 0x21, al
1654
	   mov al, 0x20
1655
	   out 0x20, al
1656
	   jmp .restart
465 serge 1657
 
1658
.slave:
672 hidnplayr 1659
	   mov ax, app_data
1660
	   mov ds, eax
1661
	   mov es, eax
1662
	   mov ebx, [esp+4]  ;IRQ_xx
1663
	   mov eax, [irq_handlers+ebx+4]
1664
	   call intr_handler
1665
	   mov ecx, [esp+4]
1666
	   sub ecx, 8
1667
	   cmp [irq_actids+ecx*4], 0
1668
	   je @F
1669
	   in al, 0xA1
1670
	   bts eax, ecx
1671
	   out 0xA1, al
1672
	   mov al, 0x20
1673
	   out 0xA0, al
1674
	   out 0x20, al
465 serge 1675
.restart:
672 hidnplayr 1676
	   mov ebx, [next_slot]
1677
	   test ebx, ebx
1678
	   jz @F
1679
	   mov [next_task],0
1680
	   mov esi, [prev_slot]
1681
	   call do_change_task
1682
	   add esp, 4
1683
	   iretd
465 serge 1684
 
1685
end if
1686