[docs] Replace cyrillic 'с' with latin 'c' in register names
[kolibrios.git] / kernel / trunk / fs / fs_lfn.inc
blob09a5f63f4c2786bcdb45ca90eacdc28f6be5e7f8
1 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2 ;;                                                              ;;
3 ;; Copyright (C) KolibriOS team 2004-2024. All rights reserved. ;;
4 ;;  Distributed under terms of the GNU General Public License.  ;;
5 ;;                                                              ;;
6 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
9 ERROR_SUCCESS        = 0
10 ERROR_DISK_BASE      = 1
11 ERROR_UNSUPPORTED_FS = 2
12 ERROR_UNKNOWN_FS     = 3
13 ERROR_PARTITION      = 4
14 ERROR_FILE_NOT_FOUND = 5
15 ERROR_END_OF_FILE    = 6
16 ERROR_MEMORY_POINTER = 7
17 ERROR_DISK_FULL      = 8
18 ERROR_FS_FAIL        = 9
19 ERROR_ACCESS_DENIED  = 10
20 ERROR_DEVICE         = 11
22 maxPathLength = 1000h
24 image_of_eax EQU esp+32
25 image_of_ebx EQU esp+20
27 ; fs api for drivers
28 struct  FileSystem
29         Next            dd ?
30         Prev            dd ?
31         Creat_part      dd ?  ; %FSNAME%_create_partition
32         UserFuncs       dd ? ; for fs_del
33         Name            rd 16 ;ascii string + \n
34 ends
37 fs_list:
38         dd      fs_list
39         dd      fs_list
40 ;.look:  dd      0
42 ; IN: ecx = %FSNAME%_create_partition
43 ;     edx = ptr to UserFuncs
44 ;     [esp] = fs name
45 ;OUT: eax = list item
46 fs_add:
47         push    ecx edx
48         ; add in fs_list
49         mov     eax, sizeof.FileSystem
50         call    malloc
51         pop     edx ecx
52         test    eax, eax
53         jz      .err
55         mov     [eax + FileSystem.Creat_part], ecx
56         mov     [eax + FileSystem.UserFuncs], edx
57         mov     edx, [esp + 4]
58         mov     [eax + FileSystem.Name], edx
59         mov     edx, eax
61         cli          ; DELETE
62         list_add_tail edx, fs_list
63         sti          ; DELETE
64         mov     edx, ecx ; save function
66         ;DEBUGF  1, 'K : FS: find partition\n'
67         ; check all disks
68         mov     esi, [disk_list]
69 .new_disk:
70         cmp     dword[esi], disk_list
71         jz      .end
73         push    edx
74         mov     eax, [esi + DISK.MediaInfo.SectorSize]
75         shl     eax, 2
76         stdcall kernel_alloc, eax   ;get buffer
77         test    eax, eax
78         pop     edx
79         jz      .end ; no memory
80         mov     ebx, eax
82         mov     ecx, [esi + DISK.NumPartitions]
83         dec     ecx
84         shl     ecx, 2 ; to dword
85         add     ecx, [esi + DISK.Partitions]
86 @@:
87         mov     ebp, [ecx]
88         cmp     [ebp + PARTITION.FSUserFunctions], default_fs_functions
89         jnz     .no_fs
91         ;DEBUGF  1, 'K : FS: found partition\n'
92         push    ecx edx
94         xor     eax, eax     ; first sector of the partition
95         call    fs_read32_sys
96         push    eax
97         ;DEBUGF  1, 'K : FS: call driver func = %x\n', edx
99         call    edx ; creat_partition
100         add     esp, 4
101         ;DEBUGF  1, 'K : FS: end call\n'
102         pop     edx ecx
104         test    eax, eax
105         jz      .no_fs
106         ; save and delete old struct
107         xchg    [ecx], eax
108         push    ecx edx
109         call    free
110         pop     edx ecx
111         ;DEBUGF  1, 'K : FS: set fs for partition\n'
112 .no_fs:
113         ;sub     ecx, 4
114         cmp     ecx, [esi + DISK.Partitions]
115         lea     ecx, [ecx - 4]
116         jnz     @b
118         push    edx
119         stdcall kernel_free, ebx
120         pop     edx
122         mov     esi, [esi]
123         jmp     .new_disk
124 .end:
125 .err:
126         ret
127 ; IN: ecx = list item
128 ;OUT: -
129 ;fs_del:
131 ;        ret
135 ; System function 70 security check
136 align 4
137 proc file_system_is_operation_safe stdcall, inf_struct_ptr: dword
138 ; in:
139 ;      inf_struct_ptr = pointer to information structure was given to sysfn70
140 ; out: ZF = 1 if operation is safe
141 ;      ZF = 0 if operation can cause kernel crash
142         push    ebx ecx edx
143         xor     ecx, ecx ; ecx - length of target buffer
145         mov     ebx, [inf_struct_ptr]
146         mov     edx, [ebx + 16] ; base of target buffer
148         cmp     dword [ebx], 0 ; if 70.0
149         jnz     .case1
150         mov     ecx, dword [ebx + 12]
151         jmp     .end_switch
153 .case1:
154         cmp     dword [ebx], 1 ; if 70.1
155         jnz     .case2_3
156         ;mov     ecx, 32
157         cmp     dword [ebx + 8], 1 ; check encoding
158         jbe     .case1_304 ; if encdoing <= 1 i.e cpp866
159         mov     ecx, 560 ; if unicode then bdvk block len is 560 bytes
160         jmp     .case1_end
161 .case1_304:
162         mov     ecx, 304 ; if cp866 then bdvk block len is 304 bytes
163 .case1_end:
164         imul    ecx, dword [ebx + 12] ; multiply bdvk length by their count
165         add     ecx, 32 ; add result header len
166         jmp     .end_switch
168 .case2_3:
169         cmp     dword [ebx], 3
170         ja      .case5 ; if subfn > 3
171         mov     ecx, dword [ebx + 12]
172         jmp     .end_switch
174 .case5:
175         cmp     dword [ebx], 5
176         jnz     .case6
177         mov     ecx, 40
178         jmp     .end_switch
180 .case6:
181         cmp     dword [ebx], 6
182         jnz     .switch_none
183         mov     ecx, 32
184         jmp     .end_switch
186 .switch_none:
187         cmp     ecx, ecx
188         jmp     .ret
190 .end_switch:
191         stdcall is_region_userspace, edx, ecx
192 .ret:
193         pop     edx ecx ebx
194         ret
195 endp
197 sys_fileSystemUnicode: ; with user pointer correctness checking
198 ; in: ebx -> f.80 parameter structure
199         stdcall file_system_is_operation_safe, ebx
200         jz      @f
202         DEBUGF  1, "sysfn80 addr error\n"
203         mov     dword [image_of_eax], ERROR_MEMORY_POINTER
204         ret
206         jmp     fileSystemUnicode
208 ;System function 70
209 sys_file_system_lfn: ; with user pointer correctness checking
210 ; in: ebx -> f.70 parameter structure
211         stdcall file_system_is_operation_safe, ebx
212         jz      @f
214         DEBUGF  1, "sysfn70 addr error\n"
215         mov     dword [image_of_eax], ERROR_MEMORY_POINTER
216         ret
218         jmp     file_system_lfn
220 ;file_system_lfn_protected returns values not in registers, but in their images
221 ;on stack. Make a short wrapper to actually return values in registers.
222 file_system_lfn_protected_registers:
223         pushad
224         call    file_system_lfn_protected
225         popad
226         ret
228 file_system_lfn_protected:
229         pushad
230         call    protect_from_terminate
231         call    file_system_lfn
232         call    unprotect_from_terminate
233         popad
234         mov     [image_of_eax], eax
235         mov     [image_of_ebx], ebx
236         ret
238 fileSystemUnicode:
239 ; in: ebx -> f.80 parameter structure
240         mov     edi, [ebx+20]
241         mov     esi, [ebx+24]
242         jmp     @f
244 file_system_lfn:
245 ; in: ebx -> f.70 parameter structure
246         xor     edi, edi
247         lea     esi, [ebx+20]
248         cmp     byte [esi], 0
249         jnz     @f
250         mov     esi, [ebx+21]
252         cmp     word [esi], '/'
253         jnz     @f
254         cmp     edi, 2
255         jnz     .rootdir
256         cmp     dword[esi], '/'
257         jz      .rootdir
259         stdcall kernel_alloc, maxPathLength
260         push    eax ebx
261         xchg    eax, edi
262         call    getFullPath
263         pop     ebx ebp
264         test    eax, eax
265         jz      .notfound
266         cmp     dword[ebx], 7   ; start application
267         jnz     @f
268         mov     edx, [ebx+4]
269         mov     ecx, [ebx+8]
270         mov     ebx, ebp
271         call    fs_execute
272         mov     [image_of_eax], eax
273         ret
276         lea     esi, [ebp+2]
277         mov     ax, [esi]
278         or      ax, 2020h
279         cmp     ax, 'cd'
280         jz      .CD
281         call    dyndisk_handler ; not returns if success
282 .notfound:
283         stdcall kernel_free, ebp
284         mov     dword[image_of_eax], ERROR_FILE_NOT_FOUND
285         ret
287 .CD:
288         add     esi, 2
289         xor     eax, eax
290         lodsb       ; disk number
291         sub     eax, '0'
292         cmp     eax, 10
293         jnc     .notfound
294         mov     edi, eax
295         lodsb
296         test    eax, eax
297         jz      .maindir
298         cmp     al, '/'
299         jnz     .notfound
300         lodsb       ; partition number
301         test    eax, eax
302         jz      .maindir
303         cmp     al, '1'
304         jnz     .notfound
305         cmp     byte [esi], '/'
306         jnz     @f
307         inc     esi
309         call    reserve_cd
310         mov     eax, edi
311         bt      eax, 0
312         setc    [DiskNumber]
313         bt      eax, 1
314         setc    [ChannelNumber]
315         inc     [ChannelNumber]
316         inc     eax
317         mov     [cdpos], eax
318         call    reserve_cd_channel
319         mov     eax, edi
320         not     eax
321         and     eax, 3
322         shl     eax, 1
323         inc     eax
324         shr     edi, 2
325         mov     dword[image_of_eax], ERROR_FILE_NOT_FOUND
326         bt      [edi*5+DRIVE_DATA+1], ax
327         jnc     @f
328         mov     ecx, [ebx+12]
329         mov     edx, [ebx+16]
330         mov     eax, [ebx]
331         mov     dword[image_of_eax], ERROR_UNSUPPORTED_FS
332         cmp     eax, fs_NumCdServices
333         jae     @f
334         add     ebx, 4
335         push    ebp
336         call    dword[fs_CdServices + eax*4]
337         pop     ebp
338         mov     [image_of_eax], eax
339         mov     [image_of_ebx], ebx
341         call    free_cd_channel
342         and     [cd_status], 0
343         stdcall kernel_free, ebp
344         ret
346 .nextCD:
347         test    eax, eax    ; partition number
348         jnz     @f
349         inc     eax     ; /cdX/1
350         ret
353         stc
354         ret
356 .maindir:   ; list partitions
357         mov     esi, .nextCD
358         xor     ecx, ecx
359 .maindir_noesi:     ; backjump from dyndisk_handler
360         push    ebp
361         mov     ebp, ecx
362         call    kernel_free
363         mov     edi, [ebx+16]   ; buffer
364         cmp     byte [ebx], 5
365         jz      .deviceInfo
366         cmp     byte [ebx], 1   ; read folder?
367         jnz     .access_denied
368         push    ebp
369         pushd   [ebx+4]         ; first block
370         mov     ebp, [ebx+12]   ; the number of blocks to read
371         mov     ebx, [ebx+8]    ; flags
372         mov     ecx, 32/4
373         mov     edx, edi
374         xor     eax, eax
375         rep stosd
376         mov     byte [edx], 1   ; version
377 .maindir_loop:
378         call    esi
379         jc      .maindir_done
380         inc     dword[edx+8]
381         dec     dword[esp]
382         jns     .maindir_loop
383         dec     ebp
384         js      .maindir_loop
385         inc     dword[edx+4]
386         mov     dword[edi], 16      ; attributes: folder
387         mov     dword[edi+4], ebx   ; name encoding
388         push    eax
389         mov     ecx, 32/4
390         add     edi, 8
391         xor     eax, eax
392         rep stosd
393         pop     eax
394         push    eax edx edi
395 ; convert number in eax to decimal string
396         push    -'0'
397         mov     ecx, 10
399         xor     edx, edx
400         div     ecx
401         push    edx
402         test    eax, eax
403         jnz     @b
404         cmp     ebx, 2
405         jz      .uni
407         pop     eax
408         add     eax, '0'
409         stosb
410         test    eax, eax
411         jnz     @b
412         pop     edi edx eax
413         cmp     ebx, 3
414         jz      @f
415         add     edi, 264
416         jmp     .maindir_loop
418 .uni:
419         pop     eax
420         add     eax, '0'
421         stosw
422         test    eax, eax
423         jnz     .uni
424         pop     edi edx eax
426         add     edi, 520
427         jmp     .maindir_loop
429 .maindir_done:
430         pop     eax eax
431         mov     ebx, [edx+4]
432         xor     eax, eax
433         dec     ebp
434         js      @f
435         mov     al, ERROR_END_OF_FILE
437         mov     [image_of_eax], eax
438         mov     [image_of_ebx], ebx
439         ret
441 .access_denied:
442         mov     dword[image_of_eax], ERROR_ACCESS_DENIED
443         ret
445 .deviceInfo:
446         test    ebp, ebp
447         jz      @f
448         mov     eax, dword[ebp+DISK.MediaInfo.Capacity]
449         mov     edx, dword[ebp+DISK.MediaInfo.Capacity+4]
450         mov     ecx, [ebp + DISK.MediaInfo.SectorSize]
451         bsf     ecx, ecx
452         shld    edx, eax, cl
453         shl     eax, cl
454         mov     [edi+36], edx
455         mov     [edi+32], eax
457         and     dword[image_of_eax], 0
458         ret
460 .rootdir:   ; / - virtual root folder
461         cmp     byte [ebx], 5
462         jz      @b
463         cmp     byte [ebx], 1   ; read folder?
464         jnz     .access_denied
465         mov     ebp, [ebx+12]   ; number of blocks
466         mov     edx, [ebx+16]   ; return area
467         push    dword[ebx+4]    ; first block
468         mov     ebx, [ebx+8]    ; flags
469         mov     ecx, 32/4
470         mov     edi, edx
471         xor     eax, eax
472         rep stosd
473         mov     byte [edx], 1   ; version
474         sub     esp, 16
475 .rootdir_loop:
476         push    edi
477         lea     edi, [esp+4]
478         call    dyndisk_enum_root
479         pop     edi
480         test    eax, eax
481         jz      .rootdirCD
482         inc     dword[edx+8]
483         dec     dword[esp+16]
484         jns     .rootdir_loop
485         dec     ebp
486         js      .rootdir_loop
487         inc     dword[edx+4]
488         mov     dword[edi], 16      ; attributes: folder
489         mov     dword[edi+4], ebx   ; name encoding
490         push    eax
491         mov     ecx, 32/4
492         add     edi, 8
493         xor     eax, eax
494         rep stosd
495         push    edi
496         lea     esi, [esp+8]
497         cmp     ebx, 2
498         jz      .uni2
500         lodsb
501         stosb
502         test    eax, eax
503         jnz     @b
504         pop     edi eax
505         cmp     ebx, 3
506         jz      @f
507         add     edi, 264
508         jmp     .rootdir_loop
510 .uni2:
511         lodsb
512         stosw
513         test    eax, eax
514         jnz     .uni2
515         pop     edi eax
517         add     edi, 520
518         jmp     .rootdir_loop
520 .rootdirCD:
521         add     esp, 16
522         or      esi, -1
523 .rootdirCD_loop:
524         inc     esi
525         cmp     esi, 10
526         jnc     .rootdir_done
527         mov     eax, esi
528         not     eax
529         and     eax, 3
530         shl     eax, 1
531         inc     eax
532         mov     ecx, esi
533         shr     ecx, 2
534         bt      [ecx*5+DRIVE_DATA+1], ax
535         jnc     .rootdirCD_loop
536         inc     dword[edx+8]
537         dec     dword[esp]
538         jns     .rootdirCD_loop
539         dec     ebp
540         js      .rootdirCD_loop
541         inc     dword[edx+4]
542         mov     dword[edi], 16      ; attributes: folder
543         mov     dword[edi+4], ebx   ; name encoding
544         mov     ecx, 32/4
545         add     edi, 8
546         xor     eax, eax
547         rep stosd
548         mov     eax, esi
549         add     eax, '0'
550         cmp     ebx, 1
551         jz      @f
552         mov     word [edi], 'cd'
553         mov     [edi+2], ax
554         add     edi, 264
555         jmp     .rootdirCD_loop
558         mov     dword[edi], 640063h
559         mov     [edi+4], eax
560         add     edi, 520
561         jmp     .rootdirCD_loop
563 .rootdir_done:
564         pop     eax
565         mov     ebx, [edx+4]
566         xor     eax, eax
567         dec     ebp
568         js      @f
569         mov     al, ERROR_END_OF_FILE
571         mov     [image_of_eax], eax
572         mov     [image_of_ebx], ebx
573         ret
575 ;-----------------------------------------------------------------------------
576 process_replace_file_name:
577 ; in: [esi] = virtual path
578 ; out: [esi]+[ebp] = physical path
579         xor     edi, edi
580         xor     ebp, ebp
581 .loop:
582         cmp     edi, [full_file_name_table.size]
583         jae     .notfound
584         push    esi edi
585         shl     edi, 7
586         add     edi, [full_file_name_table]
588         cmp     byte [edi], 0
589         jz      .dest_done
590         lodsb
591         test    al, al
592         jz      .cont
593         scasb
594         jz      @b
595         or      al, 20h
596         cmp     [edi-1], al
597         jz      @b
598 .cont:
599         pop     edi esi
600         inc     edi
601         jmp     .loop
603 .dest_done:
604         cmp     byte [esi], 0
605         jz      .found
606         cmp     byte [esi], '/'
607         jnz     .cont
608 .found:
609         pop     edi eax
610         shl     edi, 7
611         add     edi, [full_file_name_table]
612         mov     ebp, esi
613         lea     esi, [edi+64]
614 .notfound:
615         ret
617 ;-----------------------------------------------------------------------------
618 uglobal
619 addDirSeal db  ?
620 endg
622 sys_current_directory:  ; sysfunction 30
623         mov     eax, [current_slot]
624         mov     edi, [eax+APPDATA.cur_dir]
625         xor     eax, eax
626         dec     ebx
627         jz      .set
628         dec     ebx
629         jz      .get
630         dec     ebx
631         jz      .mount_additional_directory
632         mov     eax, edx
633         dec     ebx
634         jz      .set
635         mov     eax, esi
636         dec     ebx
637         jz      .get
639         ret
641 .mount_additional_directory:
642 ; in: ecx -> dir name+dir path (128)
643         mov     al, 1
644         xchg    [addDirSeal], al
645         test    al, al
646         jnz     @b
647         mov     esi, ecx
648         mov     edi, sysdir_name1
649         mov     ecx, 64
650         rep movsb   ; copying fake directory name
651         mov     byte [edi-1], 0
652         mov     cl, 63
653         call    cp866toUTF8_string
654         mov     byte [edi], 0
655         mov     [full_file_name_table.size], 2
656         ret
658 .get:
659 ; in: ecx -> buffer, edx = length, eax = encoding
660         stdcall is_region_userspace, ecx, edx
661         jz      @f
663         ; if illegal buffer given
664         xor     edx, edx
665         jmp     .ret
668         mov     esi, edi
669         inc     esi
670         mov     edi, ecx
671         cmp     edx, maxPathLength
672         jc      @f
673         mov     edx, maxPathLength
675         mov     ecx, edx
676         jecxz   .ret
677         cmp     eax, 2
678         jz      .get16
679         cmp     eax, 3
680         jz      .get8
682         dec     ecx
683         js      @f
684         call    utf8to16
685         call    uni2ansi_char
686         stosb
687         test    al, al
688         jnz     @b
689         sub     edx, ecx
691         mov     byte [edi-1], 0
692 .ret:
693         mov     [esp+32], edx
694         ret
696 .get8:
697         push    edi
698         mov     edi, esi
699         xor     eax, eax
700         repnz scasb
701         sub     edx, ecx
702         mov     ecx, edx
703         pop     edi
704         rep movsb
705         jmp     @b
707 .get16:
708         shr     ecx, 1
709         shr     edx, 1
711         dec     ecx
712         js      @f
713         call    utf8to16
714         stosw
715         test    ax, ax
716         jnz     @b
717         sub     edx, ecx
719         shl     edx, 1
720         mov     word [edi-2], 0
721         jmp     .ret
723 .set:
724         mov     esi, ecx
725 getFullPath:
726 ; in: esi -> file path, eax = string encoding, edi -> destination
727 ; out: UTF-8 string (with marker), eax = length, 0 -> error
728         test    eax, eax
729         jnz     @f
730         cmp     byte [esi], 4
731         jnc     @f
732         cmp     byte [esi], 0
733         jz      @f
734         lodsb
736         cmp     byte [esi], '/'
737         jnz     .relative
738         cmp     eax, 2
739         jnz     @f
740         cmp     word [esi], '/'
741         jnz     .relative
742         inc     esi
743         inc     esi
744         jmp     .start
747         inc     esi
748         cmp     byte [esi], 4
749         jnc     .start
750         lodsb
751         cmp     byte [esi], '/'
752         jnz     .start
753         inc     esi
754 .start:
755         push    eax edi
756         call    process_replace_file_name
757         mov     edi, [esp]
758         mov     ecx, maxPathLength
759         mov     al, 3
760         mov     ah, '/'
761         stosw
762         sub     ecx, 2
763         test    ebp, ebp
764         jz      .absolute
766         lodsb
767         stosb
768         dec     ecx
769         test    al, al
770         jnz     @b
771         mov     esi, ebp
772         dec     edi
773 .absolute:
774         cmp     byte [esp+4], 2
775         jz      .utf16
776         cmp     byte [esp+4], 3
777         jz      .utf8
778         call    cp866toUTF8_string
779         jns     .end
780         jmp     .fail
782 .utf8:
783         dec     ecx
784         js      .fail
785         lodsb
786         stosb
787         test    al, al
788         jz      .end
789         jmp     .utf8
791 .utf16:
792         call    UTF16to8_string
793         jns     .end
794 .fail:
795         mov     byte [edi], 0
796         pop     eax eax
797         xor     eax, eax
798         ret
800 .relative:
801         push    eax edi
802         mov     ebx, esi
803         mov     edi, [current_slot]
804         mov     edi, [edi+APPDATA.cur_dir]
805         mov     edx, edi
806         mov     ecx, maxPathLength
807         xor     eax, eax
808         repnz scasb
809         mov     esi, edi
810         mov     edi, [esp]
811         jecxz   .fail
812         cmp     byte [ebx], 0
813         jz      .set_ok
814         dec     esi
815         cmp     edx, edi    ; is destination equal to cur_dir?
816         mov     edi, esi
817         jz      @f
818         mov     edi, [esp]
819         mov     ecx, esi
820         sub     ecx, edx
821         mov     esi, edx
822         mov     edx, edi
823         rep movsb
825         mov     byte [edi], '/'
826         inc     edi
827         mov     esi, ebx
828         mov     ecx, edx
829         add     ecx, maxPathLength
830         sub     ecx, edi
831         jmp     .absolute
833 .set_ok:
834         cmp     edx, edi    ; is destination equal to cur_dir?
835         jz      @f
836         mov     ecx, esi
837         sub     ecx, edx
838         mov     esi, edx
839         rep movsb
841         pop     eax
842         sub     edi, eax
843         pop     eax
844         mov     eax, edi
845         ret
847 .end:
848         or      ecx, -1
849         mov     edi, [esp]
850         xor     eax, eax
851         push    edi
852         repnz scasb
853         not     ecx
854         pop     edi
855 .parse:
856         mov     al, '/'
857         repnz scasb
858         jecxz   @b
859         cmp     byte [edi], '.'
860         jnz     .parse
861         mov     esi, edi
863         lodsw
864         sub     ecx, 2
865         cmp     ax, './'
866         jz      @b
867         cmp     ax, '..'
868         jnz     @f
869         cmp     byte [esi], '/'
870         jnz     @f
871         mov     edx, ecx
872         mov     ecx, edi
873         sub     ecx, [esp]
874         sub     ecx, 2
875         jc      .fail
876         sub     edi, 2
877         lodsb
878         dec     edx
879         std
880         repnz scasb
881         cld
882         add     edi, 2
883         mov     ecx, edx
884         jmp     @b
887         sub     esi, 2
888         add     ecx, 2
889         cmp     esi, edi
890         jz      .parse
891         push    edi ecx
892         rep movsb
893         pop     ecx edi
894         jmp     .parse
896 include "parse_fn.inc"
897 include "fs_common.inc"
898 include "iso9660.inc"   ; read for CD filesystem
899 include "fat.inc"
900 include "exfat.inc"
901 include "ntfs.inc"
902 include "ext.inc"
903 include "xfs.asm"