Subversion Repositories Kolibri OS

Rev

Rev 2434 | Rev 2987 | 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: 2465 $
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
440
        pushfd
441
        cli
442
        stdcall unpack, [file], eax
443
        popfd
444
        stdcall kernel_free, [file]
445
        mov     eax, [file2]
446
        mov     ebx, [file_size]
211 serge 447
.exit:
2434 Serge 448
        push    eax
449
        lea     edi, [eax+ebx]    ;cleanup remain space
450
        mov     ecx, 4096         ;from file end
451
        and     ebx, 4095
452
        jz      @f
453
        sub     ecx, ebx
454
        xor     eax, eax
455
        cld
456
        rep stosb
521 diamond 457
@@:
2434 Serge 458
        mov     ebx, [file_size]
459
        pop     eax
460
        pop     edi
461
        pop     esi
462
        ret
188 serge 463
.cleanup:
2434 Serge 464
        stdcall kernel_free, [file]
188 serge 465
.fail:
2434 Serge 466
        xor     eax, eax
467
        xor     ebx, ebx
468
        pop     edi
469
        pop     esi
470
        ret
188 serge 471
endp
164 serge 472
 
188 serge 473
align 4
474
proc get_proc_ex stdcall, proc_name:dword, imports:dword
475
 
476
.look_up:
2434 Serge 477
        mov     edx, [imports]
478
        test    edx, edx
479
        jz      .end
480
        mov     edx, [edx]
481
        test    edx, edx
482
        jz      .end
188 serge 483
.next:
2434 Serge 484
        mov     eax, [edx]
485
        test    eax, eax
486
        jz      .next_table
164 serge 487
 
2434 Serge 488
        push    edx
489
        stdcall strncmp, eax, [proc_name], 256
490
        pop     edx
491
        test    eax, eax
492
        jz      .ok
164 serge 493
 
2434 Serge 494
        add     edx, 8
495
        jmp     .next
188 serge 496
.next_table:
2434 Serge 497
        add     [imports], 4
498
        jmp     .look_up
188 serge 499
.ok:
2434 Serge 500
        mov     eax, [edx+4]
501
        ret
188 serge 502
.end:
2434 Serge 503
        xor     eax, eax
504
        ret
188 serge 505
endp
164 serge 506
 
188 serge 507
align 4
1289 diamond 508
proc fix_coff_symbols stdcall uses ebx esi, sec:dword, symbols:dword,\
2434 Serge 509
                      sym_count:dword, strings:dword, imports:dword
510
           locals
511
             retval dd ?
512
           endl
164 serge 513
 
2434 Serge 514
        mov     edi, [symbols]
515
        mov     [retval], 1
188 serge 516
.fix:
2434 Serge 517
        movzx   ebx, [edi+COFF_SYM.SectionNumber]
518
        test    ebx, ebx
519
        jnz     .internal
520
        mov     eax, dword [edi+COFF_SYM.Name]
521
        test    eax, eax
522
        jnz     @F
164 serge 523
 
2434 Serge 524
        mov     edi, [edi+4]
525
        add     edi, [strings]
188 serge 526
@@:
2434 Serge 527
        push    edi
528
        stdcall get_proc_ex, edi, [imports]
529
        pop     edi
164 serge 530
 
2434 Serge 531
        xor     ebx, ebx
532
        test    eax, eax
533
        jnz     @F
164 serge 534
 
2434 Serge 535
        mov     esi, msg_unresolved
536
        call    sys_msg_board_str
537
        mov     esi, edi
538
        call    sys_msg_board_str
539
        mov     esi, msg_CR
540
        call    sys_msg_board_str
164 serge 541
 
2434 Serge 542
        mov     [retval], 0
188 serge 543
@@:
2434 Serge 544
        mov     edi, [symbols]
545
        mov     [edi+COFF_SYM.Value], eax
546
        jmp     .next
188 serge 547
.internal:
2434 Serge 548
        cmp     bx, -1
549
        je      .next
550
        cmp     bx, -2
551
        je      .next
541 serge 552
 
2434 Serge 553
        dec     ebx
554
        shl     ebx, 3
555
        lea     ebx, [ebx+ebx*4]
556
        add     ebx, [sec]
188 serge 557
 
2434 Serge 558
        mov     eax, [ebx+COFF_SECTION.VirtualAddress]
559
        add     [edi+COFF_SYM.Value], eax
188 serge 560
.next:
2434 Serge 561
        add     edi, sizeof.COFF_SYM
562
        mov     [symbols], edi
563
        dec     [sym_count]
564
        jnz     .fix
565
        mov     eax, [retval]
566
        ret
164 serge 567
endp
568
 
569
align 4
1289 diamond 570
proc fix_coff_relocs stdcall uses ebx esi, coff:dword, sym:dword, \
2434 Serge 571
        delta:dword
572
           locals
573
             n_sec     dd ?
574
           endl
164 serge 575
 
2434 Serge 576
        mov     eax, [coff]
577
        movzx   ebx, [eax+COFF_HEADER.nSections]
578
        mov     [n_sec], ebx
579
        lea     esi, [eax+20]
188 serge 580
.fix_sec:
2434 Serge 581
        mov     edi, [esi+COFF_SECTION.PtrReloc]
582
        add     edi, [coff]
164 serge 583
 
2434 Serge 584
        movzx   ecx, [esi+COFF_SECTION.NumReloc]
585
        test    ecx, ecx
