Subversion Repositories Kolibri OS

Rev

Rev 2288 | Rev 2889 | 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-2011. All rights reserved. ;;
2288 clevermous 4
;; Distributed under terms of the GNU General Public License    ;;
5
;;                                                              ;;
6
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
7
 
8
$Revision: 2455 $
9
 
10
 
11
image_of_eax EQU esp+32
12
image_of_ebx EQU esp+20
13
 
14
; System function 70 - files with long names (LFN)
15
; diamond, 2006
16
 
17
iglobal
18
; in this table names must be in lowercase
19
rootdirs:
20
        db      2,'rd'
21
        dd      fs_OnRamdisk
22
        dd      fs_NextRamdisk
23
        db      7,'ramdisk'
24
        dd      fs_OnRamdisk
25
        dd      fs_NextRamdisk
26
        db      2,'fd'
27
        dd      fs_OnFloppy
28
        dd      fs_NextFloppy
29
        db      10,'floppydisk'
30
        dd      fs_OnFloppy
31
        dd      fs_NextFloppy
32
        db      3,'hd0'
33
        dd      fs_OnHd0
34
        dd      fs_NextHd0
35
        db      3,'hd1'
36
        dd      fs_OnHd1
37
        dd      fs_NextHd1
38
        db      3,'hd2'
39
        dd      fs_OnHd2
40
        dd      fs_NextHd2
41
        db      3,'hd3'
42
        dd      fs_OnHd3
43
        dd      fs_NextHd3
44
;**********************************************
45
        db      3,'cd0'
46
        dd      fs_OnCd0
47
        dd      fs_NextCd
48
        db      3,'cd1'
49
        dd      fs_OnCd1
50
        dd      fs_NextCd
51
        db      3,'cd2'
52
        dd      fs_OnCd2
53
        dd      fs_NextCd
54
        db      3,'cd3'
55
        dd      fs_OnCd3
56
        dd      fs_NextCd
57
;***********************************************
58
        db      0
59
 
60
 
61
virtual_root_query:
62
        dd      fs_HasRamdisk
63
        db      'rd',0
64
        dd      fs_HasFloppy
65
        db      'fd',0
66
        dd      fs_HasHd0
67
        db      'hd0',0
68
        dd      fs_HasHd1
69
        db      'hd1',0
70
        dd      fs_HasHd2
71
        db      'hd2',0
72
        dd      fs_HasHd3
73
        db      'hd3',0
74
;**********************************************
75
        dd      fs_HasCd0
76
        db      'cd0',0
77
        dd      fs_HasCd1
78
        db      'cd1',0
79
        dd      fs_HasCd2
80
        db      'cd2',0
81
        dd      fs_HasCd3
82
        db      'cd3',0
83
;**********************************************
84
        dd      0
85
 
86
fs_additional_handlers:
87
        dd      biosdisk_handler, biosdisk_enum_root
88
        dd      dyndisk_handler, dyndisk_enum_root
89
; add new handlers here
90
        dd      0
91
 
92
endg
93
file_system_lfn:
94
; in: ebx->fileinfo block
95
; operation codes:
96
; 0 : read file
97
; 1 : read folder
98
; 2 : create/rewrite file
99
; 3 : write/append to file
100
; 4 : set end of file
101
; 5 : get file/directory attributes structure
102
; 6 : set file/directory attributes structure
103
; 7 : start application
104
; 8 : delete file
105
; 9 : create directory
106
 
107
; parse file name
108
        lea     esi, [ebx+20]
109
        lodsb
110
        test    al, al
111
        jnz     @f
112
        mov     esi, [esi]
113
        lodsb
114
@@:
115
        cmp     al, '/'
116
        jz      .notcurdir
117
        dec     esi
118
        mov     ebp, esi
119
        test    al, al
120
        jnz     @f
121
        xor     ebp, ebp
122
@@:
123
        mov     esi, [current_slot]
124
        mov     esi, [esi+APPDATA.cur_dir]
125
        jmp     .parse_normal
126
.notcurdir:
127
        cmp     byte [esi], 0
128
        jz      .rootdir
129
        call    process_replace_file_name
130
.parse_normal:
131
        cmp     dword [ebx], 7
132
        jne     @F
133
        mov     edx, [ebx+4]
134
        mov     ebx, [ebx+8]
135
        call    fs_execute; esi+ebp, ebx, edx
136
        mov     [image_of_eax], eax
137
        ret
138
@@:
139
        mov     edi, rootdirs-8
140
        xor     ecx, ecx
141
        push    esi
142
.scan1:
143
        pop     esi
144
        add     edi, ecx
145
        scasd
146
        scasd
147
        mov     cl, byte [edi]
