Subversion Repositories Kolibri OS

Rev

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

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