Subversion Repositories Kolibri OS

Rev

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