148
        test    cl, cl
149
        jz      .notfound_try
150
        inc     edi
151
        push    esi
152
@@:
153
        lodsb
154
        or      al, 20h
155
        scasb
156
        loopz   @b
157
        jnz     .scan1
158
        lodsb
159
        cmp     al, '/'
160
        jz      .found1
161
        test    al, al
162
        jnz     .scan1
163
        pop     eax
164
; directory /xxx
165
.maindir:
166
        mov     esi, [edi+4]
167
.maindir_noesi:
168
        cmp     dword [ebx], 1
169
        jnz     .access_denied
170
        xor     eax, eax
171
        mov     ebp, [ebx+12]                   ;количество блоков для считывания
172
        mov     edx, [ebx+16]                   ;куда записывать рузельтат
173
    ;    add     edx, std_application_base_address
174
        push    dword [ebx+4]   ; first block
175
        mov     ebx, [ebx+8]    ; flags
176
; ebx=flags, [esp]=first block, ebp=number of blocks, edx=return area, esi='Next' handler
177
        mov     edi, edx
178
        push    ecx
179
        mov     ecx, 32/4
180
        rep stosd
181
        pop     ecx
182
        mov     byte [edx], 1   ; version
183
.maindir_loop:
184
        call    esi
185
        jc      .maindir_done
186
        inc     dword [edx+8]
187
        dec     dword [esp]
188
        jns     .maindir_loop
189
        dec     ebp
190
        js      .maindir_loop
191
        inc     dword [edx+4]
192
        mov     dword [edi], 0x10       ; attributes: folder
193
        mov     dword [edi+4], 1        ; name type: UNICODE
194
        push    eax
195
        xor     eax, eax
196
        add     edi, 8
197
        push    ecx
198
        mov     ecx, 40/4-2
199
        rep stosd
200
        pop     ecx
201
        pop     eax
202
        push    eax edx
203
; convert number in eax to decimal UNICODE string
204
        push    edi
205
        push    ecx
206
        push    -'0'
207
        mov     ecx, 10
208
@@:
209
        xor     edx, edx
210
        div     ecx
211
        push    edx
212
        test    eax, eax
213
        jnz     @b
214
@@:
215
        pop     eax
216
        add     al, '0'
217
        stosb
218
        test    bl, 1           ; UNICODE name?
219
        jz      .ansi2
220
        mov     byte [edi], 0
221
        inc     edi
222
.ansi2:
223
        test    al, al
224
        jnz     @b
225
        mov     byte [edi-1], 0
226
        pop     ecx
227
        pop     edi
228
; UNICODE name length is 520 bytes, ANSI - 264
229
        add     edi, 520
230
        test    bl, 1
231
        jnz     @f
232
        sub     edi, 520-264
233
@@:
234
        pop     edx eax
235
        jmp     .maindir_loop
236
.maindir_done:
237
        pop     eax
238
        mov     ebx, [edx+4]
239
        xor     eax, eax
240
        dec     ebp
241
        js      @f
242
        mov     al, ERROR_END_OF_FILE
243
@@:
244
        mov     [image_of_eax], eax
245
        mov     [image_of_ebx], ebx
246
        ret
247
; directory /
248
.rootdir:
249
        cmp     dword [ebx], 1  ; read folder?
250
        jz      .readroot
251
.access_denied:
252
        mov     dword [image_of_eax], 10      ; access denied
253
        ret
254
 
255
.readroot:
256
; virtual root folder - special handler
257
        mov     esi, virtual_root_query
258
        mov     ebp, [ebx+12]
259
        mov     edx, [ebx+16]
260
    ;    add     edx, std_application_base_address
261
        push    dword [ebx+4]   ; first block
262
        mov     ebx, [ebx+8]    ; flags
263
        xor     eax, eax
264
; eax=0, [esp]=first block, ebx=flags, ebp=number of blocks, edx=return area
265
        mov     edi, edx
266
        mov     ecx, 32/4
267
        rep stosd
268
        mov     byte [edx], 1   ; version
269
.readroot_loop:
270
        cmp     dword [esi], eax
271
        jz      .readroot_done_static
272
        call    dword [esi]
273
        add     esi, 4
274
        test    eax, eax
275
        jnz     @f
276
.readroot_next:
277
        or      ecx, -1
278
        xchg    esi, edi
279
        repnz scasb
280
        xchg    esi, edi
281
        jmp     .readroot_loop
282
@@:
283
        xor     eax, eax
284
        inc     dword [edx+8]
285
        dec     dword [esp]
286
        jns     .readroot_next
287
        dec     ebp
288
        js      .readroot_next
289
        inc     dword [edx+4]
290
        mov     dword [edi], 0x10       ; attributes: folder
