Subversion Repositories Kolibri OS

Rev

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

Rev Author Line No. Line
2288 clevermous 1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                              ;;
2455 mario79 3
;; Copyright (C) KolibriOS team 2004-2012. All rights reserved. ;;
2288 clevermous 4
;; Distributed under terms of the GNU General Public License    ;;
5
;;                                                              ;;
6
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
7
 
8
$Revision: 4237 $
9
 
10
 
11
DRV_COMPAT   equ  5  ;minimal required drivers version
12
DRV_CURRENT  equ  6  ;current drivers model version
13
 
14
DRV_VERSION equ (DRV_COMPAT shl 16) or DRV_CURRENT
15
PID_KERNEL  equ 1    ;os_idle thread
16
 
17
 
18
 
19
align 4
20
proc get_notify stdcall, p_ev:dword
21
 
22
.wait:
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
32
@@:
33
        call    change_task
34
        jmp     .wait
35
endp
36
 
37
align 4
38
proc pci_read32 stdcall, bus:dword, devfn:dword, reg:dword
39
        push    ebx
40
        xor     eax, eax
41
        xor     ebx, ebx
42
        mov     ah, byte [bus]
43
        mov     al, 6
44
        mov     bh, byte [devfn]
45
        mov     bl, byte [reg]
46
        call    pci_read_reg
47
        pop     ebx
48
        ret
49
endp
50
 
51
align 4
52
proc pci_read16 stdcall, bus:dword, devfn:dword, reg:dword
53
        push    ebx
54
        xor     eax, eax
55
        xor     ebx, ebx
56
        mov     ah, byte [bus]
57
        mov     al, 5
58
        mov     bh, byte [devfn]
59
        mov     bl, byte [reg]
60
        call    pci_read_reg
61
        pop     ebx
62
        ret
63
endp
64
 
65
align 4
66
proc pci_read8 stdcall, bus:dword, devfn:dword, reg:dword
67
        push    ebx
68
        xor     eax, eax
69
        xor     ebx, ebx
70
        mov     ah, byte [bus]
71
        mov     al, 4
72
        mov     bh, byte [devfn]
73
        mov     bl, byte [reg]
74
        call    pci_read_reg
75
        pop     ebx
76
        ret
77
endp
78
 
79
align 4
80
proc pci_write8 stdcall, bus:dword, devfn:dword, reg:dword, val:dword
81
        push    ebx
82
        xor     eax, eax
83
        xor     ebx, ebx
84
        mov     ah, byte [bus]
85
        mov     al, 8
86
        mov     bh, byte [devfn]
87
        mov     bl, byte [reg]
88
        mov     ecx, [val]
89
        call    pci_write_reg
90
        pop     ebx
91
        ret
92
endp
93
 
94
align 4
95
proc pci_write16 stdcall, bus:dword, devfn:dword, reg:dword, val:dword
96
        push    ebx
97
        xor     eax, eax
98
        xor     ebx, ebx
99
        mov     ah, byte [bus]
100
        mov     al, 9
101
        mov     bh, byte [devfn]
102
        mov     bl, byte [reg]
103
        mov     ecx, [val]
104
        call    pci_write_reg
105
        pop     ebx
106
        ret
107
endp
108
 
109
align 4
110
proc pci_write32 stdcall, bus:dword, devfn:dword, reg:dword, val:dword
111
        push    ebx
112
        xor     eax, eax
113
        xor     ebx, ebx
114
        mov     ah, byte [bus]
115
        mov     al, 10
116
        mov     bh, byte [devfn]
117
        mov     bl, byte [reg]
118
        mov     ecx, [val]
119
        call    pci_write_reg
120
        pop     ebx
121
        ret
122
endp
123
 
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
130
 
131
 
132
align 4
133
proc srv_handler stdcall, ioctl:dword
134
        mov     esi, [ioctl]
135
        test    esi, esi
136
        jz      .err
137
 
138
        mov     edi, [esi+handle]
139
        cmp     [edi+SRV.magic], ' SRV'
140
        jne     .fail
141
 
2384 hidnplayr 142
        cmp     [edi+SRV.size], sizeof.SRV
2288 clevermous 143
        jne     .fail
144
 
3520 clevermous 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
2288 clevermous 150
        ret
151
.fail:
152
        xor     eax, eax
153
        not     eax
154
        mov     [esi+output], eax
155
        mov     [esi+out_size], 4
156
        ret
157
.err:
158
        xor     eax, eax
159
        not     eax
160
        ret
161
endp
162
 
163
; param
164
;  ecx= io_control
165
;
166
; retval
167
;  eax= error code
168
 
169
align 4
170
srv_handlerEx:
171
        cmp     ecx, OS_BASE
172
        jae     .fail
173
 
174
        mov     eax, [ecx+handle]
175
        cmp     [eax+SRV.magic], ' SRV'
176
        jne     .fail
177
 
2384 hidnplayr 178
        cmp     [eax+SRV.size], sizeof.SRV
2288 clevermous 179
        jne     .fail
180
 
3520 clevermous 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
2288 clevermous 186
        ret
187
.fail:
188
        or      eax, -1
189
        ret
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
200
        mov     eax, [sz_name]
201
        test    eax, eax
202
        jnz     @F
203
        ret
204
@@:
205
        mov     edx, [srv.fd]
206
@@:
2384 hidnplayr 207
        cmp     edx, srv.fd-SRV.fd
2288 clevermous 208
        je      .not_load
209
 
210
        stdcall strncmp, edx, [sz_name], 16
211
        test    eax, eax
212
        je      .ok
213
 
214
        mov     edx, [edx+SRV.fd]
215
        jmp     @B
216
.not_load:
217
        pop     ebp
218
        jmp     load_driver
219
.ok:
220
        mov     eax, edx
221
        ret
222
endp
223
 
3520 clevermous 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
2288 clevermous 234
 
3520 clevermous 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
 
2288 clevermous 249
        push    ebx
250
 
251
        xor     eax, eax
252
 
253
        cmp     [name], eax
254
        je      .fail
255
 
3520 clevermous 256
;        cmp     [handler], eax
257
;        je      .fail
2288 clevermous 258
 
3520 clevermous 259
        mov     eax, [srvsize]
2288 clevermous 260
        call    malloc
261
        test    eax, eax
262
        jz      .fail
263
 
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
274
 
275
        mov     [eax+SRV.magic], ' SRV'
2384 hidnplayr 276
        mov     [eax+SRV.size], sizeof.SRV
2288 clevermous 277
 
2384 hidnplayr 278
        mov     ebx, srv.fd-SRV.fd
2288 clevermous 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
284
 
285
        mov     ecx, [handler]
286
        mov     [eax+SRV.srv_proc], ecx
287
        pop     ebx
288
        ret
289
.fail:
290
        xor     eax, eax
291
        pop     ebx
292
        ret
293
endp
294
 
295
align 4
296
proc get_proc stdcall, exp:dword, sz_name:dword
297
 
