Subversion Repositories Kolibri OS

Rev

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