291
        mov     dword [edi+4], ebx      ; name type: UNICODE
292
        add     edi, 8
293
        mov     ecx, 40/4-2
294
        rep stosd
295
        push    edi
296
@@:
297
        lodsb
298
        stosb
299
        test    bl, 1
300
        jz      .ansi
301
        mov     byte [edi], 0
302
        inc     edi
303
.ansi:
304
        test    eax, eax
305
        jnz     @b
306
        pop     edi
307
        add     edi, 520
308
        test    bl, 1
309
        jnz     .readroot_loop
310
        sub     edi, 520-264
311
        jmp     .readroot_loop
312
.readroot_done_static:
313
        mov     esi, fs_additional_handlers-8
314
        sub     esp, 16
315
.readroot_ah_loop:
316
        add     esi, 8
317
        cmp     dword [esi], 0
318
        jz      .readroot_done
319
        xor     eax, eax
320
.readroot_ah_loop2:
321
        push    edi
322
        lea     edi, [esp+4]
323
        call    dword [esi+4]
324
        pop     edi
325
        test    eax, eax
326
        jz      .readroot_ah_loop
327
        inc     dword [edx+8]
328
        dec     dword [esp+16]
329
        jns     .readroot_ah_loop2
330
        dec     ebp
331
        js      .readroot_ah_loop2
332
        push    eax
333
        xor     eax, eax
334
        inc     dword [edx+4]
335
        mov     dword [edi], 0x10       ; attributes: folder
336
        mov     dword [edi+4], ebx
337
        add     edi, 8
338
        mov     ecx, 40/4-2
339
        rep stosd
340
        push    esi edi
341
        lea     esi, [esp+12]
342
@@:
343
        lodsb
344
        stosb
345
        test    bl, 1
346
        jz      .ansi3
347
        mov     byte [edi], 0
348
        inc     edi
349
.ansi3:
350
        test    al, al
351
        jnz     @b
352
        pop     edi esi eax
353
        add     edi, 520
354
        test    bl, 1
355
        jnz     .readroot_ah_loop2
356
        sub     edi, 520-264
357
        jmp     .readroot_ah_loop2
358
.readroot_done:
359
        add     esp, 16
360
        pop     eax
361
        mov     ebx, [edx+4]
362
        xor     eax, eax
363
        dec     ebp
364
        js      @f
365
        mov     al, ERROR_END_OF_FILE
366
@@:
367
        mov     [image_of_eax], eax
368
        mov     [image_of_ebx], ebx
369
        ret
370
.notfound_try:
371
        mov     edi, fs_additional_handlers
372
@@:
373
        cmp     dword [edi], 0
374
        jz      .notfound
375
        call    dword [edi]
376
        scasd
377
        scasd
378
        jmp     @b
379
.notfound:
380
        mov     dword [image_of_eax], ERROR_FILE_NOT_FOUND
381
        and     dword [image_of_ebx], 0
382
        ret
383
 
384
.notfounda:
385
        cmp     edi, esp
386
        jnz     .notfound
387
        call    dword [edi+4]
388
        add     esp, 16
389
        jmp     .notfound
390
 
391
.found1:
392
        pop     eax
393
        cmp     byte [esi], 0
394
        jz      .maindir
395
.found2:
396
; read partition number
397
        xor     ecx, ecx
398
        xor     eax, eax
399
@@:
400
        lodsb
401
        cmp     al, '/'
402
        jz      .done1
403
        test    al, al
404
        jz      .done1
405
        sub     al, '0'
406
        cmp     al, 9
407
        ja      .notfounda
408
        lea     ecx, [ecx*5]
409
        lea     ecx, [ecx*2+eax]
410
        jmp     @b
411
.done1:
412
        jecxz   .notfounda
413
        test    al, al
414
        jnz     @f
415
        dec     esi
416
@@:
417
        cmp     byte [esi], 0
418
        jnz     @f
419
        test    ebp, ebp
420
        jz      @f
421
        mov     esi, ebp
422
        xor     ebp, ebp
423
@@:
424
; now [edi] contains handler address, ecx - partition number,
425
; esi points to ASCIIZ string - rest of name
426
        jmp     dword [edi]
427
 
428
; handlers for devices
429
; in: ecx = 0 => query virtual directory /xxx
430
; in: ecx = partition number
431
;     esi -> relative (for device) name
432
;     ebx -> fileinfo
433
;     ebp = 0 or pointer to rest of name from folder addressed by esi
434
; out: [image_of_eax]=image of eax, [image_of_ebx]=image of ebx
435
 
436
fs_OnRamdisk:
437
        cmp     ecx, 1
438
        jnz     file_system_lfn.notfound
