Subversion Repositories Kolibri OS

Rev

Rev 3296 | Rev 3761 | 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: 3520 $
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
2288 clevermous 518
proc get_proc_ex stdcall, proc_name:dword, imports:dword
519
 
520
.look_up:
521
        mov     edx, [imports]
522
        test    edx, edx
523
        jz      .end
524
        mov     edx, [edx]
525
        test    edx, edx
526
        jz      .end
527
.next:
528
        mov     eax, [edx]
529
        test    eax, eax
530
        jz      .next_table
531
 
532
        push    edx
533
        stdcall strncmp, eax, [proc_name], 256
534
        pop     edx
535
        test    eax, eax
536
        jz      .ok
537
 
538
        add     edx, 8
539
        jmp     .next
540
.next_table:
541
        add     [imports], 4
542
        jmp     .look_up
543
.ok:
544
        mov     eax, [edx+4]
545
        ret
546
.end:
547
        xor     eax, eax
548
        ret
549
endp
550
 
551
align 4
552
proc fix_coff_symbols stdcall uses ebx esi, sec:dword, symbols:dword,\
553
                      sym_count:dword, strings:dword, imports:dword
554
           locals
555
             retval dd ?
556
           endl
557
 
558
        mov     edi, [symbols]
559
        mov     [retval], 1
560
.fix:
2384 hidnplayr 561
        movzx   ebx, [edi+COFF_SYM.SectionNumber]
2288 clevermous 562
        test    ebx, ebx
563
        jnz     .internal
2384 hidnplayr 564
        mov     eax, dword [edi+COFF_SYM.Name]
2288 clevermous 565
        test    eax, eax
566
        jnz     @F
567
 
568
        mov     edi, [edi+4]
569
        add     edi, [strings]
570
@@:
571
        push    edi
572
        stdcall get_proc_ex, edi, [imports]
573
        pop     edi
574
 
575
        xor     ebx, ebx
576
        test    eax, eax
577
        jnz     @F
578
 
579
        mov     esi, msg_unresolved
580
        call    sys_msg_board_str
581
        mov     esi, edi
582
        call    sys_msg_board_str
583
        mov     esi, msg_CR
584
        call    sys_msg_board_str
585
 
586
        mov     [retval], 0
587
@@:
588
        mov     edi, [symbols]
2384 hidnplayr 589
        mov     [edi+COFF_SYM.Value], eax
2288 clevermous 590
        jmp     .next
591
.internal:
592
        cmp     bx, -1
593
        je      .next
594
        cmp     bx, -2
595
        je      .next
596
 
597
        dec     ebx
598
        shl     ebx, 3
599
        lea     ebx, [ebx+ebx*4]
600
        add     ebx, [sec]
601
 
2384 hidnplayr 602
        mov     eax, [ebx+COFF_SECTION.VirtualAddress]
603
        add     [edi+COFF_SYM.Value], eax
2288 clevermous 604
.next:
2384 hidnplayr 605
        add     edi, sizeof.COFF_SYM
2288 clevermous 606
        mov     [symbols], edi
607
        dec     [sym_count]
608
        jnz     .fix
609
        mov     eax, [retval]
610
        ret
611
endp
612
 
613
align 4
614
proc fix_coff_relocs stdcall uses ebx esi, coff:dword, sym:dword, \
615
        delta:dword
616
           locals
617
             n_sec     dd ?
618
           endl
619
 
620
        mov     eax, [coff]
2384 hidnplayr 621
        movzx   ebx, [eax+COFF_HEADER.nSections]
2288 clevermous 622
        mov     [n_sec], ebx
623
        lea     esi, [eax+20]
624
.fix_sec:
2384 hidnplayr 625
        mov     edi, [esi+COFF_SECTION.PtrReloc]
2288 clevermous 626
        add     edi, [coff]
627
 
2384 hidnplayr 628
        movzx   ecx, [esi+COFF_SECTION.NumReloc]
2288 clevermous 629
        test    ecx, ecx
630
        jz      .next
631
.reloc_loop:
2384 hidnplayr 632
        mov     ebx, [edi+COFF_RELOC.SymIndex]
2288 clevermous 633
        add     ebx, ebx
634
        lea     ebx, [ebx+ebx*8]
635
        add     ebx, [sym]
636
 
2384 hidnplayr 637
        mov     edx, [ebx+COFF_SYM.Value]
2288 clevermous 638
 
2384 hidnplayr 639
        cmp     [edi+COFF_RELOC.Type], 6
2288 clevermous 640
        je      .dir_32
641
 
2384 hidnplayr 642
        cmp     [edi+COFF_RELOC.Type], 20
2288 clevermous 643
        jne     .next_reloc
644
.rel_32:
2384 hidnplayr 645
        mov     eax, [edi+COFF_RELOC.VirtualAddress]
646
        add     eax, [esi+COFF_SECTION.VirtualAddress]
2288 clevermous 647
        sub     edx, eax
