Subversion Repositories Kolibri OS

Rev

Rev 3725 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 3725 Rev 3908
1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                                 ;;
2
;;                                                                 ;;
3
;; Copyright (C) KolibriOS team 2004-2011. All rights reserved.    ;;
3
;; Copyright (C) KolibriOS team 2004-2013. All rights reserved.    ;;
4
;; Distributed under terms of the GNU General Public License       ;;
4
;; Distributed under terms of the GNU General Public License       ;;
5
;;                                                                 ;;
5
;;                                                                 ;;
6
;;  FAT32.INC                                                      ;;
6
;;  FAT32.INC                                                      ;;
7
;;                                                                 ;;
7
;;                                                                 ;;
8
;;  FAT16/32 functions for KolibriOS                               ;;
8
;;  FAT16/32 functions for KolibriOS                               ;;
9
;;                                                                 ;;
9
;;                                                                 ;;
10
;;  Copyright 2002 Paolo Minazzi, paolo.minazzi@inwind.it          ;;
10
;;  Copyright 2002 Paolo Minazzi, paolo.minazzi@inwind.it          ;;
11
;;                                                                 ;;
11
;;                                                                 ;;
12
;;  See file COPYING for details                                   ;;
12
;;  See file COPYING for details                                   ;;
13
;;  04.02.2007 LFN create folder - diamond                         ;;
13
;;  04.02.2007 LFN create folder - diamond                         ;;
14
;;  08.10.2006 LFN delete file/folder - diamond                    ;;
14
;;  08.10.2006 LFN delete file/folder - diamond                    ;;
15
;;  20.08.2006 LFN set file size (truncate/extend) - diamond       ;;
15
;;  20.08.2006 LFN set file size (truncate/extend) - diamond       ;;
16
;;  17.08.2006 LFN write/append to file - diamond                  ;;
16
;;  17.08.2006 LFN write/append to file - diamond                  ;;
17
;;  23.06.2006 LFN start application - diamond                     ;;
17
;;  23.06.2006 LFN start application - diamond                     ;;
18
;;  15.06.2006 LFN get/set file/folder info - diamond              ;;
18
;;  15.06.2006 LFN get/set file/folder info - diamond              ;;
19
;;  27.05.2006 LFN create/rewrite file - diamond                   ;;
19
;;  27.05.2006 LFN create/rewrite file - diamond                   ;;
20
;;  04.05.2006 LFN read folder - diamond                           ;;
20
;;  04.05.2006 LFN read folder - diamond                           ;;
21
;;  29.04.2006 Elimination of hangup after the                     ;;
21
;;  29.04.2006 Elimination of hangup after the                     ;;
22
;;             expiration hd_wait_timeout -  Mario79               ;;
22
;;             expiration hd_wait_timeout -  Mario79               ;;
23
;;  23.04.2006 LFN read file - diamond                             ;;
23
;;  23.04.2006 LFN read file - diamond                             ;;
24
;;  28.01.2006 find all Fat16/32 partition in all input point      ;;
24
;;  28.01.2006 find all Fat16/32 partition in all input point      ;;
25
;;             to MBR, see file part_set.inc - Mario79             ;;
25
;;             to MBR, see file part_set.inc - Mario79             ;;
26
;;  15.01.2005 get file size/attr/date, file_append - ATV          ;;
26
;;  15.01.2005 get file size/attr/date, file_append - ATV          ;;
27
;;  04.12.2004 skip volume label, file delete bug fixed - ATV      ;;
27
;;  04.12.2004 skip volume label, file delete bug fixed - ATV      ;;
28
;;  29.11.2004 get_free_FAT changed, append dir bug fixed - ATV    ;;
28
;;  29.11.2004 get_free_FAT changed, append dir bug fixed - ATV    ;;
29
;;  23.11.2004 don't allow overwrite dir with file - ATV           ;;
29
;;  23.11.2004 don't allow overwrite dir with file - ATV           ;;
30
;;  18.11.2004 get_disk_info and more error codes - ATV            ;;
30
;;  18.11.2004 get_disk_info and more error codes - ATV            ;;
31
;;  17.11.2004 set_FAT/get_FAT and disk cache rewritten - ATV      ;;
31
;;  17.11.2004 set_FAT/get_FAT and disk cache rewritten - ATV      ;;
32
;;  10.11.2004 removedir clear whole directory structure - ATV     ;;
32
;;  10.11.2004 removedir clear whole directory structure - ATV     ;;
33
;;  08.11.2004 rename - ATV                                        ;;
33
;;  08.11.2004 rename - ATV                                        ;;
34
;;  30.10.2004 file_read return also dirsize in bytes - ATV        ;;
34
;;  30.10.2004 file_read return also dirsize in bytes - ATV        ;;
35
;;  20.10.2004 Makedir/Removedir - ATV                             ;;
35
;;  20.10.2004 Makedir/Removedir - ATV                             ;;
36
;;  14.10.2004 Partition chain/Fat16 - ATV (thanks drh3xx)         ;;
36
;;  14.10.2004 Partition chain/Fat16 - ATV (thanks drh3xx)         ;;
37
;;  06.9.2004  Fix free space by Mario79 added - MH                ;;
37
;;  06.9.2004  Fix free space by Mario79 added - MH                ;;
38
;;  24.5.2004  Write back buffer for File_write -VT                ;;
38
;;  24.5.2004  Write back buffer for File_write -VT                ;;
39
;;  20.5.2004  File_read function to work with syscall 58 - VT     ;;
39
;;  20.5.2004  File_read function to work with syscall 58 - VT     ;;
40
;;  30.3.2004  Error parameters at function return - VT            ;;
40
;;  30.3.2004  Error parameters at function return - VT            ;;
41
;;  01.5.2002  Bugfix in device write - VT                         ;;
41
;;  01.5.2002  Bugfix in device write - VT                         ;;
42
;;  20.5.2002  Hd status check - VT                                ;;
42
;;  20.5.2002  Hd status check - VT                                ;;
43
;;  29.6.2002  Improved fat32 verification - VT                    ;;
43
;;  29.6.2002  Improved fat32 verification - VT                    ;;
44
;;                                                                 ;;
44
;;                                                                 ;;
45
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
45
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
46
 
46
 
47
$Revision: 3725 $
47
$Revision: 3908 $
48
 
48
 
49
 
49
 
50
cache_max equ 1919      ; max. is 1919*512+0x610000=0x6ffe00
50
cache_max equ 1919      ; max. is 1919*512+0x610000=0x6ffe00
51
 
51
 
52
PUSHAD_EAX equ [esp+28]
52
PUSHAD_EAX equ [esp+28]
53
PUSHAD_ECX equ [esp+24]
53
PUSHAD_ECX equ [esp+24]
54
PUSHAD_EDX equ [esp+20]
54
PUSHAD_EDX equ [esp+20]
55
PUSHAD_EBX equ [esp+16]
55
PUSHAD_EBX equ [esp+16]
56
PUSHAD_EBP equ [esp+8]
56
PUSHAD_EBP equ [esp+8]
57
PUSHAD_ESI equ [esp+4]
57
PUSHAD_ESI equ [esp+4]
58
PUSHAD_EDI equ [esp+0]
58
PUSHAD_EDI equ [esp+0]
59
 
59
 
60
; Internal data for every FAT partition.
60
; Internal data for every FAT partition.
61
struct FAT
61
struct FAT PARTITION
62
p       PARTITION       ; must be the first item
-
 
63
fs_type              db ?
62
fs_type              db ?
64
fat16_root           db 0       ; flag for fat16 rootdir
63
fat16_root           db 0       ; flag for fat16 rootdir
65
fat_change           db 0       ; 1=fat has changed
64
fat_change           db 0       ; 1=fat has changed
66
                     db ?       ; alignment
65
                     db ?       ; alignment
67
Lock                 MUTEX ?    ; currently operations with one partition
66
Lock                 MUTEX ?    ; currently operations with one partition
68
                                 ; can not be executed in parallel since the
67
                                ; can not be executed in parallel since the
69
                                 ; legacy code is not ready; this mutex guards
68
                                ; legacy code is not ready; this mutex guards
70
                                 ; all operations
69
                                ; all operations
71
SECTORS_PER_FAT      dd 0x1f3a
70
SECTORS_PER_FAT      dd 0x1f3a
72
NUMBER_OF_FATS       dd 0x2
71
NUMBER_OF_FATS       dd 0x2
73
SECTORS_PER_CLUSTER  dd 0x8
72
SECTORS_PER_CLUSTER  dd 0x8
74
BYTES_PER_SECTOR     dd 0x200   ; Note: if BPS <> 512 need lots of changes
73
BYTES_PER_SECTOR     dd 0x200   ; Note: if BPS <> 512 need lots of changes
75
ROOT_CLUSTER         dd 2       ; first rootdir cluster
74
ROOT_CLUSTER         dd 2       ; first rootdir cluster
76
FAT_START            dd 0       ; start of fat table
75
FAT_START            dd 0       ; start of fat table
77
ROOT_START           dd 0       ; start of rootdir (only fat16)
76
ROOT_START           dd 0       ; start of rootdir (only fat16)
78
ROOT_SECTORS         dd 0       ; count of rootdir sectors (only fat16)
77
ROOT_SECTORS         dd 0       ; count of rootdir sectors (only fat16)
79
DATA_START           dd 0       ; start of data area (=first cluster 2)
78
DATA_START           dd 0       ; start of data area (=first cluster 2)
80
LAST_CLUSTER         dd 0       ; last availabe cluster
79
LAST_CLUSTER         dd 0       ; last availabe cluster
81
ADR_FSINFO           dd 0       ; used only by fat32
80
ADR_FSINFO           dd 0       ; used only by fat32
82
 
81
 
83
fatRESERVED          dd 0x0FFFFFF6
82
fatRESERVED          dd 0x0FFFFFF6
84
fatBAD               dd 0x0FFFFFF7
83
fatBAD               dd 0x0FFFFFF7
85
fatEND               dd 0x0FFFFFF8
84
fatEND               dd 0x0FFFFFF8
86
fatMASK              dd 0x0FFFFFFF
85
fatMASK              dd 0x0FFFFFFF
87
 
86
 
88
fatStartScan         dd 2
87
fatStartScan         dd 2
89
 
88
 
90
cluster_tmp          dd 0       ; used by analyze_directory
89
cluster_tmp          dd 0       ; used by analyze_directory
91
                                ; and analyze_directory_to_write
90
                                ; and analyze_directory_to_write
92
 
91
 
93
longname_sec1        dd 0       ; used by analyze_directory to save 2 previous
92
longname_sec1        dd 0       ; used by analyze_directory to save 2 previous
94
longname_sec2        dd 0       ; directory sectors for delete long filename
93
longname_sec2        dd 0       ; directory sectors for delete long filename
95
 
94
 
96
fat_in_cache         dd -1
95
fat_in_cache         dd -1
97
 
96
 
98
fat_cache            rb 512
97
fat_cache            rb 512
99
buffer               rb 512
98
buffer               rb 512
100
fsinfo_buffer        rb 512
99
fsinfo_buffer        rb 512
101
ends
100
ends
102
 
101
 
103
uglobal
102
uglobal
104
align 4
103
align 4
105
partition_count      dd 0       ; partitions found by set_FAT32_variables
104
partition_count      dd 0       ; partitions found by set_FAT32_variables
106
 
105
 
107
hd_error             dd 0       ; set by wait_for_sector_buffer
106
hd_error             dd 0       ; set by wait_for_sector_buffer
108
hd_setup             dd 0
107
hd_setup             dd 0
109
hd_wait_timeout      dd 0
108
hd_wait_timeout      dd 0
110
 
109
 
111
cache_search_start   dd 0       ; used by find_empty_slot
110
cache_search_start   dd 0       ; used by find_empty_slot
112
endg
111
endg
113
 
112
 
114
uglobal
113
uglobal
115
align 4
114
align 4
116
 Sector512:                      ; label for dev_hdcd.inc
115
 Sector512:                      ; label for dev_hdcd.inc
117
  buffer:
116
  buffer:
118
                       times 512 db 0
117
                times 512 db 0
119
endg
118
endg
120
 
119
 
121
iglobal
120
iglobal
122
align 4
121
align 4
123
fat_user_functions:
122
fat_user_functions:
-
 
123
        dd      free
124
        dd      (fat_user_functions_end - fat_user_functions - 4) / 4
124
        dd      (fat_user_functions_end - fat_user_functions - 4) / 4
125
        dd      fat_Read
125
        dd      fat_Read
126
        dd      fat_ReadFolder
126
        dd      fat_ReadFolder
127
        dd      fat_Rewrite
127
        dd      fat_Rewrite
128
        dd      fat_Write
128
        dd      fat_Write
129
        dd      fat_SetFileEnd
129
        dd      fat_SetFileEnd
130
        dd      fat_GetFileInfo
130
        dd      fat_GetFileInfo
131
        dd      fat_SetFileInfo
131
        dd      fat_SetFileInfo
132
        dd      0
132
        dd      0
133
        dd      fat_Delete
133
        dd      fat_Delete
134
        dd      fat_CreateFolder
134
        dd      fat_CreateFolder
135
fat_user_functions_end:
135
fat_user_functions_end:
136
endg
136
endg
137
 
137
 
138
; these labels are located before the main function to make
138
; these labels are located before the main function to make
139
; most of jumps to these be short
139
; most of jumps to these be short
140
fat_create_partition.free_return0:
140
fat_create_partition.free_return0:
141
        push    ebx
-
 
142
        mov     eax, ebp
141
        mov     eax, ebp
143
        call    free
142
        call    free
144
        pop     ebx
-
 
145
        pop     ebp
143
        pop     ebp
146
fat_create_partition.return0:
144
fat_create_partition.return0:
147
        xor     eax, eax
145
        xor     eax, eax
148
        ret
146
        ret
149
fat_create_partition:
147
fat_create_partition:
150
; bootsector must have been successfully read
148
; bootsector must have been successfully read
151
        cmp     dword [esp+4], 1
149
        cmp     dword [esp+4], 0
152
        jnz     .return0
150
        jnz     .return0
153
; bootsector signature must be correct
151
; bootsector signature must be correct
154
        cmp     word [ebx+0x1fe], 0xaa55
152
        cmp     word [ebx+0x1fe], 0xaa55
155
        jnz     .return0
153
        jnz     .return0
156
; sectors per cluster must be nonzero
154
; sectors per cluster must be nonzero
157
        cmp     byte [ebx+0xd], 0
155
        cmp     byte [ebx+0xd], 0
158
        jz      .return0
156
        jz      .return0
159
; bytes per sector must be 0x200
157
; bytes per sector must be 0x200
160
        cmp     word [ebx+0xb], 0x200
158
        cmp     word [ebx+0xb], 0x200
161
        jnz     .return0
159
        jnz     .return0
162
; number of fats must be nonzero
160
; number of fats must be nonzero
163
        cmp     byte [ebx+0x10], 0
161
        cmp     byte [ebx+0x10], 0
164
        jz      .return0
162
        jz      .return0
165
; The only reason to be invalid partition now is FAT12. Since the test for
163
; 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
164
; 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
165
; in the normal operation, let's hope for the best and allocate data now; if
168
; it will prove wrong, just deallocate it.
166
; it will prove wrong, just deallocate it.
169
        movi    eax, sizeof.FAT
167
        movi    eax, sizeof.FAT
170
        call    malloc
168
        call    malloc
171
        test    eax, eax
169
        test    eax, eax
172
        jz      .return0
170
        jz      .return0
173
        mov     ecx, [ebp+8]
171
        mov     ecx, dword [ebp+PARTITION.FirstSector]
174
        mov     dword [eax+FAT.p.FirstSector], ecx
172
        mov     dword [eax+FAT.FirstSector], ecx
175
        mov     ecx, [ebp+12]
173
        mov     ecx, dword [ebp+PARTITION.FirstSector+4]
176
        mov     dword [eax+FAT.p.FirstSector+4], ecx
174
        mov     dword [eax+FAT.FirstSector+4], ecx
177
        mov     ecx, [ebp+16]
175
        mov     ecx, dword [ebp+PARTITION.Length]
178
        mov     dword [eax+FAT.p.Length], ecx
176
        mov     dword [eax+FAT.Length], ecx
179
        mov     ecx, [ebp+20]
177
        mov     ecx, dword [ebp+PARTITION.Length+4]
180
        mov     dword [eax+FAT.p.Length+4], ecx
178
        mov     dword [eax+FAT.Length+4], ecx
-
 
179
        mov     ecx, [ebp+PARTITION.Disk]
181
        mov     [eax+FAT.p.Disk], esi
180
        mov     [eax+FAT.Disk], ecx
182
        mov     [eax+FAT.p.FSUserFunctions], fat_user_functions
181
        mov     [eax+FAT.FSUserFunctions], fat_user_functions
183
        or      [eax+FAT.fat_in_cache], -1
182
        or      [eax+FAT.fat_in_cache], -1
184
        mov     [eax+FAT.fat_change], 0
183
        mov     [eax+FAT.fat_change], 0
185
        push    ebp
184
        push    ebp
186
        mov     ebp, eax
185
        mov     ebp, eax
187
 
186
 
188
        lea     ecx, [ebp+FAT.Lock]
187
        lea     ecx, [ebp+FAT.Lock]
189
        call    mutex_init
188
        call    mutex_init
190
 
189
 
191
        movzx   eax, word [ebx+0xe]     ; sectors reserved
190
        movzx   eax, word [ebx+0xe]     ; sectors reserved
192
        mov     [ebp+FAT.FAT_START], eax
191
        mov     [ebp+FAT.FAT_START], eax
193
 
192
 
194
        movzx   eax, byte [ebx+0xd]     ; sectors per cluster
193
        movzx   eax, byte [ebx+0xd]     ; sectors per cluster
195
        mov     [ebp+FAT.SECTORS_PER_CLUSTER], eax
194
        mov     [ebp+FAT.SECTORS_PER_CLUSTER], eax
196
 
195
 
197
        movzx   ecx, word [ebx+0xb]     ; bytes per sector
196
        movzx   ecx, word [ebx+0xb]     ; bytes per sector
198
        mov     [ebp+FAT.BYTES_PER_SECTOR], ecx
197
        mov     [ebp+FAT.BYTES_PER_SECTOR], ecx
199
 
198
 
200
        movzx   eax, word [ebx+0x11]    ; count of rootdir entries (=0 fat32)
199
        movzx   eax, word [ebx+0x11]    ; count of rootdir entries (=0 fat32)
201
        shl     eax, 5                  ; mul 32
200
        shl     eax, 5                  ; mul 32
202
        dec     ecx
201
        dec     ecx
203
        add     eax, ecx                ; round up if not equal count
202
        add     eax, ecx                ; round up if not equal count
204
        inc     ecx                     ; bytes per sector
203
        inc     ecx                     ; bytes per sector
205
        xor     edx, edx
204
        xor     edx, edx
206
        div     ecx
205
        div     ecx
207
        mov     [ebp+FAT.ROOT_SECTORS], eax     ; count of rootdir sectors
206
        mov     [ebp+FAT.ROOT_SECTORS], eax     ; count of rootdir sectors
208
 
207
 
209
        movzx   eax, word [ebx+0x16]    ; sectors per fat <65536
208
        movzx   eax, word [ebx+0x16]    ; sectors per fat <65536
210
        test    eax, eax
209
        test    eax, eax
211
        jnz     @f
210
        jnz     @f
212
        mov     eax, [ebx+0x24]         ; sectors per fat
211
        mov     eax, [ebx+0x24]         ; sectors per fat
213
@@:
212
@@:
214
        mov     [ebp+FAT.SECTORS_PER_FAT], eax
213
        mov     [ebp+FAT.SECTORS_PER_FAT], eax
215
 
214
 
216
        movzx   eax, byte [ebx+0x10]    ; number of fats
215
        movzx   eax, byte [ebx+0x10]    ; number of fats
217
        mov     [ebp+FAT.NUMBER_OF_FATS], eax
216
        mov     [ebp+FAT.NUMBER_OF_FATS], eax
218
        imul    eax, [ebp+FAT.SECTORS_PER_FAT]
217
        imul    eax, [ebp+FAT.SECTORS_PER_FAT]
219
        add     eax, [ebp+FAT.FAT_START]
218
        add     eax, [ebp+FAT.FAT_START]
220
        mov     [ebp+FAT.ROOT_START], eax       ; rootdir = fat_start + fat_size * fat_count
219
        mov     [ebp+FAT.ROOT_START], eax       ; rootdir = fat_start + fat_size * fat_count
221
        add     eax, [ebp+FAT.ROOT_SECTORS]     ; rootdir sectors should be 0 on fat32
220
        add     eax, [ebp+FAT.ROOT_SECTORS]     ; rootdir sectors should be 0 on fat32
222
        mov     [ebp+FAT.DATA_START], eax       ; data area = rootdir + rootdir_size
221
        mov     [ebp+FAT.DATA_START], eax       ; data area = rootdir + rootdir_size
223
 
222
 
224
        movzx   eax, word [ebx+0x13]    ; total sector count <65536
223
        movzx   eax, word [ebx+0x13]    ; total sector count <65536
225
        test    eax, eax
224
        test    eax, eax
226
        jnz     @f
225
        jnz     @f
227
        mov     eax, [ebx+0x20]         ; total sector count
226
        mov     eax, [ebx+0x20]         ; total sector count
228
@@:
227
@@:
229
        mov     dword [ebp+FAT.p.Length], eax
228
        mov     dword [ebp+FAT.Length], eax
230
        and     dword [ebp+FAT.p.Length+4], 0
229
        and     dword [ebp+FAT.Length+4], 0
231
        sub     eax, [ebp+FAT.DATA_START]       ; eax = count of data sectors
230
        sub     eax, [ebp+FAT.DATA_START]       ; eax = count of data sectors
232
        xor     edx, edx
231
        xor     edx, edx
233
        div     [ebp+FAT.SECTORS_PER_CLUSTER]
232
        div     [ebp+FAT.SECTORS_PER_CLUSTER]
234
        inc     eax
233
        inc     eax
235
        mov     [ebp+FAT.LAST_CLUSTER], eax
234
        mov     [ebp+FAT.LAST_CLUSTER], eax
236
        dec     eax                     ; cluster count
235
        dec     eax                     ; cluster count
237
        mov     [ebp+FAT.fatStartScan], 2
236
        mov     [ebp+FAT.fatStartScan], 2
238
 
237
 
239
        ; limits by Microsoft Hardware White Paper v1.03
238
        ; limits by Microsoft Hardware White Paper v1.03
240
        cmp     eax, 4085               ; 0xff5
239
        cmp     eax, 4085               ; 0xff5
241
        jb      .free_return0           ; fat12 not supported
240
        jb      .free_return0           ; fat12 not supported
242
        cmp     eax, 65525              ; 0xfff5
241
        cmp     eax, 65525              ; 0xfff5
243
        jb      .fat16
242
        jb      .fat16
244
.fat32:
243
.fat32:
245
        mov     eax, [ebx+0x2c]         ; rootdir cluster
244
        mov     eax, [ebx+0x2c]         ; rootdir cluster
246
        mov     [ebp+FAT.ROOT_CLUSTER], eax
245
        mov     [ebp+FAT.ROOT_CLUSTER], eax
247
        movzx   eax, word [ebx+0x30]
246
        movzx   eax, word [ebx+0x30]
248
        mov     [ebp+FAT.ADR_FSINFO], eax
247
        mov     [ebp+FAT.ADR_FSINFO], eax
249
        push    ebx
248
        push    ebx
250
        add     ebx, 512
249
        add     ebx, 512
251
        call    fs_read32_sys
250
        call    fs_read32_sys
252
        test    eax, eax
251
        test    eax, eax
253
        jnz     @f
252
        jnz     @f
254
        mov     eax, [ebx+0x1ec]
253
        mov     eax, [ebx+0x1ec]
255
        cmp     eax, -1
254
        cmp     eax, -1
256
        jz      @f
255
        jz      @f
257
        mov     [ebp+FAT.fatStartScan], eax
256
        mov     [ebp+FAT.fatStartScan], eax
258
@@:
257
@@:
259
        pop     ebx
258
        pop     ebx
260
        mov     [ebp+FAT.fatRESERVED], 0x0FFFFFF6
259
        mov     [ebp+FAT.fatRESERVED], 0x0FFFFFF6
261
        mov     [ebp+FAT.fatBAD], 0x0FFFFFF7
260
        mov     [ebp+FAT.fatBAD], 0x0FFFFFF7
262
        mov     [ebp+FAT.fatEND], 0x0FFFFFF8
261
        mov     [ebp+FAT.fatEND], 0x0FFFFFF8
263
        mov     [ebp+FAT.fatMASK], 0x0FFFFFFF
262
        mov     [ebp+FAT.fatMASK], 0x0FFFFFFF
264
        mov     al, 32
263
        mov     al, 32
265
        mov     [fs_type], al
-
 
266
        mov     [ebp+FAT.fs_type], al
264
        mov     [ebp+FAT.fs_type], al
267
        mov     eax, ebp
265
        mov     eax, ebp
268
        pop     ebp
266
        pop     ebp
269
        ret
267
        ret
270
.fat16:
268
.fat16:
271
        and     [ebp+FAT.ROOT_CLUSTER], 0
269
        and     [ebp+FAT.ROOT_CLUSTER], 0
272
        mov     [ebp+FAT.fatRESERVED], 0x0000FFF6
270
        mov     [ebp+FAT.fatRESERVED], 0x0000FFF6