439
        mov     eax, [ebx]
440
        cmp     eax, fs_NumRamdiskServices
441
        jae     .not_impl
442
        mov     ecx, [ebx+12]
443
        mov     edx, [ebx+16]
444
   ;     add     edx, std_application_base_address
445
        add     ebx, 4
446
        call    dword [fs_RamdiskServices + eax*4]
447
        mov     [image_of_eax], eax
448
        mov     [image_of_ebx], ebx
449
        ret
450
.not_impl:
451
        mov     dword [image_of_eax], 2       ; not implemented
452
        ret
453
 
454
fs_NotImplemented:
455
        mov     eax, 2
456
        ret
457
 
458
fs_RamdiskServices:
459
        dd      fs_RamdiskRead
460
        dd      fs_RamdiskReadFolder
461
        dd      fs_RamdiskRewrite
462
        dd      fs_RamdiskWrite
463
        dd      fs_RamdiskSetFileEnd
464
        dd      fs_RamdiskGetFileInfo
465
        dd      fs_RamdiskSetFileInfo
466
        dd      0
467
        dd      fs_RamdiskDelete
468
        dd      fs_RamdiskCreateFolder
469
fs_NumRamdiskServices = ($ - fs_RamdiskServices)/4
470
 
471
fs_OnFloppy:
472
        cmp     ecx, 2
473
        ja      file_system_lfn.notfound
474
        mov     eax, [ebx]
475
        cmp     eax, fs_NumFloppyServices
476
        jae     fs_OnRamdisk.not_impl
477
        call    reserve_flp
478
        mov     [flp_number], cl
479
        mov     ecx, [ebx+12]
480
        mov     edx, [ebx+16]
481
   ;     add     edx, std_application_base_address
482
        add     ebx, 4
483
        call    dword [fs_FloppyServices + eax*4]
484
        and     [flp_status], 0
485
        mov     [image_of_eax], eax
486
        mov     [image_of_ebx], ebx
487
        ret
488
 
489
fs_FloppyServices:
490
        dd      fs_FloppyRead
491
        dd      fs_FloppyReadFolder
492
        dd      fs_FloppyRewrite
493
        dd      fs_FloppyWrite
494
        dd      fs_FloppySetFileEnd
495
        dd      fs_FloppyGetFileInfo
496
        dd      fs_FloppySetFileInfo
497
        dd      0
498
        dd      fs_FloppyDelete
499
        dd      fs_FloppyCreateFolder
500
fs_NumFloppyServices = ($ - fs_FloppyServices)/4
501
 
502
fs_OnHd0:
503
        call    reserve_hd1
504
        mov     [hdbase], 0x1F0
505
        mov     [hdid], 0
506
        push    1
507
        jmp     fs_OnHd
508
fs_OnHd1:
509
        call    reserve_hd1
510
        mov     [hdbase], 0x1F0
511
        mov     [hdid], 0x10
512
        push    2
513
        jmp     fs_OnHd
514
fs_OnHd2:
515
        call    reserve_hd1
516
        mov     [hdbase], 0x170
517
        mov     [hdid], 0
518
        push    3
519
        jmp     fs_OnHd
520
fs_OnHd3:
521
        call    reserve_hd1
522
        mov     [hdbase], 0x170
523
        mov     [hdid], 0x10
524
        push    4
525
fs_OnHd:
526
        call    reserve_hd_channel
527
        pop     eax
528
        mov     [hdpos], eax
529
        cmp     ecx, 0x100
530
        jae     fs_OnHdAndBd.nf
531
        cmp     cl, [DRIVE_DATA+1+eax]
532
fs_OnHdAndBd:
533
        jbe     @f
534
.nf:
535
        call    free_hd_channel
536
        and     [hd1_status], 0
537
        mov     dword [image_of_eax], 5       ; not found
538
        ret
539
@@:
540
        mov     [known_part], ecx ;     mov     [fat32part], ecx
541
        push    ebx esi
542
        call    choice_necessity_partition_1
543
        pop     esi ebx
544
        mov     ecx, [ebx+12]
545
        mov     edx, [ebx+16]
546
    ;    add     edx, std_application_base_address
547
        mov     eax, [ebx]
548
        cmp     eax, fs_NumHdServices
549
        jae     .not_impl
550
        add     ebx, 4
551
        call    dword [fs_HdServices + eax*4]
552
        call    free_hd_channel
553
        and     [hd1_status], 0
554
        mov     [image_of_eax], eax
555
        mov     [image_of_ebx], ebx
556
        ret
557
.not_impl:
558
        call    free_hd_channel
559
        and     [hd1_status], 0
560
        mov     dword [image_of_eax], 2       ; not implemented
561
        ret
562
 