648
        sub     edx, 4
649
        jmp     .fix
650
.dir_32:
2384 hidnplayr 651
        mov     eax, [edi+COFF_RELOC.VirtualAddress]
652
        add     eax, [esi+COFF_SECTION.VirtualAddress]
2288 clevermous 653
.fix:
654
        add     eax, [delta]
655
        add     [eax], edx
656
.next_reloc:
657
        add     edi, 10
658
        dec     ecx
659
        jnz     .reloc_loop
660
.next:
2384 hidnplayr 661
        add     esi, sizeof.COFF_SECTION
2288 clevermous 662
        dec     [n_sec]
663
        jnz     .fix_sec
664
.exit:
665
        ret
666
endp
667
 
668
align 4
669
proc rebase_coff stdcall uses ebx esi, coff:dword, sym:dword, \
670
        delta:dword
671
           locals
672
             n_sec     dd ?
673
           endl
674
 
675
        mov     eax, [coff]
2384 hidnplayr 676
        movzx   ebx, [eax+COFF_HEADER.nSections]
2288 clevermous 677
        mov     [n_sec], ebx
678
        lea     esi, [eax+20]
679
        mov     edx, [delta]
680
.fix_sec:
2384 hidnplayr 681
        mov     edi, [esi+COFF_SECTION.PtrReloc]
2288 clevermous 682
        add     edi, [coff]
683
 
2384 hidnplayr 684
        movzx   ecx, [esi+COFF_SECTION.NumReloc]
2288 clevermous 685
        test    ecx, ecx
686
        jz      .next
687
.reloc_loop:
2384 hidnplayr 688
        cmp     [edi+COFF_RELOC.Type], 6
2288 clevermous 689
        jne     .next_reloc
690
.dir_32:
2384 hidnplayr 691
        mov     eax, [edi+COFF_RELOC.VirtualAddress]
692
        add     eax, [esi+COFF_SECTION.VirtualAddress]
2288 clevermous 693
        add     [eax+edx], edx
694
.next_reloc:
695
        add     edi, 10
696
        dec     ecx
697
        jnz     .reloc_loop
698
.next:
2384 hidnplayr 699
        add     esi, sizeof.COFF_SECTION
2288 clevermous 700
        dec     [n_sec]
701
        jnz     .fix_sec
702
.exit:
703
        ret
704
endp
705
 
706
align 4
707
proc load_driver stdcall, driver_name:dword
708
           locals
709
             coff      dd ?
710
             sym       dd ?
711
             strings   dd ?
712
             img_size  dd ?
713
             img_base  dd ?
714
             start     dd ?
715
 
716
             exports   dd ?   ;fake exports table
717
                       dd ?
718
             file_name rb 13+16+4+1      ; '/sys/drivers/.obj'
719
           endl
720
 
721
        lea     edx, [file_name]
722
        mov     dword [edx], '/sys'
723
        mov     dword [edx+4], '/dri'
724
        mov     dword [edx+8], 'vers'
725
        mov     byte [edx+12], '/'
726
        mov     esi, [driver_name]
727
.redo:
728
        lea     edx, [file_name]
729
        lea     edi, [edx+13]
730
        mov     ecx, 16
731
@@:
732
        lodsb
733
        test    al, al
734
        jz      @f
735
        stosb
736
        loop    @b
737
@@:
738
        mov     dword [edi], '.obj'
739
        mov     byte [edi+4], 0
740
        stdcall load_file, edx
741
 
742
        test    eax, eax
743
        jz      .exit
744
 
745
        mov     [coff], eax
746
 
2384 hidnplayr 747
        movzx   ecx, [eax+COFF_HEADER.nSections]
2288 clevermous 748
        xor     ebx, ebx
749
 
750
        lea     edx, [eax+20]
751
@@:
2384 hidnplayr 752
        add     ebx, [edx+COFF_SECTION.SizeOfRawData]
2288 clevermous 753
        add     ebx, 15
754
        and     ebx, not 15
2384 hidnplayr 755
        add     edx, sizeof.COFF_SECTION
2288 clevermous 756
        dec     ecx
757
        jnz     @B
758
        mov     [img_size], ebx
759
 
760
        stdcall kernel_alloc, ebx
761
        test    eax, eax
762
        jz      .fail
763
        mov     [img_base], eax
764
 
765
        mov     edi, eax
766
        xor     eax, eax
767
        mov     ecx, [img_size]
768
        add     ecx, 4095
769
        and     ecx, not 4095
770
        shr     ecx, 2
771
        cld
772
        rep stosd
773
 
774
        mov     edx, [coff]
2384 hidnplayr 775
        movzx   ebx, [edx+COFF_HEADER.nSections]
2288 clevermous 776
        mov     edi, [img_base]
777
        lea     eax, [edx+20]
778
@@:
2384 hidnplayr 779
        mov     [eax+COFF_SECTION.VirtualAddress], edi