273
        mov     [ebp+FAT.fatBAD], 0x0000FFF7
271
        mov     [ebp+FAT.fatBAD], 0x0000FFF7
274
        mov     [ebp+FAT.fatEND], 0x0000FFF8
272
        mov     [ebp+FAT.fatEND], 0x0000FFF8
275
        mov     [ebp+FAT.fatMASK], 0x0000FFFF
273
        mov     [ebp+FAT.fatMASK], 0x0000FFFF
276
        mov     al, 16
274
        mov     al, 16
277
        mov     [fs_type], al
-
 
278
        mov     [ebp+FAT.fs_type], al
275
        mov     [ebp+FAT.fs_type], al
279
        mov     eax, ebp
276
        mov     eax, ebp
280
        pop     ebp
277
        pop     ebp
281
        ret
278
        ret
282
 
279
 
283
set_FAT:
280
set_FAT:
284
;--------------------------------
281
;--------------------------------
285
; input  : EAX = cluster
282
; input  : EAX = cluster
286
;          EDX = value to save
283
;          EDX = value to save
287
;          EBP = pointer to FAT structure
284
;          EBP = pointer to FAT structure
288
; output : EDX = old value
285
; output : EDX = old value
289
;--------------------------------
286
;--------------------------------
290
; out: CF set <=> error
287
; out: CF set <=> error
291
        push    eax ebx esi
288
        push    eax ebx esi
292
 
289
 
293
        cmp     eax, 2
290
        cmp     eax, 2
294
        jb      sfc_error
291
        jb      sfc_error
295
        cmp     eax, [ebp+FAT.LAST_CLUSTER]
292
        cmp     eax, [ebp+FAT.LAST_CLUSTER]
296
        ja      sfc_error
293
        ja      sfc_error
297
        cmp     [ebp+FAT.fs_type], 16
294
        cmp     [ebp+FAT.fs_type], 16
298
        je      sfc_1
295
        je      sfc_1
299
        add     eax, eax
296
        add     eax, eax
300
  sfc_1:
297
  sfc_1:
301
        add     eax, eax
298
        add     eax, eax
302
        mov     esi, 511
299
        mov     esi, 511
303
        and     esi, eax        ; esi = position in fat sector
300
        and     esi, eax        ; esi = position in fat sector
304
        shr     eax, 9          ; eax = fat sector
301
        shr     eax, 9          ; eax = fat sector
305
        add     eax, [ebp+FAT.FAT_START]
302
        add     eax, [ebp+FAT.FAT_START]
306
        lea     ebx, [ebp+FAT.fat_cache]
303
        lea     ebx, [ebp+FAT.fat_cache]
307
 
304
 
308
        cmp     eax, [ebp+FAT.fat_in_cache]; is fat sector already in memory?
305
        cmp     eax, [ebp+FAT.fat_in_cache]; is fat sector already in memory?
309
        je      sfc_in_cache    ; yes
306
        je      sfc_in_cache    ; yes
310
 
307
 
311
        cmp     [ebp+FAT.fat_change], 0; is fat changed?
308
        cmp     [ebp+FAT.fat_change], 0; is fat changed?
312
        je      sfc_no_change   ; no
309
        je      sfc_no_change   ; no
313
        call    write_fat_sector; yes. write it into disk
310
        call    write_fat_sector; yes. write it into disk
314
        jc      sfc_error
311
        jc      sfc_error
315
 
312
 
316
  sfc_no_change:
313
  sfc_no_change:
317
        mov     [ebp+FAT.fat_in_cache], eax; save fat sector
314
        mov     [ebp+FAT.fat_in_cache], eax; save fat sector
318
        call    fs_read32_sys
315
        call    fs_read32_sys
319
        test    eax, eax
316
        test    eax, eax
320
        jne     sfc_error
317
        jne     sfc_error
321
 
318
 
322
 
319
 
323
  sfc_in_cache:
320
  sfc_in_cache:
324
        cmp     [ebp+FAT.fs_type], 16
321
        cmp     [ebp+FAT.fs_type], 16
325
        jne     sfc_test32
322
        jne     sfc_test32
326
 
323
 
327
  sfc_set16:
324
  sfc_set16:
328
        xchg    [ebx+esi], dx   ; save new value and get old value
325
        xchg    [ebx+esi], dx   ; save new value and get old value
329
        jmp     sfc_write
326
        jmp     sfc_write
330
 
327
 
331
  sfc_test32:
328
  sfc_test32:
332
        mov     eax, [ebp+FAT.fatMASK]
329
        mov     eax, [ebp+FAT.fatMASK]
333
 
330
 
334
  sfc_set32:
331
  sfc_set32:
335
        and     edx, eax
332
        and     edx, eax
336
        xor     eax, -1         ; mask for high bits
333
        xor     eax, -1         ; mask for high bits
337
        and     eax, [ebx+esi]  ; get high 4 bits
334
        and     eax, [ebx+esi]  ; get high 4 bits
338
        or      eax, edx
335
        or      eax, edx
339
        mov     edx, [ebx+esi]  ; get old value
336
        mov     edx, [ebx+esi]  ; get old value
340
        mov     [ebx+esi], eax  ; save new value
337
        mov     [ebx+esi], eax  ; save new value
341
 
338
 
342
  sfc_write:
339
  sfc_write:
343
        mov     [ebp+FAT.fat_change], 1; fat has changed
340
        mov     [ebp+FAT.fat_change], 1; fat has changed
344
 
341
 
345
  sfc_nonzero:
342
  sfc_nonzero:
346
        and     edx, [ebp+FAT.fatMASK]
343
        and     edx, [ebp+FAT.fatMASK]
347
 
344
 
348
  sfc_return:
345
  sfc_return:
349
        pop     esi ebx eax
346
        pop     esi ebx eax
350
        ret
347
        ret
351
  sfc_error:
348
  sfc_error:
352
        stc
349
        stc
353
        jmp     sfc_return
350
        jmp     sfc_return
354
 
351
 
355
 
352
 
356
get_FAT:
353
get_FAT:
357
;--------------------------------
354
;--------------------------------
358
; input  : EAX = cluster
355
; input  : EAX = cluster
359
;          EBP = pointer to FAT structure
356
;          EBP = pointer to FAT structure
360
; output : EAX = next cluster
357
; output : EAX = next cluster
361
;--------------------------------
358
;--------------------------------
362
; out: CF set <=> error
359
; out: CF set <=> error
363
        push    ebx esi
360
        push    ebx esi
364
 
361
 
365
        cmp     [ebp+FAT.fs_type], 16
362
        cmp     [ebp+FAT.fs_type], 16
366
        je      gfc_1
363
        je      gfc_1
367
        add     eax, eax
364
        add     eax, eax
368
  gfc_1:
365
  gfc_1:
369
        add     eax, eax
366
        add     eax, eax
370
        mov     esi, 511
367
        mov     esi, 511
371
        and     esi, eax        ; esi = position in fat sector
368
        and     esi, eax        ; esi = position in fat sector
372
        shr     eax, 9          ; eax = fat sector
369
        shr     eax, 9          ; eax = fat sector
373
        add     eax, [ebp+FAT.FAT_START]
370
        add     eax, [ebp+FAT.FAT_START]
374
        lea     ebx, [ebp+FAT.fat_cache]
371
        lea     ebx, [ebp+FAT.fat_cache]
375
 
372
 
376
        cmp     eax, [ebp+FAT.fat_in_cache]; is fat sector already in memory?
373
        cmp     eax, [ebp+FAT.fat_in_cache]; is fat sector already in memory?
377
        je      gfc_in_cache
374
        je      gfc_in_cache
378
 
375
 
379
        cmp     [ebp+FAT.fat_change], 0; is fat changed?
376
        cmp     [ebp+FAT.fat_change], 0; is fat changed?
380
        je      gfc_no_change   ; no
377
        je      gfc_no_change   ; no
381
        call    write_fat_sector; yes. write it into disk
378
        call    write_fat_sector; yes. write it into disk
382
        jc      hd_error_01
379
        jc      hd_error_01
383
 
380
 
384
  gfc_no_change:
381
  gfc_no_change:
385
        mov     [ebp+FAT.fat_in_cache], eax
382
        mov     [ebp+FAT.fat_in_cache], eax
386
        call    fs_read32_sys
383
        call    fs_read32_sys
387
        test    eax, eax
384
        test    eax, eax
388
        jne     hd_error_01
385
        jne     hd_error_01
389
 
386
 
390
  gfc_in_cache:
387
  gfc_in_cache:
391
        mov     eax, [ebx+esi]
388
        mov     eax, [ebx+esi]
392
        and     eax, [ebp+FAT.fatMASK]
389
        and     eax, [ebp+FAT.fatMASK]
393
  gfc_return:
390
  gfc_return:
394
        pop     esi ebx
391
        pop     esi ebx
395
        ret
392
        ret
396
 hd_error_01:
393
 hd_error_01:
397
        stc
394
        stc
398
        jmp     gfc_return
395
        jmp     gfc_return
399
 
396
 
400
 
397
 
401
get_free_FAT:
398
get_free_FAT:
402
;-----------------------------------------------------------
399
;-----------------------------------------------------------
403
; output : if CARRY=0 EAX = # first cluster found free
400
; output : if CARRY=0 EAX = # first cluster found free
404
;          if CARRY=1 disk full
401
;          if CARRY=1 disk full
405
; Note   : for more speed need to use fat_cache directly
402
; Note   : for more speed need to use fat_cache directly
406
;-----------------------------------------------------------
403
;-----------------------------------------------------------
407
        push    ecx
404
        push    ecx
408
        mov     ecx, [ebp+FAT.LAST_CLUSTER]; counter for full disk
405
        mov     ecx, [ebp+FAT.LAST_CLUSTER]; counter for full disk
409
        sub     ecx, 2
406
        sub     ecx, 2
410
        mov     eax, [ebp+FAT.fatStartScan]
407
        mov     eax, [ebp+FAT.fatStartScan]
411
        cmp     eax, 2
408
        cmp     eax, 2
412
        jb      gff_reset
409
        jb      gff_reset
413
 
410
 
414
  gff_test:
411
  gff_test:
415
        cmp     eax, [ebp+FAT.LAST_CLUSTER]; if above last cluster start at cluster 2
412
        cmp     eax, [ebp+FAT.LAST_CLUSTER]; if above last cluster start at cluster 2
416
        jbe     gff_in_range
413
        jbe     gff_in_range
417
  gff_reset:
414
  gff_reset:
418
        mov     eax, 2
415
        mov     eax, 2
419
 
416
 
420
  gff_in_range:
417
  gff_in_range:
421
        push    eax
418
        push    eax
422
        call    get_FAT         ; get cluster state
419
        call    get_FAT         ; get cluster state
423
        jc      gff_not_found_1
420
        jc      gff_not_found_1
424
 
421
 
425
        test    eax, eax        ; is it free?
422
        test    eax, eax        ; is it free?
426
        pop     eax
423
        pop     eax
427
        je      gff_found       ; yes
424
        je      gff_found       ; yes
428
        inc     eax             ; next cluster
425
        inc     eax             ; next cluster
429
        dec     ecx             ; is all checked?
426
        dec     ecx             ; is all checked?
430
        jns     gff_test        ; no
427
        jns     gff_test        ; no
431
 
428
 
432
  gff_not_found:
429
  gff_not_found:
433
        pop     ecx             ; yes. disk is full
430
        pop     ecx             ; yes. disk is full
434
        stc
431
        stc
435
        ret
432
        ret
436
 
433
 
437
  gff_not_found_1:
434
  gff_not_found_1:
438
        pop     eax
435
        pop     eax
439
        jmp     gff_not_found
436
        jmp     gff_not_found
440
 
437
 
441
  gff_found:
438
  gff_found:
442
        lea     ecx, [eax+1]
439
        lea     ecx, [eax+1]
443
        mov     [ebp+FAT.fatStartScan], ecx
440
        mov     [ebp+FAT.fatStartScan], ecx
444
        pop     ecx
441
        pop     ecx
445
        clc
442
        clc
446
        ret
443
        ret
447
 
444
 
448
 
445
 
449
write_fat_sector:
446
write_fat_sector:
450
;-----------------------------------------------------------
447
;-----------------------------------------------------------
451
; write changed fat to disk
448
; write changed fat to disk
452
;-----------------------------------------------------------
449
;-----------------------------------------------------------
453
        push    eax ebx ecx
450
        push    eax ebx ecx
454
 
451
 
455
        mov     [ebp+FAT.fat_change], 0
452
        mov     [ebp+FAT.fat_change], 0
456
        mov     eax, [ebp+FAT.fat_in_cache]
453
        mov     eax, [ebp+FAT.fat_in_cache]
457
        cmp     eax, -1
454
        cmp     eax, -1
458
        jz      write_fat_not_used
455
        jz      write_fat_not_used
459
        lea     ebx, [ebp+FAT.fat_cache]
456
        lea     ebx, [ebp+FAT.fat_cache]
460
        mov     ecx, [ebp+FAT.NUMBER_OF_FATS]
457
        mov     ecx, [ebp+FAT.NUMBER_OF_FATS]
461
 
458
 
462
  write_next_fat:
459
  write_next_fat:
463
        push    eax
460
        push    eax
464
        call    fs_write32_sys
461
        call    fs_write32_sys
465
        test    eax, eax
462
        test    eax, eax
466
        pop     eax
463
        pop     eax
467
        jnz     write_fat_not_used
464
        jnz     write_fat_not_used
468
 
465
 
469
        add     eax, [ebp+FAT.SECTORS_PER_FAT]
466
        add     eax, [ebp+FAT.SECTORS_PER_FAT]
470
        dec     ecx
467
        dec     ecx
471
        jnz     write_next_fat
468
        jnz     write_next_fat
472
 
469
 
473
  write_fat_not_used:
470
  write_fat_not_used:
474
        pop     ecx ebx eax
471
        pop     ecx ebx eax
475
        ret
472
        ret
476
 
473
 
477
 
474
 
478
 
475
 
479
 
476
 
480
 
477
 
481
bcd2bin:
478
bcd2bin:
482
;----------------------------------
479
;----------------------------------
483
; input  : AL=BCD number (eg. 0x11)
480
; input  : AL=BCD number (eg. 0x11)
484
; output : AH=0
481
; output : AH=0
485
;          AL=decimal number (eg. 11)
482
;          AL=decimal number (eg. 11)
486
;----------------------------------
483
;----------------------------------
487
        xor     ah, ah
484
        xor     ah, ah
488
        shl     ax, 4
485
        shl     ax, 4
489
        shr     al, 4
486
        shr     al, 4
490
        aad
487
        aad
491
        ret
488
        ret
492
 
489
 
493
 
490
 
494
get_date_for_file:
491
get_date_for_file:
495
;-----------------------------------------------------
492
;-----------------------------------------------------
496
; Get date from CMOS and pack day,month,year in AX
493
; Get date from CMOS and pack day,month,year in AX
497
; DATE   bits  0..4   : day of month 0..31
494
; DATE   bits  0..4   : day of month 0..31
498
;              5..8   : month of year 1..12
495
;              5..8   : month of year 1..12
499
;              9..15  : count of years from 1980
496
;              9..15  : count of years from 1980
500
;-----------------------------------------------------
497
;-----------------------------------------------------
501
        mov     al, 0x7 ;day
498
        mov     al, 0x7 ;day
502
        out     0x70, al
499
        out     0x70, al
503
        in      al, 0x71
500
        in      al, 0x71
504
        call    bcd2bin
501
        call    bcd2bin
505
        ror     eax, 5
502
        ror     eax, 5
506
 
503
 
507
        mov     al, 0x8 ;month
504
        mov     al, 0x8 ;month
508
        out     0x70, al
505
        out     0x70, al
509
        in      al, 0x71
506
        in      al, 0x71
510
        call    bcd2bin
507
        call    bcd2bin
511
        ror     eax, 4
508
        ror     eax, 4
512
 
509
 
513
        mov     al, 0x9 ;year
510
        mov     al, 0x9 ;year
514
        out     0x70, al
511
        out     0x70, al
515
        in      al, 0x71
512
        in      al, 0x71
516
        call    bcd2bin
513
        call    bcd2bin
517
        add     ax, 20  ;because CMOS return only the two last
514
        add     ax, 20  ;because CMOS return only the two last
518
                        ;digit (eg. 2000 -> 00 , 2001 -> 01) and we
515
                        ;digit (eg. 2000 -> 00 , 2001 -> 01) and we
519
        rol     eax, 9  ;need the difference with 1980 (eg. 2001-1980)
516
        rol     eax, 9  ;need the difference with 1980 (eg. 2001-1980)
520
        ret
517
        ret
521
 
518
 
522
 
519
 
523
get_time_for_file:
520
get_time_for_file:
524
;-----------------------------------------------------
521
;-----------------------------------------------------
525
; Get time from CMOS and pack hour,minute,second in AX
522
; Get time from CMOS and pack hour,minute,second in AX
526
; TIME   bits  0..4   : second (the low bit is lost)
523
; TIME   bits  0..4   : second (the low bit is lost)
527
;              5..10  : minute 0..59
524
;              5..10  : minute 0..59
528
;              11..15 : hour 0..23
525
;              11..15 : hour 0..23
529
;-----------------------------------------------------
526
;-----------------------------------------------------
530
        mov     al, 0x0 ;second
527
        mov     al, 0x0 ;second
531
        out     0x70, al
528
        out     0x70, al
532
        in      al, 0x71
529
        in      al, 0x71
533
        call    bcd2bin
530
        call    bcd2bin
534
        ror     eax, 6
531
        ror     eax, 6
535
 
532
 
536
        mov     al, 0x2 ;minute
533
        mov     al, 0x2 ;minute
537
        out     0x70, al
534
        out     0x70, al
538
        in      al, 0x71
535
        in      al, 0x71
539
        call    bcd2bin
536
        call    bcd2bin
540
        ror     eax, 6
537
        ror     eax, 6
541
 
538
 
542
        mov     al, 0x4 ;hour
539
        mov     al, 0x4 ;hour
543
        out     0x70, al
540
        out     0x70, al
544
        in      al, 0x71
541
        in      al, 0x71
545
        call    bcd2bin
542
        call    bcd2bin
546
        rol     eax, 11
543
        rol     eax, 11
547
        ret
544
        ret
548
 
545
 
549
 
546
 
550
set_current_time_for_entry:
547
set_current_time_for_entry:
551
;-----------------------------------------------------
548
;-----------------------------------------------------
552
; Set current time/date for file entry
549
; Set current time/date for file entry
553
; input  : ebx = file entry pointer
550
; input  : ebx = file entry pointer
554
;-----------------------------------------------------
551
;-----------------------------------------------------
555
        push    eax
552
        push    eax
556
        call    get_time_for_file; update files date/time
553
        call    get_time_for_file; update files date/time
557
        mov     [ebx+22], ax
554
        mov     [ebx+22], ax
558
        call    get_date_for_file
555
        call    get_date_for_file
559
        mov     [ebx+24], ax
556
        mov     [ebx+24], ax
560
        pop     eax
557
        pop     eax
561
        ret
558
        ret
562
 
559
 
563
 
560
 
564
 
561
 
565
add_disk_free_space:
562
add_disk_free_space:
566
;-----------------------------------------------------
563
;-----------------------------------------------------
567
; input  : ecx = cluster count
564
; input  : ecx = cluster count
568
; Note   : negative = remove clusters from free space
565
; Note   : negative = remove clusters from free space
569
;          positive = add clusters to free space
566
;          positive = add clusters to free space
570
;-----------------------------------------------------
567
;-----------------------------------------------------
571
        test    ecx, ecx        ; no change
568
        test    ecx, ecx        ; no change
572
        je      add_dfs_no
569
        je      add_dfs_no
573
        cmp     [ebp+FAT.fs_type], 32  ; free disk space only used by fat32
570
        cmp     [ebp+FAT.fs_type], 32  ; free disk space only used by fat32
574
        jne     add_dfs_no
571
        jne     add_dfs_no
575
 
572
 
576
        push    eax ebx
573
        push    eax ebx
577
        mov     eax, [ebp+FAT.ADR_FSINFO]
574
        mov     eax, [ebp+FAT.ADR_FSINFO]
578
        lea     ebx, [ebp+FAT.fsinfo_buffer]
575
        lea     ebx, [ebp+FAT.fsinfo_buffer]
579
        call    fs_read32_sys
576
        call    fs_read32_sys
580
        test    eax, eax
577
        test    eax, eax
581
        jnz     add_not_fs
578
        jnz     add_not_fs
582
 
579
 
583
        cmp     dword [ebx+0x1fc], 0xaa550000; check sector id
580
        cmp     dword [ebx+0x1fc], 0xaa550000; check sector id
584
        jne     add_not_fs
581
        jne     add_not_fs
585
 
582
 
586
        add     [ebx+0x1e8], ecx
583
        add     [ebx+0x1e8], ecx
587
        push    [ebp+FAT.fatStartScan]
584
        push    [ebp+FAT.fatStartScan]
588
        pop     dword [ebx+0x1ec]
585
        pop     dword [ebx+0x1ec]
589
        mov     eax, [ebp+FAT.ADR_FSINFO]
586
        mov     eax, [ebp+FAT.ADR_FSINFO]
590
        call    fs_write32_sys
587
        call    fs_write32_sys
591
;    jc    add_not_fs
588
;    jc    add_not_fs
592
 
589
 
593
  add_not_fs:
590
  add_not_fs:
594
        pop     ebx eax
591
        pop     ebx eax
595
 
592
 
596
  add_dfs_no:
593
  add_dfs_no:
597
        ret
594
        ret
598
 
595
 
599
 
596
 
600
 
597
 
601
clear_cluster_chain:
598
clear_cluster_chain:
602
;-----------------------------------------------------
599
;-----------------------------------------------------
603
; input  : eax = first cluster
600
; input  : eax = first cluster
604
;-----------------------------------------------------
601
;-----------------------------------------------------
605
        push    eax ecx edx
602
        push    eax ecx edx
606
        xor     ecx, ecx        ; cluster count
603
        xor     ecx, ecx        ; cluster count
607
 
604
 
608
  clean_new_chain:
605
  clean_new_chain:
609
        cmp     eax, [ebp+FAT.LAST_CLUSTER]; end of file
606
        cmp     eax, [ebp+FAT.LAST_CLUSTER]; end of file
610
        ja      delete_OK
607
        ja      delete_OK
611
        cmp     eax, 2          ; unfinished fat chain or zero length file
608
        cmp     eax, 2          ; unfinished fat chain or zero length file
612
        jb      delete_OK
609
        jb      delete_OK
613
        cmp     eax, [ebp+FAT.ROOT_CLUSTER]; don't remove root cluster
610
        cmp     eax, [ebp+FAT.ROOT_CLUSTER]; don't remove root cluster
614
        jz      delete_OK
611
        jz      delete_OK
615
 
612
 
616
        xor     edx, edx
613
        xor     edx, edx
617
        call    set_FAT         ; clear fat entry
614
        call    set_FAT         ; clear fat entry
618
        jc      access_denied_01
615
        jc      access_denied_01
619
 
616
 
620
        inc     ecx             ; update cluster count
617
        inc     ecx             ; update cluster count
621
        mov     eax, edx        ; old cluster
618
        mov     eax, edx        ; old cluster
622
        jmp     clean_new_chain
619
        jmp     clean_new_chain
623
 
620
 
624
  delete_OK:
621
  delete_OK:
625
        call    add_disk_free_space; add clusters to free disk space
622
        call    add_disk_free_space; add clusters to free disk space
626
        clc
623
        clc
627
  access_denied_01:
624
  access_denied_01:
628
        pop     edx ecx eax
625
        pop     edx ecx eax
629
        ret
626
        ret
630
 
627
 
631
 
628
 
632
if 0
629
if 0
633
get_hd_info:
630
get_hd_info:
634
;-----------------------------------------------------------
631
;-----------------------------------------------------------
635
; output : eax = 0 - ok
632
; output : eax = 0 - ok
636
;                3 - unknown FS
633
;                3 - unknown FS
637
;               10 - access denied
634
;               10 - access denied
638
;          edx = cluster size in bytes
635
;          edx = cluster size in bytes
639
;          ebx = total clusters on disk
636
;          ebx = total clusters on disk
640
;          ecx = free clusters on disk
637
;          ecx = free clusters on disk
641
;-----------------------------------------------------------
638
;-----------------------------------------------------------
642
        cmp     [ebp+FAT.fs_type], 16
639
        cmp     [ebp+FAT.fs_type], 16
643
        jz      info_fat_ok
640
        jz      info_fat_ok
644
        cmp     [ebp+FAT.fs_type], 32
641
        cmp     [ebp+FAT.fs_type], 32
645
        jz      info_fat_ok
642
        jz      info_fat_ok
646
        xor     edx, edx
643
        xor     edx, edx
647
        xor     ebx, ebx
644
        xor     ebx, ebx
648
        xor     ecx, ecx
645
        xor     ecx, ecx
649
        mov     eax, ERROR_UNKNOWN_FS
646
        mov     eax, ERROR_UNKNOWN_FS
650
        ret
647
        ret
651
 
648
 
652
  info_fat_ok:
649
  info_fat_ok:
653
;    call  reserve_hd1
650
;    call  reserve_hd1
654
 
651
 
655
        xor     ecx, ecx        ; count of free clusters
652
        xor     ecx, ecx        ; count of free clusters
656
        mov     eax, 2
653
        mov     eax, 2