586
        jz      .next
1289 diamond 587
.reloc_loop:
2434 Serge 588
        mov     ebx, [edi+COFF_RELOC.SymIndex]
589
        add     ebx, ebx
590
        lea     ebx, [ebx+ebx*8]
591
        add     ebx, [sym]
164 serge 592
 
2434 Serge 593
        mov     edx, [ebx+COFF_SYM.Value]
164 serge 594
 
2434 Serge 595
        cmp     [edi+COFF_RELOC.Type], 6
596
        je      .dir_32
164 serge 597
 
2434 Serge 598
        cmp     [edi+COFF_RELOC.Type], 20
599
        jne     .next_reloc
188 serge 600
.rel_32:
2434 Serge 601
        mov     eax, [edi+COFF_RELOC.VirtualAddress]
602
        add     eax, [esi+COFF_SECTION.VirtualAddress]
603
        sub     edx, eax
604
        sub     edx, 4
605
        jmp     .fix
188 serge 606
.dir_32:
2434 Serge 607
        mov     eax, [edi+COFF_RELOC.VirtualAddress]
608
        add     eax, [esi+COFF_SECTION.VirtualAddress]
188 serge 609
.fix:
2434 Serge 610
        add     eax, [delta]
611
        add     [eax], edx
1289 diamond 612
.next_reloc:
2434 Serge 613
        add     edi, 10
614
        dec     ecx
615
        jnz     .reloc_loop
188 serge 616
.next:
2434 Serge 617
        add     esi, sizeof.COFF_SECTION
618
        dec     [n_sec]
619
        jnz     .fix_sec
164 serge 620
.exit:
2434 Serge 621
        ret
164 serge 622
endp
623
 
2106 serge 624
align 4
1289 diamond 625
proc rebase_coff stdcall uses ebx esi, coff:dword, sym:dword, \
2434 Serge 626
        delta:dword
627
           locals
628
             n_sec     dd ?
629
           endl
1289 diamond 630
 
2434 Serge 631
        mov     eax, [coff]
632
        movzx   ebx, [eax+COFF_HEADER.nSections]
633
        mov     [n_sec], ebx
634
        lea     esi, [eax+20]
635
        mov     edx, [delta]
1289 diamond 636
.fix_sec:
2434 Serge 637
        mov     edi, [esi+COFF_SECTION.PtrReloc]
638
        add     edi, [coff]
1289 diamond 639
 
2434 Serge 640
        movzx   ecx, [esi+COFF_SECTION.NumReloc]
641
        test    ecx, ecx
642
        jz      .next
1289 diamond 643
.reloc_loop:
2434 Serge 644
        cmp     [edi+COFF_RELOC.Type], 6
645
        jne     .next_reloc
1289 diamond 646
.dir_32:
2434 Serge 647
        mov     eax, [edi+COFF_RELOC.VirtualAddress]
648
        add     eax, [esi+COFF_SECTION.VirtualAddress]
649
        add     [eax+edx], edx
1289 diamond 650
.next_reloc:
2434 Serge 651
        add     edi, 10
652
        dec     ecx
653
        jnz     .reloc_loop
1289 diamond 654
.next:
2434 Serge 655
        add     esi, sizeof.COFF_SECTION
656
        dec     [n_sec]
657
        jnz     .fix_sec
1289 diamond 658
.exit:
2434 Serge 659
        ret
1289 diamond 660
endp
661
 
188 serge 662
align 4
346 diamond 663
proc load_driver stdcall, driver_name:dword
2434 Serge 664
           locals
665
             coff      dd ?
666
             sym       dd ?
667
             strings   dd ?
668
             img_size  dd ?
669
             img_base  dd ?
670
             start     dd ?
188 serge 671
 
2434 Serge 672
             exports   dd ?   ;fake exports table
673
                       dd ?
674
             file_name rb 13+16+4+1      ; '/sys/drivers/.obj'
675
           endl
188 serge 676
 
2434 Serge 677
        lea     edx, [file_name]
678
        mov     dword [edx], '/sys'
679
        mov     dword [edx+4], '/dri'
680
        mov     dword [edx+8], 'vers'
681
        mov     byte [edx+12], '/'
682
        mov     esi, [driver_name]
1018 diamond 683
.redo:
2434 Serge 684
        lea     edx, [file_name]
685
        lea     edi, [edx+13]
686
        mov     ecx, 16
346 diamond 687
@@:
2434 Serge 688
        lodsb
689
        test    al, al
690
        jz      @f
691
        stosb
692
        loop    @b
346 diamond 693
@@:
2434 Serge 694
        mov     dword [edi], '.obj'
695
        mov     byte [edi+4], 0
696
        stdcall load_file, edx
214 serge 697
 
2434 Serge 698
        test    eax, eax
699
        jz      .exit
188 serge 700
 
2434 Serge 701
        mov     [coff], eax
188 serge 702
 
2434 Serge 703
        movzx   ecx, [eax+COFF_HEADER.nSections]
704
        xor     ebx, ebx
188 serge 705
 
2434 Serge 706
        lea     edx, [eax+20]
188 serge 707
@@:
2434 Serge 708
        add     ebx, [edx+COFF_SECTION.SizeOfRawData]
709
        add     ebx, 15
710
        and     ebx, not 15
711
        add     edx, sizeof.COFF_SECTION
712
        dec     ecx
713
        jnz     @B
714
        mov     [img_size], ebx
188 serge 715
 
