Subversion Repositories Kolibri OS

Rev

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