657
        mov     ebx, [ebp+FAT.LAST_CLUSTER]
654
        mov     ebx, [ebp+FAT.LAST_CLUSTER]
658
 
655
 
659
  info_cluster:
656
  info_cluster:
660
        push    eax
657
        push    eax
661
        call    get_FAT         ; get cluster info
658
        call    get_FAT         ; get cluster info
662
        jc      info_access_denied
659
        jc      info_access_denied
663
 
660
 
664
        test    eax, eax        ; is it free?
661
        test    eax, eax        ; is it free?
665
        jnz     info_used       ; no
662
        jnz     info_used       ; no
666
        inc     ecx
663
        inc     ecx
667
 
664
 
668
  info_used:
665
  info_used:
669
        pop     eax
666
        pop     eax
670
        inc     eax
667
        inc     eax
671
        cmp     eax, ebx        ; is above last cluster?
668
        cmp     eax, ebx        ; is above last cluster?
672
        jbe     info_cluster    ; no. test next cluster
669
        jbe     info_cluster    ; no. test next cluster
673
 
670
 
674
        dec     ebx             ; cluster count
671
        dec     ebx             ; cluster count
675
        imul    edx, [ebp+FAT.SECTORS_PER_CLUSTER], 512; cluster size in bytes
672
        imul    edx, [ebp+FAT.SECTORS_PER_CLUSTER], 512; cluster size in bytes
676
        xor     eax, eax
673
        xor     eax, eax
677
        ret
674
        ret
678
 
675
 
679
  info_access_denied:
676
  info_access_denied:
680
        add     esp, 4
677
        add     esp, 4
681
        xor     edx, edx
678
        xor     edx, edx
682
        xor     ebx, ebx
679
        xor     ebx, ebx
683
        xor     ecx, ecx
680
        xor     ecx, ecx
684
        mov     eax, ERROR_ACCESS_DENIED
681
        mov     eax, ERROR_ACCESS_DENIED
685
        ret
682
        ret
686
end if
683
end if
687
 
684
 
688
update_disk:
685
update_disk:
689
;-----------------------------------------------------------
686
;-----------------------------------------------------------
690
; write changed fat and cache to disk
687
; write changed fat and cache to disk
691
;-----------------------------------------------------------
688
;-----------------------------------------------------------
692
        cmp     [ebp+FAT.fat_change], 0 ; is fat changed?
689
        cmp     [ebp+FAT.fat_change], 0 ; is fat changed?
693
        je      upd_no_change
690
        je      upd_no_change
694
 
691
 
695
        call    write_fat_sector
692
        call    write_fat_sector
696
        jc      update_disk_acces_denied
693
        jc      update_disk_acces_denied
697
 
694
 
698
  upd_no_change:
695
  upd_no_change:
699
 
696
 
700
        push    esi
697
        push    esi
701
        mov     esi, [ebp+PARTITION.Disk]
698
        mov     esi, [ebp+PARTITION.Disk]
702
        call    disk_sync
699
        call    disk_sync
703
        pop     esi
700
        pop     esi
704
  update_disk_acces_denied:
701
  update_disk_acces_denied:
705
        ret
702
        ret
706
 
703
 
707
fat_lock:
704
fat_lock:
708
        lea     ecx, [ebp+FAT.Lock]
705
        lea     ecx, [ebp+FAT.Lock]
709
        jmp     mutex_lock
706
        jmp     mutex_lock
710
fat_unlock:
707
fat_unlock:
711
        lea     ecx, [ebp+FAT.Lock]
708
        lea     ecx, [ebp+FAT.Lock]
712
        jmp     mutex_unlock
709
        jmp     mutex_unlock
713
 
710
 
714
; \begin{diamond}
711
; \begin{diamond}
715
hd_find_lfn:
712
hd_find_lfn:
716
; in: ebp -> FAT structure
713
; in: ebp -> FAT structure
717
; in: esi+[esp+4] -> name
714
; in: esi+[esp+4] -> name
718
; out: CF=1 - file not found, eax=error code
715
; out: CF=1 - file not found, eax=error code
719
;      else CF=0 and edi->direntry, eax=sector
716
;      else CF=0 and edi->direntry, eax=sector
720
; destroys eax
717
; destroys eax
721
        push    esi edi
718
        push    esi edi
722
        push    0
719
        push    0
723
        push    0
720
        push    0
724
        push    fat16_root_first
721
        push    fat16_root_first
725
        push    fat16_root_next
722
        push    fat16_root_next
726
        mov     eax, [ebp+FAT.ROOT_CLUSTER]
723
        mov     eax, [ebp+FAT.ROOT_CLUSTER]
727
        cmp     [ebp+FAT.fs_type], 32
724
        cmp     [ebp+FAT.fs_type], 32
728
        jz      .fat32
725
        jz      .fat32
729
.loop:
726
.loop:
730
        call    fat_find_lfn
727
        call    fat_find_lfn
731
        jc      .notfound
728
        jc      .notfound
732
        cmp     byte [esi], 0
729
        cmp     byte [esi], 0
733
        jz      .found
730
        jz      .found
734
.continue:
731
.continue:
735
        test    byte [edi+11], 10h
732
        test    byte [edi+11], 10h
736
        jz      .notfound
733
        jz      .notfound
737
        and     dword [esp+12], 0
734
        and     dword [esp+12], 0
738
        mov     eax, [edi+20-2]
735
        mov     eax, [edi+20-2]
739
        mov     ax, [edi+26]    ; cluster
736
        mov     ax, [edi+26]    ; cluster
740
.fat32:
737
.fat32:
741
        mov     [esp+8], eax
738
        mov     [esp+8], eax
742
        mov     dword [esp+4], fat_notroot_first
739
        mov     dword [esp+4], fat_notroot_first
743
        mov     dword [esp], fat_notroot_next
740
        mov     dword [esp], fat_notroot_next
744
        jmp     .loop
741
        jmp     .loop
745
.notfound:
742
.notfound:
746
        add     esp, 16
743
        add     esp, 16
747
        pop     edi esi
744
        pop     edi esi
748
        stc
745
        stc
749
        ret     4
746
        ret     4
750
.found:
747
.found:
751
        lea     eax, [esp+4+24]
748
        lea     eax, [esp+4+24]
752
        cmp     dword [eax], 0
749
        cmp     dword [eax], 0
753
        jz      @f
750
        jz      @f
754
        mov     esi, [eax]
751
        mov     esi, [eax]
755
        and     dword [eax], 0
752
        and     dword [eax], 0
756
        jmp     .continue
753
        jmp     .continue
757
@@:
754
@@:
758
        lea     eax, [esp+8]
755
        lea     eax, [esp+8]
759
        cmp     dword [eax], 0
756
        cmp     dword [eax], 0
760
        jz      .root
757
        jz      .root
761
        call    fat_get_sector
758
        call    fat_get_sector
762
        jmp     .cmn
759
        jmp     .cmn
763
.root:
760
.root:
764
        mov     eax, [eax+4]
761
        mov     eax, [eax+4]
765
        add     eax, [ebp+FAT.ROOT_START]
762
        add     eax, [ebp+FAT.ROOT_START]
766
.cmn:
763
.cmn:
767
        add     esp, 20         ; CF=0
764
        add     esp, 20         ; CF=0
768
        pop     esi
765
        pop     esi
769
        ret     4
766
        ret     4
770
 
767
 
771
;----------------------------------------------------------------
768
;----------------------------------------------------------------
772
;
-
 
773
;  fs_HdRead - LFN variant for reading hard disk
-
 
774
;
-
 
775
;  Obsolete, will be replaced with filesystem-specific functions.
-
 
776
;
-
 
777
;  esi  points to filename
-
 
778
;  ebx  pointer to 64-bit number = first wanted byte, 0+
-
 
779
;       may be ebx=0 - start from first byte
-
 
780
;  ecx  number of bytes to read, 0+
-
 
781
;  edx  mem location to return data
-
 
782
;
-
 
783
;  ret ebx = bytes read or 0xffffffff file not found
-
 
784
;      eax = 0 ok read or other = errormsg
-
 
785
;
-
 
786
;--------------------------------------------------------------
-
 
787
fs_HdRead:
-
 
788
        cmp     [fs_type], 16
-
 
789
        jz      @f
-
 
790
        cmp     [fs_type], 32
-
 
791
        jz      @f
-
 
792
        cmp     [fs_type], 1
-
 
793
        jz      ntfs_HdRead
-
 
794
        cmp     [fs_type], 2
-
 
795
        jz      ext2_HdRead
-
 
796
        or      ebx, -1
-
 
797
        mov     eax, ERROR_UNKNOWN_FS
-
 
798
        ret
-
 
799
@@:
-
 
800
        sub     ebx, 4
-
 
801
        push    ebp
-
 
802
        mov     ebp, [fs_dependent_data_start.partition]
-
 
803
        call    fat_Read
-
 
804
        pop     ebp
-
 
805
        ret
-
 
806
 
-
 
807
;----------------------------------------------------------------
-
 
808
; fat_Read - FAT16/32 implementation of reading a file
769
; fat_Read - FAT16/32 implementation of reading a file
809
; in:  ebp = pointer to FAT structure
770
; in:  ebp = pointer to FAT structure
810
; in:  esi+[esp+4] = name
771
; in:  esi+[esp+4] = name
811
; in:  ebx = pointer to parameters from sysfunc 70
772
; in:  ebx = pointer to parameters from sysfunc 70
812
; out: eax, ebx = return values for sysfunc 70
773
; out: eax, ebx = return values for sysfunc 70
813
;----------------------------------------------------------------
774
;----------------------------------------------------------------
814
fat_Read:
775
fat_Read:
815
        call    fat_lock
776
        call    fat_lock
816
        push    edi
777
        push    edi
817
        cmp     byte [esi], 0
778
        cmp     byte [esi], 0
818
        jnz     @f
779
        jnz     @f
819
.noaccess:
780
.noaccess:
820
        pop     edi
781
        pop     edi
821
.noaccess_2:
782
.noaccess_2:
822
        call    fat_unlock
783
        call    fat_unlock
823
        or      ebx, -1
784
        or      ebx, -1
824
        mov     eax, ERROR_ACCESS_DENIED
785
        mov     eax, ERROR_ACCESS_DENIED
825
        ret
786
        ret
826
 
787
 
827
@@:
788
@@:
828
        stdcall hd_find_lfn, [esp+4+4]
789
        stdcall hd_find_lfn, [esp+4+4]
829
        jnc     .found
790
        jnc     .found
830
        pop     edi
791
        pop     edi
831
        push    eax
792
        push    eax
832
        call    fat_unlock
793
        call    fat_unlock
833
        pop     eax
794
        pop     eax
834
        or      ebx, -1
795
        or      ebx, -1
835
        ret
796
        ret
836
 
797
 
837
.found:
798
.found:
838
        test    byte [edi+11], 0x10; do not allow read directories
799
        test    byte [edi+11], 0x10; do not allow read directories
839
        jnz     .noaccess
800
        jnz     .noaccess
840
        cmp     dword [ebx+8], 0
801
        cmp     dword [ebx+8], 0
841
        jz      @f
802
        jz      @f
842
        xor     ebx, ebx
803
        xor     ebx, ebx
843
.reteof:
804
.reteof:
844
        call    fat_unlock
805
        call    fat_unlock
845
        mov     eax, ERROR_END_OF_FILE
806
        mov     eax, ERROR_END_OF_FILE
846
        pop     edi
807
        pop     edi
847
        ret
808
        ret
848
@@:
809
@@:
849
        mov     ecx, [ebx+12]   ; size
810
        mov     ecx, [ebx+12]   ; size
850
        mov     edx, [ebx+16]   ; pointer
811
        mov     edx, [ebx+16]   ; pointer
851
        mov     ebx, [ebx+4]    ; file offset
812
        mov     ebx, [ebx+4]    ; file offset
852
        push    edx
813
        push    edx
853
        push    0
814
        push    0
854
        mov     eax, [edi+28]
815
        mov     eax, [edi+28]
855
        sub     eax, ebx
816
        sub     eax, ebx
856
        jb      .eof
817
        jb      .eof
857
        cmp     eax, ecx
818
        cmp     eax, ecx
858
        jae     @f
819
        jae     @f
859
        mov     ecx, eax
820
        mov     ecx, eax
860
        mov     byte [esp], 6
821
        mov     byte [esp], 6
861
@@:
822
@@:
862
        mov     eax, [edi+20-2]
823
        mov     eax, [edi+20-2]
863
        mov     ax, [edi+26]
824
        mov     ax, [edi+26]
864
; now eax=cluster, ebx=position, ecx=count, edx=buffer for data
825
; now eax=cluster, ebx=position, ecx=count, edx=buffer for data
865
.new_cluster:
826
.new_cluster:
866
        jecxz   .new_sector
827
        jecxz   .new_sector
867
        cmp     eax, 2
828
        cmp     eax, 2
868
        jb      .eof
829
        jb      .eof
869
        cmp     eax, [ebp+FAT.fatRESERVED]
830
        cmp     eax, [ebp+FAT.fatRESERVED]
870
        jae     .eof
831
        jae     .eof
871
        mov     [ebp+FAT.cluster_tmp], eax
832
        mov     [ebp+FAT.cluster_tmp], eax
872
        dec     eax
833
        dec     eax
873
        dec     eax
834
        dec     eax
874
        mov     edi, [ebp+FAT.SECTORS_PER_CLUSTER]
835
        mov     edi, [ebp+FAT.SECTORS_PER_CLUSTER]
875
        imul    eax, edi
836
        imul    eax, edi
876
        add     eax, [ebp+FAT.DATA_START]
837
        add     eax, [ebp+FAT.DATA_START]
877
.new_sector:
838
.new_sector:
878
        test    ecx, ecx
839
        test    ecx, ecx
879
        jz      .done
840
        jz      .done
880
        sub     ebx, 512
841
        sub     ebx, 512
881
        jae     .skip
842
        jae     .skip
882
        add     ebx, 512
843
        add     ebx, 512
883
        jnz     .force_buf
844
        jnz     .force_buf
884
        cmp     ecx, 512
845
        cmp     ecx, 512
885
        jb      .force_buf
846
        jb      .force_buf
886
; we may read directly to given buffer
847
; we may read directly to given buffer
887
        push    eax ebx
848
        push    eax ebx
888
        mov     ebx, edx
849
        mov     ebx, edx
889
        call    fs_read32_app
850
        call    fs_read32_app
890
        test    eax, eax
851
        test    eax, eax
891
        pop     ebx eax
852
        pop     ebx eax
892
        jne     .noaccess_1
853
        jne     .noaccess_1
893
        add     edx, 512
854
        add     edx, 512
894
        sub     ecx, 512
855
        sub     ecx, 512
895
        jmp     .skip
856
        jmp     .skip
896
.force_buf:
857
.force_buf:
897
; we must read sector to temporary buffer and then copy it to destination
858
; we must read sector to temporary buffer and then copy it to destination
898
        push    eax ebx
859
        push    eax ebx
899
        lea     ebx, [ebp+FAT.buffer]
860
        lea     ebx, [ebp+FAT.buffer]
900
        call    fs_read32_app
861
        call    fs_read32_app
901
        test    eax, eax
862
        test    eax, eax
902
        mov     eax, ebx
863
        mov     eax, ebx
903
        pop     ebx
864
        pop     ebx
904
        jne     .noaccess_3
865
        jne     .noaccess_3
905
        add     eax, ebx
866
        add     eax, ebx
906
        push    ecx
867
        push    ecx
907
        add     ecx, ebx
868
        add     ecx, ebx
908
        cmp     ecx, 512
869
        cmp     ecx, 512
909
        jbe     @f
870
        jbe     @f
910
        mov     ecx, 512
871
        mov     ecx, 512
911
@@:
872
@@:
912
        sub     ecx, ebx
873
        sub     ecx, ebx
913
        mov     ebx, edx
874
        mov     ebx, edx
914
        call    memmove
875
        call    memmove
915
        add     edx, ecx
876
        add     edx, ecx
916
        sub     [esp], ecx
877
        sub     [esp], ecx
917
        pop     ecx
878
        pop     ecx
918
        pop     eax
879
        pop     eax
919
        xor     ebx, ebx
880
        xor     ebx, ebx
920
.skip:
881
.skip:
921
        inc     eax
882
        inc     eax
922
        dec     edi
883
        dec     edi
923
        jnz     .new_sector
884
        jnz     .new_sector
924
        mov     eax, [ebp+FAT.cluster_tmp]
885
        mov     eax, [ebp+FAT.cluster_tmp]
925
        call    get_FAT
886
        call    get_FAT
926
        jc      .noaccess_1
887
        jc      .noaccess_1
927
 
888
 
928
        jmp     .new_cluster
889
        jmp     .new_cluster
929
.noaccess_3:
890
.noaccess_3:
930
        pop     eax
891
        pop     eax
931
.noaccess_1:
892
.noaccess_1:
932
        pop     eax
893
        pop     eax
933
        push    ERROR_DEVICE
894
        push    ERROR_DEVICE
934
.done:
895
.done:
935
        mov     ebx, edx
896
        mov     ebx, edx
936
        call    fat_unlock
897
        call    fat_unlock
937
        pop     eax edx edi
898
        pop     eax edx edi
938
        sub     ebx, edx
899
        sub     ebx, edx
939
        ret
900
        ret
940
.eof:
901
.eof:
941
        mov     ebx, edx
902
        mov     ebx, edx
942
        pop     eax edx
903
        pop     eax edx
943
        sub     ebx, edx
904
        sub     ebx, edx
944
        jmp     .reteof
905
        jmp     .reteof
945
 
906
 
946
;----------------------------------------------------------------
907
;----------------------------------------------------------------
947
;
-
 
948
;  fs_HdReadFolder - LFN variant for reading hard disk folder
-
 
949
;
-
 
950
;  Obsolete, will be replaced with filesystem-specific functions.
-
 
951
;
-
 
952
;  esi  points to filename
-
 
953
;  ebx  pointer to structure 32-bit number = first wanted block, 0+
-
 
954
;                          & flags (bitfields)
-
 
955
; flags: bit 0: 0=ANSI names, 1=UNICODE names
-
 
956
;  ecx  number of blocks to read, 0+
-
 
957
;  edx  mem location to return data
-
 
958
;
-
 
959
;  ret ebx = blocks read or 0xffffffff folder not found
-
 
960
;      eax = 0 ok read or other = errormsg
-
 
961
;
-
 
962
;--------------------------------------------------------------
-
 
963
fs_HdReadFolder:
-
 
964
        cmp     [fs_type], 16
-
 
965
        jz      @f
-
 
966
        cmp     [fs_type], 32
-
 
967
        jz      @f
-
 
968
        cmp     [fs_type], 1
-
 
969
        jz      ntfs_HdReadFolder
-
 
970
        cmp     [fs_type], 2
-
 
971
        jz      ext2_HdReadFolder
-
 
972
        movi    eax, ERROR_UNSUPPORTED_FS
-
 
973
        or      ebx, -1
-
 
974
        ret
-
 
975
@@:
-
 
976
        sub     ebx, 4
-
 
977
        push    ebp
-
 
978
        mov     ebp, [fs_dependent_data_start.partition]
-
 
979
        call    fat_ReadFolder
-
 
980
        pop     ebp
-
 
981
        ret
-
 
982
 
-
 
983
;----------------------------------------------------------------
-
 
984
; fat_ReadFolder - FAT16/32 implementation of reading a folder
908
; fat_ReadFolder - FAT16/32 implementation of reading a folder
985
; in:  ebp = pointer to FAT structure
909
; in:  ebp = pointer to FAT structure
986
; in:  esi+[esp+4] = name
910
; in:  esi+[esp+4] = name
987
; in:  ebx = pointer to parameters from sysfunc 70
911
; in:  ebx = pointer to parameters from sysfunc 70
988
; out: eax, ebx = return values for sysfunc 70
912
; out: eax, ebx = return values for sysfunc 70
989
;----------------------------------------------------------------
913
;----------------------------------------------------------------
990
fat_ReadFolder:
914
fat_ReadFolder:
991
        call    fat_lock
915
        call    fat_lock
992
        mov     eax, [ebp+FAT.ROOT_CLUSTER]
916
        mov     eax, [ebp+FAT.ROOT_CLUSTER]
993
        push    edi
917
        push    edi
994
        cmp     byte [esi], 0
918
        cmp     byte [esi], 0
995
        jz      .doit
919
        jz      .doit
996
        stdcall hd_find_lfn, [esp+4+4]
920
        stdcall hd_find_lfn, [esp+4+4]
997
        jnc     .found
921
        jnc     .found
998
        pop     edi
922
        pop     edi
999
        push    eax
923
        push    eax
1000
        call    fat_unlock
924
        call    fat_unlock
1001
        pop     eax
925
        pop     eax
1002
        or      ebx, -1
926
        or      ebx, -1
1003
        ret
927
        ret
1004
.found:
928
.found:
1005
        test    byte [edi+11], 0x10     ; do not allow read files
929
        test    byte [edi+11], 0x10     ; do not allow read files
1006
        jnz     .found_dir
930
        jnz     .found_dir
1007
        pop     edi
931
        pop     edi
1008
        call    fat_unlock
932
        call    fat_unlock
1009
        or      ebx, -1
933
        or      ebx, -1
1010
        mov     eax, ERROR_ACCESS_DENIED
934
        mov     eax, ERROR_ACCESS_DENIED
1011
        ret
935
        ret
1012
.found_dir:
936
.found_dir:
1013
        mov     eax, [edi+20-2]
937
        mov     eax, [edi+20-2]
1014
        mov     ax, [edi+26]    ; eax=cluster
938
        mov     ax, [edi+26]    ; eax=cluster
1015
.doit:
939
.doit:
1016
        push    esi
940
        push    esi
1017
        sub     esp, 262*2      ; reserve space for LFN
941
        sub     esp, 262*2      ; reserve space for LFN
1018
        push    dword [ebx+8]   ; for fat_get_name: read ANSI/UNICODE name
942
        push    dword [ebx+8]   ; for fat_get_name: read ANSI/UNICODE name
1019
        mov     edx, [ebx+16]   ; pointer to buffer
943
        mov     edx, [ebx+16]   ; pointer to buffer
1020
; init header
944
; init header
1021
        push    eax
945
        push    eax
1022
        mov     edi, edx
946
        mov     edi, edx
1023
        mov     ecx, 32/4
947
        mov     ecx, 32/4
1024
        xor     eax, eax
948
        xor     eax, eax
1025
        rep stosd
949
        rep stosd
1026
        pop     eax
950
        pop     eax
1027
        mov     byte [edx], 1   ; version
951
        mov     byte [edx], 1   ; version
1028
        mov     esi, edi        ; esi points to BDFE
952
        mov     esi, edi        ; esi points to BDFE
1029
        mov     ecx, [ebx+12]   ; number of blocks to read
953
        mov     ecx, [ebx+12]   ; number of blocks to read
1030
        mov     ebx, [ebx+4]    ; index of the first block
954
        mov     ebx, [ebx+4]    ; index of the first block
1031
.new_cluster:
955
.new_cluster:
1032
        mov     [ebp+FAT.cluster_tmp], eax
956
        mov     [ebp+FAT.cluster_tmp], eax
1033
        test    eax, eax
957
        test    eax, eax
1034
        jnz     @f
958
        jnz     @f
1035
        cmp     [ebp+FAT.fs_type], 32
959
        cmp     [ebp+FAT.fs_type], 32
1036
        jz      .notfound
960
        jz      .notfound
1037
        mov     eax, [ebp+FAT.ROOT_START]
961
        mov     eax, [ebp+FAT.ROOT_START]
1038
        push    [ebp+FAT.ROOT_SECTORS]
962
        push    [ebp+FAT.ROOT_SECTORS]
1039
        push    ebx
963
        push    ebx
1040
        jmp     .new_sector
964
        jmp     .new_sector
1041
@@:
965
@@:
1042
        dec     eax
966
        dec     eax
1043
        dec     eax
967
        dec     eax
1044
        imul    eax, [ebp+FAT.SECTORS_PER_CLUSTER]
968
        imul    eax, [ebp+FAT.SECTORS_PER_CLUSTER]
1045
        push    [ebp+FAT.SECTORS_PER_CLUSTER]
969
        push    [ebp+FAT.SECTORS_PER_CLUSTER]
1046
        add     eax, [ebp+FAT.DATA_START]
970
        add     eax, [ebp+FAT.DATA_START]
1047
        push    ebx
971
        push    ebx
1048
.new_sector:
972
.new_sector:
1049
        lea     ebx, [ebp+FAT.buffer]
973
        lea     ebx, [ebp+FAT.buffer]
1050
        mov     edi, ebx
974
        mov     edi, ebx
1051
        push    eax
975
        push    eax
1052
        call    fs_read32_sys
976
        call    fs_read32_sys
1053
        test    eax, eax
977
        test    eax, eax
1054
        pop     eax
978
        pop     eax
1055
        jnz     .notfound2
979
        jnz     .notfound2
1056
        add     ebx, 512
980
        add     ebx, 512
1057
        push    eax
981
        push    eax
1058
.l1:
982
.l1:
1059
        push    ebp
983
        push    ebp
1060
        lea     ebp, [esp+20]
984
        lea     ebp, [esp+20]
1061
        call    fat_get_name
985
        call    fat_get_name
1062
        pop     ebp
986
        pop     ebp
1063
        jc      .l2
987
        jc      .l2
1064
        cmp     byte [edi+11], 0xF
988
        cmp     byte [edi+11], 0xF