2434 Serge 716
        stdcall kernel_alloc, ebx
717
        test    eax, eax
718
        jz      .fail
719
        mov     [img_base], eax
188 serge 720
 
2434 Serge 721
        mov     edi, eax
722
        xor     eax, eax
723
        mov     ecx, [img_size]
724
        add     ecx, 4095
725
        and     ecx, not 4095
726
        shr     ecx, 2
727
        cld
728
        rep stosd
188 serge 729
 
2434 Serge 730
        mov     edx, [coff]
731
        movzx   ebx, [edx+COFF_HEADER.nSections]
732
        mov     edi, [img_base]
733
        lea     eax, [edx+20]
188 serge 734
@@:
2434 Serge 735
        mov     [eax+COFF_SECTION.VirtualAddress], edi
736
        mov     esi, [eax+COFF_SECTION.PtrRawData]
737
        test    esi, esi
738
        jnz     .copy
739
        add     edi, [eax+COFF_SECTION.SizeOfRawData]
740
        jmp     .next
188 serge 741
.copy:
2434 Serge 742
        add     esi, edx
743
        mov     ecx, [eax+COFF_SECTION.SizeOfRawData]
744
        cld
745
        rep movsb
188 serge 746
.next:
2434 Serge 747
        add     edi, 15
748
        and     edi, not 15
749
        add     eax, sizeof.COFF_SECTION
750
        dec     ebx
751
        jnz     @B
188 serge 752
 
2434 Serge 753
        mov     ebx, [edx+COFF_HEADER.pSymTable]
754
        add     ebx, edx
755
        mov     [sym], ebx
756
        mov     ecx, [edx+COFF_HEADER.nSymbols]
757
        add     ecx, ecx
758
        lea     ecx, [ecx+ecx*8];ecx*=18 = nSymbols*CSYM_SIZE
759
        add     ecx, [sym]
760
        mov     [strings], ecx
188 serge 761
 
2434 Serge 762
        lea     ebx, [exports]
763
        mov     dword [ebx], kernel_export
764
        mov     dword [ebx+4], 0
765
        lea     eax, [edx+20]
188 serge 766
 
2434 Serge 767
        stdcall fix_coff_symbols, eax, [sym], [edx+COFF_HEADER.nSymbols], \
768
                [strings], ebx
769
        test    eax, eax
770
        jz      .link_fail
188 serge 771
 
2434 Serge 772
        mov     ebx, [coff]
773
        stdcall fix_coff_relocs, ebx, [sym], 0
188 serge 774
 
2434 Serge 775
        stdcall get_coff_sym, [sym], [ebx+COFF_HEADER.nSymbols], szVersion
776
        test    eax, eax
777
        jz      .link_fail
227 serge 778
 
2434 Serge 779
        mov     eax, [eax]
780
        shr     eax, 16
781
        cmp     eax, DRV_COMPAT
782
        jb      .ver_fail
227 serge 783
 
2434 Serge 784
        cmp     eax, DRV_CURRENT
785
        ja      .ver_fail
227 serge 786
 
2434 Serge 787
        mov     ebx, [coff]
788
        stdcall get_coff_sym, [sym], [ebx+COFF_HEADER.nSymbols], szSTART
789
        mov     [start], eax
188 serge 790
 
2434 Serge 791
        stdcall kernel_free, [coff]
188 serge 792
 
2434 Serge 793
        mov     ebx, [start]
794
        stdcall ebx, DRV_ENTRY
795
        test    eax, eax
796
        jnz     .ok
188 serge 797
 
2434 Serge 798
        stdcall kernel_free, [img_base]
799
        cmp     dword [file_name+13], 'SOUN'
800
        jnz     @f
801
        cmp     dword [file_name+17], 'D.ob'
802
        jnz     @f
803
        cmp     word [file_name+21], 'j'
804
        jnz     @f
2465 Serge 805
        mov     esi, aHDA
2434 Serge 806
        jmp     .redo
1018 diamond 807
@@:
2434 Serge 808
        xor     eax, eax
809
        ret
188 serge 810
.ok:
2434 Serge 811
        mov     ebx, [img_base]
812
        mov     [eax+SRV.base], ebx
813
        mov     ecx, [start]
814
        mov     [eax+SRV.entry], ecx
815
        ret
227 serge 816
 
817
.ver_fail:
2434 Serge 818
        mov     esi, msg_CR
819
        call    sys_msg_board_str
820
        mov     esi, [driver_name]
821
        call    sys_msg_board_str
822
        mov     esi, msg_CR
823
        call    sys_msg_board_str
824
        mov     esi, msg_version
825
        call    sys_msg_board_str
826
        mov     esi, msg_www
827
        call    sys_msg_board_str
828
        jmp     .cleanup
227 serge 829
 
830
.link_fail:
2434 Serge 831
        mov     esi, msg_module
832
        call    sys_msg_board_str
833
        mov     esi, [driver_name]
834
        call    sys_msg_board_str
835
        mov     esi, msg_CR
836
        call    sys_msg_board_str
227 serge 837
.cleanup:
2434 Serge 838
        stdcall kernel_free, [img_base]
188 serge 839
.fail:
2434 Serge 840
        stdcall kernel_free, [coff]
227 serge 841
.exit:
2434 Serge 842
        xor     eax, eax
843
        ret
164 serge 844
endp
845
 
