Subversion Repositories Kolibri OS

Rev

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