1065
        jnz     .do_bdfe
989
        jnz     .do_bdfe
1066
        add     edi, 0x20
990
        add     edi, 0x20
1067
        cmp     edi, ebx
991
        cmp     edi, ebx
1068
        jb      .do_bdfe
992
        jb      .do_bdfe
1069
        pop     eax
993
        pop     eax
1070
        inc     eax
994
        inc     eax
1071
        dec     dword [esp+4]
995
        dec     dword [esp+4]
1072
        jnz     @f
996
        jnz     @f
1073
        mov     eax, [ebp+FAT.cluster_tmp]
997
        mov     eax, [ebp+FAT.cluster_tmp]
1074
        test    eax, eax
998
        test    eax, eax
1075
        jz      .done
999
        jz      .done
1076
        call    get_FAT
1000
        call    get_FAT
1077
        jc      .notfound2
1001
        jc      .notfound2
1078
        cmp     eax, 2
1002
        cmp     eax, 2
1079
        jb      .done
1003
        jb      .done
1080
        cmp     eax, [ebp+FAT.fatRESERVED]
1004
        cmp     eax, [ebp+FAT.fatRESERVED]
1081
        jae     .done
1005
        jae     .done
1082
        push    eax
1006
        push    eax
1083
        mov     eax, [ebp+FAT.SECTORS_PER_CLUSTER]
1007
        mov     eax, [ebp+FAT.SECTORS_PER_CLUSTER]
1084
        mov     [esp+8], eax
1008
        mov     [esp+8], eax
1085
        pop     eax
1009
        pop     eax
1086
        mov     [ebp+FAT.cluster_tmp], eax
1010
        mov     [ebp+FAT.cluster_tmp], eax
1087
        dec     eax
1011
        dec     eax
1088
        dec     eax
1012
        dec     eax
1089
        imul    eax, [ebp+FAT.SECTORS_PER_CLUSTER]
1013
        imul    eax, [ebp+FAT.SECTORS_PER_CLUSTER]
1090
        add     eax, [ebp+FAT.DATA_START]
1014
        add     eax, [ebp+FAT.DATA_START]
1091
@@:
1015
@@:
1092
        lea     ebx, [ebp+FAT.buffer]
1016
        lea     ebx, [ebp+FAT.buffer]
1093
        mov     edi, ebx
1017
        mov     edi, ebx
1094
        push    eax
1018
        push    eax
1095
        call    fs_read32_sys
1019
        call    fs_read32_sys
1096
        test    eax, eax
1020
        test    eax, eax
1097
        pop     eax
1021
        pop     eax
1098
        jnz     .notfound2
1022
        jnz     .notfound2
1099
        add     ebx, 512
1023
        add     ebx, 512
1100
        push    eax
1024
        push    eax
1101
.do_bdfe:
1025
.do_bdfe:
1102
        inc     dword [edx+8]   ; new file found
1026
        inc     dword [edx+8]   ; new file found
1103
        dec     dword [esp+4]
1027
        dec     dword [esp+4]
1104
        jns     .l2
1028
        jns     .l2
1105
        dec     ecx
1029
        dec     ecx
1106
        js      .l2
1030
        js      .l2
1107
        inc     dword [edx+4]   ; new file block copied
1031
        inc     dword [edx+4]   ; new file block copied
1108
        push    ebp
1032
        push    ebp
1109
        lea     ebp, [esp+20]
1033
        lea     ebp, [esp+20]
1110
        call    fat_entry_to_bdfe
1034
        call    fat_entry_to_bdfe
1111
        pop     ebp
1035
        pop     ebp
1112
.l2:
1036
.l2:
1113
        add     edi, 0x20
1037
        add     edi, 0x20
1114
        cmp     edi, ebx
1038
        cmp     edi, ebx
1115
        jb      .l1
1039
        jb      .l1
1116
        pop     eax
1040
        pop     eax
1117
        inc     eax
1041
        inc     eax
1118
        dec     dword [esp+4]
1042
        dec     dword [esp+4]
1119
        jnz     .new_sector
1043
        jnz     .new_sector
1120
        mov     eax, [ebp+FAT.cluster_tmp]
1044
        mov     eax, [ebp+FAT.cluster_tmp]
1121
        test    eax, eax
1045
        test    eax, eax
1122
        jz      .done
1046
        jz      .done
1123
        call    get_FAT
1047
        call    get_FAT
1124
        jc      .notfound2
1048
        jc      .notfound2
1125
        cmp     eax, 2
1049
        cmp     eax, 2
1126
        jb      .done
1050
        jb      .done
1127
        cmp     eax, [ebp+FAT.fatRESERVED]
1051
        cmp     eax, [ebp+FAT.fatRESERVED]
1128
        jae     .done
1052
        jae     .done
1129
        push    eax
1053
        push    eax
1130
        mov     eax, [ebp+FAT.SECTORS_PER_CLUSTER]
1054
        mov     eax, [ebp+FAT.SECTORS_PER_CLUSTER]
1131
        mov     [esp+8], eax
1055
        mov     [esp+8], eax
1132
        pop     eax
1056
        pop     eax
1133
        pop     ebx
1057
        pop     ebx
1134
        add     esp, 4
1058
        add     esp, 4
1135
        jmp     .new_cluster
1059
        jmp     .new_cluster
1136
.notfound2:
1060
.notfound2:
1137
        add     esp, 8
1061
        add     esp, 8
1138
.notfound:
1062
.notfound:
1139
        add     esp, 262*2+4
1063
        add     esp, 262*2+4
1140
        pop     esi edi
1064
        pop     esi edi
1141
        mov     ebx, [edx+4]
1065
        mov     ebx, [edx+4]
1142
        call    fat_unlock
1066
        call    fat_unlock
1143
        mov     eax, ERROR_DEVICE
1067
        mov     eax, ERROR_DEVICE
1144
        ret
1068
        ret
1145
.done:
1069
.done:
1146
        add     esp, 262*2+4+8
1070
        add     esp, 262*2+4+8
1147
        mov     ebx, [edx+4]
1071
        mov     ebx, [edx+4]
1148
        xor     eax, eax
1072
        xor     eax, eax
1149
        dec     ecx
1073
        dec     ecx
1150
        js      @f
1074
        js      @f
1151
        mov     al, ERROR_END_OF_FILE
1075
        mov     al, ERROR_END_OF_FILE
1152
@@:
1076
@@:
1153
        push    eax
1077
        push    eax
1154
        call    fat_unlock
1078
        call    fat_unlock
1155
        pop     eax
1079
        pop     eax
1156
        pop     esi edi
1080
        pop     esi edi
1157
        ret
1081
        ret
1158
 
1082
 
1159
fat16_root_next:
1083
fat16_root_next:
1160
        push    ecx
1084
        push    ecx
1161
        lea     ecx, [ebp+FAT.buffer+0x200-0x20]
1085
        lea     ecx, [ebp+FAT.buffer+0x200-0x20]
1162
        cmp     edi, ecx
1086
        cmp     edi, ecx
1163
        jae     fat16_root_next_sector
1087
        jae     fat16_root_next_sector
1164
        pop     ecx
1088
        pop     ecx
1165
        add     edi, 0x20
1089
        add     edi, 0x20
1166
        ret     ; CF=0
1090
        ret     ; CF=0
1167
fat16_root_next_sector:
1091
fat16_root_next_sector:
1168
; read next sector
1092
; read next sector
1169
        push    [ebp+FAT.longname_sec2]
1093
        push    [ebp+FAT.longname_sec2]
1170
        pop     [ebp+FAT.longname_sec1]
1094
        pop     [ebp+FAT.longname_sec1]
1171
        mov     ecx, [eax+4]
1095
        mov     ecx, [eax+4]
1172
        push    ecx
1096
        push    ecx
1173
        add     ecx, [ebp+FAT.ROOT_START]
1097
        add     ecx, [ebp+FAT.ROOT_START]
1174
        mov     [ebp+FAT.longname_sec2], ecx
1098
        mov     [ebp+FAT.longname_sec2], ecx
1175
        pop     ecx
1099
        pop     ecx
1176
        inc     ecx
1100
        inc     ecx
1177
        mov     [eax+4], ecx
1101
        mov     [eax+4], ecx
1178
        cmp     ecx, [ebp+FAT.ROOT_SECTORS]
1102
        cmp     ecx, [ebp+FAT.ROOT_SECTORS]
1179
        pop     ecx
1103
        pop     ecx
1180
        jb      fat16_root_first
1104
        jb      fat16_root_first
1181
        mov     eax, ERROR_FILE_NOT_FOUND
1105
        mov     eax, ERROR_FILE_NOT_FOUND
1182
        stc
1106
        stc
1183
        ret
1107
        ret
1184
fat16_root_first:
1108
fat16_root_first:
1185
        mov     eax, [eax+4]
1109
        mov     eax, [eax+4]
1186
        add     eax, [ebp+FAT.ROOT_START]
1110
        add     eax, [ebp+FAT.ROOT_START]
1187
        push    ebx
1111
        push    ebx
1188
        lea     edi, [ebp+FAT.buffer]
1112
        lea     edi, [ebp+FAT.buffer]
1189
        mov     ebx, edi
1113
        mov     ebx, edi
1190
        call    fs_read32_sys
1114
        call    fs_read32_sys
1191
        pop     ebx
1115
        pop     ebx
1192
        test    eax, eax
1116
        test    eax, eax
1193
        jnz     .readerr
1117
        jnz     .readerr
1194
        ret     ; CF=0
1118
        ret     ; CF=0
1195
.readerr:
1119
.readerr:
1196
        mov     eax, ERROR_DEVICE
1120
        mov     eax, ERROR_DEVICE
1197
        stc
1121
        stc
1198
        ret
1122
        ret
1199
.notfound:
1123
.notfound:
1200
        mov     eax, ERROR_FILE_NOT_FOUND
1124
        mov     eax, ERROR_FILE_NOT_FOUND
1201
        stc
1125
        stc
1202
        ret
1126
        ret
1203
fat16_root_begin_write:
1127
fat16_root_begin_write:
1204
        push    edi eax
1128
        push    edi eax
1205
        call    fat16_root_first
1129
        call    fat16_root_first
1206
        pop     eax edi
1130
        pop     eax edi
1207
        ret
1131
        ret
1208
fat16_root_end_write:
1132
fat16_root_end_write:
1209
        pusha
1133
        pusha
1210
        mov     eax, [eax+4]
1134
        mov     eax, [eax+4]
1211
        add     eax, [ebp+FAT.ROOT_START]
1135
        add     eax, [ebp+FAT.ROOT_START]
1212
        lea     ebx, [ebp+FAT.buffer]
1136
        lea     ebx, [ebp+FAT.buffer]
1213
        call    fs_write32_sys
1137
        call    fs_write32_sys
1214
        popa
1138
        popa
1215
        ret
1139
        ret
1216
fat16_root_next_write:
1140
fat16_root_next_write:
1217
        push    ecx
1141
        push    ecx
1218
        lea     ecx, [ebp+FAT.buffer+0x200]
1142
        lea     ecx, [ebp+FAT.buffer+0x200]
1219
        cmp     edi, ecx
1143
        cmp     edi, ecx
1220
        jae     @f
1144
        jae     @f
1221
        pop     ecx
1145
        pop     ecx
1222
        ret
1146
        ret
1223
@@:
1147
@@:
1224
        call    fat16_root_end_write
1148
        call    fat16_root_end_write
1225
        jmp     fat16_root_next_sector
1149
        jmp     fat16_root_next_sector
1226
fat16_root_extend_dir:
1150
fat16_root_extend_dir:
1227
        stc
1151
        stc
1228
        ret
1152
        ret
1229
 
1153
 
1230
fat_notroot_next:
1154
fat_notroot_next:
1231
        push    ecx
1155
        push    ecx
1232
        lea     ecx, [ebp+FAT.buffer+0x200-0x20]
1156
        lea     ecx, [ebp+FAT.buffer+0x200-0x20]
1233
        cmp     edi, ecx
1157
        cmp     edi, ecx
1234
        jae     fat_notroot_next_sector
1158
        jae     fat_notroot_next_sector
1235
        pop     ecx
1159
        pop     ecx
1236
        add     edi, 0x20
1160
        add     edi, 0x20
1237
        ret     ; CF=0
1161
        ret     ; CF=0
1238
fat_notroot_next_sector:
1162
fat_notroot_next_sector:
1239
        push    [ebp+FAT.longname_sec2]
1163
        push    [ebp+FAT.longname_sec2]
1240
        pop     [ebp+FAT.longname_sec1]
1164
        pop     [ebp+FAT.longname_sec1]
1241
        push    eax
1165
        push    eax
1242
        call    fat_get_sector
1166
        call    fat_get_sector
1243
        mov     [ebp+FAT.longname_sec2], eax
1167
        mov     [ebp+FAT.longname_sec2], eax
1244
        pop     eax
1168
        pop     eax
1245
        mov     ecx, [eax+4]
1169
        mov     ecx, [eax+4]
1246
        inc     ecx
1170
        inc     ecx
1247
        cmp     ecx, [ebp+FAT.SECTORS_PER_CLUSTER]
1171
        cmp     ecx, [ebp+FAT.SECTORS_PER_CLUSTER]
1248
        jae     fat_notroot_next_cluster
1172
        jae     fat_notroot_next_cluster
1249
        mov     [eax+4], ecx
1173
        mov     [eax+4], ecx
1250
        jmp     @f
1174
        jmp     @f
1251
fat_notroot_next_cluster:
1175
fat_notroot_next_cluster:
1252
        push    eax
1176
        push    eax
1253
        mov     eax, [eax]
1177
        mov     eax, [eax]
1254
        call    get_FAT
1178
        call    get_FAT
1255
        mov     ecx, eax
1179
        mov     ecx, eax
1256
        pop     eax
1180
        pop     eax
1257
        jc      fat_notroot_first.deverr
1181
        jc      fat_notroot_first.deverr
1258
        cmp     ecx, 2
1182
        cmp     ecx, 2
1259
        jb      fat_notroot_next_err
1183
        jb      fat_notroot_next_err
1260
        cmp     ecx, [ebp+FAT.fatRESERVED]
1184
        cmp     ecx, [ebp+FAT.fatRESERVED]
1261
        jae     fat_notroot_next_err
1185
        jae     fat_notroot_next_err
1262
        mov     [eax], ecx
1186
        mov     [eax], ecx
1263
        and     dword [eax+4], 0
1187
        and     dword [eax+4], 0
1264
@@:
1188
@@:
1265
        pop     ecx
1189
        pop     ecx
1266
fat_notroot_first:
1190
fat_notroot_first:
1267
        call    fat_get_sector
1191
        call    fat_get_sector
1268
        push    ebx
1192
        push    ebx
1269
        lea     edi, [ebp+FAT.buffer]
1193
        lea     edi, [ebp+FAT.buffer]
1270
        mov     ebx, edi
1194
        mov     ebx, edi
1271
        call    fs_read32_sys
1195
        call    fs_read32_sys
1272
        pop     ebx
1196
        pop     ebx
1273
        test    eax, eax
1197
        test    eax, eax
1274
        jz      .ret ; CF=0
1198
        jz      .ret ; CF=0
1275
        push    ecx
1199
        push    ecx
1276
.deverr:
1200
.deverr:
1277
        pop     ecx
1201
        pop     ecx
1278
        mov     eax, ERROR_DEVICE
1202
        mov     eax, ERROR_DEVICE
1279
        stc
1203
        stc
1280
.ret:
1204
.ret:
1281
        ret
1205
        ret
1282
fat_notroot_next_err:
1206
fat_notroot_next_err:
1283
        pop     ecx
1207
        pop     ecx
1284
        mov     eax, ERROR_FILE_NOT_FOUND
1208
        mov     eax, ERROR_FILE_NOT_FOUND
1285
        stc
1209
        stc
1286
        ret
1210
        ret
1287
fat_notroot_begin_write:
1211
fat_notroot_begin_write:
1288
        push    eax edi
1212
        push    eax edi
1289
        call    fat_notroot_first
1213
        call    fat_notroot_first
1290
        pop     edi eax
1214
        pop     edi eax
1291
        ret
1215
        ret
1292
fat_notroot_end_write:
1216
fat_notroot_end_write:
1293
        call    fat_get_sector
1217
        call    fat_get_sector
1294
        push    ebx
1218
        push    ebx
1295
        lea     ebx, [ebp+FAT.buffer]
1219
        lea     ebx, [ebp+FAT.buffer]
1296
        call    fs_write32_sys
1220
        call    fs_write32_sys
1297
        pop     ebx
1221
        pop     ebx
1298
        ret
1222
        ret
1299
fat_notroot_next_write:
1223
fat_notroot_next_write:
1300
        push    ecx
1224
        push    ecx
1301
        lea     ecx, [ebp+FAT.buffer+0x200]
1225
        lea     ecx, [ebp+FAT.buffer+0x200]
1302
        cmp     edi, ecx
1226
        cmp     edi, ecx
1303
        jae     @f
1227
        jae     @f
1304
        pop     ecx
1228
        pop     ecx
1305
        ret
1229
        ret
1306
@@:
1230
@@:
1307
        push    eax
1231
        push    eax
1308
        call    fat_notroot_end_write
1232
        call    fat_notroot_end_write
1309
        pop     eax
1233
        pop     eax
1310
        jmp     fat_notroot_next_sector
1234
        jmp     fat_notroot_next_sector
1311
fat_notroot_extend_dir:
1235
fat_notroot_extend_dir:
1312
        push    eax
1236
        push    eax
1313
        call    get_free_FAT
1237
        call    get_free_FAT
1314
        jnc     .found
1238
        jnc     .found
1315
        pop     eax
1239
        pop     eax
1316
        ret     ; CF=1
1240
        ret     ; CF=1
1317
.found:
1241
.found:
1318
        push    edx
1242
        push    edx
1319
        mov     edx, [ebp+FAT.fatEND]
1243
        mov     edx, [ebp+FAT.fatEND]
1320
        call    set_FAT
1244
        call    set_FAT
1321
        jc      .writeerr
1245
        jc      .writeerr
1322
        mov     edx, eax
1246
        mov     edx, eax
1323
        mov     eax, [esp+4]
1247
        mov     eax, [esp+4]
1324
        mov     eax, [eax]
1248
        mov     eax, [eax]
1325
        push    edx
1249
        push    edx
1326
        call    set_FAT
1250
        call    set_FAT
1327
        pop     edx
1251
        pop     edx
1328
        jnc     @f
1252
        jnc     @f
1329
.writeerr:
1253
.writeerr:
1330
        pop     edx
1254
        pop     edx
1331
        pop     eax
1255
        pop     eax
1332
        stc
1256
        stc
1333
        ret
1257
        ret
1334
@@:
1258
@@:
1335
        push    ecx
1259
        push    ecx
1336
        or      ecx, -1
1260
        or      ecx, -1
1337
        call    add_disk_free_space
1261
        call    add_disk_free_space
1338
; zero new cluster
1262
; zero new cluster
1339
        mov     ecx, 512/4
1263
        mov     ecx, 512/4
1340
        lea     edi, [ebp+FAT.buffer]
1264
        lea     edi, [ebp+FAT.buffer]
1341
        push    edi
1265
        push    edi
1342
        xor     eax, eax
1266
        xor     eax, eax
1343
        rep stosd
1267
        rep stosd
1344
        pop     edi
1268
        pop     edi
1345
        pop     ecx
1269
        pop     ecx
1346
        mov     eax, [esp+4]
1270
        mov     eax, [esp+4]
1347
        mov     [eax], edx
1271
        mov     [eax], edx
1348
        and     dword [eax+4], 0
1272
        and     dword [eax+4], 0
1349
        pop     edx
1273
        pop     edx
1350
        mov     eax, [eax]
1274
        mov     eax, [eax]
1351
        dec     eax
1275
        dec     eax
1352
        dec     eax
1276
        dec     eax
1353
        push    ebx ecx
1277
        push    ebx ecx
1354
        mov     ecx, [ebp+FAT.SECTORS_PER_CLUSTER]
1278
        mov     ecx, [ebp+FAT.SECTORS_PER_CLUSTER]
1355
        imul    eax, ecx
1279
        imul    eax, ecx
1356
        add     eax, [ebp+FAT.DATA_START]
1280
        add     eax, [ebp+FAT.DATA_START]
1357
        mov     ebx, edi
1281
        mov     ebx, edi
1358
@@:
1282
@@:
1359
        push    eax
1283
        push    eax
1360
        call    fs_write32_sys
1284
        call    fs_write32_sys
1361
        pop     eax
1285
        pop     eax
1362
        inc     eax
1286
        inc     eax
1363
        loop    @b
1287
        loop    @b
1364
        pop     ecx ebx eax
1288
        pop     ecx ebx eax
1365
        clc
1289
        clc
1366
        ret
1290
        ret
1367
 
1291
 
1368
fat_get_sector:
1292
fat_get_sector:
1369
        push    ecx
1293
        push    ecx
1370
        mov     ecx, [eax]
1294
        mov     ecx, [eax]
1371
        dec     ecx
1295
        dec     ecx
1372
        dec     ecx
1296
        dec     ecx
1373
        imul    ecx, [ebp+FAT.SECTORS_PER_CLUSTER]
1297
        imul    ecx, [ebp+FAT.SECTORS_PER_CLUSTER]
1374
        add     ecx, [ebp+FAT.DATA_START]
1298
        add     ecx, [ebp+FAT.DATA_START]
1375
        add     ecx, [eax+4]
1299
        add     ecx, [eax+4]
1376
        mov     eax, ecx
1300
        mov     eax, ecx
1377
        pop     ecx
1301
        pop     ecx
1378
        ret
1302
        ret
1379
 
-
 
1380
;----------------------------------------------------------------
-
 
1381
;
-
 
1382
;  fs_HdRewrite - LFN variant for writing hard disk
-
 
1383
;
-
 
1384
;  Obsolete, will be replaced with filesystem-specific functions.
-
 
1385
;
-
 
1386
;  esi  points to filename
-
 
1387
;  ebx  ignored (reserved)
-
 
1388
;  ecx  number of bytes to write, 0+
-
 
1389
;  edx  mem location to data
-
 
1390
;
-
 
1391
;  ret ebx = number of written bytes
-
 
1392
;      eax = 0 ok read or other = errormsg
-
 
1393
;
-
 
1394
;--------------------------------------------------------------
-
 
1395
fs_HdCreateFolder:
-
 
1396
        mov     al, 1
-
 
1397
        jmp     fs_HdRewrite.common
-
 
1398
 
-
 
1399
fs_HdRewrite:
-
 
1400
        xor     eax, eax
-
 
1401
.common:
-
 
1402
        cmp     [fs_type], 16
-
 
1403
        jz      @f
-
 
1404
        cmp     [fs_type], 32
-
 
1405
        jz      @f
-
 
1406
        cmp     [fs_type], 1
-
 
1407
        jz      ntfs_HdRewrite
-
 
1408
        cmp     [fs_type], 2
-
 
1409
        jz      ext2_HdRewrite
-
 
1410
        mov     eax, ERROR_UNKNOWN_FS
-
 
1411
        xor     ebx, ebx
-
 
1412
        ret
-
 
1413
@@:
-
 
1414
        sub     ebx, 4
-
 
1415
        push    ebp
-
 
1416
        mov     ebp, [fs_dependent_data_start.partition]
-
 
1417
        test    eax, eax
-
 
1418
        mov     eax, fat_CreateFolder
-
 
1419
        jnz     @f
-
 
1420
        mov     eax, fat_Rewrite
-
 
1421
@@:
-
 
1422
        call    eax
-
 
1423
        pop     ebp
-
 
1424
        ret
-
 
1425
 
1303
 
1426
fshrad:
1304
fshrad:
1427
        call    fat_unlock
1305
        call    fat_unlock
1428
        mov     eax, ERROR_ACCESS_DENIED
1306
        mov     eax, ERROR_ACCESS_DENIED
1429
        xor     ebx, ebx
1307
        xor     ebx, ebx
1430
        ret
1308
        ret
1431
 
1309
 
1432
;----------------------------------------------------------------
1310
;----------------------------------------------------------------
1433
; fat_CreateFolder - FAT16/32 implementation of creating a folder
1311
; fat_CreateFolder - FAT16/32 implementation of creating a folder
1434
; in:  ebp = pointer to FAT structure
1312
; in:  ebp = pointer to FAT structure
1435
; in:  esi+[esp+4] = name
1313
; in:  esi+[esp+4] = name
1436
; in:  ebx = pointer to parameters from sysfunc 70
1314
; in:  ebx = pointer to parameters from sysfunc 70
1437
; out: eax, ebx = return values for sysfunc 70
1315
; out: eax, ebx = return values for sysfunc 70
1438
;----------------------------------------------------------------
1316
;----------------------------------------------------------------
1439
fat_CreateFolder:
1317
fat_CreateFolder:
1440
        push    1
1318
        push    1
1441
        jmp     fat_Rewrite.common
1319
        jmp     fat_Rewrite.common
1442
 
1320
 
1443
;----------------------------------------------------------------
1321
;----------------------------------------------------------------
1444
; fat_HdRewrite - FAT16/32 implementation of creating a new file
1322
; fat_Rewrite - FAT16/32 implementation of creating a new file
1445
; in:  ebp = pointer to FAT structure
1323
; in:  ebp = pointer to FAT structure
1446
; in:  esi+[esp+4] = name
1324
; in:  esi+[esp+4] = name
1447
; in:  ebx = pointer to parameters from sysfunc 70
1325
; in:  ebx = pointer to parameters from sysfunc 70
1448
; out: eax, ebx = return values for sysfunc 70
1326
; out: eax, ebx = return values for sysfunc 70
1449
;----------------------------------------------------------------
1327
;----------------------------------------------------------------
1450
fat_Rewrite:
1328
fat_Rewrite:
1451
        push    0
