Subversion Repositories Kolibri OS

Rev

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