298
        mov     edx, [exp]
299
.next:
300
        mov     eax, [edx]
301
        test    eax, eax
302
        jz      .end
303
 
304
        push    edx
305
        stdcall strncmp, eax, [sz_name], 16
306
        pop     edx
307
        test    eax, eax
308
        jz      .ok
309
 
310
        add     edx, 8
311
        jmp     .next
312
.ok:
313
        mov     eax, [edx+4]
314
.end:
315
        ret
316
endp
317
 
318
align 4
319
proc get_coff_sym stdcall, pSym:dword,count:dword, sz_sym:dword
320
 
321
@@:
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
330
.ok:
331
        mov     eax, [pSym]
332
        mov     eax, [eax+8]
333
        ret
334
endp
335
 
336
align 4
337
proc get_curr_task
338
        mov     eax, [CURRENT_TASK]
339
        shl     eax, 8
340
        ret
341
endp
342
 
343
align 4
344
proc get_fileinfo stdcall, file_name:dword, info:dword
345
           locals
346
             cmd     dd ?
347
             offset  dd ?
348
                     dd ?
349
             count   dd ?
350
             buff    dd ?
351
                     db ?
352
             name    dd ?
353
           endl
354
 
355
        xor     eax, eax
356
        mov     ebx, [file_name]
357
        mov     ecx, [info]
358
 
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
366
 
367
        mov     eax, 70
368
        lea     ebx, [cmd]
369
        int     0x40
370
        ret
371
endp
372
 
373
align 4
374
proc read_file stdcall,file_name:dword, buffer:dword, off:dword,\
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
385
 
386
        xor     eax, eax
387
        mov     ebx, [file_name]
388
        mov     ecx, [off]
389
        mov     edx, [bytes]
390
        mov     esi, [buffer]
391
 
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
399
 
400
        pushad
401
        lea     ebx, [cmd]
3296 clevermous 402
        call    file_system_lfn_protected
2288 clevermous 403
        popad
404
        ret
405
endp
406
 
407
; description
408
;  allocate kernel memory and loads the specified file
409
;
410
; param
3786 Serge 411
;  file_name= path to file
2288 clevermous 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
 
421
align 4
422
proc load_file stdcall, file_name:dword
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 ?
433
 
434
             file       dd ?
435
             file2      dd ?
436
           endl
437
 
438
        push    esi
439
        push    edi
440
 
441
        lea     eax, [attr]
442
        stdcall get_fileinfo, [file_name], eax
443
        test    eax, eax
444
        jnz     .fail
445
 
446
        mov     eax, [file_size]
447
        cmp     eax, 1024*1024*16
448
        ja      .fail
449
 
450
        stdcall kernel_alloc, [file_size]
451
        mov     [file], eax
452
        test    eax, eax
453
        jz      .fail
454
 
455
        stdcall read_file, [file_name], eax, dword 0, [file_size]
456
        cmp     ebx, [file_size]
457
        jne     .cleanup
458
 
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
465
 
466
        test    eax, eax
467
        jz      .cleanup
468
 
469
        mov     [file2], eax
2486 mario79 470
 
2500 mario79 471
        pushad
2489 mario79 472
        mov     ecx, unpack_mutex
473
        call    mutex_lock
2500 mario79 474
        popad
2486 mario79 475
 
2288 clevermous 476
        stdcall unpack, [file], eax
2486 mario79 477
 
2500 mario79 478
        pushad
479
        mov     ecx, unpack_mutex
2489 mario79 480
        call    mutex_unlock
2500 mario79 481
        popad
2486 mario79 482
 
2288 clevermous 483
        stdcall kernel_free, [file]
484
        mov     eax, [file2]
485
        mov     ebx, [file_size]
486
.exit:
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
496
@@:
497
        mov     ebx, [file_size]
498
        pop     eax
499
        pop     edi
500
        pop     esi
501
        ret
502
.cleanup:
503
        stdcall kernel_free, [file]
504
.fail:
505
        xor     eax, eax
506
        xor     ebx, ebx
507
        pop     edi
508
        pop     esi
509
        ret
510
endp
511
 
3786 Serge 512
; description
513
;  allocate user memory and loads the specified file
514
;
515
; param
516
;  file_name= path to file
517
;
518
; retval
519
;  eax= file image in user memory
520
;  ebx= size of file
521
;
522
; warging
523
;  You mast call kernel_free() to delete each file
524
;  loaded by the load_file() function
525
 
526
align 4
527
proc load_file_umode stdcall, file_name:dword
528
           locals
529
             attr       dd ?
530
             flags      dd ?
531
             cr_time    dd ?
532
             cr_date    dd ?
533
             acc_time   dd ?
534
             acc_date   dd ?
535
             mod_time   dd ?
536
             mod_date   dd ?
537
             file_size  dd ?
538
 
539
             km_file    dd ?
540
             um_file    dd ?
541
           endl
542
 
543
        push    esi
544
        push    edi
545
        push    ebx
546
 
547
        lea     eax, [attr]
548
        stdcall get_fileinfo, [file_name], eax   ;find file and get info
549
        test    eax, eax
550
        jnz     .err_1
551
 
552
        mov     eax, [file_size]
553
        cmp     eax, 1024*1024*16                ;to be enough for anybody (c)
554
        ja      .err_1
555
                                                 ;it is very likely that the file is packed
556
        stdcall kernel_alloc, [file_size]        ;with kpack, so allocate memory from kernel heap
557
        mov     [km_file], eax
558
        test    eax, eax
559
        jz      .err_1
560
 
561
        stdcall read_file, [file_name], eax, dword 0, [file_size]
562
        cmp     ebx, [file_size]
563
 
564
        jne     .err_2
565
 
566
        mov     eax, [km_file]
567
        cmp     dword [eax], 0x4B43504B          ; check kpack signature
568
        jne     .raw_file
569
 
570
        mov     ebx, [eax+4]                     ;get real size of file
571
        mov     [file_size], ebx
4237 Serge 572
        stdcall user_alloc, ebx                  ;and allocate space from user heap
3786 Serge 573
        mov     [um_file], eax
574
        test    eax, eax
575
        jz      .err_2
576
 
4237 Serge 577
        mov     edx, [file_size]                 ;preallocate page memory
578
        shr     eax, 10
579
        lea     edi, [page_tabs+eax]
580
        add     edx, 4095
581
        shr     edx, 12
582
@@:
583
        call    alloc_page
584
        test    eax, eax
585
        jz      .err_3
586
 
587
        or      eax, PG_UW
588
        stosd
589
        dec     edx
590
        jnz     @B
591
 
3786 Serge 592
        pushad
593
        mov     ecx, unpack_mutex
594
        call    mutex_lock
595
 
596
        stdcall unpack, [km_file], [um_file]
597
 
598
        mov     ecx, unpack_mutex
599
        call    mutex_unlock
600
        popad
601
 
602
        stdcall kernel_free, [km_file]           ;we don't need packed file anymore
603
.exit:
4237 Serge 604
 