1329
        push    0
1452
.common:
1330
.common:
1453
        call    fat_lock
1331
        call    fat_lock
1454
        pop     eax
1332
        pop     eax
1455
        cmp     byte [esi], 0
1333
        cmp     byte [esi], 0
1456
        jz      fshrad
1334
        jz      fshrad
1457
        mov     ecx, [ebx+12]
1335
        mov     ecx, [ebx+12]
1458
        mov     edx, [ebx+16]
1336
        mov     edx, [ebx+16]
1459
        pushad
1337
        pushad
1460
        xor     edi, edi
1338
        xor     edi, edi
1461
        mov     edx, [esp+4+20h]
1339
        mov     edx, [esp+4+20h]
1462
        push    esi
1340
        push    esi
1463
        test    edx, edx
1341
        test    edx, edx
1464
        jz      @f
1342
        jz      @f
1465
        mov     esi, edx
1343
        mov     esi, edx
1466
@@:
1344
@@:
1467
        lodsb
1345
        lodsb
1468
        test    al, al
1346
        test    al, al
1469
        jz      @f
1347
        jz      @f
1470
        cmp     al, '/'
1348
        cmp     al, '/'
1471
        jnz     @b
1349
        jnz     @b
1472
        lea     edi, [esi-1]
1350
        lea     edi, [esi-1]
1473
        jmp     @b
1351
        jmp     @b
1474
@@:
1352
@@:
1475
        pop     esi
1353
        pop     esi
1476
        test    edi, edi
1354
        test    edi, edi
1477
        jnz     .noroot
1355
        jnz     .noroot
1478
        test    edx, edx
1356
        test    edx, edx
1479
        jnz     .hasebp
1357
        jnz     .hasebp
1480
        mov     edx, [ebp+FAT.ROOT_CLUSTER]
1358
        mov     edx, [ebp+FAT.ROOT_CLUSTER]
1481
        cmp     [ebp+FAT.fs_type], 32
1359
        cmp     [ebp+FAT.fs_type], 32
1482
        jz      .pushnotroot
1360
        jz      .pushnotroot
1483
        xor     edx, edx
1361
        xor     edx, edx
1484
        push    edx
1362
        push    edx
1485
        push    fat16_root_extend_dir
1363
        push    fat16_root_extend_dir
1486
        push    fat16_root_end_write
1364
        push    fat16_root_end_write
1487
        push    fat16_root_next_write
1365
        push    fat16_root_next_write
1488
        push    fat16_root_begin_write
1366
        push    fat16_root_begin_write
1489
        push    edx
1367
        push    edx
1490
        push    edx
1368
        push    edx
1491
        push    fat16_root_first
1369
        push    fat16_root_first
1492
        push    fat16_root_next
1370
        push    fat16_root_next
1493
        jmp     .common1
1371
        jmp     .common1
1494
.hasebp:
1372
.hasebp:
1495
        mov     eax, ERROR_ACCESS_DENIED
1373
        mov     eax, ERROR_ACCESS_DENIED
1496
        cmp     byte [edx], 0
1374
        cmp     byte [edx], 0
1497
        jz      .ret1
1375
        jz      .ret1
1498
        stdcall hd_find_lfn, 0
1376
        stdcall hd_find_lfn, 0
1499
        mov     esi, [esp+4+20h]
1377
        mov     esi, [esp+4+20h]
1500
        jc      .ret1
1378
        jc      .ret1
1501
        jmp     .common0
1379
        jmp     .common0
1502
.noroot:
1380
.noroot:
1503
        mov     eax, ERROR_ACCESS_DENIED
1381
        mov     eax, ERROR_ACCESS_DENIED
1504
        cmp     byte [edi+1], 0
1382
        cmp     byte [edi+1], 0
1505
        jz      .ret1
1383
        jz      .ret1
1506
; check existence
1384
; check existence
1507
        mov     byte [edi], 0
1385
        mov     byte [edi], 0
1508
        push    edi
1386
        push    edi
1509
        stdcall hd_find_lfn, [esp+4+24h]
1387
        stdcall hd_find_lfn, [esp+4+24h]
1510
        pop     esi
1388
        pop     esi
1511
        mov     byte [esi], '/'
1389
        mov     byte [esi], '/'
1512
        jnc     @f
1390
        jnc     @f
1513
.notfound0:
1391
.notfound0:
1514
        mov     eax, ERROR_FILE_NOT_FOUND
1392
        mov     eax, ERROR_FILE_NOT_FOUND
1515
.ret1:
1393
.ret1:
1516
        mov     [esp+28], eax
1394
        mov     [esp+28], eax
1517
        call    fat_unlock
1395
        call    fat_unlock
1518
        popad
1396
        popad
1519
        xor     ebx, ebx
1397
        xor     ebx, ebx
1520
        ret
1398
        ret
1521
@@:
1399
@@:
1522
        inc     esi
1400
        inc     esi
1523
.common0:
1401
.common0:
1524
        test    byte [edi+11], 0x10     ; must be directory
1402
        test    byte [edi+11], 0x10     ; must be directory
1525
        mov     eax, ERROR_ACCESS_DENIED
1403
        mov     eax, ERROR_ACCESS_DENIED
1526
        jz      .ret1
1404
        jz      .ret1
1527
        mov     edx, [edi+20-2]
1405
        mov     edx, [edi+20-2]
1528
        mov     dx, [edi+26]            ; ebp=cluster
1406
        mov     dx, [edi+26]            ; ebp=cluster
1529
        mov     eax, ERROR_FAT_TABLE
1407
        mov     eax, ERROR_FAT_TABLE
1530
        cmp     edx, 2
1408
        cmp     edx, 2
1531
        jb      .ret1
1409
        jb      .ret1
1532
.pushnotroot:
1410
.pushnotroot:
1533
        push    edx
1411
        push    edx
1534
        push    fat_notroot_extend_dir
1412
        push    fat_notroot_extend_dir
1535
        push    fat_notroot_end_write
1413
        push    fat_notroot_end_write
1536
        push    fat_notroot_next_write
1414
        push    fat_notroot_next_write
1537
        push    fat_notroot_begin_write
1415
        push    fat_notroot_begin_write
1538
        push    0
1416
        push    0
1539
        push    edx
1417
        push    edx
1540
        push    fat_notroot_first
1418
        push    fat_notroot_first
1541
        push    fat_notroot_next
1419
        push    fat_notroot_next
1542
.common1:
1420
.common1:
1543
        call    fat_find_lfn
1421
        call    fat_find_lfn
1544
        jc      .notfound
1422
        jc      .notfound
1545
; found
1423
; found
1546
        test    byte [edi+11], 10h
1424
        test    byte [edi+11], 10h
1547
        jz      .exists_file
1425
        jz      .exists_file
1548
; found directory; if we are creating directory, return OK,
1426
; found directory; if we are creating directory, return OK,
1549
;                  if we are creating file, say "access denied"
1427
;                  if we are creating file, say "access denied"
1550
        add     esp, 36
1428
        add     esp, 36
1551
        call    fat_unlock
1429
        call    fat_unlock
1552
        popad
1430
        popad
1553
        test    al, al
1431
        test    al, al
1554
        mov     eax, ERROR_ACCESS_DENIED
1432
        mov     eax, ERROR_ACCESS_DENIED
1555
        jz      @f
1433
        jz      @f
1556
        mov     al, 0
1434
        mov     al, 0
1557
@@:
1435
@@:
1558
        xor     ebx, ebx
1436
        xor     ebx, ebx
1559
        ret
1437
        ret
1560
.exists_file:
1438
.exists_file:
1561
; found file; if we are creating directory, return "access denied",
1439
; found file; if we are creating directory, return "access denied",
1562
;             if we are creating file, delete existing file and continue
1440
;             if we are creating file, delete existing file and continue
1563
        cmp     byte [esp+36+28], 0
1441
        cmp     byte [esp+36+28], 0
1564
        jz      @f
1442
        jz      @f
1565
        add     esp, 36
1443
        add     esp, 36
1566
        call    fat_unlock
1444
        call    fat_unlock
1567
        popad
1445
        popad
1568
        mov     eax, ERROR_ACCESS_DENIED
1446
        mov     eax, ERROR_ACCESS_DENIED
1569
        xor     ebx, ebx
1447
        xor     ebx, ebx
1570
        ret
1448
        ret
1571
@@:
1449
@@:
1572
; delete FAT chain
1450
; delete FAT chain
1573
        push    edi
1451
        push    edi
1574
        xor     eax, eax
1452
        xor     eax, eax
1575
        mov     dword [edi+28], eax     ; zero size
1453
        mov     dword [edi+28], eax     ; zero size
1576
        xor     ecx, ecx
1454
        xor     ecx, ecx
1577
        mov     eax, [edi+20-2]
1455
        mov     eax, [edi+20-2]
1578
        mov     ax, [edi+26]
1456
        mov     ax, [edi+26]
1579
        mov     word [edi+20], cx
1457
        mov     word [edi+20], cx
1580
        mov     word [edi+26], cx
1458
        mov     word [edi+26], cx
1581
        test    eax, eax
1459
        test    eax, eax
1582
        jz      .done1
1460
        jz      .done1
1583
@@:
1461
@@:
1584
        cmp     eax, [ebp+FAT.fatRESERVED]
1462
        cmp     eax, [ebp+FAT.fatRESERVED]
1585
        jae     .done1
1463
        jae     .done1
1586
        push    edx
1464
        push    edx
1587
        xor     edx, edx
1465
        xor     edx, edx
1588
        call    set_FAT
1466
        call    set_FAT
1589
        mov     eax, edx
1467
        mov     eax, edx
1590
        pop     edx
1468
        pop     edx
1591
        jc      .done1
1469
        jc      .done1
1592
        inc     ecx
1470
        inc     ecx
1593
        jmp     @b
1471
        jmp     @b
1594
.done1:
1472
.done1:
1595
        pop     edi
1473
        pop     edi
1596
        call    get_time_for_file
1474
        call    get_time_for_file
1597
        mov     [edi+22], ax
1475
        mov     [edi+22], ax
1598
        call    get_date_for_file
1476
        call    get_date_for_file
1599
        mov     [edi+24], ax
1477
        mov     [edi+24], ax
1600
        mov     [edi+18], ax
1478
        mov     [edi+18], ax
1601
        or      byte [edi+11], 20h      ; set 'archive' attribute
1479
        or      byte [edi+11], 20h      ; set 'archive' attribute
1602
        jmp     .doit
1480
        jmp     .doit
1603
.notfound:
1481
.notfound:
1604
; file is not found; generate short name
1482
; file is not found; generate short name
1605
        call    fat_name_is_legal
1483
        call    fat_name_is_legal
1606
        jc      @f
1484
        jc      @f
1607
        add     esp, 36
1485
        add     esp, 36
1608
        call    fat_unlock
1486
        call    fat_unlock
1609
        popad
1487
        popad
1610
        mov     eax, ERROR_FILE_NOT_FOUND
1488
        mov     eax, ERROR_FILE_NOT_FOUND
1611
        xor     ebx, ebx
1489
        xor     ebx, ebx
1612
        ret
1490
        ret
1613
@@:
1491
@@:
1614
        sub     esp, 12
1492
        sub     esp, 12
1615
        mov     edi, esp
1493
        mov     edi, esp
1616
        call    fat_gen_short_name
1494
        call    fat_gen_short_name
1617
.test_short_name_loop:
1495
.test_short_name_loop:
1618
        push    esi edi ecx
1496
        push    esi edi ecx
1619
        mov     esi, edi
1497
        mov     esi, edi
1620
        lea     eax, [esp+12+12+8]
1498
        lea     eax, [esp+12+12+8]
1621
        mov     edx, [eax+24]
1499
        mov     edx, [eax+24]
1622
        mov     [eax], edx
1500
        mov     [eax], edx
1623
        and     dword [eax+4], 0
1501
        and     dword [eax+4], 0
1624
        call    dword [eax-4]
1502
        call    dword [eax-4]
1625
        jc      .found
1503
        jc      .found
1626
.test_short_name_entry:
1504
.test_short_name_entry:
1627
        cmp     byte [edi+11], 0xF
1505
        cmp     byte [edi+11], 0xF
1628
        jz      .test_short_name_cont
1506
        jz      .test_short_name_cont
1629
        mov     ecx, 11
1507
        mov     ecx, 11
1630
        push    esi edi
1508
        push    esi edi
1631
        repz cmpsb
1509
        repz cmpsb
1632
        pop     edi esi
1510
        pop     edi esi
1633
        jz      .short_name_found
1511
        jz      .short_name_found
1634
.test_short_name_cont:
1512
.test_short_name_cont:
1635
        lea     eax, [esp+12+12+8]
1513
        lea     eax, [esp+12+12+8]
1636
        call    dword [eax-8]
1514
        call    dword [eax-8]
1637
        jnc     .test_short_name_entry
1515
        jnc     .test_short_name_entry
1638
        jmp     .found
1516
        jmp     .found
1639
.short_name_found:
1517
.short_name_found:
1640
        pop     ecx edi esi
1518
        pop     ecx edi esi
1641
        call    fat_next_short_name
1519
        call    fat_next_short_name
1642
        jnc     .test_short_name_loop
1520
        jnc     .test_short_name_loop
1643
.disk_full:
1521
.disk_full:
1644
        add     esp, 12+36
1522
        add     esp, 12+36
1645
        call    fat_unlock
1523
        call    fat_unlock
1646
        popa
1524
        popa
1647
        mov     eax, ERROR_DISK_FULL
1525
        mov     eax, ERROR_DISK_FULL
1648
        xor     ebx, ebx
1526
        xor     ebx, ebx
1649
        ret
1527
        ret
1650
.found:
1528
.found:
1651
        pop     ecx edi esi
1529
        pop     ecx edi esi
1652
; now find space in directory
1530
; now find space in directory
1653
; we need to save LFN <=> LFN is not equal to short name <=> generated name contains '~'
1531
; we need to save LFN <=> LFN is not equal to short name <=> generated name contains '~'
1654
        mov     al, '~'
1532
        mov     al, '~'
1655
        push    ecx edi
1533
        push    ecx edi
1656
        mov     ecx, 8
1534
        mov     ecx, 8
1657
        repnz scasb
1535
        repnz scasb
1658
        movi    eax, 1     ; 1 entry
1536
        movi    eax, 1     ; 1 entry
1659
        jnz     .notilde
1537
        jnz     .notilde
1660
; we need ceil(strlen(esi)/13) additional entries = floor((strlen(esi)+12+13)/13) total
1538
; we need ceil(strlen(esi)/13) additional entries = floor((strlen(esi)+12+13)/13) total
1661
        xor     eax, eax
1539
        xor     eax, eax
1662
@@:
1540
@@:
1663
        cmp     byte [esi], 0
1541
        cmp     byte [esi], 0
1664
        jz      @f
1542
        jz      @f
1665
        inc     esi
1543
        inc     esi
1666
        inc     eax
1544
        inc     eax
1667
        jmp     @b
1545
        jmp     @b
1668
@@:
1546
@@:
1669
        sub     esi, eax
1547
        sub     esi, eax
1670
        add     eax, 12+13
1548
        add     eax, 12+13
1671
        mov     ecx, 13
1549
        mov     ecx, 13
1672
        push    edx
1550
        push    edx
1673
        cdq
1551
        cdq
1674
        div     ecx
1552
        div     ecx
1675
        pop     edx
1553
        pop     edx
1676
.notilde:
1554
.notilde:
1677
        push    -1
1555
        push    -1
1678
        push    -1
1556
        push    -1
1679
        push    -1
1557
        push    -1
1680
; find  successive entries in directory
1558
; find  successive entries in directory
1681
        xor     ecx, ecx
1559
        xor     ecx, ecx
1682
        push    eax
1560
        push    eax
1683
        lea     eax, [esp+16+8+12+8]
1561
        lea     eax, [esp+16+8+12+8]
1684
        mov     edx, [eax+24]
1562
        mov     edx, [eax+24]
1685
        mov     [eax], edx
1563
        mov     [eax], edx
1686
        and     dword [eax+4], 0
1564
        and     dword [eax+4], 0
1687
        call    dword [eax-4]
1565
        call    dword [eax-4]
1688
        pop     eax
1566
        pop     eax
1689
        jnc     .scan_dir
1567
        jnc     .scan_dir
1690
.fsfrfe3:
1568
.fsfrfe3:
1691
        add     esp, 12+8+12+36
1569
        add     esp, 12+8+12+36
1692
        call    fat_unlock
1570
        call    fat_unlock
1693
        popad
1571
        popad
1694
        mov     eax, ERROR_DEVICE
1572
        mov     eax, ERROR_DEVICE
1695
        xor     ebx, ebx
1573
        xor     ebx, ebx
1696
        ret
1574
        ret
1697
.scan_dir:
1575
.scan_dir:
1698
        cmp     byte [edi], 0
1576
        cmp     byte [edi], 0
1699
        jz      .free
1577
        jz      .free
1700
        cmp     byte [edi], 0xE5
1578
        cmp     byte [edi], 0xE5
1701
        jz      .free
1579
        jz      .free
1702
        xor     ecx, ecx
1580
        xor     ecx, ecx
1703
.scan_cont:
1581
.scan_cont:
1704
        push    eax
1582
        push    eax
1705
        lea     eax, [esp+16+8+12+8]
1583
        lea     eax, [esp+16+8+12+8]
1706
        call    dword [eax-8]
1584
        call    dword [eax-8]
1707
        mov     edx, eax
1585
        mov     edx, eax
1708
        pop     eax
1586
        pop     eax
1709
        jnc     .scan_dir
1587
        jnc     .scan_dir
1710
        cmp     edx, ERROR_DEVICE
1588
        cmp     edx, ERROR_DEVICE
1711
        jz      .fsfrfe3
1589
        jz      .fsfrfe3
1712
        push    eax
1590
        push    eax
1713
        lea     eax, [esp+16+8+12+8]
1591
        lea     eax, [esp+16+8+12+8]
1714
        call    dword [eax+20]          ; extend directory
1592
        call    dword [eax+20]          ; extend directory
1715
        pop     eax
1593
        pop     eax
1716
        jnc     .scan_dir
1594
        jnc     .scan_dir
1717
        add     esp, 12+8+12+36
1595
        add     esp, 12+8+12+36
1718
        call    fat_unlock
1596
        call    fat_unlock
1719
        popad
1597
        popad
1720
        mov     eax, ERROR_DISK_FULL
1598
        mov     eax, ERROR_DISK_FULL
1721
        xor     ebx, ebx
1599
        xor     ebx, ebx
1722
        ret
1600
        ret
1723
.free:
1601
.free:
1724
        test    ecx, ecx
1602
        test    ecx, ecx
1725
        jnz     @f
1603
        jnz     @f
1726
        mov     [esp], edi
1604
        mov     [esp], edi
1727
        mov     ecx, [esp+12+8+12+8]
1605
        mov     ecx, [esp+12+8+12+8]
1728
        mov     [esp+4], ecx
1606
        mov     [esp+4], ecx
1729
        mov     ecx, [esp+12+8+12+12]
1607
        mov     ecx, [esp+12+8+12+12]
1730
        mov     [esp+8], ecx
1608
        mov     [esp+8], ecx
1731
        xor     ecx, ecx
1609
        xor     ecx, ecx
1732
@@:
1610
@@:
1733
        inc     ecx
1611
        inc     ecx
1734
        cmp     ecx, eax
1612
        cmp     ecx, eax
1735
        jb      .scan_cont
1613
        jb      .scan_cont
1736
; found!
1614
; found!
1737
        push    esi ecx
1615
        push    esi ecx
1738
; If creating a directory, allocate one data cluster now and fail immediately
1616
; If creating a directory, allocate one data cluster now and fail immediately
1739
; if this is impossible. This prevents from creating an invalid directory entry
1617
; if this is impossible. This prevents from creating an invalid directory entry
1740
; on a full disk.
1618
; on a full disk.
1741
; yup, the argument is quite non-intuitive... but what should I do if
1619
; yup, the argument is quite non-intuitive... but what should I do if
1742
; the entire function uses such arguments? BTW, it refers to al from pushad,
1620
; the entire function uses such arguments? BTW, it refers to al from pushad,
1743
; which in turn is filled with 0 in fat_Rewrite and 1 in fat_CreateFolder.
1621
; which in turn is filled with 0 in fat_Rewrite and 1 in fat_CreateFolder.
1744
        cmp     byte [esp+8+12+8+12+36+28], 0
1622
        cmp     byte [esp+8+12+8+12+36+28], 0
1745
        jz      .no.preallocate.folder.data
1623
        jz      .no.preallocate.folder.data
1746
        call    get_free_FAT
1624
        call    get_free_FAT
1747
        jnc     @f
1625
        jnc     @f
1748
        add     esp, 8+12+8
1626
        add     esp, 8+12+8
1749
        jmp     .disk_full
1627
        jmp     .disk_full
1750
@@:
1628
@@:
1751
        mov     [esp+8+12+8+12+36+20], eax ; store the cluster somewhere
1629
        mov     [esp+8+12+8+12+36+20], eax ; store the cluster somewhere
1752
.no.preallocate.folder.data:
1630
.no.preallocate.folder.data:
1753
; calculate name checksum
1631
; calculate name checksum
1754
        mov     esi, [esp+8+12]
1632
        mov     esi, [esp+8+12]
1755
        mov     ecx, 11
1633
        mov     ecx, 11
1756
        xor     eax, eax
1634
        xor     eax, eax
1757
@@:
1635
@@:
1758
        ror     al, 1
1636
        ror     al, 1
1759
        add     al, [esi]
1637
        add     al, [esi]
1760
        inc     esi
1638
        inc     esi
1761
        loop    @b
1639
        loop    @b
1762
        pop     ecx esi
1640
        pop     ecx esi
1763
        pop     edi
1641
        pop     edi
1764
        pop     dword [esp+8+12+12]
1642
        pop     dword [esp+8+12+12]
1765
        pop     dword [esp+8+12+12]
1643
        pop     dword [esp+8+12+12]
1766
; edi points to first entry in free chunk
1644
; edi points to first entry in free chunk
1767
        dec     ecx
1645
        dec     ecx
1768
        jz      .nolfn
1646
        jz      .nolfn
1769
        push    esi
1647
        push    esi
1770
        push    eax
1648
        push    eax
1771
        lea     eax, [esp+8+8+12+8]
1649
        lea     eax, [esp+8+8+12+8]
1772
        call    dword [eax+8]         ; begin write
1650
        call    dword [eax+8]         ; begin write
1773
        mov     al, 40h
1651
        mov     al, 40h
1774
.writelfn:
1652
.writelfn:
1775
        or      al, cl
1653
        or      al, cl
1776
        mov     esi, [esp+4]
1654
        mov     esi, [esp+4]
1777
        push    ecx
1655
        push    ecx
1778
        dec     ecx
1656
        dec     ecx
1779
        imul    ecx, 13
1657
        imul    ecx, 13
1780
        add     esi, ecx
1658
        add     esi, ecx
1781
        stosb
1659
        stosb
1782
        mov     cl, 5
1660
        mov     cl, 5
1783
        call    fs_RamdiskRewrite.read_symbols
1661
        call    fs_RamdiskRewrite.read_symbols
1784
        mov     ax, 0xF
1662
        mov     ax, 0xF
1785
        stosw
1663
        stosw
1786
        mov     al, [esp+4]
1664
        mov     al, [esp+4]
1787
        stosb
1665
        stosb
1788
        mov     cl, 6
1666
        mov     cl, 6
1789
        call    fs_RamdiskRewrite.read_symbols
1667
        call    fs_RamdiskRewrite.read_symbols
1790
        xor     eax, eax
1668
        xor     eax, eax
1791
        stosw
1669
        stosw
1792
        mov     cl, 2
1670
        mov     cl, 2
1793
        call    fs_RamdiskRewrite.read_symbols
1671
        call    fs_RamdiskRewrite.read_symbols
1794
        pop     ecx
1672
        pop     ecx
1795
        lea     eax, [esp+8+8+12+8]
1673
        lea     eax, [esp+8+8+12+8]
1796
        call    dword [eax+12]         ; next write
1674
        call    dword [eax+12]         ; next write
1797
        xor     eax, eax
1675
        xor     eax, eax
1798
        loop    .writelfn
1676
        loop    .writelfn
1799
        pop     eax
1677
        pop     eax
1800
        pop     esi
1678
        pop     esi
1801
;        lea     eax, [esp+8+12+8]
1679
;        lea     eax, [esp+8+12+8]
1802
;        call    dword [eax+16]          ; end write
1680
;        call    dword [eax+16]          ; end write
1803
.nolfn:
1681
.nolfn:
1804
        xchg    esi, [esp]
1682
        xchg    esi, [esp]
1805
        mov     ecx, 11
1683
        mov     ecx, 11
1806
        rep movsb
1684
        rep movsb
1807
        mov     word [edi], 20h         ; attributes
1685
        mov     word [edi], 20h         ; attributes
1808
        sub     edi, 11
1686
        sub     edi, 11
1809
        pop     esi ecx
1687
        pop     esi ecx
1810
        add     esp, 12