780
        mov     esi, [eax+COFF_SECTION.PtrRawData]
2288 clevermous 781
        test    esi, esi
782
        jnz     .copy
2384 hidnplayr 783
        add     edi, [eax+COFF_SECTION.SizeOfRawData]
2288 clevermous 784
        jmp     .next
785
.copy:
786
        add     esi, edx
2384 hidnplayr 787
        mov     ecx, [eax+COFF_SECTION.SizeOfRawData]
2288 clevermous 788
        cld
789
        rep movsb
790
.next:
791
        add     edi, 15
792
        and     edi, not 15
2384 hidnplayr 793
        add     eax, sizeof.COFF_SECTION
2288 clevermous 794
        dec     ebx
795
        jnz     @B
796
 
2384 hidnplayr 797
        mov     ebx, [edx+COFF_HEADER.pSymTable]
2288 clevermous 798
        add     ebx, edx
799
        mov     [sym], ebx
2384 hidnplayr 800
        mov     ecx, [edx+COFF_HEADER.nSymbols]
2288 clevermous 801
        add     ecx, ecx
802
        lea     ecx, [ecx+ecx*8];ecx*=18 = nSymbols*CSYM_SIZE
803
        add     ecx, [sym]
804
        mov     [strings], ecx
805
 
806
        lea     ebx, [exports]
807
        mov     dword [ebx], kernel_export
808
        mov     dword [ebx+4], 0
809
        lea     eax, [edx+20]
810
 
2384 hidnplayr 811
        stdcall fix_coff_symbols, eax, [sym], [edx+COFF_HEADER.nSymbols], \
2288 clevermous 812
                [strings], ebx
813
        test    eax, eax
814
        jz      .link_fail
815
 
816
        mov     ebx, [coff]
817
        stdcall fix_coff_relocs, ebx, [sym], 0
818
 
2384 hidnplayr 819
        stdcall get_coff_sym, [sym], [ebx+COFF_HEADER.nSymbols], szVersion
2288 clevermous 820
        test    eax, eax
821
        jz      .link_fail
822
 
823
        mov     eax, [eax]
824
        shr     eax, 16
825
        cmp     eax, DRV_COMPAT
826
        jb      .ver_fail
827
 
828
        cmp     eax, DRV_CURRENT
829
        ja      .ver_fail
830
 
831
        mov     ebx, [coff]
2384 hidnplayr 832
        stdcall get_coff_sym, [sym], [ebx+COFF_HEADER.nSymbols], szSTART
2288 clevermous 833
        mov     [start], eax
834
 
835
        stdcall kernel_free, [coff]
836
 
837
        mov     ebx, [start]
838
        stdcall ebx, DRV_ENTRY
839
        test    eax, eax
840
        jnz     .ok
841
 
842
        stdcall kernel_free, [img_base]
3171 hidnplayr 843
 
2288 clevermous 844
        xor     eax, eax
845
        ret
846
.ok:
847
        mov     ebx, [img_base]
848
        mov     [eax+SRV.base], ebx
849
        mov     ecx, [start]
850
        mov     [eax+SRV.entry], ecx
851
        ret
852
 
853
.ver_fail:
854
        mov     esi, msg_CR
855
        call    sys_msg_board_str
856
        mov     esi, [driver_name]
857
        call    sys_msg_board_str
858
        mov     esi, msg_CR
859
        call    sys_msg_board_str
860
        mov     esi, msg_version
861
        call    sys_msg_board_str
862
        mov     esi, msg_www
863
        call    sys_msg_board_str
864
        jmp     .cleanup
865
 
866
.link_fail:
867
        mov     esi, msg_module
868
        call    sys_msg_board_str
869
        mov     esi, [driver_name]
870
        call    sys_msg_board_str
871
        mov     esi, msg_CR
872
        call    sys_msg_board_str
873
.cleanup:
874
        stdcall kernel_free, [img_base]
875
.fail:
876
        stdcall kernel_free, [coff]
877
.exit:
878
        xor     eax, eax
879
        ret
880
endp
881
 
882
; in: edx -> COFF_SECTION struct
883
; out: eax = alignment as mask for bits to drop
884
coff_get_align:
885
; Rules:
886
; - if alignment is not given, use default = 4K;
887
; - if alignment is given and is no more than 4K, use it;
888
; - if alignment is more than 4K, revert to 4K.
889
        push    ecx
2384 hidnplayr 890
        mov     cl, byte [edx+COFF_SECTION.Characteristics+2]
2288 clevermous 891
        mov     eax, 1
892
        shr     cl, 4
893
        dec     cl
894
        js      .default
895
        cmp     cl, 12
896
        jbe     @f
897
.default:
898
        mov     cl, 12
899
@@:
900
        shl     eax, cl
901
        pop     ecx
902
        dec     eax
903
        ret
904
 
905
align 4
906
proc load_library stdcall, file_name:dword
907
           locals