605
        mov     edi, [um_file]
606
        mov     esi, [um_file]
607
        mov     eax, [file_size]
608
        mov     edx, eax
609
 
610
        add     edi, eax                         ;cleanup remain space
611
        mov     ecx, 4096                        ;from file end
612
        and     eax, 4095
613
        jz      @f
614
        sub     ecx, eax
615
        xor     eax, eax
616
        cld
617
        rep stosb
618
@@:
3786 Serge 619
        mov     eax, [um_file]
620
 
621
        pop     ebx
622
        pop     edi
623
        pop     esi
624
        ret
625
 
626
.raw_file:                                       ; sometimes we load unpacked file
627
        stdcall user_alloc, ebx                  ; allocate space from user heap
628
        mov     [um_file], eax
629
 
630
        test    eax, eax
631
        jz      .err_2
632
 
633
        shr     eax, 10                          ; and remap pages.
634
 
635
        mov     ecx, [file_size]
636
        add     ecx, 4095
637
        shr     ecx, 12
638
 
639
        mov     esi, [km_file]
640
        shr     esi, 10
641
        add     esi, page_tabs
642
 
643
        lea     edi, [page_tabs+eax]
644
 
645
        cld
646
@@:
647
        lodsd
648
        and     eax, 0xFFFFF000
4237 Serge 649
        or      eax, PG_UW
3786 Serge 650
        stosd
651
        loop    @B
652
 
653
        stdcall free_kernel_space, [km_file]     ; release allocated kernel space
654
        jmp     .exit                            ; physical pages still in use
4237 Serge 655
.err_3:
656
        stdcall user_free, [um_file]
3786 Serge 657
.err_2:
658
        stdcall kernel_free, [km_file]
659
.err_1:
660
        xor     eax, eax
661
        xor     edx, edx
662
 
663
        pop     ebx
664
        pop     edi
665
        pop     esi
666
        ret
667
endp
668
 
669
 
2489 mario79 670
uglobal
2288 clevermous 671
align 4
2489 mario79 672
unpack_mutex MUTEX
2486 mario79 673
endg
674
 
675
align 4
3761 clevermous 676
proc get_proc_ex stdcall uses ebx esi, proc_name:dword, imports:dword
677
        mov     ebx, [imports]
678
        test    ebx, ebx
679
        jz      .end
680
        xor     esi, esi
2288 clevermous 681
.look_up:
682
 
3761 clevermous 683
        mov     eax, [ebx+32]
684
        mov     eax, [OS_BASE+eax+esi*4]
685
        add     eax, OS_BASE
2288 clevermous 686
        stdcall strncmp, eax, [proc_name], 256
687
        test    eax, eax
688
        jz      .ok
689
 
3761 clevermous 690
        inc     esi
691
        cmp     esi, [ebx+24]
692
        jb      .look_up
2288 clevermous 693
.end:
694
        xor     eax, eax
695
        ret
3761 clevermous 696
.ok:
697
        mov     eax, [ebx+28]
698
        mov     eax, [OS_BASE+eax+esi*4]
699
        add     eax, OS_BASE
700
        ret
2288 clevermous 701
endp
702
 
703
align 4
704
proc fix_coff_symbols stdcall uses ebx esi, sec:dword, symbols:dword,\
705
                      sym_count:dword, strings:dword, imports:dword
706
           locals
707
             retval dd ?
708
           endl
709
 
710
        mov     edi, [symbols]
711
        mov     [retval], 1
712
.fix:
2384 hidnplayr 713
        movzx   ebx, [edi+COFF_SYM.SectionNumber]
2288 clevermous 714
        test    ebx, ebx
715
        jnz     .internal
2384 hidnplayr 716
        mov     eax, dword [edi+COFF_SYM.Name]
2288 clevermous 717
        test    eax, eax
718
        jnz     @F
719
 
720
        mov     edi, [edi+4]
721
        add     edi, [strings]
722
@@:
723
        push    edi
724
        stdcall get_proc_ex, edi, [imports]
725
        pop     edi
726
 
727
        xor     ebx, ebx
728
        test    eax, eax
729
        jnz     @F
730
 
731
        mov     esi, msg_unresolved
732
        call    sys_msg_board_str
733
        mov     esi, edi
734
        call    sys_msg_board_str
735
        mov     esi, msg_CR
736
        call    sys_msg_board_str
737
 
738
        mov     [retval], 0
739
@@:
740
        mov     edi, [symbols]
2384 hidnplayr 741
        mov     [edi+COFF_SYM.Value], eax
2288 clevermous 742
        jmp     .next
743
.internal:
744
        cmp     bx, -1
745
        je      .next
746
        cmp     bx, -2
747
        je      .next
748
 
749
        dec     ebx
750
        shl     ebx, 3
751
        lea     ebx, [ebx+ebx*4]
752
        add     ebx, [sec]
753
 
2384 hidnplayr 754
        mov     eax, [ebx+COFF_SECTION.VirtualAddress]
755
        add     [edi+COFF_SYM.Value], eax
2288 clevermous 756
.next:
2384 hidnplayr 757
        add     edi, sizeof.COFF_SYM
2288 clevermous 758
        mov     [symbols], edi
759
        dec     [sym_count]
760
        jnz     .fix
761
        mov     eax, [retval]
762
        ret
763
endp
764
 
765
align 4
766
proc fix_coff_relocs stdcall uses ebx esi, coff:dword, sym:dword, \
767
        delta:dword
768
           locals
769
             n_sec     dd ?
770
           endl
771
 
772
        mov     eax, [coff]
2384 hidnplayr 773
        movzx   ebx, [eax+COFF_HEADER.nSections]
2288 clevermous 774
        mov     [n_sec], ebx
775
        lea     esi, [eax+20]
776
.fix_sec:
2384 hidnplayr 777
        mov     edi, [esi+COFF_SECTION.PtrReloc]
2288 clevermous 778
        add     edi, [coff]
779
 
2384 hidnplayr 780
        movzx   ecx, [esi+COFF_SECTION.NumReloc]
2288 clevermous 781
        test    ecx, ecx
782
        jz      .next
783
.reloc_loop:
2384 hidnplayr 784
        mov     ebx, [edi+COFF_RELOC.SymIndex]
2288 clevermous 785
        add     ebx, ebx
786
        lea     ebx, [ebx+ebx*8]
787
        add     ebx, [sym]
788
 
2384 hidnplayr 789
        mov     edx, [ebx+COFF_SYM.Value]
2288 clevermous 790
 
2384 hidnplayr 791
        cmp     [edi+COFF_RELOC.Type], 6
2288 clevermous 792
        je      .dir_32
793
 
2384 hidnplayr 794
        cmp     [edi+COFF_RELOC.Type], 20
2288 clevermous 795
        jne     .next_reloc
796
.rel_32:
2384 hidnplayr 797
        mov     eax, [edi+COFF_RELOC.VirtualAddress]
798
        add     eax, [esi+COFF_SECTION.VirtualAddress]