1296 diamond 846
; in: edx -> COFF_SECTION struct
847
; out: eax = alignment as mask for bits to drop
848
coff_get_align:
849
; Rules:
850
; - if alignment is not given, use default = 4K;
851
; - if alignment is given and is no more than 4K, use it;
852
; - if alignment is more than 4K, revert to 4K.
2434 Serge 853
        push    ecx
854
        mov     cl, byte [edx+COFF_SECTION.Characteristics+2]
855
        mov     eax, 1
856
        shr     cl, 4
857
        dec     cl
858
        js      .default
859
        cmp     cl, 12
860
        jbe     @f
1296 diamond 861
.default:
2434 Serge 862
        mov     cl, 12
1296 diamond 863
@@:
2434 Serge 864
        shl     eax, cl
865
        pop     ecx
866
        dec     eax
867
        ret
1296 diamond 868
 
198 serge 869
align 4
870
proc load_library stdcall, file_name:dword
2434 Serge 871
           locals
872
             fullname  rb 260
873
             fileinfo  rb 40
874
             coff      dd ?
875
             img_base  dd ?
876
           endl
198 serge 877
 
2434 Serge 878
        cli
198 serge 879
 
1289 diamond 880
; resolve file name
2434 Serge 881
        mov     ebx, [file_name]
882
        lea     edi, [fullname+1]
883
        mov     byte [edi-1], '/'
884
        stdcall get_full_file_name, edi, 259
885
        test    al, al
886
        jz      .fail
1289 diamond 887
 
888
; scan for required DLL in list of already loaded for this process,
889
; ignore timestamp
2434 Serge 890
        mov     esi, [CURRENT_TASK]
891
        shl     esi, 8
892
        lea     edi, [fullname]
893
        mov     ebx, [esi+SLOT_BASE+APPDATA.dlls_list_ptr]
894
        test    ebx, ebx
895
        jz      .not_in_process
896
        mov     esi, [ebx+HDLL.fd]
1289 diamond 897
.scan_in_process:
2434 Serge 898
        cmp     esi, ebx
899
        jz      .not_in_process
900
        mov     eax, [esi+HDLL.parent]
901
        add     eax, DLLDESCR.name
902
        stdcall strncmp, eax, edi, -1
903
        test    eax, eax
904
        jnz     .next_in_process
1289 diamond 905
; simple variant: load DLL which is already loaded in this process
906
; just increment reference counters and return address of exports table
2434 Serge 907
        inc     [esi+HDLL.refcount]
908
        mov     ecx, [esi+HDLL.parent]
909
        inc     [ecx+DLLDESCR.refcount]
910
        mov     eax, [ecx+DLLDESCR.exports]
911
        sub     eax, [ecx+DLLDESCR.defaultbase]
912
        add     eax, [esi+HDLL.base]
913
        ret
1289 diamond 914
.next_in_process:
2434 Serge 915
        mov     esi, [esi+HDLL.fd]
916
        jmp     .scan_in_process
1289 diamond 917
.not_in_process:
918
 
919
; scan in full list, compare timestamp
2434 Serge 920
        lea     eax, [fileinfo]
921
        stdcall get_fileinfo, edi, eax
922
        test    eax, eax
923
        jnz     .fail
924
        mov     esi, [dll_list.fd]
1289 diamond 925
.scan_for_dlls:
2434 Serge 926
        cmp     esi, dll_list
927
        jz      .load_new
928
        lea     eax, [esi+DLLDESCR.name]
929
        stdcall strncmp, eax, edi, -1
930
        test    eax, eax
931
        jnz     .continue_scan
1289 diamond 932
.test_prev_dll:
2434 Serge 933
        mov     eax, dword [fileinfo+24]; last modified time
934
        mov     edx, dword [fileinfo+28]; last modified date
935
        cmp     dword [esi+DLLDESCR.timestamp], eax
936
        jnz     .continue_scan
937
        cmp     dword [esi+DLLDESCR.timestamp+4], edx
938
        jz      .dll_already_loaded
1289 diamond 939
.continue_scan:
2434 Serge 940
        mov     esi, [esi+DLLDESCR.fd]
941
        jmp     .scan_for_dlls
1289 diamond 942
 
943
; new DLL
944
.load_new:
945
; load file
2434 Serge 946
        stdcall load_file, edi
947
        test    eax, eax
948
        jz      .fail
949
        mov     [coff], eax
950
        mov     dword [fileinfo+32], ebx
198 serge 951
 
1289 diamond 952
; allocate DLLDESCR struct; size is DLLDESCR.sizeof plus size of DLL name
2434 Serge 953
        mov     esi, edi
954
        mov     ecx, -1
955
        xor     eax, eax
956
        repnz scasb
957
        not     ecx
958
        lea     eax, [ecx+sizeof.DLLDESCR]
959
        push    ecx
960
        call    malloc
961
        pop     ecx
962
        test    eax, eax
963
        jz      .fail_and_free_coff
1289 diamond 964
; save timestamp
2434 Serge 965
        lea     edi, [eax+DLLDESCR.name]
966
        rep movsb
967
        mov     esi, eax
968
        mov     eax, dword [fileinfo+24]
969
        mov     dword [esi+DLLDESCR.timestamp], eax
970
        mov     eax, dword [fileinfo+28]
971
        mov     dword [esi+DLLDESCR.timestamp+4], eax
1289 diamond 972
; initialize DLLDESCR struct
2434 Serge 973
        and     dword [esi+DLLDESCR.refcount], 0; no HDLLs yet; later it will be incremented
