Subversion Repositories Kolibri OS

Rev

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