908
             fullname  rb 260
909
             fileinfo  rb 40
910
             coff      dd ?
911
             img_base  dd ?
912
           endl
913
 
914
        cli
915
 
916
; resolve file name
917
        mov     ebx, [file_name]
918
        lea     edi, [fullname+1]
919
        mov     byte [edi-1], '/'
920
        stdcall get_full_file_name, edi, 259
921
        test    al, al
922
        jz      .fail
923
 
924
; scan for required DLL in list of already loaded for this process,
925
; ignore timestamp
926
        mov     esi, [CURRENT_TASK]
927
        shl     esi, 8
928
        lea     edi, [fullname]
929
        mov     ebx, [esi+SLOT_BASE+APPDATA.dlls_list_ptr]
930
        test    ebx, ebx
931
        jz      .not_in_process
932
        mov     esi, [ebx+HDLL.fd]
933
.scan_in_process:
934
        cmp     esi, ebx
935
        jz      .not_in_process
936
        mov     eax, [esi+HDLL.parent]
937
        add     eax, DLLDESCR.name
938
        stdcall strncmp, eax, edi, -1
939
        test    eax, eax
940
        jnz     .next_in_process
941
; simple variant: load DLL which is already loaded in this process
942
; just increment reference counters and return address of exports table
943
        inc     [esi+HDLL.refcount]
944
        mov     ecx, [esi+HDLL.parent]
945
        inc     [ecx+DLLDESCR.refcount]
946
        mov     eax, [ecx+DLLDESCR.exports]
947
        sub     eax, [ecx+DLLDESCR.defaultbase]
948
        add     eax, [esi+HDLL.base]
949
        ret
950
.next_in_process:
951
        mov     esi, [esi+HDLL.fd]
952
        jmp     .scan_in_process
953
.not_in_process:
954
 
955
; scan in full list, compare timestamp
956
        lea     eax, [fileinfo]
957
        stdcall get_fileinfo, edi, eax
958
        test    eax, eax
959
        jnz     .fail
960
        mov     esi, [dll_list.fd]
961
.scan_for_dlls:
962
        cmp     esi, dll_list
963
        jz      .load_new
964
        lea     eax, [esi+DLLDESCR.name]
965
        stdcall strncmp, eax, edi, -1
966
        test    eax, eax
967
        jnz     .continue_scan
968
.test_prev_dll:
969
        mov     eax, dword [fileinfo+24]; last modified time
970
        mov     edx, dword [fileinfo+28]; last modified date
971
        cmp     dword [esi+DLLDESCR.timestamp], eax
972
        jnz     .continue_scan
973
        cmp     dword [esi+DLLDESCR.timestamp+4], edx
974
        jz      .dll_already_loaded
975
.continue_scan:
976
        mov     esi, [esi+DLLDESCR.fd]
977
        jmp     .scan_for_dlls
978
 
979
; new DLL
980
.load_new:
981
; load file
982
        stdcall load_file, edi
983
        test    eax, eax
984
        jz      .fail
985
        mov     [coff], eax
986
        mov     dword [fileinfo+32], ebx
987
 
988
; allocate DLLDESCR struct; size is DLLDESCR.sizeof plus size of DLL name
989
        mov     esi, edi
990
        mov     ecx, -1
991
        xor     eax, eax
992
        repnz scasb
993
        not     ecx
2384 hidnplayr 994
        lea     eax, [ecx+sizeof.DLLDESCR]
2288 clevermous 995
        push    ecx
996
        call    malloc
997
        pop     ecx
998
        test    eax, eax
999
        jz      .fail_and_free_coff
1000
; save timestamp
1001
        lea     edi, [eax+DLLDESCR.name]
1002
        rep movsb
1003
        mov     esi, eax
1004
        mov     eax, dword [fileinfo+24]
1005
        mov     dword [esi+DLLDESCR.timestamp], eax
1006
        mov     eax, dword [fileinfo+28]
1007
        mov     dword [esi+DLLDESCR.timestamp+4], eax
1008
; initialize DLLDESCR struct
1009
        and     dword [esi+DLLDESCR.refcount], 0; no HDLLs yet; later it will be incremented
1010
        mov     [esi+DLLDESCR.fd], dll_list
1011
        mov     eax, [dll_list.bk]
1012
        mov     [dll_list.bk], esi
1013
        mov     [esi+DLLDESCR.bk], eax
1014
        mov     [eax+DLLDESCR.fd], esi
1015
 
1016
; calculate size of loaded DLL
1017
        mov     edx, [coff]
2384 hidnplayr 1018
        movzx   ecx, [edx+COFF_HEADER.nSections]
2288 clevermous 1019
        xor     ebx, ebx
1020
 
1021
        add     edx, 20
1022
@@:
1023
        call    coff_get_align
1024
        add     ebx, eax
1025
        not     eax
1026
        and     ebx, eax
2384 hidnplayr 1027
        add     ebx, [edx+COFF_SECTION.SizeOfRawData]
