Subversion Repositories Kolibri OS

Rev

Rev 9047 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2288 clevermous 1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                              ;;
7965 hidnplayr 3
;; Copyright (C) KolibriOS team 2004-2020. All rights reserved. ;;
6502 pathoswith 4
;;  Distributed under terms of the GNU General Public License.  ;;
2288 clevermous 5
;;                                                              ;;
6
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
7
 
8
$Revision: 9048 $
9
 
10
 
7136 dunkaist 11
DRV_COMPAT   =  5  ;minimal required drivers version
12
DRV_CURRENT  =  6  ;current drivers model version
2288 clevermous 13
 
7136 dunkaist 14
DRV_VERSION = (DRV_COMPAT shl 16) or DRV_CURRENT
15
PID_KERNEL  = 1    ;os_idle thread
2288 clevermous 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
5088 clevermous 212
        mov     eax, edx
213
        je      .nothing
2288 clevermous 214
 
215
        mov     edx, [edx+SRV.fd]
216
        jmp     @B
217
.not_load:
4418 clevermous 218
        mov     eax, [sz_name]
219
        push    edi
220
        sub     esp, 36
221
        mov     edi, esp
222
        mov     dword [edi], '/sys'
223
        mov     dword [edi+4], '/dri'
224
        mov     dword [edi+8], 'vers'
225
        mov     byte [edi+12], '/'
226
@@:
227
        mov     dl, [eax]
228
        mov     [edi+13], dl
229
        inc     eax
230
        inc     edi
231
        test    dl, dl
232
        jnz     @b
233
        mov     dword [edi+12], '.sys'
234
        mov     byte [edi+16], 0
235
        mov     edi, esp
236
        stdcall load_pe_driver, edi, 0
237
        add     esp, 36
238
        pop     edi
239
.nothing:
2288 clevermous 240
        ret
241
endp
242
 
3520 clevermous 243
reg_service:
244
        xor     eax, eax
245
        mov     ecx, [esp+8]
246
        jecxz   .nothing
247
        push    sizeof.SRV
248
        push    ecx
249
        pushd   [esp+12]
250
        call    reg_service_ex
251
.nothing:
252
        ret     8
2288 clevermous 253
 
3520 clevermous 254
reg_usb_driver:
255
        push    sizeof.USBSRV
256
        pushd   [esp+12]
257
        pushd   [esp+12]
258
        call    reg_service_ex
259
        test    eax, eax
260
        jz      .nothing
261
        mov     ecx, [esp+12]
262
        mov     [eax+USBSRV.usb_func], ecx
263
.nothing:
264
        ret     12
265
 
266
proc reg_service_ex stdcall, name:dword, handler:dword, srvsize:dword
267
 
2288 clevermous 268
        push    ebx
269
 
270
        xor     eax, eax
271
 
272
        cmp     [name], eax
273
        je      .fail
274
 
3520 clevermous 275
;        cmp     [handler], eax
276
;        je      .fail
2288 clevermous 277
 
3520 clevermous 278
        mov     eax, [srvsize]
2288 clevermous 279
        call    malloc
280
        test    eax, eax
281
        jz      .fail
282
 
283
        push    esi
284
        push    edi
285
        mov     edi, eax
286
        mov     esi, [name]
287
        movsd
288
        movsd
289
        movsd
290
        movsd
291
        pop     edi
292
        pop     esi
293
 
294
        mov     [eax+SRV.magic], ' SRV'
2384 hidnplayr 295
        mov     [eax+SRV.size], sizeof.SRV
2288 clevermous 296
 
2384 hidnplayr 297
        mov     ebx, srv.fd-SRV.fd
2288 clevermous 298
        mov     edx, [ebx+SRV.fd]
299
        mov     [eax+SRV.fd], edx
300
        mov     [eax+SRV.bk], ebx
301
        mov     [ebx+SRV.fd], eax
302
        mov     [edx+SRV.bk], eax
303
 
304
        mov     ecx, [handler]
305
        mov     [eax+SRV.srv_proc], ecx
306
        pop     ebx
307
        ret
308
.fail:
309
        xor     eax, eax
310
        pop     ebx
311
        ret
312
endp
313
 
314
align 4
315
proc get_proc stdcall, exp:dword, sz_name:dword
316
 
317
        mov     edx, [exp]
318
.next:
319
        mov     eax, [edx]
320
        test    eax, eax
321
        jz      .end
322
 
323
        push    edx
324
        stdcall strncmp, eax, [sz_name], 16
325
        pop     edx