2288 clevermous 799
        sub     edx, eax
800
        sub     edx, 4
801
        jmp     .fix
802
.dir_32:
2384 hidnplayr 803
        mov     eax, [edi+COFF_RELOC.VirtualAddress]
804
        add     eax, [esi+COFF_SECTION.VirtualAddress]
2288 clevermous 805
.fix:
806
        add     eax, [delta]
807
        add     [eax], edx
808
.next_reloc:
809
        add     edi, 10
810
        dec     ecx
811
        jnz     .reloc_loop
812
.next:
2384 hidnplayr 813
        add     esi, sizeof.COFF_SECTION
2288 clevermous 814
        dec     [n_sec]
815
        jnz     .fix_sec
816
.exit:
817
        ret
818
endp
819
 
820
align 4
821
proc rebase_coff stdcall uses ebx esi, coff:dword, sym:dword, \
822
        delta:dword
823
           locals
824
             n_sec     dd ?
825
           endl
826
 
827
        mov     eax, [coff]
2384 hidnplayr 828
        movzx   ebx, [eax+COFF_HEADER.nSections]
2288 clevermous 829
        mov     [n_sec], ebx
830
        lea     esi, [eax+20]
831
        mov     edx, [delta]
832
.fix_sec:
2384 hidnplayr 833
        mov     edi, [esi+COFF_SECTION.PtrReloc]
2288 clevermous 834
        add     edi, [coff]
835
 
2384 hidnplayr 836
        movzx   ecx, [esi+COFF_SECTION.NumReloc]
2288 clevermous 837
        test    ecx, ecx
838
        jz      .next
839
.reloc_loop:
2384 hidnplayr 840
        cmp     [edi+COFF_RELOC.Type], 6
2288 clevermous 841
        jne     .next_reloc
842
.dir_32:
2384 hidnplayr 843
        mov     eax, [edi+COFF_RELOC.VirtualAddress]
844
        add     eax, [esi+COFF_SECTION.VirtualAddress]
2288 clevermous 845
        add     [eax+edx], edx
846
.next_reloc:
847
        add     edi, 10
848
        dec     ecx
849
        jnz     .reloc_loop
850
.next:
2384 hidnplayr 851
        add     esi, sizeof.COFF_SECTION
2288 clevermous 852
        dec     [n_sec]
853
        jnz     .fix_sec
854
.exit:
855
        ret
856
endp
857
 
858
align 4
859
proc load_driver stdcall, driver_name:dword
860
           locals
861
             coff      dd ?
862
             sym       dd ?
863
             strings   dd ?
864
             img_size  dd ?
865
             img_base  dd ?
866
             start     dd ?
867
 
868
             file_name rb 13+16+4+1      ; '/sys/drivers/.obj'
869
           endl
870
 
871
        lea     edx, [file_name]
872
        mov     dword [edx], '/sys'
873
        mov     dword [edx+4], '/dri'
874
        mov     dword [edx+8], 'vers'
875
        mov     byte [edx+12], '/'
876
        mov     esi, [driver_name]
877
.redo:
878
        lea     edx, [file_name]
879
        lea     edi, [edx+13]
880
        mov     ecx, 16
881
@@:
882
        lodsb
883
        test    al, al
884
        jz      @f
885
        stosb
886
        loop    @b
887
@@:
888
        mov     dword [edi], '.obj'
889
        mov     byte [edi+4], 0
890
        stdcall load_file, edx
891
 
892
        test    eax, eax
893
        jz      .exit
894
 
895
        mov     [coff], eax
896
 
2384 hidnplayr 897
        movzx   ecx, [eax+COFF_HEADER.nSections]
2288 clevermous 898
        xor     ebx, ebx
899
 
900
        lea     edx, [eax+20]
901
@@:
2384 hidnplayr 902
        add     ebx, [edx+COFF_SECTION.SizeOfRawData]
2288 clevermous 903
        add     ebx, 15
904
        and     ebx, not 15
2384 hidnplayr 905
        add     edx, sizeof.COFF_SECTION
2288 clevermous 906
        dec     ecx
907
        jnz     @B
908
        mov     [img_size], ebx
909
 
910
        stdcall kernel_alloc, ebx
911
        test    eax, eax
912
        jz      .fail
913
        mov     [img_base], eax
914
 
915
        mov     edi, eax
916
        xor     eax, eax
917
        mov     ecx, [img_size]
918
        add     ecx, 4095
919
        and     ecx, not 4095
920
        shr     ecx, 2
921
        cld
922
        rep stosd
923
 
924
        mov     edx, [coff]
2384 hidnplayr 925
        movzx   ebx, [edx+COFF_HEADER.nSections]
2288 clevermous 926
        mov     edi, [img_base]
927
        lea     eax, [edx+20]
928
@@:
2384 hidnplayr 929
        mov     [eax+COFF_SECTION.VirtualAddress], edi
930
        mov     esi, [eax+COFF_SECTION.PtrRawData]
2288 clevermous 931
        test    esi, esi
932
        jnz     .copy
2384 hidnplayr 933
        add     edi, [eax+COFF_SECTION.SizeOfRawData]
2288 clevermous 934
        jmp     .next
935
.copy:
936
        add     esi, edx
2384 hidnplayr 937
        mov     ecx, [eax+COFF_SECTION.SizeOfRawData]
2288 clevermous 938
        cld
939
        rep movsb
940
.next:
941
        add     edi, 15
942
        and     edi, not 15
2384 hidnplayr 943
        add     eax, sizeof.COFF_SECTION
2288 clevermous 944
        dec     ebx
945
        jnz     @B
946
 
2384 hidnplayr 947
        mov     ebx, [edx+COFF_HEADER.pSymTable]
2288 clevermous 948
        add     ebx, edx
949
        mov     [sym], ebx
2384 hidnplayr 950
        mov     ecx, [edx+COFF_HEADER.nSymbols]
2288 clevermous 951
        add     ecx, ecx
952
        lea     ecx, [ecx+ecx*8];ecx*=18 = nSymbols*CSYM_SIZE
953
        add     ecx, [sym]
954
        mov     [strings], ecx
955
 
956
        lea     eax, [edx+20]
957
 
2384 hidnplayr 958
        stdcall fix_coff_symbols, eax, [sym], [edx+COFF_HEADER.nSymbols], \
3761 clevermous 959
                [strings], __exports
2288 clevermous 960
        test    eax, eax
961
        jz      .link_fail
962
 
963
        mov     ebx, [coff]
964
        stdcall fix_coff_relocs, ebx, [sym], 0
965
 
2384 hidnplayr 966
        stdcall get_coff_sym, [sym], [ebx+COFF_HEADER.nSymbols], szVersion
2288 clevermous 967
        test    eax, eax
968
        jz      .link_fail
969
 
970
        mov     eax, [eax]
971
        shr     eax, 16
972
        cmp     eax, DRV_COMPAT
973
        jb      .ver_fail
974
 
