Subversion Repositories Kolibri OS

Rev

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