326
        test    eax, eax
327
        jz      .ok
328
 
329
        add     edx, 8
330
        jmp     .next
331
.ok:
332
        mov     eax, [edx+4]
333
.end:
334
        ret
335
endp
336
 
337
align 4
338
proc get_coff_sym stdcall, pSym:dword,count:dword, sz_sym:dword
339
 
340
@@:
341
        stdcall strncmp, [pSym], [sz_sym], 8
342
        test    eax, eax
343
        jz      .ok
344
        add     [pSym], 18
345
        dec     [count]
346
        jnz     @b
347
        xor     eax, eax
348
        ret
349
.ok:
350
        mov     eax, [pSym]
351
        mov     eax, [eax+8]
352
        ret
353
endp
354
 
355
align 4
356
proc get_curr_task
8869 rgimad 357
        mov     eax, [current_slot_idx]
2288 clevermous 358
        shl     eax, 8
359
        ret
360
endp
361
 
362
align 4
363
proc get_fileinfo stdcall, file_name:dword, info:dword
364
           locals
365
             cmd     dd ?
366
             offset  dd ?
367
                     dd ?
368
             count   dd ?
369
             buff    dd ?
370
                     db ?
371
             name    dd ?
372
           endl
373
 
374
        xor     eax, eax
375
        mov     ebx, [file_name]
376
        mov     ecx, [info]
377
 
378
        mov     [cmd], 5
379
        mov     [offset], eax
380
        mov     [offset+4], eax
381
        mov     [count], eax
382
        mov     [buff], ecx
383
        mov     byte [buff+4], al
384
        mov     [name], ebx
385
 
386
        mov     eax, 70
387
        lea     ebx, [cmd]
8680 rgimad 388
        pushad
389
        cld
390
        call    protect_from_terminate
391
        call    file_system_lfn
392
        call    unprotect_from_terminate
393
        popad
2288 clevermous 394
        ret
395
endp
396
 
397
align 4
398
proc read_file stdcall,file_name:dword, buffer:dword, off:dword,\
399
                                     bytes:dword
400
           locals
401
             cmd     dd ?
402
             offset  dd ?
403
                     dd ?
404
             count   dd ?
405
             buff    dd ?
406
                     db ?
407
             name    dd ?
408
           endl
409
 
410
        xor     eax, eax
411
        mov     ebx, [file_name]
412
        mov     ecx, [off]
413
        mov     edx, [bytes]
414
        mov     esi, [buffer]
415
 
416
        mov     [cmd], eax
417
        mov     [offset], ecx
418
        mov     [offset+4], eax
419
        mov     [count], edx
420
        mov     [buff], esi
421
        mov     byte [buff+4], al
422
        mov     [name], ebx
423
 
424
        pushad
425
        lea     ebx, [cmd]
3296 clevermous 426
        call    file_system_lfn_protected
2288 clevermous 427
        popad
428
        ret
429
endp
430
 
9034 Boppan 431
align 4
432
; @brief Allocate kernel memory and loads the specified file
2288 clevermous 433
;
9034 Boppan 434
; @param file_name Path to file
2288 clevermous 435
;
9034 Boppan 436
; @returns File image in kernel memory in `eax` and size of file in `ebx`
2288 clevermous 437
;
9034 Boppan 438
; @warning You must call kernel_free() to delete each file loaded by the
439
;          load_file() function
2288 clevermous 440
proc load_file stdcall, file_name:dword
441
           locals
442
             attr       dd ?
443
             flags      dd ?
444
             cr_time    dd ?
445
             cr_date    dd ?
446
             acc_time   dd ?
447
             acc_date   dd ?
448
             mod_time   dd ?
449
             mod_date   dd ?
450
             file_size  dd ?
451
 
452
             file       dd ?
453
             file2      dd ?
454
           endl
455
 
456
        push    esi
457
        push    edi
458
 
459
        lea     eax, [attr]
460
        stdcall get_fileinfo, [file_name], eax
461
        test    eax, eax
462
        jnz     .fail
463
 
464
        mov     eax, [file_size]
465
        cmp     eax, 1024*1024*16
466
        ja      .fail
467
 
468
        stdcall kernel_alloc, [file_size]
469
        mov     [file], eax
470
        test    eax, eax
471
        jz      .fail
472
 
473
        stdcall read_file, [file_name], eax, dword 0, [file_size]
474
        cmp     ebx, [file_size]
475
        jne     .cleanup
476
 
477
        mov     eax, [file]