974
        mov     [esi+DLLDESCR.fd], dll_list
975
        mov     eax, [dll_list.bk]
976
        mov     [dll_list.bk], esi
977
        mov     [esi+DLLDESCR.bk], eax
978
        mov     [eax+DLLDESCR.fd], esi
1289 diamond 979
 
980
; calculate size of loaded DLL
2434 Serge 981
        mov     edx, [coff]
982
        movzx   ecx, [edx+COFF_HEADER.nSections]
983
        xor     ebx, ebx
198 serge 984
 
2434 Serge 985
        add     edx, 20
198 serge 986
@@:
2434 Serge 987
        call    coff_get_align
988
        add     ebx, eax
989
        not     eax
990
        and     ebx, eax
991
        add     ebx, [edx+COFF_SECTION.SizeOfRawData]
992
        add     edx, sizeof.COFF_SECTION
993
        dec     ecx
994
        jnz     @B
1289 diamond 995
; it must be nonzero and not too big
2434 Serge 996
        mov     [esi+DLLDESCR.size], ebx
997
        test    ebx, ebx
998
        jz      .fail_and_free_dll
999
        cmp     ebx, MAX_DEFAULT_DLL_ADDR-MIN_DEFAULT_DLL_ADDR
1000
        ja      .fail_and_free_dll
1289 diamond 1001
; allocate memory for kernel-side image
2434 Serge 1002
        stdcall kernel_alloc, ebx
1003
        test    eax, eax
1004
        jz      .fail_and_free_dll
1005
        mov     [esi+DLLDESCR.data], eax
1289 diamond 1006
; calculate preferred base address
2434 Serge 1007
        add     ebx, 0x1FFF
1008
        and     ebx, not 0xFFF
1009
        mov     ecx, [dll_cur_addr]
1010
        lea     edx, [ecx+ebx]
1011
        cmp     edx, MAX_DEFAULT_DLL_ADDR
1012
        jb      @f
1013
        mov     ecx, MIN_DEFAULT_DLL_ADDR
1014
        lea     edx, [ecx+ebx]
1289 diamond 1015
@@:
2434 Serge 1016
        mov     [esi+DLLDESCR.defaultbase], ecx
1017
        mov     [dll_cur_addr], edx
198 serge 1018
 
1289 diamond 1019
; copy sections and set correct values for VirtualAddress'es in headers
2434 Serge 1020
        push    esi
1021
        mov     edx, [coff]
1022
        movzx   ebx, [edx+COFF_HEADER.nSections]
1023
        mov     edi, eax
1024
        add     edx, 20
1025
        cld
198 serge 1026
@@:
2434 Serge 1027
        call    coff_get_align
1028
        add     ecx, eax
1029
        add     edi, eax
1030
        not     eax
1031
        and     ecx, eax
1032
        and     edi, eax
1033
        mov     [edx+COFF_SECTION.VirtualAddress], ecx
1034
        add     ecx, [edx+COFF_SECTION.SizeOfRawData]
1035
        mov     esi, [edx+COFF_SECTION.PtrRawData]
1036
        push    ecx
1037
        mov     ecx, [edx+COFF_SECTION.SizeOfRawData]
1038
        test    esi, esi
1039
        jnz     .copy
1040
        xor     eax, eax
1041
        rep stosb
1042
        jmp     .next
198 serge 1043
.copy:
2434 Serge 1044
        add     esi, [coff]
1045
        rep movsb
198 serge 1046
.next:
2434 Serge 1047
        pop     ecx
1048
        add     edx, sizeof.COFF_SECTION
1049
        dec     ebx
1050
        jnz     @B
1051
        pop     esi
198 serge 1052
 
1289 diamond 1053
; save some additional data from COFF file
1054
; later we will use COFF header, headers for sections and symbol table
1055
; and also relocations table for all sections
2434 Serge 1056
        mov     edx, [coff]
1057
        mov     ebx, [edx+COFF_HEADER.pSymTable]
1058
        mov     edi, dword [fileinfo+32]
1059
        sub     edi, ebx
1060
        jc      .fail_and_free_data
1061
        mov     [esi+DLLDESCR.symbols_lim], edi
1062
        add     ebx, edx
1063
        movzx   ecx, [edx+COFF_HEADER.nSections]
1064
        lea     ecx, [ecx*5]
1065
        lea     edi, [edi+ecx*8+20]
1066
        add     edx, 20
1289 diamond 1067
@@:
2434 Serge 1068
        movzx   eax, [edx+COFF_SECTION.NumReloc]
1069
        lea     eax, [eax*5]
1070
        lea     edi, [edi+eax*2]
1071
        add     edx, sizeof.COFF_SECTION
1072
        sub     ecx, 5
1073
        jnz     @b
1074
        stdcall kernel_alloc, edi
1075
        test    eax, eax
1076
        jz      .fail_and_free_data
1077
        mov     edx, [coff]
1078
        movzx   ecx, [edx+COFF_HEADER.nSections]
1079
        lea     ecx, [ecx*5]
1080
        lea     ecx, [ecx*2+5]
1081
        mov     [esi+DLLDESCR.coff_hdr], eax
1082
        push    esi
1083
        mov     esi, edx
1084
        mov     edi, eax
1085
        rep movsd
1086
        pop     esi
1087
        mov     [esi+DLLDESCR.symbols_ptr], edi
1088
        push    esi
