Subversion Repositories Kolibri OS

Rev

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