7122 dunkaist 478
        cmp     dword [eax], 'KPCK'
2288 clevermous 479
        jne     .exit
480
        mov     ebx, [eax+4]
481
        mov     [file_size], ebx
482
        stdcall kernel_alloc, ebx
483
 
484
        test    eax, eax
485
        jz      .cleanup
486
 
487
        mov     [file2], eax
2486 mario79 488
 
2500 mario79 489
        pushad
2489 mario79 490
        mov     ecx, unpack_mutex
491
        call    mutex_lock
2500 mario79 492
        popad
2486 mario79 493
 
2288 clevermous 494
        stdcall unpack, [file], eax
2486 mario79 495
 
2500 mario79 496
        pushad
497
        mov     ecx, unpack_mutex
2489 mario79 498
        call    mutex_unlock
2500 mario79 499
        popad
2486 mario79 500
 
2288 clevermous 501
        stdcall kernel_free, [file]
502
        mov     eax, [file2]
503
        mov     ebx, [file_size]
504
.exit:
505
        push    eax
506
        lea     edi, [eax+ebx]    ;cleanup remain space
507
        mov     ecx, 4096         ;from file end
508
        and     ebx, 4095
509
        jz      @f
510
        sub     ecx, ebx
511
        xor     eax, eax
512
        cld
513
        rep stosb
514
@@:
515
        mov     ebx, [file_size]
516
        pop     eax
517
        pop     edi
518
        pop     esi
519
        ret
520
.cleanup:
521
        stdcall kernel_free, [file]
522
.fail:
523
        xor     eax, eax
524
        xor     ebx, ebx
525
        pop     edi
526
        pop     esi
527
        ret
528
endp
529
 
3786 Serge 530
; description
531
;  allocate user memory and loads the specified file
532
;
533
; param
534
;  file_name= path to file
535
;
536
; retval
537
;  eax= file image in user memory
538
;  ebx= size of file
539
;
540
; warging
541
;  You mast call kernel_free() to delete each file
542
;  loaded by the load_file() function
543
 
544
align 4
545
proc load_file_umode stdcall, file_name:dword
546
           locals
547
             attr       dd ?
548
             flags      dd ?
549
             cr_time    dd ?
550
             cr_date    dd ?
551
             acc_time   dd ?
552
             acc_date   dd ?
553
             mod_time   dd ?
554
             mod_date   dd ?
555
             file_size  dd ?
556
 
557
             km_file    dd ?
558
             um_file    dd ?
559
           endl
560
 
561
        push    esi
562
        push    edi
563
        push    ebx
564
 
565
        lea     eax, [attr]
566
        stdcall get_fileinfo, [file_name], eax   ;find file and get info
567
        test    eax, eax
568
        jnz     .err_1
569
 
570
        mov     eax, [file_size]
571
        cmp     eax, 1024*1024*16                ;to be enough for anybody (c)
572
        ja      .err_1
573
                                                 ;it is very likely that the file is packed
574
        stdcall kernel_alloc, [file_size]        ;with kpack, so allocate memory from kernel heap
575
        mov     [km_file], eax
576
        test    eax, eax
577
        jz      .err_1
578
 
579
        stdcall read_file, [file_name], eax, dword 0, [file_size]
580
        cmp     ebx, [file_size]
581
 
582
        jne     .err_2
583
 
584
        mov     eax, [km_file]
7122 dunkaist 585
        cmp     dword [eax], 'KPCK'              ; check kpack signature
3786 Serge 586
        jne     .raw_file
587
 
588
        mov     ebx, [eax+4]                     ;get real size of file
589
        mov     [file_size], ebx
4237 Serge 590
        stdcall user_alloc, ebx                  ;and allocate space from user heap
3786 Serge 591
        mov     [um_file], eax
592
        test    eax, eax
593
        jz      .err_2
594
 
4237 Serge 595
        mov     edx, [file_size]                 ;preallocate page memory
596
        shr     eax, 10
597
        lea     edi, [page_tabs+eax]
598
        add     edx, 4095
599
        shr     edx, 12
600
@@:
601
        call    alloc_page
602
        test    eax, eax
603
        jz      .err_3
604
 
5356 serge 605
        or      eax, PG_UWR
4237 Serge 606
        stosd
607
        dec     edx
608
        jnz     @B
609
 
3786 Serge 610
        pushad
611
        mov     ecx, unpack_mutex
612
        call    mutex_lock
613
 
614
        stdcall unpack, [km_file], [um_file]
615
 
616
        mov     ecx, unpack_mutex