1028
        add     edx, sizeof.COFF_SECTION
2288 clevermous 1029
        dec     ecx
1030
        jnz     @B
1031
; it must be nonzero and not too big
1032
        mov     [esi+DLLDESCR.size], ebx
1033
        test    ebx, ebx
1034
        jz      .fail_and_free_dll
1035
        cmp     ebx, MAX_DEFAULT_DLL_ADDR-MIN_DEFAULT_DLL_ADDR
1036
        ja      .fail_and_free_dll
1037
; allocate memory for kernel-side image
1038
        stdcall kernel_alloc, ebx
1039
        test    eax, eax
1040
        jz      .fail_and_free_dll
1041
        mov     [esi+DLLDESCR.data], eax
1042
; calculate preferred base address
1043
        add     ebx, 0x1FFF
1044
        and     ebx, not 0xFFF
1045
        mov     ecx, [dll_cur_addr]
1046
        lea     edx, [ecx+ebx]
1047
        cmp     edx, MAX_DEFAULT_DLL_ADDR
1048
        jb      @f
1049
        mov     ecx, MIN_DEFAULT_DLL_ADDR
1050
        lea     edx, [ecx+ebx]
1051
@@:
1052
        mov     [esi+DLLDESCR.defaultbase], ecx
1053
        mov     [dll_cur_addr], edx
1054
 
1055
; copy sections and set correct values for VirtualAddress'es in headers
1056
        push    esi
1057
        mov     edx, [coff]
2384 hidnplayr 1058
        movzx   ebx, [edx+COFF_HEADER.nSections]
2288 clevermous 1059
        mov     edi, eax
1060
        add     edx, 20
1061
        cld
1062
@@:
1063
        call    coff_get_align
1064
        add     ecx, eax
1065
        add     edi, eax
1066
        not     eax
1067
        and     ecx, eax
1068
        and     edi, eax
2384 hidnplayr 1069
        mov     [edx+COFF_SECTION.VirtualAddress], ecx
1070
        add     ecx, [edx+COFF_SECTION.SizeOfRawData]
1071
        mov     esi, [edx+COFF_SECTION.PtrRawData]
2288 clevermous 1072
        push    ecx
2384 hidnplayr 1073
        mov     ecx, [edx+COFF_SECTION.SizeOfRawData]
2288 clevermous 1074
        test    esi, esi
1075
        jnz     .copy
1076
        xor     eax, eax
1077
        rep stosb
1078
        jmp     .next
1079
.copy:
1080
        add     esi, [coff]
1081
        rep movsb
1082
.next:
1083
        pop     ecx
2384 hidnplayr 1084
        add     edx, sizeof.COFF_SECTION
2288 clevermous 1085
        dec     ebx
1086
        jnz     @B
1087
        pop     esi
1088
 
1089
; save some additional data from COFF file
1090
; later we will use COFF header, headers for sections and symbol table
1091
; and also relocations table for all sections
1092
        mov     edx, [coff]
2384 hidnplayr 1093
        mov     ebx, [edx+COFF_HEADER.pSymTable]
2288 clevermous 1094
        mov     edi, dword [fileinfo+32]
1095
        sub     edi, ebx
1096
        jc      .fail_and_free_data
1097
        mov     [esi+DLLDESCR.symbols_lim], edi
1098
        add     ebx, edx
2384 hidnplayr 1099
        movzx   ecx, [edx+COFF_HEADER.nSections]
2288 clevermous 1100
        lea     ecx, [ecx*5]
1101
        lea     edi, [edi+ecx*8+20]
1102
        add     edx, 20
1103
@@:
2384 hidnplayr 1104
        movzx   eax, [edx+COFF_SECTION.NumReloc]
2288 clevermous 1105
        lea     eax, [eax*5]
1106
        lea     edi, [edi+eax*2]
2384 hidnplayr 1107
        add     edx, sizeof.COFF_SECTION
2288 clevermous 1108
        sub     ecx, 5
1109
        jnz     @b
1110
        stdcall kernel_alloc, edi
1111
        test    eax, eax
1112
        jz      .fail_and_free_data
1113
        mov     edx, [coff]
2384 hidnplayr 1114
        movzx   ecx, [edx+COFF_HEADER.nSections]
2288 clevermous 1115
        lea     ecx, [ecx*5]
1116
        lea     ecx, [ecx*2+5]
1117
        mov     [esi+DLLDESCR.coff_hdr], eax
1118
        push    esi
1119
        mov     esi, edx
1120
        mov     edi, eax
1121
        rep movsd
1122
        pop     esi
1123
        mov     [esi+DLLDESCR.symbols_ptr], edi
1124
        push    esi
2384 hidnplayr 1125
        mov     ecx, [edx+COFF_HEADER.nSymbols]
2288 clevermous 1126
        mov     [esi+DLLDESCR.symbols_num], ecx