1089
        mov     ecx, [edx+COFF_HEADER.nSymbols]
1090
        mov     [esi+DLLDESCR.symbols_num], ecx
1091
        mov     ecx, [esi+DLLDESCR.symbols_lim]
1092
        mov     esi, ebx
1093
        rep movsb
1094
        pop     esi
1095
        mov     ebx, [esi+DLLDESCR.coff_hdr]
1096
        push    esi
1097
        movzx   eax, [edx+COFF_HEADER.nSections]
1098
        lea     edx, [ebx+20]
1289 diamond 1099
@@:
2434 Serge 1100
        movzx   ecx, [edx+COFF_SECTION.NumReloc]
1101
        lea     ecx, [ecx*5]
1102
        mov     esi, [edx+COFF_SECTION.PtrReloc]
1103
        mov     [edx+COFF_SECTION.PtrReloc], edi
1104
        sub     [edx+COFF_SECTION.PtrReloc], ebx
1105
        add     esi, [coff]
1106
        shr     ecx, 1
1107
        rep movsd
1108
        adc     ecx, ecx
1109
        rep movsw
1110
        add     edx, sizeof.COFF_SECTION
1111
        dec     eax
1112
        jnz     @b
1113
        pop     esi
198 serge 1114
 
1289 diamond 1115
; fixup symbols
2434 Serge 1116
        mov     edx, ebx
1117
        mov     eax, [ebx+COFF_HEADER.nSymbols]
1118
        add     edx, 20
1119
        mov     ecx, [esi+DLLDESCR.symbols_num]
1120
        lea     ecx, [ecx*9]
1121
        add     ecx, ecx
1122
        add     ecx, [esi+DLLDESCR.symbols_ptr]
198 serge 1123
 
2434 Serge 1124
        stdcall fix_coff_symbols, edx, [esi+DLLDESCR.symbols_ptr], eax, \
1125
                ecx, 0
1126
;          test eax, eax
1127
;          jnz @F
1289 diamond 1128
;
1129
;@@:
1130
 
2434 Serge 1131
        stdcall get_coff_sym, [esi+DLLDESCR.symbols_ptr], [ebx+COFF_HEADER.nSymbols], szEXPORTS
1132
        test    eax, eax
1133
        jnz     @F
198 serge 1134
 
2434 Serge 1135
        stdcall get_coff_sym, [esi+DLLDESCR.symbols_ptr], [ebx+COFF_HEADER.nSymbols], sz_EXPORTS
198 serge 1136
@@:
2434 Serge 1137
        mov     [esi+DLLDESCR.exports], eax
198 serge 1138
 
1289 diamond 1139
; fix relocs in the hidden copy in kernel memory to default address
1140
; it is first fix; usually this will be enough, but second fix
1141
; can be necessary if real load address will not equal assumption
2434 Serge 1142
        mov     eax, [esi+DLLDESCR.data]
1143
        sub     eax, [esi+DLLDESCR.defaultbase]
1144
        stdcall fix_coff_relocs, ebx, [esi+DLLDESCR.symbols_ptr], eax
198 serge 1145
 
2434 Serge 1146
        stdcall kernel_free, [coff]
916 serge 1147
 
1289 diamond 1148
.dll_already_loaded:
2434 Serge 1149
        inc     [esi+DLLDESCR.refcount]
1150
        push    esi
1151
        call    init_heap
1152
        pop     esi
1289 diamond 1153
 
2434 Serge 1154
        mov     edi, [esi+DLLDESCR.size]
1155
        stdcall user_alloc_at, [esi+DLLDESCR.defaultbase], edi
1156
        test    eax, eax
1157
        jnz     @f
1158
        stdcall user_alloc, edi
1159
        test    eax, eax
1160
        jz      .fail_and_dereference
917 diamond 1161
@@:
2434 Serge 1162
        mov     [img_base], eax
1163
        mov     eax, sizeof.HDLL
1164
        call    malloc
1165
        test    eax, eax
1166
        jz      .fail_and_free_user
1167
        mov     ebx, [CURRENT_TASK]
1168
        shl     ebx, 5
1169
        mov     edx, [CURRENT_TASK+ebx+TASKDATA.pid]
1170
        mov     [eax+HDLL.pid], edx
1171
        push    eax
1172
        call    init_dlls_in_thread
1173
        pop     ebx
1174
        test    eax, eax
1175
        jz      .fail_and_free_user
1176
        mov     edx, [eax+HDLL.fd]
1177
        mov     [ebx+HDLL.fd], edx
1178
        mov     [ebx+HDLL.bk], eax
1179
        mov     [eax+HDLL.fd], ebx
1180
        mov     [edx+HDLL.bk], ebx
1181
        mov     eax, ebx
1182
        mov     ebx, [img_base]
1183
        mov     [eax+HDLL.base], ebx
1184
        mov     [eax+HDLL.size], edi
1185
        mov     [eax+HDLL.refcount], 1
1186
        mov     [eax+HDLL.parent], esi
1187
        mov     edx, ebx
1188
        shr     edx, 12
1189
        or      dword [page_tabs+(edx-1)*4], DONT_FREE_BLOCK
1289 diamond 1190
; copy entries of page table from kernel-side image to usermode
1191
; use copy-on-write for user-mode image, so map as readonly
2434 Serge 1192
        xor     edi, edi
1193
        mov     ecx, [esi+DLLDESCR.data]
1194
        shr     ecx, 12