1688
        add     esp, 12
1811
        mov     byte [edi+13], 0        ; tenths of a second at file creation time
1689
        mov     byte [edi+13], 0        ; tenths of a second at file creation time
1812
        call    get_time_for_file
1690
        call    get_time_for_file
1813
        mov     [edi+14], ax            ; creation time
1691
        mov     [edi+14], ax            ; creation time
1814
        mov     [edi+22], ax            ; last write time
1692
        mov     [edi+22], ax            ; last write time
1815
        call    get_date_for_file
1693
        call    get_date_for_file
1816
        mov     [edi+16], ax            ; creation date
1694
        mov     [edi+16], ax            ; creation date
1817
        mov     [edi+24], ax            ; last write date
1695
        mov     [edi+24], ax            ; last write date
1818
        mov     [edi+18], ax            ; last access date
1696
        mov     [edi+18], ax            ; last access date
1819
        xor     ecx, ecx
1697
        xor     ecx, ecx
1820
        mov     word [edi+20], cx       ; high word of cluster
1698
        mov     word [edi+20], cx       ; high word of cluster
1821
        mov     word [edi+26], cx       ; low word of cluster - to be filled
1699
        mov     word [edi+26], cx       ; low word of cluster - to be filled
1822
        mov     dword [edi+28], ecx     ; file size - to be filled
1700
        mov     dword [edi+28], ecx     ; file size - to be filled
1823
        cmp     byte [esp+36+28], cl
1701
        cmp     byte [esp+36+28], cl
1824
        jz      .doit
1702
        jz      .doit
1825
; create directory
1703
; create directory
1826
        mov     byte [edi+11], 10h      ; attributes: folder
1704
        mov     byte [edi+11], 10h      ; attributes: folder
1827
        mov     esi, edi
1705
        mov     esi, edi
1828
        lea     eax, [esp+8]
1706
        lea     eax, [esp+8]
1829
        call    dword [eax+16]  ; flush directory
1707
        call    dword [eax+16]  ; flush directory
1830
        mov     eax, [esp+36+20] ; extract saved cluster
1708
        mov     eax, [esp+36+20] ; extract saved cluster
1831
        mov     [esp+36+20], edi ; this is needed for calculating arg of add_disk_free_space!
1709
        mov     [esp+36+20], edi ; this is needed for calculating arg of add_disk_free_space!
1832
        push    ecx
1710
        push    ecx
1833
        mov     ecx, [ebp+FAT.SECTORS_PER_CLUSTER]
1711
        mov     ecx, [ebp+FAT.SECTORS_PER_CLUSTER]
1834
        shl     ecx, 9
1712
        shl     ecx, 9
1835
        push    ecx
1713
        push    ecx
1836
        push    edi
1714
        push    edi
1837
        jmp     .doit2
1715
        jmp     .doit2
1838
.doit:
1716
.doit:
1839
        mov     esi, [esp+36+20]
1717
        mov     esi, [esp+36+20]
1840
        lea     eax, [esp+8]
1718
        lea     eax, [esp+8]
1841
        call    dword [eax+16]  ; flush directory
1719
        call    dword [eax+16]  ; flush directory
1842
        push    ecx
1720
        push    ecx
1843
        mov     ecx, [esp+4+36+24]
1721
        mov     ecx, [esp+4+36+24]
1844
        push    ecx
1722
        push    ecx
1845
        push    edi
1723
        push    edi
1846
        test    ecx, ecx
1724
        test    ecx, ecx
1847
        jz      .done
1725
        jz      .done
1848
        call    get_free_FAT
1726
        call    get_free_FAT
1849
        jc      .diskfull
1727
        jc      .diskfull
1850
.doit2:
1728
.doit2:
1851
        push    eax
1729
        push    eax
1852
        mov     [edi+26], ax
1730
        mov     [edi+26], ax
1853
        shr     eax, 16
1731
        shr     eax, 16
1854
        mov     [edi+20], ax
1732
        mov     [edi+20], ax
1855
        lea     eax, [esp+16+8]
1733
        lea     eax, [esp+16+8]
1856
        call    dword [eax+16]  ; flush directory
1734
        call    dword [eax+16]  ; flush directory
1857
        pop     eax
1735
        pop     eax
1858
        push    edx
1736
        push    edx
1859
        mov     edx, [ebp+FAT.fatEND]
1737
        mov     edx, [ebp+FAT.fatEND]
1860
        call    set_FAT
1738
        call    set_FAT
1861
        pop     edx
1739
        pop     edx
1862
.write_cluster:
1740
.write_cluster:
1863
        push    eax
1741
        push    eax
1864
        dec     eax
1742
        dec     eax
1865
        dec     eax
1743
        dec     eax
1866
        imul    eax, [ebp+FAT.SECTORS_PER_CLUSTER]
1744
        imul    eax, [ebp+FAT.SECTORS_PER_CLUSTER]
1867
        add     eax, [ebp+FAT.DATA_START]
1745
        add     eax, [ebp+FAT.DATA_START]
1868
        push    [ebp+FAT.SECTORS_PER_CLUSTER]
1746
        push    [ebp+FAT.SECTORS_PER_CLUSTER]
1869
; write data
1747
; write data
1870
.write_sector:
1748
.write_sector:
1871
        cmp     byte [esp+20+36+28], 0
1749
        cmp     byte [esp+20+36+28], 0
1872
        jnz     .writedir
1750
        jnz     .writedir
1873
        mov     ecx, 512
1751
        mov     ecx, 512
1874
        cmp     dword [esp+12], ecx
1752
        cmp     dword [esp+12], ecx
1875
        jb      .writeshort
1753
        jb      .writeshort
1876
; we can write directly from given buffer
1754
; we can write directly from given buffer
1877
        mov     ebx, esi
1755
        mov     ebx, esi
1878
        add     esi, ecx
1756
        add     esi, ecx
1879
        jmp     .writecommon
1757
        jmp     .writecommon
1880
.writeshort:
1758
.writeshort:
1881
        mov     ecx, [esp+12]
1759
        mov     ecx, [esp+12]
1882
        push    ecx
1760
        push    ecx
1883
        lea     edi, [ebp+FAT.buffer]
1761
        lea     edi, [ebp+FAT.buffer]
1884
        mov     ebx, edi
1762
        mov     ebx, edi
1885
        rep movsb
1763
        rep movsb
1886
.writedircont:
1764
.writedircont:
1887
        lea     ecx, [ebp+FAT.buffer+0x200]
1765
        lea     ecx, [ebp+FAT.buffer+0x200]
1888
        sub     ecx, edi
1766
        sub     ecx, edi
1889
        push    eax
1767
        push    eax
1890
        xor     eax, eax
1768
        xor     eax, eax
1891
        rep stosb
1769
        rep stosb
1892
        pop     eax
1770
        pop     eax
1893
        pop     ecx
1771
        pop     ecx
1894
.writecommon:
1772
.writecommon:
1895
        push    eax
1773
        push    eax
1896
        call    fs_write32_app
1774
        call    fs_write32_app
1897
        test    eax, eax
1775
        test    eax, eax
1898
        pop     eax
1776
        pop     eax
1899
        jnz     .writeerr
1777
        jnz     .writeerr
1900
        inc     eax
1778
        inc     eax
1901
        sub     dword [esp+12], ecx
1779
        sub     dword [esp+12], ecx
1902
        jz      .writedone
1780
        jz      .writedone
1903
        dec     dword [esp]
1781
        dec     dword [esp]
1904
        jnz     .write_sector
1782
        jnz     .write_sector
1905
        pop     eax
1783
        pop     eax
1906
; allocate new cluster
1784
; allocate new cluster
1907
        pop     eax
1785
        pop     eax
1908
        mov     ecx, eax
1786
        mov     ecx, eax
1909
        call    get_free_FAT
1787
        call    get_free_FAT
1910
        jc      .diskfull
1788
        jc      .diskfull
1911
        push    edx
1789
        push    edx
1912
        mov     edx, [ebp+FAT.fatEND]
1790
        mov     edx, [ebp+FAT.fatEND]
1913
        call    set_FAT
1791
        call    set_FAT
1914
        xchg    eax, ecx
1792
        xchg    eax, ecx
1915
        mov     edx, ecx
1793
        mov     edx, ecx
1916
        call    set_FAT
1794
        call    set_FAT
1917
        pop     edx
1795
        pop     edx
1918
        xchg    eax, ecx
1796
        xchg    eax, ecx
1919
        jmp     .write_cluster
1797
        jmp     .write_cluster
1920
.diskfull:
1798
.diskfull:
1921
        mov     eax, ERROR_DISK_FULL
1799
        mov     eax, ERROR_DISK_FULL
1922
        jmp     .ret
1800
        jmp     .ret
1923
.writeerr:
1801
.writeerr:
1924
        pop     eax eax
1802
        pop     eax eax
1925
        sub     esi, ecx
1803
        sub     esi, ecx
1926
        mov     eax, ERROR_DEVICE
1804
        mov     eax, ERROR_DEVICE
1927
        jmp     .ret
1805
        jmp     .ret
1928
.writedone:
1806
.writedone:
1929
        pop     eax eax
1807
        pop     eax eax
1930
.done:
1808
.done:
1931
        xor     eax, eax
1809
        xor     eax, eax
1932
.ret:
1810
.ret:
1933
        pop     edi ecx
1811
        pop     edi ecx
1934
        sub     esi, [esp+4+36+20]
1812
        sub     esi, [esp+4+36+20]
1935
        mov     [esp+4+36+28], eax
1813
        mov     [esp+4+36+28], eax
1936
        mov     [esp+4+36+16], esi
1814
        mov     [esp+4+36+16], esi
1937
        lea     eax, [esp+12]
1815
        lea     eax, [esp+12]
1938
        call    dword [eax+8]
1816
        call    dword [eax+8]
1939
        mov     [edi+28], esi
1817
        mov     [edi+28], esi
1940
        call    dword [eax+16]
1818
        call    dword [eax+16]
1941
        mov     [esp+36+16], ebx
1819
        mov     [esp+36+16], ebx
1942
        lea     eax, [esi+511]
1820
        lea     eax, [esi+511]
1943
        shr     eax, 9
1821
        shr     eax, 9
1944
        mov     ecx, [ebp+FAT.SECTORS_PER_CLUSTER]
1822
        mov     ecx, [ebp+FAT.SECTORS_PER_CLUSTER]
1945
        lea     eax, [eax+ecx-1]
1823
        lea     eax, [eax+ecx-1]
1946
        xor     edx, edx
1824
        xor     edx, edx
1947
        div     ecx
1825
        div     ecx
1948
        pop     ecx
1826
        pop     ecx
1949
        sub     ecx, eax
1827
        sub     ecx, eax
1950
        call    add_disk_free_space
1828
        call    add_disk_free_space
1951
        add     esp, 36
1829
        add     esp, 36
1952
        call    update_disk
1830
        call    update_disk
1953
        call    fat_unlock
1831
        call    fat_unlock
1954
        popad
1832
        popad
1955
        ret
1833
        ret
1956
.writedir:
1834
.writedir:
1957
        push    512
1835
        push    512
1958
        lea     edi, [ebp+FAT.buffer]
1836
        lea     edi, [ebp+FAT.buffer]
1959
        mov     ebx, edi
1837
        mov     ebx, edi
1960
        mov     ecx, [ebp+FAT.SECTORS_PER_CLUSTER]
1838
        mov     ecx, [ebp+FAT.SECTORS_PER_CLUSTER]
1961
        shl     ecx, 9
1839
        shl     ecx, 9
1962
        cmp     ecx, [esp+16]
1840
        cmp     ecx, [esp+16]
1963
        jnz     .writedircont
1841
        jnz     .writedircont
1964
        dec     dword [esp+20]
1842
        dec     dword [esp+20]
1965
        push    esi
1843
        push    esi
1966
        mov     ecx, 32/4
1844
        mov     ecx, 32/4
1967
        rep movsd
1845
        rep movsd
1968
        pop     esi
1846
        pop     esi
1969
        mov     dword [edi-32], '.   '
1847
        mov     dword [edi-32], '.   '
1970
        mov     dword [edi-32+4], '    '
1848
        mov     dword [edi-32+4], '    '
1971
        mov     dword [edi-32+8], '    '
1849
        mov     dword [edi-32+8], '    '
1972
        mov     byte [edi-32+11], 10h
1850
        mov     byte [edi-32+11], 10h
1973
        push    esi
1851
        push    esi
1974
        mov     ecx, 32/4
1852
        mov     ecx, 32/4
1975
        rep movsd
1853
        rep movsd
1976
        pop     esi
1854
        pop     esi
1977
        mov     dword [edi-32], '..  '
1855
        mov     dword [edi-32], '..  '
1978
        mov     dword [edi-32+4], '    '
1856
        mov     dword [edi-32+4], '    '
1979
        mov     dword [edi-32+8], '    '
1857
        mov     dword [edi-32+8], '    '
1980
        mov     byte [edi-32+11], 10h
1858
        mov     byte [edi-32+11], 10h
1981
        mov     ecx, [esp+20+36]
1859
        mov     ecx, [esp+20+36]
1982
        cmp     ecx, [ebp+FAT.ROOT_CLUSTER]
1860
        cmp     ecx, [ebp+FAT.ROOT_CLUSTER]
1983
        jnz     @f
1861
        jnz     @f
1984
        xor     ecx, ecx
1862
        xor     ecx, ecx
1985
@@:
1863
@@:
1986
        mov     word [edi-32+26], cx
1864
        mov     word [edi-32+26], cx
1987
        shr     ecx, 16
1865
        shr     ecx, 16
1988
        mov     [edi-32+20], cx
1866
        mov     [edi-32+20], cx
1989
        jmp     .writedircont
1867
        jmp     .writedircont
1990
 
-
 
1991
;----------------------------------------------------------------
-
 
1992
;
-
 
1993
;  fs_HdWrite - LFN variant for writing to hard disk
-
 
1994
;
-
 
1995
;  Obsolete, will be replaced with filesystem-specific functions.
-
 
1996
;
-
 
1997
;  esi  points to filename
-
 
1998
;  ebx  pointer to 64-bit number = first wanted byte, 0+
-
 
1999
;       may be ebx=0 - start from first byte
-
 
2000
;  ecx  number of bytes to write, 0+
-
 
2001
;  edx  mem location to data
-
 
2002
;
-
 
2003
;  ret ebx = bytes written (maybe 0)
-
 
2004
;      eax = 0 ok write or other = errormsg
-
 
2005
;
-
 
2006
;--------------------------------------------------------------
1868
 
2007
fat_Write.access_denied:
1869
fat_Write.access_denied:
2008
        push    ERROR_ACCESS_DENIED
1870
        push    ERROR_ACCESS_DENIED
2009
fs_HdWrite.ret0:
1871
fat_Write.ret0:
2010
        pop     eax
1872
        pop     eax
2011
        xor     ebx, ebx
1873
        xor     ebx, ebx
2012
        ret
1874
        ret
2013
 
1875
 
2014
fs_HdWrite.ret11:
1876
fat_Write.ret11:
2015
        push    ERROR_DEVICE
1877
        push    ERROR_DEVICE
2016
        jmp     fs_HdWrite.ret0
-
 
2017
 
-
 
2018
fs_HdWrite:
-
 
2019
        cmp     [fs_type], 16
-
 
2020
        jz      @f
-
 
2021
        cmp     [fs_type], 32
-
 
2022
        jz      @f
-
 
2023
        cmp     [fs_type], 1
-
 
2024
        jz      ntfs_HdWrite
-
 
2025
        cmp     [fs_type], 2
-
 
2026
        jz      ext2_HdWrite
-
 
2027
        push    ERROR_UNKNOWN_FS
-
 
2028
        jmp     .ret0
-
 
2029
@@:
-
 
2030
        sub     ebx, 4
-
 
2031
        push    ebp
-
 
2032
        mov     ebp, [fs_dependent_data_start.partition]
-
 
2033
        call    fat_Write
-
 
2034
        pop     ebp
-
 
2035
        ret
1878
        jmp     fat_Write.ret0
2036
 
1879
 
2037
;----------------------------------------------------------------
1880
;----------------------------------------------------------------
2038
; fat_Write - FAT16/32 implementation of writing to file
1881
; fat_Write - FAT16/32 implementation of writing to file
2039
; in:  ebp = pointer to FAT structure
1882
; in:  ebp = pointer to FAT structure
2040
; in:  esi+[esp+4] = name
1883
; in:  esi+[esp+4] = name
2041
; in:  ebx = pointer to parameters from sysfunc 70
1884
; in:  ebx = pointer to parameters from sysfunc 70
2042
; out: eax, ebx = return values for sysfunc 70
1885
; out: eax, ebx = return values for sysfunc 70
2043
;----------------------------------------------------------------
1886
;----------------------------------------------------------------
2044
fat_Write:
1887
fat_Write:
2045
        cmp     byte [esi], 0
1888
        cmp     byte [esi], 0
2046
        jz      .access_denied
1889
        jz      .access_denied
2047
        call    fat_lock
1890
        call    fat_lock
2048
        push    edi
1891
        push    edi
2049
        stdcall hd_find_lfn, [esp+4+4]
1892
        stdcall hd_find_lfn, [esp+4+4]
2050
        jnc     .found
1893
        jnc     .found
2051
        pop     edi
1894
        pop     edi
2052
        push    eax
1895
        push    eax
2053
        call    fat_unlock
1896
        call    fat_unlock
2054
        jmp     fs_HdWrite.ret0
1897
        jmp     .ret0
2055
.found:
1898
.found:
2056
; FAT does not support files larger than 4GB
1899
; FAT does not support files larger than 4GB
2057
        cmp     dword [ebx+8], 0
1900
        cmp     dword [ebx+8], 0
2058
        jz      @f
1901
        jz      @f
2059
.eof:
1902
.eof:
2060
        pop     edi
1903
        pop     edi
2061
        push    ERROR_END_OF_FILE
1904
        push    ERROR_END_OF_FILE
2062
        call    fat_unlock
1905
        call    fat_unlock
2063
        jmp     fs_HdWrite.ret0
1906
        jmp     .ret0
2064
@@:
1907
@@:
2065
        mov     ecx, [ebx+12]
1908
        mov     ecx, [ebx+12]
2066
        mov     edx, [ebx+16]
1909
        mov     edx, [ebx+16]
2067
        mov     ebx, [ebx+4]
1910
        mov     ebx, [ebx+4]
2068
; now edi points to direntry, ebx=start byte to write,
1911
; now edi points to direntry, ebx=start byte to write,
2069
; ecx=number of bytes to write, edx=data pointer
1912
; ecx=number of bytes to write, edx=data pointer
2070
 
1913
 
2071
; extend file if needed
1914
; extend file if needed
2072
        add     ecx, ebx
1915
        add     ecx, ebx
2073
        jc      .eof    ; FAT does not support files larger than 4GB
1916
        jc      .eof    ; FAT does not support files larger than 4GB
2074
        push    edx
1917
        push    edx
2075
        push    eax     ; save directory sector
1918
        push    eax     ; save directory sector
2076
        push    0       ; return value=0
1919
        push    0       ; return value=0
2077
 
1920
 
2078
        call    get_time_for_file
1921
        call    get_time_for_file
2079
        mov     [edi+22], ax            ; last write time
1922
        mov     [edi+22], ax            ; last write time
2080
        call    get_date_for_file
1923
        call    get_date_for_file
2081
        mov     [edi+24], ax            ; last write date
1924
        mov     [edi+24], ax            ; last write date
2082
        mov     [edi+18], ax            ; last access date
1925
        mov     [edi+18], ax            ; last access date
2083
 
1926
 
2084
        push    dword [edi+28]          ; save current file size
1927
        push    dword [edi+28]          ; save current file size
2085
        cmp     ecx, [edi+28]
1928
        cmp     ecx, [edi+28]
2086
        jbe     .length_ok
1929
        jbe     .length_ok
2087
        cmp     ecx, ebx
1930
        cmp     ecx, ebx
2088
        jz      .length_ok
1931
        jz      .length_ok
2089
        call    hd_extend_file
1932
        call    hd_extend_file
2090
        jnc     .length_ok
1933
        jnc     .length_ok
2091
        mov     [esp+4], eax
1934
        mov     [esp+4], eax
2092
; hd_extend_file can return three error codes: FAT table error, device error or disk full.
1935
; hd_extend_file can return three error codes: FAT table error, device error or disk full.
2093
; First two cases are fatal errors, in third case we may write some data
1936
; First two cases are fatal errors, in third case we may write some data
2094
        cmp     al, ERROR_DISK_FULL
1937
        cmp     al, ERROR_DISK_FULL
2095
        jz      .disk_full
1938
        jz      .disk_full
2096
        call    fat_unlock
1939
        call    fat_unlock
2097
        pop     eax
1940
        pop     eax
2098
        pop     eax
1941
        pop     eax
2099
        pop     ecx
1942
        pop     ecx
2100
        pop     edx
1943
        pop     edx
2101
        pop     edi
1944
        pop     edi
2102
        xor     ebx, ebx
1945
        xor     ebx, ebx
2103
        ret
1946
        ret
2104
.disk_full:
1947
.disk_full:
2105
; correct number of bytes to write
1948
; correct number of bytes to write
2106
        mov     ecx, [edi+28]
1949
        mov     ecx, [edi+28]
2107
        cmp     ecx, ebx
1950
        cmp     ecx, ebx
2108
        ja      .length_ok
1951
        ja      .length_ok
2109
        push    0
1952
        push    0
2110
.ret:
1953
.ret:
2111
        pop     eax
1954
        pop     eax
2112
        sub     edx, [esp+12]
1955
        sub     edx, [esp+12]
2113
        mov     ebx, edx        ; ebx=number of written bytes
1956
        mov     ebx, edx        ; ebx=number of written bytes
2114
        call    update_disk
1957
        call    update_disk
2115
        test    eax, eax
1958
        test    eax, eax
2116
        jz      @f
1959
        jz      @f
2117
        mov     byte [esp+4], ERROR_DEVICE
1960
        mov     byte [esp+4], ERROR_DEVICE
2118
@@:
1961
@@:
2119
        call    fat_unlock
1962
        call    fat_unlock
2120
        pop     eax
1963
        pop     eax
2121
        pop     eax
1964
        pop     eax
2122
        pop     ecx
1965
        pop     ecx
2123
        pop     edx
1966
        pop     edx
2124
        pop     edi
1967
        pop     edi
2125
        ret
1968
        ret
2126
.length_ok:
1969
.length_ok:
2127
        mov     esi, [edi+28]
1970
        mov     esi, [edi+28]
2128
        mov     eax, [edi+20-2]
1971
        mov     eax, [edi+20-2]
2129
        mov     ax, [edi+26]
1972
        mov     ax, [edi+26]
2130
        mov     edi, eax        ; edi=current cluster
1973
        mov     edi, eax        ; edi=current cluster
2131
        push    0               ; current sector in cluster
1974
        push    0               ; current sector in cluster
2132
; save directory
1975
; save directory
2133
        mov     eax, [esp+12]
1976
        mov     eax, [esp+12]
2134
        push    ebx
1977
        push    ebx
2135
        lea     ebx, [ebp+FAT.buffer]
1978
        lea     ebx, [ebp+FAT.buffer]
2136
        call    fs_write32_sys
1979
        call    fs_write32_sys
2137
        pop     ebx
1980
        pop     ebx
2138
        test    eax, eax
1981
        test    eax, eax
2139
        jz      @f
1982
        jz      @f
2140
.device_err:
1983
.device_err:
2141
        mov     byte [esp+8], ERROR_DEVICE
1984
        mov     byte [esp+8], ERROR_DEVICE
2142
        jmp     .ret
1985
        jmp     .ret
2143
.fat_err:
1986
.fat_err:
2144
        mov     byte [esp+8], ERROR_FAT_TABLE
1987
        mov     byte [esp+8], ERROR_FAT_TABLE
2145
        jmp     .ret
1988
        jmp     .ret
2146
@@:
1989
@@:
2147
 
1990
 
2148
; now ebx=start pos, ecx=end pos, both lie inside file
1991
; now ebx=start pos, ecx=end pos, both lie inside file
2149
        sub     ecx, ebx
1992
        sub     ecx, ebx
2150
        jz      .ret
1993
        jz      .ret
2151
.write_loop:
1994
.write_loop:
2152
; skip unmodified sectors
1995
; skip unmodified sectors
2153
        cmp     dword [esp+4], 0x200
1996
        cmp     dword [esp+4], 0x200
2154
        jb      .modify
1997
        jb      .modify
2155
        sub     ebx, 0x200
1998
        sub     ebx, 0x200
2156
        jae     .skip
1999
        jae     .skip
2157
        add     ebx, 0x200
2000
        add     ebx, 0x200
2158
.modify:
2001
.modify:
2159
; get length of data in current sector
2002
; get length of data in current sector
2160
        push    ecx
2003
        push    ecx
2161
        sub     ebx, 0x200
2004
        sub     ebx, 0x200
2162
        jb      .hasdata
2005
        jb      .hasdata
2163
        neg     ebx
2006
        neg     ebx
2164
        xor     ecx, ecx
2007
        xor     ecx, ecx
2165
        jmp     @f
2008
        jmp     @f
2166
.hasdata:
2009
.hasdata:
2167
        neg     ebx
2010
        neg     ebx
2168
        cmp     ecx, ebx
2011
        cmp     ecx, ebx
2169
        jbe     @f
2012
        jbe     @f
2170
        mov     ecx, ebx