617
        call    mutex_unlock
618
        popad
619
 
620
        stdcall kernel_free, [km_file]           ;we don't need packed file anymore
621
.exit:
4237 Serge 622
 
623
        mov     edi, [um_file]
624
        mov     esi, [um_file]
625
        mov     eax, [file_size]
626
        mov     edx, eax
627
 
628
        add     edi, eax                         ;cleanup remain space
629
        mov     ecx, 4096                        ;from file end
630
        and     eax, 4095
631
        jz      @f
632
        sub     ecx, eax
633
        xor     eax, eax
634
        cld
635
        rep stosb
636
@@:
3786 Serge 637
        mov     eax, [um_file]
638
 
639
        pop     ebx
640
        pop     edi
641
        pop     esi
642
        ret
643
 
644
.raw_file:                                       ; sometimes we load unpacked file
645
        stdcall user_alloc, ebx                  ; allocate space from user heap
646
        mov     [um_file], eax
647
 
648
        test    eax, eax
649
        jz      .err_2
650
 
651
        shr     eax, 10                          ; and remap pages.
652
 
653
        mov     ecx, [file_size]
654
        add     ecx, 4095
655
        shr     ecx, 12
656
 
657
        mov     esi, [km_file]
658
        shr     esi, 10
659
        add     esi, page_tabs
660
 
661
        lea     edi, [page_tabs+eax]
662
 
663
        cld
664
@@:
665
        lodsd
666
        and     eax, 0xFFFFF000
5356 serge 667
        or      eax, PG_UWR
3786 Serge 668
        stosd
669
        loop    @B
670
 
671
        stdcall free_kernel_space, [km_file]     ; release allocated kernel space
672
        jmp     .exit                            ; physical pages still in use
4237 Serge 673
.err_3:
674
        stdcall user_free, [um_file]
3786 Serge 675
.err_2:
676
        stdcall kernel_free, [km_file]
677
.err_1:
678
        xor     eax, eax
679
        xor     edx, edx
680
 
681
        pop     ebx
682
        pop     edi
683
        pop     esi
684
        ret
685
endp
686
 
687
 
2489 mario79 688
uglobal
2288 clevermous 689
align 4
2489 mario79 690
unpack_mutex MUTEX
2486 mario79 691
endg
692
 
693
align 4
3761 clevermous 694
proc get_proc_ex stdcall uses ebx esi, proc_name:dword, imports:dword
695
        mov     ebx, [imports]
696
        test    ebx, ebx
697
        jz      .end
698
        xor     esi, esi
2288 clevermous 699
.look_up:
700
 
3761 clevermous 701
        mov     eax, [ebx+32]
702
        mov     eax, [OS_BASE+eax+esi*4]
703
        add     eax, OS_BASE
2288 clevermous 704
        stdcall strncmp, eax, [proc_name], 256
705
        test    eax, eax
706
        jz      .ok
707
 
3761 clevermous 708
        inc     esi
709
        cmp     esi, [ebx+24]
710
        jb      .look_up
2288 clevermous 711
.end:
712
        xor     eax, eax
713
        ret
3761 clevermous 714
.ok:
715
        mov     eax, [ebx+28]
716
        mov     eax, [OS_BASE+eax+esi*4]
717
        add     eax, OS_BASE
718
        ret
2288 clevermous 719
endp
720
 
721
align 4
722
proc fix_coff_symbols stdcall uses ebx esi, sec:dword, symbols:dword,\
723
                      sym_count:dword, strings:dword, imports:dword
724
           locals
725
             retval dd ?
726
           endl
727
 
728
        mov     edi, [symbols]
729
        mov     [retval], 1
730
.fix:
2384 hidnplayr 731
        movzx   ebx, [edi+COFF_SYM.SectionNumber]
2288 clevermous 732
        test    ebx, ebx
733
        jnz     .internal
2384 hidnplayr 734
        mov     eax, dword [edi+COFF_SYM.Name]
2288 clevermous 735
        test    eax, eax
736
        jnz     @F
737
 
738
        mov     edi, [edi+4]
739
        add     edi, [strings]
740
@@:
741
        push    edi
742
        stdcall get_proc_ex, edi, [imports]
743
        pop     edi
744
 
745
        xor     ebx, ebx
746
        test    eax, eax
747
        jnz     @F
748
 
5998 veliant 749
        ; disable debug msg
750
        ;mov     esi, msg_unresolved
751
        ;call    sys_msg_board_str
752
        ;mov     esi, edi
753
        ;call    sys_msg_board_str
