Subversion Repositories Kolibri OS

Rev

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