2013
        mov     ecx, ebx
2171
@@:
2014
@@:
2172
; get current sector number
2015
; get current sector number
2173
        mov     eax, edi
2016
        mov     eax, edi
2174
        dec     eax
2017
        dec     eax
2175
        dec     eax
2018
        dec     eax
2176
        imul    eax, [ebp+FAT.SECTORS_PER_CLUSTER]
2019
        imul    eax, [ebp+FAT.SECTORS_PER_CLUSTER]
2177
        add     eax, [ebp+FAT.DATA_START]
2020
        add     eax, [ebp+FAT.DATA_START]
2178
        add     eax, [esp+4]
2021
        add     eax, [esp+4]
2179
; load sector if needed
2022
; load sector if needed
2180
        cmp     dword [esp+8], 0        ; we don't need to read uninitialized data
2023
        cmp     dword [esp+8], 0        ; we don't need to read uninitialized data
2181
        jz      .noread
2024
        jz      .noread
2182
        cmp     ecx, 0x200      ; we don't need to read sector if it is fully rewritten
2025
        cmp     ecx, 0x200      ; we don't need to read sector if it is fully rewritten
2183
        jz      .noread
2026
        jz      .noread
2184
        cmp     ecx, esi        ; (same for the last sector)
2027
        cmp     ecx, esi        ; (same for the last sector)
2185
        jz      .noread
2028
        jz      .noread
2186
        push    eax ebx
2029
        push    eax ebx
2187
        lea     ebx, [ebp+FAT.buffer]
2030
        lea     ebx, [ebp+FAT.buffer]
2188
        call    fs_read32_app
2031
        call    fs_read32_app
2189
        test    eax, eax
2032
        test    eax, eax
2190
        pop     ebx eax
2033
        pop     ebx eax
2191
        jz      @f
2034
        jz      @f
2192
.device_err2:
2035
.device_err2:
2193
        pop     ecx
2036
        pop     ecx
2194
        jmp     .device_err
2037
        jmp     .device_err
2195
@@:
2038
@@:
2196
.noread:
2039
.noread:
2197
; zero uninitialized data if file was extended (because hd_extend_file does not this)
2040
; zero uninitialized data if file was extended (because hd_extend_file does not this)
2198
        push    eax ecx edi
2041
        push    eax ecx edi
2199
        xor     eax, eax
2042
        xor     eax, eax
2200
        mov     ecx, 0x200
2043
        mov     ecx, 0x200
2201
        sub     ecx, [esp+8+12]
2044
        sub     ecx, [esp+8+12]
2202
        jbe     @f
2045
        jbe     @f
2203
        lea     edi, [ebp+FAT.buffer]
2046
        lea     edi, [ebp+FAT.buffer]
2204
        add     edi, [esp+8+12]
2047
        add     edi, [esp+8+12]
2205
        rep stosb
2048
        rep stosb
2206
@@:
2049
@@:
2207
; zero uninitialized data in the last sector
2050
; zero uninitialized data in the last sector
2208
        mov     ecx, 0x200
2051
        mov     ecx, 0x200
2209
        sub     ecx, esi
2052
        sub     ecx, esi
2210
        jbe     @f
2053
        jbe     @f
2211
        lea     edi, [ebp+FAT.buffer+esi]
2054
        lea     edi, [ebp+FAT.buffer+esi]
2212
        rep stosb
2055
        rep stosb
2213
@@:
2056
@@:
2214
        pop     edi ecx
2057
        pop     edi ecx
2215
; copy new data
2058
; copy new data
2216
        mov     eax, edx
2059
        mov     eax, edx
2217
        neg     ebx
2060
        neg     ebx
2218
        jecxz   @f
2061
        jecxz   @f
2219
        lea     ebx, [ebp+FAT.buffer+0x200+ebx]
2062
        lea     ebx, [ebp+FAT.buffer+0x200+ebx]
2220
        call    memmove
2063
        call    memmove
2221
        xor     ebx, ebx
2064
        xor     ebx, ebx
2222
@@:
2065
@@:
2223
        pop     eax
2066
        pop     eax
2224
; save sector
2067
; save sector
2225
        push    ebx
2068
        push    ebx
2226
        lea     ebx, [ebp+FAT.buffer]
2069
        lea     ebx, [ebp+FAT.buffer]
2227
        call    fs_write32_app
2070
        call    fs_write32_app
2228
        pop     ebx
2071
        pop     ebx
2229
        test    eax, eax
2072
        test    eax, eax
2230
        jnz     .device_err2
2073
        jnz     .device_err2
2231
        add     edx, ecx
2074
        add     edx, ecx
2232
        sub     [esp], ecx
2075
        sub     [esp], ecx
2233
        pop     ecx
2076
        pop     ecx
2234
        jz      .ret
2077
        jz      .ret
2235
.skip:
2078
.skip:
2236
; next sector
2079
; next sector
2237
        pop     eax
2080
        pop     eax
2238
        inc     eax
2081
        inc     eax
2239
        push    eax
2082
        push    eax
2240
        cmp     eax, [ebp+FAT.SECTORS_PER_CLUSTER]
2083
        cmp     eax, [ebp+FAT.SECTORS_PER_CLUSTER]
2241
        jb      @f
2084
        jb      @f
2242
        and     dword [esp], 0
2085
        and     dword [esp], 0
2243
        mov     eax, edi
2086
        mov     eax, edi
2244
        call    get_FAT
2087
        call    get_FAT
2245
        mov     edi, eax
2088
        mov     edi, eax
2246
        jc      .device_err
2089
        jc      .device_err
2247
        cmp     edi, 2
2090
        cmp     edi, 2
2248
        jb      .fat_err
2091
        jb      .fat_err
2249
        cmp     edi, [ebp+FAT.fatRESERVED]
2092
        cmp     edi, [ebp+FAT.fatRESERVED]
2250
        jae     .fat_err
2093
        jae     .fat_err
2251
@@:
2094
@@:
2252
        sub     esi, 0x200
2095
        sub     esi, 0x200
2253
        jae     @f
2096
        jae     @f
2254
        xor     esi, esi
2097
        xor     esi, esi
2255
@@:
2098
@@:
2256
        sub     dword [esp+4], 0x200
2099
        sub     dword [esp+4], 0x200
2257
        jae     @f
2100
        jae     @f
2258
        and     dword [esp+4], 0
2101
        and     dword [esp+4], 0
2259
@@:
2102
@@:
2260
        jmp     .write_loop
2103
        jmp     .write_loop
2261
 
2104
 
2262
hd_extend_file.zero_size:
2105
hd_extend_file.zero_size:
2263
        xor     eax, eax
2106
        xor     eax, eax
2264
        jmp     hd_extend_file.start_extend
2107
        jmp     hd_extend_file.start_extend
2265
 
2108
 
2266
; extends file on hd to given size (new data area is undefined)
2109
; extends file on hd to given size (new data area is undefined)
2267
; in: edi->direntry, ecx=new size
2110
; in: edi->direntry, ecx=new size
2268
; out: CF=0 => OK, eax=0
2111
; out: CF=0 => OK, eax=0
2269
;      CF=1 => error, eax=code (ERROR_FAT_TABLE or ERROR_DISK_FULL or ERROR_DEVICE)
2112
;      CF=1 => error, eax=code (ERROR_FAT_TABLE or ERROR_DISK_FULL or ERROR_DEVICE)
2270
hd_extend_file:
2113
hd_extend_file:
2271
        push    esi
2114
        push    esi
2272
        mov     esi, [ebp+FAT.SECTORS_PER_CLUSTER]
2115
        mov     esi, [ebp+FAT.SECTORS_PER_CLUSTER]
2273
        imul    esi, [ebp+FAT.BYTES_PER_SECTOR]
2116
        imul    esi, [ebp+FAT.BYTES_PER_SECTOR]
2274
        push    ecx
2117
        push    ecx
2275
; find the last cluster of file
2118
; find the last cluster of file
2276
        mov     eax, [edi+20-2]
2119
        mov     eax, [edi+20-2]
2277
        mov     ax, [edi+26]
2120
        mov     ax, [edi+26]
2278
        mov     ecx, [edi+28]
2121
        mov     ecx, [edi+28]
2279
        jecxz   .zero_size
2122
        jecxz   .zero_size
2280
.last_loop:
2123
.last_loop:
2281
        sub     ecx, esi
2124
        sub     ecx, esi
2282
        jbe     .last_found
2125
        jbe     .last_found
2283
        call    get_FAT
2126
        call    get_FAT
2284
        jnc     @f
2127
        jnc     @f
2285
.device_err:
2128
.device_err:
2286
        pop     ecx
2129
        pop     ecx
2287
.device_err2:
2130
.device_err2:
2288
        pop     esi
2131
        pop     esi
2289
        push    ERROR_DEVICE
2132
        push    ERROR_DEVICE
2290
.ret_err:
2133
.ret_err:
2291
        pop     eax
2134
        pop     eax
2292
        stc
2135
        stc
2293
        ret
2136
        ret
2294
@@:
2137
@@:
2295
        cmp     eax, 2
2138
        cmp     eax, 2
2296
        jb      .fat_err
2139
        jb      .fat_err
2297
        cmp     eax, [ebp+FAT.fatRESERVED]
2140
        cmp     eax, [ebp+FAT.fatRESERVED]
2298
        jb      .last_loop
2141
        jb      .last_loop
2299
.fat_err:
2142
.fat_err:
2300
        pop     ecx esi
2143
        pop     ecx esi
2301
        push    ERROR_FAT_TABLE
2144
        push    ERROR_FAT_TABLE
2302
        jmp     .ret_err
2145
        jmp     .ret_err
2303
.last_found:
2146
.last_found:
2304
        push    eax
2147
        push    eax
2305
        call    get_FAT
2148
        call    get_FAT
2306
        jnc     @f
2149
        jnc     @f
2307
        pop     eax
2150
        pop     eax
2308
        jmp     .device_err
2151
        jmp     .device_err
2309
@@:
2152
@@:
2310
        cmp     eax, [ebp+FAT.fatRESERVED]
2153
        cmp     eax, [ebp+FAT.fatRESERVED]
2311
        pop     eax
2154
        pop     eax
2312
        jb      .fat_err
2155
        jb      .fat_err
2313
; set length to full number of clusters
2156
; set length to full number of clusters
2314
        sub     [edi+28], ecx
2157
        sub     [edi+28], ecx
2315
.start_extend:
2158
.start_extend:
2316
        pop     ecx
2159
        pop     ecx
2317
; now do extend
2160
; now do extend
2318
        push    edx
2161
        push    edx
2319
        mov     edx, 2          ; start scan from cluster 2
2162
        mov     edx, 2          ; start scan from cluster 2
2320
.extend_loop:
2163
.extend_loop:
2321
        cmp     [edi+28], ecx
2164
        cmp     [edi+28], ecx
2322
        jae     .extend_done
2165
        jae     .extend_done
2323
; add new cluster
2166
; add new cluster
2324
        push    eax
2167
        push    eax
2325
        call    get_free_FAT
2168
        call    get_free_FAT
2326
        jc      .disk_full
2169
        jc      .disk_full
2327
        mov     edx, [ebp+FAT.fatEND]
2170
        mov     edx, [ebp+FAT.fatEND]
2328
        call    set_FAT
2171
        call    set_FAT
2329
        mov     edx, eax
2172
        mov     edx, eax
2330
        pop     eax
2173
        pop     eax
2331
        test    eax, eax
2174
        test    eax, eax
2332
        jz      .first_cluster
2175
        jz      .first_cluster
2333
        push    edx
2176
        push    edx
2334
        call    set_FAT
2177
        call    set_FAT
2335
        pop     edx
2178
        pop     edx
2336
        jmp     @f
2179
        jmp     @f
2337
.first_cluster:
2180
.first_cluster:
2338
        ror     edx, 16
2181
        ror     edx, 16
2339
        mov     [edi+20], dx
2182
        mov     [edi+20], dx
2340
        ror     edx, 16
2183
        ror     edx, 16
2341
        mov     [edi+26], dx
2184
        mov     [edi+26], dx
2342
@@:
2185
@@:
2343
        push    ecx
2186
        push    ecx
2344
        mov     ecx, -1
2187
        mov     ecx, -1
2345
        call    add_disk_free_space
2188
        call    add_disk_free_space
2346
        pop     ecx
2189
        pop     ecx
2347
        mov     eax, edx
2190
        mov     eax, edx
2348
        add     [edi+28], esi
2191
        add     [edi+28], esi
2349
        jmp     .extend_loop
2192
        jmp     .extend_loop
2350
.extend_done:
2193
.extend_done:
2351
        mov     [edi+28], ecx
2194
        mov     [edi+28], ecx
2352
        pop     edx esi
2195
        pop     edx esi
2353
        xor     eax, eax        ; CF=0
2196
        xor     eax, eax        ; CF=0
2354
        ret
2197
        ret
2355
.device_err3:
2198
.device_err3:
2356
        pop     edx
2199
        pop     edx
2357
        jmp     .device_err2
2200
        jmp     .device_err2
2358
.disk_full:
2201
.disk_full:
2359
        pop     eax edx esi
2202
        pop     eax edx esi
2360
        movi    eax, ERROR_DISK_FULL
2203
        movi    eax, ERROR_DISK_FULL
2361
        stc
2204
        stc
2362
        ret
2205
        ret
2363
 
2206
 
2364
;----------------------------------------------------------------
2207
;----------------------------------------------------------------
2365
;
-
 
2366
;  fs_HdSetFileEnd - set end of file on hard disk
-
 
2367
;
-
 
2368
;  Obsolete, will be replaced with filesystem-specific functions.
-
 
2369
;
-
 
2370
;  esi  points to filename
-
 
2371
;  ebx  points to 64-bit number = new file size
-
 
2372
;  ecx  ignored (reserved)
-
 
2373
;  edx  ignored (reserved)
-
 
2374
;
-
 
2375
;  ret eax = 0 ok or other = errormsg
-
 
2376
;
-
 
2377
;--------------------------------------------------------------
-
 
2378
fs_HdSetFileEnd:
-
 
2379
        cmp     [fs_type], 16
-
 
2380
        jz      @f
-
 
2381
        cmp     [fs_type], 32
-
 
2382
        jz      @f
-
 
2383
        cmp     [fs_type], 1
-
 
2384
        jz      ntfs_HdSetFileEnd
-
 
2385
        cmp     [fs_type], 2
-
 
2386
        jz      ext2_HdSetFileEnd
-
 
2387
        movi    eax, ERROR_UNKNOWN_FS
-
 
2388
        ret
-
 
2389
@@:
-
 
2390
        sub     ebx, 4
-
 
2391
        push    ebp
-
 
2392
        mov     ebp, [fs_dependent_data_start.partition]
-
 
2393
        call    fat_SetFileEnd
-
 
2394
        pop     ebp
-
 
2395
        ret
-
 
2396
 
-
 
2397
;----------------------------------------------------------------
-
 
2398
; fat_SetFileEnd - FAT16/32 implementation of setting end-of-file
2208
; fat_SetFileEnd - FAT16/32 implementation of setting end-of-file
2399
; in:  ebp = pointer to FAT structure
2209
; in:  ebp = pointer to FAT structure
2400
; in:  esi+[esp+4] = name
2210
; in:  esi+[esp+4] = name
2401
; in:  ebx = pointer to parameters from sysfunc 70
2211
; in:  ebx = pointer to parameters from sysfunc 70
2402
; out: eax, ebx = return values for sysfunc 70
2212
; out: eax, ebx = return values for sysfunc 70
2403
;----------------------------------------------------------------
2213
;----------------------------------------------------------------
2404
fat_SetFileEnd:
2214
fat_SetFileEnd:
2405
        call    fat_lock
2215
        call    fat_lock
2406
        push    edi
2216
        push    edi
2407
        cmp     byte [esi], 0
2217
        cmp     byte [esi], 0
2408
        jnz     @f
2218
        jnz     @f
2409
.access_denied:
2219
.access_denied:
2410
        push    ERROR_ACCESS_DENIED
2220
        push    ERROR_ACCESS_DENIED
2411
.ret:
2221
.ret:
2412
        call    fat_unlock
2222
        call    fat_unlock
2413
        pop     eax
2223
        pop     eax
2414
        pop     edi
2224
        pop     edi
2415
        ret
2225
        ret
2416
@@:
2226
@@:
2417
        stdcall hd_find_lfn, [esp+4+4]
2227
        stdcall hd_find_lfn, [esp+4+4]
2418
        jnc     @f
2228
        jnc     @f
2419
.reteax:
2229
.reteax:
2420
        push    eax
2230
        push    eax
2421
        jmp     .ret
2231
        jmp     .ret
2422
@@:
2232
@@:
2423
; must not be directory
2233
; must not be directory
2424
        test    byte [edi+11], 10h
2234
        test    byte [edi+11], 10h
2425
        jnz     .access_denied
2235
        jnz     .access_denied
2426
; file size must not exceed 4 Gb
2236
; file size must not exceed 4 Gb
2427
        cmp     dword [ebx+8], 0
2237
        cmp     dword [ebx+8], 0
2428
        jz      @f
2238
        jz      @f
2429
        push    ERROR_END_OF_FILE
2239
        push    ERROR_END_OF_FILE
2430
        jmp     .ret
2240
        jmp     .ret
2431
@@:
2241
@@:
2432
        push    eax     ; save directory sector
2242
        push    eax     ; save directory sector
2433
; set file modification date/time to current
2243
; set file modification date/time to current
2434
        call    fat_update_datetime
2244
        call    fat_update_datetime
2435
        mov     eax, [ebx+4]
2245
        mov     eax, [ebx+4]
2436
        cmp     eax, [edi+28]
2246
        cmp     eax, [edi+28]
2437
        jb      .truncate
2247
        jb      .truncate
2438
        ja      .expand
2248
        ja      .expand
2439
        pop     eax
2249
        pop     eax
2440
        lea     ebx, [ebp+FAT.buffer]
2250
        lea     ebx, [ebp+FAT.buffer]
2441
        call    fs_write32_sys
2251
        call    fs_write32_sys
2442
        test    eax, eax
2252
        test    eax, eax
2443
        jz      @f
2253
        jz      @f
2444
        push    ERROR_DEVICE
2254
        push    ERROR_DEVICE
2445
        jmp     .ret
2255
        jmp     .ret
2446
@@:
2256
@@:
2447
        push    0
2257
        push    0
2448
        jmp     .ret
2258
        jmp     .ret
2449
.expand:
2259
.expand:
2450
        push    ebx ebp ecx
2260
        push    ebx ebp ecx
2451
        push    dword [edi+28]  ; save old size
2261
        push    dword [edi+28]  ; save old size
2452
        mov     ecx, eax
2262
        mov     ecx, eax
2453
        call    hd_extend_file
2263
        call    hd_extend_file
2454
        push    eax             ; return code
2264
        push    eax             ; return code
2455
        jnc     .expand_ok
2265
        jnc     .expand_ok
2456
        cmp     al, ERROR_DISK_FULL
2266
        cmp     al, ERROR_DISK_FULL
2457
        jz      .disk_full
2267
        jz      .disk_full
2458
.pop_ret:
2268
.pop_ret:
2459
        call    update_disk
2269
        call    update_disk
2460
        pop     eax ecx ecx ebp ebx ecx
2270
        pop     eax ecx ecx ebp ebx ecx
2461
        jmp     .reteax
2271
        jmp     .reteax
2462
.expand_ok:
2272
.expand_ok:
2463
.disk_full:
2273
.disk_full:
2464
; save directory
2274
; save directory
2465
        mov     eax, [edi+28]
2275
        mov     eax, [edi+28]
2466
        xchg    eax, [esp+20]
2276
        xchg    eax, [esp+20]
2467
        lea     ebx, [ebp+FAT.buffer]
2277
        lea     ebx, [ebp+FAT.buffer]
2468
        call    fs_write32_sys
2278
        call    fs_write32_sys
2469
        test    eax, eax
2279
        test    eax, eax
2470
        mov     eax, [edi+20-2]
2280
        mov     eax, [edi+20-2]
2471
        mov     ax, [edi+26]
2281
        mov     ax, [edi+26]
2472
        mov     edi, eax
2282
        mov     edi, eax
2473
        jz      @f
2283
        jz      @f
2474
.pop_ret11:
2284
.pop_ret11:
2475
        mov     byte [esp], ERROR_DEVICE
2285
        mov     byte [esp], ERROR_DEVICE
2476
        jmp     .pop_ret
2286
        jmp     .pop_ret
2477
@@:
2287
@@:
2478
        test    edi, edi
2288
        test    edi, edi
2479
        jz      .pop_ret
2289
        jz      .pop_ret
2480
; now zero new data
2290
; now zero new data
2481
        push    0
2291
        push    0
2482
; edi=current cluster, [esp]=sector in cluster
2292
; edi=current cluster, [esp]=sector in cluster
2483
; [esp+24]=new size, [esp+8]=old size, [esp+4]=return code
2293
; [esp+24]=new size, [esp+8]=old size, [esp+4]=return code
2484
.zero_loop:
2294
.zero_loop:
2485
        cmp     edi, 2
2295
        cmp     edi, 2
2486
        jb      .error_fat
2296
        jb      .error_fat
2487
        cmp     edi, [ebp+FAT.fatRESERVED]
2297
        cmp     edi, [ebp+FAT.fatRESERVED]
2488
        jae     .error_fat
2298
        jae     .error_fat
2489
        sub     dword [esp+8], 0x200
2299
        sub     dword [esp+8], 0x200
2490
        jae     .next_cluster
2300
        jae     .next_cluster
2491
        lea     eax, [edi-2]
2301
        lea     eax, [edi-2]
2492
        imul    eax, [ebp+FAT.SECTORS_PER_CLUSTER]
2302
        imul    eax, [ebp+FAT.SECTORS_PER_CLUSTER]
2493
        add     eax, [ebp+FAT.DATA_START]
2303
        add     eax, [ebp+FAT.DATA_START]
2494
        add     eax, [esp]
2304
        add     eax, [esp]
2495
        cmp     dword [esp+8], -0x200
2305
        cmp     dword [esp+8], -0x200
2496
        jz      .noread
2306
        jz      .noread
2497
        push    eax
2307
        push    eax
2498
        lea     ebx, [ebp+FAT.buffer]
2308
        lea     ebx, [ebp+FAT.buffer]
2499
        call    fs_read32_app
2309
        call    fs_read32_app
2500
        test    eax, eax
2310
        test    eax, eax
2501
        pop     eax
2311
        pop     eax
2502
        jnz     .err_next
2312
        jnz     .err_next
2503
.noread:
2313
.noread:
2504
        mov     ecx, [esp+8]
2314
        mov     ecx, [esp+8]
2505
        neg     ecx
2315
        neg     ecx
2506
        push    edi
2316
        push    edi
2507
        lea     edi, [ebp+FAT.buffer+0x200]
2317
        lea     edi, [ebp+FAT.buffer+0x200]
2508
        add     edi, [esp+12]
2318
        add     edi, [esp+12]
2509
        push    eax
2319
        push    eax
2510
        xor     eax, eax
2320
        xor     eax, eax
2511
        mov     [esp+16], eax
2321
        mov     [esp+16], eax
2512
        rep stosb
2322
        rep stosb
2513
        pop     eax
2323
        pop     eax
2514
        pop     edi
2324
        pop     edi
2515
        call    fs_write32_app
2325
        call    fs_write32_app
2516
        test    eax, eax
2326
        test    eax, eax
2517
        jz      .next_cluster
2327
        jz      .next_cluster
2518
.err_next:
2328
.err_next:
2519
        mov     byte [esp+4], ERROR_DEVICE
2329
        mov     byte [esp+4], ERROR_DEVICE
2520
.next_cluster:
2330
.next_cluster:
2521
        pop     eax
2331
        pop     eax
2522
        sub     dword [esp+20], 0x200
2332
        sub     dword [esp+20], 0x200
2523
        jbe     .pop_ret
2333
        jbe     .pop_ret
2524
        inc     eax
2334
        inc     eax
2525
        push    eax
2335
        push    eax
2526
        cmp     eax, [ebp+FAT.SECTORS_PER_CLUSTER]
2336
        cmp     eax, [ebp+FAT.SECTORS_PER_CLUSTER]
2527
        jb      .zero_loop
2337
        jb      .zero_loop
2528
        and     dword [esp], 0
2338
        and     dword [esp], 0
2529
        mov     eax, edi
2339
        mov     eax, edi
2530
        call    get_FAT
2340
        call    get_FAT
2531
        mov     edi, eax
2341
        mov     edi, eax
2532
        jnc     .zero_loop
2342
        jnc     .zero_loop
2533
        pop     eax
2343
        pop     eax
2534
        jmp     .pop_ret11
2344
        jmp     .pop_ret11
2535
.truncate:
2345
.truncate:
2536
        mov     [edi+28], eax
2346
        mov     [edi+28], eax
2537
        push    ecx
2347
        push    ecx
2538
        mov     ecx, [edi+20-2]
2348
        mov     ecx, [edi+20-2]
2539
        mov     cx, [edi+26]
2349
        mov     cx, [edi+26]
2540
        push    eax
2350
        push    eax
2541
        test    eax, eax
2351
        test    eax, eax
2542
        jz      .zero_size
2352
        jz      .zero_size
2543
; find new last cluster
2353
; find new last cluster
2544
@@:
2354
@@:
2545
        cmp     ecx, 2
2355
        cmp     ecx, 2
2546
        jb      .error_fat2
2356
        jb      .error_fat2