754
        ;mov     esi, msg_CR
755
        ;call    sys_msg_board_str
2288 clevermous 756
 
757
        mov     [retval], 0
758
@@:
759
        mov     edi, [symbols]
2384 hidnplayr 760
        mov     [edi+COFF_SYM.Value], eax
2288 clevermous 761
        jmp     .next
762
.internal:
763
        cmp     bx, -1
764
        je      .next
765
        cmp     bx, -2
766
        je      .next
767
 
768
        dec     ebx
769
        shl     ebx, 3
770
        lea     ebx, [ebx+ebx*4]
771
        add     ebx, [sec]
772
 
2384 hidnplayr 773
        mov     eax, [ebx+COFF_SECTION.VirtualAddress]
774
        add     [edi+COFF_SYM.Value], eax
2288 clevermous 775
.next:
2384 hidnplayr 776
        add     edi, sizeof.COFF_SYM
2288 clevermous 777
        mov     [symbols], edi
778
        dec     [sym_count]
779
        jnz     .fix
780
        mov     eax, [retval]
781
        ret
782
endp
783
 
784
align 4
785
proc fix_coff_relocs stdcall uses ebx esi, coff:dword, sym:dword, \
786
        delta:dword
787
           locals
788
             n_sec     dd ?
789
           endl
790
 
791
        mov     eax, [coff]
2384 hidnplayr 792
        movzx   ebx, [eax+COFF_HEADER.nSections]
2288 clevermous 793
        mov     [n_sec], ebx
794
        lea     esi, [eax+20]
795
.fix_sec:
2384 hidnplayr 796
        mov     edi, [esi+COFF_SECTION.PtrReloc]
2288 clevermous 797
        add     edi, [coff]
798
 
2384 hidnplayr 799
        movzx   ecx, [esi+COFF_SECTION.NumReloc]
2288 clevermous 800
        test    ecx, ecx
801
        jz      .next
802
.reloc_loop:
2384 hidnplayr 803
        mov     ebx, [edi+COFF_RELOC.SymIndex]
2288 clevermous 804
        add     ebx, ebx
805
        lea     ebx, [ebx+ebx*8]
806
        add     ebx, [sym]
807
 
2384 hidnplayr 808
        mov     edx, [ebx+COFF_SYM.Value]
2288 clevermous 809
 
2384 hidnplayr 810
        cmp     [edi+COFF_RELOC.Type], 6
2288 clevermous 811
        je      .dir_32
812
 
2384 hidnplayr 813
        cmp     [edi+COFF_RELOC.Type], 20
2288 clevermous 814
        jne     .next_reloc
815
.rel_32:
2384 hidnplayr 816
        mov     eax, [edi+COFF_RELOC.VirtualAddress]
817
        add     eax, [esi+COFF_SECTION.VirtualAddress]
2288 clevermous 818
        sub     edx, eax
819
        sub     edx, 4
820
        jmp     .fix
821
.dir_32:
2384 hidnplayr 822
        mov     eax, [edi+COFF_RELOC.VirtualAddress]
823
        add     eax, [esi+COFF_SECTION.VirtualAddress]
2288 clevermous 824
.fix:
825
        add     eax, [delta]
826
        add     [eax], edx
827
.next_reloc:
828
        add     edi, 10
829
        dec     ecx
830
        jnz     .reloc_loop
831
.next:
2384 hidnplayr 832
        add     esi, sizeof.COFF_SECTION
2288 clevermous 833
        dec     [n_sec]
834
        jnz     .fix_sec
835
.exit:
836
        ret
837
endp
838
 
839
align 4
840
proc rebase_coff stdcall uses ebx esi, coff:dword, sym:dword, \
841
        delta:dword
842
           locals
843
             n_sec     dd ?
844
           endl
845
 
846
        mov     eax, [coff]
2384 hidnplayr 847
        movzx   ebx, [eax+COFF_HEADER.nSections]
2288 clevermous 848
        mov     [n_sec], ebx
849
        lea     esi, [eax+20]
850
        mov     edx, [delta]
851
.fix_sec:
2384 hidnplayr 852
        mov     edi, [esi+COFF_SECTION.PtrReloc]
2288 clevermous 853
        add     edi, [coff]
854
 
2384 hidnplayr 855
        movzx   ecx, [esi+COFF_SECTION.NumReloc]
2288 clevermous 856
        test    ecx, ecx
857
        jz      .next
858
.reloc_loop:
2384 hidnplayr 859
        cmp     [edi+COFF_RELOC.Type], 6