1127
        mov     ecx, [esi+DLLDESCR.symbols_lim]
1128
        mov     esi, ebx
1129
        rep movsb
1130
        pop     esi
1131
        mov     ebx, [esi+DLLDESCR.coff_hdr]
1132
        push    esi
2384 hidnplayr 1133
        movzx   eax, [edx+COFF_HEADER.nSections]
2288 clevermous 1134
        lea     edx, [ebx+20]
1135
@@:
2384 hidnplayr 1136
        movzx   ecx, [edx+COFF_SECTION.NumReloc]
2288 clevermous 1137
        lea     ecx, [ecx*5]
2384 hidnplayr 1138
        mov     esi, [edx+COFF_SECTION.PtrReloc]
1139
        mov     [edx+COFF_SECTION.PtrReloc], edi
1140
        sub     [edx+COFF_SECTION.PtrReloc], ebx
2288 clevermous 1141
        add     esi, [coff]
1142
        shr     ecx, 1
1143
        rep movsd
1144
        adc     ecx, ecx
1145
        rep movsw
2384 hidnplayr 1146
        add     edx, sizeof.COFF_SECTION
2288 clevermous 1147
        dec     eax
1148
        jnz     @b
1149
        pop     esi
1150
 
1151
; fixup symbols
1152
        mov     edx, ebx
2384 hidnplayr 1153
        mov     eax, [ebx+COFF_HEADER.nSymbols]
2288 clevermous 1154
        add     edx, 20
1155
        mov     ecx, [esi+DLLDESCR.symbols_num]
1156
        lea     ecx, [ecx*9]
1157
        add     ecx, ecx
1158
        add     ecx, [esi+DLLDESCR.symbols_ptr]
1159
 
1160
        stdcall fix_coff_symbols, edx, [esi+DLLDESCR.symbols_ptr], eax, \
1161
                ecx, 0
1162
;          test eax, eax
1163
;          jnz @F
1164
;
1165
;@@:
1166
 
2384 hidnplayr 1167
        stdcall get_coff_sym, [esi+DLLDESCR.symbols_ptr], [ebx+COFF_HEADER.nSymbols], szEXPORTS
2288 clevermous 1168
        test    eax, eax
1169
        jnz     @F
1170
 
2384 hidnplayr 1171
        stdcall get_coff_sym, [esi+DLLDESCR.symbols_ptr], [ebx+COFF_HEADER.nSymbols], sz_EXPORTS
2288 clevermous 1172
@@:
1173
        mov     [esi+DLLDESCR.exports], eax
1174
 
1175
; fix relocs in the hidden copy in kernel memory to default address
1176
; it is first fix; usually this will be enough, but second fix
1177
; can be necessary if real load address will not equal assumption
1178
        mov     eax, [esi+DLLDESCR.data]
1179
        sub     eax, [esi+DLLDESCR.defaultbase]
1180
        stdcall fix_coff_relocs, ebx, [esi+DLLDESCR.symbols_ptr], eax
1181
 
1182
        stdcall kernel_free, [coff]
1183
 
1184
.dll_already_loaded:
1185
        inc     [esi+DLLDESCR.refcount]
1186
        push    esi
1187
        call    init_heap
1188
        pop     esi
1189
 
1190
        mov     edi, [esi+DLLDESCR.size]
1191
        stdcall user_alloc_at, [esi+DLLDESCR.defaultbase], edi
1192
        test    eax, eax
1193
        jnz     @f
1194
        stdcall user_alloc, edi
1195
        test    eax, eax
1196
        jz      .fail_and_dereference
1197
@@:
1198
        mov     [img_base], eax
2384 hidnplayr 1199
        mov     eax, sizeof.HDLL
2288 clevermous 1200
        call    malloc
1201
        test    eax, eax
1202
        jz      .fail_and_free_user
1203
        mov     ebx, [CURRENT_TASK]
1204
        shl     ebx, 5
1205
        mov     edx, [CURRENT_TASK+ebx+TASKDATA.pid]
1206
        mov     [eax+HDLL.pid], edx
1207
        push    eax
1208
        call    init_dlls_in_thread
1209
        pop     ebx
1210
        test    eax, eax
1211
        jz      .fail_and_free_user
1212
        mov     edx, [eax+HDLL.fd]
1213
        mov     [ebx+HDLL.fd], edx
1214
        mov     [ebx+HDLL.bk], eax
1215
        mov     [eax+HDLL.fd], ebx
1216
        mov     [edx+HDLL.bk], ebx
1217
        mov     eax, ebx
1218
        mov     ebx, [img_base]
1219
        mov     [eax+HDLL.base], ebx
1220
        mov     [eax+HDLL.size], edi
1221
        mov     [eax+HDLL.refcount], 1
1222
        mov     [eax+HDLL.parent], esi
1223
        mov     edx, ebx
1224
        shr     edx, 12
1225
        or      dword [page_tabs+(edx-1)*4], DONT_FREE_BLOCK