2547
        cmp     ecx, [ebp+FAT.fatRESERVED]
2357
        cmp     ecx, [ebp+FAT.fatRESERVED]
2548
        jae     .error_fat2
2358
        jae     .error_fat2
2549
        mov     eax, [ebp+FAT.SECTORS_PER_CLUSTER]
2359
        mov     eax, [ebp+FAT.SECTORS_PER_CLUSTER]
2550
        shl     eax, 9
2360
        shl     eax, 9
2551
        sub     [esp], eax
2361
        sub     [esp], eax
2552
        jbe     @f
2362
        jbe     @f
2553
        mov     eax, ecx
2363
        mov     eax, ecx
2554
        call    get_FAT
2364
        call    get_FAT
2555
        mov     ecx, eax
2365
        mov     ecx, eax
2556
        jnc     @b
2366
        jnc     @b
2557
.device_err3:
2367
.device_err3:
2558
        pop     eax ecx eax edi
2368
        pop     eax ecx eax edi
2559
        call    update_disk
2369
        call    update_disk
2560
        call    fat_unlock
2370
        call    fat_unlock
2561
        movi    eax, ERROR_DEVICE
2371
        movi    eax, ERROR_DEVICE
2562
        ret
2372
        ret
2563
@@:
2373
@@:
2564
; we will zero data at the end of last sector - remember it
2374
; we will zero data at the end of last sector - remember it
2565
        push    ecx
2375
        push    ecx
2566
; terminate FAT chain
2376
; terminate FAT chain
2567
        push    edx
2377
        push    edx
2568
        mov     eax, ecx
2378
        mov     eax, ecx
2569
        mov     edx, [ebp+FAT.fatEND]
2379
        mov     edx, [ebp+FAT.fatEND]
2570
        call    set_FAT
2380
        call    set_FAT
2571
        mov     eax, edx
2381
        mov     eax, edx
2572
        pop     edx
2382
        pop     edx
2573
        jnc     @f
2383
        jnc     @f
2574
.device_err4:
2384
.device_err4:
2575
        pop     ecx
2385
        pop     ecx
2576
        jmp     .device_err3
2386
        jmp     .device_err3
2577
.zero_size:
2387
.zero_size:
2578
        and     word [edi+20], 0
2388
        and     word [edi+20], 0
2579
        and     word [edi+26], 0
2389
        and     word [edi+26], 0
2580
        push    0
2390
        push    0
2581
        mov     eax, ecx
2391
        mov     eax, ecx
2582
@@:
2392
@@:
2583
; delete FAT chain
2393
; delete FAT chain
2584
        call    clear_cluster_chain
2394
        call    clear_cluster_chain
2585
        jc      .device_err4
2395
        jc      .device_err4
2586
; save directory
2396
; save directory
2587
        mov     eax, [esp+12]
2397
        mov     eax, [esp+12]
2588
        push    ebx
2398
        push    ebx
2589
        lea     ebx, [ebp+FAT.buffer]
2399
        lea     ebx, [ebp+FAT.buffer]
2590
        call    fs_write32_sys
2400
        call    fs_write32_sys
2591
        pop     ebx
2401
        pop     ebx
2592
        test    eax, eax
2402
        test    eax, eax
2593
        jnz     .device_err4
2403
        jnz     .device_err4
2594
; zero last sector, ignore errors
2404
; zero last sector, ignore errors
2595
        pop     ecx
2405
        pop     ecx
2596
        pop     eax
2406
        pop     eax
2597
        dec     ecx
2407
        dec     ecx
2598
        imul    ecx, [ebp+FAT.SECTORS_PER_CLUSTER]
2408
        imul    ecx, [ebp+FAT.SECTORS_PER_CLUSTER]
2599
        add     ecx, [ebp+FAT.DATA_START]
2409
        add     ecx, [ebp+FAT.DATA_START]
2600
        push    eax
2410
        push    eax
2601
        sar     eax, 9
2411
        sar     eax, 9
2602
        add     ecx, eax
2412
        add     ecx, eax
2603
        pop     eax
2413
        pop     eax
2604
        and     eax, 0x1FF
2414
        and     eax, 0x1FF
2605
        jz      .truncate_done
2415
        jz      .truncate_done
2606
        push    ebx eax
2416
        push    ebx eax
2607
        mov     eax, ecx
2417
        mov     eax, ecx
2608
        lea     ebx, [ebp+FAT.buffer]
2418
        lea     ebx, [ebp+FAT.buffer]
2609
        call    fs_read32_app
2419
        call    fs_read32_app
2610
        pop     eax
2420
        pop     eax
2611
        lea     edi, [ebp+FAT.buffer+eax]
2421
        lea     edi, [ebp+FAT.buffer+eax]
2612
        push    ecx
2422
        push    ecx
2613
        mov     ecx, 0x200
2423
        mov     ecx, 0x200
2614
        sub     ecx, eax
2424
        sub     ecx, eax
2615
        xor     eax, eax
2425
        xor     eax, eax
2616
        rep stosb
2426
        rep stosb
2617
        pop     eax
2427
        pop     eax
2618
        call    fs_write32_app
2428
        call    fs_write32_app
2619
        pop     ebx
2429
        pop     ebx
2620
.truncate_done:
2430
.truncate_done:
2621
        pop     ecx eax edi
2431
        pop     ecx eax edi
2622
        call    update_disk
2432
        call    update_disk
2623
        call    fat_unlock
2433
        call    fat_unlock
2624
        xor     eax, eax
2434
        xor     eax, eax
2625
        ret
2435
        ret
2626
.error_fat:
2436
.error_fat:
2627
        pop     eax
2437
        pop     eax
2628
        mov     byte [esp], ERROR_FAT_TABLE
2438
        mov     byte [esp], ERROR_FAT_TABLE
2629
        jmp     .pop_ret
2439
        jmp     .pop_ret
2630
.error_fat2:
2440
.error_fat2:
2631
        pop     eax ecx eax edi
2441
        pop     eax ecx eax edi
2632
        call    update_disk
2442
        call    update_disk
2633
        call    fat_unlock
2443
        call    fat_unlock
2634
        movi    eax, ERROR_FAT_TABLE
2444
        movi    eax, ERROR_FAT_TABLE
2635
        ret
2445
        ret
2636
 
-
 
2637
fs_HdGetFileInfo:
-
 
2638
        cmp     [fs_type], 16
-
 
2639
        jz      @f
-
 
2640
        cmp     [fs_type], 32
-
 
2641
        jz      @f
-
 
2642
        cmp     [fs_type], 1
-
 
2643
        jz      ntfs_HdGetFileInfo
-
 
2644
        cmp     [fs_type], 2
-
 
2645
        jz      ext2_HdGetFileInfo
-
 
2646
        mov     eax, ERROR_UNKNOWN_FS
-
 
2647
        ret
-
 
2648
@@:
-
 
2649
        sub     ebx, 4
-
 
2650
        push    ebp
-
 
2651
        mov     ebp, [fs_dependent_data_start.partition]
-
 
2652
        call    fat_GetFileInfo
-
 
2653
        pop     ebp
-
 
2654
        ret
-
 
2655
 
2446
 
2656
;----------------------------------------------------------------
2447
;----------------------------------------------------------------
2657
; fat_GetFileInfo - FAT16/32 implementation of getting file info
2448
; fat_GetFileInfo - FAT16/32 implementation of getting file info
2658
; in:  ebp = pointer to FAT structure
2449
; in:  ebp = pointer to FAT structure
2659
; in:  esi+[esp+4] = name
2450
; in:  esi+[esp+4] = name
2660
; in:  ebx = pointer to parameters from sysfunc 70
2451
; in:  ebx = pointer to parameters from sysfunc 70
2661
; out: eax, ebx = return values for sysfunc 70
2452
; out: eax, ebx = return values for sysfunc 70
2662
;----------------------------------------------------------------
2453
;----------------------------------------------------------------
2663
fat_GetFileInfo:
2454
fat_GetFileInfo:
2664
        cmp     byte [esi], 0
2455
        cmp     byte [esi], 0
2665
        jnz     @f
2456
        jnz     @f
2666
        mov     eax, 2
2457
        mov     eax, 2
2667
        ret
2458
        ret
2668
@@:
2459
@@:
2669
        push    edi
2460
        push    edi
2670
        call    fat_lock
2461
        call    fat_lock
2671
        stdcall hd_find_lfn, [esp+4+4]
2462
        stdcall hd_find_lfn, [esp+4+4]
2672
        jc      .error
2463
        jc      .error
2673
        push    ebp
2464
        push    ebp
2674
        xor     ebp, ebp
2465
        xor     ebp, ebp
2675
        mov     esi, [ebx+16]
2466
        mov     esi, [ebx+16]
2676
        mov     dword [esi+4], ebp
2467
        mov     dword [esi+4], ebp
2677
        call    fat_entry_to_bdfe2
2468
        call    fat_entry_to_bdfe2
2678
        pop     ebp
2469
        pop     ebp
2679
        call    fat_unlock
2470
        call    fat_unlock
2680
        xor     eax, eax
2471
        xor     eax, eax
2681
        pop     edi
2472
        pop     edi
2682
        ret
2473
        ret
2683
.error:
2474
.error:
2684
        push    eax
2475
        push    eax
2685
        call    fat_unlock
2476
        call    fat_unlock
2686
        pop     eax
2477
        pop     eax
2687
        pop     edi
2478
        pop     edi
2688
        ret
2479
        ret
2689
 
-
 
2690
fs_HdSetFileInfo:
-
 
2691
        cmp     [fs_type], 16
-
 
2692
        jz      @f
-
 
2693
        cmp     [fs_type], 32
-
 
2694
        jz      @f
-
 
2695
        cmp     [fs_type], 1
-
 
2696
        jz      ntfs_HdSetFileInfo
-
 
2697
        cmp     [fs_type], 2
-
 
2698
        jz      ext2_HdSetFileInfo
-
 
2699
        mov     eax, ERROR_UNKNOWN_FS
-
 
2700
        ret
-
 
2701
@@:
-
 
2702
        sub     ebx, 4
-
 
2703
        push    ebp
-
 
2704
        mov     ebp, [fs_dependent_data_start.partition]
-
 
2705
        call    fat_SetFileInfo
-
 
2706
        pop     ebp
-
 
2707
        ret
-
 
2708
 
2480
 
2709
;----------------------------------------------------------------
2481
;----------------------------------------------------------------
2710
; fat_SetFileInfo - FAT16/32 implementation of setting file info
2482
; fat_SetFileInfo - FAT16/32 implementation of setting file info
2711
; in:  ebp = pointer to FAT structure
2483
; in:  ebp = pointer to FAT structure
2712
; in:  esi+[esp+4] = name
2484
; in:  esi+[esp+4] = name
2713
; in:  ebx = pointer to parameters from sysfunc 70
2485
; in:  ebx = pointer to parameters from sysfunc 70
2714
; out: eax, ebx = return values for sysfunc 70
2486
; out: eax, ebx = return values for sysfunc 70
2715
;----------------------------------------------------------------
2487
;----------------------------------------------------------------
2716
fat_SetFileInfo:
2488
fat_SetFileInfo:
2717
        cmp     byte [esi], 0
2489
        cmp     byte [esi], 0
2718
        jnz     @f
2490
        jnz     @f
2719
        mov     eax, 2
2491
        mov     eax, 2
2720
        ret
2492
        ret
2721
@@:
2493
@@:
2722
        push    edi
2494
        push    edi
2723
        call    fat_lock
2495
        call    fat_lock
2724
        stdcall hd_find_lfn, [esp+4+4]
2496
        stdcall hd_find_lfn, [esp+4+4]
2725
        jc      .error
2497
        jc      .error
2726
        push    eax
2498
        push    eax
2727
        mov     edx, [ebx+16]
2499
        mov     edx, [ebx+16]
2728
        call    bdfe_to_fat_entry
2500
        call    bdfe_to_fat_entry
2729
        pop     eax
2501
        pop     eax
2730
        lea     ebx, [ebp+FAT.buffer]
2502
        lea     ebx, [ebp+FAT.buffer]
2731
        call    fs_write32_sys
2503
        call    fs_write32_sys
2732
        call    update_disk
2504
        call    update_disk
2733
        call    fat_unlock
2505
        call    fat_unlock
2734
        pop     edi
2506
        pop     edi
2735
        xor     eax, eax
2507
        xor     eax, eax
2736
        ret
2508
        ret
2737
.error:
2509
.error:
2738
        push    eax
2510
        push    eax
2739
        call    fat_unlock
2511
        call    fat_unlock
2740
        pop     eax
2512
        pop     eax
2741
        pop     edi
2513
        pop     edi
2742
        ret
2514
        ret
2743
 
-
 
2744
;----------------------------------------------------------------
-
 
2745
;
-
 
2746
;  fs_HdDelete - delete file or empty folder from hard disk
-
 
2747
;
-
 
2748
;  Obsolete, will be replaced with filesystem-specific functions.
-
 
2749
;
-
 
2750
;  esi  points to filename
-
 
2751
;
-
 
2752
;  ret  eax = 0 ok or other = errormsg
-
 
2753
;
-
 
2754
;--------------------------------------------------------------
-
 
2755
fs_HdDelete:
-
 
2756
        cmp     [fs_type], 16
-
 
2757
        jz      @f
-
 
2758
        cmp     [fs_type], 32
-
 
2759
        jz      @f
-
 
2760
        cmp     [fs_type], 1
-
 
2761
        jz      ntfs_HdDelete
-
 
2762
        cmp     [fs_type], 2
-
 
2763
        jz      ext2_HdDelete
-
 
2764
        movi    eax, ERROR_UNKNOWN_FS
-
 
2765
        ret
-
 
2766
@@:
-
 
2767
        sub     ebx, 4
-
 
2768
        push    ebp
-
 
2769
        mov     ebp, [fs_dependent_data_start.partition]
-
 
2770
        call    fat_Delete
-
 
2771
        pop     ebp
-
 
2772
        ret
-
 
2773
 
2515
 
2774
;----------------------------------------------------------------
2516
;----------------------------------------------------------------
2775
; fat_Delete - FAT16/32 implementation of deleting a file/folder
2517
; fat_Delete - FAT16/32 implementation of deleting a file/folder
2776
; in:  ebp = pointer to FAT structure
2518
; in:  ebp = pointer to FAT structure
2777
; in:  esi+[esp+4] = name
2519
; in:  esi+[esp+4] = name
2778
; in:  ebx = pointer to parameters from sysfunc 70
2520
; in:  ebx = pointer to parameters from sysfunc 70
2779
; out: eax, ebx = return values for sysfunc 70
2521
; out: eax, ebx = return values for sysfunc 70
2780
;----------------------------------------------------------------
2522
;----------------------------------------------------------------
2781
fat_Delete:
2523
fat_Delete:
2782
        call    fat_lock
2524
        call    fat_lock
2783
        cmp     byte [esi], 0
2525
        cmp     byte [esi], 0
2784
        jnz     @f
2526
        jnz     @f
2785
; cannot delete root!
2527
; cannot delete root!
2786
.access_denied:
2528
.access_denied:
2787
        push    ERROR_ACCESS_DENIED
2529
        push    ERROR_ACCESS_DENIED
2788
.pop_ret:
2530
.pop_ret:
2789
        call    fat_unlock
2531
        call    fat_unlock
2790
        pop     eax
2532
        pop     eax
2791
        xor     ebx, ebx
2533
        xor     ebx, ebx
2792
        ret
2534
        ret
2793
@@:
2535
@@:
2794
        and     [ebp+FAT.longname_sec1], 0
2536
        and     [ebp+FAT.longname_sec1], 0
2795
        and     [ebp+FAT.longname_sec2], 0
2537
        and     [ebp+FAT.longname_sec2], 0
2796
        push    edi
2538
        push    edi
2797
        stdcall hd_find_lfn, [esp+4+4]
2539
        stdcall hd_find_lfn, [esp+4+4]
2798
        jnc     .found
2540
        jnc     .found
2799
        pop     edi
2541
        pop     edi
2800
        push    ERROR_FILE_NOT_FOUND
2542
        push    ERROR_FILE_NOT_FOUND
2801
        jmp     .pop_ret
2543
        jmp     .pop_ret
2802
.found:
2544
.found:
2803
        cmp     dword [edi], '.   '
2545
        cmp     dword [edi], '.   '
2804
        jz      .access_denied2
2546
        jz      .access_denied2
2805
        cmp     dword [edi], '..  '
2547
        cmp     dword [edi], '..  '
2806
        jz      .access_denied2
2548
        jz      .access_denied2
2807
        test    byte [edi+11], 10h
2549
        test    byte [edi+11], 10h
2808
        jz      .dodel
2550
        jz      .dodel
2809
; we can delete only empty folders!
2551
; we can delete only empty folders!
2810
        pushad
2552
        pushad
2811
        mov     esi, [edi+20-2]
2553
        mov     esi, [edi+20-2]
2812
        mov     si, [edi+26]
2554
        mov     si, [edi+26]
2813
        xor     ecx, ecx
2555
        xor     ecx, ecx
2814
        lea     eax, [esi-2]
2556
        lea     eax, [esi-2]
2815
        imul    eax, [ebp+FAT.SECTORS_PER_CLUSTER]
2557
        imul    eax, [ebp+FAT.SECTORS_PER_CLUSTER]
2816
        add     eax, [ebp+FAT.DATA_START]
2558
        add     eax, [ebp+FAT.DATA_START]
2817
        lea     ebx, [ebp+FAT.buffer]
2559
        lea     ebx, [ebp+FAT.buffer]
2818
        call    fs_read32_sys
2560
        call    fs_read32_sys
2819
        test    eax, eax
2561
        test    eax, eax
2820
        jnz     .err1
2562
        jnz     .err1
2821
        lea     eax, [ebx+0x200]
2563
        lea     eax, [ebx+0x200]
2822
        add     ebx, 2*0x20
2564
        add     ebx, 2*0x20
2823
.checkempty:
2565
.checkempty:
2824
        cmp     byte [ebx], 0
2566
        cmp     byte [ebx], 0
2825
        jz      .empty
2567
        jz      .empty
2826
        cmp     byte [ebx], 0xE5
2568
        cmp     byte [ebx], 0xE5
2827
        jnz     .notempty
2569
        jnz     .notempty
2828
        add     ebx, 0x20
2570
        add     ebx, 0x20
2829
        cmp     ebx, eax
2571
        cmp     ebx, eax
2830
        jb      .checkempty
2572
        jb      .checkempty
2831
        inc     ecx
2573
        inc     ecx
2832
        cmp     ecx, [ebp+FAT.SECTORS_PER_CLUSTER]
2574
        cmp     ecx, [ebp+FAT.SECTORS_PER_CLUSTER]
2833
        jb      @f
2575
        jb      @f
2834
        mov     eax, esi
2576
        mov     eax, esi
2835
        call    get_FAT
2577
        call    get_FAT
2836
        jc      .err1
2578
        jc      .err1
2837
        cmp     eax, 2
2579
        cmp     eax, 2
2838
        jb      .error_fat
2580
        jb      .error_fat
2839
        cmp     eax, [ebp+FAT.fatRESERVED]
2581
        cmp     eax, [ebp+FAT.fatRESERVED]
2840
        jae     .empty
2582
        jae     .empty
2841
        mov     esi, eax
2583
        mov     esi, eax
2842
        xor     ecx, ecx
2584
        xor     ecx, ecx
2843
@@:
2585
@@:
2844
        lea     eax, [esi-2]
2586
        lea     eax, [esi-2]
2845
        imul    eax, [ebp+FAT.SECTORS_PER_CLUSTER]
2587
        imul    eax, [ebp+FAT.SECTORS_PER_CLUSTER]
2846
        add     eax, [ebp+FAT.DATA_START]
2588
        add     eax, [ebp+FAT.DATA_START]
2847
        add     eax, ecx
2589
        add     eax, ecx
2848
        lea     ebx, [ebp+FAT.buffer]
2590
        lea     ebx, [ebp+FAT.buffer]
2849
        call    fs_read32_sys
2591
        call    fs_read32_sys
2850
        test    eax, eax
2592
        test    eax, eax
2851
        lea     eax, [ebx+0x200]
2593
        lea     eax, [ebx+0x200]
2852
        jz      .checkempty
2594
        jz      .checkempty
2853
.err1:
2595
.err1:
2854
        popad
2596
        popad
2855
.err2:
2597
.err2:
2856
        pop     edi
2598
        pop     edi
2857
        call    fat_unlock
2599
        call    fat_unlock
2858
        movi    eax, ERROR_DEVICE
2600
        movi    eax, ERROR_DEVICE
2859
        ret
2601
        ret
2860
.error_fat:
2602
.error_fat:
2861
        popad
2603
        popad
2862
        pop     edi
2604
        pop     edi
2863
        call    fat_unlock
2605
        call    fat_unlock
2864
        movi    eax, ERROR_FAT_TABLE
2606
        movi    eax, ERROR_FAT_TABLE
2865
        ret
2607
        ret
2866
.notempty:
2608
.notempty:
2867
        popad
2609
        popad
2868
.access_denied2:
2610
.access_denied2:
2869
        pop     edi
2611
        pop     edi
2870
        call    fat_unlock
2612
        call    fat_unlock
2871
        movi    eax, ERROR_ACCESS_DENIED
2613
        movi    eax, ERROR_ACCESS_DENIED
2872
        ret
2614
        ret
2873
.empty:
2615
.empty:
2874
        popad
2616
        popad
2875
        push    eax ebx
2617
        push    eax ebx
2876
        lea     ebx, [ebp+FAT.buffer]
2618
        lea     ebx, [ebp+FAT.buffer]
2877
        call    fs_read32_sys
2619
        call    fs_read32_sys
2878
        test    eax, eax
2620
        test    eax, eax
2879
        pop     ebx eax
2621
        pop     ebx eax
2880
        jnz     .err2
2622
        jnz     .err2
2881
.dodel:
2623
.dodel:
2882
        push    eax
2624
        push    eax
2883
        mov     eax, [edi+20-2]
2625
        mov     eax, [edi+20-2]
2884
        mov     ax, [edi+26]
2626
        mov     ax, [edi+26]
2885
        xchg    eax, [esp]
2627
        xchg    eax, [esp]
2886
; delete folder entry
2628
; delete folder entry
2887
        mov     byte [edi], 0xE5
2629
        mov     byte [edi], 0xE5
2888
; delete LFN (if present)
2630
; delete LFN (if present)
2889
.lfndel:
2631
.lfndel:
2890
        lea     edx, [ebp+FAT.buffer]
2632
        lea     edx, [ebp+FAT.buffer]
2891
        cmp     edi, edx
2633
        cmp     edi, edx
2892
        ja      @f
2634
        ja      @f
2893
        cmp     [ebp+FAT.longname_sec2], 0
2635
        cmp     [ebp+FAT.longname_sec2], 0
2894
        jz      .lfndone
2636
        jz      .lfndone
2895
        push    [ebp+FAT.longname_sec2]
2637
        push    [ebp+FAT.longname_sec2]
2896
        push    [ebp+FAT.longname_sec1]
2638
        push    [ebp+FAT.longname_sec1]
2897
        pop     [ebp+FAT.longname_sec2]
2639
        pop     [ebp+FAT.longname_sec2]
2898
        and     [ebp+FAT.longname_sec1], 0
2640
        and     [ebp+FAT.longname_sec1], 0
2899
        push    ebx
2641
        push    ebx
2900
        mov     ebx, edx
2642
        mov     ebx, edx
2901
        call    fs_write32_sys
2643
        call    fs_write32_sys
2902
        mov     eax, [esp+4]
2644
        mov     eax, [esp+4]
2903
        call    fs_read32_sys
2645
        call    fs_read32_sys
2904
        pop     ebx
2646
        pop     ebx
2905
        pop     eax
2647
        pop     eax
2906
        lea     edi, [ebp+FAT.buffer+0x200]
2648
        lea     edi, [ebp+FAT.buffer+0x200]
2907
@@:
2649
@@:
2908
        sub     edi, 0x20
2650
        sub     edi, 0x20
2909
        cmp     byte [edi], 0xE5
2651
        cmp     byte [edi], 0xE5
2910
        jz      .lfndone
2652
        jz      .lfndone
2911
        cmp     byte [edi+11], 0xF
2653
        cmp     byte [edi+11], 0xF
2912
        jnz     .lfndone
2654
        jnz     .lfndone
2913
        mov     byte [edi], 0xE5
2655
        mov     byte [edi], 0xE5
2914
        jmp     .lfndel
2656
        jmp     .lfndel
2915
.lfndone:
2657
.lfndone:
2916
        push    ebx
2658
        push    ebx
2917
        lea     ebx, [ebp+FAT.buffer]
2659
        lea     ebx, [ebp+FAT.buffer]
2918
        call    fs_write32_sys
2660
        call    fs_write32_sys
2919
        pop     ebx
2661
        pop     ebx
2920
; delete FAT chain
2662
; delete FAT chain
2921
        pop     eax
2663
        pop     eax
2922
        call    clear_cluster_chain
2664
        call    clear_cluster_chain
2923
        call    update_disk
2665
        call    update_disk
2924
        call    fat_unlock
2666
        call    fat_unlock
2925
        pop     edi
2667
        pop     edi
2926
        xor     eax, eax
2668
        xor     eax, eax
2927
        ret
2669
        ret
2928
 
2670
 
2929
; \end{diamond}
2671
; \end{diamond}
2930
>
2672
>
2931
>
2673
>