2288 clevermous 860
        jne     .next_reloc
861
.dir_32:
2384 hidnplayr 862
        mov     eax, [edi+COFF_RELOC.VirtualAddress]
863
        add     eax, [esi+COFF_SECTION.VirtualAddress]
2288 clevermous 864
        add     [eax+edx], edx
865
.next_reloc:
866
        add     edi, 10
867
        dec     ecx
868
        jnz     .reloc_loop
869
.next:
2384 hidnplayr 870
        add     esi, sizeof.COFF_SECTION
2288 clevermous 871
        dec     [n_sec]
872
        jnz     .fix_sec
873
.exit:
874
        ret
875
endp
876
 
877
; in: edx -> COFF_SECTION struct
878
; out: eax = alignment as mask for bits to drop
879
coff_get_align:
880
; Rules:
881
; - if alignment is not given, use default = 4K;
882
; - if alignment is given and is no more than 4K, use it;
883
; - if alignment is more than 4K, revert to 4K.
884
        push    ecx
2384 hidnplayr 885
        mov     cl, byte [edx+COFF_SECTION.Characteristics+2]
2288 clevermous 886
        mov     eax, 1
887
        shr     cl, 4
888
        dec     cl
889
        js      .default
890
        cmp     cl, 12
891
        jbe     @f
892
.default:
893
        mov     cl, 12
894
@@:
895
        shl     eax, cl
896
        pop     ecx
897
        dec     eax
898
        ret
899
 
900
align 4
6792 pathoswith 901
proc load_library stdcall, file_name:dword, encoding:dword
6502 pathoswith 902
    locals
903
        fullname    dd  ?
9048 Boppan 904
        filesize    dd  ?
6502 pathoswith 905
        coff        dd  ?
906
        img_base    dd  ?
9048 Boppan 907
        img_size    dd  ?
908
        symbols_ptr dd  ?
909
        symbols_lim dd  ?
910
        exports     dd  ?
6502 pathoswith 911
    endl
2288 clevermous 912
 
913
; resolve file name
6502 pathoswith 914
        stdcall kernel_alloc, maxPathLength
915
        mov     [fullname], eax
6792 pathoswith 916
        mov     edi, eax
917
        mov     esi, [file_name]
918
        mov     eax, [encoding]
919
        push    ebp
920
        call    getFullPath
921
        pop     ebp
6502 pathoswith 922
        test    eax, eax
2288 clevermous 923
        jz      .fail
6502 pathoswith 924
 
2288 clevermous 925
; load file
9048 Boppan 926
        stdcall load_file, [fullname]
2288 clevermous 927
        test    eax, eax
928
        jz      .fail
929
        mov     [coff], eax
9048 Boppan 930
        mov     [filesize], ebx
2288 clevermous 931
 
932
; calculate size of loaded DLL
9048 Boppan 933
        movzx   ecx, [eax+COFF_HEADER.nSections]
2288 clevermous 934
        xor     ebx, ebx
935
 
9048 Boppan 936
        lea     edx, [eax+20]
2288 clevermous 937
@@:
938
        call    coff_get_align
939
        add     ebx, eax
940
        not     eax
941
        and     ebx, eax
2384 hidnplayr 942
        add     ebx, [edx+COFF_SECTION.SizeOfRawData]
943
        add     edx, sizeof.COFF_SECTION
2288 clevermous 944
        dec     ecx
945
        jnz     @B
946
; it must be nonzero and not too big
9048 Boppan 947
        mov     [img_size], ebx
2288 clevermous 948
        test    ebx, ebx
9048 Boppan 949
        jz      .fail_and_free_coff
950
        cmp     ebx, 0x10000000
951
        ja      .fail_and_free_coff
952
; allocate memory
953
        call    init_heap
954
        stdcall user_alloc, [img_size]
2288 clevermous 955
        test    eax, eax
9048 Boppan 956
        jz      .fail_and_free_coff
957
        mov	[img_base], eax
2288 clevermous 958
 
959
; copy sections and set correct values for VirtualAddress'es in headers
960
        mov     edx, [coff]
2384 hidnplayr 961
        movzx   ebx, [edx+COFF_HEADER.nSections]
2288 clevermous 962
        mov     edi, eax
963
        add     edx, 20
964
        cld
965
@@:
966
        call    coff_get_align
967
        add     edi, eax
968
        not     eax
969
        and     edi, eax
9048 Boppan 970
        mov     [edx+COFF_SECTION.VirtualAddress], edi