975
        cmp     eax, DRV_CURRENT
976
        ja      .ver_fail
977
 
978
        mov     ebx, [coff]
2384 hidnplayr 979
        stdcall get_coff_sym, [sym], [ebx+COFF_HEADER.nSymbols], szSTART
2288 clevermous 980
        mov     [start], eax
981
 
982
        stdcall kernel_free, [coff]
983
 
984
        mov     ebx, [start]
985
        stdcall ebx, DRV_ENTRY
986
        test    eax, eax
987
        jnz     .ok
988
 
989
        stdcall kernel_free, [img_base]
3171 hidnplayr 990
 
2288 clevermous 991
        xor     eax, eax
992
        ret
993
.ok:
994
        mov     ebx, [img_base]
995
        mov     [eax+SRV.base], ebx
996
        mov     ecx, [start]
997
        mov     [eax+SRV.entry], ecx
998
        ret
999
 
1000
.ver_fail:
1001
        mov     esi, msg_CR
1002
        call    sys_msg_board_str
1003
        mov     esi, [driver_name]
1004
        call    sys_msg_board_str
1005
        mov     esi, msg_CR
1006
        call    sys_msg_board_str
1007
        mov     esi, msg_version
1008
        call    sys_msg_board_str
1009
        mov     esi, msg_www
1010
        call    sys_msg_board_str
1011
        jmp     .cleanup
1012
 
1013
.link_fail:
1014
        mov     esi, msg_module
1015
        call    sys_msg_board_str
1016
        mov     esi, [driver_name]
1017
        call    sys_msg_board_str
1018
        mov     esi, msg_CR
1019
        call    sys_msg_board_str
1020
.cleanup:
1021
        stdcall kernel_free, [img_base]
1022
.fail:
1023
        stdcall kernel_free, [coff]
1024
.exit:
1025
        xor     eax, eax
1026
        ret
1027
endp
1028
 
1029
; in: edx -> COFF_SECTION struct
1030
; out: eax = alignment as mask for bits to drop
1031
coff_get_align:
1032
; Rules:
1033
; - if alignment is not given, use default = 4K;
1034
; - if alignment is given and is no more than 4K, use it;
1035
; - if alignment is more than 4K, revert to 4K.
1036
        push    ecx
2384 hidnplayr 1037
        mov     cl, byte [edx+COFF_SECTION.Characteristics+2]
2288 clevermous 1038
        mov     eax, 1
1039
        shr     cl, 4
1040
        dec     cl
1041
        js      .default
1042
        cmp     cl, 12
1043
        jbe     @f
1044
.default:
1045
        mov     cl, 12
1046
@@:
1047
        shl     eax, cl
1048
        pop     ecx
1049
        dec     eax
1050
        ret
1051
 
1052
align 4
1053
proc load_library stdcall, file_name:dword
1054
           locals
1055
             fullname  rb 260
1056
             fileinfo  rb 40
1057
             coff      dd ?
1058
             img_base  dd ?
1059
           endl
1060
 
1061
; resolve file name
1062
        mov     ebx, [file_name]
1063
        lea     edi, [fullname+1]
1064
        mov     byte [edi-1], '/'
1065
        stdcall get_full_file_name, edi, 259
1066
        test    al, al
1067
        jz      .fail
1068
 
1069
; scan for required DLL in list of already loaded for this process,
1070
; ignore timestamp
3827 clevermous 1071
        cli
1072
 
2288 clevermous 1073
        mov     esi, [CURRENT_TASK]
1074
        shl     esi, 8
1075
        lea     edi, [fullname]
1076
        mov     ebx, [esi+SLOT_BASE+APPDATA.dlls_list_ptr]
1077
        test    ebx, ebx
1078
        jz      .not_in_process
1079
        mov     esi, [ebx+HDLL.fd]
1080
.scan_in_process:
1081
        cmp     esi, ebx
1082
        jz      .not_in_process
1083
        mov     eax, [esi+HDLL.parent]
1084
        add     eax, DLLDESCR.name
1085
        stdcall strncmp, eax, edi, -1
1086
        test    eax, eax
1087
        jnz     .next_in_process
1088
; simple variant: load DLL which is already loaded in this process
1089
; just increment reference counters and return address of exports table
1090
        inc     [esi+HDLL.refcount]
1091
        mov     ecx, [esi+HDLL.parent]
1092
        inc     [ecx+DLLDESCR.refcount]
1093
        mov     eax, [ecx+DLLDESCR.exports]
1094
        sub     eax, [ecx+DLLDESCR.defaultbase]
1095
        add     eax, [esi+HDLL.base]
3827 clevermous 1096
        sti
2288 clevermous 1097
        ret
1098
.next_in_process:
1099
        mov     esi, [esi+HDLL.fd]
1100
        jmp     .scan_in_process
1101
.not_in_process:
1102
 
1103
; scan in full list, compare timestamp
3827 clevermous 1104
        sti
2288 clevermous 1105
        lea     eax, [fileinfo]
1106
        stdcall get_fileinfo, edi, eax
1107
        test    eax, eax
1108
        jnz     .fail
3827 clevermous 1109
        cli
2288 clevermous 1110
        mov     esi, [dll_list.fd]
1111
.scan_for_dlls:
1112
        cmp     esi, dll_list
1113
        jz      .load_new
1114
        lea     eax, [esi+DLLDESCR.name]
1115
        stdcall strncmp, eax, edi, -1
1116
        test    eax, eax
1117
        jnz     .continue_scan
1118
.test_prev_dll:
1119
        mov     eax, dword [fileinfo+24]; last modified time
1120
        mov     edx, dword [fileinfo+28]; last modified date
1121
        cmp     dword [esi+DLLDESCR.timestamp], eax
1122
        jnz     .continue_scan
1123
        cmp     dword [esi+DLLDESCR.timestamp+4], edx
1124
        jz      .dll_already_loaded
1125
.continue_scan:
1126
        mov     esi, [esi+DLLDESCR.fd]
1127
        jmp     .scan_for_dlls
1128
 
1129
; new DLL
1130
.load_new:
3827 clevermous 1131
        sti
2288 clevermous 1132
; load file
1133
        stdcall load_file, edi
1134
        test    eax, eax
1135
        jz      .fail
1136
        mov     [coff], eax
1137
        mov     dword [fileinfo+32], ebx
1138
 
1139
; allocate DLLDESCR struct; size is DLLDESCR.sizeof plus size of DLL name
1140
        mov     esi, edi
1141
        mov     ecx, -1
1142
        xor     eax, eax
1143
        repnz scasb
1144
        not     ecx
2384 hidnplayr 1145
        lea     eax, [ecx+sizeof.DLLDESCR]
2288 clevermous 1146
        push    ecx
1147
        call    malloc
1148
        pop     ecx
1149
        test    eax, eax
1150
        jz      .fail_and_free_coff
1151
; save timestamp
1152
        lea     edi, [eax+DLLDESCR.name]
1153
        rep movsb
