Subversion Repositories Kolibri OS

Rev

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