Subversion Repositories Kolibri OS

Rev

Rev 6078 | Details | Compare with Previous | Last modification | View Log | RSS feed

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