2384 hidnplayr 971
        mov     esi, [edx+COFF_SECTION.PtrRawData]
972
        mov     ecx, [edx+COFF_SECTION.SizeOfRawData]
2288 clevermous 973
        test    esi, esi
974
        jnz     .copy
975
        xor     eax, eax
976
        rep stosb
977
        jmp     .next
978
.copy:
979
        add     esi, [coff]
980
        rep movsb
981
.next:
2384 hidnplayr 982
        add     edx, sizeof.COFF_SECTION
2288 clevermous 983
        dec     ebx
984
        jnz     @B
985
 
986
        mov     edx, [coff]
2384 hidnplayr 987
        mov     ebx, [edx+COFF_HEADER.pSymTable]
9048 Boppan 988
        mov     edi, [filesize]
2288 clevermous 989
        sub     edi, ebx
990
        jc      .fail_and_free_data
9048 Boppan 991
        mov     [symbols_lim], edi
2288 clevermous 992
        add     ebx, edx
9048 Boppan 993
; coff_hdr = coff
994
; symbols_num = coff.nSymbols
995
	mov	[symbols_ptr], ebx
996
        mov     ebx, edx
2288 clevermous 997
 
998
; fixup symbols
9048 Boppan 999
        mov     eax, [edx+COFF_HEADER.nSymbols]
2288 clevermous 1000
        add     edx, 20
9048 Boppan 1001
        lea     ecx, [eax*9]
2288 clevermous 1002
        add     ecx, ecx
9048 Boppan 1003
        add     ecx, [symbols_ptr]
2288 clevermous 1004
 
9048 Boppan 1005
        stdcall fix_coff_symbols, edx, [symbols_ptr], eax, \
2288 clevermous 1006
                ecx, 0
1007
;          test eax, eax
1008
;          jnz @F
1009
;
1010
;@@:
1011
 
9048 Boppan 1012
        stdcall get_coff_sym, [symbols_ptr], [ebx+COFF_HEADER.nSymbols], szEXPORTS
2288 clevermous 1013
        test    eax, eax
1014
        jnz     @F
1015
 
9048 Boppan 1016
        stdcall get_coff_sym, [symbols_ptr], [ebx+COFF_HEADER.nSymbols], sz_EXPORTS
2288 clevermous 1017
@@:
9048 Boppan 1018
        mov     [exports], eax
2288 clevermous 1019
 
9048 Boppan 1020
        stdcall fix_coff_relocs, ebx, [symbols_ptr], 0
2288 clevermous 1021
 
1022
        stdcall kernel_free, [coff]
1023
 
6502 pathoswith 1024
        stdcall kernel_free, [fullname]
2288 clevermous 1025
 
9048 Boppan 1026
        mov     eax, [exports]
2288 clevermous 1027
        ret
6502 pathoswith 1028
 
2288 clevermous 1029
.fail_and_free_data:
9048 Boppan 1030
	stdcall	user_free, [img_base]
2288 clevermous 1031
.fail_and_free_coff:
1032
        stdcall kernel_free, [coff]
1033
.fail:
6502 pathoswith 1034
        stdcall kernel_free, [fullname]
2288 clevermous 1035
        xor     eax, eax
1036
        ret
1037
endp
1038
 
9048 Boppan 1039
; in: esi -> PEDESCR struct
1040
proc dereference_pe
1041
        mov     ecx, pe_list_mutex
1042
        call    mutex_lock
1043
        dec     [esi+PEDESCR.refcount]
1044
        jnz     mutex_unlock
1045
        mov     eax, [esi+PEDESCR.fd]
1046
        mov     edx, [esi+PEDESCR.bk]
1047
        mov     [eax+PEDESCR.bk], edx
1048
        mov     [edx+PEDESCR.fd], eax
1049
        call    mutex_unlock
2288 clevermous 1050
        mov     eax, esi
1051
        call    free
1052
        ret
9048 Boppan 1053
endp
2288 clevermous 1054
 
1055
align 4
1056
stop_all_services:
1057
        push    ebp
1058
        mov     edx, [srv.fd]
1059
.next:
2384 hidnplayr 1060
        cmp     edx, srv.fd-SRV.fd
2288 clevermous 1061
        je      .done
1062
        cmp     [edx+SRV.magic], ' SRV'
1063
        jne     .next
2384 hidnplayr 1064
        cmp     [edx+SRV.size], sizeof.SRV
2288 clevermous 1065
        jne     .next
1066
 
1067
        mov     ebx, [edx+SRV.entry]