563
fs_HdServices:
564
        dd      fs_HdRead
565
        dd      fs_HdReadFolder
566
        dd      fs_HdRewrite
567
        dd      fs_HdWrite
568
        dd      fs_HdSetFileEnd
569
        dd      fs_HdGetFileInfo
570
        dd      fs_HdSetFileInfo
571
        dd      0
572
        dd      fs_HdDelete
573
        dd      fs_HdCreateFolder
574
fs_NumHdServices = ($ - fs_HdServices)/4
575
 
576
;*******************************************************
577
fs_OnCd0:
578
        call    reserve_cd
579
        mov     [ChannelNumber], 1
580
        mov     [DiskNumber], 0
581
        push    6
582
        push    1
583
        jmp     fs_OnCd
584
fs_OnCd1:
585
        call    reserve_cd
586
        mov     [ChannelNumber], 1
587
        mov     [DiskNumber], 1
588
        push    4
589
        push    2
590
        jmp     fs_OnCd
591
fs_OnCd2:
592
        call    reserve_cd
593
        mov     [ChannelNumber], 2
594
        mov     [DiskNumber], 0
595
        push    2
596
        push    3
597
        jmp     fs_OnCd
598
fs_OnCd3:
599
        call    reserve_cd
600
        mov     [ChannelNumber], 2
601
        mov     [DiskNumber], 1
602
        push    0
603
        push    4
604
fs_OnCd:
605
        call    reserve_cd_channel
606
        pop     eax
607
        mov     [cdpos], eax
608
        pop     eax
609
        cmp     ecx, 0x100
610
        jae     .nf
611
        push    ecx ebx
612
        mov     cl, al
613
        mov     bl, [DRIVE_DATA+1]
614
        shr     bl, cl
615
        test    bl, 2
616
        pop     ebx ecx
617
 
618
        jnz     @f
619
.nf:
620
        call    free_cd_channel
621
        and     [cd_status], 0
622
        mov     dword [image_of_eax], 5       ; not found
623
        ret
624
@@:
625
        mov     ecx, [ebx+12]
626
        mov     edx, [ebx+16]
627
    ;    add     edx, std_application_base_address
628
        mov     eax, [ebx]
629
        cmp     eax, fs_NumCdServices
630
        jae     .not_impl
631
        add     ebx, 4
632
        call    dword [fs_CdServices + eax*4]
633
        call    free_cd_channel
634
        and     [cd_status], 0
635
        mov     [image_of_eax], eax
636
        mov     [image_of_ebx], ebx
637
        ret
638
.not_impl:
639
        call    free_cd_channel
640
        and     [cd_status], 0
641
        mov     dword [image_of_eax], 2       ; not implemented
642
        ret
643
 
644
fs_CdServices:
645
        dd      fs_CdRead
646
        dd      fs_CdReadFolder
647
        dd      fs_NotImplemented
648
        dd      fs_NotImplemented
649
        dd      fs_NotImplemented
650
        dd      fs_CdGetFileInfo
651
        dd      fs_NotImplemented
652
        dd      0
653
        dd      fs_NotImplemented
654
        dd      fs_NotImplemented
655
fs_NumCdServices = ($ - fs_CdServices)/4
656
 
657
;*******************************************************
658
 
659
fs_HasRamdisk:
660
        mov     al, 1   ; we always have ramdisk
661
        ret
662
 
663
fs_HasFloppy:
664
        cmp     byte [DRIVE_DATA], 0
665
        setnz   al
666
        ret
667
 
668
fs_HasHd0:
669
        mov     al, [DRIVE_DATA+1]
670
        and     al, 11000000b
671
        cmp     al, 01000000b
672
        setz    al
673
        ret
674
fs_HasHd1:
675
        mov     al, [DRIVE_DATA+1]
676
        and     al, 00110000b
677
        cmp     al, 00010000b
678
        setz    al
679
        ret
680
fs_HasHd2:
681
        mov     al, [DRIVE_DATA+1]
682
        and     al, 00001100b
683
        cmp     al, 00000100b
684
        setz    al
685
        ret
686
fs_HasHd3:
687
        mov     al, [DRIVE_DATA+1]
688
        and     al, 00000011b
689
        cmp     al, 00000001b
690
        setz    al
691
        ret
692
 
693
;*******************************************************
694
fs_HasCd0:
695
        mov     al, [DRIVE_DATA+1]
696
        and     al, 11000000b
697
        cmp     al, 10000000b
698
        setz    al
699
        ret
700
fs_HasCd1:
701
        mov     al, [DRIVE_DATA+1]
702
        and     al, 00110000b
703
        cmp     al, 00100000b
704
        setz    al
705
        ret