1226
; copy entries of page table from kernel-side image to usermode
1227
; use copy-on-write for user-mode image, so map as readonly
1228
        xor     edi, edi
1229
        mov     ecx, [esi+DLLDESCR.data]
1230
        shr     ecx, 12
1231
.map_pages_loop:
1232
        mov     eax, [page_tabs+ecx*4]
1233
        and     eax, not 0xFFF
1234
        or      al, PG_USER
1235
        xchg    eax, [page_tabs+edx*4]
1236
        test    al, 1
1237
        jz      @f
1238
        call    free_page
1239
@@:
1240
        invlpg  [ebx+edi]
1241
        inc     ecx
1242
        inc     edx
1243
        add     edi, 0x1000
1244
        cmp     edi, [esi+DLLDESCR.size]
1245
        jb      .map_pages_loop
1246
 
1247
; if real user-mode base is not equal to preferred base, relocate image
1248
        sub     ebx, [esi+DLLDESCR.defaultbase]
1249
        jz      @f
1250
        stdcall rebase_coff, [esi+DLLDESCR.coff_hdr], [esi+DLLDESCR.symbols_ptr], ebx
1251
@@:
1252
 
1253
        mov     eax, [esi+DLLDESCR.exports]
1254
        sub     eax, [esi+DLLDESCR.defaultbase]
1255
        add     eax, [img_base]
1256
        ret
1257
.fail_and_free_data:
1258
        stdcall kernel_free, [esi+DLLDESCR.data]
1259
.fail_and_free_dll:
1260
        mov     eax, esi
1261
        call    free
1262
.fail_and_free_coff:
1263
        stdcall kernel_free, [coff]
1264
.fail:
1265
        xor     eax, eax
1266
        ret
1267
.fail_and_free_user:
1268
        stdcall user_free, [img_base]
1269
.fail_and_dereference:
1270
        mov     eax, 1  ; delete 1 reference
1271
        call    dereference_dll
1272
        xor     eax, eax
1273
        ret
1274
endp
1275
 
1276
; initialize [APPDATA.dlls_list_ptr] for given thread
1277
; DLL is per-process object, so APPDATA.dlls_list_ptr must be
1278
; kept in sync for all threads of one process.
1279
; out: eax = APPDATA.dlls_list_ptr if all is OK,
1280
; NULL if memory allocation failed
1281
init_dlls_in_thread:
1282
        mov     ebx, [current_slot]
1283
        mov     eax, [ebx+APPDATA.dlls_list_ptr]
1284
        test    eax, eax
1285
        jnz     .ret
1286
        push    [ebx+APPDATA.dir_table]
1287
        mov     eax, 8
1288
        call    malloc
1289
        pop     edx
1290
        test    eax, eax
1291
        jz      .ret
1292
        mov     [eax], eax
1293
        mov     [eax+4], eax
1294
        mov     ecx, [TASK_COUNT]
1295
        mov     ebx, SLOT_BASE+256
1296
.set:
1297
        cmp     [ebx+APPDATA.dir_table], edx
1298
        jnz     @f
1299
        mov     [ebx+APPDATA.dlls_list_ptr], eax
1300
@@:
1301
        add     ebx, 256
1302
        dec     ecx
1303
        jnz     .set
1304
.ret:
1305
        ret
1306
 
1307
; in: eax = number of references to delete, esi -> DLLDESCR struc
1308
dereference_dll:
1309
        sub     [esi+DLLDESCR.refcount], eax
1310
        jnz     .ret
1311
        mov     eax, [esi+DLLDESCR.fd]
1312
        mov     edx, [esi+DLLDESCR.bk]
1313
        mov     [eax+DLLDESCR.bk], edx
1314
        mov     [edx+DLLDESCR.fd], eax
1315
        stdcall kernel_free, [esi+DLLDESCR.coff_hdr]
1316
        stdcall kernel_free, [esi+DLLDESCR.data]
1317
        mov     eax, esi
1318
        call    free
1319
.ret:
1320
        ret
1321
 
1322
destroy_hdll:
1323
        push    ebx ecx esi edi
1324
        push    eax
1325
        mov     ebx, [eax+HDLL.base]
1326
        mov     esi, [eax+HDLL.parent]
1327
        mov     edx, [esi+DLLDESCR.size]
1328
; The following actions require the context of application where HDLL is mapped.
1329
; However, destroy_hdll can be called in the context of OS thread when
1330
; cleaning up objects created by the application which is destroyed.
1331
; So remember current cr3 and set it to page table of target.
1332
        mov     eax, [ecx+APPDATA.dir_table]
1333
; Because we cheat with cr3, disable interrupts: task switch would restore
1334
; page table from APPDATA of current thread.
1335
; Also set [current_slot] because it is used by user_free.
1336
        pushf
1337
        cli
1338
        push    [current_slot]
1339
        mov     [current_slot], ecx
