Subversion Repositories Kolibri OS

Rev

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