Subversion Repositories Kolibri OS

Rev

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