1340
        mov     ecx, cr3
1341
        push    ecx
1342
        mov     cr3, eax
1343
        push    ebx     ; argument for user_free
1344
        mov     eax, ebx
1345
        shr     ebx, 12
1346
        push    ebx
1347
        mov     esi, [esi+DLLDESCR.data]
1348
        shr     esi, 12
1349
.unmap_loop:
1350
        push    eax
1351
        mov     eax, 2
1352
        xchg    eax, [page_tabs+ebx*4]
1353
        mov     ecx, [page_tabs+esi*4]
1354
        and     eax, not 0xFFF
1355
        and     ecx, not 0xFFF
1356
        cmp     eax, ecx
1357
        jz      @f
1358
        call    free_page
1359
@@:
1360
        pop     eax
1361
        invlpg  [eax]
1362
        add     eax, 0x1000
1363
        inc     ebx
1364
        inc     esi
1365
        sub     edx, 0x1000
1366
        ja      .unmap_loop
1367
        pop     ebx
1368
        and     dword [page_tabs+(ebx-1)*4], not DONT_FREE_BLOCK
1369
        call    user_free
1370
; Restore context.
1371
        pop     eax
1372
        mov     cr3, eax
1373
        pop     [current_slot]
1374
        popf
1375
; Ok, cheating is done.
1376
        pop     eax
1377
        push    eax
1378
        mov     esi, [eax+HDLL.parent]
1379
        mov     eax, [eax+HDLL.refcount]
1380
        call    dereference_dll
1381
        pop     eax
1382
        mov     edx, [eax+HDLL.bk]
1383
        mov     ebx, [eax+HDLL.fd]
1384
        mov     [ebx+HDLL.bk], edx
1385
        mov     [edx+HDLL.fd], ebx
1386
        call    free
1387
        pop     edi esi ecx ebx
1388
        ret
1389
 
1390
; ecx -> APPDATA for slot, esi = dlls_list_ptr
1391
destroy_all_hdlls:
1392
        test    esi, esi
1393
        jz      .ret
1394
.loop:
1395
        mov     eax, [esi+HDLL.fd]
1396
        cmp     eax, esi
1397
        jz      free
1398
        call    destroy_hdll
1399
        jmp     .loop
1400
.ret:
1401
        ret
1402
 
1403
align 4
1404
stop_all_services:
1405
        push    ebp
1406
        mov     edx, [srv.fd]
1407
.next:
2384 hidnplayr 1408
        cmp     edx, srv.fd-SRV.fd
2288 clevermous 1409
        je      .done
1410
        cmp     [edx+SRV.magic], ' SRV'
1411
        jne     .next
2384 hidnplayr 1412
        cmp     [edx+SRV.size], sizeof.SRV
2288 clevermous 1413
        jne     .next
1414
 
1415
        mov     ebx, [edx+SRV.entry]
1416
        mov     edx, [edx+SRV.fd]
1417
        test    ebx, ebx
1418
        jz      .next
1419
 
1420
        push    edx
1421
        mov     ebp, esp
1422
        push    0
1423
        push    -1
1424
        call    ebx
1425
        mov     esp, ebp
1426
        pop     edx
1427
        jmp     .next
1428
.done:
1429
        pop     ebp
1430
        ret
1431
 
1432
; param
1433
;  eax= size
1434
;  ebx= pid
1435
 
1436
align 4
1437
create_kernel_object:
1438
 
1439
        push    ebx
1440
        call    malloc
1441
        pop     ebx
1442
        test    eax, eax
1443
        jz      .fail
1444
 
1445
        mov     ecx, [current_slot]
1446
        add     ecx, APP_OBJ_OFFSET
1447
 
1448
        pushfd
1449
        cli
1450
        mov     edx, [ecx+APPOBJ.fd]
1451
        mov     [eax+APPOBJ.fd], edx
1452
        mov     [eax+APPOBJ.bk], ecx
1453
        mov     [eax+APPOBJ.pid], ebx
1454
 
1455
        mov     [ecx+APPOBJ.fd], eax
1456
        mov     [edx+APPOBJ.bk], eax
1457
        popfd
1458
.fail:
1459
        ret
1460
 
1461
; param
1462
;  eax= object
1463
 
1464
align 4
1465
destroy_kernel_object:
1466
 
1467
        pushfd
1468
        cli
1469
        mov     ebx, [eax+APPOBJ.fd]
1470
        mov     ecx, [eax+APPOBJ.bk]
1471
        mov     [ebx+APPOBJ.bk], ecx
1472
        mov     [ecx+APPOBJ.fd], ebx
1473
        popfd
1474
 
1475
        xor     edx, edx       ;clear common header
1476
        mov     [eax], edx
1477
        mov     [eax+4], edx
1478
        mov     [eax+8], edx
1479
        mov     [eax+12], edx
1480
        mov     [eax+16], edx
1481
 
1482
        call    free           ;release object memory
1483
        ret