Subversion Repositories Kolibri OS

Rev

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

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