1289 diamond 1195
.map_pages_loop:
2434 Serge 1196
        mov     eax, [page_tabs+ecx*4]
1197
        and     eax, not 0xFFF
1198
        or      al, PG_USER
1199
        xchg    eax, [page_tabs+edx*4]
1200
        test    al, 1
1201
        jz      @f
1202
        call    free_page
1289 diamond 1203
@@:
2434 Serge 1204
        invlpg  [ebx+edi]
1205
        inc     ecx
1206
        inc     edx
1207
        add     edi, 0x1000
1208
        cmp     edi, [esi+DLLDESCR.size]
1209
        jb      .map_pages_loop
1289 diamond 1210
 
1211
; if real user-mode base is not equal to preferred base, relocate image
2434 Serge 1212
        sub     ebx, [esi+DLLDESCR.defaultbase]
1213
        jz      @f
1214
        stdcall rebase_coff, [esi+DLLDESCR.coff_hdr], [esi+DLLDESCR.symbols_ptr], ebx
1289 diamond 1215
@@:
1216
 
2434 Serge 1217
        mov     eax, [esi+DLLDESCR.exports]
1218
        sub     eax, [esi+DLLDESCR.defaultbase]
1219
        add     eax, [img_base]
1220
        ret
1289 diamond 1221
.fail_and_free_data:
2434 Serge 1222
        stdcall kernel_free, [esi+DLLDESCR.data]
1289 diamond 1223
.fail_and_free_dll:
2434 Serge 1224
        mov     eax, esi
1225
        call    free
1289 diamond 1226
.fail_and_free_coff:
2434 Serge 1227
        stdcall kernel_free, [coff]
198 serge 1228
.fail:
2434 Serge 1229
        xor     eax, eax
1230
        ret
1289 diamond 1231
.fail_and_free_user:
2434 Serge 1232
        stdcall user_free, [img_base]
1289 diamond 1233
.fail_and_dereference:
2434 Serge 1234
        mov     eax, 1  ; delete 1 reference
1235
        call    dereference_dll
1236
        xor     eax, eax
1237
        ret
198 serge 1238
endp
1239
 
1311 diamond 1240
; initialize [APPDATA.dlls_list_ptr] for given thread
1241
; DLL is per-process object, so APPDATA.dlls_list_ptr must be
1242
; kept in sync for all threads of one process.
1243
; out: eax = APPDATA.dlls_list_ptr if all is OK,
1244
; NULL if memory allocation failed
1245
init_dlls_in_thread:
2434 Serge 1246
        mov     ebx, [current_slot]
1247
        mov     eax, [ebx+APPDATA.dlls_list_ptr]
1248
        test    eax, eax
1249
        jnz     .ret
1250
        push    [ebx+APPDATA.dir_table]
1251
        mov     eax, 8
1252
        call    malloc
1253
        pop     edx
1254
        test    eax, eax
1255
        jz      .ret
1256
        mov     [eax], eax
1257
        mov     [eax+4], eax
1258
        mov     ecx, [TASK_COUNT]
1259
        mov     ebx, SLOT_BASE+256
1311 diamond 1260
.set:
2434 Serge 1261
        cmp     [ebx+APPDATA.dir_table], edx
1262
        jnz     @f
1263
        mov     [ebx+APPDATA.dlls_list_ptr], eax
1311 diamond 1264
@@:
2434 Serge 1265
        add     ebx, 256
1266
        dec     ecx
1267
        jnz     .set
1311 diamond 1268
.ret:
2434 Serge 1269
        ret
1311 diamond 1270
 
1289 diamond 1271
; in: eax = number of references to delete, esi -> DLLDESCR struc
1272
dereference_dll:
2434 Serge 1273
        sub     [esi+DLLDESCR.refcount], eax
1274
        jnz     .ret
1275
        mov     eax, [esi+DLLDESCR.fd]
1276
        mov     edx, [esi+DLLDESCR.bk]
1277
        mov     [eax+DLLDESCR.bk], edx
1278
        mov     [edx+DLLDESCR.fd], eax
1279
        stdcall kernel_free, [esi+DLLDESCR.coff_hdr]
1280
        stdcall kernel_free, [esi+DLLDESCR.data]
1281
        mov     eax, esi
1282
        call    free
1289 diamond 1283
.ret:
2434 Serge 1284
        ret
1289 diamond 1285
 
1286
destroy_hdll:
2434 Serge 1287
        push    ebx ecx esi edi
1288
        push    eax
1289
        mov     ebx, [eax+HDLL.base]
1290
        mov     esi, [eax+HDLL.parent]
1291
        mov     edx, [esi+DLLDESCR.size]
1292 diamond 1292
; The following actions require the context of application where HDLL is mapped.
1293
; However, destroy_hdll can be called in the context of OS thread when
1294
; cleaning up objects created by the application which is destroyed.
1295
; So remember current cr3 and set it to page table of target.
2434 Serge 1296
        mov     eax, [ecx+APPDATA.dir_table]
1292 diamond 1297
; Because we cheat with cr3, disable interrupts: task switch would restore
1298
; page table from APPDATA of current thread.
1299
; Also set [current_slot] because it is used by user_free.
2434 Serge 1300
        pushf
1301
        cli
1302
        push    [current_slot]
1303
        mov     [current_slot], ecx
1304
        mov     ecx, cr3
1305
        push    ecx
1306
        mov     cr3, eax
1307
        push    ebx     ; argument for user_free