1154
        mov     esi, eax
1155
        mov     eax, dword [fileinfo+24]
1156
        mov     dword [esi+DLLDESCR.timestamp], eax
1157
        mov     eax, dword [fileinfo+28]
1158
        mov     dword [esi+DLLDESCR.timestamp+4], eax
1159
 
1160
; calculate size of loaded DLL
1161
        mov     edx, [coff]
2384 hidnplayr 1162
        movzx   ecx, [edx+COFF_HEADER.nSections]
2288 clevermous 1163
        xor     ebx, ebx
1164
 
1165
        add     edx, 20
1166
@@:
1167
        call    coff_get_align
1168
        add     ebx, eax
1169
        not     eax
1170
        and     ebx, eax
2384 hidnplayr 1171
        add     ebx, [edx+COFF_SECTION.SizeOfRawData]
1172
        add     edx, sizeof.COFF_SECTION
2288 clevermous 1173
        dec     ecx
1174
        jnz     @B
1175
; it must be nonzero and not too big
1176
        mov     [esi+DLLDESCR.size], ebx
1177
        test    ebx, ebx
1178
        jz      .fail_and_free_dll
1179
        cmp     ebx, MAX_DEFAULT_DLL_ADDR-MIN_DEFAULT_DLL_ADDR
1180
        ja      .fail_and_free_dll
1181
; allocate memory for kernel-side image
1182
        stdcall kernel_alloc, ebx
1183
        test    eax, eax
1184
        jz      .fail_and_free_dll
1185
        mov     [esi+DLLDESCR.data], eax
1186
; calculate preferred base address
1187
        add     ebx, 0x1FFF
1188
        and     ebx, not 0xFFF
1189
        mov     ecx, [dll_cur_addr]
1190
        lea     edx, [ecx+ebx]
1191
        cmp     edx, MAX_DEFAULT_DLL_ADDR
1192
        jb      @f
1193
        mov     ecx, MIN_DEFAULT_DLL_ADDR
1194
        lea     edx, [ecx+ebx]
1195
@@:
1196
        mov     [esi+DLLDESCR.defaultbase], ecx
1197
        mov     [dll_cur_addr], edx
1198
 
1199
; copy sections and set correct values for VirtualAddress'es in headers
1200
        push    esi
1201
        mov     edx, [coff]
2384 hidnplayr 1202
        movzx   ebx, [edx+COFF_HEADER.nSections]
2288 clevermous 1203
        mov     edi, eax
1204
        add     edx, 20
1205
        cld
1206
@@:
1207
        call    coff_get_align
1208
        add     ecx, eax
1209
        add     edi, eax
1210
        not     eax
1211
        and     ecx, eax
1212
        and     edi, eax
2384 hidnplayr 1213
        mov     [edx+COFF_SECTION.VirtualAddress], ecx
1214
        add     ecx, [edx+COFF_SECTION.SizeOfRawData]
1215
        mov     esi, [edx+COFF_SECTION.PtrRawData]
2288 clevermous 1216
        push    ecx
2384 hidnplayr 1217
        mov     ecx, [edx+COFF_SECTION.SizeOfRawData]
2288 clevermous 1218
        test    esi, esi
1219
        jnz     .copy
1220
        xor     eax, eax
1221
        rep stosb
1222
        jmp     .next
1223
.copy:
1224
        add     esi, [coff]
1225
        rep movsb
1226
.next:
1227
        pop     ecx
2384 hidnplayr 1228
        add     edx, sizeof.COFF_SECTION
2288 clevermous 1229
        dec     ebx
1230
        jnz     @B
1231
        pop     esi
1232
 
1233
; save some additional data from COFF file
1234
; later we will use COFF header, headers for sections and symbol table
1235
; and also relocations table for all sections
1236
        mov     edx, [coff]
2384 hidnplayr 1237
        mov     ebx, [edx+COFF_HEADER.pSymTable]
2288 clevermous 1238
        mov     edi, dword [fileinfo+32]
1239
        sub     edi, ebx
1240
        jc      .fail_and_free_data
1241
        mov     [esi+DLLDESCR.symbols_lim], edi
1242
        add     ebx, edx
2384 hidnplayr 1243
        movzx   ecx, [edx+COFF_HEADER.nSections]
2288 clevermous 1244
        lea     ecx, [ecx*5]
1245
        lea     edi, [edi+ecx*8+20]
1246
        add     edx, 20
1247
@@:
2384 hidnplayr 1248
        movzx   eax, [edx+COFF_SECTION.NumReloc]
2288 clevermous 1249
        lea     eax, [eax*5]
1250
        lea     edi, [edi+eax*2]
2384 hidnplayr 1251
        add     edx, sizeof.COFF_SECTION
2288 clevermous 1252
        sub     ecx, 5
1253
        jnz     @b
1254
        stdcall kernel_alloc, edi
1255
        test    eax, eax
1256
        jz      .fail_and_free_data
1257
        mov     edx, [coff]
2384 hidnplayr 1258
        movzx   ecx, [edx+COFF_HEADER.nSections]
2288 clevermous 1259
        lea     ecx, [ecx*5]
1260
        lea     ecx, [ecx*2+5]
1261
        mov     [esi+DLLDESCR.coff_hdr], eax
1262
        push    esi
1263
        mov     esi, edx
1264
        mov     edi, eax
1265
        rep movsd
1266
        pop     esi
1267
        mov     [esi+DLLDESCR.symbols_ptr], edi
1268
        push    esi
2384 hidnplayr 1269
        mov     ecx, [edx+COFF_HEADER.nSymbols]
2288 clevermous 1270
        mov     [esi+DLLDESCR.symbols_num], ecx
1271
        mov     ecx, [esi+DLLDESCR.symbols_lim]
1272
        mov     esi, ebx
1273
        rep movsb
1274
        pop     esi
1275
        mov     ebx, [esi+DLLDESCR.coff_hdr]
1276
        push    esi
2384 hidnplayr 1277
        movzx   eax, [edx+COFF_HEADER.nSections]
2288 clevermous 1278
        lea     edx, [ebx+20]
1279
@@:
2384 hidnplayr 1280
        movzx   ecx, [edx+COFF_SECTION.NumReloc]
2288 clevermous 1281
        lea     ecx, [ecx*5]
2384 hidnplayr 1282
        mov     esi, [edx+COFF_SECTION.PtrReloc]
1283
        mov     [edx+COFF_SECTION.PtrReloc], edi
1284
        sub     [edx+COFF_SECTION.PtrReloc], ebx
2288 clevermous 1285
        add     esi, [coff]
1286
        shr     ecx, 1
1287
        rep movsd
1288
        adc     ecx, ecx
1289
        rep movsw
2384 hidnplayr 1290
        add     edx, sizeof.COFF_SECTION
2288 clevermous 1291
        dec     eax
1292
        jnz     @b
1293
        pop     esi
1294
 
1295
; fixup symbols
1296
        mov     edx, ebx
