Rev 5565 | Rev 5596 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
4287 | Serge | 1 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
2 | ;; ;; |
||
5565 | serge | 3 | ;; Copyright (C) KolibriOS team 2004-2015. All rights reserved. ;; |
4287 | Serge | 4 | ;; Distributed under terms of the GNU General Public License ;; |
5 | ;; ;; |
||
6 | ;; FAT functions for KolibriOS ;; |
||
7 | ;; ;; |
||
8 | ;; Copyright 2002 Paolo Minazzi, paolo.minazzi@inwind.it ;; |
||
9 | ;; ;; |
||
10 | ;; See file COPYING for details ;; |
||
5594 | serge | 11 | ;; 06.2015 fs_read64 - pathoswithin ;; |
4287 | Serge | 12 | ;; 04.02.2007 LFN create folder - diamond ;; |
13 | ;; 08.10.2006 LFN delete file/folder - diamond ;; |
||
14 | ;; 20.08.2006 LFN set file size (truncate/extend) - diamond ;; |
||
15 | ;; 17.08.2006 LFN write/append to file - diamond ;; |
||
16 | ;; 23.06.2006 LFN start application - diamond ;; |
||
17 | ;; 15.06.2006 LFN get/set file/folder info - diamond ;; |
||
18 | ;; 27.05.2006 LFN create/rewrite file - diamond ;; |
||
19 | ;; 04.05.2006 LFN read folder - diamond ;; |
||
20 | ;; 29.04.2006 Elimination of hangup after the ;; |
||
21 | ;; expiration hd_wait_timeout - Mario79 ;; |
||
22 | ;; 23.04.2006 LFN read file - diamond ;; |
||
23 | ;; 28.01.2006 find all Fat16/32 partition in all input point ;; |
||
24 | ;; to MBR, see file part_set.inc - Mario79 ;; |
||
25 | ;; 15.01.2005 get file size/attr/date, file_append - ATV ;; |
||
26 | ;; 04.12.2004 skip volume label, file delete bug fixed - ATV ;; |
||
27 | ;; 29.11.2004 get_free_FAT changed, append dir bug fixed - ATV ;; |
||
28 | ;; 23.11.2004 don't allow overwrite dir with file - ATV ;; |
||
29 | ;; 18.11.2004 get_disk_info and more error codes - ATV ;; |
||
30 | ;; 17.11.2004 set_FAT/get_FAT and disk cache rewritten - ATV ;; |
||
31 | ;; 10.11.2004 removedir clear whole directory structure - ATV ;; |
||
32 | ;; 08.11.2004 rename - ATV ;; |
||
33 | ;; 30.10.2004 file_read return also dirsize in bytes - ATV ;; |
||
34 | ;; 20.10.2004 Makedir/Removedir - ATV ;; |
||
35 | ;; 14.10.2004 Partition chain/Fat16 - ATV (thanks drh3xx) ;; |
||
5594 | serge | 36 | ;; 06.09.2004 Fix free space - Mario79 ;; |
37 | ;; 24.05.2004 Write back buffer for File_write - VT ;; |
||
38 | ;; 20.05.2004 File_read function to work with syscall 58 - VT ;; |
||
39 | ;; 30.03.2004 Error parameters at function return - VT ;; |
||
40 | ;; 29.06.2002 Improved fat32 verification - VT ;; |
||
41 | ;; 20.05.2002 Hd status check - VT ;; |
||
42 | ;; 01.05.2002 Bugfix in device write - VT ;; |
||
4287 | Serge | 43 | ;; ;; |
5594 | serge | 44 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
4287 | Serge | 45 | |
46 | |||
47 | cache_max equ 1919 ; max. is 1919*512+0x610000=0x6ffe00 |
||
48 | |||
49 | PUSHAD_EAX equ [esp+28] |
||
50 | PUSHAD_ECX equ [esp+24] |
||
51 | PUSHAD_EDX equ [esp+20] |
||
52 | PUSHAD_EBX equ [esp+16] |
||
53 | PUSHAD_EBP equ [esp+8] |
||
54 | PUSHAD_ESI equ [esp+4] |
||
55 | PUSHAD_EDI equ [esp+0] |
||
56 | |||
57 | ; Internal data for every FAT partition. |
||
58 | struct FAT PARTITION |
||
59 | fs_type db ? |
||
60 | fat16_root db 0 ; flag for fat16 rootdir |
||
61 | fat_change db 0 ; 1=fat has changed |
||
5594 | serge | 62 | rb 1 |
4287 | Serge | 63 | Lock MUTEX ? ; currently operations with one partition |
5594 | serge | 64 | ; can not be executed in parallel since the legacy code is not ready |
4287 | Serge | 65 | SECTORS_PER_FAT dd 0x1f3a |
66 | NUMBER_OF_FATS dd 0x2 |
||
67 | SECTORS_PER_CLUSTER dd 0x8 |
||
68 | BYTES_PER_SECTOR dd 0x200 ; Note: if BPS <> 512 need lots of changes |
||
69 | ROOT_CLUSTER dd 2 ; first rootdir cluster |
||
70 | FAT_START dd 0 ; start of fat table |
||
71 | ROOT_START dd 0 ; start of rootdir (only fat16) |
||
72 | ROOT_SECTORS dd 0 ; count of rootdir sectors (only fat16) |
||
73 | DATA_START dd 0 ; start of data area (=first cluster 2) |
||
74 | LAST_CLUSTER dd 0 ; last availabe cluster |
||
75 | ADR_FSINFO dd 0 ; used only by fat32 |
||
76 | |||
77 | fatRESERVED dd 0x0FFFFFF6 |
||
78 | fatBAD dd 0x0FFFFFF7 |
||
79 | fatEND dd 0x0FFFFFF8 |
||
80 | fatMASK dd 0x0FFFFFFF |
||
81 | |||
82 | fatStartScan dd 2 |
||
83 | cluster_tmp dd 0 ; used by analyze_directory |
||
84 | ; and analyze_directory_to_write |
||
85 | longname_sec1 dd 0 ; used by analyze_directory to save 2 previous |
||
86 | longname_sec2 dd 0 ; directory sectors for delete long filename |
||
87 | fat_in_cache dd -1 |
||
88 | |||
89 | ; For FAT16/FAT32, this points to 512-byte buffer for the current sector of FAT. |
||
90 | ; For FAT12, the entire FAT structure is read |
||
91 | ; and unpacked from 12bit per cluster to word per cluster. |
||
5594 | serge | 92 | |
4287 | Serge | 93 | ; Note: work with unpacked copy of FAT12 means |
94 | ; additional memory and additional code for packing/unpacking. |
||
95 | ; I'm not sure that the economy justifies the cost, but anyway, |
||
96 | ; there is how work was done before my edits, and I'm just keeping the principle. |
||
97 | fat_cache_ptr dd ? |
||
98 | fat12_unpacked_ptr dd ? |
||
99 | buffer rb 512 |
||
100 | fsinfo_buffer rb 512 |
||
101 | ends |
||
102 | |||
103 | uglobal |
||
104 | align 4 |
||
105 | partition_count dd 0 ; partitions found by set_FAT32_variables |
||
5594 | serge | 106 | hd_error dd 0 |
4287 | Serge | 107 | hd_setup dd 0 |
108 | hd_wait_timeout dd 0 |
||
109 | cache_search_start dd 0 ; used by find_empty_slot |
||
110 | endg |
||
111 | |||
112 | uglobal |
||
113 | align 4 |
||
5594 | serge | 114 | Sector512: ; label for dev_hdcd.inc |
115 | buffer: |
||
116 | rb 512 |
||
4287 | Serge | 117 | endg |
118 | |||
119 | iglobal |
||
120 | align 4 |
||
121 | fat_user_functions: |
||
122 | dd fat_free |
||
123 | dd (fat_user_functions_end - fat_user_functions - 4) / 4 |
||
124 | dd fat_Read |
||
125 | dd fat_ReadFolder |
||
126 | dd fat_Rewrite |
||
127 | dd fat_Write |
||
128 | dd fat_SetFileEnd |
||
129 | dd fat_GetFileInfo |
||
130 | dd fat_SetFileInfo |
||
131 | dd 0 |
||
132 | dd fat_Delete |
||
133 | dd fat_CreateFolder |
||
134 | fat_user_functions_end: |
||
135 | endg |
||
136 | |||
137 | ; these labels are located before the main function to make |
||
138 | ; most of jumps to these be short |
||
139 | fat_create_partition.free_return0: |
||
140 | mov eax, ebp |
||
141 | call free |
||
142 | pop ebp |
||
143 | fat_create_partition.return0: |
||
144 | xor eax, eax |
||
145 | ret |
||
146 | fat_create_partition: |
||
5201 | serge | 147 | ; sector size must be 512 |
148 | cmp dword [esi+DISK.MediaInfo.SectorSize], 512 |
||
149 | jnz .return0 |
||
4287 | Serge | 150 | ; bootsector must have been successfully read |
151 | cmp dword [esp+4], 0 |
||
152 | jnz .return0 |
||
153 | ; bootsector signature must be correct |
||
154 | cmp word [ebx+0x1fe], 0xaa55 |
||
155 | jnz .return0 |
||
156 | ; sectors per cluster must be nonzero |
||
157 | cmp byte [ebx+0xd], 0 |
||
158 | jz .return0 |
||
159 | ; bytes per sector must be 0x200 |
||
160 | cmp word [ebx+0xb], 0x200 |
||
161 | jnz .return0 |
||
162 | ; number of fats must be nonzero |
||
163 | cmp byte [ebx+0x10], 0 |
||
164 | jz .return0 |
||
165 | ; The only reason to be invalid partition now is FAT12. Since the test for |
||
166 | ; FAT size requires knowledge of some calculated values, which are also used |
||
167 | ; in the normal operation, let's hope for the best and allocate data now; if |
||
168 | ; it will prove wrong, just deallocate it. |
||
169 | movi eax, sizeof.FAT |
||
170 | call malloc |
||
171 | test eax, eax |
||
172 | jz .return0 |
||
173 | mov ecx, dword [ebp+PARTITION.FirstSector] |
||
174 | mov dword [eax+FAT.FirstSector], ecx |
||
175 | mov ecx, dword [ebp+PARTITION.FirstSector+4] |
||
176 | mov dword [eax+FAT.FirstSector+4], ecx |
||
177 | mov ecx, dword [ebp+PARTITION.Length] |
||
178 | mov dword [eax+FAT.Length], ecx |
||
179 | mov ecx, dword [ebp+PARTITION.Length+4] |
||
180 | mov dword [eax+FAT.Length+4], ecx |
||
181 | mov ecx, [ebp+PARTITION.Disk] |
||
182 | mov [eax+FAT.Disk], ecx |
||
183 | mov [eax+FAT.FSUserFunctions], fat_user_functions |
||
184 | or [eax+FAT.fat_in_cache], -1 |
||
185 | mov [eax+FAT.fat_change], 0 |
||
186 | push ebp |
||
187 | mov ebp, eax |
||
188 | |||
189 | lea ecx, [ebp+FAT.Lock] |
||
190 | call mutex_init |
||
191 | |||
192 | movzx eax, word [ebx+0xe] ; sectors reserved |
||
193 | mov [ebp+FAT.FAT_START], eax |
||
194 | |||
195 | movzx eax, byte [ebx+0xd] ; sectors per cluster |
||
196 | mov [ebp+FAT.SECTORS_PER_CLUSTER], eax |
||
197 | |||
198 | movzx ecx, word [ebx+0xb] ; bytes per sector |
||
199 | mov [ebp+FAT.BYTES_PER_SECTOR], ecx |
||
200 | |||
201 | movzx eax, word [ebx+0x11] ; count of rootdir entries (=0 fat32) |
||
202 | shl eax, 5 ; mul 32 |
||
203 | dec ecx |
||
204 | add eax, ecx ; round up if not equal count |
||
205 | inc ecx ; bytes per sector |
||
206 | xor edx, edx |
||
207 | div ecx |
||
208 | mov [ebp+FAT.ROOT_SECTORS], eax ; count of rootdir sectors |
||
209 | |||
210 | movzx eax, word [ebx+0x16] ; sectors per fat <65536 |
||
211 | test eax, eax |
||
212 | jnz @f |
||
213 | mov eax, [ebx+0x24] ; sectors per fat |
||
214 | @@: |
||
215 | mov [ebp+FAT.SECTORS_PER_FAT], eax |
||
216 | |||
217 | movzx eax, byte [ebx+0x10] ; number of fats |
||
218 | mov [ebp+FAT.NUMBER_OF_FATS], eax |
||
219 | mul [ebp+FAT.SECTORS_PER_FAT] |
||
220 | test edx, edx |
||
221 | jnz .free_return0 |
||
222 | add eax, [ebp+FAT.FAT_START] |
||
223 | jc .free_return0 |
||
224 | mov [ebp+FAT.ROOT_START], eax ; rootdir = fat_start + fat_size * fat_count |
||
225 | add eax, [ebp+FAT.ROOT_SECTORS] ; rootdir sectors should be 0 on fat32 |
||
226 | jc .free_return0 |
||
227 | mov [ebp+FAT.DATA_START], eax ; data area = rootdir + rootdir_size |
||
228 | |||
229 | movzx eax, word [ebx+0x13] ; total sector count <65536 |
||
230 | test eax, eax |
||
231 | jnz @f |
||
232 | mov eax, [ebx+0x20] ; total sector count |
||
233 | @@: |
||
234 | ; total sector count must not exceed partition size |
||
235 | cmp dword [ebp+FAT.Length+4], 0 |