1308
        mov     eax, ebx
1309
        shr     ebx, 12
1310
        push    ebx
1311
        mov     esi, [esi+DLLDESCR.data]
1312
        shr     esi, 12
1289 diamond 1313
.unmap_loop:
2434 Serge 1314
        push    eax
1315
        mov     eax, 2
1316
        xchg    eax, [page_tabs+ebx*4]
1317
        mov     ecx, [page_tabs+esi*4]
1318
        and     eax, not 0xFFF
1319
        and     ecx, not 0xFFF
1320
        cmp     eax, ecx
1321
        jz      @f
1322
        call    free_page
1289 diamond 1323
@@:
2434 Serge 1324
        pop     eax
1325
        invlpg  [eax]
1326
        add     eax, 0x1000
1327
        inc     ebx
1328
        inc     esi
1329
        sub     edx, 0x1000
1330
        ja      .unmap_loop
1331
        pop     ebx
1332
        and     dword [page_tabs+(ebx-1)*4], not DONT_FREE_BLOCK
1333
        call    user_free
1292 diamond 1334
; Restore context.
2434 Serge 1335
        pop     eax
1336
        mov     cr3, eax
1337
        pop     [current_slot]
1338
        popf
1292 diamond 1339
; Ok, cheating is done.
2434 Serge 1340
        pop     eax
1341
        push    eax
1342
        mov     esi, [eax+HDLL.parent]
1343
        mov     eax, [eax+HDLL.refcount]
1344
        call    dereference_dll
1345
        pop     eax
1346
        mov     edx, [eax+HDLL.bk]
1347
        mov     ebx, [eax+HDLL.fd]
1348
        mov     [ebx+HDLL.bk], edx
1349
        mov     [edx+HDLL.fd], ebx
1350
        call    free
1351
        pop     edi esi ecx ebx
1352
        ret
1289 diamond 1353
 
1311 diamond 1354
; ecx -> APPDATA for slot, esi = dlls_list_ptr
1355
destroy_all_hdlls:
2434 Serge 1356
        test    esi, esi
1357
        jz      .ret
1311 diamond 1358
.loop:
2434 Serge 1359
        mov     eax, [esi+HDLL.fd]
1360
        cmp     eax, esi
1361
        jz      free
1362
        call    destroy_hdll
1363
        jmp     .loop
1311 diamond 1364
.ret:
2434 Serge 1365
        ret
1311 diamond 1366
 
214 serge 1367
align 4
1275 serge 1368
stop_all_services:
2434 Serge 1369
        push    ebp
1370
        mov     edx, [srv.fd]
214 serge 1371
.next:
2434 Serge 1372
        cmp     edx, srv.fd-SRV.fd
1373
        je      .done
1374
        cmp     [edx+SRV.magic], ' SRV'
1375
        jne     .next
1376
        cmp     [edx+SRV.size], sizeof.SRV
1377
        jne     .next
732 serge 1378
 
2434 Serge 1379
        mov     ebx, [edx+SRV.entry]
1380
        mov     edx, [edx+SRV.fd]
1381
        test    ebx, ebx
1382
        jz      .next
732 serge 1383
 
2434 Serge 1384
        push    edx
1385
        mov     ebp, esp
1386
        push    0
1387
        push    -1
1388
        call    ebx
1389
        mov     esp, ebp
1390
        pop     edx
1391
        jmp     .next
278 serge 1392
.done:
2434 Serge 1393
        pop     ebp
1394
        ret
198 serge 1395
 
281 serge 1396
; param
291 serge 1397
;  eax= size
1398
;  ebx= pid
214 serge 1399
 
281 serge 1400
align 4
1401
create_kernel_object:
1402
 
2434 Serge 1403
        push    ebx
1404
        call    malloc
1405
        pop     ebx
1406
        test    eax, eax
1407
        jz      .fail
281 serge 1408
 
2434 Serge 1409
        mov     ecx, [current_slot]
1410
        add     ecx, APP_OBJ_OFFSET
281 serge 1411
 
2434 Serge 1412
        pushfd
1413
        cli
1414
        mov     edx, [ecx+APPOBJ.fd]
1415
        mov     [eax+APPOBJ.fd], edx
1416
        mov     [eax+APPOBJ.bk], ecx
1417
        mov     [eax+APPOBJ.pid], ebx
281 serge 1418
 
2434 Serge 1419
        mov     [ecx+APPOBJ.fd], eax
1420
        mov     [edx+APPOBJ.bk], eax
1421
        popfd
281 serge 1422
.fail:
2434 Serge 1423
        ret
281 serge 1424
 
1425
; param
1426
;  eax= object
1427
 
1428
align 4
1429
destroy_kernel_object:
1430
 
2434 Serge 1431
        pushfd
1432
        cli
1433
        mov     ebx, [eax+APPOBJ.fd]
1434
        mov     ecx, [eax+APPOBJ.bk]
1435
        mov     [ebx+APPOBJ.bk], ecx
1436
        mov     [ecx+APPOBJ.fd], ebx
1437
        popfd
281 serge 1438
 
2434 Serge 1439
        xor     edx, edx       ;clear common header
1440
        mov     [eax], edx
1441
        mov     [eax+4], edx
1442
        mov     [eax+8], edx
1443
        mov     [eax+12], edx
1444
        mov     [eax+16], edx
281 serge 1445
 
2434 Serge 1446
        call    free           ;release object memory
1447
        ret