706
fs_HasCd2:
707
        mov     al, [DRIVE_DATA+1]
708
        and     al, 00001100b
709
        cmp     al, 00001000b
710
        setz    al
711
        ret
712
fs_HasCd3:
713
        mov     al, [DRIVE_DATA+1]
714
        and     al, 00000011b
715
        cmp     al, 00000010b
716
        setz    al
717
        ret
718
;*******************************************************
719
 
720
; fs_NextXXX functions:
721
; in: eax = partition number, from which start to scan
722
; out: CF=1 => no more partitions
723
;      CF=0 => eax=next partition number
724
 
725
fs_NextRamdisk:
726
; we always have /rd/1
727
        test    eax, eax
728
        stc
729
        jnz     @f
730
        mov     al, 1
731
        clc
732
@@:
733
        ret
734
 
735
fs_NextFloppy:
736
; we have /fd/1 iff (([DRIVE_DATA] and 0xF0) != 0) and /fd/2 iff (([DRIVE_DATA] and 0x0F) != 0)
737
        test    byte [DRIVE_DATA], 0xF0
738
        jz      .no1
739
        test    eax, eax
740
        jnz     .no1
741
        inc     eax
742
        ret     ; CF cleared
743
.no1:
744
        test    byte [DRIVE_DATA], 0x0F
745
        jz      .no2
746
        cmp     al, 2
747
        jae     .no2
748
        mov     al, 2
749
        clc
750
        ret
751
.no2:
752
        stc
753
        ret
754
 
755
; on hdx, we have partitions from 1 to [0x40002+x]
756
fs_NextHd0:
757
        push    0
758
        jmp     fs_NextHd
759
fs_NextHd1:
760
        push    1
761
        jmp     fs_NextHd
762
fs_NextHd2:
763
        push    2
764
        jmp     fs_NextHd
765
fs_NextHd3:
766
        push    3
767
fs_NextHd:
768
        pop     ecx
769
        movzx   ecx, byte [DRIVE_DATA+2+ecx]
770
        cmp     eax, ecx
771
        jae     fs_NextFloppy.no2
772
        inc     eax
773
        clc
774
        ret
775
 
776
;*******************************************************
777
fs_NextCd:
778
; we always have /cdX/1
779
        test    eax, eax
780
        stc
781
        jnz     @f
782
        mov     al, 1
783
        clc
784
@@:
785
        ret
786
;*******************************************************
787
 
788
; Additional FS handlers.
789
; This handler gets the control each time when fn 70 is called
790
; with unknown item of root subdirectory.
791
; in: esi -> name
792
;     ebp = 0 or rest of name relative to esi
793
; out: if the handler processes path, he must not return in file_system_lfn,
794
;      but instead pop return address and return directly to the caller
795
;      otherwise simply return
796
 
797
; here we test for /bd/... - BIOS disks
798
biosdisk_handler:
799
        cmp     [NumBiosDisks], 0
800
        jz      .ret
801
        mov     al, [esi]
802
        or      al, 20h
803
        cmp     al, 'b'
804
        jnz     .ret
805
        mov     al, [esi+1]
806
        or      al, 20h
807
        cmp     al, 'd'
808
        jnz     .ret
809
        push    esi
810
        inc     esi
811
        inc     esi
812
        cmp     byte [esi], '0'
813
        jb      .ret2
814
        cmp     byte [esi], '9'
815
        ja      .ret2
816
        xor     edx, edx
817
@@:
818
        lodsb
819
        test    al, al
820
        jz      .ok
821
        cmp     al, '/'
822
        jz      .ok
823
        sub     al, '0'
824
        cmp     al, 9
825
        ja      .ret2
826
        lea     edx, [edx*5]
827
        lea     edx, [edx*2+eax]
828
        jmp     @b
829
.ret2:
830
        pop     esi
831
.ret:
832
        ret
833
.ok:
834
        cmp     al, '/'
835
        jz      @f
836
        dec     esi
837
@@:
838
        add     dl, 80h
839
        xor     ecx, ecx
840
@@:
841
        cmp     dl, [BiosDisksData+ecx*4]
842
        jz      .ok2
843
        inc     ecx
844
        cmp     ecx, [NumBiosDisks]
845
        jb      @b
846
        jmp     .ret2
847
.ok2:
848
        add     esp, 8
849
        test    al, al
850
        jnz     @f
851
        mov     esi, fs_BdNext
852
        jmp     file_system_lfn.maindir_noesi
853
@@:
854
        push    ecx
855
        push    ecx
856
        push    biosdisk_cleanup
857
        push    fs_OnBd
858
        mov     edi, esp
859
        jmp     file_system_lfn.found2
860
 