2384 hidnplayr 1297
        mov     eax, [ebx+COFF_HEADER.nSymbols]
2288 clevermous 1298
        add     edx, 20
1299
        mov     ecx, [esi+DLLDESCR.symbols_num]
1300
        lea     ecx, [ecx*9]
1301
        add     ecx, ecx
1302
        add     ecx, [esi+DLLDESCR.symbols_ptr]
1303
 
1304
        stdcall fix_coff_symbols, edx, [esi+DLLDESCR.symbols_ptr], eax, \
1305
                ecx, 0
1306
;          test eax, eax
1307
;          jnz @F
1308
;
1309
;@@:
1310
 
2384 hidnplayr 1311
        stdcall get_coff_sym, [esi+DLLDESCR.symbols_ptr], [ebx+COFF_HEADER.nSymbols], szEXPORTS
2288 clevermous 1312
        test    eax, eax
1313
        jnz     @F
1314
 
2384 hidnplayr 1315
        stdcall get_coff_sym, [esi+DLLDESCR.symbols_ptr], [ebx+COFF_HEADER.nSymbols], sz_EXPORTS
2288 clevermous 1316
@@:
1317
        mov     [esi+DLLDESCR.exports], eax
1318
 
1319
; fix relocs in the hidden copy in kernel memory to default address
1320
; it is first fix; usually this will be enough, but second fix
1321
; can be necessary if real load address will not equal assumption
1322
        mov     eax, [esi+DLLDESCR.data]
1323
        sub     eax, [esi+DLLDESCR.defaultbase]
1324
        stdcall fix_coff_relocs, ebx, [esi+DLLDESCR.symbols_ptr], eax
1325
 
1326
        stdcall kernel_free, [coff]
1327
 
3827 clevermous 1328
        cli
1329
; initialize DLLDESCR struct
1330
        and     dword [esi+DLLDESCR.refcount], 0; no HDLLs yet; later it will be incremented
1331
        mov     [esi+DLLDESCR.fd], dll_list
1332
        mov     eax, [dll_list.bk]
1333
        mov     [dll_list.bk], esi
1334
        mov     [esi+DLLDESCR.bk], eax
1335
        mov     [eax+DLLDESCR.fd], esi
2288 clevermous 1336
.dll_already_loaded:
1337
        inc     [esi+DLLDESCR.refcount]
1338
        push    esi
1339
        call    init_heap
1340
        pop     esi
1341
 
1342
        mov     edi, [esi+DLLDESCR.size]
1343
        stdcall user_alloc_at, [esi+DLLDESCR.defaultbase], edi
1344
        test    eax, eax
1345
        jnz     @f
1346
        stdcall user_alloc, edi
1347
        test    eax, eax
1348
        jz      .fail_and_dereference
1349
@@:
1350
        mov     [img_base], eax
2384 hidnplayr 1351
        mov     eax, sizeof.HDLL
2288 clevermous 1352
        call    malloc
1353
        test    eax, eax
1354
        jz      .fail_and_free_user
1355
        mov     ebx, [CURRENT_TASK]
1356
        shl     ebx, 5
1357
        mov     edx, [CURRENT_TASK+ebx+TASKDATA.pid]
1358
        mov     [eax+HDLL.pid], edx
1359
        push    eax
1360
        call    init_dlls_in_thread
1361
        pop     ebx
1362
        test    eax, eax
1363
        jz      .fail_and_free_user
1364
        mov     edx, [eax+HDLL.fd]
1365
        mov     [ebx+HDLL.fd], edx
1366
        mov     [ebx+HDLL.bk], eax
1367
        mov     [eax+HDLL.fd], ebx
1368
        mov     [edx+HDLL.bk], ebx
1369
        mov     eax, ebx
1370
        mov     ebx, [img_base]
1371
        mov     [eax+HDLL.base], ebx
1372
        mov     [eax+HDLL.size], edi
1373
        mov     [eax+HDLL.refcount], 1
1374
        mov     [eax+HDLL.parent], esi
1375
        mov     edx, ebx
1376
        shr     edx, 12
1377
        or      dword [page_tabs+(edx-1)*4], DONT_FREE_BLOCK
1378
; copy entries of page table from kernel-side image to usermode
1379
; use copy-on-write for user-mode image, so map as readonly
1380
        xor     edi, edi
1381
        mov     ecx, [esi+DLLDESCR.data]
1382
        shr     ecx, 12
1383
.map_pages_loop:
1384
        mov     eax, [page_tabs+ecx*4]
1385
        and     eax, not 0xFFF
1386
        or      al, PG_USER
1387
        xchg    eax, [page_tabs+edx*4]
1388
        test    al, 1
1389
        jz      @f
1390
        call    free_page
1391
@@:
1392
        invlpg  [ebx+edi]
1393
        inc     ecx
1394
        inc     edx
1395
        add     edi, 0x1000
1396
        cmp     edi, [esi+DLLDESCR.size]
1397
        jb      .map_pages_loop
1398
 
1399
; if real user-mode base is not equal to preferred base, relocate image
1400
        sub     ebx, [esi+DLLDESCR.defaultbase]
1401
        jz      @f
1402
        stdcall rebase_coff, [esi+DLLDESCR.coff_hdr], [esi+DLLDESCR.symbols_ptr], ebx
1403
@@:
1404
 
1405
        mov     eax, [esi+DLLDESCR.exports]
1406
        sub     eax, [esi+DLLDESCR.defaultbase]
1407
        add     eax, [img_base]
3827 clevermous 1408
        sti
2288 clevermous 1409
        ret
1410
.fail_and_free_data:
1411
        stdcall kernel_free, [esi+DLLDESCR.data]
1412
.fail_and_free_dll:
1413
        mov     eax, esi
1414
        call    free
1415
.fail_and_free_coff:
1416
        stdcall kernel_free, [coff]
1417
.fail:
1418
        xor     eax, eax
1419
        ret
1420
.fail_and_free_user:
1421
        stdcall user_free, [img_base]
1422
.fail_and_dereference:
1423
        mov     eax, 1  ; delete 1 reference
1424
        call    dereference_dll
3827 clevermous 1425
        sti
2288 clevermous 1426
        xor     eax, eax
1427
        ret
1428
endp
1429
 
1430
; initialize [APPDATA.dlls_list_ptr] for given thread
1431
; DLL is per-process object, so APPDATA.dlls_list_ptr must be
1432
; kept in sync for all threads of one process.
1433
; out: eax = APPDATA.dlls_list_ptr if all is OK,
1434
; NULL if memory allocation failed
1435
init_dlls_in_thread:
1436
        mov     ebx, [current_slot]
1437
        mov     eax, [ebx+APPDATA.dlls_list_ptr]
1438
        test    eax, eax
1439
        jnz     .ret
1440
        push    [ebx+APPDATA.dir_table]
1441
        mov     eax, 8
1442
        call    malloc
1443
        pop     edx
1444
        test    eax, eax
1445
        jz      .ret
1446
        mov     [eax], eax
