Subversion Repositories Kolibri OS

Rev

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