861
fs_BdNext:
862
        cmp     eax, [BiosDiskPartitions+ecx*4]
863
        inc     eax
864
        cmc
865
biosdisk_cleanup:
866
        ret
867
 
868
fs_OnBd:
869
        pop     edx edx edx edx
870
; edx = disk number, ecx = partition number
871
; esi+ebp = name
872
        call    reserve_hd1
873
        add     edx, 0x80
874
        mov     [hdpos], edx
875
        cmp     ecx, [BiosDiskPartitions+(edx-0x80)*4]
876
        jmp     fs_OnHdAndBd
877
 
878
; This handler is called when virtual root is enumerated
879
; and must return all items which can be handled by this.
880
; It is called several times, first time with eax=0
881
; in: eax = 0 for first call, previously returned value for subsequent calls
882
; out: eax = 0 => no more items
883
;      eax != 0 => buffer pointed to by edi contains name of item
884
 
885
; here we enumerate existing BIOS disks /bd
886
biosdisk_enum_root:
887
        cmp     eax, [NumBiosDisks]
888
        jae     .end
889
        push    eax
890
        movzx   eax, byte [BiosDisksData+eax*4]
891
        sub     al, 80h
892
        push    eax
893
        mov     al, 'b'
894
        stosb
895
        mov     al, 'd'
896
        stosb
897
        pop     eax
898
        cmp     al, 10
899
        jae     .big
900
        add     al, '0'
901
        stosb
902
        mov     byte [edi], 0
903
        pop     eax
904
        inc     eax
905
        ret
906
.end:
907
        xor     eax, eax
908
        ret
909
.big:
910
        push    ecx edx
911
        push    -'0'
912
        mov     ecx, 10
913
@@:
914
        xor     edx, edx
915
        div     ecx
916
        push    edx
917
        test    eax, eax
918
        jnz     @b
919
        xchg    eax, edx
920
@@:
921
        pop     eax
922
        add     al, '0'
923
        stosb
924
        jnz     @b
925
        pop     edx ecx
926
        pop     eax
927
        inc     eax
928
        ret
929
 
930
process_replace_file_name:
931
        mov     ebp, [full_file_name_table]
932
        mov     edi, [full_file_name_table.size]
933
        dec     edi
934
        shl     edi, 7
935
        add     edi, ebp
936
.loop:
937
        cmp     edi, ebp
938
        jb      .notfound
939
        push    esi edi
940
@@:
941
        cmp     byte [edi], 0
942
        jz      .dest_done
943
        lodsb
944
        test    al, al
945
        jz      .cont
946
        or      al, 20h
947
        scasb
948
        jz      @b
949
        jmp     .cont
950
.dest_done:
951
        cmp     byte [esi], 0
952
        jz      .found
953
        cmp     byte [esi], '/'
954
        jnz     .cont
955
        inc     esi
956
        jmp     .found
957
.cont:
958
        pop     edi esi
959
        sub     edi, 128
960
        jmp     .loop
961
.found:
962
        pop     edi eax
963
        mov     ebp, esi
964
        cmp     byte [esi], 0
965
        lea     esi, [edi+64]
966
        jnz     .ret
967
.notfound:
968
        xor     ebp, ebp
969
.ret:
970
        ret
971
 
972
sys_current_directory:
973
;       mov     esi, [current_slot]
974
;       mov     esi, [esi+APPDATA.cur_dir]
975
;       mov     edx, esi
976
 
977
;get length string of appdata.cur_dir
978
        mov     eax, [current_slot]
979
        mov     edi, [eax+APPDATA.cur_dir]
980
 
981
        dec     ebx
982
        jz      .set
983
        dec     ebx
984
        jz      .get
985
        ret
986
.get:
987
; sysfunction 30.2: [for app] eax=30,ebx=2,ecx->buffer,edx=len
988
; for our code: ebx->buffer,ecx=len
989
max_cur_dir     equ     0x1000
990
 
991
        mov     ebx, edi
992
 
993
        push    ecx
994
        push    edi
995
 
996
        xor     eax, eax
997
        mov     ecx, max_cur_dir
998
 
999
        repne scasb             ;find zerro at and string
1000
        jnz     .error          ; no zero in cur_dir: internal error, should not happen
1001
 
1002
        sub     edi, ebx        ;lenght for copy
1003
        inc     edi
1004
        mov     [esp+32+8], edi ;return in eax
1005
 
1006
        cmp     edx, edi
1007
        jbe     @f
1008
        mov     edx, edi
1009
@@:
1010
;source string
1011
        pop     esi
1012
;destination string
1013
        pop     edi
1014
        cmp     edx, 1
1015
        jbe     .ret
1016
 
1017
        mov     al, '/'         ;start string with '/'
