File system additions: create/rewrite files with long names

git-svn-id: svn://kolibrios.org@83 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
Evgeny Grechnikov (Diamond) 2006-05-30 07:32:30 +00:00
parent 26d6c6af0e
commit 1e5f55f29c
6 changed files with 2005 additions and 408 deletions

View File

@ -3,6 +3,7 @@
;; RAMDISK functions ;; ;; RAMDISK functions ;;
;; (C) 2004 Ville Turjanmaa, License: GPL ;; ;; (C) 2004 Ville Turjanmaa, License: GPL ;;
;; Addings by M.Lisovin ;; ;; Addings by M.Lisovin ;;
;; LFN support by diamond ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; calculate fat chain ; calculate fat chain
@ -379,7 +380,6 @@ filesave:
; find an empty spot for filename in the root dir ; find an empty spot for filename in the root dir
l20ds: l20ds:
dec edx dec edx
test edx,edx
jz frnoreadds jz frnoreadds
l21ds: l21ds:
cmp [edi],byte 0xE5 cmp [edi],byte 0xE5
@ -1076,4 +1076,522 @@ fs_RamdiskReadFolder:
pop ecx edi esi pop ecx edi esi
ret ret
iglobal
label fat_legal_chars byte
; 0 = not allowed
; 1 = allowed only in long names
; 3 = allowed
times 32 db 0
; ! " # $ % & ' ( ) * + , - . /
db 1,3,0,3,3,3,3,3,3,3,0,1,1,3,3,0
; 0 1 2 3 4 5 6 7 8 9 : ; < = > ?
db 3,3,3,3,3,3,3,3,3,3,0,1,0,1,0,0
; @ A B C D E F G H I J K L M N O
db 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3
; P Q R S T U V W X Y Z [ \ ] ^ _
db 3,3,3,3,3,3,3,3,3,3,3,1,0,1,3,3
; ` a b c d e f g h i j k l m n o
db 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3
; p q r s t u v w x y z { | } ~
db 3,3,3,3,3,3,3,3,3,3,3,3,0,3,3,0
endg
fat_name_is_legal:
; in: esi->(long) name
; out: CF set <=> legal
; destroys eax
push esi
xor eax, eax
@@:
lodsb
test al, al
jz .done
cmp al, 80h
jae .big
test [fat_legal_chars+eax], 1
jnz @b
.err:
pop esi
clc
ret
.big:
; 0x80-0xAF, 0xE0-0xEF
cmp al, 0xB0
jb @b
cmp al, 0xE0
jb .err
cmp al, 0xF0
jb @b
jmp .err
.done:
sub esi, [esp]
cmp esi, 257
pop esi
ret
fat_next_short_name:
; in: edi->8+3 name
; out: name corrected
; CF=1 <=> error
pushad
mov ecx, 8
mov al, '~'
std
push edi
add edi, 7
repnz scasb
pop edi
cld
jz .tilde
; tilde is not found, insert "~1" at end
add edi, 6
cmp word [edi], ' '
jnz .insert_tilde
@@: dec edi
cmp byte [edi], ' '
jz @b
inc edi
.insert_tilde:
mov word [edi], '~1'
popad
; clc ; CF already cleared
ret
.tilde:
push edi
add edi, 7
xor ecx, ecx
@@:
; after tilde may be only digits and trailing spaces
cmp byte [edi], '~'
jz .break
cmp byte [edi], ' '
jz .space
cmp byte [edi], '9'
jnz .found
dec edi
jmp @b
.space:
dec edi
inc ecx
jmp @b
.found:
inc byte [edi]
.succ:
pop edi
popad
clc
ret
.break:
jecxz .noplace
inc edi
mov al, '1'
@@:
xchg al, [edi]
inc edi
cmp al, ' '
mov al, '0'
jnz @b
jmp .succ
.noplace:
dec edi
cmp edi, [esp]
jz .err
add dword [esp], 8
mov word [edi], '~1'
inc edi
inc edi
@@:
mov byte [edi], '0'
inc edi
cmp edi, [esp]
jb @b
pop edi
popad
;clc ; automatically
ret
.err:
pop edi
popad
stc
ret
fat_gen_short_name:
; in: esi->long name
; edi->buffer (8+3=11 chars)
; out: buffer filled
pushad
mov eax, ' '
push edi
stosd
stosd
stosd
pop edi
xor eax, eax
push 8
pop ebx
lea ecx, [edi+8]
.loop:
lodsb
test al, al
jz .done
call char_toupper
cmp al, ' '
jz .space
cmp al, 80h
ja .big
test [fat_legal_chars+eax], 2
jnz .symbol
.inv_symbol:
mov al, '_'
or bh, 1
.symbol:
cmp al, '.'
jz .dot
.normal_symbol:
dec bl
jns .store
mov bl, 0
.space:
or bh, 1
jmp .loop
.store:
stosb
jmp .loop
.big:
cmp al, 0xB0
jb .normal_symbol
cmp al, 0xE0
jb .inv_symbol
cmp al, 0xF0
jb .normal_symbol
jmp .inv_symbol
.dot:
test bh, 2
jz .firstdot
pop ebx
add ebx, edi
sub ebx, ecx
push ebx
cmp edi, ecx
jbe .skip
@@:
dec edi
mov al, ' '
xchg al, [edi]
dec ebx
mov [ebx], al
cmp edi, ecx
ja @b
.skip:
mov bh, 3
jmp @f
.firstdot:
cmp bl, 8
jz .space
push edi
or bh, 2
@@:
mov edi, ecx
mov bl, 3
jmp .loop
.done:
test bh, 2
jz @f
pop edi
@@:
lea edi, [ecx-8]
test bh, 1
jz @f
call fat_next_short_name
@@:
popad
ret
;----------------------------------------------------------------
;
; fs_RamdiskRewrite - LFN variant for writing sys floppy
;
; esi points to filename
; ebx ignored (reserved)
; ecx number of bytes to write, 0+
; edx mem location to data
;
; ret ebx = number of written bytes
; eax = 0 ok read or other = errormsg
;
;--------------------------------------------------------------
@@:
mov eax, ERROR_ACCESS_DENIED
xor ebx, ebx
ret
fs_RamdiskRewrite:
cmp byte [esi], 0
jz @b
; ramdisk doesn't support folders
push esi
@@:
lodsb
test al, al
jz @f
cmp al, '/'
jnz @b
pop esi
.err5:
mov eax, 5 ; file not found
xor ebx, ebx
ret
@@:
pop esi
; check existence
push edi
call rd_find_lfn
jc .notfound
; found, delete FAT chain
push edi
xor eax, eax
mov dword [edi+28], eax ; zero size
xchg ax, word [edi+26] ; start cluster
test eax, eax
jz .done1
@@:
cmp eax, 0xFF8
jae .done1
lea edi, [0x280000 + eax*2] ; position in FAT
xor eax, eax
xchg ax, [edi]
jmp @b
.done1:
pop edi
call get_time_for_file
mov [edi+22], ax
call get_date_for_file
mov [edi+24], ax
mov [edi+18], ax
or byte [edi+11], 20h ; set 'archive' attribute
jmp .doit
.notfound:
; file is not found; generate short name
call fat_name_is_legal
jc @f
pop edi
jmp .err5
@@:
sub esp, 12
mov edi, esp
call fat_gen_short_name
.test_short_name_loop:
push esi ecx
mov esi, 0x100000+512*19
.test_short_name_entry:
cmp byte [esi+11], 0xF
jz .test_short_name_cont
mov ecx, 11
push esi edi
repz cmpsb
pop edi esi
jz .short_name_found
.test_short_name_cont:
add esi, 20h
cmp esi, 0x100000+512*33
jb .test_short_name_entry
pop ecx esi
jmp .found
.short_name_found:
call fat_next_short_name
pop ecx esi
jnc .test_short_name_loop
.disk_full:
add esp, 12
pop edi
mov eax, ERROR_DISK_FULL
xor ebx, ebx
ret
.found:
; now find space in directory
; we need to save LFN <=> LFN is not equal to short name <=> generated name contains '~'
mov al, '~'
push ecx edi
mov ecx, 8
repnz scasb
push 1
pop eax ; 1 entry
jnz .notilde
; we need ceil(strlen(esi)/13) additional entries = floor((strlen(esi)+12+13)/13) total
xor eax, eax
@@:
cmp byte [esi], 0
jz @f
inc esi
inc eax
jmp @b
@@:
sub esi, eax
add eax, 12+13
mov ecx, 13
push edx
cdq
div ecx
pop edx
.notilde:
; find <eax> successive entries in directory
xor ecx, ecx
mov edi, 0x100000+512*19
.scan_dir:
cmp byte [edi], 0
jz .free
cmp byte [edi], 0xE5
jz .free
xor ecx, ecx
.scan_cont:
add edi, 0x20
cmp edi, 0x100000+512*33
jb .scan_dir
pop edi ecx
jmp .disk_full
.free:
inc ecx
cmp ecx, eax
jb .scan_cont
; found!
; calculate name checksum
push esi ecx
mov esi, [esp+8]
mov ecx, 11
xor eax, eax
@@:
ror al, 1
add al, [esi]
inc esi
loop @b
pop ecx esi
; edi points to last entry in free chunk
dec ecx
jz .nolfn
push esi
push edi
.writelfn:
sub edi, 20h
push ecx eax
mov eax, [esp+8]
sub eax, edi
shr eax, 5
cmp ecx, 1
jnz @f
or al, 40h
@@:
stosb
mov cl, 5
call .read_symbols
mov ax, 0xF
stosw
pop eax
stosb
push eax
mov cl, 6
call .read_symbols
xor eax, eax
stosw
mov cl, 2
call .read_symbols
pop eax ecx
sub edi, 0x20
loop .writelfn
pop edi
pop esi
.nolfn:
xchg esi, [esp]
mov ecx, 11
rep movsb
mov word [edi], 20h ; attributes
sub edi, 11
pop esi ecx
add esp, 12
mov byte [edi+13], 0 ; tenths of a second at file creation time
call get_time_for_file
mov [edi+14], ax ; creation time
mov [edi+22], ax ; last write time
call get_date_for_file
mov [edi+16], ax ; creation date
mov [edi+24], ax ; last write date
mov [edi+18], ax ; last access date
and word [edi+20], 0 ; high word of cluster
and word [edi+26], 0 ; low word of cluster - to be filled
and dword [edi+28], 0 ; file size - to be filled
.doit:
push ecx edx
push ecx
push edi
add edi, 26 ; edi points to low word of cluster
push edi
jecxz .done
mov ecx, 2849
mov edi, 0x280000
.write_loop:
; allocate new cluster
xor eax, eax
repnz scasw
jnz .disk_full2
dec edi
dec edi
lea eax, [edi-0x280000]
shr eax, 1 ; eax = cluster
mov word [edi], 0xFFF ; mark as last cluster
xchg edi, [esp]
stosw
pop edi
push edi
inc ecx
; write data
shl eax, 9
add eax, 0x100000+31*512
mov ebx, edx
xchg eax, ebx
push ecx
mov ecx, 512
cmp dword [esp+12], ecx
jae @f
mov ecx, [esp+12]
@@:
call memmove
add edx, ecx
sub [esp+12], ecx
pop ecx
jnz .write_loop
.done:
mov ebx, edx
pop edi edi ecx edx ecx
sub ebx, edx
mov [edi+28], ebx
pop edi
xor eax, eax
ret
.disk_full2:
mov ebx, edx
pop edi edi ecx edx ecx
sub ebx, edx
mov [edi+28], ebx
pop edi
push ERROR_DISK_FULL
pop eax
ret
.read_symbol:
or ax, -1
test esi, esi
jz .retFFFF
lodsb
test al, al
jnz ansi2uni_char
xor eax, eax
xor esi, esi
.retFFFF:
ret
.read_symbols:
call .read_symbol
stosw
loop .read_symbols
ret
; \end{diamond} ; \end{diamond}

View File

@ -2770,7 +2770,7 @@ dword-
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥: ‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* eax = 0 - ãᯥ譮, ¨­ ç¥ ª®¤ ®è¨¡ª¨ ä ©«®¢®© á¨á⥬ë * eax = 0 - ãᯥ譮, ¨­ ç¥ ª®¤ ®è¨¡ª¨ ä ©«®¢®© á¨á⥬ë
‡ ¬¥ç ­¨ï: ‡ ¬¥ç ­¨ï:
* <20>β  δγ­<CEB3>ζ¨ο γαβ ΰ¥« ; δγ­<CEB3>ζ¨ο 58 ―®§Ά®«ο¥β Άλ―®«­οβμ * <20>â  äã­ªæ¨ï ãáâ à¥« ; äã­ªæ¨ï 70 ¯®§¢®«ï¥â ¢ë¯®«­ïâì
⥠¦¥ ¤¥©á⢨ï á à áè¨à¥­­ë¬¨ ¢®§¬®¦­®áâﬨ. ⥠¦¥ ¤¥©á⢨ï á à áè¨à¥­­ë¬¨ ¢®§¬®¦­®áâﬨ.
* „ ­­ ï äã­ªæ¨ï ¯à¥¤¯®« £ ¥â, çâ® ¢® ¢à¥¬ï ¥ñ ¢ë§®¢  ®¤­¨¬ * „ ­­ ï äã­ªæ¨ï ¯à¥¤¯®« £ ¥â, çâ® ¢® ¢à¥¬ï ¥ñ ¢ë§®¢  ®¤­¨¬
¯à¨«®¦¥­¨¥¬ ­¨ª ª®¥ ¤à㣮¥ ¯à¨«®¦¥­¨¥ ­¥ à ¡®â ¥â ¯à¨«®¦¥­¨¥¬ ­¨ª ª®¥ ¤à㣮¥ ¯à¨«®¦¥­¨¥ ­¥ à ¡®â ¥â
@ -2930,6 +2930,8 @@ dword-
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥: ‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* eax = 0 - ãᯥ譮, ¨­ ç¥ ª®¤ ®è¨¡ª¨ ä ©«®¢®© á¨á⥬ë * eax = 0 - ãᯥ譮, ¨­ ç¥ ª®¤ ®è¨¡ª¨ ä ©«®¢®© á¨á⥬ë
* ebx à §àãè ¥âáï * ebx à §àãè ¥âáï
‡ ¬¥ç ­¨ï:
* <20>â  äã­ªæ¨ï ãáâ à¥« , ¨á¯®«ì§ã©â¥ ¯®¤äã­ªæ¨î 2 ä㭪樨 70.
====================================================================== ======================================================================
=========== ”ã­ªæ¨ï 58, ¯®¤äã­ªæ¨ï 2 - 㤠«¨âì ä ©«/¯ ¯ªã. =========== =========== ”ã­ªæ¨ï 58, ¯®¤äã­ªæ¨ï 2 - 㤠«¨âì ä ©«/¯ ¯ªã. ===========
@ -3085,9 +3087,6 @@ dword-
¯®¤ä㭪樥© 11 ä㭪樨 21. “§­ âì íâ® ¬®¦­® ¢ë§®¢®¬ ¯®¤ä㭪樥© 11 ä㭪樨 21. “§­ âì íâ® ¬®¦­® ¢ë§®¢®¬
¯®¤ä㭪樥© 11 ä㭪樨 26. ¯®¤ä㭪樥© 11 ä㭪樨 26.
* LBA-ç⥭¨¥ ¤¨áª¥âë ­¥ ¯®¤¤¥à¦¨¢ ¥âáï. * LBA-ç⥭¨¥ ¤¨áª¥âë ­¥ ¯®¤¤¥à¦¨¢ ¥âáï.
* <20>΅ΰ ι¥­¨¥ <20> ­¥αγι¥αβΆγξ饬㠦ραβ<CEB1>®¬γ ¤¨α<C2A8>γ ­ ¬¥ΰβΆ® Ά¥θ ¥β ―®β®<CEB2>.
“§­ βμ, αγι¥αβΆγ¥β «¨ ¤¨α<C2A8>, ¬®¦­® ¨§ αβΰγ<CEB0>βγΰλ, Ά®§Άΰ ι ¥¬®©
―®¤δγ­<CEB3>樥© 11 δγ­<CEB3>樨 18.
* ”ã­ªæ¨ï áç¨â뢠¥â ¤ ­­ë¥ 䨧¨ç¥áª®£® ¦ñá⪮£® ¤¨áª ; * ”ã­ªæ¨ï áç¨â뢠¥â ¤ ­­ë¥ 䨧¨ç¥áª®£® ¦ñá⪮£® ¤¨áª ;
¥á«¨ ¯® ª ª¨¬-â® ¯à¨ç¨­ ¬ ­ã¦­ë ¤ ­­ë¥ ª®­ªà¥â­®£® à §¤¥« , ¥á«¨ ¯® ª ª¨¬-â® ¯à¨ç¨­ ¬ ­ã¦­ë ¤ ­­ë¥ ª®­ªà¥â­®£® à §¤¥« ,
¯à¨¤ñâáï ®¯à¥¤¥«ïâì ­ ç «ì­ë© ᥪâ®à í⮣® à §¤¥«  ¯à¨¤ñâáï ®¯à¥¤¥«ïâì ­ ç «ì­ë© ᥪâ®à í⮣® à §¤¥« 
@ -4055,14 +4054,14 @@ Architecture Software Developer's Manual, Volume 3, Appendix B);
x - ­®¬¥à à §¤¥«  ­  ¢ë¡à ­­®¬ ¢¨­ç¥áâ¥à¥, ¨§¬¥­ï¥âáï ®â 1 ¤® 255 x - ­®¬¥à à §¤¥«  ­  ¢ë¡à ­­®¬ ¢¨­ç¥áâ¥à¥, ¨§¬¥­ï¥âáï ®â 1 ¤® 255
(­  ª ¦¤®¬ ¨§ ¢¨­ç¥áâ¥à®¢ ­ã¬¥à æ¨ï ­ ç¨­ ¥âáï á 1) (­  ª ¦¤®¬ ¨§ ¢¨­ç¥áâ¥à®¢ ­ã¬¥à æ¨ï ­ ç¨­ ¥âáï á 1)
<EFBFBD>ਬ¥àë: <EFBFBD>ਬ¥àë:
* '/RAMDISK/FIRST/KERNEL.ASM',0 * '/rd/1/kernel.asm',0
'/rd/1/kernel.asm',0
* '/HD0/1/kernel.asm',0 * '/HD0/1/kernel.asm',0
* '/hd0/2/menuet/pics/tanzania.bmp',0 * '/hd0/2/menuet/pics/tanzania.bmp',0
* '/hd0/1/Program files/NameOfProgram/SomeFile.SomeExtension',0 * '/hd0/1/Program files/NameOfProgram/SomeFile.SomeExtension',0
„®áâã¯­ë¥ ¯®¤ä㭪樨: „®áâã¯­ë¥ ¯®¤ä㭪樨:
* ¯®¤äã­ªæ¨ï 0 - ç⥭¨¥ ä ©«  * ¯®¤äã­ªæ¨ï 0 - ç⥭¨¥ ä ©« 
* ¯®¤äã­ªæ¨ï 1 - ç⥭¨¥ ¯ ¯ª¨ * ¯®¤äã­ªæ¨ï 1 - ç⥭¨¥ ¯ ¯ª¨
* ¯®¤äã­ªæ¨ï 2 - ᮧ¤ ­¨¥/¯¥à¥§ ¯¨áì ä ©« 
====================================================================== ======================================================================
= ”ã­ªæ¨ï 70, ¯®¤äã­ªæ¨ï 0 - ç⥭¨¥ ä ©«  á ¯®¤¤¥à¦ª®© ¤«¨­­ëå ¨¬ñ­. = = ”ã­ªæ¨ï 70, ¯®¤äã­ªæ¨ï 0 - ç⥭¨¥ ä ©«  á ¯®¤¤¥à¦ª®© ¤«¨­­ëå ¨¬ñ­. =
@ -4185,6 +4184,30 @@ Architecture Software Developer's Manual, Volume 3, Appendix B);
0x10,   ¢à¥¬¥­  ¨ ¤ âë ®¡­ã«¥­ë. €«ìâ¥à­ â¨¢­ë© ᯮᮡ ¯®«ã祭¨ï 0x10,   ¢à¥¬¥­  ¨ ¤ âë ®¡­ã«¥­ë. €«ìâ¥à­ â¨¢­ë© ᯮᮡ ¯®«ã祭¨ï
¨­ä®à¬ æ¨¨ ®¡ ®¡®à㤮¢ ­¨¨ - ¯®¤äã­ªæ¨ï 11 ä㭪樨 18. ¨­ä®à¬ æ¨¨ ®¡ ®¡®à㤮¢ ­¨¨ - ¯®¤äã­ªæ¨ï 11 ä㭪樨 18.
======================================================================
====================== ”ã­ªæ¨ï 70, ¯®¤äã­ªæ¨ï 2 ======================
======== ‘®§¤ ­¨¥/¯¥à¥§ ¯¨áì ä ©«  á ¯®¤¤¥à¦ª®© ¤«¨­­ëå ¨¬ñ­. ========
======================================================================
<EFBFBD> à ¬¥âàë:
* eax = 70 - ­®¬¥à ä㭪樨
* ebx = 㪠§ â¥«ì ­  ¨­ä®à¬ æ¨®­­ãî áâàãªâãàã
”®à¬ â ¨­ä®à¬ æ¨®­­®© áâàãªâãàë:
* +0: dword: 2 = ­®¬¥à ¯®¤ä㭪樨
* +4: dword: 0 (§ à¥§¥à¢¨à®¢ ­®)
* +8: dword: 0 (§ à¥§¥à¢¨à®¢ ­®)
* +12 = +0xC: dword: ᪮«ìª® ¡ ©â ¯¨á âì
* +16 = +0x10: dword: 㪠§ â¥«ì ­  ¤ ­­ë¥
* +20 = +0x14: ASCIIZ-¨¬ï ä ©« , ¯à ¢¨«  ä®à¬¨à®¢ ­¨ï ¨¬ñ­ 㪠§ ­ë ¢
®¡é¥¬ ®¯¨á ­¨¨
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* eax = 0 - ãᯥ譮, ¨­ ç¥ ª®¤ ®è¨¡ª¨ ä ©«®¢®© á¨á⥬ë
* ebx = ç¨á«® § ¯¨á ­­ëå ¡ ©â (¢®§¬®¦­®, 0)
‡ ¬¥ç ­¨ï:
* …᫨ ä ©« á â ª¨¬ ¨¬¥­¥¬ ­¥ áãé¥á⢮¢ «, ®­ ᮧ¤ ñâáï; ¥á«¨
áãé¥á⢮¢ «, â® ¯¥à¥§ ¯¨á뢠¥âáï.
* …᫨ ᢮¡®¤­®£® ¬¥áâ  ­  ¤¨áª¥ ­¥¤®áâ â®ç­®, â® äã­ªæ¨ï § ¯¨è¥â,
᪮«ìª® ᬮ¦¥â, ¯®á«¥ 祣® ¢¥à­ñâ ª®¤ ®è¨¡ª¨ 8.
====================================================================== ======================================================================
========== ”ã­ªæ¨ï -1 - § ¢¥àè¨âì ¢ë¯®«­¥­¨¥ ¯®â®ª /¯à®æ¥áá  ========= ========== ”ã­ªæ¨ï -1 - § ¢¥àè¨âì ¢ë¯®«­¥­¨¥ ¯®â®ª /¯à®æ¥áá  =========
====================================================================== ======================================================================
@ -4254,6 +4277,7 @@ Architecture Software Developer's Manual, Volume 3, Appendix B);
* 8 = ¤¨áª § ¯®«­¥­ * 8 = ¤¨áª § ¯®«­¥­
* 9 = â ¡«¨æ  FAT à §àã襭  * 9 = â ¡«¨æ  FAT à §àã襭 
* 10 = ¤®áâ㯠§ ¯à¥éñ­ * 10 = ¤®áâ㯠§ ¯à¥éñ­
* 11 = ®è¨¡ª  ãáâனá⢠
<EFBFBD>ਠ§ ¯ã᪥ ¯à®£à ¬¬ë ¢®§¬®¦­ë â ª¦¥ á«¥¤ãî騥 ª®¤ë ®è¨¡®ª: <EFBFBD>ਠ§ ¯ã᪥ ¯à®£à ¬¬ë ¢®§¬®¦­ë â ª¦¥ á«¥¤ãî騥 ª®¤ë ®è¨¡®ª:
* 30 = 0x1E = ­¥¤®áâ â®ç­® ¯ ¬ï⨠* 30 = 0x1E = ­¥¤®áâ â®ç­® ¯ ¬ïâ¨
* 31 = 0x1F = ä ©« ­¥ ï¥âáï ¨á¯®«­¨¬ë¬ * 31 = 0x1F = ä ©« ­¥ ï¥âáï ¨á¯®«­¨¬ë¬

View File

@ -545,10 +545,8 @@ l.21_2:
add ecx,21 add ecx,21
add edi, ecx ;Advance to next entry add edi, ecx ;Advance to next entry
dec dl dec dl
cmp dl,0
jne l.21_2 jne l.21_2
dec dh dec dh
cmp dh,0
jne l.20_2 jne l.20_2
jmp frnoreadd_1 jmp frnoreadd_1
@ -561,9 +559,7 @@ fifoundd_1:
mov eax,[path_pointer_flp] mov eax,[path_pointer_flp]
cmp [eax+36],byte 0 cmp [eax+36],byte 0
je fifoundd_2 je fifoundd_2
add edi,0xf movzx eax, word [edi+0xf]
mov eax,[edi]
and eax,65535
mov ebx,[path_pointer_flp] mov ebx,[path_pointer_flp]
add ebx,36 add ebx,36
call get_cluster_of_a_path_flp call get_cluster_of_a_path_flp
@ -575,10 +571,7 @@ fifoundd_2:
dec [FDD_Sector] dec [FDD_Sector]
fifoundd_2_1: fifoundd_2_1:
mov [edi-11],byte 0xE5 ;mark filename deleted mov [edi-11],byte 0xE5 ;mark filename deleted
add edi,0xf movzx edi, word [edi+0xf] ;edi = cluster
mov eax,[edi]
and eax,65535
mov edi,eax ;edi = cluster
frnewd_1: frnewd_1:
shl edi,1 ;find next cluster from FAT shl edi,1 ;find next cluster from FAT
add edi,0x282000 add edi,0x282000
@ -674,9 +667,7 @@ rd_do_save_1:
; find an empty spot for filename in the root dir ; find an empty spot for filename in the root dir
l20ds_1: l20ds_1:
sub edx,1 sub edx,1
cmp edx,0 jz frnoreadds_1
jnz l21ds_1
jmp frnoreadds_1
l21ds_1: l21ds_1:
cmp [edi],byte 0xE5 cmp [edi],byte 0xE5
jz fifoundds_1 jz fifoundds_1
@ -709,10 +700,8 @@ l.21_3:
add ecx,21 add ecx,21
add edi, ecx ;Advance to next entry add edi, ecx ;Advance to next entry
dec dl dec dl
cmp dl,0
jne l.21_3 jne l.21_3
dec dh dec dh
cmp dh,0
jne l.20_3 jne l.20_3
fdc_status_error_8: fdc_status_error_8:
pop edi esi edx ecx ebx eax pop edi esi edx ecx ebx eax
@ -797,7 +786,6 @@ frnewds_2:
add edi,0x282000 add edi,0x282000
mov eax,[edi] mov eax,[edi]
and eax,4095 and eax,4095
cmp eax,0x0
jnz frnewds_2 jnz frnewds_2
mov [edx],bx ; save next cluster pos. to prev cl. mov [edx],bx ; save next cluster pos. to prev cl.
mov edx,edi ; next save pos abs mem add mov edx,edi ; next save pos abs mem add
@ -1083,84 +1071,201 @@ check_new_flp:
ret ret
; \begin{diamond} ; \begin{diamond}
fat_find_lfn:
; in: esi->name
; [esp+4] = next
; [esp+8] = first
; [esp+C]... - possibly parameters for first and next
; out: CF=1 - file not found
; else CF=0, esi->next name component, edi->direntry
pusha
lea eax, [esp+0Ch+20h]
call dword [eax-4]
jc .reterr
sub esp, 262*2 ; reserve place for LFN
mov ebp, esp
push 0 ; for fat_get_name: read ASCII name
.l1:
call fat_get_name
jc .l2
call fat_compare_name
jz .found
.l2:
lea eax, [esp+0Ch+20h+262*2+4]
call dword [eax-8]
jnc .l1
add esp, 262*2+4
.reterr:
stc
popa
ret
.found:
add esp, 262*2+4
; if this is LFN entry, advance to true entry
cmp byte [edi+11], 0xF
jnz @f
lea eax, [esp+0Ch+20h]
call dword [eax-8]
jc .reterr
@@:
add esp, 8 ; CF=0
push esi
push edi
popa
ret
flp_root_next:
cmp edi, 0xD200-0x20
jae @f
add edi, 0x20
ret ; CF=0
@@:
; read next sector
inc dword [eax]
cmp dword [eax], 14
jae flp_root_first.readerr
flp_root_first:
mov eax, [eax]
pusha
add eax, 19
call read_chs_sector
popa
cmp [FDC_Status], 0
jnz .readerr
mov edi, 0xD000
ret ; CF=0
.readerr:
stc
ret
flp_rootmem_first:
mov edi, 0x8000
clc
ret
flp_rootmem_next:
add edi, 0x20
cmp edi, 0x8000+14*0x200
cmc
flp_rootmem_next_write:
flp_rootmem_begin_write:
flp_rootmem_end_write:
ret
flp_rootmem_extend_dir:
stc
ret
flp_notroot_next:
cmp edi, 0xD200-0x20
jae flp_notroot_next_sector
add edi, 0x20
ret ; CF=0
flp_notroot_next_sector:
push ecx
mov ecx, [eax]
mov ecx, [ecx*2+0x282000]
and ecx, 0xFFF
cmp ecx, 2849
jae flp_notroot_first.err2
mov [eax], ecx
pop ecx
flp_notroot_first:
mov eax, [eax]
cmp eax, 2
jb .err
cmp eax, 2849
jae .err
pusha
add eax, 31
call read_chs_sector
popa
mov edi, 0xD000
cmp [FDC_Status], 0
jnz .err
ret ; CF=0
.err2:
pop ecx
.err:
stc
ret
flp_notroot_begin_write:
pusha
mov eax, [eax]
add eax, 31
call read_chs_sector
popa
ret
flp_notroot_end_write:
pusha
mov eax, [eax]
add eax, 31
call save_chs_sector
popa
ret
flp_notroot_next_write:
cmp edi, 0xD200
jae @f
ret
@@:
call flp_notroot_end_write
jmp flp_notroot_next_sector
flp_notroot_extend_dir:
; find free cluster in FAT
pusha
xor eax, eax
mov edi, 0x282000
mov ecx, 2849
repnz scasw
jnz .notfound
mov word [edi-2], 0xFFF ; mark as last cluster
sub edi, 0x282000
shr edi, 1
dec edi
mov eax, [esp+28]
mov ecx, [eax]
mov [0x282000+ecx*2], di
mov [eax], edi
xor eax, eax
mov edi, 0xD000
mov ecx, 128
rep stosd
popa
call flp_notroot_end_write
mov edi, 0xD000
clc
ret
.notfound:
popa
stc
ret
fd_find_lfn: fd_find_lfn:
; in: esi->name ; in: esi->name
; out: CF=1 - file not found ; out: CF=1 - file not found
; else CF=0 and edi->direntry ; else CF=0 and edi->direntry
pusha push esi edi
sub esp, 262*2 ; reserve place for LFN push 0
mov ebp, esp push flp_root_first
push 0 ; for fat_get_name: read ASCII name push flp_root_next
call read_flp_fat .loop:
cmp [FDC_Status], 0 call fat_find_lfn
jnz .error jc .notfound
mov eax, 19 cmp byte [esi], 0
mov dh, 14
.main_loop:
.20_1:
pusha
call read_chs_sector
popa
cmp [FDC_Status], 0
jnz .error
mov edi, 0xD000
inc [FDD_Sector]
push eax
.21_1:
call fat_get_name
jc @f
call fat_compare_name
jz .found jz .found
@@: test byte [edi+11], 10h
add edi, 0x20 jz .notfound
cmp edi, 0xD200 movzx eax, word [edi+26] ; cluster
jb .21_1 mov [esp+8], eax
pop eax mov dword [esp+4], flp_notroot_first
inc eax mov dword [esp], flp_notroot_next
dec dh jmp .loop
js @f .notfound:
jnz .20_1 add esp, 12
.error: pop edi esi
add esp, 262*2+4
popa
stc stc
ret ret
@@:
; read next sector from FAT
mov eax, [(eax-31-1)*2+0x282000]
and eax, 0xFFF
cmp eax, 0xFF8
jae .error
add eax, 31
jmp .main_loop
.found: .found:
pop eax add esp, 16 ; CF=0
; if LFN entry, advance to corresponding short entry pop esi
cmp byte [edi+11], 0xF
jnz .entryfound
add edi, 0x20
cmp edi, 0xD200
jb .entryfound
dec dh
jz .error
inc eax
call read_chs_sector
cmp [FDC_Status], 0
jnz .error
mov edi, 0xD000
.entryfound:
cmp byte [esi], 0
jz .done
test byte [edi+11], 10h ; is a directory?
jz .error
movzx eax, word [edi+26]
add eax, 31
mov dh, 0
jmp .main_loop
.done:
add esp, 262*2+4+4
push edi
popad
ret ret
;---------------------------------------------------------------- ;----------------------------------------------------------------
@ -1259,7 +1364,7 @@ fs_FloppyRead:
mov ebx, edx mov ebx, edx
pop eax edx ecx edi pop eax edx ecx edi
sub ebx, edx sub ebx, edx
mov al, 5 ; may be other error code? mov al, 11
ret ret
;---------------------------------------------------------------- ;----------------------------------------------------------------
@ -1398,4 +1503,406 @@ fs_FloppyReadFolder:
pop ecx edi edi pop ecx edi edi
ret ret
;----------------------------------------------------------------
;
; fs_FloppyRewrite - LFN variant for writing sys floppy
;
; esi points to filename
; ebx ignored (reserved)
; ecx number of bytes to write, 0+
; edx mem location to data
;
; ret ebx = number of written bytes
; eax = 0 ok read or other = errormsg
;
;--------------------------------------------------------------
@@:
mov eax, ERROR_ACCESS_DENIED
xor ebx, ebx
ret
fsfrfe2:
popad
fsfrfe:
mov eax, 11
xor ebx, ebx
ret
fs_FloppyRewrite:
cmp byte [esi], 0
jz @b
call read_flp_fat
cmp [FDC_Status], 0
jnz fsfrfe
pushad
xor ebp, ebp
push esi
@@:
lodsb
test al, al
jz @f
cmp al, '/'
jnz @b
lea ebp, [esi-1]
jmp @b
@@:
pop esi
test ebp, ebp
jnz .noroot
call read_flp_root
cmp [FDC_Status], 0
jnz fsfrfe2
push flp_rootmem_extend_dir
push flp_rootmem_end_write
push flp_rootmem_next_write
push flp_rootmem_begin_write
xor ebp, ebp
push ebp
push flp_rootmem_first
push flp_rootmem_next
jmp .common1
.noroot:
; check existence
mov byte [ebp], 0
call fd_find_lfn
mov byte [ebp], '/'
lea esi, [ebp+1]
jnc @f
mov eax, ERROR_FILE_NOT_FOUND
.ret1:
mov [esp+28], eax
popad
xor ebx, ebx
ret
@@:
test byte [edi+11], 0x10 ; must be directory
mov eax, ERROR_ACCESS_DENIED
jz .ret1
movzx ebp, word [edi+26] ; ebp=cluster
mov eax, ERROR_FAT_TABLE
cmp ebp, 2
jb .ret1
cmp ebp, 2849
jae .ret1
push flp_notroot_extend_dir
push flp_notroot_end_write
push flp_notroot_next_write
push flp_notroot_begin_write
push ebp
push flp_notroot_first
push flp_notroot_next
.common1:
call fat_find_lfn
jc .notfound
; found, delete FAT chain
push edi
xor eax, eax
mov dword [edi+28], eax ; zero size
xchg ax, word [edi+26] ; start cluster
test eax, eax
jz .done1
@@:
cmp eax, 0xFF8
jae .done1
lea edi, [0x282000 + eax*2] ; position in FAT
xor eax, eax
xchg ax, [edi]
jmp @b
.done1:
pop edi
call get_time_for_file
mov [edi+22], ax
call get_date_for_file
mov [edi+24], ax
mov [edi+18], ax
or byte [edi+11], 20h ; set 'archive' attribute
jmp .doit
.notfound:
; file is not found; generate short name
call fat_name_is_legal
jc @f
add esp, 28
popad
mov eax, ERROR_FILE_NOT_FOUND
xor ebx, ebx
ret
@@:
sub esp, 12
mov edi, esp
call fat_gen_short_name
.test_short_name_loop:
push esi edi ecx
mov esi, edi
lea eax, [esp+12+12+8]
mov [eax], ebp
call dword [eax-4]
jc .found
.test_short_name_entry:
cmp byte [edi+11], 0xF
jz .test_short_name_cont
mov ecx, 11
push esi edi
repz cmpsb
pop edi esi
jz .short_name_found
.test_short_name_cont:
lea eax, [esp+12+12+8]
call dword [eax-8]
jnc .test_short_name_entry
jmp .found
.short_name_found:
pop ecx edi esi
call fat_next_short_name
jnc .test_short_name_loop
.disk_full:
add esp, 12+28
popa
mov eax, ERROR_DISK_FULL
xor ebx, ebx
ret
.found:
pop ecx edi esi
; now find space in directory
; we need to save LFN <=> LFN is not equal to short name <=> generated name contains '~'
mov al, '~'
push ecx edi
mov ecx, 8
repnz scasb
push 1
pop eax ; 1 entry
jnz .notilde
; we need ceil(strlen(esi)/13) additional entries = floor((strlen(esi)+12+13)/13) total
xor eax, eax
@@:
cmp byte [esi], 0
jz @f
inc esi
inc eax
jmp @b
@@:
sub esi, eax
add eax, 12+13
mov ecx, 13
push edx
cdq
div ecx
pop edx
.notilde:
push -1
push -1
; find <eax> successive entries in directory
xor ecx, ecx
push eax
lea eax, [esp+12+8+12+8]
mov [eax], ebp
call dword [eax-4]
pop eax
jnc .scan_dir
.fsfrfe3:
add esp, 8+8+12+28
popad
mov eax, 11
xor ebx, ebx
ret
.scan_dir:
cmp byte [edi], 0
jz .free
cmp byte [edi], 0xE5
jz .free
xor ecx, ecx
.scan_cont:
push eax
lea eax, [esp+12+8+12+8]
call dword [eax-8]
pop eax
jnc .scan_dir
cmp [FDC_Status], 0
jnz .fsfrfe3
push eax
lea eax, [esp+12+8+12+8]
call dword [eax+16] ; extend directory
pop eax
jnc .scan_dir
add esp, 8+8+12+28
popad
mov eax, ERROR_DISK_FULL
xor ebx, ebx
ret
.free:
test ecx, ecx
jnz @f
mov [esp], edi
mov ecx, [esp+8+8+12+8]
mov [esp+4], ecx
xor ecx, ecx
@@:
inc ecx
cmp ecx, eax
jb .scan_cont
; found!
; calculate name checksum
push esi ecx
mov esi, [esp+8+8]
mov ecx, 11
xor eax, eax
@@:
ror al, 1
add al, [esi]
inc esi
loop @b
pop ecx esi
pop edi
pop dword [esp+8+12+8]
; edi points to first entry in free chunk
dec ecx
jz .nolfn
push esi
push eax
lea eax, [esp+8+8+12+8]
call dword [eax+4] ; begin write
mov al, 40h
.writelfn:
or al, cl
mov esi, [esp+4]
push ecx
dec ecx
imul ecx, 13
add esi, ecx
stosb
mov cl, 5
call fs_RamdiskRewrite.read_symbols
mov ax, 0xF
stosw
mov al, [esp+4]
stosb
mov cl, 6
call fs_RamdiskRewrite.read_symbols
xor eax, eax
stosw
mov cl, 2
call fs_RamdiskRewrite.read_symbols
pop ecx
lea eax, [esp+8+8+12+8]
call dword [eax+8] ; next write
xor eax, eax
loop .writelfn
pop eax
pop esi
; lea eax, [esp+8+12+8]
; call dword [eax+12] ; end write
.nolfn:
xchg esi, [esp]
mov ecx, 11
rep movsb
mov word [edi], 20h ; attributes
sub edi, 11
pop esi ecx
add esp, 12
mov byte [edi+13], 0 ; tenths of a second at file creation time
call get_time_for_file
mov [edi+14], ax ; creation time
mov [edi+22], ax ; last write time
call get_date_for_file
mov [edi+16], ax ; creation date
mov [edi+24], ax ; last write date
mov [edi+18], ax ; last access date
and word [edi+20], 0 ; high word of cluster
and word [edi+26], 0 ; low word of cluster - to be filled
and dword [edi+28], 0 ; file size - to be filled
.doit:
lea eax, [esp+8]
call dword [eax+12] ; flush directory
push ecx
push edi
add edi, 26 ; edi points to low word of cluster
push edi
mov esi, edx
jecxz .done
mov ecx, 2849
mov edi, 0x282000
push 0 ; first cluster
.write_loop:
; allocate new cluster
xor eax, eax
repnz scasw
mov al, ERROR_DISK_FULL
jnz .ret
dec edi
dec edi
lea eax, [edi-0x282000]
shr eax, 1 ; eax = cluster
mov word [edi], 0xFFF ; mark as last cluster
cmp dword [esp], 0
jz .first
xchg edi, [esp+4]
stosw
mov edi, [esp+4]
jmp @f
.first:
mov [esp], eax
@@:
inc ecx
; write data
push ecx edi
mov ecx, 512
cmp dword [esp+20], ecx
jae @f
mov ecx, [esp+20]
@@:
push ecx
mov edi, 0xD000
rep movsb
pop ecx
push ecx
sub ecx, 512
neg ecx
push eax
xor eax, eax
rep stosb
pop eax
add eax, 31
pusha
call save_chs_sector
popa
pop ecx
cmp [FDC_Status], 0
jnz .diskerr
sub [esp+20], ecx
pop edi ecx
jnz .write_loop
.done:
xor eax, eax
.ret:
pop ebx edi edi ecx
mov [esp+28+28], eax
lea eax, [esp+8]
call dword [eax+4]
mov [edi+26], bx
mov ebx, esi
sub ebx, edx
mov [edi+28], ebx
call dword [eax+12]
mov [esp+28+16], ebx
test ebp, ebp
jnz @f
call save_flp_root
@@:
add esp, 28
cmp [FDC_Status], 0
jnz .err3
call save_flp_fat
cmp [FDC_Status], 0
jnz .err3
popa
ret
.err3:
popa
mov al, 11
xor ebx, ebx
ret
.diskerr:
sub esi, ecx
mov eax, 11
pop edi ecx
jmp .ret
; \end{diamond} ; \end{diamond}

View File

@ -7,6 +7,7 @@
;; Copyright 2002 Paolo Minazzi, paolo.minazzi@inwind.it ;; ;; Copyright 2002 Paolo Minazzi, paolo.minazzi@inwind.it ;;
;; ;; ;; ;;
;; See file COPYING for details ;; ;; See file COPYING for details ;;
;; 27.05.2006 LFN create/rewrite file - diamond ;;
;; 04.05.2006 LFN read folder - diamond ;; ;; 04.05.2006 LFN read folder - diamond ;;
;; 29.04.2006 Elimination of hangup after the ;; ;; 29.04.2006 Elimination of hangup after the ;;
;; expiration hd_wait_timeout - Mario79 ;; ;; expiration hd_wait_timeout - Mario79 ;;
@ -2934,113 +2935,37 @@ hd_find_lfn:
; in: esi->name ; in: esi->name
; out: CF=1 - file not found ; out: CF=1 - file not found
; else CF=0 and edi->direntry ; else CF=0 and edi->direntry
pusha ; destroys eax
sub esp, 262*2 ; allocate space for LFN push esi edi
mov ebp, esp push 0
push 0 ; for fat_get_name: read ASCII name push 0
mov eax, [ROOT_CLUSTER] ; start from root push fat16_root_first
.mainloop: push fat16_root_next
.new_cluster: mov eax, [ROOT_CLUSTER]
mov [cluster_tmp], eax cmp [fat_type], 32
mov [fat16_root], 0 jz .fat32
cmp eax, [LAST_CLUSTER] .loop:
ja .notfound call fat_find_lfn
cmp eax, 2 jc .notfound
jae .data_cluster cmp byte [esi], 0
cmp [fat_type], 16
jnz .notfound
mov eax, [ROOT_START]
mov ecx, [ROOT_SECTORS]
mov [fat16_root], 1
jmp .new_sector
.data_cluster:
dec eax
dec eax
mov ecx, [SECTORS_PER_CLUSTER]
mul ecx
add eax, [DATA_START]
.new_sector:
mov ebx, buffer
call hd_read
cmp [hd_error],0
jne .notfound
mov edi, ebx
add ebx, 512
push eax
.l1:
call fat_get_name
jc .l2
call fat_compare_name
jz .found jz .found
.l2: test byte [edi+11], 10h
add edi, 0x20 jz .notfound
cmp edi, ebx and dword [esp+12], 0
jb .l1 movzx eax, word [edi+26] ; cluster
pop eax .fat32:
inc eax mov [esp+8], eax
loop .new_sector mov dword [esp+4], fat_notroot_first
cmp [fat16_root], 0 mov dword [esp], fat_notroot_next
jnz .notfound jmp .loop
mov eax, [cluster_tmp]
call get_FAT
cmp [hd_error],0
jne .notfound
cmp eax, 2
jb .notfound
cmp eax, [fatRESERVED]
jb .new_cluster
.notfound: .notfound:
add esp, 262*2+4 add esp, 16
popa pop edi esi
stc stc
ret ret
.found: .found:
pop eax add esp, 20 ; CF=0
; if this is LFN entry, advance to true entry pop esi
cmp byte [edi+11], 0xF
jnz .entryfound
add edi, 0x20
cmp edi, ebx
jb .entryfound
inc eax
dec ecx
jnz .read_entry
cmp [fat16_root], 0
jnz .notfound
mov eax, [cluster_tmp]
call get_FAT
cmp [hd_error],0
jne .notfound
cmp eax, 2
jb .notfound
cmp eax, [fatRESERVED]
jae .notfound
dec eax
dec eax
mul [SECTORS_PER_CLUSTER]
add eax, [DATA_START]
.read_entry:
mov ebx, [buffer]
call hd_read
cmp [hd_error],0
jne .notfound
mov edi, ebx
.entryfound:
cmp byte [esi], 0
jz .done
test byte [edi+11], 10h ; is a directory?
jz .notfound
mov eax, [edi+20-2]
mov ax, [edi+26]
jmp .mainloop
.done:
add esp, 262*2+4+4 ; CF=0
push edi
popad
ret ret
;---------------------------------------------------------------- ;----------------------------------------------------------------
@ -3366,4 +3291,620 @@ fs_HdReadFolder:
pop ecx esi edi pop ecx esi edi
ret ret
fat16_root_next:
cmp edi, buffer+0x200-0x20
jae fat16_root_next_sector
add edi, 0x20
ret ; CF=0
fat16_root_next_sector:
; read next sector
push ecx
mov ecx, [eax+4]
inc ecx
mov [eax+4], ecx
cmp ecx, [ROOT_SECTORS]
pop ecx
jae fat16_root_first.readerr
fat16_root_first:
mov eax, [eax+4]
add eax, [ROOT_START]
push ebx
mov edi, buffer
mov ebx, edi
call hd_read
pop ebx
cmp [hd_error], 0
jnz .readerr
ret ; CF=0
.readerr:
stc
ret
fat16_root_begin_write:
push edi eax
call fat16_root_first
pop eax edi
ret
fat16_root_end_write:
pusha
mov eax, [eax+4]
add eax, [ROOT_START]
mov ebx, buffer
call hd_write
popa
ret
fat16_root_next_write:
cmp edi, buffer+0x200
jae @f
ret
@@:
call fat16_root_end_write
jmp fat16_root_next_sector
fat16_root_extend_dir:
stc
ret
fat_notroot_next:
cmp edi, buffer+0x200-0x20
jae fat_notroot_next_sector
add edi, 0x20
ret ; CF=0
fat_notroot_next_sector:
push ecx
mov ecx, [eax+4]
inc ecx
cmp ecx, [SECTORS_PER_CLUSTER]
jae fat_notroot_next_cluster
mov [eax+4], ecx
jmp @f
fat_notroot_next_cluster:
push eax
mov eax, [eax]
call get_FAT
mov ecx, eax
pop eax
cmp [hd_error], 0
jnz fat_notroot_next_err
cmp ecx, [fatRESERVED]
jae fat_notroot_next_err
mov [eax], ecx
and dword [eax+4], 0
@@:
pop ecx
fat_notroot_first:
call fat_get_sector
push ebx
mov edi, buffer
mov ebx, edi
call hd_read
pop ebx
cmp [hd_error], 0
jnz @f
ret ; CF=0
fat_notroot_next_err:
pop ecx
@@:
stc
ret
fat_notroot_begin_write:
push eax edi
call fat_notroot_first
pop edi eax
ret
fat_notroot_end_write:
call fat_get_sector
push ebx
mov ebx, buffer
call hd_write
pop ebx
ret
fat_notroot_next_write:
cmp edi, buffer+0x200
jae @f
ret
@@:
push eax
call fat_notroot_end_write
pop eax
jmp fat_notroot_next_sector
fat_notroot_extend_dir:
push eax
mov eax, [eax]
call get_free_FAT
jnc .found
pop eax
ret ; CF=1
.found:
push edx
mov edx, [fatEND]
call set_FAT
mov edx, eax
mov eax, [esp+4]
mov eax, [eax]
push edx
mov [f_del], 1
call set_FAT
pop edx
cmp [hd_error], 0
jz @f
pop edx
pop eax
stc
ret
@@:
push ecx
or ecx, -1
call add_disk_free_space
; zero new cluster
mov ecx, 512/4
mov edi, buffer
push edi
xor eax, eax
rep stosd
pop edi
pop ecx
mov eax, [esp+4]
mov [eax], edx
and dword [eax+4], 0
pop edx
mov eax, [eax]
dec eax
dec eax
push ebx ecx
mov ecx, [SECTORS_PER_CLUSTER]
imul eax, ecx
add eax, [DATA_START]
mov ebx, edi
@@:
call hd_write
inc eax
loop @b
pop ecx ebx eax
clc
ret
fat_get_sector:
push ecx
mov ecx, [eax]
dec ecx
dec ecx
imul ecx, [SECTORS_PER_CLUSTER]
add ecx, [DATA_START]
add ecx, [eax+4]
mov eax, ecx
pop ecx
ret
;----------------------------------------------------------------
;
; fs_HdRewrite - LFN variant for writing hard disk
;
; esi points to filename
; ebx ignored (reserved)
; ecx number of bytes to write, 0+
; edx mem location to data
;
; ret ebx = number of written bytes
; eax = 0 ok read or other = errormsg
;
;--------------------------------------------------------------
fshrad:
mov eax, ERROR_ACCESS_DENIED
xor ebx, ebx
ret
fshrfs:
mov eax, ERROR_UNKNOWN_FS
xor ebx, ebx
ret
fs_HdRewrite:
cmp [fat_type], 0
jz fshrfs
cmp byte [esi], 0
jz fshrad
pushad
xor ebp, ebp
push esi
@@:
lodsb
test al, al
jz @f
cmp al, '/'
jnz @b
lea ebp, [esi-1]
jmp @b
@@:
pop esi
test ebp, ebp
jnz .noroot
mov ebp, [ROOT_CLUSTER]
cmp [fat_type], 32
jz .pushnotroot
push fat16_root_extend_dir
push fat16_root_end_write
push fat16_root_next_write
push fat16_root_begin_write
xor ebp, ebp
push ebp
push ebp
push fat16_root_first
push fat16_root_next
jmp .common1
.noroot:
; check existence
mov byte [ebp], 0
call hd_find_lfn
mov byte [ebp], '/'
lea esi, [ebp+1]
jnc @f
mov eax, ERROR_FILE_NOT_FOUND
.ret1:
mov [esp+28], eax
popad
xor ebx, ebx
ret
@@:
test byte [edi+11], 0x10 ; must be directory
mov eax, ERROR_ACCESS_DENIED
jz .ret1
mov ebp, [edi+20-2]
mov bp, [edi+26] ; ebp=cluster
mov eax, ERROR_FAT_TABLE
cmp ebp, 2
jb .ret1
.pushnotroot:
push fat_notroot_extend_dir
push fat_notroot_end_write
push fat_notroot_next_write
push fat_notroot_begin_write
push 0
push ebp
push fat_notroot_first
push fat_notroot_next
.common1:
call fat_find_lfn
jc .notfound
; found, delete FAT chain
push edi
xor eax, eax
mov dword [edi+28], eax ; zero size
xor ecx, ecx
mov eax, [edi+20-2]
mov ax, [edi+26]
mov word [edi+20], cx
mov word [edi+26], cx
test eax, eax
jz .done1
mov [f_del], 1
@@:
cmp eax, [fatRESERVED]
jae .done1
push edx
xor edx, edx
call set_FAT
mov eax, edx
pop edx
inc ecx
jmp @b
.done1:
pop edi
call get_time_for_file
mov [edi+22], ax
call get_date_for_file
mov [edi+24], ax
mov [edi+18], ax
or byte [edi+11], 20h ; set 'archive' attribute
jmp .doit
.notfound:
; file is not found; generate short name
call fat_name_is_legal
jc @f
add esp, 32
popad
mov eax, ERROR_FILE_NOT_FOUND
xor ebx, ebx
ret
@@:
sub esp, 12
mov edi, esp
call fat_gen_short_name
.test_short_name_loop:
push esi edi ecx
mov esi, edi
lea eax, [esp+12+12+8]
mov [eax], ebp
and dword [eax+4], 0
call dword [eax-4]
jc .found
.test_short_name_entry:
cmp byte [edi+11], 0xF
jz .test_short_name_cont
mov ecx, 11
push esi edi
repz cmpsb
pop edi esi
jz .short_name_found
.test_short_name_cont:
lea eax, [esp+12+12+8]
call dword [eax-8]
jnc .test_short_name_entry
jmp .found
.short_name_found:
pop ecx edi esi
call fat_next_short_name
jnc .test_short_name_loop
.disk_full:
add esp, 12+32
popa
mov eax, ERROR_DISK_FULL
xor ebx, ebx
ret
.found:
pop ecx edi esi
; now find space in directory
; we need to save LFN <=> LFN is not equal to short name <=> generated name contains '~'
mov al, '~'
push ecx edi
mov ecx, 8
repnz scasb
push 1
pop eax ; 1 entry
jnz .notilde
; we need ceil(strlen(esi)/13) additional entries = floor((strlen(esi)+12+13)/13) total
xor eax, eax
@@:
cmp byte [esi], 0
jz @f
inc esi
inc eax
jmp @b
@@:
sub esi, eax
add eax, 12+13
mov ecx, 13
push edx
cdq
div ecx
pop edx
.notilde:
push -1
push -1
push -1
; find <eax> successive entries in directory
xor ecx, ecx
push eax
lea eax, [esp+16+8+12+8]
mov [eax], ebp
and dword [eax+4], 0
call dword [eax-4]
pop eax
jnc .scan_dir
.fsfrfe3:
add esp, 12+8+12+32
popad
mov eax, 11
xor ebx, ebx
ret
.scan_dir:
cmp byte [edi], 0
jz .free
cmp byte [edi], 0xE5
jz .free
xor ecx, ecx
.scan_cont:
push eax
lea eax, [esp+16+8+12+8]
call dword [eax-8]
pop eax
jnc .scan_dir
cmp [hd_error], 0
jnz .fsfrfe3
push eax
lea eax, [esp+16+8+12+8]
call dword [eax+20] ; extend directory
pop eax
jnc .scan_dir
add esp, 12+8+12+32
popad
mov eax, ERROR_DISK_FULL
xor ebx, ebx
ret
.free:
test ecx, ecx
jnz @f
mov [esp], edi
mov ecx, [esp+12+8+12+8]
mov [esp+4], ecx
mov ecx, [esp+12+8+12+12]
mov [esp+8], ecx
xor ecx, ecx
@@:
inc ecx
cmp ecx, eax
jb .scan_cont
; found!
; calculate name checksum
push esi ecx
mov esi, [esp+8+12]
mov ecx, 11
xor eax, eax
@@:
ror al, 1
add al, [esi]
inc esi
loop @b
pop ecx esi
pop edi
pop dword [esp+8+12+12]
pop dword [esp+8+12+12]
; edi points to first entry in free chunk
dec ecx
jz .nolfn
push esi
push eax
lea eax, [esp+8+8+12+8]
call dword [eax+8] ; begin write
mov al, 40h
.writelfn:
or al, cl
mov esi, [esp+4]
push ecx
dec ecx
imul ecx, 13
add esi, ecx
stosb
mov cl, 5
call fs_RamdiskRewrite.read_symbols
mov ax, 0xF
stosw
mov al, [esp+4]
stosb
mov cl, 6
call fs_RamdiskRewrite.read_symbols
xor eax, eax
stosw
mov cl, 2
call fs_RamdiskRewrite.read_symbols
pop ecx
lea eax, [esp+8+8+12+8]
call dword [eax+12] ; next write
xor eax, eax
loop .writelfn
pop eax
pop esi
; lea eax, [esp+8+12+8]
; call dword [eax+16] ; end write
.nolfn:
xchg esi, [esp]
mov ecx, 11
rep movsb
mov word [edi], 20h ; attributes
sub edi, 11
pop esi ecx
add esp, 12
mov byte [edi+13], 0 ; tenths of a second at file creation time
call get_time_for_file
mov [edi+14], ax ; creation time
mov [edi+22], ax ; last write time
call get_date_for_file
mov [edi+16], ax ; creation date
mov [edi+24], ax ; last write date
mov [edi+18], ax ; last access date
xor ecx, ecx
mov word [edi+20], cx ; high word of cluster
mov word [edi+26], cx ; low word of cluster - to be filled
mov dword [edi+28], ecx ; file size - to be filled
.doit:
lea eax, [esp+8]
call dword [eax+16] ; flush directory
push ecx
mov ecx, [esp+4+32+24]
push ecx
push edi
mov esi, edx
test ecx, ecx
jz .done
mov eax, 2
call get_free_FAT
jc .diskfull
push eax
mov [edi+26], ax
shr eax, 16
mov [edi+20], ax
lea eax, [esp+16+8]
call dword [eax+16] ; flush directory
pop eax
push edx
mov edx, [fatEND]
call set_FAT
pop edx
.write_cluster:
push eax
dec eax
dec eax
mov ebp, [SECTORS_PER_CLUSTER]
imul eax, ebp
add eax, [DATA_START]
; write data
.write_sector:
mov ecx, 512
cmp dword [esp+8], ecx
jb .writeshort
; we can write directly from given buffer
mov ebx, esi
add esi, ecx
jmp .writecommon
.writeshort:
mov ecx, [esp+8]
push ecx
mov edi, buffer
mov ebx, edi
rep movsb
mov ecx, buffer+0x200
sub ecx, edi
push eax
xor eax, eax
rep stosb
pop eax
pop ecx
.writecommon:
call hd_write
cmp [hd_error], 0
jnz .writeerr
inc eax
sub dword [esp+8], ecx
jz .writedone
dec ebp
jnz .write_sector
; allocate new cluster
pop eax
mov ecx, eax
call get_free_FAT
jc .diskfull
mov [f_del], 1
push edx
mov edx, [fatEND]
call set_FAT
xchg eax, ecx
mov edx, ecx
call set_FAT
pop edx
xchg eax, ecx
jmp .write_cluster
.diskfull:
mov eax, ERROR_DISK_FULL
jmp .ret
.writeerr:
pop eax
sub esi, ecx
mov eax, 11
jmp .ret
.writedone:
pop eax
.done:
xor eax, eax
.ret:
pop edi ecx
mov ebx, esi
sub ebx, edx
pop ebp
mov [esp+32+28], eax
lea eax, [esp+8]
call dword [eax+8]
mov [edi+28], ebx
call dword [eax+16]
mov [esp+32+16], ebx
lea eax, [ebx+511]
shr eax, 9
mov ecx, [SECTORS_PER_CLUSTER]
lea eax, [eax+ecx-1]
xor edx, edx
div ecx
mov ecx, ebp
sub ecx, eax
call add_disk_free_space
add esp, 32
call update_disk
popad
ret
; \end{diamond} ; \end{diamond}

View File

@ -61,6 +61,7 @@ file_system:
; eax = 8 : disk full ; eax = 8 : disk full
; eax = 9 : fat table corrupted ; eax = 9 : fat table corrupted
; eax = 10 : access denied ; eax = 10 : access denied
; eax = 11 : disk error
; ;
; ebx = size ; ebx = size

View File

@ -51,13 +51,13 @@ file_system_lfn:
; operation codes: ; operation codes:
; 0 : read file ; 0 : read file
; 1 : read folder ; 1 : read folder
; 2 : rewrite file - not implemented yet ; 2 : create/rewrite file
; 3 : write/append to file - not implemented yet ; 3 : write/append to file - not implemented yet
; 4 : start application - not implemented yet ; 4 : delete file - not implemented yet
; 5 : delete file - not implemented yet ; 5 : create directory - not implemented yet
; 6 : create directory - not implemented yet ; 6 : rename file/directory - not implemented yet
; 7 : rename file/directory - not implemented yet ; 7 : get file attributes structure - not implemented yet
; 8 : get file attributes structure - not implemented yet ; 8 : start application - not implemented yet
add eax, std_application_base_address add eax, std_application_base_address
; parse file name ; parse file name
@ -290,8 +290,8 @@ fs_OnRamdisk:
cmp ecx, 1 cmp ecx, 1
jnz file_system_lfn.notfound jnz file_system_lfn.notfound
mov eax, [ebx] mov eax, [ebx]
cmp eax, 1 cmp eax, fs_NumRamdiskServices
ja .not_impl jae .not_impl
mov ecx, [ebx+12] mov ecx, [ebx+12]
mov edx, [ebx+16] mov edx, [ebx+16]
add edx, std_application_base_address add edx, std_application_base_address
@ -307,13 +307,15 @@ fs_OnRamdisk:
fs_RamdiskServices: fs_RamdiskServices:
dd fs_RamdiskRead dd fs_RamdiskRead
dd fs_RamdiskReadFolder dd fs_RamdiskReadFolder
dd fs_RamdiskRewrite
fs_NumRamdiskServices = ($ - fs_RamdiskServices)/4
fs_OnFloppy: fs_OnFloppy:
cmp ecx, 2 cmp ecx, 2
ja file_system_lfn.notfound ja file_system_lfn.notfound
mov eax, [ebx] mov eax, [ebx]
cmp eax, 1 cmp eax, fs_NumFloppyServices
ja fs_OnRamdisk.not_impl jae fs_OnRamdisk.not_impl
call reserve_flp call reserve_flp
mov [flp_number], cl mov [flp_number], cl
mov ecx, [ebx+12] mov ecx, [ebx+12]
@ -329,6 +331,8 @@ fs_OnFloppy:
fs_FloppyServices: fs_FloppyServices:
dd fs_FloppyRead dd fs_FloppyRead
dd fs_FloppyReadFolder dd fs_FloppyReadFolder
dd fs_FloppyRewrite
fs_NumFloppyServices = ($ - fs_FloppyServices)/4
fs_OnHd0: fs_OnHd0:
call reserve_hd1 call reserve_hd1
@ -373,8 +377,8 @@ fs_OnHd:
mov edx, [ebx+16] mov edx, [ebx+16]
add edx, std_application_base_address add edx, std_application_base_address
mov eax, [ebx] mov eax, [ebx]
cmp eax, 1 cmp eax, fs_NumHdServices
ja .not_impl jae .not_impl
add ebx, 4 add ebx, 4
call dword [fs_HdServices + eax*4] call dword [fs_HdServices + eax*4]
and [hd1_status], 0 and [hd1_status], 0
@ -389,6 +393,8 @@ fs_OnHd:
fs_HdServices: fs_HdServices:
dd fs_HdRead dd fs_HdRead
dd fs_HdReadFolder dd fs_HdReadFolder
dd fs_HdRewrite
fs_NumHdServices = ($ - fs_HdServices)/4
fs_HasRamdisk: fs_HasRamdisk:
mov al, 1 ; we always have ramdisk mov al, 1 ; we always have ramdisk