1068
        mov     edx, [edx+SRV.fd]
1069
        test    ebx, ebx
1070
        jz      .next
1071
 
1072
        push    edx
1073
        mov     ebp, esp
1074
        push    0
1075
        push    -1
1076
        call    ebx
1077
        mov     esp, ebp
1078
        pop     edx
1079
        jmp     .next
1080
.done:
1081
        pop     ebp
1082
        ret
1083
 
1084
; param
1085
;  eax= size
1086
;  ebx= pid
1087
 
1088
align 4
1089
create_kernel_object:
1090
 
1091
        push    ebx
1092
        call    malloc
1093
        pop     ebx
1094
        test    eax, eax
1095
        jz      .fail
1096
 
1097
        mov     ecx, [current_slot]
1098
        add     ecx, APP_OBJ_OFFSET
1099
 
1100
        pushfd
1101
        cli
1102
        mov     edx, [ecx+APPOBJ.fd]
1103
        mov     [eax+APPOBJ.fd], edx
1104
        mov     [eax+APPOBJ.bk], ecx
1105
        mov     [eax+APPOBJ.pid], ebx
1106
 
1107
        mov     [ecx+APPOBJ.fd], eax
1108
        mov     [edx+APPOBJ.bk], eax
1109
        popfd
1110
.fail:
1111
        ret
1112
 
1113
; param
1114
;  eax= object
1115
 
1116
align 4
1117
destroy_kernel_object:
1118
 
1119
        pushfd
1120
        cli
1121
        mov     ebx, [eax+APPOBJ.fd]
1122
        mov     ecx, [eax+APPOBJ.bk]
1123
        mov     [ebx+APPOBJ.bk], ecx
1124
        mov     [ecx+APPOBJ.fd], ebx
1125
        popfd
1126
 
1127
        xor     edx, edx       ;clear common header
1128
        mov     [eax], edx
1129
        mov     [eax+4], edx
1130
        mov     [eax+8], edx
1131
        mov     [eax+12], edx
1132
        mov     [eax+16], edx
1133
 
1134
        call    free           ;release object memory
1135
        ret
5595 serge 1136
 
6926 serge 1137
 
1138
;void* __fastcall create_object(size_t size)
5595 serge 1139
; param
1140
;  ecx= size
1141
 
1142
align 4
1143
create_object:
1144
 
1145
        push    esi
1146
        push    edi
1147
        pushfd
1148
        cli
1149
 
1150
        mov     esi, [current_process]
1151
        mov     eax, [esi+PROC.ht_free]
1152
        mov     edi, [esi+PROC.ht_next]
1153
        dec     eax
1154
        js      .err0
1155
 
1156
        mov     [esi+PROC.ht_free], eax
1157
        mov     eax, [esi+PROC.htab+edi*4]
1158
        mov     [esi+PROC.ht_next], eax
1159
        popfd
1160
 
1161
        mov     eax, ecx
1162
        call    malloc
1163
        test    eax, eax
1164
        jz      .err1
1165
 
1166
        mov     [eax+FUTEX.handle], edi
1167
        mov     [esi+PROC.htab+edi*4], eax
1168
        pop     edi
1169
        pop     esi
1170
        ret
1171
 
1172
.err1:
1173
        pushfd
1174
        cli
1175
 
1176
        mov     eax, [esi+PROC.ht_next]
1177
        mov     [esi+PROC.htab+edi*4], eax
1178
        mov     [esi+PROC.ht_next], edi
1179
        inc     [esi+PROC.ht_free]
1180
.err0:
1181
        popfd
1182
        pop     edi
1183
        pop     esi
1184
        xor     eax, eax
1185
        ret
1186
 
6926 serge 1187
 
1188
;int __fastcall destroy_object(struct object *obj)
1189
 
1190
align 4
1191
destroy_object:
1192
        push    esi
1193
        mov     esi, [current_process]
1194
        mov     edx, [ecx+FUTEX.handle]
1195
 
1196
        pushfd
1197
        cli
1198
 
1199
        mov     eax, [esi+PROC.ht_next]
1200
        mov     [esi+PROC.htab+edx*4], eax
1201
        mov     [esi+PROC.ht_next], edx
1202
        inc     [esi+PROC.ht_free]
1203
 
1204
        popfd
1205
        pop     esi
1206
 
1207
        mov     eax, ecx
1208
        call    free
1209
        xor     eax, eax
1210
        ret
1211
.fail:
1212
        popfd
1213
        pop     esi
1214
        mov     eax, -1
1215
        ret
1216