1018
        stosb
1019
        mov     ecx, edx
1020
        rep movsb               ;copy string
1021
.ret:
1022
        ret
1023
 
1024
.error:
1025
        add     esp, 8
1026
        or      dword [esp+32], -1      ;error not found zerro at string ->[eax+APPDATA.cur_dir]
1027
        ret
1028
.set:
1029
; sysfunction 30.1: [for app] eax=30,ebx=1,ecx->string
1030
; for our code: ebx->string to set
1031
; use generic resolver with APPDATA.cur_dir as destination
1032
        push    max_cur_dir     ;0x1000
1033
        push    edi     ;destination
1034
        mov     ebx, ecx
1035
        call    get_full_file_name
1036
        ret
1037
 
1038
; in: ebx = file name, [esp+4] = destination, [esp+8] = sizeof destination
1039
; destroys all registers except ebp,esp
1040
get_full_file_name:
1041
        push    ebp
1042
        mov     esi, [current_slot]
1043
        mov     esi, [esi+APPDATA.cur_dir]
1044
        mov     edx, esi
1045
@@:
1046
        inc     esi
1047
        cmp     byte [esi-1], 0
1048
        jnz     @b
1049
        dec     esi
1050
        cmp     byte [ebx], '/'
1051
        jz      .set_absolute
1052
; string gives relative path
1053
        mov     edi, [esp+8]    ; destination
1054
.relative:
1055
        cmp     byte [ebx], 0
1056
        jz      .set_ok
1057
        cmp     word [ebx], '.'
1058
        jz      .set_ok
1059
        cmp     word [ebx], './'
1060
        jnz     @f
1061
        add     ebx, 2
1062
        jmp     .relative
1063
@@:
1064
        cmp     word [ebx], '..'
1065
        jnz     .doset_relative
1066
        cmp     byte [ebx+2], 0
1067
        jz      @f
1068
        cmp     byte [ebx+2], '/'
1069
        jnz     .doset_relative
1070
@@:
1071
        dec     esi
1072
        cmp     byte [esi], '/'
1073
        jnz     @b
1074
        add     ebx, 3
1075
        jmp     .relative
1076
.set_ok:
1077
        cmp     edx, edi        ; is destination equal to APPDATA.cur_dir?
1078
        jz      .set_ok.cur_dir
1079
        sub     esi, edx
1080
        cmp     esi, [esp+12]
1081
        jb      .set_ok.copy
1082
.fail:
1083
        mov     byte [edi], 0
1084
        xor     eax, eax        ; fail
1085
        pop     ebp
1086
        ret     8
1087
.set_ok.copy:
1088
        mov     ecx, esi
1089
        mov     esi, edx
1090
        rep movsb
1091
        mov     byte [edi], 0
1092
.ret.ok:
1093
        mov     al, 1   ; ok
1094
        pop     ebp
1095
        ret     8
1096
.set_ok.cur_dir:
1097
        mov     byte [esi], 0
1098
        jmp     .ret.ok
1099
.doset_relative:
1100
        cmp     edx, edi
1101
        jz      .doset_relative.cur_dir
1102
        sub     esi, edx
1103
        cmp     esi, [esp+12]
1104
        jae     .fail
1105
        mov     ecx, esi
1106
        mov     esi, edx
1107
        mov     edx, edi
1108
        rep movsb
1109
        jmp     .doset_relative.copy
1110
.doset_relative.cur_dir:
1111
        mov     edi, esi
1112
.doset_relative.copy:
1113
        add     edx, [esp+12]
1114
        mov     byte [edi], '/'
1115
        inc     edi
1116
        cmp     edi, edx
1117
        jae     .overflow
1118
@@:
1119
        mov     al, [ebx]
1120
        inc     ebx
1121
        stosb
1122
        test    al, al
1123
        jz      .ret.ok
1124
        cmp     edi, edx
1125
        jb      @b
1126
.overflow:
1127
        dec     edi
1128
        jmp     .fail
1129
.set_absolute:
1130
        lea     esi, [ebx+1]
1131
        call    process_replace_file_name
1132
        mov     edi, [esp+8]
1133
        mov     edx, [esp+12]
1134
        add     edx, edi
1135
.set_copy:
1136
        lodsb
1137
        stosb
1138
        test    al, al
1139
        jz      .set_part2
1140
.set_copy_cont:
1141
        cmp     edi, edx
1142
        jb      .set_copy
1143
        jmp     .overflow
1144
.set_part2:
1145
        mov     esi, ebp
1146
        xor     ebp, ebp
1147
        test    esi, esi
1148
        jz      .ret.ok
1149
        mov     byte [edi-1], '/'
1150
        jmp     .set_copy_cont