Subversion Repositories Kolibri OS

Rev

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