1447
        mov     [eax+4], eax
1448
        mov     ecx, [TASK_COUNT]
1449
        mov     ebx, SLOT_BASE+256
1450
.set:
1451
        cmp     [ebx+APPDATA.dir_table], edx
1452
        jnz     @f
1453
        mov     [ebx+APPDATA.dlls_list_ptr], eax
1454
@@:
1455
        add     ebx, 256
1456
        dec     ecx
1457
        jnz     .set
1458
.ret:
1459
        ret
1460
 
1461
; in: eax = number of references to delete, esi -> DLLDESCR struc
1462
dereference_dll:
1463
        sub     [esi+DLLDESCR.refcount], eax
1464
        jnz     .ret
1465
        mov     eax, [esi+DLLDESCR.fd]
1466
        mov     edx, [esi+DLLDESCR.bk]
1467
        mov     [eax+DLLDESCR.bk], edx
1468
        mov     [edx+DLLDESCR.fd], eax
1469
        stdcall kernel_free, [esi+DLLDESCR.coff_hdr]
1470
        stdcall kernel_free, [esi+DLLDESCR.data]
1471
        mov     eax, esi
1472
        call    free
1473
.ret:
1474
        ret
1475
 
1476
destroy_hdll:
1477
        push    ebx ecx esi edi
1478
        push    eax
1479
        mov     ebx, [eax+HDLL.base]
1480
        mov     esi, [eax+HDLL.parent]
1481
        mov     edx, [esi+DLLDESCR.size]
1482
; The following actions require the context of application where HDLL is mapped.
1483
; However, destroy_hdll can be called in the context of OS thread when
1484
; cleaning up objects created by the application which is destroyed.
1485
; So remember current cr3 and set it to page table of target.
1486
        mov     eax, [ecx+APPDATA.dir_table]
1487
; Because we cheat with cr3, disable interrupts: task switch would restore
1488
; page table from APPDATA of current thread.
1489
; Also set [current_slot] because it is used by user_free.
1490
        pushf
1491
        cli
1492
        push    [current_slot]
1493
        mov     [current_slot], ecx
1494
        mov     ecx, cr3
1495
        push    ecx
1496
        mov     cr3, eax
1497
        push    ebx     ; argument for user_free
1498
        mov     eax, ebx
1499
        shr     ebx, 12
1500
        push    ebx
1501
        mov     esi, [esi+DLLDESCR.data]
1502
        shr     esi, 12
1503
.unmap_loop:
1504
        push    eax
1505
        mov     eax, 2
1506
        xchg    eax, [page_tabs+ebx*4]
1507
        mov     ecx, [page_tabs+esi*4]
1508
        and     eax, not 0xFFF
1509
        and     ecx, not 0xFFF
1510
        cmp     eax, ecx
1511
        jz      @f
1512
        call    free_page
1513
@@:
1514
        pop     eax
1515
        invlpg  [eax]
1516
        add     eax, 0x1000
1517
        inc     ebx
1518
        inc     esi
1519
        sub     edx, 0x1000
1520
        ja      .unmap_loop
1521
        pop     ebx
1522
        and     dword [page_tabs+(ebx-1)*4], not DONT_FREE_BLOCK
1523
        call    user_free
1524
; Restore context.
1525
        pop     eax
1526
        mov     cr3, eax
1527
        pop     [current_slot]
1528
        popf
1529
; Ok, cheating is done.
1530
        pop     eax
1531
        push    eax
1532
        mov     esi, [eax+HDLL.parent]
1533
        mov     eax, [eax+HDLL.refcount]
1534
        call    dereference_dll
1535
        pop     eax
1536
        mov     edx, [eax+HDLL.bk]
1537
        mov     ebx, [eax+HDLL.fd]
1538
        mov     [ebx+HDLL.bk], edx
1539
        mov     [edx+HDLL.fd], ebx
1540
        call    free
1541
        pop     edi esi ecx ebx
1542
        ret
1543
 
1544
; ecx -> APPDATA for slot, esi = dlls_list_ptr
1545
destroy_all_hdlls:
1546
        test    esi, esi
1547
        jz      .ret
1548
.loop:
1549
        mov     eax, [esi+HDLL.fd]
1550
        cmp     eax, esi
1551
        jz      free
1552
        call    destroy_hdll
1553
        jmp     .loop
1554
.ret:
1555
        ret
1556
 
1557
align 4
1558
stop_all_services:
1559
        push    ebp
1560
        mov     edx, [srv.fd]
1561
.next:
2384 hidnplayr 1562
        cmp     edx, srv.fd-SRV.fd
2288 clevermous 1563
        je      .done
1564
        cmp     [edx+SRV.magic], ' SRV'
1565
        jne     .next
2384 hidnplayr 1566
        cmp     [edx+SRV.size], sizeof.SRV
2288 clevermous 1567
        jne     .next
1568
 
1569
        mov     ebx, [edx+SRV.entry]
1570
        mov     edx, [edx+SRV.fd]
1571
        test    ebx, ebx
1572
        jz      .next
1573
 
1574
        push    edx
1575
        mov     ebp, esp
1576
        push    0
1577
        push    -1
1578
        call    ebx
1579
        mov     esp, ebp
1580
        pop     edx
1581
        jmp     .next
1582
.done:
1583
        pop     ebp
1584
        ret
1585
 
1586
; param
1587
;  eax= size
1588
;  ebx= pid
1589
 
1590
align 4
1591
create_kernel_object:
1592
 
1593
        push    ebx
1594
        call    malloc
1595
        pop     ebx
1596
        test    eax, eax
1597
        jz      .fail
1598
 
1599
        mov     ecx, [current_slot]
1600
        add     ecx, APP_OBJ_OFFSET
1601
 
1602
        pushfd
1603
        cli
1604
        mov     edx, [ecx+APPOBJ.fd]
1605
        mov     [eax+APPOBJ.fd], edx
1606
        mov     [eax+APPOBJ.bk], ecx
1607
        mov     [eax+APPOBJ.pid], ebx
1608
 
1609
        mov     [ecx+APPOBJ.fd], eax
1610
        mov     [edx+APPOBJ.bk], eax
1611
        popfd
1612
.fail:
1613
        ret
1614
 
1615
; param
1616
;  eax= object
1617
 
1618
align 4
1619
destroy_kernel_object:
1620
 
1621
        pushfd
1622
        cli
1623
        mov     ebx, [eax+APPOBJ.fd]
1624
        mov     ecx, [eax+APPOBJ.bk]
1625
        mov     [ebx+APPOBJ.bk], ecx
1626
        mov     [ecx+APPOBJ.fd], ebx
1627
        popfd
1628
 
1629
        xor     edx, edx       ;clear common header
1630
        mov     [eax], edx
1631
        mov     [eax+4], edx
1632
        mov     [eax+8], edx
1633
        mov     [eax+12], edx
1634
        mov     [eax+16], edx
1635
 
1636
        call    free           ;release object memory
1637
        ret