Subversion Repositories Kolibri OS

Rev

Rev 3520 | Rev 3786 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

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