Subversion Repositories Kolibri OS

Rev

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

Rev 5565 Rev 5594
1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                                 ;;
2
;;                                                                 ;;
3
;; Copyright (C) KolibriOS team 2004-2015. All rights reserved.    ;;
3
;; Copyright (C) KolibriOS team 2004-2015. 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                                                      ;;
-
 
7
;;                                                                 ;;
-
 
8
;;  FAT functions for KolibriOS                                    ;;
6
;;  FAT functions for KolibriOS                                    ;;
9
;;                                                                 ;;
7
;;                                                                 ;;
10
;;  Copyright 2002 Paolo Minazzi, paolo.minazzi@inwind.it          ;;
8
;;  Copyright 2002 Paolo Minazzi, paolo.minazzi@inwind.it          ;;
11
;;                                                                 ;;
9
;;                                                                 ;;
12
;;  See file COPYING for details                                   ;;
10
;;  See file COPYING for details                                   ;;
-
 
11
;;  06.2015 fs_read64 - pathoswithin                            ;;
13
;;  04.02.2007 LFN create folder - diamond                         ;;
12
;;  04.02.2007 LFN create folder - diamond                         ;;
14
;;  08.10.2006 LFN delete file/folder - diamond                    ;;
13
;;  08.10.2006 LFN delete file/folder - diamond                    ;;
15
;;  20.08.2006 LFN set file size (truncate/extend) - diamond       ;;
14
;;  20.08.2006 LFN set file size (truncate/extend) - diamond       ;;
16
;;  17.08.2006 LFN write/append to file - diamond                  ;;
15
;;  17.08.2006 LFN write/append to file - diamond                  ;;
17
;;  23.06.2006 LFN start application - diamond                     ;;
16
;;  23.06.2006 LFN start application - diamond                     ;;
18
;;  15.06.2006 LFN get/set file/folder info - diamond              ;;
17
;;  15.06.2006 LFN get/set file/folder info - diamond              ;;
19
;;  27.05.2006 LFN create/rewrite file - diamond                   ;;
18
;;  27.05.2006 LFN create/rewrite file - diamond                   ;;
20
;;  04.05.2006 LFN read folder - diamond                           ;;
19
;;  04.05.2006 LFN read folder - diamond                           ;;
21
;;  29.04.2006 Elimination of hangup after the                     ;;
20
;;  29.04.2006 Elimination of hangup after the                     ;;
22
;;             expiration hd_wait_timeout -  Mario79               ;;
21
;;             expiration hd_wait_timeout -  Mario79               ;;
23
;;  23.04.2006 LFN read file - diamond                             ;;
22
;;  23.04.2006 LFN read file - diamond                             ;;
24
;;  28.01.2006 find all Fat16/32 partition in all input point      ;;
23
;;  28.01.2006 find all Fat16/32 partition in all input point      ;;
25
;;             to MBR, see file part_set.inc - Mario79             ;;
24
;;             to MBR, see file part_set.inc - Mario79             ;;
26
;;  15.01.2005 get file size/attr/date, file_append - ATV          ;;
25
;;  15.01.2005 get file size/attr/date, file_append - ATV          ;;
27
;;  04.12.2004 skip volume label, file delete bug fixed - ATV      ;;
26
;;  04.12.2004 skip volume label, file delete bug fixed - ATV      ;;
28
;;  29.11.2004 get_free_FAT changed, append dir bug fixed - ATV    ;;
27
;;  29.11.2004 get_free_FAT changed, append dir bug fixed - ATV    ;;
29
;;  23.11.2004 don't allow overwrite dir with file - ATV           ;;
28
;;  23.11.2004 don't allow overwrite dir with file - ATV           ;;
30
;;  18.11.2004 get_disk_info and more error codes - ATV            ;;
29
;;  18.11.2004 get_disk_info and more error codes - ATV            ;;
31
;;  17.11.2004 set_FAT/get_FAT and disk cache rewritten - ATV      ;;
30
;;  17.11.2004 set_FAT/get_FAT and disk cache rewritten - ATV      ;;
32
;;  10.11.2004 removedir clear whole directory structure - ATV     ;;
31
;;  10.11.2004 removedir clear whole directory structure - ATV     ;;
33
;;  08.11.2004 rename - ATV                                        ;;
32
;;  08.11.2004 rename - ATV                                        ;;
34
;;  30.10.2004 file_read return also dirsize in bytes - ATV        ;;
33
;;  30.10.2004 file_read return also dirsize in bytes - ATV        ;;
35
;;  20.10.2004 Makedir/Removedir - ATV                             ;;
34
;;  20.10.2004 Makedir/Removedir - ATV                             ;;
36
;;  14.10.2004 Partition chain/Fat16 - ATV (thanks drh3xx)         ;;
35
;;  14.10.2004 Partition chain/Fat16 - ATV (thanks drh3xx)         ;;
37
;;  06.9.2004  Fix free space by Mario79 added - MH                ;;
36
;;  06.09.2004 Fix free space - Mario79                         ;;
38
;;  24.5.2004  Write back buffer for File_write -VT                ;;
37
;;  24.05.2004 Write back buffer for File_write - VT            ;;
39
;;  20.5.2004  File_read function to work with syscall 58 - VT     ;;
38
;;  20.05.2004 File_read function to work with syscall 58 - VT  ;;
40
;;  30.3.2004  Error parameters at function return - VT            ;;
39
;;  30.03.2004 Error parameters at function return - VT         ;;
41
;;  01.5.2002  Bugfix in device write - VT                         ;;
40
;;  29.06.2002 Improved fat32 verification - VT                 ;;
42
;;  20.5.2002  Hd status check - VT                                ;;
41
;;  20.05.2002 Hd status check - VT                             ;;
43
;;  29.6.2002  Improved fat32 verification - VT                    ;;
42
;;  01.05.2002 Bugfix in device write - VT                      ;;
44
;;                                                                 ;;
43
;;                                                                 ;;
45
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
44
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
46
 
-
 
47
$Revision: 4273 $
-
 
48
 
45
 
49
 
46
 
50
cache_max equ 1919      ; max. is 1919*512+0x610000=0x6ffe00
47
cache_max equ 1919      ; max. is 1919*512+0x610000=0x6ffe00
51
 
48
 
52
PUSHAD_EAX equ [esp+28]
49
PUSHAD_EAX equ [esp+28]
53
PUSHAD_ECX equ [esp+24]
50
PUSHAD_ECX equ [esp+24]
54
PUSHAD_EDX equ [esp+20]
51
PUSHAD_EDX equ [esp+20]
55
PUSHAD_EBX equ [esp+16]
52
PUSHAD_EBX equ [esp+16]
56
PUSHAD_EBP equ [esp+8]
53
PUSHAD_EBP equ [esp+8]
57
PUSHAD_ESI equ [esp+4]
54
PUSHAD_ESI equ [esp+4]
58
PUSHAD_EDI equ [esp+0]
55
PUSHAD_EDI equ [esp+0]
59
 
56
 
60
; Internal data for every FAT partition.
57
; Internal data for every FAT partition.
61
struct FAT PARTITION
58
struct FAT PARTITION
62
fs_type              db ?
59
fs_type              db ?
63
fat16_root           db 0       ; flag for fat16 rootdir
60
fat16_root           db 0       ; flag for fat16 rootdir
64
fat_change           db 0       ; 1=fat has changed
61
fat_change           db 0       ; 1=fat has changed
65
                     db ?       ; alignment
62
                     rb 1
66
Lock                 MUTEX ?    ; currently operations with one partition
63
Lock                 MUTEX ?    ; currently operations with one partition
67
                                ; can not be executed in parallel since the
-
 
68
                                ; legacy code is not ready; this mutex guards
64
; can not be executed in parallel since the legacy code is not ready
69
                                ; all operations
-
 
70
SECTORS_PER_FAT      dd 0x1f3a
65
SECTORS_PER_FAT      dd 0x1f3a
71
NUMBER_OF_FATS       dd 0x2
66
NUMBER_OF_FATS       dd 0x2
72
SECTORS_PER_CLUSTER  dd 0x8
67
SECTORS_PER_CLUSTER  dd 0x8
73
BYTES_PER_SECTOR     dd 0x200   ; Note: if BPS <> 512 need lots of changes
68
BYTES_PER_SECTOR     dd 0x200   ; Note: if BPS <> 512 need lots of changes
74
ROOT_CLUSTER         dd 2       ; first rootdir cluster
69
ROOT_CLUSTER         dd 2       ; first rootdir cluster
75
FAT_START            dd 0       ; start of fat table
70
FAT_START            dd 0       ; start of fat table
76
ROOT_START           dd 0       ; start of rootdir (only fat16)
71
ROOT_START           dd 0       ; start of rootdir (only fat16)
77
ROOT_SECTORS         dd 0       ; count of rootdir sectors (only fat16)
72
ROOT_SECTORS         dd 0       ; count of rootdir sectors (only fat16)
78
DATA_START           dd 0       ; start of data area (=first cluster 2)
73
DATA_START           dd 0       ; start of data area (=first cluster 2)
79
LAST_CLUSTER         dd 0       ; last availabe cluster
74
LAST_CLUSTER         dd 0       ; last availabe cluster
80
ADR_FSINFO           dd 0       ; used only by fat32
75
ADR_FSINFO           dd 0       ; used only by fat32
81
 
76
 
82
fatRESERVED          dd 0x0FFFFFF6
77
fatRESERVED          dd 0x0FFFFFF6
83
fatBAD               dd 0x0FFFFFF7
78
fatBAD               dd 0x0FFFFFF7
84
fatEND               dd 0x0FFFFFF8
79
fatEND               dd 0x0FFFFFF8
85
fatMASK              dd 0x0FFFFFFF
80
fatMASK              dd 0x0FFFFFFF
86
 
81
 
87
fatStartScan         dd 2
82
fatStartScan         dd 2
88
 
-
 
89
cluster_tmp          dd 0       ; used by analyze_directory
83
cluster_tmp          dd 0       ; used by analyze_directory
90
                                ; and analyze_directory_to_write
84
                                ; and analyze_directory_to_write
91
 
-
 
92
longname_sec1        dd 0       ; used by analyze_directory to save 2 previous
85
longname_sec1        dd 0       ; used by analyze_directory to save 2 previous
93
longname_sec2        dd 0       ; directory sectors for delete long filename
86
longname_sec2        dd 0       ; directory sectors for delete long filename
94
 
-
 
95
fat_in_cache         dd -1
87
fat_in_cache         dd -1
96
 
88
 
97
; For FAT16/FAT32, this points to 512-byte buffer for the current sector of FAT.
89
; For FAT16/FAT32, this points to 512-byte buffer for the current sector of FAT.
98
; For FAT12, the entire FAT structure is read
90
; For FAT12, the entire FAT structure is read
99
; and unpacked from 12bit per cluster to word per cluster.
91
; and unpacked from 12bit per cluster to word per cluster.
100
;
92
 
101
; Note: work with unpacked copy of FAT12 means
93
; Note: work with unpacked copy of FAT12 means
102
; additional memory and additional code for packing/unpacking.
94
; additional memory and additional code for packing/unpacking.
103
; I'm not sure that the economy justifies the cost, but anyway,
95
; I'm not sure that the economy justifies the cost, but anyway,
104
; there is how work was done before my edits, and I'm just keeping the principle.
96
; there is how work was done before my edits, and I'm just keeping the principle.
105
fat_cache_ptr        dd ?
97
fat_cache_ptr        dd ?
106
fat12_unpacked_ptr   dd ?
98
fat12_unpacked_ptr   dd ?
107
buffer               rb 512
99
buffer               rb 512
108
fsinfo_buffer        rb 512
100
fsinfo_buffer        rb 512
109
ends
101
ends
110
 
102
 
111
uglobal
103
uglobal
112
align 4
104
align 4
113
partition_count      dd 0       ; partitions found by set_FAT32_variables
105
partition_count      dd 0       ; partitions found by set_FAT32_variables
114
 
-
 
115
hd_error             dd 0       ; set by wait_for_sector_buffer
106
hd_error             dd 0
116
hd_setup             dd 0
107
hd_setup             dd 0
117
hd_wait_timeout      dd 0
108
hd_wait_timeout      dd 0
118
 
-
 
119
cache_search_start   dd 0       ; used by find_empty_slot
109
cache_search_start   dd 0       ; used by find_empty_slot
120
endg
110
endg
121
 
111
 
122
uglobal
112
uglobal
123
align 4
113
align 4
124
 Sector512:                      ; label for dev_hdcd.inc
114
Sector512:      ; label for dev_hdcd.inc
125
  buffer:
115
buffer:
126
                times 512 db 0
116
rb 512
127
endg
117
endg
128
 
118
 
129
iglobal
119
iglobal
130
align 4
120
align 4
131
fat_user_functions:
121
fat_user_functions:
132
        dd      fat_free
122
        dd      fat_free
133
        dd      (fat_user_functions_end - fat_user_functions - 4) / 4
123
        dd      (fat_user_functions_end - fat_user_functions - 4) / 4
134
        dd      fat_Read
124
        dd      fat_Read
135
        dd      fat_ReadFolder
125
        dd      fat_ReadFolder
136
        dd      fat_Rewrite
126
        dd      fat_Rewrite
137
        dd      fat_Write
127
        dd      fat_Write
138
        dd      fat_SetFileEnd
128
        dd      fat_SetFileEnd
139
        dd      fat_GetFileInfo
129
        dd      fat_GetFileInfo
140
        dd      fat_SetFileInfo
130
        dd      fat_SetFileInfo
141
        dd      0
131
        dd      0
142
        dd      fat_Delete
132
        dd      fat_Delete
143
        dd      fat_CreateFolder
133
        dd      fat_CreateFolder
144
fat_user_functions_end:
134
fat_user_functions_end:
145
endg
135
endg
146
 
136
 
147
; these labels are located before the main function to make
137
; these labels are located before the main function to make
148
; most of jumps to these be short
138
; most of jumps to these be short
149
fat_create_partition.free_return0:
139
fat_create_partition.free_return0:
150
        mov     eax, ebp
140
        mov     eax, ebp
151
        call    free
141
        call    free
152
        pop     ebp
142
        pop     ebp
153
fat_create_partition.return0:
143
fat_create_partition.return0:
154
        xor     eax, eax
144
        xor     eax, eax
155
        ret
145
        ret
156
fat_create_partition:
146
fat_create_partition:
157
; sector size must be 512
147
; sector size must be 512
158
        cmp     dword [esi+DISK.MediaInfo.SectorSize], 512
148
        cmp     dword [esi+DISK.MediaInfo.SectorSize], 512
159
        jnz     .return0
149
        jnz     .return0
160
; bootsector must have been successfully read
150
; bootsector must have been successfully read
161
        cmp     dword [esp+4], 0
151
        cmp     dword [esp+4], 0
162
        jnz     .return0
152
        jnz     .return0
163
; bootsector signature must be correct
153
; bootsector signature must be correct
164
        cmp     word [ebx+0x1fe], 0xaa55
154
        cmp     word [ebx+0x1fe], 0xaa55
165
        jnz     .return0
155
        jnz     .return0
166
; sectors per cluster must be nonzero
156
; sectors per cluster must be nonzero
167
        cmp     byte [ebx+0xd], 0
157
        cmp     byte [ebx+0xd], 0
168
        jz      .return0
158
        jz      .return0
169
; bytes per sector must be 0x200
159
; bytes per sector must be 0x200
170
        cmp     word [ebx+0xb], 0x200
160
        cmp     word [ebx+0xb], 0x200
171
        jnz     .return0
161
        jnz     .return0
172
; number of fats must be nonzero
162
; number of fats must be nonzero
173
        cmp     byte [ebx+0x10], 0
163
        cmp     byte [ebx+0x10], 0
174
        jz      .return0
164
        jz      .return0
175
; The only reason to be invalid partition now is FAT12. Since the test for
165
; The only reason to be invalid partition now is FAT12. Since the test for
176
; FAT size requires knowledge of some calculated values, which are also used
166
; FAT size requires knowledge of some calculated values, which are also used
177
; in the normal operation, let's hope for the best and allocate data now; if
167
; in the normal operation, let's hope for the best and allocate data now; if
178
; it will prove wrong, just deallocate it.
168
; it will prove wrong, just deallocate it.
179
        movi    eax, sizeof.FAT
169
        movi    eax, sizeof.FAT
180
        call    malloc
170
        call    malloc
181
        test    eax, eax
171
        test    eax, eax
182
        jz      .return0
172
        jz      .return0
183
        mov     ecx, dword [ebp+PARTITION.FirstSector]
173
        mov     ecx, dword [ebp+PARTITION.FirstSector]
184
        mov     dword [eax+FAT.FirstSector], ecx
174
        mov     dword [eax+FAT.FirstSector], ecx
185
        mov     ecx, dword [ebp+PARTITION.FirstSector+4]
175
        mov     ecx, dword [ebp+PARTITION.FirstSector+4]
186
        mov     dword [eax+FAT.FirstSector+4], ecx
176
        mov     dword [eax+FAT.FirstSector+4], ecx
187
        mov     ecx, dword [ebp+PARTITION.Length]
177
        mov     ecx, dword [ebp+PARTITION.Length]
188
        mov     dword [eax+FAT.Length], ecx
178
        mov     dword [eax+FAT.Length], ecx
189
        mov     ecx, dword [ebp+PARTITION.Length+4]
179
        mov     ecx, dword [ebp+PARTITION.Length+4]
190
        mov     dword [eax+FAT.Length+4], ecx
180
        mov     dword [eax+FAT.Length+4], ecx
191
        mov     ecx, [ebp+PARTITION.Disk]
181
        mov     ecx, [ebp+PARTITION.Disk]
192
        mov     [eax+FAT.Disk], ecx
182
        mov     [eax+FAT.Disk], ecx
193
        mov     [eax+FAT.FSUserFunctions], fat_user_functions
183
        mov     [eax+FAT.FSUserFunctions], fat_user_functions
194
        or      [eax+FAT.fat_in_cache], -1
184
        or      [eax+FAT.fat_in_cache], -1
195
        mov     [eax+FAT.fat_change], 0
185
        mov     [eax+FAT.fat_change], 0
196
        push    ebp
186
        push    ebp
197
        mov     ebp, eax
187
        mov     ebp, eax
198
 
188
 
199
        lea     ecx, [ebp+FAT.Lock]
189
        lea     ecx, [ebp+FAT.Lock]
200
        call    mutex_init
190
        call    mutex_init
201
 
191
 
202
        movzx   eax, word [ebx+0xe]     ; sectors reserved
192
        movzx   eax, word [ebx+0xe]     ; sectors reserved
203
        mov     [ebp+FAT.FAT_START], eax
193
        mov     [ebp+FAT.FAT_START], eax
204
 
194
 
205
        movzx   eax, byte [ebx+0xd]     ; sectors per cluster
195
        movzx   eax, byte [ebx+0xd]     ; sectors per cluster
206
        mov     [ebp+FAT.SECTORS_PER_CLUSTER], eax
196
        mov     [ebp+FAT.SECTORS_PER_CLUSTER], eax
207
 
197
 
208
        movzx   ecx, word [ebx+0xb]     ; bytes per sector
198
        movzx   ecx, word [ebx+0xb]     ; bytes per sector
209
        mov     [ebp+FAT.BYTES_PER_SECTOR], ecx
199
        mov     [ebp+FAT.BYTES_PER_SECTOR], ecx
210
 
200
 
211
        movzx   eax, word [ebx+0x11]    ; count of rootdir entries (=0 fat32)
201
        movzx   eax, word [ebx+0x11]    ; count of rootdir entries (=0 fat32)
212
        shl     eax, 5                  ; mul 32
202
        shl     eax, 5                  ; mul 32
213
        dec     ecx
203
        dec     ecx
214
        add     eax, ecx                ; round up if not equal count
204
        add     eax, ecx                ; round up if not equal count
215
        inc     ecx                     ; bytes per sector
205
        inc     ecx                     ; bytes per sector
216
        xor     edx, edx
206
        xor     edx, edx
217
        div     ecx
207
        div     ecx
218
        mov     [ebp+FAT.ROOT_SECTORS], eax     ; count of rootdir sectors
208
        mov     [ebp+FAT.ROOT_SECTORS], eax     ; count of rootdir sectors
219
 
209
 
220
        movzx   eax, word [ebx+0x16]    ; sectors per fat <65536
210
        movzx   eax, word [ebx+0x16]    ; sectors per fat <65536
221
        test    eax, eax
211
        test    eax, eax
222
        jnz     @f
212
        jnz     @f
223
        mov     eax, [ebx+0x24]         ; sectors per fat
213
        mov     eax, [ebx+0x24]         ; sectors per fat
224
@@:
214
@@:
225
        mov     [ebp+FAT.SECTORS_PER_FAT], eax
215
        mov     [ebp+FAT.SECTORS_PER_FAT], eax
226
 
216
 
227
        movzx   eax, byte [ebx+0x10]    ; number of fats
217
        movzx   eax, byte [ebx+0x10]    ; number of fats
228
        mov     [ebp+FAT.NUMBER_OF_FATS], eax
218
        mov     [ebp+FAT.NUMBER_OF_FATS], eax
229
        mul     [ebp+FAT.SECTORS_PER_FAT]
219
        mul     [ebp+FAT.SECTORS_PER_FAT]
230
        test    edx, edx
220
        test    edx, edx
231
        jnz     .free_return0
221
        jnz     .free_return0
232
        add     eax, [ebp+FAT.FAT_START]
222
        add     eax, [ebp+FAT.FAT_START]
233
        jc      .free_return0
223
        jc      .free_return0
234
        mov     [ebp+FAT.ROOT_START], eax       ; rootdir = fat_start + fat_size * fat_count
224
        mov     [ebp+FAT.ROOT_START], eax       ; rootdir = fat_start + fat_size * fat_count
235
        add     eax, [ebp+FAT.ROOT_SECTORS]     ; rootdir sectors should be 0 on fat32
225
        add     eax, [ebp+FAT.ROOT_SECTORS]     ; rootdir sectors should be 0 on fat32
236
        jc      .free_return0
226
        jc      .free_return0
237
        mov     [ebp+FAT.DATA_START], eax       ; data area = rootdir + rootdir_size
227
        mov     [ebp+FAT.DATA_START], eax       ; data area = rootdir + rootdir_size
238
 
228
 
239
        movzx   eax, word [ebx+0x13]    ; total sector count <65536
229
        movzx   eax, word [ebx+0x13]    ; total sector count <65536
240
        test    eax, eax
230
        test    eax, eax
241
        jnz     @f
231
        jnz     @f
242
        mov     eax, [ebx+0x20]         ; total sector count
232
        mov     eax, [ebx+0x20]         ; total sector count
243
@@:
233
@@:
244
; total sector count must not exceed partition size
234
; total sector count must not exceed partition size
245
        cmp     dword [ebp+FAT.Length+4], 0
235
        cmp     dword [ebp+FAT.Length+4], 0
246
        jnz     @f
236
        jnz     @f
247
        cmp     eax, dword [ebp+FAT.Length]
237
        cmp     eax, dword [ebp+FAT.Length]
248
        ja      .free_return0
238
        ja      .free_return0
249
@@:
239
@@:
250
        mov     dword [ebp+FAT.Length], eax
240
        mov     dword [ebp+FAT.Length], eax
251
        and     dword [ebp+FAT.Length+4], 0
241
        and     dword [ebp+FAT.Length+4], 0
252
        sub     eax, [ebp+FAT.DATA_START]       ; eax = count of data sectors
242
        sub     eax, [ebp+FAT.DATA_START]       ; eax = count of data sectors
253
        jc      .free_return0
243
        jc      .free_return0
254
        xor     edx, edx
244
        xor     edx, edx
255
        div     [ebp+FAT.SECTORS_PER_CLUSTER]
245
        div     [ebp+FAT.SECTORS_PER_CLUSTER]
256
        inc     eax
246
        inc     eax
257
        mov     [ebp+FAT.LAST_CLUSTER], eax
247
        mov     [ebp+FAT.LAST_CLUSTER], eax
258
        dec     eax                     ; cluster count
248
        dec     eax                     ; cluster count
259
        jz      .free_return0
249
        jz      .free_return0
260
        mov     [ebp+FAT.fatStartScan], 2
250
        mov     [ebp+FAT.fatStartScan], 2
261
 
251
 
262
        ; limits by Microsoft Hardware White Paper v1.03
252
        ; limits by Microsoft Hardware White Paper v1.03
263
        cmp     eax, 4085               ; 0xff5
253
        cmp     eax, 4085               ; 0xff5
264
        jb      .fat12
254
        jb      .fat12
265
        cmp     eax, 65525              ; 0xfff5
255
        cmp     eax, 65525              ; 0xfff5
266
        jb      .fat16
256
        jb      .fat16
267
.fat32:
257
.fat32:
268
        mov     eax, [ebx+0x2c]         ; rootdir cluster
258
        mov     eax, [ebx+0x2c]         ; rootdir cluster
269
        mov     [ebp+FAT.ROOT_CLUSTER], eax
259
        mov     [ebp+FAT.ROOT_CLUSTER], eax
270
        movzx   eax, word [ebx+0x30]
260
        movzx   eax, word [ebx+0x30]
271
        mov     [ebp+FAT.ADR_FSINFO], eax
261
        mov     [ebp+FAT.ADR_FSINFO], eax
272
        push    ebx
262
        push    ebx
273
        add     ebx, 512
263
        add     ebx, 512
274
        call    fs_read32_sys
264
        call    fs_read32_sys
275
        test    eax, eax
265
        test    eax, eax
276
        jnz     @f
266
        jnz     @f
277
        mov     eax, [ebx+0x1ec]
267
        mov     eax, [ebx+0x1ec]
278
        cmp     eax, -1
268
        cmp     eax, -1
279
        jz      @f
269
        jz      @f
280
        mov     [ebp+FAT.fatStartScan], eax
270
        mov     [ebp+FAT.fatStartScan], eax
281
@@:
271
@@:
282
        pop     ebx
272
        pop     ebx
283
        mov     [ebp+FAT.fatRESERVED], 0x0FFFFFF6
273
        mov     [ebp+FAT.fatRESERVED], 0x0FFFFFF6
284
        mov     [ebp+FAT.fatBAD], 0x0FFFFFF7
274
        mov     [ebp+FAT.fatBAD], 0x0FFFFFF7
285
        mov     [ebp+FAT.fatEND], 0x0FFFFFF8
275
        mov     [ebp+FAT.fatEND], 0x0FFFFFF8
286
        mov     [ebp+FAT.fatMASK], 0x0FFFFFFF
276
        mov     [ebp+FAT.fatMASK], 0x0FFFFFFF
287
        mov     al, 32
277
        mov     al, 32
288
.fat_not_12_finalize:
278
.fat_not_12_finalize:
289
        mov     [ebp+FAT.fs_type], al
279
        mov     [ebp+FAT.fs_type], al
290
; For FAT16 and FAT32, allocate 512 bytes for FAT cache.
280
; For FAT16 and FAT32, allocate 512 bytes for FAT cache.
291
        mov     eax, 512
281
        mov     eax, 512
292
        call    malloc
282
        call    malloc
293
        test    eax, eax
283
        test    eax, eax
294
        jz      .free_return0
284
        jz      .free_return0
295
        mov     [ebp+FAT.fat_cache_ptr], eax
285
        mov     [ebp+FAT.fat_cache_ptr], eax
296
        mov     eax, ebp
286
        mov     eax, ebp
297
        pop     ebp
287
        pop     ebp
298
        ret
288
        ret
299
.fat16:
289
.fat16:
300
        and     [ebp+FAT.ROOT_CLUSTER], 0
290
        and     [ebp+FAT.ROOT_CLUSTER], 0
301
        mov     [ebp+FAT.fatRESERVED], 0x0000FFF6
291
        mov     [ebp+FAT.fatRESERVED], 0x0000FFF6
302
        mov     [ebp+FAT.fatBAD], 0x0000FFF7
292
        mov     [ebp+FAT.fatBAD], 0x0000FFF7
303
        mov     [ebp+FAT.fatEND], 0x0000FFF8
293
        mov     [ebp+FAT.fatEND], 0x0000FFF8
304
        mov     [ebp+FAT.fatMASK], 0x0000FFFF
294
        mov     [ebp+FAT.fatMASK], 0x0000FFFF
305
        mov     al, 16
295
        mov     al, 16
306
        jmp     .fat_not_12_finalize
296
        jmp     .fat_not_12_finalize
307
.fat12:
297
.fat12:
308
        and     [ebp+FAT.ROOT_CLUSTER], 0
298
        and     [ebp+FAT.ROOT_CLUSTER], 0
309
        mov     [ebp+FAT.fatRESERVED], 0xFF6
299
        mov     [ebp+FAT.fatRESERVED], 0xFF6
310
        mov     [ebp+FAT.fatBAD], 0xFF7
300
        mov     [ebp+FAT.fatBAD], 0xFF7
311
        mov     [ebp+FAT.fatEND], 0xFFF
301
        mov     [ebp+FAT.fatEND], 0xFFF
312
        mov     [ebp+FAT.fatMASK], 0xFFF
302
        mov     [ebp+FAT.fatMASK], 0xFFF
313
        mov     al, 12
303
        mov     al, 12
314
        mov     [ebp+FAT.fs_type], al
304
        mov     [ebp+FAT.fs_type], al
315
; For FAT12, allocate&read data for entire table:
305
; For FAT12, allocate&read data for entire table:
316
; calculate A = ALIGN_UP(NUM_CLUSTERS, 8),
306
; calculate A = ALIGN_UP(NUM_CLUSTERS, 8),
317
; calculatefatchain/restorefatchain will process A items,
307
; calculatefatchain/restorefatchain will process A items,
318
; allocate ALIGN_UP(A*3/2, 512) bytes for FAT table plus A*2 bytes for unpacked data.
308
; allocate ALIGN_UP(A*3/2, 512) bytes for FAT table plus A*2 bytes for unpacked data.
319
        mov     eax, [ebp+FAT.LAST_CLUSTER]
309
        mov     eax, [ebp+FAT.LAST_CLUSTER]
320
        and     eax, not 7
310
        and     eax, not 7
321
        add     eax, 8
311
        add     eax, 8
322
        mov     edx, eax
312
        mov     edx, eax
323
        lea     eax, [eax*3]
313
        lea     eax, [eax*3]
324
        add     eax, 512*2-1
314
        add     eax, 512*2-1
325
        shr     eax, 10
315
        shr     eax, 10
326
        shl     eax, 9
316
        shl     eax, 9
327
        lea     eax, [eax+edx*2]
317
        lea     eax, [eax+edx*2]
328
        call    malloc
318
        call    malloc
329
        test    eax, eax
319
        test    eax, eax
330
        jz      .free_return0
320
        jz      .free_return0
331
; Read ALIGN_UP(NUM_CLUSTERS*3/2, 512) bytes.
321
; Read ALIGN_UP(NUM_CLUSTERS*3/2, 512) bytes.
332
; Note that this can be less than allocated, this is ok,
322
; Note that this can be less than allocated, this is ok,
333
; overallocation simplifies calculatefatchain/restorefatchain.
323
; overallocation simplifies calculatefatchain/restorefatchain.
334
        push    ebx
324
        push    ebx
335
        mov     [ebp+FAT.fat_cache_ptr], eax
325
        mov     [ebp+FAT.fat_cache_ptr], eax
336
        mov     edx, [ebp+FAT.LAST_CLUSTER]
326
        mov     edx, [ebp+FAT.LAST_CLUSTER]
337
        lea     edx, [(edx+1)*3 + 512*2-1]
327
        lea     edx, [(edx+1)*3 + 512*2-1]
338
        shr     edx, 10
328
        shr     edx, 10
339
        xchg    eax, ebx
329
        xchg    eax, ebx
340
        xor     eax, eax
330
        xor     eax, eax
341
.read_fat:
331
.read_fat:
342
        push    eax
332
        push    eax
343
        add     eax, [ebp+FAT.FAT_START]
333
        add     eax, [ebp+FAT.FAT_START]
344
        call    fs_read32_sys
334
        call    fs_read32_sys
345
        test    eax, eax
335
        test    eax, eax
346
        pop     eax
336
        pop     eax
347
        jz      @f
337
        jz      @f
348
        dbgstr 'Failed to read FAT table'
338
        dbgstr 'Failed to read FAT table'
349
        mov     eax, [ebp+FAT.fat_cache_ptr]
339
        mov     eax, [ebp+FAT.fat_cache_ptr]
350
        call    free
340
        call    free
351
        pop     ebx
341
        pop     ebx
352
        jmp     .free_return0
342
        jmp     .free_return0
353
@@:
343
@@:
354
        add     ebx, 512
344
        add     ebx, 512
355
        inc     eax
345
        inc     eax
356
        cmp     eax, edx
346
        cmp     eax, edx
357
        jb      .read_fat
347
        jb      .read_fat
358
        mov     [ebp+FAT.fat12_unpacked_ptr], ebx
348
        mov     [ebp+FAT.fat12_unpacked_ptr], ebx
359
        call    calculatefatchain
349
        call    calculatefatchain
360
        pop     ebx
350
        pop     ebx
361
        mov     eax, ebp
351
        mov     eax, ebp
362
        pop     ebp
352
        pop     ebp
363
        ret
353
        ret
364
 
354
 
365
fat_free:
355
fat_free:
366
        push    eax
356
        push    eax
367
        mov     eax, [eax+FAT.fat_cache_ptr]
357
        mov     eax, [eax+FAT.fat_cache_ptr]
368
        call    free
358
        call    free
369
        pop     eax
359
        pop     eax
370
        jmp     free
360
        jmp     free
371
 
361
 
372
calculatefatchain:
362
calculatefatchain:
373
 
363
 
374
        pushad
364
        pushad
375
 
365
 
376
        mov     esi, [ebp+FAT.fat_cache_ptr]
366
        mov     esi, [ebp+FAT.fat_cache_ptr]
377
        mov     edi, [ebp+FAT.fat12_unpacked_ptr]
367
        mov     edi, [ebp+FAT.fat12_unpacked_ptr]
378
 
368
 
379
        mov     edx, [ebp+FAT.LAST_CLUSTER]
369
        mov     edx, [ebp+FAT.LAST_CLUSTER]
380
        and     edx, not 7
370
        and     edx, not 7
381
        lea     edx, [edi+(edx+8)*2]
371
        lea     edx, [edi+(edx+8)*2]
382
        push    edx
372
        push    edx
383
 
373
 
384
 fcnew:
374
 fcnew:
385
        mov     eax, dword [esi]
375
        mov     eax, dword [esi]
386
        mov     ebx, dword [esi+4]
376
        mov     ebx, dword [esi+4]
387
        mov     ecx, dword [esi+8]
377
        mov     ecx, dword [esi+8]
388
        mov     edx, ecx
378
        mov     edx, ecx
389
        shr     edx, 4;8 ok
379
        shr     edx, 4;8 ok
390
        shr     dx, 4;7 ok
380
        shr     dx, 4;7 ok
391
        xor     ch, ch
381
        xor     ch, ch
392
        shld    ecx, ebx, 20;6 ok
382
        shld    ecx, ebx, 20;6 ok
393
        shr     cx, 4;5 ok
383
        shr     cx, 4;5 ok
394
        shld    ebx, eax, 12
384
        shld    ebx, eax, 12
395
        and     ebx, 0x0fffffff;4 ok
385
        and     ebx, 0x0fffffff;4 ok
396
        shr     bx, 4;3 ok
386
        shr     bx, 4;3 ok
397
        shl     eax, 4
387
        shl     eax, 4
398
        and     eax, 0x0fffffff;2 ok
388
        and     eax, 0x0fffffff;2 ok
399
        shr     ax, 4;1 ok
389
        shr     ax, 4;1 ok
400
        mov     dword [edi], eax
390
        mov     dword [edi], eax
401
        mov     dword [edi+4], ebx
391
        mov     dword [edi+4], ebx
402
        mov     dword [edi+8], ecx
392
        mov     dword [edi+8], ecx
403
        mov     dword [edi+12], edx
393
        mov     dword [edi+12], edx
404
        add     edi, 16
394
        add     edi, 16
405
        add     esi, 12
395
        add     esi, 12
406
 
396
 
407
        cmp     edi, [esp]
397
        cmp     edi, [esp]
408
        jnz     fcnew
398
        jnz     fcnew
409
        pop     eax
399
        pop     eax
410
 
400
 
411
        popad
401
        popad
412
        ret
402
        ret
413
 
403
 
414
 
404
 
415
restorefatchain:   ; restore fat chain
405
restorefatchain:   ; restore fat chain
416
 
406
 
417
        pushad
407
        pushad
418
 
408
 
419
        mov     esi, [ebp+FAT.fat12_unpacked_ptr]
409
        mov     esi, [ebp+FAT.fat12_unpacked_ptr]
420
        mov     edi, [ebp+FAT.fat_cache_ptr]
410
        mov     edi, [ebp+FAT.fat_cache_ptr]
421
 
411
 
422
        mov     edx, [ebp+FAT.LAST_CLUSTER]
412
        mov     edx, [ebp+FAT.LAST_CLUSTER]
423
        and     edx, not 7
413
        and     edx, not 7
424
        lea     edx, [esi+(edx+8)*2]
414
        lea     edx, [esi+(edx+8)*2]
425
 
415
 
426
  fcnew2:
416
  fcnew2:
427
        mov     eax, dword [esi]
417
        mov     eax, dword [esi]
428
        mov     ebx, dword [esi+4]
418
        mov     ebx, dword [esi+4]
429
        shl     ax, 4
419
        shl     ax, 4
430
        shl     eax, 4
420
        shl     eax, 4
431
        shl     bx, 4
421
        shl     bx, 4
432
        shr     ebx, 4
422
        shr     ebx, 4
433
        shrd    eax, ebx, 8
423
        shrd    eax, ebx, 8
434
        shr     ebx, 8
424
        shr     ebx, 8
435
        mov     dword [edi], eax
425
        mov     dword [edi], eax
436
        mov     word [edi+4], bx
426
        mov     word [edi+4], bx
437
        add     edi, 6
427
        add     edi, 6
438
        add     esi, 8
428
        add     esi, 8
439
 
429
 
440
        cmp     esi, edx
430
        cmp     esi, edx
441
        jb      fcnew2
431
        jb      fcnew2
442
 
432
 
443
        mov     esi, [ebp+FAT.NUMBER_OF_FATS]
433
        mov     esi, [ebp+FAT.NUMBER_OF_FATS]
444
        mov     edx, [ebp+FAT.LAST_CLUSTER]
434
        mov     edx, [ebp+FAT.LAST_CLUSTER]
445
        lea     edx, [(edx+1)*3 + 512*2-1]
435
        lea     edx, [(edx+1)*3 + 512*2-1]
446
        shr     edx, 10
436
        shr     edx, 10
447
        push    [ebp+FAT.FAT_START]
437
        push    [ebp+FAT.FAT_START]
448
 
438
 
449
.write_fats:
439
.write_fats:
450
        xor     eax, eax
440
        xor     eax, eax
451
        mov     ebx, [ebp+FAT.fat_cache_ptr]
441
        mov     ebx, [ebp+FAT.fat_cache_ptr]
452
.loop1:
442
.loop1:
453
        push    eax
443
        push    eax
454
        add     eax, [esp+4]
444
        add     eax, [esp+4]
455
        call    fs_write32_sys
445
        call    fs_write32_sys
456
        test    eax, eax
446
        test    eax, eax
457
        pop     eax
447
        pop     eax
458
        jnz     .fail
448
        jnz     .fail
459
        add     ebx, 512
449
        add     ebx, 512
460
        inc     eax
450
        inc     eax
461
        cmp     eax, edx
451
        cmp     eax, edx
462
        jb      .loop1
452
        jb      .loop1
463
        pop     eax
453
        pop     eax
464
        add     eax, [ebp+FAT.SECTORS_PER_FAT]
454
        add     eax, [ebp+FAT.SECTORS_PER_FAT]
465
        push    eax
455
        push    eax
466
        dec     esi
456
        dec     esi
467
        jnz     .write_fats
457
        jnz     .write_fats
468
        pop     eax
458
        pop     eax
469
 
459
 
470
        popad
460
        popad
471
        ret
461
        ret
472
.fail:
462
.fail:
473
        dbgstr 'Failed to save FAT'
463
        dbgstr 'Failed to save FAT'
474
        popad
464
        popad
475
        ret
465
        ret
476
 
466
 
477
iglobal
467
iglobal
478
label fat_legal_chars byte
468
label fat_legal_chars byte
479
; 0 = not allowed
469
; 0 = not allowed
480
; 1 = allowed only in long names
470
; 1 = allowed only in long names
481
; 3 = allowed
471
; 3 = allowed
482
        times 32 db 0
472
        times 32 db 0
483
;                 ! " # $ % & ' ( ) * + , - . /
473
;                 ! " # $ % & ' ( ) * + , - . /
484
        db      1,3,0,3,3,3,3,3,3,3,0,1,1,3,3,0
474
        db      1,3,0,3,3,3,3,3,3,3,0,1,1,3,3,0
485
;               0 1 2 3 4 5 6 7 8 9 : ; < = > ?
475
;               0 1 2 3 4 5 6 7 8 9 : ; < = > ?
486
        db      3,3,3,3,3,3,3,3,3,3,0,1,0,1,0,0
476
        db      3,3,3,3,3,3,3,3,3,3,0,1,0,1,0,0
487
;               @ A B C D E F G H I J K L M N O
477
;               @ A B C D E F G H I J K L M N O
488
        db      3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3
478
        db      3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3
489
;               P Q R S T U V W X Y Z [ \ ] ^ _
479
;               P Q R S T U V W X Y Z [ \ ] ^ _
490
        db      3,3,3,3,3,3,3,3,3,3,3,1,0,1,3,3
480
        db      3,3,3,3,3,3,3,3,3,3,3,1,0,1,3,3
491
;               ` a b c d e f g h i j k l m n o
481
;               ` a b c d e f g h i j k l m n o
492
        db      3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3
482
        db      3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3
493
;               p q r s t u v w x y z { | } ~
483
;               p q r s t u v w x y z { | } ~
494
        db      3,3,3,3,3,3,3,3,3,3,3,3,0,3,3,0
484
        db      3,3,3,3,3,3,3,3,3,3,3,3,0,3,3,0
495
endg
485
endg
496
 
486
 
497
fat_name_is_legal:
487
fat_name_is_legal:
498
; in: esi->(long) name
488
; in: esi->(long) name
499
; out: CF set <=> legal
489
; out: CF set <=> legal
500
; destroys eax
490
; destroys eax
501
        push    esi
491
        push    esi
502
        xor     eax, eax
492
        xor     eax, eax
503
@@:
493
@@:
504
        lodsb
494
        lodsb
505
        test    al, al
495
        test    al, al
506
        jz      .done
496
        jz      .done
507
        cmp     al, 80h
497
        cmp     al, 80h
508
        jae     .big
498
        jae     .big
509
        test    [fat_legal_chars+eax], 1
499
        test    [fat_legal_chars+eax], 1
510
        jnz     @b
500
        jnz     @b
511
.err:
501
.err:
512
        pop     esi
502
        pop     esi
513
        clc
503
        clc
514
        ret
504
        ret
515
.big:
505
.big:
516
; 0x80-0xAF, 0xE0-0xEF
506
; 0x80-0xAF, 0xE0-0xEF
517
        cmp     al, 0xB0
507
        cmp     al, 0xB0
518
        jb      @b
508
        jb      @b
519
        cmp     al, 0xE0
509
        cmp     al, 0xE0
520
        jb      .err
510
        jb      .err
521
        cmp     al, 0xF0
511
        cmp     al, 0xF0
522
        jb      @b
512
        jb      @b
523
        jmp     .err
513
        jmp     .err
524
.done:
514
.done:
525
        sub     esi, [esp]
515
        sub     esi, [esp]
526
        cmp     esi, 257
516
        cmp     esi, 257
527
        pop     esi
517
        pop     esi
528
        ret
518
        ret
529
 
519
 
530
fat_next_short_name:
520
fat_next_short_name:
531
; in: edi->8+3 name
521
; in: edi->8+3 name
532
; out: name corrected
522
; out: name corrected
533
;      CF=1 <=> error
523
;      CF=1 <=> error
534
        pushad
524
        pushad
535
        mov     ecx, 8
525
        mov     ecx, 8
536
        mov     al, '~'
526
        mov     al, '~'
537
        std
527
        std
538
        push    edi
528
        push    edi
539
        add     edi, 7
529
        add     edi, 7
540
        repnz scasb
530
        repnz scasb
541
        pop     edi
531
        pop     edi
542
        cld
532
        cld
543
        jz      .tilde
533
        jz      .tilde
544
; tilde is not found, insert "~1" at end
534
; tilde is not found, insert "~1" at end
545
        add     edi, 6
535
        add     edi, 6
546
        cmp     word [edi], '  '
536
        cmp     word [edi], '  '
547
        jnz     .insert_tilde
537
        jnz     .insert_tilde
548
@@:
538
@@:
549
        dec     edi
539
        dec     edi
550
        cmp     byte [edi], ' '
540
        cmp     byte [edi], ' '
551
        jz      @b
541
        jz      @b
552
        inc     edi
542
        inc     edi
553
.insert_tilde:
543
.insert_tilde:
554
        mov     word [edi], '~1'
544
        mov     word [edi], '~1'
555
        popad
545
        popad
556
        clc
546
        clc
557
        ret
547
        ret
558
.tilde:
548
.tilde:
559
        push    edi
549
        push    edi
560
        add     edi, 7
550
        add     edi, 7
561
        xor     ecx, ecx
551
        xor     ecx, ecx
562
@@:
552
@@:
563
; after tilde may be only digits and trailing spaces
553
; after tilde may be only digits and trailing spaces
564
        cmp     byte [edi], '~'
554
        cmp     byte [edi], '~'
565
        jz      .break
555
        jz      .break
566
        cmp     byte [edi], ' '
556
        cmp     byte [edi], ' '
567
        jz      .space
557
        jz      .space
568
        cmp     byte [edi], '9'
558
        cmp     byte [edi], '9'
569
        jnz     .found
559
        jnz     .found
570
        dec     edi
560
        dec     edi
571
        jmp     @b
561
        jmp     @b
572
.space:
562
.space:
573
        dec     edi
563
        dec     edi
574
        inc     ecx
564
        inc     ecx
575
        jmp     @b
565
        jmp     @b
576
.found:
566
.found:
577
        inc     byte [edi]
567
        inc     byte [edi]
578
        add     dword [esp], 8
568
        add     dword [esp], 8
579
        jmp     .zerorest
569
        jmp     .zerorest
580
.break:
570
.break:
581
        jecxz   .noplace
571
        jecxz   .noplace
582
        inc     edi
572
        inc     edi
583
        mov     al, '1'
573
        mov     al, '1'
584
@@:
574
@@:
585
        xchg    al, [edi]
575
        xchg    al, [edi]
586
        inc     edi
576
        inc     edi
587
        cmp     al, ' '
577
        cmp     al, ' '
588
        mov     al, '0'
578
        mov     al, '0'
589
        jnz     @b
579
        jnz     @b
590
.succ:
580
.succ:
591
        pop     edi
581
        pop     edi
592
        popad
582
        popad
593
        clc
583
        clc
594
        ret
584
        ret
595
.noplace:
585
.noplace:
596
        dec     edi
586
        dec     edi
597
        cmp     edi, [esp]
587
        cmp     edi, [esp]
598
        jz      .err
588
        jz      .err
599
        add     dword [esp], 8
589
        add     dword [esp], 8
600
        mov     word [edi], '~1'
590
        mov     word [edi], '~1'
601
        inc     edi
591
        inc     edi
602
        inc     edi
592
        inc     edi
603
@@:
593
@@:
604
        mov     byte [edi], '0'
594
        mov     byte [edi], '0'
605
.zerorest:
595
.zerorest:
606
        inc     edi
596
        inc     edi
607
        cmp     edi, [esp]
597
        cmp     edi, [esp]
608
        jb      @b
598
        jb      @b
609
        pop     edi
599
        pop     edi
610
        popad
600
        popad
611
        ;clc    ; automatically
601
        ;clc    ; automatically
612
        ret
602
        ret
613
.err:
603
.err:
614
        pop     edi
604
        pop     edi
615
        popad
605
        popad
616
        stc
606
        stc
617
        ret
607
        ret
618
 
608
 
619
fat_gen_short_name:
609
fat_gen_short_name:
620
; in: esi->long name
610
; in: esi->long name
621
;     edi->buffer (8+3=11 chars)
611
;     edi->buffer (8+3=11 chars)
622
; out: buffer filled
612
; out: buffer filled
623
        pushad
613
        pushad
624
        mov     eax, '    '
614
        mov     eax, '    '
625
        push    edi
615
        push    edi
626
        stosd
616
        stosd
627
        stosd
617
        stosd
628
        stosd
618
        stosd
629
        pop     edi
619
        pop     edi
630
        xor     eax, eax
620
        xor     eax, eax
631
        movi    ebx, 8
621
        movi    ebx, 8
632
        lea     ecx, [edi+8]
622
        lea     ecx, [edi+8]
633
.loop:
623
.loop:
634
        lodsb
624
        lodsb
635
        test    al, al
625
        test    al, al
636
        jz      .done
626
        jz      .done
637
        call    char_toupper
627
        call    char_toupper
638
        cmp     al, ' '
628
        cmp     al, ' '
639
        jz      .space
629
        jz      .space
640
        cmp     al, 80h
630
        cmp     al, 80h
641
        ja      .big
631
        ja      .big
642
        test    [fat_legal_chars+eax], 2
632
        test    [fat_legal_chars+eax], 2
643
        jnz     .symbol
633
        jnz     .symbol
644
.inv_symbol:
634
.inv_symbol:
645
        mov     al, '_'
635
        mov     al, '_'
646
        or      bh, 1
636
        or      bh, 1
647
.symbol:
637
.symbol:
648
        cmp     al, '.'
638
        cmp     al, '.'
649
        jz      .dot
639
        jz      .dot
650
.normal_symbol:
640
.normal_symbol:
651
        dec     bl
641
        dec     bl
652
        jns     .store
642
        jns     .store
653
        mov     bl, 0
643
        mov     bl, 0
654
.space:
644
.space:
655
        or      bh, 1
645
        or      bh, 1
656
        jmp     .loop
646
        jmp     .loop
657
.store:
647
.store:
658
        stosb
648
        stosb
659
        jmp     .loop
649
        jmp     .loop
660
.big:
650
.big:
661
        cmp     al, 0xB0
651
        cmp     al, 0xB0
662
        jb      .normal_symbol
652
        jb      .normal_symbol
663
        cmp     al, 0xE0
653
        cmp     al, 0xE0
664
        jb      .inv_symbol
654
        jb      .inv_symbol
665
        cmp     al, 0xF0
655
        cmp     al, 0xF0
666
        jb      .normal_symbol
656
        jb      .normal_symbol
667
        jmp     .inv_symbol
657
        jmp     .inv_symbol
668
.dot:
658
.dot:
669
        test    bh, 2
659
        test    bh, 2
670
        jz      .firstdot
660
        jz      .firstdot
671
        pop     ebx
661
        pop     ebx
672
        add     ebx, edi
662
        add     ebx, edi
673
        sub     ebx, ecx
663
        sub     ebx, ecx
674
        push    ebx
664
        push    ebx
675
        cmp     ebx, ecx
665
        cmp     ebx, ecx
676
        jb      @f
666
        jb      @f
677
        pop     ebx
667
        pop     ebx
678
        push    ecx
668
        push    ecx
679
@@:
669
@@:
680
        cmp     edi, ecx
670
        cmp     edi, ecx
681
        jbe     .skip
671
        jbe     .skip
682
@@:
672
@@:
683
        dec     edi
673
        dec     edi
684
        mov     al, [edi]
674
        mov     al, [edi]
685
        dec     ebx
675
        dec     ebx
686
        mov     [ebx], al
676
        mov     [ebx], al
687
        mov     byte [edi], ' '
677
        mov     byte [edi], ' '
688
        cmp     edi, ecx
678
        cmp     edi, ecx
689
        ja      @b
679
        ja      @b
690
.skip:
680
.skip:
691
        mov     bh, 3
681
        mov     bh, 3
692
        jmp     @f
682
        jmp     @f
693
.firstdot:
683
.firstdot:
694
        cmp     bl, 8
684
        cmp     bl, 8
695
        jz      .space
685
        jz      .space
696
        push    edi
686
        push    edi
697
        or      bh, 2
687
        or      bh, 2
698
@@:
688
@@:
699
        mov     edi, ecx
689
        mov     edi, ecx
700
        mov     bl, 3
690
        mov     bl, 3
701
        jmp     .loop
691
        jmp     .loop
702
.done:
692
.done:
703
        test    bh, 2
693
        test    bh, 2
704
        jz      @f
694
        jz      @f
705
        pop     edi
695
        pop     edi
706
@@:
696
@@:
707
        lea     edi, [ecx-8]
697
        lea     edi, [ecx-8]
708
        test    bh, 1
698
        test    bh, 1
709
        jz      @f
699
        jz      @f
710
        call    fat_next_short_name
700
        call    fat_next_short_name
711
@@:
701
@@:
712
        popad
702
        popad
713
        ret
703
        ret
714
 
704
 
715
fat12_free_space:
705
fat12_free_space:
716
;---------------------------------------------
706
;---------------------------------------------
717
;
707
;
718
; returns free space in edi
708
; returns free space in edi
719
; rewr.by Mihasik
709
; rewr.by Mihasik
720
;---------------------------------------------
710
;---------------------------------------------
721
 
711
 
722
        push    eax ebx ecx
712
        push    eax ebx ecx
723
 
713
 
724
        mov     edi, [ebp+FAT.fat12_unpacked_ptr];start of FAT
714
        mov     edi, [ebp+FAT.fat12_unpacked_ptr];start of FAT
725
        xor     ax, ax;Free cluster=0x0000 in FAT
715
        xor     ax, ax;Free cluster=0x0000 in FAT
726
        xor     ebx, ebx;counter
716
        xor     ebx, ebx;counter
727
        mov     ecx, [ebp+FAT.LAST_CLUSTER]
717
        mov     ecx, [ebp+FAT.LAST_CLUSTER]
728
        inc     ecx
718
        inc     ecx
729
        cld
719
        cld
730
    rdfs1:
720
    rdfs1:
731
        repne scasw
721
        repne scasw
732
        jnz     rdfs2 ;if last cluster not 0
722
        jnz     rdfs2 ;if last cluster not 0
733
        inc     ebx
723
        inc     ebx
734
        test    ecx, ecx
724
        test    ecx, ecx
735
        jnz     rdfs1
725
        jnz     rdfs1
736
    rdfs2:
726
    rdfs2:
737
        shl     ebx, 9;free clusters*512
727
        shl     ebx, 9;free clusters*512
738
        mov     edi, ebx
728
        mov     edi, ebx
739
 
729
 
740
        pop     ecx ebx eax
730
        pop     ecx ebx eax
741
        ret
731
        ret
742
 
732
 
743
 
733
 
744
 
734
 
745
set_FAT:
735
set_FAT:
746
;--------------------------------
736
;--------------------------------
747
; input  : EAX = cluster
737
; input  : EAX = cluster
748
;          EDX = value to save
738
;          EDX = value to save
749
;          EBP = pointer to FAT structure
739
;          EBP = pointer to FAT structure
750
; output : EDX = old value
740
; output : EDX = old value
751
;--------------------------------
741
;--------------------------------
752
; out: CF set <=> error
742
; out: CF set <=> error
753
        push    eax ebx esi
743
        push    eax ebx esi
754
 
744
 
755
        cmp     eax, 2
745
        cmp     eax, 2
756
        jb      sfc_error
746
        jb      sfc_error
757
        cmp     eax, [ebp+FAT.LAST_CLUSTER]
747
        cmp     eax, [ebp+FAT.LAST_CLUSTER]
758
        ja      sfc_error
748
        ja      sfc_error
759
        cmp     [ebp+FAT.fs_type], 12
749
        cmp     [ebp+FAT.fs_type], 12
760
        je      set_FAT12
750
        je      set_FAT12
761
        cmp     [ebp+FAT.fs_type], 16
751
        cmp     [ebp+FAT.fs_type], 16
762
        je      sfc_1
752
        je      sfc_1
763
        add     eax, eax
753
        add     eax, eax
764
  sfc_1:
754
  sfc_1:
765
        add     eax, eax
755
        add     eax, eax
766
        mov     esi, 511
756
        mov     esi, 511
767
        and     esi, eax        ; esi = position in fat sector
757
        and     esi, eax        ; esi = position in fat sector
768
        shr     eax, 9          ; eax = fat sector
758
        shr     eax, 9          ; eax = fat sector
769
        add     eax, [ebp+FAT.FAT_START]
759
        add     eax, [ebp+FAT.FAT_START]
770
        mov     ebx, [ebp+FAT.fat_cache_ptr]
760
        mov     ebx, [ebp+FAT.fat_cache_ptr]
771
 
761
 
772
        cmp     eax, [ebp+FAT.fat_in_cache]; is fat sector already in memory?
762
        cmp     eax, [ebp+FAT.fat_in_cache]; is fat sector already in memory?
773
        je      sfc_in_cache    ; yes
763
        je      sfc_in_cache    ; yes
774
 
764
 
775
        cmp     [ebp+FAT.fat_change], 0; is fat changed?
765
        cmp     [ebp+FAT.fat_change], 0; is fat changed?
776
        je      sfc_no_change   ; no
766
        je      sfc_no_change   ; no
777
        call    write_fat_sector; yes. write it into disk
767
        call    write_fat_sector; yes. write it into disk
778
        jc      sfc_error
768
        jc      sfc_error
779
 
769
 
780
  sfc_no_change:
770
  sfc_no_change:
781
        mov     [ebp+FAT.fat_in_cache], eax; save fat sector
771
        mov     [ebp+FAT.fat_in_cache], eax; save fat sector
782
        call    fs_read32_sys
772
        call    fs_read32_sys
783
        test    eax, eax
773
        test    eax, eax
784
        jne     sfc_error
774
        jne     sfc_error
785
 
775
 
786
 
776
 
787
  sfc_in_cache:
777
  sfc_in_cache:
788
        cmp     [ebp+FAT.fs_type], 16
778
        cmp     [ebp+FAT.fs_type], 16
789
        jne     sfc_test32
779
        jne     sfc_test32
790
 
780
 
791
  sfc_set16:
781
  sfc_set16:
792
        xchg    [ebx+esi], dx   ; save new value and get old value
782
        xchg    [ebx+esi], dx   ; save new value and get old value
793
        jmp     sfc_write
783
        jmp     sfc_write
794
 
784
 
795
  sfc_test32:
785
  sfc_test32:
796
        mov     eax, [ebp+FAT.fatMASK]
786
        mov     eax, [ebp+FAT.fatMASK]
797
 
787
 
798
  sfc_set32:
788
  sfc_set32:
799
        and     edx, eax
789
        and     edx, eax
800
        xor     eax, -1         ; mask for high bits
790
        xor     eax, -1         ; mask for high bits
801
        and     eax, [ebx+esi]  ; get high 4 bits
791
        and     eax, [ebx+esi]  ; get high 4 bits
802
        or      eax, edx
792
        or      eax, edx
803
        mov     edx, [ebx+esi]  ; get old value
793
        mov     edx, [ebx+esi]  ; get old value
804
        mov     [ebx+esi], eax  ; save new value
794
        mov     [ebx+esi], eax  ; save new value
805
 
795
 
806
  sfc_write:
796
  sfc_write:
807
        mov     [ebp+FAT.fat_change], 1; fat has changed
797
        mov     [ebp+FAT.fat_change], 1; fat has changed
808
 
798
 
809
  sfc_nonzero:
799
  sfc_nonzero:
810
        and     edx, [ebp+FAT.fatMASK]
800
        and     edx, [ebp+FAT.fatMASK]
811
 
801
 
812
  sfc_return:
802
  sfc_return:
813
        pop     esi ebx eax
803
        pop     esi ebx eax
814
        ret
804
        ret
815
  sfc_error:
805
  sfc_error:
816
        stc
806
        stc
817
        jmp     sfc_return
807
        jmp     sfc_return
818
 
808
 
819
  set_FAT12:
809
  set_FAT12:
820
        test    edx, 0xF000
810
        test    edx, 0xF000
821
        jnz     sfc_error
811
        jnz     sfc_error
822
        mov     ebx, [ebp+FAT.fat12_unpacked_ptr]
812
        mov     ebx, [ebp+FAT.fat12_unpacked_ptr]
823
        xchg    [ebx+eax*2], dx
813
        xchg    [ebx+eax*2], dx
824
        mov     [ebp+FAT.fat_change], 1
814
        mov     [ebp+FAT.fat_change], 1
825
        pop     esi ebx eax
815
        pop     esi ebx eax
826
        clc
816
        clc
827
        ret
817
        ret
828
 
818
 
829
get_FAT:
819
get_FAT:
830
;--------------------------------
820
;--------------------------------
831
; input  : EAX = cluster
821
; input  : EAX = cluster
832
;          EBP = pointer to FAT structure
822
;          EBP = pointer to FAT structure
833
; output : EAX = next cluster
823
; output : EAX = next cluster
834
;--------------------------------
824
;--------------------------------
835
; out: CF set <=> error
825
; out: CF set <=> error
836
        push    ebx esi
826
        push    ebx esi
837
 
827
 
838
        cmp     [ebp+FAT.fs_type], 12
828
        cmp     [ebp+FAT.fs_type], 12
839
        je      get_FAT12
829
        je      get_FAT12
840
 
830
 
841
        cmp     [ebp+FAT.fs_type], 16
831
        cmp     [ebp+FAT.fs_type], 16
842
        je      gfc_1
832
        je      gfc_1
843
        add     eax, eax
833
        add     eax, eax
844
  gfc_1:
834
  gfc_1:
845
        add     eax, eax
835
        add     eax, eax
846
        mov     esi, 511
836
        mov     esi, 511
847
        and     esi, eax        ; esi = position in fat sector
837
        and     esi, eax        ; esi = position in fat sector
848
        shr     eax, 9          ; eax = fat sector
838
        shr     eax, 9          ; eax = fat sector
849
        add     eax, [ebp+FAT.FAT_START]
839
        add     eax, [ebp+FAT.FAT_START]
850
        mov     ebx, [ebp+FAT.fat_cache_ptr]
840
        mov     ebx, [ebp+FAT.fat_cache_ptr]
851
 
841
 
852
        cmp     eax, [ebp+FAT.fat_in_cache]; is fat sector already in memory?
842
        cmp     eax, [ebp+FAT.fat_in_cache]; is fat sector already in memory?
853
        je      gfc_in_cache
843
        je      gfc_in_cache
854
 
844
 
855
        cmp     [ebp+FAT.fat_change], 0; is fat changed?
845
        cmp     [ebp+FAT.fat_change], 0; is fat changed?
856
        je      gfc_no_change   ; no
846
        je      gfc_no_change   ; no
857
        call    write_fat_sector; yes. write it into disk
847
        call    write_fat_sector; yes. write it into disk
858
        jc      hd_error_01
848
        jc      hd_error_01
859
 
849
 
860
  gfc_no_change:
850
  gfc_no_change:
861
        mov     [ebp+FAT.fat_in_cache], eax
851
        mov     [ebp+FAT.fat_in_cache], eax
862
        call    fs_read32_sys
852
        call    fs_read32_sys
863
        test    eax, eax
853
        test    eax, eax
864
        jne     hd_error_01
854
        jne     hd_error_01
865
 
855
 
866
  gfc_in_cache:
856
  gfc_in_cache:
867
        mov     eax, [ebx+esi]
857
        mov     eax, [ebx+esi]
868
        and     eax, [ebp+FAT.fatMASK]
858
        and     eax, [ebp+FAT.fatMASK]
869
  gfc_return:
859
  gfc_return:
870
        pop     esi ebx
860
        pop     esi ebx
871
        ret
861
        ret
872
 hd_error_01:
862
 hd_error_01:
873
        stc
863
        stc
874
        jmp     gfc_return
864
        jmp     gfc_return
875
 
865
 
876
get_FAT12:
866
get_FAT12:
877
        mov     ebx, [ebp+FAT.fat12_unpacked_ptr]
867
        mov     ebx, [ebp+FAT.fat12_unpacked_ptr]
878
        movzx   eax, word [ebx+eax*2]
868
        movzx   eax, word [ebx+eax*2]
879
        pop     esi ebx
869
        pop     esi ebx
880
        clc
870
        clc
881
        ret
871
        ret
882
 
872
 
883
 
873
 
884
get_free_FAT:
874
get_free_FAT:
885
;-----------------------------------------------------------
875
;-----------------------------------------------------------
886
; output : if CARRY=0 EAX = # first cluster found free
876
; output : if CARRY=0 EAX = # first cluster found free
887
;          if CARRY=1 disk full
877
;          if CARRY=1 disk full
888
; Note   : for more speed need to use fat_cache directly
878
; Note   : for more speed need to use fat_cache directly
889
;-----------------------------------------------------------
879
;-----------------------------------------------------------
890
        push    ecx
880
        push    ecx
891
        mov     ecx, [ebp+FAT.LAST_CLUSTER]; counter for full disk
881
        mov     ecx, [ebp+FAT.LAST_CLUSTER]; counter for full disk
892
        mov     eax, [ebp+FAT.fatStartScan]
882
        mov     eax, [ebp+FAT.fatStartScan]
893
        cmp     [ebp+FAT.fs_type], 12
883
        cmp     [ebp+FAT.fs_type], 12
894
        jz      get_free_FAT12
884
        jz      get_free_FAT12
895
        dec     ecx
885
        dec     ecx
896
        cmp     eax, 2
886
        cmp     eax, 2
897
        jb      gff_reset
887
        jb      gff_reset
898
 
888
 
899
  gff_test:
889
  gff_test:
900
        cmp     eax, [ebp+FAT.LAST_CLUSTER]; if above last cluster start at cluster 2
890
        cmp     eax, [ebp+FAT.LAST_CLUSTER]; if above last cluster start at cluster 2
901
        jbe     gff_in_range
891
        jbe     gff_in_range
902
  gff_reset:
892
  gff_reset:
903
        mov     eax, 2
893
        mov     eax, 2
904
 
894
 
905
  gff_in_range:
895
  gff_in_range:
906
        push    eax
896
        push    eax
907
        call    get_FAT         ; get cluster state
897
        call    get_FAT         ; get cluster state
908
        jc      gff_not_found_1
898
        jc      gff_not_found_1
909
 
899
 
910
        test    eax, eax        ; is it free?
900
        test    eax, eax        ; is it free?
911
        pop     eax
901
        pop     eax
912
        je      gff_found       ; yes
902
        je      gff_found       ; yes
913
        inc     eax             ; next cluster
903
        inc     eax             ; next cluster
914
        dec     ecx             ; is all checked?
904
        dec     ecx             ; is all checked?
915
        jnz     gff_test        ; no
905
        jnz     gff_test        ; no
916
 
906
 
917
  gff_not_found:
907
  gff_not_found:
918
        pop     ecx             ; yes. disk is full
908
        pop     ecx             ; yes. disk is full
919
        stc
909
        stc
920
        ret
910
        ret
921
 
911
 
922
  gff_not_found_1:
912
  gff_not_found_1:
923
        pop     eax
913
        pop     eax
924
        jmp     gff_not_found
914
        jmp     gff_not_found
925
 
915
 
926
  gff_found:
916
  gff_found:
927
        lea     ecx, [eax+1]
917
        lea     ecx, [eax+1]
928
        mov     [ebp+FAT.fatStartScan], ecx
918
        mov     [ebp+FAT.fatStartScan], ecx
929
        pop     ecx
919
        pop     ecx
930
        clc
920
        clc
931
        ret
921
        ret
932
 
922
 
933
get_free_FAT12:
923
get_free_FAT12:
934
        push    edx edi
924
        push    edx edi
935
        mov     edi, [ebp+FAT.fat12_unpacked_ptr]
925
        mov     edi, [ebp+FAT.fat12_unpacked_ptr]
936
        cmp     eax, 2
926
        cmp     eax, 2
937
        jb      .reset
927
        jb      .reset
938
        cmp     eax, ecx
928
        cmp     eax, ecx
939
        jbe     @f
929
        jbe     @f
940
.reset:
930
.reset:
941
        mov     eax, 2
931
        mov     eax, 2
942
@@:
932
@@:
943
        mov     edx, eax
933
        mov     edx, eax
944
        lea     edi, [edi+eax*2]
934
        lea     edi, [edi+eax*2]
945
        sub     ecx, eax
935
        sub     ecx, eax
946
        inc     ecx
936
        inc     ecx
947
        xor     eax, eax
937
        xor     eax, eax
948
        repnz scasw
938
        repnz scasw
949
        jz      .found
939
        jz      .found
950
        cmp     edx, 2
940
        cmp     edx, 2
951
        jz      .notfound
941
        jz      .notfound
952
        mov     edi, [ebp+FAT.fat12_unpacked_ptr]
942
        mov     edi, [ebp+FAT.fat12_unpacked_ptr]
953
        lea     ecx, [edx-2]
943
        lea     ecx, [edx-2]
954
        repnz scasw
944
        repnz scasw
955
        jnz     .notfound
945
        jnz     .notfound
956
.found:
946
.found:
957
        sub     edi, [ebp+FAT.fat12_unpacked_ptr]
947
        sub     edi, [ebp+FAT.fat12_unpacked_ptr]
958
        shr     edi, 1
948
        shr     edi, 1
959
        mov     [ebp+FAT.fatStartScan], edi
949
        mov     [ebp+FAT.fatStartScan], edi
960
        lea     eax, [edi-1]
950
        lea     eax, [edi-1]
961
        pop     edi edx ecx
951
        pop     edi edx ecx
962
        ret
952
        ret
963
.notfound:
953
.notfound:
964
        pop     edi edx ecx
954
        pop     edi edx ecx
965
        stc
955
        stc
966
        ret
956
        ret
967
 
957
 
968
 
958
 
969
write_fat_sector:
959
write_fat_sector:
970
;-----------------------------------------------------------
960
;-----------------------------------------------------------
971
; write changed fat to disk
961
; write changed fat to disk
972
;-----------------------------------------------------------
962
;-----------------------------------------------------------
973
        push    eax ebx ecx
963
        push    eax ebx ecx
974
 
964
 
975
        mov     [ebp+FAT.fat_change], 0
965
        mov     [ebp+FAT.fat_change], 0
976
        mov     eax, [ebp+FAT.fat_in_cache]
966
        mov     eax, [ebp+FAT.fat_in_cache]
977
        cmp     eax, -1
967
        cmp     eax, -1
978
        jz      write_fat_not_used
968
        jz      write_fat_not_used
979
        mov     ebx, [ebp+FAT.fat_cache_ptr]
969
        mov     ebx, [ebp+FAT.fat_cache_ptr]
980
        mov     ecx, [ebp+FAT.NUMBER_OF_FATS]
970
        mov     ecx, [ebp+FAT.NUMBER_OF_FATS]
981
 
971
 
982
  write_next_fat:
972
  write_next_fat:
983
        push    eax
973
        push    eax
984
        call    fs_write32_sys
974
        call    fs_write32_sys
985
        test    eax, eax
975
        test    eax, eax
986
        pop     eax
976
        pop     eax
987
        jnz     write_fat_not_used
977
        jnz     write_fat_not_used
988
 
978
 
989
        add     eax, [ebp+FAT.SECTORS_PER_FAT]
979
        add     eax, [ebp+FAT.SECTORS_PER_FAT]
990
        dec     ecx
980
        dec     ecx
991
        jnz     write_next_fat
981
        jnz     write_next_fat
992
 
982
 
993
  write_fat_not_used:
983
  write_fat_not_used:
994
        pop     ecx ebx eax
984
        pop     ecx ebx eax
995
        ret
985
        ret
996
 
986
 
997
 
987
 
998
 
988
 
999
 
989
 
1000
 
990
 
1001
bcd2bin:
991
bcd2bin:
1002
;----------------------------------
992
;----------------------------------
1003
; input  : AL=BCD number (eg. 0x11)
993
; input  : AL=BCD number (eg. 0x11)
1004
; output : AH=0
994
; output : AH=0
1005
;          AL=decimal number (eg. 11)
995
;          AL=decimal number (eg. 11)
1006
;----------------------------------
996
;----------------------------------
1007
        xor     ah, ah
997
        xor     ah, ah
1008
        shl     ax, 4
998
        shl     ax, 4
1009
        shr     al, 4
999
        shr     al, 4
1010
        aad
1000
        aad
1011
        ret
1001
        ret
1012
 
1002
 
1013
 
1003
 
1014
get_date_for_file:
1004
get_date_for_file:
1015
;-----------------------------------------------------
1005
;-----------------------------------------------------
1016
; Get date from CMOS and pack day,month,year in AX
1006
; Get date from CMOS and pack day,month,year in AX
1017
; DATE   bits  0..4   : day of month 0..31
1007
; DATE   bits  0..4   : day of month 0..31
1018
;              5..8   : month of year 1..12
1008
;              5..8   : month of year 1..12
1019
;              9..15  : count of years from 1980
1009
;              9..15  : count of years from 1980
1020
;-----------------------------------------------------
1010
;-----------------------------------------------------
1021
        mov     al, 0x7 ;day
1011
        mov     al, 0x7 ;day
1022
        out     0x70, al
1012
        out     0x70, al
1023
        in      al, 0x71
1013
        in      al, 0x71
1024
        call    bcd2bin
1014
        call    bcd2bin
1025
        ror     eax, 5
1015
        ror     eax, 5
1026
 
1016
 
1027
        mov     al, 0x8 ;month
1017
        mov     al, 0x8 ;month
1028
        out     0x70, al
1018
        out     0x70, al
1029
        in      al, 0x71
1019
        in      al, 0x71
1030
        call    bcd2bin
1020
        call    bcd2bin
1031
        ror     eax, 4
1021
        ror     eax, 4
1032
 
1022
 
1033
        mov     al, 0x9 ;year
1023
        mov     al, 0x9 ;year
1034
        out     0x70, al
1024
        out     0x70, al
1035
        in      al, 0x71
1025
        in      al, 0x71
1036
        call    bcd2bin
1026
        call    bcd2bin
1037
        add     ax, 20  ;because CMOS return only the two last
1027
        add     ax, 20  ;because CMOS return only the two last
1038
                        ;digit (eg. 2000 -> 00 , 2001 -> 01) and we
1028
                        ;digit (eg. 2000 -> 00 , 2001 -> 01) and we
1039
        rol     eax, 9  ;need the difference with 1980 (eg. 2001-1980)
1029
        rol     eax, 9  ;need the difference with 1980 (eg. 2001-1980)
1040
        ret
1030
        ret
1041
 
1031
 
1042
 
1032
 
1043
get_time_for_file:
1033
get_time_for_file:
1044
;-----------------------------------------------------
1034
;-----------------------------------------------------
1045
; Get time from CMOS and pack hour,minute,second in AX
1035
; Get time from CMOS and pack hour,minute,second in AX
1046
; TIME   bits  0..4   : second (the low bit is lost)
1036
; TIME   bits  0..4   : second (the low bit is lost)
1047
;              5..10  : minute 0..59
1037
;              5..10  : minute 0..59
1048
;              11..15 : hour 0..23
1038
;              11..15 : hour 0..23
1049
;-----------------------------------------------------
1039
;-----------------------------------------------------
1050
        mov     al, 0x0 ;second
1040
        mov     al, 0x0 ;second
1051
        out     0x70, al
1041
        out     0x70, al
1052
        in      al, 0x71
1042
        in      al, 0x71
1053
        call    bcd2bin
1043
        call    bcd2bin
1054
        ror     eax, 6
1044
        ror     eax, 6
1055
 
1045
 
1056
        mov     al, 0x2 ;minute
1046
        mov     al, 0x2 ;minute
1057
        out     0x70, al
1047
        out     0x70, al
1058
        in      al, 0x71
1048
        in      al, 0x71
1059
        call    bcd2bin
1049
        call    bcd2bin
1060
        ror     eax, 6
1050
        ror     eax, 6
1061
 
1051
 
1062
        mov     al, 0x4 ;hour
1052
        mov     al, 0x4 ;hour
1063
        out     0x70, al
1053
        out     0x70, al
1064
        in      al, 0x71
1054
        in      al, 0x71
1065
        call    bcd2bin
1055
        call    bcd2bin
1066
        rol     eax, 11
1056
        rol     eax, 11
1067
        ret
1057
        ret
1068
 
1058
 
1069
 
1059
 
1070
set_current_time_for_entry:
1060
set_current_time_for_entry:
1071
;-----------------------------------------------------
1061
;-----------------------------------------------------
1072
; Set current time/date for file entry
1062
; Set current time/date for file entry
1073
; input  : ebx = file entry pointer
1063
; input  : ebx = file entry pointer
1074
;-----------------------------------------------------
1064
;-----------------------------------------------------
1075
        push    eax
1065
        push    eax
1076
        call    get_time_for_file; update files date/time
1066
        call    get_time_for_file; update files date/time
1077
        mov     [ebx+22], ax
1067
        mov     [ebx+22], ax
1078
        call    get_date_for_file
1068
        call    get_date_for_file
1079
        mov     [ebx+24], ax
1069
        mov     [ebx+24], ax
1080
        pop     eax
1070
        pop     eax
1081
        ret
1071
        ret
1082
 
1072
 
1083
 
1073
 
1084
 
1074
 
1085
add_disk_free_space:
1075
add_disk_free_space:
1086
;-----------------------------------------------------
1076
;-----------------------------------------------------
1087
; input  : ecx = cluster count
1077
; input  : ecx = cluster count
1088
; Note   : negative = remove clusters from free space
1078
; Note   : negative = remove clusters from free space
1089
;          positive = add clusters to free space
1079
;          positive = add clusters to free space
1090
;-----------------------------------------------------
1080
;-----------------------------------------------------
1091
        test    ecx, ecx        ; no change
1081
        test    ecx, ecx        ; no change
1092
        je      add_dfs_no
1082
        je      add_dfs_no
1093
        cmp     [ebp+FAT.fs_type], 32  ; free disk space only used by fat32
1083
        cmp     [ebp+FAT.fs_type], 32  ; free disk space only used by fat32
1094
        jne     add_dfs_no
1084
        jne     add_dfs_no
1095
 
1085
 
1096
        push    eax ebx
1086
        push    eax ebx
1097
        mov     eax, [ebp+FAT.ADR_FSINFO]
1087
        mov     eax, [ebp+FAT.ADR_FSINFO]
1098
        lea     ebx, [ebp+FAT.fsinfo_buffer]
1088
        lea     ebx, [ebp+FAT.fsinfo_buffer]
1099
        call    fs_read32_sys
1089
        call    fs_read32_sys
1100
        test    eax, eax
1090
        test    eax, eax
1101
        jnz     add_not_fs
1091
        jnz     add_not_fs
1102
 
1092
 
1103
        cmp     dword [ebx+0x1fc], 0xaa550000; check sector id
1093
        cmp     dword [ebx+0x1fc], 0xaa550000; check sector id
1104
        jne     add_not_fs
1094
        jne     add_not_fs
1105
 
1095
 
1106
        add     [ebx+0x1e8], ecx
1096
        add     [ebx+0x1e8], ecx
1107
        push    [ebp+FAT.fatStartScan]
1097
        push    [ebp+FAT.fatStartScan]
1108
        pop     dword [ebx+0x1ec]
1098
        pop     dword [ebx+0x1ec]
1109
        mov     eax, [ebp+FAT.ADR_FSINFO]
1099
        mov     eax, [ebp+FAT.ADR_FSINFO]
1110
        call    fs_write32_sys
1100
        call    fs_write32_sys
1111
;    jc    add_not_fs
1101
;    jc    add_not_fs
1112
 
1102
 
1113
  add_not_fs:
1103
  add_not_fs:
1114
        pop     ebx eax
1104
        pop     ebx eax
1115
 
1105
 
1116
  add_dfs_no:
1106
  add_dfs_no:
1117
        ret
1107
        ret
1118
 
1108
 
1119
 
1109
 
1120
 
1110
 
1121
clear_cluster_chain:
1111
clear_cluster_chain:
1122
;-----------------------------------------------------
1112
;-----------------------------------------------------
1123
; input  : eax = first cluster
1113
; input  : eax = first cluster
1124
;-----------------------------------------------------
1114
;-----------------------------------------------------
1125
        push    eax ecx edx
1115
        push    eax ecx edx
1126
        xor     ecx, ecx        ; cluster count
1116
        xor     ecx, ecx        ; cluster count
1127
 
1117
 
1128
  clean_new_chain:
1118
  clean_new_chain:
1129
        cmp     eax, [ebp+FAT.LAST_CLUSTER]; end of file
1119
        cmp     eax, [ebp+FAT.LAST_CLUSTER]; end of file
1130
        ja      delete_OK
1120
        ja      delete_OK
1131
        cmp     eax, 2          ; unfinished fat chain or zero length file
1121
        cmp     eax, 2          ; unfinished fat chain or zero length file
1132
        jb      delete_OK
1122
        jb      delete_OK
1133
        cmp     eax, [ebp+FAT.ROOT_CLUSTER]; don't remove root cluster
1123
        cmp     eax, [ebp+FAT.ROOT_CLUSTER]; don't remove root cluster
1134
        jz      delete_OK
1124
        jz      delete_OK
1135
 
1125
 
1136
        xor     edx, edx
1126
        xor     edx, edx
1137
        call    set_FAT         ; clear fat entry
1127
        call    set_FAT         ; clear fat entry
1138
        jc      access_denied_01
1128
        jc      access_denied_01
1139
 
1129
 
1140
        inc     ecx             ; update cluster count
1130
        inc     ecx             ; update cluster count
1141
        mov     eax, edx        ; old cluster
1131
        mov     eax, edx        ; old cluster
1142
        jmp     clean_new_chain
1132
        jmp     clean_new_chain
1143
 
1133
 
1144
  delete_OK:
1134
  delete_OK:
1145
        call    add_disk_free_space; add clusters to free disk space
1135
        call    add_disk_free_space; add clusters to free disk space
1146
        clc
1136
        clc
1147
  access_denied_01:
1137
  access_denied_01:
1148
        pop     edx ecx eax
1138
        pop     edx ecx eax
1149
        ret
1139
        ret
1150
 
1140
 
1151
 
1141
 
1152
if 0
1142
if 0
1153
get_hd_info:
1143
get_hd_info:
1154
;-----------------------------------------------------------
1144
;-----------------------------------------------------------
1155
; output : eax = 0 - ok
1145
; output : eax = 0 - ok
1156
;                3 - unknown FS
1146
;                3 - unknown FS
1157
;               10 - access denied
1147
;               10 - access denied
1158
;          edx = cluster size in bytes
1148
;          edx = cluster size in bytes
1159
;          ebx = total clusters on disk
1149
;          ebx = total clusters on disk
1160
;          ecx = free clusters on disk
1150
;          ecx = free clusters on disk
1161
;-----------------------------------------------------------
1151
;-----------------------------------------------------------
1162
        cmp     [ebp+FAT.fs_type], 16
1152
        cmp     [ebp+FAT.fs_type], 16
1163
        jz      info_fat_ok
1153
        jz      info_fat_ok
1164
        cmp     [ebp+FAT.fs_type], 32
1154
        cmp     [ebp+FAT.fs_type], 32
1165
        jz      info_fat_ok
1155
        jz      info_fat_ok
1166
        xor     edx, edx
1156
        xor     edx, edx
1167
        xor     ebx, ebx
1157
        xor     ebx, ebx
1168
        xor     ecx, ecx
1158
        xor     ecx, ecx
1169
        mov     eax, ERROR_UNKNOWN_FS
1159
        mov     eax, ERROR_UNKNOWN_FS
1170
        ret
1160
        ret
1171
 
1161
 
1172
  info_fat_ok:
1162
  info_fat_ok:
1173
;    call  reserve_hd1
1163
;    call  reserve_hd1
1174
 
1164
 
1175
        xor     ecx, ecx        ; count of free clusters
1165
        xor     ecx, ecx        ; count of free clusters
1176
        mov     eax, 2
1166
        mov     eax, 2
1177
        mov     ebx, [ebp+FAT.LAST_CLUSTER]
1167
        mov     ebx, [ebp+FAT.LAST_CLUSTER]
1178
 
1168
 
1179
  info_cluster:
1169
  info_cluster:
1180
        push    eax
1170
        push    eax
1181
        call    get_FAT         ; get cluster info
1171
        call    get_FAT         ; get cluster info
1182
        jc      info_access_denied
1172
        jc      info_access_denied
1183
 
1173
 
1184
        test    eax, eax        ; is it free?
1174
        test    eax, eax        ; is it free?
1185
        jnz     info_used       ; no
1175
        jnz     info_used       ; no
1186
        inc     ecx
1176
        inc     ecx
1187
 
1177
 
1188
  info_used:
1178
  info_used:
1189
        pop     eax
1179
        pop     eax
1190
        inc     eax
1180
        inc     eax
1191
        cmp     eax, ebx        ; is above last cluster?
1181
        cmp     eax, ebx        ; is above last cluster?
1192
        jbe     info_cluster    ; no. test next cluster
1182
        jbe     info_cluster    ; no. test next cluster
1193
 
1183
 
1194
        dec     ebx             ; cluster count
1184
        dec     ebx             ; cluster count
1195
        imul    edx, [ebp+FAT.SECTORS_PER_CLUSTER], 512; cluster size in bytes
1185
        imul    edx, [ebp+FAT.SECTORS_PER_CLUSTER], 512; cluster size in bytes
1196
        xor     eax, eax
1186
        xor     eax, eax
1197
        ret
1187
        ret
1198
 
1188
 
1199
  info_access_denied:
1189
  info_access_denied:
1200
        add     esp, 4
1190
        add     esp, 4
1201
        xor     edx, edx
1191
        xor     edx, edx
1202
        xor     ebx, ebx
1192
        xor     ebx, ebx
1203
        xor     ecx, ecx
1193
        xor     ecx, ecx
1204
        mov     eax, ERROR_ACCESS_DENIED
1194
        mov     eax, ERROR_ACCESS_DENIED
1205
        ret
1195
        ret
1206
end if
1196
end if
1207
 
1197
 
1208
update_disk:
1198
update_disk:
1209
        cmp     [ebp+FAT.fat_change], 0 ; is fat changed?
1199
        cmp     [ebp+FAT.fat_change], 0 ; is fat changed?
1210
        je      upd_no_change
1200
        je      upd_no_change
1211
        cmp     [ebp+FAT.fs_type], 12
1201
        cmp     [ebp+FAT.fs_type], 12
1212
        jz      .fat12
1202
        jz      .fat12
1213
;-----------------------------------------------------------
1203
;-----------------------------------------------------------
1214
; write changed fat and cache to disk
1204
; write changed fat and cache to disk
1215
;-----------------------------------------------------------
1205
;-----------------------------------------------------------
1216
 
1206
 
1217
        call    write_fat_sector
1207
        call    write_fat_sector
1218
        jc      update_disk_acces_denied
1208
        jc      update_disk_acces_denied
1219
        jmp     upd_no_change
1209
        jmp     upd_no_change
1220
.fat12:
1210
.fat12:
1221
        call    restorefatchain
1211
        call    restorefatchain
1222
        mov     [ebp+FAT.fat_change], 0
1212
        mov     [ebp+FAT.fat_change], 0
1223
 
1213
 
1224
  upd_no_change:
1214
  upd_no_change:
1225
 
1215
 
1226
        push    esi
1216
        push    esi
1227
        mov     esi, [ebp+PARTITION.Disk]
1217
        mov     esi, [ebp+PARTITION.Disk]
1228
        call    disk_sync
1218
        call    disk_sync
1229
        pop     esi
1219
        pop     esi
1230
  update_disk_acces_denied:
1220
  update_disk_acces_denied:
1231
        ret
1221
        ret
1232
 
1222
 
1233
fat_lock:
1223
fat_lock:
1234
        lea     ecx, [ebp+FAT.Lock]
1224
        lea     ecx, [ebp+FAT.Lock]
1235
        jmp     mutex_lock
1225
        jmp     mutex_lock
1236
fat_unlock:
1226
fat_unlock:
1237
        lea     ecx, [ebp+FAT.Lock]
1227
        lea     ecx, [ebp+FAT.Lock]
1238
        jmp     mutex_unlock
1228
        jmp     mutex_unlock
1239
 
1229
 
1240
; \begin{diamond}
1230
; \begin{diamond}
1241
uni2ansi_str:
1231
uni2ansi_str:
1242
; convert UNICODE zero-terminated string to ASCII-string (codepage 866)
1232
; convert UNICODE zero-terminated string to ASCII-string (codepage 866)
1243
; in: esi->source, edi->buffer (may be esi=edi)
1233
; in: esi->source, edi->buffer (may be esi=edi)
1244
; destroys: eax,esi,edi
1234
; destroys: eax,esi,edi
1245
        lodsw
1235
        lodsw
1246
        test    ax, ax
1236
        test    ax, ax
1247
        jz      .done
1237
        jz      .done
1248
        cmp     ax, 0x80
1238
        cmp     ax, 0x80
1249
        jb      .ascii
1239
        jb      .ascii
1250
        cmp     ax, 0x401
1240
        cmp     ax, 0x401
1251
        jz      .yo1
1241
        jz      .yo1
1252
        cmp     ax, 0x451
1242
        cmp     ax, 0x451
1253
        jz      .yo2
1243
        jz      .yo2
1254
        cmp     ax, 0x410
1244
        cmp     ax, 0x410
1255
        jb      .unk
1245
        jb      .unk
1256
        cmp     ax, 0x440
1246
        cmp     ax, 0x440
1257
        jb      .rus1
1247
        jb      .rus1
1258
        cmp     ax, 0x450
1248
        cmp     ax, 0x450
1259
        jb      .rus2
1249
        jb      .rus2
1260
.unk:
1250
.unk:
1261
        mov     al, '_'
1251
        mov     al, '_'
1262
        jmp     .doit
1252
        jmp     .doit
1263
.yo1:
1253
.yo1:
1264
        mov     al, 0xF0 ; 'Ё'
1254
        mov     al, 0xF0 ; 'Ё'
1265
        jmp     .doit
1255
        jmp     .doit
1266
.yo2:
1256
.yo2:
1267
        mov     al, 0xF1 ; 'ё'
1257
        mov     al, 0xF1 ; 'ё'
1268
        jmp     .doit
1258
        jmp     .doit
1269
.rus1:
1259
.rus1:
1270
; 0x410-0x43F -> 0x80-0xAF
1260
; 0x410-0x43F -> 0x80-0xAF
1271
        add     al, 0x70
1261
        add     al, 0x70
1272
        jmp     .doit
1262
        jmp     .doit
1273
.rus2:
1263
.rus2:
1274
; 0x440-0x44F -> 0xE0-0xEF
1264
; 0x440-0x44F -> 0xE0-0xEF
1275
        add     al, 0xA0
1265
        add     al, 0xA0
1276
.ascii:
1266
.ascii:
1277
.doit:
1267
.doit:
1278
        stosb
1268
        stosb
1279
        jmp     uni2ansi_str
1269
        jmp     uni2ansi_str
1280
.done:
1270
.done:
1281
        mov     byte [edi], 0
1271
        mov     byte [edi], 0
1282
        ret
1272
        ret
1283
 
1273
 
1284
ansi2uni_char:
1274
ansi2uni_char:
1285
; convert ANSI character in al to UNICODE character in ax, using cp866 encoding
1275
; convert ANSI character in al to UNICODE character in ax, using cp866 encoding
1286
        mov     ah, 0
1276
        mov     ah, 0
1287
; 0x00-0x7F - trivial map
1277
; 0x00-0x7F - trivial map
1288
        cmp     al, 0x80
1278
        cmp     al, 0x80
1289
        jb      .ret
1279
        jb      .ret
1290
; 0x80-0xAF -> 0x410-0x43F
1280
; 0x80-0xAF -> 0x410-0x43F
1291
        cmp     al, 0xB0
1281
        cmp     al, 0xB0
1292
        jae     @f
1282
        jae     @f
1293
        add     ax, 0x410-0x80
1283
        add     ax, 0x410-0x80
1294
.ret:
1284
.ret:
1295
        ret
1285
        ret
1296
@@:
1286
@@:
1297
; 0xE0-0xEF -> 0x440-0x44F
1287
; 0xE0-0xEF -> 0x440-0x44F
1298
        cmp     al, 0xE0
1288
        cmp     al, 0xE0
1299
        jb      .unk
1289
        jb      .unk
1300
        cmp     al, 0xF0
1290
        cmp     al, 0xF0
1301
        jae     @f
1291
        jae     @f
1302
        add     ax, 0x440-0xE0
1292
        add     ax, 0x440-0xE0
1303
        ret
1293
        ret
1304
; 0xF0 -> 0x401
1294
; 0xF0 -> 0x401
1305
; 0xF1 -> 0x451
1295
; 0xF1 -> 0x451
1306
@@:
1296
@@:
1307
        cmp     al, 0xF0 ; 'Ё'
1297
        cmp     al, 0xF0 ; 'Ё'
1308
        jz      .yo1
1298
        jz      .yo1
1309
        cmp     al, 0xF1 ; 'ё'
1299
        cmp     al, 0xF1 ; 'ё'
1310
        jz      .yo2
1300
        jz      .yo2
1311
.unk:
1301
.unk:
1312
        mov     al, '_'         ; ah=0
1302
        mov     al, '_'         ; ah=0
1313
        ret
1303
        ret
1314
.yo1:
1304
.yo1:
1315
        mov     ax, 0x401
1305
        mov     ax, 0x401
1316
        ret
1306
        ret
1317
.yo2:
1307
.yo2:
1318
        mov     ax, 0x451
1308
        mov     ax, 0x451
1319
        ret
1309
        ret
1320
 
1310
 
1321
char_toupper:
1311
char_toupper:
1322
; convert character to uppercase, using cp866 encoding
1312
; convert character to uppercase, using cp866 encoding
1323
; in: al=symbol
1313
; in: al=symbol
1324
; out: al=converted symbol
1314
; out: al=converted symbol
1325
        cmp     al, 'a'
1315
        cmp     al, 'a'
1326
        jb      .ret
1316
        jb      .ret
1327
        cmp     al, 'z'
1317
        cmp     al, 'z'
1328
        jbe     .az
1318
        jbe     .az
1329
        cmp     al, 0xF1 ; 'ё'
1319
        cmp     al, 0xF1 ; 'ё'
1330
        jz      .yo1
1320
        jz      .yo1
1331
        cmp     al, 0xA0 ; 'а'
1321
        cmp     al, 0xA0 ; 'а'
1332
        jb      .ret
1322
        jb      .ret
1333
        cmp     al, 0xE0 ; 'р'
1323
        cmp     al, 0xE0 ; 'р'
1334
        jb      .rus1
1324
        jb      .rus1
1335
        cmp     al, 0xEF ; 'я'
1325
        cmp     al, 0xEF ; 'я'
1336
        ja      .ret
1326
        ja      .ret
1337
; 0xE0-0xEF -> 0x90-0x9F
1327
; 0xE0-0xEF -> 0x90-0x9F
1338
        sub     al, 0xE0-0x90
1328
        sub     al, 0xE0-0x90
1339
.ret:
1329
.ret:
1340
        ret
1330
        ret
1341
.rus1:
1331
.rus1:
1342
; 0xA0-0xAF -> 0x80-0x8F
1332
; 0xA0-0xAF -> 0x80-0x8F
1343
.az:
1333
.az:
1344
        and     al, not 0x20
1334
        and     al, not 0x20
1345
        ret
1335
        ret
1346
.yo1:
1336
.yo1:
1347
; 0xF1 -> 0xF0
1337
; 0xF1 -> 0xF0
1348
        dec     ax
1338
        dec     ax
1349
        ret
1339
        ret
1350
 
1340
 
1351
fat_get_name:
1341
fat_get_name:
1352
; in: edi->FAT entry
1342
; in: edi->FAT entry
1353
; out: CF=1 - no valid entry
1343
; out: CF=1 - no valid entry
1354
; else CF=0 and ebp->ASCIIZ-name
1344
; else CF=0 and ebp->ASCIIZ-name
1355
; (maximum length of filename is 255 (wide) symbols without trailing 0,
1345
; (maximum length of filename is 255 (wide) symbols without trailing 0,
1356
;  but implementation requires buffer 261 words)
1346
;  but implementation requires buffer 261 words)
1357
; destroys eax
1347
; destroys eax
1358
        cmp     byte [edi], 0
1348
        cmp     byte [edi], 0
1359
        jz      .no
1349
        jz      .no
1360
        cmp     byte [edi], 0xE5
1350
        cmp     byte [edi], 0xE5
1361
        jnz     @f
1351
        jnz     @f
1362
.no:
1352
.no:
1363
        stc
1353
        stc
1364
        ret
1354
        ret
1365
@@:
1355
@@:
1366
        cmp     byte [edi+11], 0xF
1356
        cmp     byte [edi+11], 0xF
1367
        jz      .longname
1357
        jz      .longname
1368
        test    byte [edi+11], 8
1358
        test    byte [edi+11], 8
1369
        jnz     .no
1359
        jnz     .no
1370
        push    ecx
1360
        push    ecx
1371
        push    edi ebp
1361
        push    edi ebp
1372
        test    byte [ebp-4], 1
1362
        test    byte [ebp-4], 1
1373
        jnz     .unicode_short
1363
        jnz     .unicode_short
1374
 
1364
 
1375
        mov     eax, [edi]
1365
        mov     eax, [edi]
1376
        mov     ecx, [edi+4]
1366
        mov     ecx, [edi+4]
1377
        mov     [ebp], eax
1367
        mov     [ebp], eax
1378
        mov     [ebp+4], ecx
1368
        mov     [ebp+4], ecx
1379
 
1369
 
1380
        mov     ecx, 8
1370
        mov     ecx, 8
1381
@@:
1371
@@:
1382
        cmp     byte [ebp+ecx-1], ' '
1372
        cmp     byte [ebp+ecx-1], ' '
1383
        loope   @b
1373
        loope   @b
1384
 
1374
 
1385
        mov     eax, [edi+8]
1375
        mov     eax, [edi+8]
1386
        cmp     al, ' '
1376
        cmp     al, ' '
1387
        je      .done
1377
        je      .done
1388
        shl     eax, 8
1378
        shl     eax, 8
1389
        mov     al, '.'
1379
        mov     al, '.'
1390
 
1380
 
1391
        lea     ebp, [ebp+ecx+1]
1381
        lea     ebp, [ebp+ecx+1]
1392
        mov     [ebp], eax
1382
        mov     [ebp], eax
1393
        mov     ecx, 3
1383
        mov     ecx, 3
1394
@@:
1384
@@:
1395
        rol     eax, 8
1385
        rol     eax, 8
1396
        cmp     al, ' '
1386
        cmp     al, ' '
1397
        jne     .done
1387
        jne     .done
1398
        loop    @b
1388
        loop    @b
1399
        dec     ebp
1389
        dec     ebp
1400
.done:
1390
.done:
1401
        and     byte [ebp+ecx+1], 0   ; CF=0
1391
        and     byte [ebp+ecx+1], 0   ; CF=0
1402
        pop     ebp edi ecx
1392
        pop     ebp edi ecx
1403
        ret
1393
        ret
1404
.unicode_short:
1394
.unicode_short:
1405
        mov     ecx, 8
1395
        mov     ecx, 8
1406
        push    ecx
1396
        push    ecx
1407
@@:
1397
@@:
1408
        mov     al, [edi]
1398
        mov     al, [edi]
1409
        inc     edi
1399
        inc     edi
1410
        call    ansi2uni_char
1400
        call    ansi2uni_char
1411
        mov     [ebp], ax
1401
        mov     [ebp], ax
1412
        inc     ebp
1402
        inc     ebp
1413
        inc     ebp
1403
        inc     ebp
1414
        loop    @b
1404
        loop    @b
1415
        pop     ecx
1405
        pop     ecx
1416
@@:
1406
@@:
1417
        cmp     word [ebp-2], ' '
1407
        cmp     word [ebp-2], ' '
1418
        jnz     @f
1408
        jnz     @f
1419
        dec     ebp
1409
        dec     ebp
1420
        dec     ebp
1410
        dec     ebp
1421
        loop    @b
1411
        loop    @b
1422
@@:
1412
@@:
1423
        mov     word [ebp], '.'
1413
        mov     word [ebp], '.'
1424
        inc     ebp
1414
        inc     ebp
1425
        inc     ebp
1415
        inc     ebp
1426
        mov     ecx, 3
1416
        mov     ecx, 3
1427
        push    ecx
1417
        push    ecx
1428
@@:
1418
@@:
1429
        mov     al, [edi]
1419
        mov     al, [edi]
1430
        inc     edi
1420
        inc     edi
1431
        call    ansi2uni_char
1421
        call    ansi2uni_char
1432
        mov     [ebp], ax
1422
        mov     [ebp], ax
1433
        inc     ebp
1423
        inc     ebp
1434
        inc     ebp
1424
        inc     ebp
1435
        loop    @b
1425
        loop    @b
1436
        pop     ecx
1426
        pop     ecx
1437
@@:
1427
@@:
1438
        cmp     word [ebp-2], ' '
1428
        cmp     word [ebp-2], ' '
1439
        jnz     @f
1429
        jnz     @f
1440
        dec     ebp
1430
        dec     ebp
1441
        dec     ebp
1431
        dec     ebp
1442
        loop    @b
1432
        loop    @b
1443
        dec     ebp
1433
        dec     ebp
1444
        dec     ebp
1434
        dec     ebp
1445
@@:
1435
@@:
1446
        and     word [ebp], 0   ; CF=0
1436
        and     word [ebp], 0   ; CF=0
1447
        pop     ebp edi ecx
1437
        pop     ebp edi ecx
1448
        ret
1438
        ret
1449
.longname:
1439
.longname:
1450
; LFN
1440
; LFN
1451
        mov     al, byte [edi]
1441
        mov     al, byte [edi]
1452
        and     eax, 0x3F
1442
        and     eax, 0x3F
1453
        dec     eax
1443
        dec     eax
1454
        cmp     al, 20
1444
        cmp     al, 20
1455
        jae     .no     ; ignore invalid entries
1445
        jae     .no     ; ignore invalid entries
1456
        mov     word [ebp+260*2], 0     ; force null-terminating for orphans
1446
        mov     word [ebp+260*2], 0     ; force null-terminating for orphans
1457
        imul    eax, 13*2
1447
        imul    eax, 13*2
1458
        add     ebp, eax
1448
        add     ebp, eax
1459
        test    byte [edi], 0x40
1449
        test    byte [edi], 0x40
1460
        jz      @f
1450
        jz      @f
1461
        mov     word [ebp+13*2], 0
1451
        mov     word [ebp+13*2], 0
1462
@@:
1452
@@:
1463
        push    eax
1453
        push    eax
1464
; now copy name from edi to ebp ...
1454
; now copy name from edi to ebp ...
1465
        mov     eax, [edi+1]
1455
        mov     eax, [edi+1]
1466
        mov     [ebp], eax      ; symbols 1,2
1456
        mov     [ebp], eax      ; symbols 1,2
1467
        mov     eax, [edi+5]
1457
        mov     eax, [edi+5]
1468
        mov     [ebp+4], eax    ; 3,4
1458
        mov     [ebp+4], eax    ; 3,4
1469
        mov     eax, [edi+9]
1459
        mov     eax, [edi+9]
1470
        mov     [ebp+8], ax     ; 5
1460
        mov     [ebp+8], ax     ; 5
1471
        mov     eax, [edi+14]
1461
        mov     eax, [edi+14]
1472
        mov     [ebp+10], eax   ; 6,7
1462
        mov     [ebp+10], eax   ; 6,7
1473
        mov     eax, [edi+18]
1463
        mov     eax, [edi+18]
1474
        mov     [ebp+14], eax   ; 8,9
1464
        mov     [ebp+14], eax   ; 8,9
1475
        mov     eax, [edi+22]
1465
        mov     eax, [edi+22]
1476
        mov     [ebp+18], eax   ; 10,11
1466
        mov     [ebp+18], eax   ; 10,11
1477
        mov     eax, [edi+28]
1467
        mov     eax, [edi+28]
1478
        mov     [ebp+22], eax   ; 12,13
1468
        mov     [ebp+22], eax   ; 12,13
1479
; ... done
1469
; ... done
1480
        pop     eax
1470
        pop     eax
1481
        sub     ebp, eax
1471
        sub     ebp, eax
1482
        test    eax, eax
1472
        test    eax, eax
1483
        jz      @f
1473
        jz      @f
1484
; if this is not first entry, more processing required
1474
; if this is not first entry, more processing required
1485
        stc
1475
        stc
1486
        ret
1476
        ret
1487
@@:
1477
@@:
1488
; if this is first entry:
1478
; if this is first entry:
1489
        test    byte [ebp-4], 1
1479
        test    byte [ebp-4], 1
1490
        jnz     .ret
1480
        jnz     .ret
1491
; buffer at ebp contains UNICODE name, convert it to ANSI
1481
; buffer at ebp contains UNICODE name, convert it to ANSI
1492
        push    esi edi
1482
        push    esi edi
1493
        mov     esi, ebp
1483
        mov     esi, ebp
1494
        mov     edi, ebp
1484
        mov     edi, ebp
1495
        call    uni2ansi_str
1485
        call    uni2ansi_str
1496
        pop     edi esi
1486
        pop     edi esi
1497
.ret:
1487
.ret:
1498
        clc
1488
        clc
1499
        ret
1489
        ret
1500
 
1490
 
1501
fat_compare_name:
1491
fat_compare_name:
1502
; compares ASCIIZ-names, case-insensitive (cp866 encoding)
1492
; compares ASCIIZ-names, case-insensitive (cp866 encoding)
1503
; in: esi->name, ebp->name
1493
; in: esi->name, ebp->name
1504
; out: if names match: ZF=1 and esi->next component of name
1494
; out: if names match: ZF=1 and esi->next component of name
1505
;      else: ZF=0, esi is not changed
1495
;      else: ZF=0, esi is not changed
1506
; destroys eax
1496
; destroys eax
1507
        push    ebp esi
1497
        push    ebp esi
1508
.loop:
1498
.loop:
1509
        mov     al, [ebp]
1499
        mov     al, [ebp]
1510
        inc     ebp
1500
        inc     ebp
1511
        call    char_toupper
1501
        call    char_toupper
1512
        push    eax
1502
        push    eax
1513
        lodsb
1503
        lodsb
1514
        call    char_toupper
1504
        call    char_toupper
1515
        cmp     al, [esp]
1505
        cmp     al, [esp]
1516
        jnz     .done
1506
        jnz     .done
1517
        pop     eax
1507
        pop     eax
1518
        test    al, al
1508
        test    al, al
1519
        jnz     .loop
1509
        jnz     .loop
1520
        dec     esi
1510
        dec     esi
1521
        pop     eax
1511
        pop     eax
1522
        pop     ebp
1512
        pop     ebp
1523
        xor     eax, eax        ; set ZF flag
1513
        xor     eax, eax        ; set ZF flag
1524
        ret
1514
        ret
1525
.done:
1515
.done:
1526
        cmp     al, '/'
1516
        cmp     al, '/'
1527
        jnz     @f
1517
        jnz     @f
1528
        cmp     byte [esp], 0
1518
        cmp     byte [esp], 0
1529
        jnz     @f
1519
        jnz     @f
1530
        mov     [esp+4], esi
1520
        mov     [esp+4], esi
1531
@@:
1521
@@:
1532
        pop     eax
1522
        pop     eax
1533
        pop     esi ebp
1523
        pop     esi ebp
1534
        ret
1524
        ret
1535
 
1525
 
1536
fat_find_lfn:
1526
fat_find_lfn:
1537
; in: esi->name
1527
; in: esi->name
1538
;     [esp+4] = next
1528
;     [esp+4] = next
1539
;     [esp+8] = first
1529
;     [esp+8] = first
1540
;     [esp+C]... - possibly parameters for first and next
1530
;     [esp+C]... - possibly parameters for first and next
1541
; out: CF=1 - file not found, eax=error code
1531
; out: CF=1 - file not found, eax=error code
1542
;      else CF=0, esi->next name component, edi->direntry
1532
;      else CF=0, esi->next name component, edi->direntry
1543
        pusha
1533
        pusha
1544
        lea     eax, [esp+0Ch+20h]
1534
        lea     eax, [esp+0Ch+20h]
1545
        call    dword [eax-4]
1535
        call    dword [eax-4]
1546
        jc      .reterr
1536
        jc      .reterr
1547
        sub     esp, 262*2      ; reserve place for LFN
1537
        sub     esp, 262*2      ; reserve place for LFN
1548
        push    0               ; for fat_get_name: read ASCII name
1538
        push    0               ; for fat_get_name: read ASCII name
1549
.l1:
1539
.l1:
1550
        lea     ebp, [esp+4]
1540
        lea     ebp, [esp+4]
1551
        call    fat_get_name
1541
        call    fat_get_name
1552
        jc      .l2
1542
        jc      .l2
1553
        call    fat_compare_name
1543
        call    fat_compare_name
1554
        jz      .found
1544
        jz      .found
1555
.l2:
1545
.l2:
1556
        mov     ebp, [esp+8+262*2+4]
1546
        mov     ebp, [esp+8+262*2+4]
1557
        lea     eax, [esp+0Ch+20h+262*2+4]
1547
        lea     eax, [esp+0Ch+20h+262*2+4]
1558
        call    dword [eax-8]
1548
        call    dword [eax-8]
1559
        jnc     .l1
1549
        jnc     .l1
1560
        add     esp, 262*2+4
1550
        add     esp, 262*2+4
1561
.reterr:
1551
.reterr:
1562
        mov     [esp+28], eax
1552
        mov     [esp+28], eax
1563
        stc
1553
        stc
1564
        popa
1554
        popa
1565
        ret
1555
        ret
1566
.found:
1556
.found:
1567
        add     esp, 262*2+4
1557
        add     esp, 262*2+4
1568
        mov     ebp, [esp+8]
1558
        mov     ebp, [esp+8]
1569
; if this is LFN entry, advance to true entry
1559
; if this is LFN entry, advance to true entry
1570
        cmp     byte [edi+11], 0xF
1560
        cmp     byte [edi+11], 0xF
1571
        jnz     @f
1561
        jnz     @f
1572
        lea     eax, [esp+0Ch+20h]
1562
        lea     eax, [esp+0Ch+20h]
1573
        call    dword [eax-8]
1563
        call    dword [eax-8]
1574
        jc      .reterr
1564
        jc      .reterr
1575
@@:
1565
@@:
1576
        add     esp, 8          ; CF=0
1566
        add     esp, 8          ; CF=0
1577
        push    esi
1567
        push    esi
1578
        push    edi
1568
        push    edi
1579
        popa
1569
        popa
1580
        ret
1570
        ret
1581
 
1571
 
1582
fat_time_to_bdfe:
1572
fat_time_to_bdfe:
1583
; in: eax=FAT time
1573
; in: eax=FAT time
1584
; out: eax=BDFE time
1574
; out: eax=BDFE time
1585
        push    ecx edx
1575
        push    ecx edx
1586
        mov     ecx, eax
1576
        mov     ecx, eax
1587
        mov     edx, eax
1577
        mov     edx, eax
1588
        shr     eax, 11
1578
        shr     eax, 11
1589
        shl     eax, 16 ; hours
1579
        shl     eax, 16 ; hours
1590
        and     edx, 0x1F
1580
        and     edx, 0x1F
1591
        add     edx, edx
1581
        add     edx, edx
1592
        mov     al, dl  ; seconds
1582
        mov     al, dl  ; seconds
1593
        shr     ecx, 5
1583
        shr     ecx, 5
1594
        and     ecx, 0x3F
1584
        and     ecx, 0x3F
1595
        mov     ah, cl  ; minutes
1585
        mov     ah, cl  ; minutes
1596
        pop     edx ecx
1586
        pop     edx ecx
1597
        ret
1587
        ret
1598
 
1588
 
1599
fat_date_to_bdfe:
1589
fat_date_to_bdfe:
1600
        push    ecx edx
1590
        push    ecx edx
1601
        mov     ecx, eax
1591
        mov     ecx, eax
1602
        mov     edx, eax
1592
        mov     edx, eax
1603
        shr     eax, 9
1593
        shr     eax, 9
1604
        add     ax, 1980
1594
        add     ax, 1980
1605
        shl     eax, 16 ; year
1595
        shl     eax, 16 ; year
1606
        and     edx, 0x1F
1596
        and     edx, 0x1F
1607
        mov     al, dl  ; day
1597
        mov     al, dl  ; day
1608
        shr     ecx, 5
1598
        shr     ecx, 5
1609
        and     ecx, 0xF
1599
        and     ecx, 0xF
1610
        mov     ah, cl  ; month
1600
        mov     ah, cl  ; month
1611
        pop     edx ecx
1601
        pop     edx ecx
1612
        ret
1602
        ret
1613
 
1603
 
1614
bdfe_to_fat_time:
1604
bdfe_to_fat_time:
1615
        push    edx
1605
        push    edx
1616
        mov     edx, eax
1606
        mov     edx, eax
1617
        shr     eax, 16
1607
        shr     eax, 16
1618
        and     dh, 0x3F
1608
        and     dh, 0x3F
1619
        shl     eax, 6
1609
        shl     eax, 6
1620
        or      al, dh
1610
        or      al, dh
1621
        shr     dl, 1
1611
        shr     dl, 1
1622
        and     dl, 0x1F
1612
        and     dl, 0x1F
1623
        shl     eax, 5
1613
        shl     eax, 5
1624
        or      al, dl
1614
        or      al, dl
1625
        pop     edx
1615
        pop     edx
1626
        ret
1616
        ret
1627
 
1617
 
1628
bdfe_to_fat_date:
1618
bdfe_to_fat_date:
1629
        push    edx
1619
        push    edx
1630
        mov     edx, eax
1620
        mov     edx, eax
1631
        shr     eax, 16
1621
        shr     eax, 16
1632
        sub     ax, 1980
1622
        sub     ax, 1980
1633
        and     dh, 0xF
1623
        and     dh, 0xF
1634
        shl     eax, 4
1624
        shl     eax, 4
1635
        or      al, dh
1625
        or      al, dh
1636
        and     dl, 0x1F
1626
        and     dl, 0x1F
1637
        shl     eax, 5
1627
        shl     eax, 5
1638
        or      al, dl
1628
        or      al, dl
1639
        pop     edx
1629
        pop     edx
1640
        ret
1630
        ret
1641
 
1631
 
1642
fat_entry_to_bdfe:
1632
fat_entry_to_bdfe:
1643
; convert FAT entry at edi to BDFE (block of data of folder entry) at esi, advance esi
1633
; convert FAT entry at edi to BDFE (block of data of folder entry) at esi, advance esi
1644
; destroys eax
1634
; destroys eax
1645
        mov     eax, [ebp-4]
1635
        mov     eax, [ebp-4]
1646
        mov     [esi+4], eax    ; ASCII/UNICODE name
1636
        mov     [esi+4], eax    ; ASCII/UNICODE name
1647
fat_entry_to_bdfe2:
1637
fat_entry_to_bdfe2:
1648
        movzx   eax, byte [edi+11]
1638
        movzx   eax, byte [edi+11]
1649
        mov     [esi], eax      ; attributes
1639
        mov     [esi], eax      ; attributes
1650
        movzx   eax, word [edi+14]
1640
        movzx   eax, word [edi+14]
1651
        call    fat_time_to_bdfe
1641
        call    fat_time_to_bdfe
1652
        mov     [esi+8], eax    ; creation time
1642
        mov     [esi+8], eax    ; creation time
1653
        movzx   eax, word [edi+16]
1643
        movzx   eax, word [edi+16]
1654
        call    fat_date_to_bdfe
1644
        call    fat_date_to_bdfe
1655
        mov     [esi+12], eax   ; creation date
1645
        mov     [esi+12], eax   ; creation date
1656
        and     dword [esi+16], 0       ; last access time is not supported on FAT
1646
        and     dword [esi+16], 0       ; last access time is not supported on FAT
1657
        movzx   eax, word [edi+18]
1647
        movzx   eax, word [edi+18]
1658
        call    fat_date_to_bdfe
1648
        call    fat_date_to_bdfe
1659
        mov     [esi+20], eax   ; last access date
1649
        mov     [esi+20], eax   ; last access date
1660
        movzx   eax, word [edi+22]
1650
        movzx   eax, word [edi+22]
1661
        call    fat_time_to_bdfe
1651
        call    fat_time_to_bdfe
1662
        mov     [esi+24], eax   ; last write time
1652
        mov     [esi+24], eax   ; last write time
1663
        movzx   eax, word [edi+24]
1653
        movzx   eax, word [edi+24]
1664
        call    fat_date_to_bdfe
1654
        call    fat_date_to_bdfe
1665
        mov     [esi+28], eax   ; last write date
1655
        mov     [esi+28], eax   ; last write date
1666
        mov     eax, [edi+28]
1656
        mov     eax, [edi+28]
1667
        mov     [esi+32], eax   ; file size (low dword)
1657
        mov     [esi+32], eax   ; file size (low dword)
1668
        xor     eax, eax
1658
        xor     eax, eax
1669
        mov     [esi+36], eax   ; file size (high dword)
1659
        mov     [esi+36], eax   ; file size (high dword)
1670
        test    ebp, ebp
1660
        test    ebp, ebp
1671
        jz      .ret
1661
        jz      .ret
1672
        push    ecx edi
1662
        push    ecx edi
1673
        lea     edi, [esi+40]
1663
        lea     edi, [esi+40]
1674
        mov     esi, ebp
1664
        mov     esi, ebp
1675
        test    byte [esi-4], 1
1665
        test    byte [esi-4], 1
1676
        jz      .ansi
1666
        jz      .ansi
1677
        mov     ecx, 260/2
1667
        mov     ecx, 260/2
1678
        rep movsd
1668
        rep movsd
1679
        mov     [edi-2], ax
1669
        mov     [edi-2], ax
1680
@@:
1670
@@:
1681
        mov     esi, edi
1671
        mov     esi, edi
1682
        pop     edi ecx
1672
        pop     edi ecx
1683
.ret:
1673
.ret:
1684
        ret
1674
        ret
1685
.ansi:
1675
.ansi:
1686
        mov     ecx, 264/4
1676
        mov     ecx, 264/4
1687
        rep movsd
1677
        rep movsd
1688
        mov     [edi-1], al
1678
        mov     [edi-1], al
1689
        jmp     @b
1679
        jmp     @b
1690
 
1680
 
1691
bdfe_to_fat_entry:
1681
bdfe_to_fat_entry:
1692
; convert BDFE at edx to FAT entry at edi
1682
; convert BDFE at edx to FAT entry at edi
1693
; destroys eax
1683
; destroys eax
1694
; attributes byte
1684
; attributes byte
1695
        test    byte [edi+11], 8        ; volume label?
1685
        test    byte [edi+11], 8        ; volume label?
1696
        jnz     @f
1686
        jnz     @f
1697
        mov     al, [edx]
1687
        mov     al, [edx]
1698
        and     al, 0x27
1688
        and     al, 0x27
1699
        and     byte [edi+11], 0x10
1689
        and     byte [edi+11], 0x10
1700
        or      byte [edi+11], al
1690
        or      byte [edi+11], al
1701
@@:
1691
@@:
1702
        mov     eax, [edx+8]
1692
        mov     eax, [edx+8]
1703
        call    bdfe_to_fat_time
1693
        call    bdfe_to_fat_time
1704
        mov     [edi+14], ax            ; creation time
1694
        mov     [edi+14], ax            ; creation time
1705
        mov     eax, [edx+12]
1695
        mov     eax, [edx+12]
1706
        call    bdfe_to_fat_date
1696
        call    bdfe_to_fat_date
1707
        mov     [edi+16], ax            ; creation date
1697
        mov     [edi+16], ax            ; creation date
1708
        mov     eax, [edx+20]
1698
        mov     eax, [edx+20]
1709
        call    bdfe_to_fat_date
1699
        call    bdfe_to_fat_date
1710
        mov     [edi+18], ax            ; last access date
1700
        mov     [edi+18], ax            ; last access date
1711
        mov     eax, [edx+24]
1701
        mov     eax, [edx+24]
1712
        call    bdfe_to_fat_time
1702
        call    bdfe_to_fat_time
1713
        mov     [edi+22], ax            ; last write time
1703
        mov     [edi+22], ax            ; last write time
1714
        mov     eax, [edx+28]
1704
        mov     eax, [edx+28]
1715
        call    bdfe_to_fat_date
1705
        call    bdfe_to_fat_date
1716
        mov     [edi+24], ax            ; last write date
1706
        mov     [edi+24], ax            ; last write date
1717
        ret
1707
        ret
1718
 
1708
 
1719
hd_find_lfn:
1709
hd_find_lfn:
1720
; in: ebp -> FAT structure
1710
; in: ebp -> FAT structure
1721
; in: esi+[esp+4] -> name
1711
; in: esi+[esp+4] -> name
1722
; out: CF=1 - file not found, eax=error code
1712
; out: CF=1 - file not found, eax=error code
1723
;      else CF=0 and edi->direntry, eax=sector
1713
;      else CF=0 and edi->direntry, eax=sector
1724
; destroys eax
1714
; destroys eax
1725
        push    esi edi
1715
        push    esi edi
1726
        push    0
1716
        push    0
1727
        push    0
1717
        push    0
1728
        push    fat1x_root_first
1718
        push    fat1x_root_first
1729
        push    fat1x_root_next
1719
        push    fat1x_root_next
1730
        mov     eax, [ebp+FAT.ROOT_CLUSTER]
1720
        mov     eax, [ebp+FAT.ROOT_CLUSTER]
1731
        cmp     [ebp+FAT.fs_type], 32
1721
        cmp     [ebp+FAT.fs_type], 32
1732
        jz      .fat32
1722
        jz      .fat32
1733
.loop:
1723
.loop:
1734
        and     [ebp+FAT.longname_sec1], 0
1724
        and     [ebp+FAT.longname_sec1], 0
1735
        and     [ebp+FAT.longname_sec2], 0
1725
        and     [ebp+FAT.longname_sec2], 0
1736
        call    fat_find_lfn
1726
        call    fat_find_lfn
1737
        jc      .notfound
1727
        jc      .notfound
1738
        cmp     byte [esi], 0
1728
        cmp     byte [esi], 0
1739
        jz      .found
1729
        jz      .found
1740
.continue:
1730
.continue:
1741
        test    byte [edi+11], 10h
1731
        test    byte [edi+11], 10h
1742
        jz      .notfound
1732
        jz      .notfound
1743
        and     dword [esp+12], 0
1733
        and     dword [esp+12], 0
1744
        mov     eax, [edi+20-2]
1734
        mov     eax, [edi+20-2]
1745
        mov     ax, [edi+26]    ; cluster
1735
        mov     ax, [edi+26]    ; cluster
1746
.fat32:
1736
.fat32:
1747
        mov     [esp+8], eax
1737
        mov     [esp+8], eax
1748
        mov     dword [esp+4], fat_notroot_first
1738
        mov     dword [esp+4], fat_notroot_first
1749
        mov     dword [esp], fat_notroot_next
1739
        mov     dword [esp], fat_notroot_next
1750
        jmp     .loop
1740
        jmp     .loop
1751
.notfound:
1741
.notfound:
1752
        add     esp, 16
1742
        add     esp, 16
1753
        pop     edi esi
1743
        pop     edi esi
1754
        stc
1744
        stc
1755
        ret     4
1745
        ret     4
1756
.found:
1746
.found:
1757
        lea     eax, [esp+4+24]
1747
        lea     eax, [esp+4+24]
1758
        cmp     dword [eax], 0
1748
        cmp     dword [eax], 0
1759
        jz      @f
1749
        jz      @f
1760
        mov     esi, [eax]
1750
        mov     esi, [eax]
1761
        and     dword [eax], 0
1751
        and     dword [eax], 0
1762
        jmp     .continue
1752
        jmp     .continue
1763
@@:
1753
@@:
1764
        lea     eax, [esp+8]
1754
        lea     eax, [esp+8]
1765
        cmp     dword [eax], 0
1755
        cmp     dword [eax], 0
1766
        jz      .root
1756
        jz      .root
1767
        call    fat_get_sector
1757
        call    fat_get_sector
1768
        jmp     .cmn
1758
        jmp     .cmn
1769
.root:
1759
.root:
1770
        mov     eax, [eax+4]
1760
        mov     eax, [eax+4]
1771
        add     eax, [ebp+FAT.ROOT_START]
1761
        add     eax, [ebp+FAT.ROOT_START]
1772
.cmn:
1762
.cmn:
1773
        add     esp, 20         ; CF=0
1763
        add     esp, 20         ; CF=0
1774
        pop     esi
1764
        pop     esi
1775
        ret     4
1765
        ret     4
1776
 
1766
 
1777
;----------------------------------------------------------------
1767
;----------------------------------------------------------------
1778
; fat_Read - FAT implementation of reading a file
1768
; fat_Read - FAT implementation of reading a file
1779
; in:  ebp = pointer to FAT structure
1769
; in:  ebp = pointer to FAT structure
1780
; in:  esi+[esp+4] = name
1770
; in:  esi+[esp+4] = name
1781
; in:  ebx = pointer to parameters from sysfunc 70
1771
; in:  ebx = pointer to parameters from sysfunc 70
1782
; out: eax, ebx = return values for sysfunc 70
1772
; out: eax, ebx = return values for sysfunc 70
1783
;----------------------------------------------------------------
1773
;----------------------------------------------------------------
1784
fat_Read:
1774
fat_Read:
1785
        call    fat_lock
1775
        call    fat_lock
1786
        push    edi
1776
        push    edi
1787
        cmp     byte [esi], 0
1777
        cmp     byte [esi], 0
1788
        jnz     @f
1778
        jnz     @f
1789
.noaccess:
1779
.noaccess:
1790
        pop     edi
1780
        pop     edi
1791
.noaccess_2:
-
 
1792
        call    fat_unlock
1781
        call    fat_unlock
1793
        or      ebx, -1
1782
        or      ebx, -1
1794
        mov     eax, ERROR_ACCESS_DENIED
1783
        mov     eax, ERROR_ACCESS_DENIED
1795
        ret
1784
        ret
1796
 
-
 
1797
@@:
1785
@@:
1798
        stdcall hd_find_lfn, [esp+4+4]
1786
        stdcall hd_find_lfn, [esp+8]
1799
        jnc     .found
1787
        jnc     .found
1800
        pop     edi
1788
        pop     edi
1801
        push    eax
1789
        push    eax
1802
        call    fat_unlock
1790
        call    fat_unlock
1803
        pop     eax
1791
        pop     eax
1804
        or      ebx, -1
1792
        or      ebx, -1
1805
        ret
1793
        ret
1806
 
-
 
1807
.found:
1794
.found:
1808
        test    byte [edi+11], 0x10; do not allow read directories
1795
        test    byte [edi+11], 0x10     ; do not allow read directories
1809
        jnz     .noaccess
1796
        jnz     .noaccess
1810
        cmp     dword [ebx+8], 0
1797
        cmp     dword [ebx+8], 0
1811
        jz      @f
1798
        jz      @f
1812
        xor     ebx, ebx
1799
        xor     ebx, ebx
1813
.reteof:
-
 
1814
        call    fat_unlock
1800
        call    fat_unlock
1815
        mov     eax, ERROR_END_OF_FILE
1801
        mov     eax, ERROR_END_OF_FILE
1816
        pop     edi
1802
        pop     edi
1817
        ret
1803
        ret
1818
@@:
1804
@@:
-
 
1805
        mov     edx, [ebx+4]    ; file offset
1819
        mov     ecx, [ebx+12]   ; size
1806
        mov     ecx, [ebx+12]   ; size
1820
        mov     edx, [ebx+16]   ; pointer
1807
        mov     ebx, [ebx+16]   ; buffer
1821
        mov     ebx, [ebx+4]    ; file offset
-
 
1822
        push    edx
1808
        push    ebx
1823
        push    0
1809
        push    0
1824
        mov     eax, [edi+28]
1810
        mov     eax, [edi+28]
1825
        sub     eax, ebx
1811
        sub     eax, edx
1826
        jb      .eof
1812
        jb      .fileEnd
1827
        cmp     eax, ecx
1813
        cmp     eax, ecx
1828
        jae     @f
1814
        jae     @f
1829
        mov     ecx, eax
1815
        mov     ecx, eax
1830
        mov     byte [esp], 6
1816
        mov     byte [esp], 6
1831
@@:
1817
@@:
1832
        mov     eax, [edi+20-2]
1818
        mov     eax, [edi+20-2]
1833
        mov     ax, [edi+26]
1819
        mov     ax, [edi+26]
1834
; now eax=cluster, ebx=position, ecx=count, edx=buffer for data
1820
; now eax=cluster, ebx=buffer for data, ecx=count, edx=position
1835
.new_cluster:
1821
        mov     edi, [ebp+FAT.SECTORS_PER_CLUSTER]
1836
        jecxz   .new_sector
1822
        shl     edi, 9
-
 
1823
@@:
1837
        cmp     eax, 2
1824
        cmp     eax, 2
1838
        jb      .eof
1825
        jb      .fileEnd
1839
        cmp     eax, [ebp+FAT.fatRESERVED]
1826
        cmp     eax, [ebp+FAT.fatRESERVED]
-
 
1827
        jae     .fileEnd
-
 
1828
        sub     edx, edi
1840
        jae     .eof
1829
        jc      @f
-
 
1830
        call    get_FAT
-
 
1831
        jc      .noaccess2
-
 
1832
        jmp     @b
-
 
1833
@@:
1841
        mov     [ebp+FAT.cluster_tmp], eax
1834
        mov     esi, eax
1842
        dec     eax
1835
        dec     eax
1843
        dec     eax
1836
        dec     eax
1844
        mov     edi, [ebp+FAT.SECTORS_PER_CLUSTER]
1837
        imul    eax, [ebp+FAT.SECTORS_PER_CLUSTER]
1845
        imul    eax, edi
-
 
1846
        add     eax, [ebp+FAT.DATA_START]
1838
        add     eax, [ebp+FAT.DATA_START]
1847
.new_sector:
-
 
1848
        test    ecx, ecx
-
 
1849
        jz      .done
-
 
1850
        sub     ebx, 512
-
 
1851
        jae     .skip
-
 
1852
        add     ebx, 512
1839
        add     edx, edi
1853
        jnz     .force_buf
-
 
1854
        cmp     ecx, 512
-
 
1855
        jb      .force_buf
1840
        jz      .alignedCluster
1856
; we may read directly to given buffer
-
 
1857
        push    eax ebx
-
 
1858
        mov     ebx, edx
1841
        mov     edi, edx
1859
        call    fs_read32_app
-
 
1860
        test    eax, eax
1842
        shr     edi, 9
1861
        pop     ebx eax
-
 
1862
        jne     .noaccess_1
-
 
1863
        add     edx, 512
1843
        add     eax, edi
1864
        sub     ecx, 512
1844
        and     edx, 511
1865
        jmp     .skip
1845
        jz      .alignedSector
1866
.force_buf:
1846
.sectorPiece:
1867
; we must read sector to temporary buffer and then copy it to destination
-
 
1868
        push    eax ebx
1847
        push    eax ebx
1869
        lea     ebx, [ebp+FAT.buffer]
1848
        lea     ebx, [ebp+FAT.buffer]
1870
        call    fs_read32_app
1849
        call    fs_read32_app
1871
        test    eax, eax
1850
        test    eax, eax
1872
        mov     eax, ebx
1851
        mov     eax, ebx
1873
        pop     ebx
1852
        pop     ebx
1874
        jne     .noaccess_3
1853
        jne     .noaccess3
1875
        add     eax, ebx
1854
        add     eax, edx
1876
        push    ecx
1855
        push    ecx
1877
        add     ecx, ebx
1856
        add     ecx, edx
1878
        cmp     ecx, 512
1857
        cmp     ecx, 512
1879
        jbe     @f
1858
        jbe     @f
1880
        mov     ecx, 512
1859
        mov     ecx, 512
1881
@@:
1860
@@:
1882
        sub     ecx, ebx
1861
        sub     ecx, edx
1883
        mov     ebx, edx
-
 
1884
        call    memmove
1862
        call    memmove
1885
        add     edx, ecx
-
 
1886
        sub     [esp], ecx
1863
        sub     [esp], ecx
1887
        pop     ecx
1864
        add     ebx, ecx
1888
        pop     eax
1865
        pop     ecx eax
1889
        xor     ebx, ebx
1866
        xor     edx, edx
1890
.skip:
1867
        inc     edi
1891
        inc     eax
1868
        inc     eax
-
 
1869
        test    ecx, ecx
1892
        dec     edi
1870
        jz      .done
-
 
1871
.alignedSector:
-
 
1872
        cmp     ecx, 512
1893
        jnz     .new_sector
1873
        jc      .sectorPiece
-
 
1874
        shl     edi, 9
-
 
1875
        add     ecx, edi
1894
        mov     eax, [ebp+FAT.cluster_tmp]
1876
        mov     edi, [ebp+FAT.SECTORS_PER_CLUSTER]
-
 
1877
        shl     edi, 9
-
 
1878
.alignedCluster:
-
 
1879
        cmp     ecx, 512
-
 
1880
        jc      .sectorPiece
-
 
1881
        mov     edx, eax
-
 
1882
        mov     eax, esi
-
 
1883
@@:
-
 
1884
        sub     ecx, edi
-
 
1885
        jbe     .readEnd
1895
        call    get_FAT
1886
        call    get_FAT
1896
        jc      .noaccess_1
1887
        jc      .noaccess4
1897
 
-
 
-
 
1888
        cmp     eax, 2
-
 
1889
        jb      .fileEnd2
-
 
1890
        cmp     eax, [ebp+FAT.fatRESERVED]
-
 
1891
        jae     .fileEnd2
-
 
1892
        inc     esi
1898
        jmp     .new_cluster
1893
        cmp     eax, esi
-
 
1894
        jz      @b
1899
.noaccess_3:
1895
.fragmentEnd:
-
 
1896
        xchg    eax, esi
-
 
1897
        dec     eax
-
 
1898
        dec     eax
-
 
1899
        imul    eax, [ebp+FAT.SECTORS_PER_CLUSTER]
-
 
1900
        add     eax, [ebp+FAT.DATA_START]
-
 
1901
        sub     eax, edx
-
 
1902
.readFragment:
-
 
1903
        push    ecx
-
 
1904
        mov     ecx, eax
-
 
1905
        mov     eax, edx
-
 
1906
        xor     edx, edx
-
 
1907
        push    eax
-
 
1908
        call    fs_read64_app
-
 
1909
        add     [esp], ecx
-
 
1910
        shl     ecx, 9
-
 
1911
        add     ebx, ecx
-
 
1912
        test    eax, eax
1900
        pop     eax
1913
        pop     eax
-
 
1914
        jnz     .noaccess3
-
 
1915
        pop     ecx
-
 
1916
        xor     edx, edx
-
 
1917
        jcxz    .done
-
 
1918
        cmp     ecx, 512
-
 
1919
        jc      .sectorPiece
-
 
1920
        mov     eax, esi
-
 
1921
        dec     eax
-
 
1922
        dec     eax
-
 
1923
        imul    eax, [ebp+FAT.SECTORS_PER_CLUSTER]
-
 
1924
        add     eax, [ebp+FAT.DATA_START]
-
 
1925
        jmp     .alignedCluster
-
 
1926
.readEnd:
-
 
1927
        add     ecx, edi
-
 
1928
        mov     edi, ecx
-
 
1929
        and     ecx, 511
-
 
1930
        shr     edi, 9
-
 
1931
        dec     eax
-
 
1932
        dec     eax
-
 
1933
        imul    eax, [ebp+FAT.SECTORS_PER_CLUSTER]
-
 
1934
        add     eax, [ebp+FAT.DATA_START]
-
 
1935
        sub     eax, edx
-
 
1936
        add     eax, edi
-
 
1937
        jmp     .readFragment
1901
.noaccess_1:
1938
.noaccess3:
1902
        pop     eax
1939
        pop     eax
-
 
1940
.noaccess2:
1903
        push    ERROR_DEVICE
1941
        mov     byte [esp], ERROR_DEVICE
1904
.done:
1942
.done:
1905
        mov     ebx, edx
-
 
1906
        call    fat_unlock
1943
        call    fat_unlock
1907
        pop     eax edx edi
1944
        pop     eax edx edi
1908
        sub     ebx, edx
1945
        sub     ebx, edx
1909
        ret
1946
        ret
1910
.eof:
1947
.fileEnd:
-
 
1948
        mov     byte [esp], ERROR_END_OF_FILE
1911
        mov     ebx, edx
1949
        jmp     .done
-
 
1950
.noaccess4:
-
 
1951
        mov     byte [esp], ERROR_DEVICE
-
 
1952
        jmp     @f
-
 
1953
.fileEnd2:
-
 
1954
        mov     byte [esp], ERROR_END_OF_FILE
-
 
1955
@@:
1912
        pop     eax edx
1956
        inc     esi
1913
        sub     ebx, edx
1957
        xor     ecx, ecx
1914
        jmp     .reteof
1958
        jmp     .fragmentEnd
1915
 
1959
 
1916
;----------------------------------------------------------------
1960
;----------------------------------------------------------------
1917
; fat_ReadFolder - FAT implementation of reading a folder
1961
; fat_ReadFolder - FAT implementation of reading a folder
1918
; in:  ebp = pointer to FAT structure
1962
; in:  ebp = pointer to FAT structure
1919
; in:  esi+[esp+4] = name
1963
; in:  esi+[esp+4] = name
1920
; in:  ebx = pointer to parameters from sysfunc 70
1964
; in:  ebx = pointer to parameters from sysfunc 70
1921
; out: eax, ebx = return values for sysfunc 70
1965
; out: eax, ebx = return values for sysfunc 70
1922
;----------------------------------------------------------------
1966
;----------------------------------------------------------------
1923
fat_ReadFolder:
1967
fat_ReadFolder:
1924
        call    fat_lock
1968
        call    fat_lock
1925
        mov     eax, [ebp+FAT.ROOT_CLUSTER]
1969
        mov     eax, [ebp+FAT.ROOT_CLUSTER]
1926
        push    edi
1970
        push    edi
1927
        cmp     byte [esi], 0
1971
        cmp     byte [esi], 0
1928
        jz      .doit
1972
        jz      .doit
1929
        stdcall hd_find_lfn, [esp+4+4]
1973
        stdcall hd_find_lfn, [esp+4+4]
1930
        jnc     .found
1974
        jnc     .found
1931
        pop     edi
1975
        pop     edi
1932
        push    eax
1976
        push    eax
1933
        call    fat_unlock
1977
        call    fat_unlock
1934
        pop     eax
1978
        pop     eax
1935
        or      ebx, -1
1979
        or      ebx, -1
1936
        ret
1980
        ret
1937
.found:
1981
.found:
1938
        test    byte [edi+11], 0x10     ; do not allow read files
1982
        test    byte [edi+11], 0x10     ; do not allow read files
1939
        jnz     .found_dir
1983
        jnz     .found_dir
1940
        pop     edi
1984
        pop     edi
1941
        call    fat_unlock
1985
        call    fat_unlock
1942
        or      ebx, -1
1986
        or      ebx, -1
1943
        mov     eax, ERROR_ACCESS_DENIED
1987
        mov     eax, ERROR_ACCESS_DENIED
1944
        ret
1988
        ret
1945
.found_dir:
1989
.found_dir:
1946
        mov     eax, [edi+20-2]
1990
        mov     eax, [edi+20-2]
1947
        mov     ax, [edi+26]    ; eax=cluster
1991
        mov     ax, [edi+26]    ; eax=cluster
1948
.doit:
1992
.doit:
1949
        push    esi
1993
        push    esi
1950
        sub     esp, 262*2      ; reserve space for LFN
1994
        sub     esp, 262*2      ; reserve space for LFN
1951
        push    dword [ebx+8]   ; for fat_get_name: read ANSI/UNICODE name
1995
        push    dword [ebx+8]   ; for fat_get_name: read ANSI/UNICODE name
1952
        mov     edx, [ebx+16]   ; pointer to buffer
1996
        mov     edx, [ebx+16]   ; pointer to buffer
1953
; init header
1997
; init header
1954
        push    eax
1998
        push    eax
1955
        mov     edi, edx
1999
        mov     edi, edx
1956
        mov     ecx, 32/4
2000
        mov     ecx, 32/4
1957
        xor     eax, eax
2001
        xor     eax, eax
1958
        rep stosd
2002
        rep stosd
1959
        pop     eax
2003
        pop     eax
1960
        mov     byte [edx], 1   ; version
2004
        mov     byte [edx], 1   ; version
1961
        mov     esi, edi        ; esi points to BDFE
2005
        mov     esi, edi        ; esi points to BDFE
1962
        mov     ecx, [ebx+12]   ; number of blocks to read
2006
        mov     ecx, [ebx+12]   ; number of blocks to read
1963
        mov     ebx, [ebx+4]    ; index of the first block
2007
        mov     ebx, [ebx+4]    ; index of the first block
1964
.new_cluster:
2008
.new_cluster:
1965
        mov     [ebp+FAT.cluster_tmp], eax
2009
        mov     [ebp+FAT.cluster_tmp], eax
1966
        test    eax, eax
2010
        test    eax, eax
1967
        jnz     @f
2011
        jnz     @f
1968
        cmp     [ebp+FAT.fs_type], 32
2012
        cmp     [ebp+FAT.fs_type], 32
1969
        jz      .notfound
2013
        jz      .notfound
1970
        mov     eax, [ebp+FAT.ROOT_START]
2014
        mov     eax, [ebp+FAT.ROOT_START]
1971
        push    [ebp+FAT.ROOT_SECTORS]
2015
        push    [ebp+FAT.ROOT_SECTORS]
1972
        push    ebx
2016
        push    ebx
1973
        jmp     .new_sector
2017
        jmp     .new_sector
1974
@@:
2018
@@:
1975
        dec     eax
2019
        dec     eax
1976
        dec     eax
2020
        dec     eax
1977
        imul    eax, [ebp+FAT.SECTORS_PER_CLUSTER]
2021
        imul    eax, [ebp+FAT.SECTORS_PER_CLUSTER]
1978
        push    [ebp+FAT.SECTORS_PER_CLUSTER]
2022
        push    [ebp+FAT.SECTORS_PER_CLUSTER]
1979
        add     eax, [ebp+FAT.DATA_START]
2023
        add     eax, [ebp+FAT.DATA_START]
1980
        push    ebx
2024
        push    ebx
1981
.new_sector:
2025
.new_sector:
1982
        lea     ebx, [ebp+FAT.buffer]
2026
        lea     ebx, [ebp+FAT.buffer]
1983
        mov     edi, ebx
2027
        mov     edi, ebx
1984
        push    eax
2028
        push    eax
1985
        call    fs_read32_sys
2029
        call    fs_read32_sys
1986
        test    eax, eax
2030
        test    eax, eax
1987
        pop     eax
2031
        pop     eax
1988
        jnz     .notfound2
2032
        jnz     .notfound2
1989
        add     ebx, 512
2033
        add     ebx, 512
1990
        push    eax
2034
        push    eax
1991
.l1:
2035
.l1:
1992
        push    ebp
2036
        push    ebp
1993
        lea     ebp, [esp+20]
2037
        lea     ebp, [esp+20]
1994
        call    fat_get_name
2038
        call    fat_get_name
1995
        pop     ebp
2039
        pop     ebp
1996
        jc      .l2
2040
        jc      .l2
1997
        cmp     byte [edi+11], 0xF
2041
        cmp     byte [edi+11], 0xF
1998
        jnz     .do_bdfe
2042
        jnz     .do_bdfe
1999
        add     edi, 0x20
2043
        add     edi, 0x20
2000
        cmp     edi, ebx
2044
        cmp     edi, ebx
2001
        jb      .do_bdfe
2045
        jb      .do_bdfe
2002
        pop     eax
2046
        pop     eax
2003
        inc     eax
2047
        inc     eax
2004
        dec     dword [esp+4]
2048
        dec     dword [esp+4]
2005
        jnz     @f
2049
        jnz     @f
2006
        mov     eax, [ebp+FAT.cluster_tmp]
2050
        mov     eax, [ebp+FAT.cluster_tmp]
2007
        test    eax, eax
2051
        test    eax, eax
2008
        jz      .done
2052
        jz      .done
2009
        call    get_FAT
2053
        call    get_FAT
2010
        jc      .notfound2
2054
        jc      .notfound2
2011
        cmp     eax, 2
2055
        cmp     eax, 2
2012
        jb      .done
2056
        jb      .done
2013
        cmp     eax, [ebp+FAT.fatRESERVED]
2057
        cmp     eax, [ebp+FAT.fatRESERVED]
2014
        jae     .done
2058
        jae     .done
2015
        push    eax
2059
        push    eax
2016
        mov     eax, [ebp+FAT.SECTORS_PER_CLUSTER]
2060
        mov     eax, [ebp+FAT.SECTORS_PER_CLUSTER]
2017
        mov     [esp+8], eax
2061
        mov     [esp+8], eax
2018
        pop     eax
2062
        pop     eax
2019
        mov     [ebp+FAT.cluster_tmp], eax
2063
        mov     [ebp+FAT.cluster_tmp], eax
2020
        dec     eax
2064
        dec     eax
2021
        dec     eax
2065
        dec     eax
2022
        imul    eax, [ebp+FAT.SECTORS_PER_CLUSTER]
2066
        imul    eax, [ebp+FAT.SECTORS_PER_CLUSTER]
2023
        add     eax, [ebp+FAT.DATA_START]
2067
        add     eax, [ebp+FAT.DATA_START]
2024
@@:
2068
@@:
2025
        lea     ebx, [ebp+FAT.buffer]
2069
        lea     ebx, [ebp+FAT.buffer]
2026
        mov     edi, ebx
2070
        mov     edi, ebx
2027
        push    eax
2071
        push    eax
2028
        call    fs_read32_sys
2072
        call    fs_read32_sys
2029
        test    eax, eax
2073
        test    eax, eax
2030
        pop     eax
2074
        pop     eax
2031
        jnz     .notfound2
2075
        jnz     .notfound2
2032
        add     ebx, 512
2076
        add     ebx, 512
2033
        push    eax
2077
        push    eax
2034
.do_bdfe:
2078
.do_bdfe:
2035
        inc     dword [edx+8]   ; new file found
2079
        inc     dword [edx+8]   ; new file found
2036
        dec     dword [esp+4]
2080
        dec     dword [esp+4]
2037
        jns     .l2
2081
        jns     .l2
2038
        dec     ecx
2082
        dec     ecx
2039
        js      .l2
2083
        js      .l2
2040
        inc     dword [edx+4]   ; new file block copied
2084
        inc     dword [edx+4]   ; new file block copied
2041
        push    ebp
2085
        push    ebp
2042
        lea     ebp, [esp+20]
2086
        lea     ebp, [esp+20]
2043
        call    fat_entry_to_bdfe
2087
        call    fat_entry_to_bdfe
2044
        pop     ebp
2088
        pop     ebp
2045
.l2:
2089
.l2:
2046
        add     edi, 0x20
2090
        add     edi, 0x20
2047
        cmp     edi, ebx
2091
        cmp     edi, ebx
2048
        jb      .l1
2092
        jb      .l1
2049
        pop     eax
2093
        pop     eax
2050
        inc     eax
2094
        inc     eax
2051
        dec     dword [esp+4]
2095
        dec     dword [esp+4]
2052
        jnz     .new_sector
2096
        jnz     .new_sector
2053
        mov     eax, [ebp+FAT.cluster_tmp]
2097
        mov     eax, [ebp+FAT.cluster_tmp]
2054
        test    eax, eax
2098
        test    eax, eax
2055
        jz      .done
2099
        jz      .done
2056
        call    get_FAT
2100
        call    get_FAT
2057
        jc      .notfound2
2101
        jc      .notfound2
2058
        cmp     eax, 2
2102
        cmp     eax, 2
2059
        jb      .done
2103
        jb      .done
2060
        cmp     eax, [ebp+FAT.fatRESERVED]
2104
        cmp     eax, [ebp+FAT.fatRESERVED]
2061
        jae     .done
2105
        jae     .done
2062
        push    eax
2106
        push    eax
2063
        mov     eax, [ebp+FAT.SECTORS_PER_CLUSTER]
2107
        mov     eax, [ebp+FAT.SECTORS_PER_CLUSTER]
2064
        mov     [esp+8], eax
2108
        mov     [esp+8], eax
2065
        pop     eax
2109
        pop     eax
2066
        pop     ebx
2110
        pop     ebx
2067
        add     esp, 4
2111
        add     esp, 4
2068
        jmp     .new_cluster
2112
        jmp     .new_cluster
2069
.notfound2:
2113
.notfound2:
2070
        add     esp, 8
2114
        add     esp, 8
2071
.notfound:
2115
.notfound:
2072
        add     esp, 262*2+4
2116
        add     esp, 262*2+4
2073
        pop     esi edi
2117
        pop     esi edi
2074
        mov     ebx, [edx+4]
2118
        mov     ebx, [edx+4]
2075
        call    fat_unlock
2119
        call    fat_unlock
2076
        mov     eax, ERROR_DEVICE
2120
        mov     eax, ERROR_DEVICE
2077
        ret
2121
        ret
2078
.done:
2122
.done:
2079
        add     esp, 262*2+4+8
2123
        add     esp, 262*2+4+8
2080
        mov     ebx, [edx+4]
2124
        mov     ebx, [edx+4]
2081
        xor     eax, eax
2125
        xor     eax, eax
2082
        dec     ecx
2126
        dec     ecx
2083
        js      @f
2127
        js      @f
2084
        mov     al, ERROR_END_OF_FILE
2128
        mov     al, ERROR_END_OF_FILE
2085
@@:
2129
@@:
2086
        push    eax
2130
        push    eax
2087
        call    fat_unlock
2131
        call    fat_unlock
2088
        pop     eax
2132
        pop     eax
2089
        pop     esi edi
2133
        pop     esi edi
2090
        ret
2134
        ret
2091
 
2135
 
2092
fat1x_root_next:
2136
fat1x_root_next:
2093
        push    ecx
2137
        push    ecx
2094
        lea     ecx, [ebp+FAT.buffer+0x200-0x20]
2138
        lea     ecx, [ebp+FAT.buffer+0x200-0x20]
2095
        cmp     edi, ecx
2139
        cmp     edi, ecx
2096
        jae     fat1x_root_next_sector
2140
        jae     fat1x_root_next_sector
2097
        pop     ecx
2141
        pop     ecx
2098
        add     edi, 0x20
2142
        add     edi, 0x20
2099
        ret     ; CF=0
2143
        ret     ; CF=0
2100
fat1x_root_next_sector:
2144
fat1x_root_next_sector:
2101
; read next sector
2145
; read next sector
2102
        push    [ebp+FAT.longname_sec2]
2146
        push    [ebp+FAT.longname_sec2]
2103
        pop     [ebp+FAT.longname_sec1]
2147
        pop     [ebp+FAT.longname_sec1]
2104
        mov     ecx, [eax+4]
2148
        mov     ecx, [eax+4]
2105
        push    ecx
2149
        push    ecx
2106
        add     ecx, [ebp+FAT.ROOT_START]
2150
        add     ecx, [ebp+FAT.ROOT_START]
2107
        mov     [ebp+FAT.longname_sec2], ecx
2151
        mov     [ebp+FAT.longname_sec2], ecx
2108
        pop     ecx
2152
        pop     ecx
2109
        inc     ecx
2153
        inc     ecx
2110
        mov     [eax+4], ecx
2154
        mov     [eax+4], ecx
2111
        cmp     ecx, [ebp+FAT.ROOT_SECTORS]
2155
        cmp     ecx, [ebp+FAT.ROOT_SECTORS]
2112
        pop     ecx
2156
        pop     ecx
2113
        jb      fat1x_root_first
2157
        jb      fat1x_root_first
2114
        mov     eax, ERROR_FILE_NOT_FOUND
2158
        mov     eax, ERROR_FILE_NOT_FOUND
2115
        stc
2159
        stc
2116
        ret
2160
        ret
2117
fat1x_root_first:
2161
fat1x_root_first:
2118
        mov     eax, [eax+4]
2162
        mov     eax, [eax+4]
2119
        add     eax, [ebp+FAT.ROOT_START]
2163
        add     eax, [ebp+FAT.ROOT_START]
2120
        push    ebx
2164
        push    ebx
2121
        lea     edi, [ebp+FAT.buffer]
2165
        lea     edi, [ebp+FAT.buffer]
2122
        mov     ebx, edi
2166
        mov     ebx, edi
2123
        call    fs_read32_sys
2167
        call    fs_read32_sys
2124
        pop     ebx
2168
        pop     ebx
2125
        test    eax, eax
2169
        test    eax, eax
2126
        jnz     .readerr
2170
        jnz     .readerr
2127
        ret     ; CF=0
2171
        ret     ; CF=0
2128
.readerr:
2172
.readerr:
2129
        mov     eax, ERROR_DEVICE
2173
        mov     eax, ERROR_DEVICE
2130
        stc
2174
        stc
2131
        ret
2175
        ret
2132
.notfound:
2176
.notfound:
2133
        mov     eax, ERROR_FILE_NOT_FOUND
2177
        mov     eax, ERROR_FILE_NOT_FOUND
2134
        stc
2178
        stc
2135
        ret
2179
        ret
2136
fat1x_root_begin_write:
2180
fat1x_root_begin_write:
2137
        push    edi eax
2181
        push    edi eax
2138
        call    fat1x_root_first
2182
        call    fat1x_root_first
2139
        pop     eax edi
2183
        pop     eax edi
2140
        ret
2184
        ret
2141
fat1x_root_end_write:
2185
fat1x_root_end_write:
2142
        pusha
2186
        pusha
2143
        mov     eax, [eax+4]
2187
        mov     eax, [eax+4]
2144
        add     eax, [ebp+FAT.ROOT_START]
2188
        add     eax, [ebp+FAT.ROOT_START]
2145
        lea     ebx, [ebp+FAT.buffer]
2189
        lea     ebx, [ebp+FAT.buffer]
2146
        call    fs_write32_sys
2190
        call    fs_write32_sys
2147
        popa
2191
        popa
2148
        ret
2192
        ret
2149
fat1x_root_next_write:
2193
fat1x_root_next_write:
2150
        push    ecx
2194
        push    ecx
2151
        lea     ecx, [ebp+FAT.buffer+0x200]
2195
        lea     ecx, [ebp+FAT.buffer+0x200]
2152
        cmp     edi, ecx
2196
        cmp     edi, ecx
2153
        jae     @f
2197
        jae     @f
2154
        pop     ecx
2198
        pop     ecx
2155
        ret
2199
        ret
2156
@@:
2200
@@:
2157
        call    fat1x_root_end_write
2201
        call    fat1x_root_end_write
2158
        jmp     fat1x_root_next_sector
2202
        jmp     fat1x_root_next_sector
2159
fat1x_root_extend_dir:
2203
fat1x_root_extend_dir:
2160
        stc
2204
        stc
2161
        ret
2205
        ret
2162
 
2206
 
2163
fat_notroot_next:
2207
fat_notroot_next:
2164
        push    ecx
2208
        push    ecx
2165
        lea     ecx, [ebp+FAT.buffer+0x200-0x20]
2209
        lea     ecx, [ebp+FAT.buffer+0x200-0x20]
2166
        cmp     edi, ecx
2210
        cmp     edi, ecx
2167
        jae     fat_notroot_next_sector
2211
        jae     fat_notroot_next_sector
2168
        pop     ecx
2212
        pop     ecx
2169
        add     edi, 0x20
2213
        add     edi, 0x20
2170
        ret     ; CF=0
2214
        ret     ; CF=0
2171
fat_notroot_next_sector:
2215
fat_notroot_next_sector:
2172
        push    [ebp+FAT.longname_sec2]
2216
        push    [ebp+FAT.longname_sec2]
2173
        pop     [ebp+FAT.longname_sec1]
2217
        pop     [ebp+FAT.longname_sec1]
2174
        push    eax
2218
        push    eax
2175
        call    fat_get_sector
2219
        call    fat_get_sector
2176
        mov     [ebp+FAT.longname_sec2], eax
2220
        mov     [ebp+FAT.longname_sec2], eax
2177
        pop     eax
2221
        pop     eax
2178
        mov     ecx, [eax+4]
2222
        mov     ecx, [eax+4]
2179
        inc     ecx
2223
        inc     ecx
2180
        cmp     ecx, [ebp+FAT.SECTORS_PER_CLUSTER]
2224
        cmp     ecx, [ebp+FAT.SECTORS_PER_CLUSTER]
2181
        jae     fat_notroot_next_cluster
2225
        jae     fat_notroot_next_cluster
2182
        mov     [eax+4], ecx
2226
        mov     [eax+4], ecx
2183
        jmp     @f
2227
        jmp     @f
2184
fat_notroot_next_cluster:
2228
fat_notroot_next_cluster:
2185
        push    eax
2229
        push    eax
2186
        mov     eax, [eax]
2230
        mov     eax, [eax]
2187
        call    get_FAT
2231
        call    get_FAT
2188
        mov     ecx, eax
2232
        mov     ecx, eax
2189
        pop     eax
2233
        pop     eax
2190
        jc      fat_notroot_first.deverr
2234
        jc      fat_notroot_first.deverr
2191
        cmp     ecx, 2
2235
        cmp     ecx, 2
2192
        jb      fat_notroot_next_err
2236
        jb      fat_notroot_next_err
2193
        cmp     ecx, [ebp+FAT.fatRESERVED]
2237
        cmp     ecx, [ebp+FAT.fatRESERVED]
2194
        jae     fat_notroot_next_err
2238
        jae     fat_notroot_next_err
2195
        mov     [eax], ecx
2239
        mov     [eax], ecx
2196
        and     dword [eax+4], 0
2240
        and     dword [eax+4], 0
2197
@@:
2241
@@:
2198
        pop     ecx
2242
        pop     ecx
2199
fat_notroot_first:
2243
fat_notroot_first:
2200
        call    fat_get_sector
2244
        call    fat_get_sector
2201
        push    ebx
2245
        push    ebx
2202
        lea     edi, [ebp+FAT.buffer]
2246
        lea     edi, [ebp+FAT.buffer]
2203
        mov     ebx, edi
2247
        mov     ebx, edi
2204
        call    fs_read32_sys
2248
        call    fs_read32_sys
2205
        pop     ebx
2249
        pop     ebx
2206
        test    eax, eax
2250
        test    eax, eax
2207
        jz      .ret ; CF=0
2251
        jz      .ret ; CF=0
2208
        push    ecx
2252
        push    ecx
2209
.deverr:
2253
.deverr:
2210
        pop     ecx
2254
        pop     ecx
2211
        mov     eax, ERROR_DEVICE
2255
        mov     eax, ERROR_DEVICE
2212
        stc
2256
        stc
2213
.ret:
2257
.ret:
2214
        ret
2258
        ret
2215
fat_notroot_next_err:
2259
fat_notroot_next_err:
2216
        pop     ecx
2260
        pop     ecx
2217
        mov     eax, ERROR_FILE_NOT_FOUND
2261
        mov     eax, ERROR_FILE_NOT_FOUND
2218
        stc
2262
        stc
2219
        ret
2263
        ret
2220
fat_notroot_begin_write:
2264
fat_notroot_begin_write:
2221
        push    eax edi
2265
        push    eax edi
2222
        call    fat_notroot_first
2266
        call    fat_notroot_first
2223
        pop     edi eax
2267
        pop     edi eax
2224
        ret
2268
        ret
2225
fat_notroot_end_write:
2269
fat_notroot_end_write:
2226
        call    fat_get_sector
2270
        call    fat_get_sector
2227
        push    ebx
2271
        push    ebx
2228
        lea     ebx, [ebp+FAT.buffer]
2272
        lea     ebx, [ebp+FAT.buffer]
2229
        call    fs_write32_sys
2273
        call    fs_write32_sys
2230
        pop     ebx
2274
        pop     ebx
2231
        ret
2275
        ret
2232
fat_notroot_next_write:
2276
fat_notroot_next_write:
2233
        push    ecx
2277
        push    ecx
2234
        lea     ecx, [ebp+FAT.buffer+0x200]
2278
        lea     ecx, [ebp+FAT.buffer+0x200]
2235
        cmp     edi, ecx
2279
        cmp     edi, ecx
2236
        jae     @f
2280
        jae     @f
2237
        pop     ecx
2281
        pop     ecx
2238
        ret
2282
        ret
2239
@@:
2283
@@:
2240
        push    eax
2284
        push    eax
2241
        call    fat_notroot_end_write
2285
        call    fat_notroot_end_write
2242
        pop     eax
2286
        pop     eax
2243
        jmp     fat_notroot_next_sector
2287
        jmp     fat_notroot_next_sector
2244
fat_notroot_extend_dir:
2288
fat_notroot_extend_dir:
2245
        push    eax
2289
        push    eax
2246
        call    get_free_FAT
2290
        call    get_free_FAT
2247
        jnc     .found
2291
        jnc     .found
2248
        pop     eax
2292
        pop     eax
2249
        ret     ; CF=1
2293
        ret     ; CF=1
2250
.found:
2294
.found:
2251
        push    edx
2295
        push    edx
2252
        mov     edx, [ebp+FAT.fatEND]
2296
        mov     edx, [ebp+FAT.fatEND]
2253
        call    set_FAT
2297
        call    set_FAT
2254
        jc      .writeerr
2298
        jc      .writeerr
2255
        mov     edx, eax
2299
        mov     edx, eax
2256
        mov     eax, [esp+4]
2300
        mov     eax, [esp+4]
2257
        mov     eax, [eax]
2301
        mov     eax, [eax]
2258
        push    edx
2302
        push    edx
2259
        call    set_FAT
2303
        call    set_FAT
2260
        pop     edx
2304
        pop     edx
2261
        jnc     @f
2305
        jnc     @f
2262
.writeerr:
2306
.writeerr:
2263
        pop     edx
2307
        pop     edx
2264
        pop     eax
2308
        pop     eax
2265
        stc
2309
        stc
2266
        ret
2310
        ret
2267
@@:
2311
@@:
2268
        push    ecx
2312
        push    ecx
2269
        or      ecx, -1
2313
        or      ecx, -1
2270
        call    add_disk_free_space
2314
        call    add_disk_free_space
2271
; zero new cluster
2315
; zero new cluster
2272
        mov     ecx, 512/4
2316
        mov     ecx, 512/4
2273
        lea     edi, [ebp+FAT.buffer]
2317
        lea     edi, [ebp+FAT.buffer]
2274
        push    edi
2318
        push    edi
2275
        xor     eax, eax
2319
        xor     eax, eax
2276
        rep stosd
2320
        rep stosd
2277
        pop     edi
2321
        pop     edi
2278
        pop     ecx
2322
        pop     ecx
2279
        mov     eax, [esp+4]
2323
        mov     eax, [esp+4]
2280
        mov     [eax], edx
2324
        mov     [eax], edx
2281
        and     dword [eax+4], 0
2325
        and     dword [eax+4], 0
2282
        pop     edx
2326
        pop     edx
2283
        mov     eax, [eax]
2327
        mov     eax, [eax]
2284
        dec     eax
2328
        dec     eax
2285
        dec     eax
2329
        dec     eax
2286
        push    ebx ecx
2330
        push    ebx ecx
2287
        mov     ecx, [ebp+FAT.SECTORS_PER_CLUSTER]
2331
        mov     ecx, [ebp+FAT.SECTORS_PER_CLUSTER]
2288
        imul    eax, ecx
2332
        imul    eax, ecx
2289
        add     eax, [ebp+FAT.DATA_START]
2333
        add     eax, [ebp+FAT.DATA_START]
2290
        mov     ebx, edi
2334
        mov     ebx, edi
2291
@@:
2335
@@:
2292
        push    eax
2336
        push    eax
2293
        call    fs_write32_sys
2337
        call    fs_write32_sys
2294
        pop     eax
2338
        pop     eax
2295
        inc     eax
2339
        inc     eax
2296
        loop    @b
2340
        loop    @b
2297
        pop     ecx ebx eax
2341
        pop     ecx ebx eax
2298
        clc
2342
        clc
2299
        ret
2343
        ret
2300
 
2344
 
2301
fat_get_sector:
2345
fat_get_sector:
2302
        push    ecx
2346
        push    ecx
2303
        mov     ecx, [eax]
2347
        mov     ecx, [eax]
2304
        dec     ecx
2348
        dec     ecx
2305
        dec     ecx
2349
        dec     ecx
2306
        imul    ecx, [ebp+FAT.SECTORS_PER_CLUSTER]
2350
        imul    ecx, [ebp+FAT.SECTORS_PER_CLUSTER]
2307
        add     ecx, [ebp+FAT.DATA_START]
2351
        add     ecx, [ebp+FAT.DATA_START]
2308
        add     ecx, [eax+4]
2352
        add     ecx, [eax+4]
2309
        mov     eax, ecx
2353
        mov     eax, ecx
2310
        pop     ecx
2354
        pop     ecx
2311
        ret
2355
        ret
2312
 
2356
 
2313
fshrad:
2357
fshrad:
2314
        call    fat_unlock
2358
        call    fat_unlock
2315
        mov     eax, ERROR_ACCESS_DENIED
2359
        mov     eax, ERROR_ACCESS_DENIED
2316
        xor     ebx, ebx
2360
        xor     ebx, ebx
2317
        ret
2361
        ret
2318
 
2362
 
2319
;----------------------------------------------------------------
2363
;----------------------------------------------------------------
2320
; fat_CreateFolder - FAT implementation of creating a folder
2364
; fat_CreateFolder - FAT implementation of creating a folder
2321
; in:  ebp = pointer to FAT structure
2365
; in:  ebp = pointer to FAT structure
2322
; in:  esi+[esp+4] = name
2366
; in:  esi+[esp+4] = name
2323
; in:  ebx = pointer to parameters from sysfunc 70
2367
; in:  ebx = pointer to parameters from sysfunc 70
2324
; out: eax, ebx = return values for sysfunc 70
2368
; out: eax, ebx = return values for sysfunc 70
2325
;----------------------------------------------------------------
2369
;----------------------------------------------------------------
2326
fat_CreateFolder:
2370
fat_CreateFolder:
2327
        push    1
2371
        push    1
2328
        jmp     fat_Rewrite.common
2372
        jmp     fat_Rewrite.common
2329
 
2373
 
2330
;----------------------------------------------------------------
2374
;----------------------------------------------------------------
2331
; fat_Rewrite - FAT implementation of creating a new file
2375
; fat_Rewrite - FAT implementation of creating a new file
2332
; in:  ebp = pointer to FAT structure
2376
; in:  ebp = pointer to FAT structure
2333
; in:  esi+[esp+4] = name
2377
; in:  esi+[esp+4] = name
2334
; in:  ebx = pointer to parameters from sysfunc 70
2378
; in:  ebx = pointer to parameters from sysfunc 70
2335
; out: eax, ebx = return values for sysfunc 70
2379
; out: eax, ebx = return values for sysfunc 70
2336
;----------------------------------------------------------------
2380
;----------------------------------------------------------------
2337
fat_Rewrite:
2381
fat_Rewrite:
2338
        push    0
2382
        push    0
2339
.common:
2383
.common:
2340
        call    fat_lock
2384
        call    fat_lock
2341
        pop     eax
2385
        pop     eax
2342
        cmp     byte [esi], 0
2386
        cmp     byte [esi], 0
2343
        jz      fshrad
2387
        jz      fshrad
2344
        mov     ecx, [ebx+12]
2388
        mov     ecx, [ebx+12]
2345
        mov     edx, [ebx+16]
2389
        mov     edx, [ebx+16]
2346
        pushad
2390
        pushad
2347
        xor     edi, edi
2391
        xor     edi, edi
2348
        mov     edx, [esp+4+20h]
2392
        mov     edx, [esp+4+20h]
2349
        push    esi
2393
        push    esi
2350
        test    edx, edx
2394
        test    edx, edx
2351
        jz      @f
2395
        jz      @f
2352
        mov     esi, edx
2396
        mov     esi, edx
2353
@@:
2397
@@:
2354
        lodsb
2398
        lodsb
2355
        test    al, al
2399
        test    al, al
2356
        jz      @f
2400
        jz      @f
2357
        cmp     al, '/'
2401
        cmp     al, '/'
2358
        jnz     @b
2402
        jnz     @b
2359
        lea     edi, [esi-1]
2403
        lea     edi, [esi-1]
2360
        jmp     @b
2404
        jmp     @b
2361
@@:
2405
@@:
2362
        pop     esi
2406
        pop     esi
2363
        test    edi, edi
2407
        test    edi, edi
2364
        jnz     .noroot
2408
        jnz     .noroot
2365
        test    edx, edx
2409
        test    edx, edx
2366
        jnz     .hasebp
2410
        jnz     .hasebp
2367
        mov     edx, [ebp+FAT.ROOT_CLUSTER]
2411
        mov     edx, [ebp+FAT.ROOT_CLUSTER]
2368
        cmp     [ebp+FAT.fs_type], 32
2412
        cmp     [ebp+FAT.fs_type], 32
2369
        jz      .pushnotroot
2413
        jz      .pushnotroot
2370
        xor     edx, edx
2414
        xor     edx, edx
2371
        push    edx
2415
        push    edx
2372
        push    fat1x_root_extend_dir
2416
        push    fat1x_root_extend_dir
2373
        push    fat1x_root_end_write
2417
        push    fat1x_root_end_write
2374
        push    fat1x_root_next_write
2418
        push    fat1x_root_next_write
2375
        push    fat1x_root_begin_write
2419
        push    fat1x_root_begin_write
2376
        push    edx
2420
        push    edx
2377
        push    edx
2421
        push    edx
2378
        push    fat1x_root_first
2422
        push    fat1x_root_first
2379
        push    fat1x_root_next
2423
        push    fat1x_root_next
2380
        jmp     .common1
2424
        jmp     .common1
2381
.hasebp:
2425
.hasebp:
2382
        mov     eax, ERROR_ACCESS_DENIED
2426
        mov     eax, ERROR_ACCESS_DENIED
2383
        cmp     byte [edx], 0
2427
        cmp     byte [edx], 0
2384
        jz      .ret1
2428
        jz      .ret1
2385
        stdcall hd_find_lfn, 0
2429
        stdcall hd_find_lfn, 0
2386
        mov     esi, [esp+4+20h]
2430
        mov     esi, [esp+4+20h]
2387
        jc      .ret1
2431
        jc      .ret1
2388
        jmp     .common0
2432
        jmp     .common0
2389
.noroot:
2433
.noroot:
2390
        mov     eax, ERROR_ACCESS_DENIED
2434
        mov     eax, ERROR_ACCESS_DENIED
2391
        cmp     byte [edi+1], 0
2435
        cmp     byte [edi+1], 0
2392
        jz      .ret1
2436
        jz      .ret1
2393
; check existence
2437
; check existence
2394
        mov     byte [edi], 0
2438
        mov     byte [edi], 0
2395
        push    edi
2439
        push    edi
2396
        stdcall hd_find_lfn, [esp+4+24h]
2440
        stdcall hd_find_lfn, [esp+4+24h]
2397
        pop     esi
2441
        pop     esi
2398
        mov     byte [esi], '/'
2442
        mov     byte [esi], '/'
2399
        jnc     @f
2443
        jnc     @f
2400
.notfound0:
2444
.notfound0:
2401
        mov     eax, ERROR_FILE_NOT_FOUND
2445
        mov     eax, ERROR_FILE_NOT_FOUND
2402
.ret1:
2446
.ret1:
2403
        mov     [esp+28], eax
2447
        mov     [esp+28], eax
2404
        call    fat_unlock
2448
        call    fat_unlock
2405
        popad
2449
        popad
2406
        xor     ebx, ebx
2450
        xor     ebx, ebx
2407
        ret
2451
        ret
2408
@@:
2452
@@:
2409
        inc     esi
2453
        inc     esi
2410
.common0:
2454
.common0:
2411
        test    byte [edi+11], 0x10     ; must be directory
2455
        test    byte [edi+11], 0x10     ; must be directory
2412
        mov     eax, ERROR_ACCESS_DENIED
2456
        mov     eax, ERROR_ACCESS_DENIED
2413
        jz      .ret1
2457
        jz      .ret1
2414
        mov     edx, [edi+20-2]
2458
        mov     edx, [edi+20-2]
2415
        mov     dx, [edi+26]            ; ebp=cluster
2459
        mov     dx, [edi+26]            ; ebp=cluster
2416
        mov     eax, ERROR_FAT_TABLE
2460
        mov     eax, ERROR_FAT_TABLE
2417
        cmp     edx, 2
2461
        cmp     edx, 2
2418
        jb      .ret1
2462
        jb      .ret1
2419
.pushnotroot:
2463
.pushnotroot:
2420
        push    edx
2464
        push    edx
2421
        push    fat_notroot_extend_dir
2465
        push    fat_notroot_extend_dir
2422
        push    fat_notroot_end_write
2466
        push    fat_notroot_end_write
2423
        push    fat_notroot_next_write
2467
        push    fat_notroot_next_write
2424
        push    fat_notroot_begin_write
2468
        push    fat_notroot_begin_write
2425
        push    0
2469
        push    0
2426
        push    edx
2470
        push    edx
2427
        push    fat_notroot_first
2471
        push    fat_notroot_first
2428
        push    fat_notroot_next
2472
        push    fat_notroot_next
2429
.common1:
2473
.common1:
2430
        call    fat_find_lfn
2474
        call    fat_find_lfn
2431
        jc      .notfound
2475
        jc      .notfound
2432
; found
2476
; found
2433
        test    byte [edi+11], 10h
2477
        test    byte [edi+11], 10h
2434
        jz      .exists_file
2478
        jz      .exists_file
2435
; found directory; if we are creating directory, return OK,
2479
; found directory; if we are creating directory, return OK,
2436
;                  if we are creating file, say "access denied"
2480
;                  if we are creating file, say "access denied"
2437
        add     esp, 36
2481
        add     esp, 36
2438
        call    fat_unlock
2482
        call    fat_unlock
2439
        popad
2483
        popad
2440
        test    al, al
2484
        test    al, al
2441
        mov     eax, ERROR_ACCESS_DENIED
2485
        mov     eax, ERROR_ACCESS_DENIED
2442
        jz      @f
2486
        jz      @f
2443
        mov     al, 0
2487
        mov     al, 0
2444
@@:
2488
@@:
2445
        xor     ebx, ebx
2489
        xor     ebx, ebx
2446
        ret
2490
        ret
2447
.exists_file:
2491
.exists_file:
2448
; found file; if we are creating directory, return "access denied",
2492
; found file; if we are creating directory, return "access denied",
2449
;             if we are creating file, delete existing file and continue
2493
;             if we are creating file, delete existing file and continue
2450
        cmp     byte [esp+36+28], 0
2494
        cmp     byte [esp+36+28], 0
2451
        jz      @f
2495
        jz      @f
2452
        add     esp, 36
2496
        add     esp, 36
2453
        call    fat_unlock
2497
        call    fat_unlock
2454
        popad
2498
        popad
2455
        mov     eax, ERROR_ACCESS_DENIED
2499
        mov     eax, ERROR_ACCESS_DENIED
2456
        xor     ebx, ebx
2500
        xor     ebx, ebx
2457
        ret
2501
        ret
2458
@@:
2502
@@:
2459
; delete FAT chain
2503
; delete FAT chain
2460
        push    edi
2504
        push    edi
2461
        xor     eax, eax
2505
        xor     eax, eax
2462
        mov     dword [edi+28], eax     ; zero size
2506
        mov     dword [edi+28], eax     ; zero size
2463
        xor     ecx, ecx
2507
        xor     ecx, ecx
2464
        mov     eax, [edi+20-2]
2508
        mov     eax, [edi+20-2]
2465
        mov     ax, [edi+26]
2509
        mov     ax, [edi+26]
2466
        mov     word [edi+20], cx
2510
        mov     word [edi+20], cx
2467
        mov     word [edi+26], cx
2511
        mov     word [edi+26], cx
2468
        test    eax, eax
2512
        test    eax, eax
2469
        jz      .done1
2513
        jz      .done1
2470
@@:
2514
@@:
2471
        cmp     eax, [ebp+FAT.fatRESERVED]
2515
        cmp     eax, [ebp+FAT.fatRESERVED]
2472
        jae     .done1
2516
        jae     .done1
2473
        push    edx
2517
        push    edx
2474
        xor     edx, edx
2518
        xor     edx, edx
2475
        call    set_FAT
2519
        call    set_FAT
2476
        mov     eax, edx
2520
        mov     eax, edx
2477
        pop     edx
2521
        pop     edx
2478
        jc      .done1
2522
        jc      .done1
2479
        inc     ecx
2523
        inc     ecx
2480
        jmp     @b
2524
        jmp     @b
2481
.done1:
2525
.done1:
2482
        pop     edi
2526
        pop     edi
2483
        call    get_time_for_file
2527
        call    get_time_for_file
2484
        mov     [edi+22], ax
2528
        mov     [edi+22], ax
2485
        call    get_date_for_file
2529
        call    get_date_for_file
2486
        mov     [edi+24], ax
2530
        mov     [edi+24], ax
2487
        mov     [edi+18], ax
2531
        mov     [edi+18], ax
2488
        or      byte [edi+11], 20h      ; set 'archive' attribute
2532
        or      byte [edi+11], 20h      ; set 'archive' attribute
2489
        jmp     .doit
2533
        jmp     .doit
2490
.notfound:
2534
.notfound:
2491
; file is not found; generate short name
2535
; file is not found; generate short name
2492
        call    fat_name_is_legal
2536
        call    fat_name_is_legal
2493
        jc      @f
2537
        jc      @f
2494
        add     esp, 36
2538
        add     esp, 36
2495
        call    fat_unlock
2539
        call    fat_unlock
2496
        popad
2540
        popad
2497
        mov     eax, ERROR_FILE_NOT_FOUND
2541
        mov     eax, ERROR_FILE_NOT_FOUND
2498
        xor     ebx, ebx
2542
        xor     ebx, ebx
2499
        ret
2543
        ret
2500
@@:
2544
@@:
2501
        sub     esp, 12
2545
        sub     esp, 12
2502
        mov     edi, esp
2546
        mov     edi, esp
2503
        call    fat_gen_short_name
2547
        call    fat_gen_short_name
2504
.test_short_name_loop:
2548
.test_short_name_loop:
2505
        push    esi edi ecx
2549
        push    esi edi ecx
2506
        mov     esi, edi
2550
        mov     esi, edi
2507
        lea     eax, [esp+12+12+8]
2551
        lea     eax, [esp+12+12+8]
2508
        mov     edx, [eax+24]
2552
        mov     edx, [eax+24]
2509
        mov     [eax], edx
2553
        mov     [eax], edx
2510
        and     dword [eax+4], 0
2554
        and     dword [eax+4], 0
2511
        call    dword [eax-4]
2555
        call    dword [eax-4]
2512
        jc      .found
2556
        jc      .found
2513
.test_short_name_entry:
2557
.test_short_name_entry:
2514
        cmp     byte [edi+11], 0xF
2558
        cmp     byte [edi+11], 0xF
2515
        jz      .test_short_name_cont
2559
        jz      .test_short_name_cont
2516
        mov     ecx, 11
2560
        mov     ecx, 11
2517
        push    esi edi
2561
        push    esi edi
2518
        repz cmpsb
2562
        repz cmpsb
2519
        pop     edi esi
2563
        pop     edi esi
2520
        jz      .short_name_found
2564
        jz      .short_name_found
2521
.test_short_name_cont:
2565
.test_short_name_cont:
2522
        lea     eax, [esp+12+12+8]
2566
        lea     eax, [esp+12+12+8]
2523
        call    dword [eax-8]
2567
        call    dword [eax-8]
2524
        jnc     .test_short_name_entry
2568
        jnc     .test_short_name_entry
2525
        jmp     .found
2569
        jmp     .found
2526
.short_name_found:
2570
.short_name_found:
2527
        pop     ecx edi esi
2571
        pop     ecx edi esi
2528
        call    fat_next_short_name
2572
        call    fat_next_short_name
2529
        jnc     .test_short_name_loop
2573
        jnc     .test_short_name_loop
2530
.disk_full:
2574
.disk_full:
2531
        add     esp, 12+36
2575
        add     esp, 12+36
2532
        call    fat_unlock
2576
        call    fat_unlock
2533
        popa
2577
        popa
2534
        mov     eax, ERROR_DISK_FULL
2578
        mov     eax, ERROR_DISK_FULL
2535
        xor     ebx, ebx
2579
        xor     ebx, ebx
2536
        ret
2580
        ret
2537
.found:
2581
.found:
2538
        pop     ecx edi esi
2582
        pop     ecx edi esi
2539
; now find space in directory
2583
; now find space in directory
2540
; we need to save LFN <=> LFN is not equal to short name <=> generated name contains '~'
2584
; we need to save LFN <=> LFN is not equal to short name <=> generated name contains '~'
2541
        mov     al, '~'
2585
        mov     al, '~'
2542
        push    ecx edi
2586
        push    ecx edi
2543
        mov     ecx, 8
2587
        mov     ecx, 8
2544
        repnz scasb
2588
        repnz scasb
2545
        movi    eax, 1     ; 1 entry
2589
        movi    eax, 1     ; 1 entry
2546
        jnz     .notilde
2590
        jnz     .notilde
2547
; we need ceil(strlen(esi)/13) additional entries = floor((strlen(esi)+12+13)/13) total
2591
; we need ceil(strlen(esi)/13) additional entries = floor((strlen(esi)+12+13)/13) total
2548
        xor     eax, eax
2592
        xor     eax, eax
2549
@@:
2593
@@:
2550
        cmp     byte [esi], 0
2594
        cmp     byte [esi], 0
2551
        jz      @f
2595
        jz      @f
2552
        inc     esi
2596
        inc     esi
2553
        inc     eax
2597
        inc     eax
2554
        jmp     @b
2598
        jmp     @b
2555
@@:
2599
@@:
2556
        sub     esi, eax
2600
        sub     esi, eax
2557
        add     eax, 12+13
2601
        add     eax, 12+13
2558
        mov     ecx, 13
2602
        mov     ecx, 13
2559
        push    edx
2603
        push    edx
2560
        cdq
2604
        cdq
2561
        div     ecx
2605
        div     ecx
2562
        pop     edx
2606
        pop     edx
2563
.notilde:
2607
.notilde:
2564
        push    -1
2608
        push    -1
2565
        push    -1
2609
        push    -1
2566
        push    -1
2610
        push    -1
2567
; find  successive entries in directory
2611
; find  successive entries in directory
2568
        xor     ecx, ecx
2612
        xor     ecx, ecx
2569
        push    eax
2613
        push    eax
2570
        lea     eax, [esp+16+8+12+8]
2614
        lea     eax, [esp+16+8+12+8]
2571
        mov     edx, [eax+24]
2615
        mov     edx, [eax+24]
2572
        mov     [eax], edx
2616
        mov     [eax], edx
2573
        and     dword [eax+4], 0
2617
        and     dword [eax+4], 0
2574
        call    dword [eax-4]
2618
        call    dword [eax-4]
2575
        pop     eax
2619
        pop     eax
2576
        jnc     .scan_dir
2620
        jnc     .scan_dir
2577
.fsfrfe3:
2621
.fsfrfe3:
2578
        add     esp, 12+8+12+36
2622
        add     esp, 12+8+12+36
2579
        call    fat_unlock
2623
        call    fat_unlock
2580
        popad
2624
        popad
2581
        mov     eax, ERROR_DEVICE
2625
        mov     eax, ERROR_DEVICE
2582
        xor     ebx, ebx
2626
        xor     ebx, ebx
2583
        ret
2627
        ret
2584
.scan_dir:
2628
.scan_dir:
2585
        cmp     byte [edi], 0
2629
        cmp     byte [edi], 0
2586
        jz      .free
2630
        jz      .free
2587
        cmp     byte [edi], 0xE5
2631
        cmp     byte [edi], 0xE5
2588
        jz      .free
2632
        jz      .free
2589
        xor     ecx, ecx
2633
        xor     ecx, ecx
2590
.scan_cont:
2634
.scan_cont:
2591
        push    eax
2635
        push    eax
2592
        lea     eax, [esp+16+8+12+8]
2636
        lea     eax, [esp+16+8+12+8]
2593
        call    dword [eax-8]
2637
        call    dword [eax-8]
2594
        mov     edx, eax
2638
        mov     edx, eax
2595
        pop     eax
2639
        pop     eax
2596
        jnc     .scan_dir
2640
        jnc     .scan_dir
2597
        cmp     edx, ERROR_DEVICE
2641
        cmp     edx, ERROR_DEVICE
2598
        jz      .fsfrfe3
2642
        jz      .fsfrfe3
2599
        push    eax
2643
        push    eax
2600
        lea     eax, [esp+16+8+12+8]
2644
        lea     eax, [esp+16+8+12+8]
2601
        call    dword [eax+20]          ; extend directory
2645
        call    dword [eax+20]          ; extend directory
2602
        pop     eax
2646
        pop     eax
2603
        jnc     .scan_dir
2647
        jnc     .scan_dir
2604
        add     esp, 12+8+12+36
2648
        add     esp, 12+8+12+36
2605
        call    fat_unlock
2649
        call    fat_unlock
2606
        popad
2650
        popad
2607
        mov     eax, ERROR_DISK_FULL
2651
        mov     eax, ERROR_DISK_FULL
2608
        xor     ebx, ebx
2652
        xor     ebx, ebx
2609
        ret
2653
        ret
2610
.free:
2654
.free:
2611
        test    ecx, ecx
2655
        test    ecx, ecx
2612
        jnz     @f
2656
        jnz     @f
2613
        mov     [esp], edi
2657
        mov     [esp], edi
2614
        mov     ecx, [esp+12+8+12+8]
2658
        mov     ecx, [esp+12+8+12+8]
2615
        mov     [esp+4], ecx
2659
        mov     [esp+4], ecx
2616
        mov     ecx, [esp+12+8+12+12]
2660
        mov     ecx, [esp+12+8+12+12]
2617
        mov     [esp+8], ecx
2661
        mov     [esp+8], ecx
2618
        xor     ecx, ecx
2662
        xor     ecx, ecx
2619
@@:
2663
@@:
2620
        inc     ecx
2664
        inc     ecx
2621
        cmp     ecx, eax
2665
        cmp     ecx, eax
2622
        jb      .scan_cont
2666
        jb      .scan_cont
2623
; found!
2667
; found!
2624
        push    esi ecx
2668
        push    esi ecx
2625
; If creating a directory, allocate one data cluster now and fail immediately
2669
; If creating a directory, allocate one data cluster now and fail immediately
2626
; if this is impossible. This prevents from creating an invalid directory entry
2670
; if this is impossible. This prevents from creating an invalid directory entry
2627
; on a full disk.
2671
; on a full disk.
2628
; yup, the argument is quite non-intuitive... but what should I do if
2672
; yup, the argument is quite non-intuitive... but what should I do if
2629
; the entire function uses such arguments? BTW, it refers to al from pushad,
2673
; the entire function uses such arguments? BTW, it refers to al from pushad,
2630
; which in turn is filled with 0 in fat_Rewrite and 1 in fat_CreateFolder.
2674
; which in turn is filled with 0 in fat_Rewrite and 1 in fat_CreateFolder.
2631
        cmp     byte [esp+8+12+8+12+36+28], 0
2675
        cmp     byte [esp+8+12+8+12+36+28], 0
2632
        jz      .no.preallocate.folder.data
2676
        jz      .no.preallocate.folder.data
2633
        call    get_free_FAT
2677
        call    get_free_FAT
2634
        jnc     @f
2678
        jnc     @f
2635
        add     esp, 8+12+8
2679
        add     esp, 8+12+8
2636
        jmp     .disk_full
2680
        jmp     .disk_full
2637
@@:
2681
@@:
2638
        mov     [esp+8+12+8+12+36+20], eax ; store the cluster somewhere
2682
        mov     [esp+8+12+8+12+36+20], eax ; store the cluster somewhere
2639
.no.preallocate.folder.data:
2683
.no.preallocate.folder.data:
2640
; calculate name checksum
2684
; calculate name checksum
2641
        mov     esi, [esp+8+12]
2685
        mov     esi, [esp+8+12]
2642
        mov     ecx, 11
2686
        mov     ecx, 11
2643
        xor     eax, eax
2687
        xor     eax, eax
2644
@@:
2688
@@:
2645
        ror     al, 1
2689
        ror     al, 1
2646
        add     al, [esi]
2690
        add     al, [esi]
2647
        inc     esi
2691
        inc     esi
2648
        loop    @b
2692
        loop    @b
2649
        pop     ecx esi
2693
        pop     ecx esi
2650
        pop     edi
2694
        pop     edi
2651
        pop     dword [esp+8+12+12]
2695
        pop     dword [esp+8+12+12]
2652
        pop     dword [esp+8+12+12]
2696
        pop     dword [esp+8+12+12]
2653
; edi points to first entry in free chunk
2697
; edi points to first entry in free chunk
2654
        dec     ecx
2698
        dec     ecx
2655
        jz      .nolfn
2699
        jz      .nolfn
2656
        push    esi
2700
        push    esi
2657
        push    eax
2701
        push    eax
2658
        lea     eax, [esp+8+8+12+8]
2702
        lea     eax, [esp+8+8+12+8]
2659
        call    dword [eax+8]         ; begin write
2703
        call    dword [eax+8]         ; begin write
2660
        mov     al, 40h
2704
        mov     al, 40h
2661
.writelfn:
2705
.writelfn:
2662
        or      al, cl
2706
        or      al, cl
2663
        mov     esi, [esp+4]
2707
        mov     esi, [esp+4]
2664
        push    ecx
2708
        push    ecx
2665
        dec     ecx
2709
        dec     ecx
2666
        imul    ecx, 13
2710
        imul    ecx, 13
2667
        add     esi, ecx
2711
        add     esi, ecx
2668
        stosb
2712
        stosb
2669
        mov     cl, 5
2713
        mov     cl, 5
2670
        call    fat_read_symbols
2714
        call    fat_read_symbols
2671
        mov     ax, 0xF
2715
        mov     ax, 0xF
2672
        stosw
2716
        stosw
2673
        mov     al, [esp+4]
2717
        mov     al, [esp+4]
2674
        stosb
2718
        stosb
2675
        mov     cl, 6
2719
        mov     cl, 6
2676
        call    fat_read_symbols
2720
        call    fat_read_symbols
2677
        xor     eax, eax
2721
        xor     eax, eax
2678
        stosw
2722
        stosw
2679
        mov     cl, 2
2723
        mov     cl, 2
2680
        call    fat_read_symbols
2724
        call    fat_read_symbols
2681
        pop     ecx
2725
        pop     ecx
2682
        lea     eax, [esp+8+8+12+8]
2726
        lea     eax, [esp+8+8+12+8]
2683
        call    dword [eax+12]         ; next write
2727
        call    dword [eax+12]         ; next write
2684
        xor     eax, eax
2728
        xor     eax, eax
2685
        loop    .writelfn
2729
        loop    .writelfn
2686
        pop     eax
2730
        pop     eax
2687
        pop     esi
2731
        pop     esi
2688
;        lea     eax, [esp+8+12+8]
2732
;        lea     eax, [esp+8+12+8]
2689
;        call    dword [eax+16]          ; end write
2733
;        call    dword [eax+16]          ; end write
2690
.nolfn:
2734
.nolfn:
2691
        xchg    esi, [esp]
2735
        xchg    esi, [esp]
2692
        mov     ecx, 11
2736
        mov     ecx, 11
2693
        rep movsb
2737
        rep movsb
2694
        mov     word [edi], 20h         ; attributes
2738
        mov     word [edi], 20h         ; attributes
2695
        sub     edi, 11
2739
        sub     edi, 11
2696
        pop     esi ecx
2740
        pop     esi ecx
2697
        add     esp, 12
2741
        add     esp, 12
2698
        mov     byte [edi+13], 0        ; tenths of a second at file creation time
2742
        mov     byte [edi+13], 0        ; tenths of a second at file creation time
2699
        call    get_time_for_file
2743
        call    get_time_for_file
2700
        mov     [edi+14], ax            ; creation time
2744
        mov     [edi+14], ax            ; creation time
2701
        mov     [edi+22], ax            ; last write time
2745
        mov     [edi+22], ax            ; last write time
2702
        call    get_date_for_file
2746
        call    get_date_for_file
2703
        mov     [edi+16], ax            ; creation date
2747
        mov     [edi+16], ax            ; creation date
2704
        mov     [edi+24], ax            ; last write date
2748
        mov     [edi+24], ax            ; last write date
2705
        mov     [edi+18], ax            ; last access date
2749
        mov     [edi+18], ax            ; last access date
2706
        xor     ecx, ecx
2750
        xor     ecx, ecx
2707
        mov     word [edi+20], cx       ; high word of cluster
2751
        mov     word [edi+20], cx       ; high word of cluster
2708
        mov     word [edi+26], cx       ; low word of cluster - to be filled
2752
        mov     word [edi+26], cx       ; low word of cluster - to be filled
2709
        mov     dword [edi+28], ecx     ; file size - to be filled
2753
        mov     dword [edi+28], ecx     ; file size - to be filled
2710
        cmp     byte [esp+36+28], cl
2754
        cmp     byte [esp+36+28], cl
2711
        jz      .doit
2755
        jz      .doit
2712
; create directory
2756
; create directory
2713
        mov     byte [edi+11], 10h      ; attributes: folder
2757
        mov     byte [edi+11], 10h      ; attributes: folder
2714
        mov     esi, edi
2758
        mov     esi, edi
2715
        lea     eax, [esp+8]
2759
        lea     eax, [esp+8]
2716
        call    dword [eax+16]  ; flush directory
2760
        call    dword [eax+16]  ; flush directory
2717
        mov     eax, [esp+36+20] ; extract saved cluster
2761
        mov     eax, [esp+36+20] ; extract saved cluster
2718
        mov     [esp+36+20], edi ; this is needed for calculating arg of add_disk_free_space!
2762
        mov     [esp+36+20], edi ; this is needed for calculating arg of add_disk_free_space!
2719
        push    ecx
2763
        push    ecx
2720
        mov     ecx, [ebp+FAT.SECTORS_PER_CLUSTER]
2764
        mov     ecx, [ebp+FAT.SECTORS_PER_CLUSTER]
2721
        shl     ecx, 9
2765
        shl     ecx, 9
2722
        push    ecx
2766
        push    ecx
2723
        push    edi
2767
        push    edi
2724
        jmp     .doit2
2768
        jmp     .doit2
2725
.doit:
2769
.doit:
2726
        mov     esi, [esp+36+20]
2770
        mov     esi, [esp+36+20]
2727
        lea     eax, [esp+8]
2771
        lea     eax, [esp+8]
2728
        call    dword [eax+16]  ; flush directory
2772
        call    dword [eax+16]  ; flush directory
2729
        push    ecx
2773
        push    ecx
2730
        mov     ecx, [esp+4+36+24]
2774
        mov     ecx, [esp+4+36+24]
2731
        push    ecx
2775
        push    ecx
2732
        push    edi
2776
        push    edi
2733
        test    ecx, ecx
2777
        test    ecx, ecx
2734
        jz      .done
2778
        jz      .done
2735
        call    get_free_FAT
2779
        call    get_free_FAT
2736
        jc      .diskfull
2780
        jc      .diskfull
2737
.doit2:
2781
.doit2:
2738
        push    eax
2782
        push    eax
2739
        mov     [edi+26], ax
2783
        mov     [edi+26], ax
2740
        shr     eax, 16
2784
        shr     eax, 16
2741
        mov     [edi+20], ax
2785
        mov     [edi+20], ax
2742
        lea     eax, [esp+16+8]
2786
        lea     eax, [esp+16+8]
2743
        call    dword [eax+16]  ; flush directory
2787
        call    dword [eax+16]  ; flush directory
2744
        pop     eax
2788
        pop     eax
2745
        push    edx
2789
        push    edx
2746
        mov     edx, [ebp+FAT.fatEND]
2790
        mov     edx, [ebp+FAT.fatEND]
2747
        call    set_FAT
2791
        call    set_FAT
2748
        pop     edx
2792
        pop     edx
2749
.write_cluster:
2793
.write_cluster:
2750
        push    eax
2794
        push    eax
2751
        dec     eax
2795
        dec     eax
2752
        dec     eax
2796
        dec     eax
2753
        imul    eax, [ebp+FAT.SECTORS_PER_CLUSTER]
2797
        imul    eax, [ebp+FAT.SECTORS_PER_CLUSTER]
2754
        add     eax, [ebp+FAT.DATA_START]
2798
        add     eax, [ebp+FAT.DATA_START]
2755
        push    [ebp+FAT.SECTORS_PER_CLUSTER]
2799
        push    [ebp+FAT.SECTORS_PER_CLUSTER]
2756
; write data
2800
; write data
2757
.write_sector:
2801
.write_sector:
2758
        cmp     byte [esp+20+36+28], 0
2802
        cmp     byte [esp+20+36+28], 0
2759
        jnz     .writedir
2803
        jnz     .writedir
2760
        mov     ecx, 512
2804
        mov     ecx, 512
2761
        cmp     dword [esp+12], ecx
2805
        cmp     dword [esp+12], ecx
2762
        jb      .writeshort
2806
        jb      .writeshort
2763
; we can write directly from given buffer
2807
; we can write directly from given buffer
2764
        mov     ebx, esi
2808
        mov     ebx, esi
2765
        add     esi, ecx
2809
        add     esi, ecx
2766
        jmp     .writecommon
2810
        jmp     .writecommon
2767
.writeshort:
2811
.writeshort:
2768
        mov     ecx, [esp+12]
2812
        mov     ecx, [esp+12]
2769
        push    ecx
2813
        push    ecx
2770
        lea     edi, [ebp+FAT.buffer]
2814
        lea     edi, [ebp+FAT.buffer]
2771
        mov     ebx, edi
2815
        mov     ebx, edi
2772
        rep movsb
2816
        rep movsb
2773
.writedircont:
2817
.writedircont:
2774
        lea     ecx, [ebp+FAT.buffer+0x200]
2818
        lea     ecx, [ebp+FAT.buffer+0x200]
2775
        sub     ecx, edi
2819
        sub     ecx, edi
2776
        push    eax
2820
        push    eax
2777
        xor     eax, eax
2821
        xor     eax, eax
2778
        rep stosb
2822
        rep stosb
2779
        pop     eax
2823
        pop     eax
2780
        pop     ecx
2824
        pop     ecx
2781
.writecommon:
2825
.writecommon:
2782
        push    eax
2826
        push    eax
2783
        call    fs_write32_app
2827
        call    fs_write32_app
2784
        test    eax, eax
2828
        test    eax, eax
2785
        pop     eax
2829
        pop     eax
2786
        jnz     .writeerr
2830
        jnz     .writeerr
2787
        inc     eax
2831
        inc     eax
2788
        sub     dword [esp+12], ecx
2832
        sub     dword [esp+12], ecx
2789
        jz      .writedone
2833
        jz      .writedone
2790
        dec     dword [esp]
2834
        dec     dword [esp]
2791
        jnz     .write_sector
2835
        jnz     .write_sector
2792
        pop     eax
2836
        pop     eax
2793
; allocate new cluster
2837
; allocate new cluster
2794
        pop     eax
2838
        pop     eax
2795
        mov     ecx, eax
2839
        mov     ecx, eax
2796
        call    get_free_FAT
2840
        call    get_free_FAT
2797
        jc      .diskfull
2841
        jc      .diskfull
2798
        push    edx
2842
        push    edx
2799
        mov     edx, [ebp+FAT.fatEND]
2843
        mov     edx, [ebp+FAT.fatEND]
2800
        call    set_FAT
2844
        call    set_FAT
2801
        xchg    eax, ecx
2845
        xchg    eax, ecx
2802
        mov     edx, ecx
2846
        mov     edx, ecx
2803
        call    set_FAT
2847
        call    set_FAT
2804
        pop     edx
2848
        pop     edx
2805
        xchg    eax, ecx
2849
        xchg    eax, ecx
2806
        jmp     .write_cluster
2850
        jmp     .write_cluster
2807
.diskfull:
2851
.diskfull:
2808
        mov     eax, ERROR_DISK_FULL
2852
        mov     eax, ERROR_DISK_FULL
2809
        jmp     .ret
2853
        jmp     .ret
2810
.writeerr:
2854
.writeerr:
2811
        pop     eax eax
2855
        pop     eax eax
2812
        sub     esi, ecx
2856
        sub     esi, ecx
2813
        mov     eax, ERROR_DEVICE
2857
        mov     eax, ERROR_DEVICE
2814
        jmp     .ret
2858
        jmp     .ret
2815
.writedone:
2859
.writedone:
2816
        pop     eax eax
2860
        pop     eax eax
2817
.done:
2861
.done:
2818
        xor     eax, eax
2862
        xor     eax, eax
2819
.ret:
2863
.ret:
2820
        pop     edi ecx
2864
        pop     edi ecx
2821
        sub     esi, [esp+4+36+20]
2865
        sub     esi, [esp+4+36+20]
2822
        mov     [esp+4+36+28], eax
2866
        mov     [esp+4+36+28], eax
2823
        mov     [esp+4+36+16], esi
2867
        mov     [esp+4+36+16], esi
2824
        lea     eax, [esp+12]
2868
        lea     eax, [esp+12]
2825
        call    dword [eax+8]
2869
        call    dword [eax+8]
2826
        mov     [edi+28], esi
2870
        mov     [edi+28], esi
2827
        call    dword [eax+16]
2871
        call    dword [eax+16]
2828
        mov     [esp+36+16], ebx
2872
        mov     [esp+36+16], ebx
2829
        lea     eax, [esi+511]
2873
        lea     eax, [esi+511]
2830
        shr     eax, 9
2874
        shr     eax, 9
2831
        mov     ecx, [ebp+FAT.SECTORS_PER_CLUSTER]
2875
        mov     ecx, [ebp+FAT.SECTORS_PER_CLUSTER]
2832
        lea     eax, [eax+ecx-1]
2876
        lea     eax, [eax+ecx-1]
2833
        xor     edx, edx
2877
        xor     edx, edx
2834
        div     ecx
2878
        div     ecx
2835
        pop     ecx
2879
        pop     ecx
2836
        sub     ecx, eax
2880
        sub     ecx, eax
2837
        call    add_disk_free_space
2881
        call    add_disk_free_space
2838
        add     esp, 36
2882
        add     esp, 36
2839
        call    update_disk
2883
        call    update_disk
2840
        call    fat_unlock
2884
        call    fat_unlock
2841
        popad
2885
        popad
2842
        ret
2886
        ret
2843
.writedir:
2887
.writedir:
2844
        push    512
2888
        push    512
2845
        lea     edi, [ebp+FAT.buffer]
2889
        lea     edi, [ebp+FAT.buffer]
2846
        mov     ebx, edi
2890
        mov     ebx, edi
2847
        mov     ecx, [ebp+FAT.SECTORS_PER_CLUSTER]
2891
        mov     ecx, [ebp+FAT.SECTORS_PER_CLUSTER]
2848
        shl     ecx, 9
2892
        shl     ecx, 9
2849
        cmp     ecx, [esp+16]
2893
        cmp     ecx, [esp+16]
2850
        jnz     .writedircont
2894
        jnz     .writedircont
2851
        dec     dword [esp+20]
2895
        dec     dword [esp+20]
2852
        push    esi
2896
        push    esi
2853
        mov     ecx, 32/4
2897
        mov     ecx, 32/4
2854
        rep movsd
2898
        rep movsd
2855
        pop     esi
2899
        pop     esi
2856
        mov     dword [edi-32], '.   '
2900
        mov     dword [edi-32], '.   '
2857
        mov     dword [edi-32+4], '    '
2901
        mov     dword [edi-32+4], '    '
2858
        mov     dword [edi-32+8], '    '
2902
        mov     dword [edi-32+8], '    '
2859
        mov     byte [edi-32+11], 10h
2903
        mov     byte [edi-32+11], 10h
2860
        push    esi
2904
        push    esi
2861
        mov     ecx, 32/4
2905
        mov     ecx, 32/4
2862
        rep movsd
2906
        rep movsd
2863
        pop     esi
2907
        pop     esi
2864
        mov     dword [edi-32], '..  '
2908
        mov     dword [edi-32], '..  '
2865
        mov     dword [edi-32+4], '    '
2909
        mov     dword [edi-32+4], '    '
2866
        mov     dword [edi-32+8], '    '
2910
        mov     dword [edi-32+8], '    '
2867
        mov     byte [edi-32+11], 10h
2911
        mov     byte [edi-32+11], 10h
2868
        mov     ecx, [esp+20+36]
2912
        mov     ecx, [esp+20+36]
2869
        cmp     ecx, [ebp+FAT.ROOT_CLUSTER]
2913
        cmp     ecx, [ebp+FAT.ROOT_CLUSTER]
2870
        jnz     @f
2914
        jnz     @f
2871
        xor     ecx, ecx
2915
        xor     ecx, ecx
2872
@@:
2916
@@:
2873
        mov     word [edi-32+26], cx
2917
        mov     word [edi-32+26], cx
2874
        shr     ecx, 16
2918
        shr     ecx, 16
2875
        mov     [edi-32+20], cx
2919
        mov     [edi-32+20], cx
2876
        jmp     .writedircont
2920
        jmp     .writedircont
2877
 
2921
 
2878
fat_read_symbol:
2922
fat_read_symbol:
2879
        or      ax, -1
2923
        or      ax, -1
2880
        test    esi, esi
2924
        test    esi, esi
2881
        jz      .retFFFF
2925
        jz      .retFFFF
2882
        lodsb
2926
        lodsb
2883
        test    al, al
2927
        test    al, al
2884
        jnz     ansi2uni_char
2928
        jnz     ansi2uni_char
2885
        xor     eax, eax
2929
        xor     eax, eax
2886
        xor     esi, esi
2930
        xor     esi, esi
2887
.retFFFF:
2931
.retFFFF:
2888
        ret
2932
        ret
2889
 
2933
 
2890
fat_read_symbols:
2934
fat_read_symbols:
2891
        call    fat_read_symbol
2935
        call    fat_read_symbol
2892
        stosw
2936
        stosw
2893
        loop    fat_read_symbols
2937
        loop    fat_read_symbols
2894
        ret
2938
        ret
2895
 
2939
 
2896
 
2940
 
2897
fat_Write.access_denied:
2941
fat_Write.access_denied:
2898
        push    ERROR_ACCESS_DENIED
2942
        push    ERROR_ACCESS_DENIED
2899
fat_Write.ret0:
2943
fat_Write.ret0:
2900
        pop     eax
2944
        pop     eax
2901
        xor     ebx, ebx
2945
        xor     ebx, ebx
2902
        ret
2946
        ret
2903
 
2947
 
2904
fat_Write.ret11:
2948
fat_Write.ret11:
2905
        push    ERROR_DEVICE
2949
        push    ERROR_DEVICE
2906
        jmp     fat_Write.ret0
2950
        jmp     fat_Write.ret0
2907
 
2951
 
2908
;----------------------------------------------------------------
2952
;----------------------------------------------------------------
2909
; fat_Write - FAT implementation of writing to file
2953
; fat_Write - FAT implementation of writing to file
2910
; in:  ebp = pointer to FAT structure
2954
; in:  ebp = pointer to FAT structure
2911
; in:  esi+[esp+4] = name
2955
; in:  esi+[esp+4] = name
2912
; in:  ebx = pointer to parameters from sysfunc 70
2956
; in:  ebx = pointer to parameters from sysfunc 70
2913
; out: eax, ebx = return values for sysfunc 70
2957
; out: eax, ebx = return values for sysfunc 70
2914
;----------------------------------------------------------------
2958
;----------------------------------------------------------------
2915
fat_Write:
2959
fat_Write:
2916
        cmp     byte [esi], 0
2960
        cmp     byte [esi], 0
2917
        jz      .access_denied
2961
        jz      .access_denied
2918
        call    fat_lock
2962
        call    fat_lock
2919
        push    edi
2963
        push    edi
2920
        stdcall hd_find_lfn, [esp+4+4]
2964
        stdcall hd_find_lfn, [esp+4+4]
2921
        jnc     .found
2965
        jnc     .found
2922
        pop     edi
2966
        pop     edi
2923
        push    eax
2967
        push    eax
2924
        call    fat_unlock
2968
        call    fat_unlock
2925
        jmp     .ret0
2969
        jmp     .ret0
2926
.found:
2970
.found:
2927
; FAT does not support files larger than 4GB
2971
; FAT does not support files larger than 4GB
2928
        cmp     dword [ebx+8], 0
2972
        cmp     dword [ebx+8], 0
2929
        jz      @f
2973
        jz      @f
2930
.eof:
2974
.eof:
2931
        pop     edi
2975
        pop     edi
2932
        push    ERROR_END_OF_FILE
2976
        push    ERROR_END_OF_FILE
2933
        call    fat_unlock
2977
        call    fat_unlock
2934
        jmp     .ret0
2978
        jmp     .ret0
2935
@@:
2979
@@:
2936
        mov     ecx, [ebx+12]
2980
        mov     ecx, [ebx+12]
2937
        mov     edx, [ebx+16]
2981
        mov     edx, [ebx+16]
2938
        mov     ebx, [ebx+4]
2982
        mov     ebx, [ebx+4]
2939
; now edi points to direntry, ebx=start byte to write,
2983
; now edi points to direntry, ebx=start byte to write,
2940
; ecx=number of bytes to write, edx=data pointer
2984
; ecx=number of bytes to write, edx=data pointer
2941
 
2985
 
2942
; extend file if needed
2986
; extend file if needed
2943
        add     ecx, ebx
2987
        add     ecx, ebx
2944
        jc      .eof    ; FAT does not support files larger than 4GB
2988
        jc      .eof    ; FAT does not support files larger than 4GB
2945
        push    edx
2989
        push    edx
2946
        push    eax     ; save directory sector
2990
        push    eax     ; save directory sector
2947
        push    0       ; return value=0
2991
        push    0       ; return value=0
2948
 
2992
 
2949
        call    get_time_for_file
2993
        call    get_time_for_file
2950
        mov     [edi+22], ax            ; last write time
2994
        mov     [edi+22], ax            ; last write time
2951
        call    get_date_for_file
2995
        call    get_date_for_file
2952
        mov     [edi+24], ax            ; last write date
2996
        mov     [edi+24], ax            ; last write date
2953
        mov     [edi+18], ax            ; last access date
2997
        mov     [edi+18], ax            ; last access date
2954
 
2998
 
2955
        push    dword [edi+28]          ; save current file size
2999
        push    dword [edi+28]          ; save current file size
2956
        cmp     ecx, [edi+28]
3000
        cmp     ecx, [edi+28]
2957
        jbe     .length_ok
3001
        jbe     .length_ok
2958
        cmp     ecx, ebx
3002
        cmp     ecx, ebx
2959
        jz      .length_ok
3003
        jz      .length_ok
2960
        call    hd_extend_file
3004
        call    hd_extend_file
2961
        jnc     .length_ok
3005
        jnc     .length_ok
2962
        mov     [esp+4], eax
3006
        mov     [esp+4], eax
2963
; hd_extend_file can return three error codes: FAT table error, device error or disk full.
3007
; hd_extend_file can return three error codes: FAT table error, device error or disk full.
2964
; First two cases are fatal errors, in third case we may write some data
3008
; First two cases are fatal errors, in third case we may write some data
2965
        cmp     al, ERROR_DISK_FULL
3009
        cmp     al, ERROR_DISK_FULL
2966
        jz      .disk_full
3010
        jz      .disk_full
2967
        call    fat_unlock
3011
        call    fat_unlock
2968
        pop     eax
3012
        pop     eax
2969
        pop     eax
3013
        pop     eax
2970
        pop     ecx
3014
        pop     ecx
2971
        pop     edx
3015
        pop     edx
2972
        pop     edi
3016
        pop     edi
2973
        xor     ebx, ebx
3017
        xor     ebx, ebx
2974
        ret
3018
        ret
2975
.disk_full:
3019
.disk_full:
2976
; correct number of bytes to write
3020
; correct number of bytes to write
2977
        mov     ecx, [edi+28]
3021
        mov     ecx, [edi+28]
2978
        cmp     ecx, ebx
3022
        cmp     ecx, ebx
2979
        ja      .length_ok
3023
        ja      .length_ok
2980
        push    0
3024
        push    0
2981
.ret:
3025
.ret:
2982
        pop     eax
3026
        pop     eax
2983
        sub     edx, [esp+12]
3027
        sub     edx, [esp+12]
2984
        mov     ebx, edx        ; ebx=number of written bytes
3028
        mov     ebx, edx        ; ebx=number of written bytes
2985
        call    update_disk
3029
        call    update_disk
2986
        test    eax, eax
3030
        test    eax, eax
2987
        jz      @f
3031
        jz      @f
2988
        mov     byte [esp+4], ERROR_DEVICE
3032
        mov     byte [esp+4], ERROR_DEVICE
2989
@@:
3033
@@:
2990
        call    fat_unlock
3034
        call    fat_unlock
2991
        pop     eax
3035
        pop     eax
2992
        pop     eax
3036
        pop     eax
2993
        pop     ecx
3037
        pop     ecx
2994
        pop     edx
3038
        pop     edx
2995
        pop     edi
3039
        pop     edi
2996
        ret
3040
        ret
2997
.length_ok:
3041
.length_ok:
2998
        mov     esi, [edi+28]
3042
        mov     esi, [edi+28]
2999
        mov     eax, [edi+20-2]
3043
        mov     eax, [edi+20-2]
3000
        mov     ax, [edi+26]
3044
        mov     ax, [edi+26]
3001
        mov     edi, eax        ; edi=current cluster
3045
        mov     edi, eax        ; edi=current cluster
3002
        push    0               ; current sector in cluster
3046
        push    0               ; current sector in cluster
3003
; save directory
3047
; save directory
3004
        mov     eax, [esp+12]
3048
        mov     eax, [esp+12]
3005
        push    ebx
3049
        push    ebx
3006
        lea     ebx, [ebp+FAT.buffer]
3050
        lea     ebx, [ebp+FAT.buffer]
3007
        call    fs_write32_sys
3051
        call    fs_write32_sys
3008
        pop     ebx
3052
        pop     ebx
3009
        test    eax, eax
3053
        test    eax, eax
3010
        jz      @f
3054
        jz      @f
3011
.device_err:
3055
.device_err:
3012
        mov     byte [esp+8], ERROR_DEVICE
3056
        mov     byte [esp+8], ERROR_DEVICE
3013
        jmp     .ret
3057
        jmp     .ret
3014
.fat_err:
3058
.fat_err:
3015
        mov     byte [esp+8], ERROR_FAT_TABLE
3059
        mov     byte [esp+8], ERROR_FAT_TABLE
3016
        jmp     .ret
3060
        jmp     .ret
3017
@@:
3061
@@:
3018
 
3062
 
3019
; now ebx=start pos, ecx=end pos, both lie inside file
3063
; now ebx=start pos, ecx=end pos, both lie inside file
3020
        sub     ecx, ebx
3064
        sub     ecx, ebx
3021
        jz      .ret
3065
        jz      .ret
3022
.write_loop:
3066
.write_loop:
3023
; skip unmodified sectors
3067
; skip unmodified sectors
3024
        cmp     dword [esp+4], 0x200
3068
        cmp     dword [esp+4], 0x200
3025
        jb      .modify
3069
        jb      .modify
3026
        sub     ebx, 0x200
3070
        sub     ebx, 0x200
3027
        jae     .skip
3071
        jae     .skip
3028
        add     ebx, 0x200
3072
        add     ebx, 0x200
3029
.modify:
3073
.modify:
3030
; get length of data in current sector
3074
; get length of data in current sector
3031
        push    ecx
3075
        push    ecx
3032
        sub     ebx, 0x200
3076
        sub     ebx, 0x200
3033
        jb      .hasdata
3077
        jb      .hasdata
3034
        neg     ebx
3078
        neg     ebx
3035
        xor     ecx, ecx
3079
        xor     ecx, ecx
3036
        jmp     @f
3080
        jmp     @f
3037
.hasdata:
3081
.hasdata:
3038
        neg     ebx
3082
        neg     ebx
3039
        cmp     ecx, ebx
3083
        cmp     ecx, ebx
3040
        jbe     @f
3084
        jbe     @f
3041
        mov     ecx, ebx
3085
        mov     ecx, ebx
3042
@@:
3086
@@:
3043
; get current sector number
3087
; get current sector number
3044
        mov     eax, edi
3088
        mov     eax, edi
3045
        dec     eax
3089
        dec     eax
3046
        dec     eax
3090
        dec     eax
3047
        imul    eax, [ebp+FAT.SECTORS_PER_CLUSTER]
3091
        imul    eax, [ebp+FAT.SECTORS_PER_CLUSTER]
3048
        add     eax, [ebp+FAT.DATA_START]
3092
        add     eax, [ebp+FAT.DATA_START]
3049
        add     eax, [esp+4]
3093
        add     eax, [esp+4]
3050
; load sector if needed
3094
; load sector if needed
3051
        cmp     dword [esp+8], 0        ; we don't need to read uninitialized data
3095
        cmp     dword [esp+8], 0        ; we don't need to read uninitialized data
3052
        jz      .noread
3096
        jz      .noread
3053
        cmp     ecx, 0x200      ; we don't need to read sector if it is fully rewritten
3097
        cmp     ecx, 0x200      ; we don't need to read sector if it is fully rewritten
3054
        jz      .noread
3098
        jz      .noread
3055
        cmp     ecx, esi        ; (same for the last sector)
3099
        cmp     ecx, esi        ; (same for the last sector)
3056
        jz      .noread
3100
        jz      .noread
3057
        push    eax ebx
3101
        push    eax ebx
3058
        lea     ebx, [ebp+FAT.buffer]
3102
        lea     ebx, [ebp+FAT.buffer]
3059
        call    fs_read32_app
3103
        call    fs_read32_app
3060
        test    eax, eax
3104
        test    eax, eax
3061
        pop     ebx eax
3105
        pop     ebx eax
3062
        jz      @f
3106
        jz      @f
3063
.device_err2:
3107
.device_err2:
3064
        pop     ecx
3108
        pop     ecx
3065
        jmp     .device_err
3109
        jmp     .device_err
3066
@@:
3110
@@:
3067
.noread:
3111
.noread:
3068
; zero uninitialized data if file was extended (because hd_extend_file does not this)
3112
; zero uninitialized data if file was extended (because hd_extend_file does not this)
3069
        push    eax ecx edi
3113
        push    eax ecx edi
3070
        xor     eax, eax
3114
        xor     eax, eax
3071
        mov     ecx, 0x200
3115
        mov     ecx, 0x200
3072
        sub     ecx, [esp+8+12]
3116
        sub     ecx, [esp+8+12]
3073
        jbe     @f
3117
        jbe     @f
3074
        lea     edi, [ebp+FAT.buffer]
3118
        lea     edi, [ebp+FAT.buffer]
3075
        add     edi, [esp+8+12]
3119
        add     edi, [esp+8+12]
3076
        rep stosb
3120
        rep stosb
3077
@@:
3121
@@:
3078
; zero uninitialized data in the last sector
3122
; zero uninitialized data in the last sector
3079
        mov     ecx, 0x200
3123
        mov     ecx, 0x200
3080
        sub     ecx, esi
3124
        sub     ecx, esi
3081
        jbe     @f
3125
        jbe     @f
3082
        lea     edi, [ebp+FAT.buffer+esi]
3126
        lea     edi, [ebp+FAT.buffer+esi]
3083
        rep stosb
3127
        rep stosb
3084
@@:
3128
@@:
3085
        pop     edi ecx
3129
        pop     edi ecx
3086
; copy new data
3130
; copy new data
3087
        mov     eax, edx
3131
        mov     eax, edx
3088
        neg     ebx
3132
        neg     ebx
3089
        jecxz   @f
3133
        jecxz   @f
3090
        lea     ebx, [ebp+FAT.buffer+0x200+ebx]
3134
        lea     ebx, [ebp+FAT.buffer+0x200+ebx]
3091
        call    memmove
3135
        call    memmove
3092
        xor     ebx, ebx
3136
        xor     ebx, ebx
3093
@@:
3137
@@:
3094
        pop     eax
3138
        pop     eax
3095
; save sector
3139
; save sector
3096
        push    ebx
3140
        push    ebx
3097
        lea     ebx, [ebp+FAT.buffer]
3141
        lea     ebx, [ebp+FAT.buffer]
3098
        call    fs_write32_app
3142
        call    fs_write32_app
3099
        pop     ebx
3143
        pop     ebx
3100
        test    eax, eax
3144
        test    eax, eax
3101
        jnz     .device_err2
3145
        jnz     .device_err2
3102
        add     edx, ecx
3146
        add     edx, ecx
3103
        sub     [esp], ecx
3147
        sub     [esp], ecx
3104
        pop     ecx
3148
        pop     ecx
3105
        jz      .ret
3149
        jz      .ret
3106
.skip:
3150
.skip:
3107
; next sector
3151
; next sector
3108
        pop     eax
3152
        pop     eax
3109
        inc     eax
3153
        inc     eax
3110
        push    eax
3154
        push    eax
3111
        cmp     eax, [ebp+FAT.SECTORS_PER_CLUSTER]
3155
        cmp     eax, [ebp+FAT.SECTORS_PER_CLUSTER]
3112
        jb      @f
3156
        jb      @f
3113
        and     dword [esp], 0
3157
        and     dword [esp], 0
3114
        mov     eax, edi
3158
        mov     eax, edi
3115
        call    get_FAT
3159
        call    get_FAT
3116
        mov     edi, eax
3160
        mov     edi, eax
3117
        jc      .device_err
3161
        jc      .device_err
3118
        cmp     edi, 2
3162
        cmp     edi, 2
3119
        jb      .fat_err
3163
        jb      .fat_err
3120
        cmp     edi, [ebp+FAT.fatRESERVED]
3164
        cmp     edi, [ebp+FAT.fatRESERVED]
3121
        jae     .fat_err
3165
        jae     .fat_err
3122
@@:
3166
@@:
3123
        sub     esi, 0x200
3167
        sub     esi, 0x200
3124
        jae     @f
3168
        jae     @f
3125
        xor     esi, esi
3169
        xor     esi, esi
3126
@@:
3170
@@:
3127
        sub     dword [esp+4], 0x200
3171
        sub     dword [esp+4], 0x200
3128
        jae     @f
3172
        jae     @f
3129
        and     dword [esp+4], 0
3173
        and     dword [esp+4], 0
3130
@@:
3174
@@:
3131
        jmp     .write_loop
3175
        jmp     .write_loop
3132
 
3176
 
3133
hd_extend_file.zero_size:
3177
hd_extend_file.zero_size:
3134
        xor     eax, eax
3178
        xor     eax, eax
3135
        jmp     hd_extend_file.start_extend
3179
        jmp     hd_extend_file.start_extend
3136
 
3180
 
3137
; extends file on hd to given size (new data area is undefined)
3181
; extends file on hd to given size (new data area is undefined)
3138
; in: edi->direntry, ecx=new size
3182
; in: edi->direntry, ecx=new size
3139
; out: CF=0 => OK, eax=0
3183
; out: CF=0 => OK, eax=0
3140
;      CF=1 => error, eax=code (ERROR_FAT_TABLE or ERROR_DISK_FULL or ERROR_DEVICE)
3184
;      CF=1 => error, eax=code (ERROR_FAT_TABLE or ERROR_DISK_FULL or ERROR_DEVICE)
3141
hd_extend_file:
3185
hd_extend_file:
3142
        push    esi
3186
        push    esi
3143
        mov     esi, [ebp+FAT.SECTORS_PER_CLUSTER]
3187
        mov     esi, [ebp+FAT.SECTORS_PER_CLUSTER]
3144
        imul    esi, [ebp+FAT.BYTES_PER_SECTOR]
3188
        imul    esi, [ebp+FAT.BYTES_PER_SECTOR]
3145
        push    ecx
3189
        push    ecx
3146
; find the last cluster of file
3190
; find the last cluster of file
3147
        mov     eax, [edi+20-2]
3191
        mov     eax, [edi+20-2]
3148
        mov     ax, [edi+26]
3192
        mov     ax, [edi+26]
3149
        mov     ecx, [edi+28]
3193
        mov     ecx, [edi+28]
3150
        jecxz   .zero_size
3194
        jecxz   .zero_size
3151
.last_loop:
3195
.last_loop:
3152
        sub     ecx, esi
3196
        sub     ecx, esi
3153
        jbe     .last_found
3197
        jbe     .last_found
3154
        call    get_FAT
3198
        call    get_FAT
3155
        jnc     @f
3199
        jnc     @f
3156
.device_err:
3200
.device_err:
3157
        pop     ecx
3201
        pop     ecx
3158
.device_err2:
3202
.device_err2:
3159
        pop     esi
3203
        pop     esi
3160
        push    ERROR_DEVICE
3204
        push    ERROR_DEVICE
3161
.ret_err:
3205
.ret_err:
3162
        pop     eax
3206
        pop     eax
3163
        stc
3207
        stc
3164
        ret
3208
        ret
3165
@@:
3209
@@:
3166
        cmp     eax, 2
3210
        cmp     eax, 2
3167
        jb      .fat_err
3211
        jb      .fat_err
3168
        cmp     eax, [ebp+FAT.fatRESERVED]
3212
        cmp     eax, [ebp+FAT.fatRESERVED]
3169
        jb      .last_loop
3213
        jb      .last_loop
3170
.fat_err:
3214
.fat_err:
3171
        pop     ecx esi
3215
        pop     ecx esi
3172
        push    ERROR_FAT_TABLE
3216
        push    ERROR_FAT_TABLE
3173
        jmp     .ret_err
3217
        jmp     .ret_err
3174
.last_found:
3218
.last_found:
3175
        push    eax
3219
        push    eax
3176
        call    get_FAT
3220
        call    get_FAT
3177
        jnc     @f
3221
        jnc     @f
3178
        pop     eax
3222
        pop     eax
3179
        jmp     .device_err
3223
        jmp     .device_err
3180
@@:
3224
@@:
3181
        cmp     eax, [ebp+FAT.fatRESERVED]
3225
        cmp     eax, [ebp+FAT.fatRESERVED]
3182
        pop     eax
3226
        pop     eax
3183
        jb      .fat_err
3227
        jb      .fat_err
3184
; set length to full number of clusters
3228
; set length to full number of clusters
3185
        sub     [edi+28], ecx
3229
        sub     [edi+28], ecx
3186
.start_extend:
3230
.start_extend:
3187
        pop     ecx
3231
        pop     ecx
3188
; now do extend
3232
; now do extend
3189
        push    edx
3233
        push    edx
3190
        mov     edx, 2          ; start scan from cluster 2
3234
        mov     edx, 2          ; start scan from cluster 2
3191
.extend_loop:
3235
.extend_loop:
3192
        cmp     [edi+28], ecx
3236
        cmp     [edi+28], ecx
3193
        jae     .extend_done
3237
        jae     .extend_done
3194
; add new cluster
3238
; add new cluster
3195
        push    eax
3239
        push    eax
3196
        call    get_free_FAT
3240
        call    get_free_FAT
3197
        jc      .disk_full
3241
        jc      .disk_full
3198
        mov     edx, [ebp+FAT.fatEND]
3242
        mov     edx, [ebp+FAT.fatEND]
3199
        call    set_FAT
3243
        call    set_FAT
3200
        mov     edx, eax
3244
        mov     edx, eax
3201
        pop     eax
3245
        pop     eax
3202
        test    eax, eax
3246
        test    eax, eax
3203
        jz      .first_cluster
3247
        jz      .first_cluster
3204
        push    edx
3248
        push    edx
3205
        call    set_FAT
3249
        call    set_FAT
3206
        pop     edx
3250
        pop     edx
3207
        jmp     @f
3251
        jmp     @f
3208
.first_cluster:
3252
.first_cluster:
3209
        ror     edx, 16
3253
        ror     edx, 16
3210
        mov     [edi+20], dx
3254
        mov     [edi+20], dx
3211
        ror     edx, 16
3255
        ror     edx, 16
3212
        mov     [edi+26], dx
3256
        mov     [edi+26], dx
3213
@@:
3257
@@:
3214
        push    ecx
3258
        push    ecx
3215
        mov     ecx, -1
3259
        mov     ecx, -1
3216
        call    add_disk_free_space
3260
        call    add_disk_free_space
3217
        pop     ecx
3261
        pop     ecx
3218
        mov     eax, edx
3262
        mov     eax, edx
3219
        add     [edi+28], esi
3263
        add     [edi+28], esi
3220
        jmp     .extend_loop
3264
        jmp     .extend_loop
3221
.extend_done:
3265
.extend_done:
3222
        mov     [edi+28], ecx
3266
        mov     [edi+28], ecx
3223
        pop     edx esi
3267
        pop     edx esi
3224
        xor     eax, eax        ; CF=0
3268
        xor     eax, eax        ; CF=0
3225
        ret
3269
        ret
3226
.device_err3:
3270
.device_err3:
3227
        pop     edx
3271
        pop     edx
3228
        jmp     .device_err2
3272
        jmp     .device_err2
3229
.disk_full:
3273
.disk_full:
3230
        pop     eax edx esi
3274
        pop     eax edx esi
3231
        movi    eax, ERROR_DISK_FULL
3275
        movi    eax, ERROR_DISK_FULL
3232
        stc
3276
        stc
3233
        ret
3277
        ret
3234
 
3278
 
3235
fat_update_datetime:
3279
fat_update_datetime:
3236
        call    get_time_for_file
3280
        call    get_time_for_file
3237
        mov     [edi+22], ax            ; last write time
3281
        mov     [edi+22], ax            ; last write time
3238
        call    get_date_for_file
3282
        call    get_date_for_file
3239
        mov     [edi+24], ax            ; last write date
3283
        mov     [edi+24], ax            ; last write date
3240
        mov     [edi+18], ax            ; last access date
3284
        mov     [edi+18], ax            ; last access date
3241
        ret
3285
        ret
3242
 
3286
 
3243
 
3287
 
3244
;----------------------------------------------------------------
3288
;----------------------------------------------------------------
3245
; fat_SetFileEnd - FAT implementation of setting end-of-file
3289
; fat_SetFileEnd - FAT implementation of setting end-of-file
3246
; in:  ebp = pointer to FAT structure
3290
; in:  ebp = pointer to FAT structure
3247
; in:  esi+[esp+4] = name
3291
; in:  esi+[esp+4] = name
3248
; in:  ebx = pointer to parameters from sysfunc 70
3292
; in:  ebx = pointer to parameters from sysfunc 70
3249
; out: eax, ebx = return values for sysfunc 70
3293
; out: eax, ebx = return values for sysfunc 70
3250
;----------------------------------------------------------------
3294
;----------------------------------------------------------------
3251
fat_SetFileEnd:
3295
fat_SetFileEnd:
3252
        call    fat_lock
3296
        call    fat_lock
3253
        push    edi
3297
        push    edi
3254
        cmp     byte [esi], 0
3298
        cmp     byte [esi], 0
3255
        jnz     @f
3299
        jnz     @f
3256
.access_denied:
3300
.access_denied:
3257
        push    ERROR_ACCESS_DENIED
3301
        push    ERROR_ACCESS_DENIED
3258
.ret:
3302
.ret:
3259
        call    fat_unlock
3303
        call    fat_unlock
3260
        pop     eax
3304
        pop     eax
3261
        pop     edi
3305
        pop     edi
3262
        ret
3306
        ret
3263
@@:
3307
@@:
3264
        stdcall hd_find_lfn, [esp+4+4]
3308
        stdcall hd_find_lfn, [esp+4+4]
3265
        jnc     @f
3309
        jnc     @f
3266
.reteax:
3310
.reteax:
3267
        push    eax
3311
        push    eax
3268
        jmp     .ret
3312
        jmp     .ret
3269
@@:
3313
@@:
3270
; must not be directory
3314
; must not be directory
3271
        test    byte [edi+11], 10h
3315
        test    byte [edi+11], 10h
3272
        jnz     .access_denied
3316
        jnz     .access_denied
3273
; file size must not exceed 4 Gb
3317
; file size must not exceed 4 Gb
3274
        cmp     dword [ebx+8], 0
3318
        cmp     dword [ebx+8], 0
3275
        jz      @f
3319
        jz      @f
3276
        push    ERROR_END_OF_FILE
3320
        push    ERROR_END_OF_FILE
3277
        jmp     .ret
3321
        jmp     .ret
3278
@@:
3322
@@:
3279
        push    eax     ; save directory sector
3323
        push    eax     ; save directory sector
3280
; set file modification date/time to current
3324
; set file modification date/time to current
3281
        call    fat_update_datetime
3325
        call    fat_update_datetime
3282
        mov     eax, [ebx+4]
3326
        mov     eax, [ebx+4]
3283
        cmp     eax, [edi+28]
3327
        cmp     eax, [edi+28]
3284
        jb      .truncate
3328
        jb      .truncate
3285
        ja      .expand
3329
        ja      .expand
3286
        pop     eax
3330
        pop     eax
3287
        lea     ebx, [ebp+FAT.buffer]
3331
        lea     ebx, [ebp+FAT.buffer]
3288
        call    fs_write32_sys
3332
        call    fs_write32_sys
3289
        test    eax, eax
3333
        test    eax, eax
3290
        jz      @f
3334
        jz      @f
3291
        push    ERROR_DEVICE
3335
        push    ERROR_DEVICE
3292
        jmp     .ret
3336
        jmp     .ret
3293
@@:
3337
@@:
3294
        push    0
3338
        push    0
3295
        jmp     .ret
3339
        jmp     .ret
3296
.expand:
3340
.expand:
3297
        push    ebx ebp ecx
3341
        push    ebx ebp ecx
3298
        push    dword [edi+28]  ; save old size
3342
        push    dword [edi+28]  ; save old size
3299
        mov     ecx, eax
3343
        mov     ecx, eax
3300
        call    hd_extend_file
3344
        call    hd_extend_file
3301
        push    eax             ; return code
3345
        push    eax             ; return code
3302
        jnc     .expand_ok
3346
        jnc     .expand_ok
3303
        cmp     al, ERROR_DISK_FULL
3347
        cmp     al, ERROR_DISK_FULL
3304
        jz      .disk_full
3348
        jz      .disk_full
3305
.pop_ret:
3349
.pop_ret:
3306
        call    update_disk
3350
        call    update_disk
3307
        pop     eax ecx ecx ebp ebx ecx
3351
        pop     eax ecx ecx ebp ebx ecx
3308
        jmp     .reteax
3352
        jmp     .reteax
3309
.expand_ok:
3353
.expand_ok:
3310
.disk_full:
3354
.disk_full:
3311
; save directory
3355
; save directory
3312
        mov     eax, [edi+28]
3356
        mov     eax, [edi+28]
3313
        xchg    eax, [esp+20]
3357
        xchg    eax, [esp+20]
3314
        lea     ebx, [ebp+FAT.buffer]
3358
        lea     ebx, [ebp+FAT.buffer]
3315
        call    fs_write32_sys
3359
        call    fs_write32_sys
3316
        test    eax, eax
3360
        test    eax, eax
3317
        mov     eax, [edi+20-2]
3361
        mov     eax, [edi+20-2]
3318
        mov     ax, [edi+26]
3362
        mov     ax, [edi+26]
3319
        mov     edi, eax
3363
        mov     edi, eax
3320
        jz      @f
3364
        jz      @f
3321
.pop_ret11:
3365
.pop_ret11:
3322
        mov     byte [esp], ERROR_DEVICE
3366
        mov     byte [esp], ERROR_DEVICE
3323
        jmp     .pop_ret
3367
        jmp     .pop_ret
3324
@@:
3368
@@:
3325
        test    edi, edi
3369
        test    edi, edi
3326
        jz      .pop_ret
3370
        jz      .pop_ret
3327
; now zero new data
3371
; now zero new data
3328
        push    0
3372
        push    0
3329
; edi=current cluster, [esp]=sector in cluster
3373
; edi=current cluster, [esp]=sector in cluster
3330
; [esp+24]=new size, [esp+8]=old size, [esp+4]=return code
3374
; [esp+24]=new size, [esp+8]=old size, [esp+4]=return code
3331
.zero_loop:
3375
.zero_loop:
3332
        cmp     edi, 2
3376
        cmp     edi, 2
3333
        jb      .error_fat
3377
        jb      .error_fat
3334
        cmp     edi, [ebp+FAT.fatRESERVED]
3378
        cmp     edi, [ebp+FAT.fatRESERVED]
3335
        jae     .error_fat
3379
        jae     .error_fat
3336
        sub     dword [esp+8], 0x200
3380
        sub     dword [esp+8], 0x200
3337
        jae     .next_cluster
3381
        jae     .next_cluster
3338
        lea     eax, [edi-2]
3382
        lea     eax, [edi-2]
3339
        imul    eax, [ebp+FAT.SECTORS_PER_CLUSTER]
3383
        imul    eax, [ebp+FAT.SECTORS_PER_CLUSTER]
3340
        add     eax, [ebp+FAT.DATA_START]
3384
        add     eax, [ebp+FAT.DATA_START]
3341
        add     eax, [esp]
3385
        add     eax, [esp]
3342
        cmp     dword [esp+8], -0x200
3386
        cmp     dword [esp+8], -0x200
3343
        jz      .noread
3387
        jz      .noread
3344
        push    eax
3388
        push    eax
3345
        lea     ebx, [ebp+FAT.buffer]
3389
        lea     ebx, [ebp+FAT.buffer]
3346
        call    fs_read32_app
3390
        call    fs_read32_app
3347
        test    eax, eax
3391
        test    eax, eax
3348
        pop     eax
3392
        pop     eax
3349
        jnz     .err_next
3393
        jnz     .err_next
3350
.noread:
3394
.noread:
3351
        mov     ecx, [esp+8]
3395
        mov     ecx, [esp+8]
3352
        neg     ecx
3396
        neg     ecx
3353
        push    edi
3397
        push    edi
3354
        lea     edi, [ebp+FAT.buffer+0x200]
3398
        lea     edi, [ebp+FAT.buffer+0x200]
3355
        add     edi, [esp+12]
3399
        add     edi, [esp+12]
3356
        push    eax
3400
        push    eax
3357
        xor     eax, eax
3401
        xor     eax, eax
3358
        mov     [esp+16], eax
3402
        mov     [esp+16], eax
3359
        rep stosb
3403
        rep stosb
3360
        pop     eax
3404
        pop     eax
3361
        pop     edi
3405
        pop     edi
3362
        call    fs_write32_app
3406
        call    fs_write32_app
3363
        test    eax, eax
3407
        test    eax, eax
3364
        jz      .next_cluster
3408
        jz      .next_cluster
3365
.err_next:
3409
.err_next:
3366
        mov     byte [esp+4], ERROR_DEVICE
3410
        mov     byte [esp+4], ERROR_DEVICE
3367
.next_cluster:
3411
.next_cluster:
3368
        pop     eax
3412
        pop     eax
3369
        sub     dword [esp+20], 0x200
3413
        sub     dword [esp+20], 0x200
3370
        jbe     .pop_ret
3414
        jbe     .pop_ret
3371
        inc     eax
3415
        inc     eax
3372
        push    eax
3416
        push    eax
3373
        cmp     eax, [ebp+FAT.SECTORS_PER_CLUSTER]
3417
        cmp     eax, [ebp+FAT.SECTORS_PER_CLUSTER]
3374
        jb      .zero_loop
3418
        jb      .zero_loop
3375
        and     dword [esp], 0
3419
        and     dword [esp], 0
3376
        mov     eax, edi
3420
        mov     eax, edi
3377
        call    get_FAT
3421
        call    get_FAT
3378
        mov     edi, eax
3422
        mov     edi, eax
3379
        jnc     .zero_loop
3423
        jnc     .zero_loop
3380
        pop     eax
3424
        pop     eax
3381
        jmp     .pop_ret11
3425
        jmp     .pop_ret11
3382
.truncate:
3426
.truncate:
3383
        mov     [edi+28], eax
3427
        mov     [edi+28], eax
3384
        push    ecx
3428
        push    ecx
3385
        mov     ecx, [edi+20-2]
3429
        mov     ecx, [edi+20-2]
3386
        mov     cx, [edi+26]
3430
        mov     cx, [edi+26]
3387
        push    eax
3431
        push    eax
3388
        test    eax, eax
3432
        test    eax, eax
3389
        jz      .zero_size
3433
        jz      .zero_size
3390
; find new last cluster
3434
; find new last cluster
3391
@@:
3435
@@:
3392
        cmp     ecx, 2
3436
        cmp     ecx, 2
3393
        jb      .error_fat2
3437
        jb      .error_fat2
3394
        cmp     ecx, [ebp+FAT.fatRESERVED]
3438
        cmp     ecx, [ebp+FAT.fatRESERVED]
3395
        jae     .error_fat2
3439
        jae     .error_fat2
3396
        mov     eax, [ebp+FAT.SECTORS_PER_CLUSTER]
3440
        mov     eax, [ebp+FAT.SECTORS_PER_CLUSTER]
3397
        shl     eax, 9
3441
        shl     eax, 9
3398
        sub     [esp], eax
3442
        sub     [esp], eax
3399
        jbe     @f
3443
        jbe     @f
3400
        mov     eax, ecx
3444
        mov     eax, ecx
3401
        call    get_FAT
3445
        call    get_FAT
3402
        mov     ecx, eax
3446
        mov     ecx, eax
3403
        jnc     @b
3447
        jnc     @b
3404
.device_err3:
3448
.device_err3:
3405
        pop     eax ecx eax edi
3449
        pop     eax ecx eax edi
3406
        call    update_disk
3450
        call    update_disk
3407
        call    fat_unlock
3451
        call    fat_unlock
3408
        movi    eax, ERROR_DEVICE
3452
        movi    eax, ERROR_DEVICE
3409
        ret
3453
        ret
3410
@@:
3454
@@:
3411
; we will zero data at the end of last sector - remember it
3455
; we will zero data at the end of last sector - remember it
3412
        push    ecx
3456
        push    ecx
3413
; terminate FAT chain
3457
; terminate FAT chain
3414
        push    edx
3458
        push    edx
3415
        mov     eax, ecx
3459
        mov     eax, ecx
3416
        mov     edx, [ebp+FAT.fatEND]
3460
        mov     edx, [ebp+FAT.fatEND]
3417
        call    set_FAT
3461
        call    set_FAT
3418
        mov     eax, edx
3462
        mov     eax, edx
3419
        pop     edx
3463
        pop     edx
3420
        jnc     @f
3464
        jnc     @f
3421
.device_err4:
3465
.device_err4:
3422
        pop     ecx
3466
        pop     ecx
3423
        jmp     .device_err3
3467
        jmp     .device_err3
3424
.zero_size:
3468
.zero_size:
3425
        and     word [edi+20], 0
3469
        and     word [edi+20], 0
3426
        and     word [edi+26], 0
3470
        and     word [edi+26], 0
3427
        push    0
3471
        push    0
3428
        mov     eax, ecx
3472
        mov     eax, ecx
3429
@@:
3473
@@:
3430
; delete FAT chain
3474
; delete FAT chain
3431
        call    clear_cluster_chain
3475
        call    clear_cluster_chain
3432
        jc      .device_err4
3476
        jc      .device_err4
3433
; save directory
3477
; save directory
3434
        mov     eax, [esp+12]
3478
        mov     eax, [esp+12]
3435
        push    ebx
3479
        push    ebx
3436
        lea     ebx, [ebp+FAT.buffer]
3480
        lea     ebx, [ebp+FAT.buffer]
3437
        call    fs_write32_sys
3481
        call    fs_write32_sys
3438
        pop     ebx
3482
        pop     ebx
3439
        test    eax, eax
3483
        test    eax, eax
3440
        jnz     .device_err4
3484
        jnz     .device_err4
3441
; zero last sector, ignore errors
3485
; zero last sector, ignore errors
3442
        pop     ecx
3486
        pop     ecx
3443
        pop     eax
3487
        pop     eax
3444
        dec     ecx
3488
        dec     ecx
3445
        imul    ecx, [ebp+FAT.SECTORS_PER_CLUSTER]
3489
        imul    ecx, [ebp+FAT.SECTORS_PER_CLUSTER]
3446
        add     ecx, [ebp+FAT.DATA_START]
3490
        add     ecx, [ebp+FAT.DATA_START]
3447
        push    eax
3491
        push    eax
3448
        sar     eax, 9
3492
        sar     eax, 9
3449
        add     ecx, eax
3493
        add     ecx, eax
3450
        pop     eax
3494
        pop     eax
3451
        and     eax, 0x1FF
3495
        and     eax, 0x1FF
3452
        jz      .truncate_done
3496
        jz      .truncate_done
3453
        push    ebx eax
3497
        push    ebx eax
3454
        mov     eax, ecx
3498
        mov     eax, ecx
3455
        lea     ebx, [ebp+FAT.buffer]
3499
        lea     ebx, [ebp+FAT.buffer]
3456
        call    fs_read32_app
3500
        call    fs_read32_app
3457
        pop     eax
3501
        pop     eax
3458
        lea     edi, [ebp+FAT.buffer+eax]
3502
        lea     edi, [ebp+FAT.buffer+eax]
3459
        push    ecx
3503
        push    ecx
3460
        mov     ecx, 0x200
3504
        mov     ecx, 0x200
3461
        sub     ecx, eax
3505
        sub     ecx, eax
3462
        xor     eax, eax
3506
        xor     eax, eax
3463
        rep stosb
3507
        rep stosb
3464
        pop     eax
3508
        pop     eax
3465
        call    fs_write32_app
3509
        call    fs_write32_app
3466
        pop     ebx
3510
        pop     ebx
3467
.truncate_done:
3511
.truncate_done:
3468
        pop     ecx eax edi
3512
        pop     ecx eax edi
3469
        call    update_disk
3513
        call    update_disk
3470
        call    fat_unlock
3514
        call    fat_unlock
3471
        xor     eax, eax
3515
        xor     eax, eax
3472
        ret
3516
        ret
3473
.error_fat:
3517
.error_fat:
3474
        pop     eax
3518
        pop     eax
3475
        mov     byte [esp], ERROR_FAT_TABLE
3519
        mov     byte [esp], ERROR_FAT_TABLE
3476
        jmp     .pop_ret
3520
        jmp     .pop_ret
3477
.error_fat2:
3521
.error_fat2:
3478
        pop     eax ecx eax edi
3522
        pop     eax ecx eax edi
3479
        call    update_disk
3523
        call    update_disk
3480
        call    fat_unlock
3524
        call    fat_unlock
3481
        movi    eax, ERROR_FAT_TABLE
3525
        movi    eax, ERROR_FAT_TABLE
3482
        ret
3526
        ret
3483
 
3527
 
3484
;----------------------------------------------------------------
3528
;----------------------------------------------------------------
3485
; fat_GetFileInfo - FAT implementation of getting file info
3529
; fat_GetFileInfo - FAT implementation of getting file info
3486
; in:  ebp = pointer to FAT structure
3530
; in:  ebp = pointer to FAT structure
3487
; in:  esi+[esp+4] = name
3531
; in:  esi+[esp+4] = name
3488
; in:  ebx = pointer to parameters from sysfunc 70
3532
; in:  ebx = pointer to parameters from sysfunc 70
3489
; out: eax, ebx = return values for sysfunc 70
3533
; out: eax, ebx = return values for sysfunc 70
3490
;----------------------------------------------------------------
3534
;----------------------------------------------------------------
3491
fat_GetFileInfo:
3535
fat_GetFileInfo:
3492
        cmp     byte [esi], 0
3536
        cmp     byte [esi], 0
3493
        jnz     @f
3537
        jnz     @f
3494
        mov     eax, 2
3538
        mov     eax, 2
3495
        ret
3539
        ret
3496
@@:
3540
@@:
3497
        push    edi
3541
        push    edi
3498
        call    fat_lock
3542
        call    fat_lock
3499
        stdcall hd_find_lfn, [esp+4+4]
3543
        stdcall hd_find_lfn, [esp+4+4]
3500
        jc      .error
3544
        jc      .error
3501
        push    ebp
3545
        push    ebp
3502
        xor     ebp, ebp
3546
        xor     ebp, ebp
3503
        mov     esi, [ebx+16]
3547
        mov     esi, [ebx+16]
3504
        mov     dword [esi+4], ebp
3548
        mov     dword [esi+4], ebp
3505
        call    fat_entry_to_bdfe2
3549
        call    fat_entry_to_bdfe2
3506
        pop     ebp
3550
        pop     ebp
3507
        call    fat_unlock
3551
        call    fat_unlock
3508
        xor     eax, eax
3552
        xor     eax, eax
3509
        pop     edi
3553
        pop     edi
3510
        ret
3554
        ret
3511
.error:
3555
.error:
3512
        push    eax
3556
        push    eax
3513
        call    fat_unlock
3557
        call    fat_unlock
3514
        pop     eax
3558
        pop     eax
3515
        pop     edi
3559
        pop     edi
3516
        ret
3560
        ret
3517
 
3561
 
3518
;----------------------------------------------------------------
3562
;----------------------------------------------------------------
3519
; fat_SetFileInfo - FAT implementation of setting file info
3563
; fat_SetFileInfo - FAT implementation of setting file info
3520
; in:  ebp = pointer to FAT structure
3564
; in:  ebp = pointer to FAT structure
3521
; in:  esi+[esp+4] = name
3565
; in:  esi+[esp+4] = name
3522
; in:  ebx = pointer to parameters from sysfunc 70
3566
; in:  ebx = pointer to parameters from sysfunc 70
3523
; out: eax, ebx = return values for sysfunc 70
3567
; out: eax, ebx = return values for sysfunc 70
3524
;----------------------------------------------------------------
3568
;----------------------------------------------------------------
3525
fat_SetFileInfo:
3569
fat_SetFileInfo:
3526
        cmp     byte [esi], 0
3570
        cmp     byte [esi], 0
3527
        jnz     @f
3571
        jnz     @f
3528
        mov     eax, 2
3572
        mov     eax, 2
3529
        ret
3573
        ret
3530
@@:
3574
@@:
3531
        push    edi
3575
        push    edi
3532
        call    fat_lock
3576
        call    fat_lock
3533
        stdcall hd_find_lfn, [esp+4+4]
3577
        stdcall hd_find_lfn, [esp+4+4]
3534
        jc      .error
3578
        jc      .error
3535
        push    eax
3579
        push    eax
3536
        mov     edx, [ebx+16]
3580
        mov     edx, [ebx+16]
3537
        call    bdfe_to_fat_entry
3581
        call    bdfe_to_fat_entry
3538
        pop     eax
3582
        pop     eax
3539
        lea     ebx, [ebp+FAT.buffer]
3583
        lea     ebx, [ebp+FAT.buffer]
3540
        call    fs_write32_sys
3584
        call    fs_write32_sys
3541
        call    update_disk
3585
        call    update_disk
3542
        call    fat_unlock
3586
        call    fat_unlock
3543
        pop     edi
3587
        pop     edi
3544
        xor     eax, eax
3588
        xor     eax, eax
3545
        ret
3589
        ret
3546
.error:
3590
.error:
3547
        push    eax
3591
        push    eax
3548
        call    fat_unlock
3592
        call    fat_unlock
3549
        pop     eax
3593
        pop     eax
3550
        pop     edi
3594
        pop     edi
3551
        ret
3595
        ret
3552
 
3596
 
3553
;----------------------------------------------------------------
3597
;----------------------------------------------------------------
3554
; fat_Delete - FAT implementation of deleting a file/folder
3598
; fat_Delete - FAT implementation of deleting a file/folder
3555
; in:  ebp = pointer to FAT structure
3599
; in:  ebp = pointer to FAT structure
3556
; in:  esi+[esp+4] = name
3600
; in:  esi+[esp+4] = name
3557
; in:  ebx = pointer to parameters from sysfunc 70
3601
; in:  ebx = pointer to parameters from sysfunc 70
3558
; out: eax, ebx = return values for sysfunc 70
3602
; out: eax, ebx = return values for sysfunc 70
3559
;----------------------------------------------------------------
3603
;----------------------------------------------------------------
3560
fat_Delete:
3604
fat_Delete:
3561
        call    fat_lock
3605
        call    fat_lock
3562
        cmp     byte [esi], 0
3606
        cmp     byte [esi], 0
3563
        jnz     @f
3607
        jnz     @f
3564
; cannot delete root!
3608
; cannot delete root!
3565
.access_denied:
3609
.access_denied:
3566
        push    ERROR_ACCESS_DENIED
3610
        push    ERROR_ACCESS_DENIED
3567
.pop_ret:
3611
.pop_ret:
3568
        call    fat_unlock
3612
        call    fat_unlock
3569
        pop     eax
3613
        pop     eax
3570
        xor     ebx, ebx
3614
        xor     ebx, ebx
3571
        ret
3615
        ret
3572
@@:
3616
@@:
3573
        and     [ebp+FAT.longname_sec1], 0
3617
        and     [ebp+FAT.longname_sec1], 0
3574
        and     [ebp+FAT.longname_sec2], 0
3618
        and     [ebp+FAT.longname_sec2], 0
3575
        push    edi
3619
        push    edi
3576
        stdcall hd_find_lfn, [esp+4+4]
3620
        stdcall hd_find_lfn, [esp+4+4]
3577
        jnc     .found
3621
        jnc     .found
3578
        pop     edi
3622
        pop     edi
3579
        push    ERROR_FILE_NOT_FOUND
3623
        push    ERROR_FILE_NOT_FOUND
3580
        jmp     .pop_ret
3624
        jmp     .pop_ret
3581
.found:
3625
.found:
3582
        cmp     dword [edi], '.   '
3626
        cmp     dword [edi], '.   '
3583
        jz      .access_denied2
3627
        jz      .access_denied2
3584
        cmp     dword [edi], '..  '
3628
        cmp     dword [edi], '..  '
3585
        jz      .access_denied2
3629
        jz      .access_denied2
3586
        test    byte [edi+11], 10h
3630
        test    byte [edi+11], 10h
3587
        jz      .dodel
3631
        jz      .dodel
3588
; we can delete only empty folders!
3632
; we can delete only empty folders!
3589
        pushad
3633
        pushad
3590
        mov     esi, [edi+20-2]
3634
        mov     esi, [edi+20-2]
3591
        mov     si, [edi+26]
3635
        mov     si, [edi+26]
3592
        xor     ecx, ecx
3636
        xor     ecx, ecx
3593
        lea     eax, [esi-2]
3637
        lea     eax, [esi-2]
3594
        imul    eax, [ebp+FAT.SECTORS_PER_CLUSTER]
3638
        imul    eax, [ebp+FAT.SECTORS_PER_CLUSTER]
3595
        add     eax, [ebp+FAT.DATA_START]
3639
        add     eax, [ebp+FAT.DATA_START]
3596
        lea     ebx, [ebp+FAT.buffer]
3640
        lea     ebx, [ebp+FAT.buffer]
3597
        call    fs_read32_sys
3641
        call    fs_read32_sys
3598
        test    eax, eax
3642
        test    eax, eax
3599
        jnz     .err1
3643
        jnz     .err1
3600
        lea     eax, [ebx+0x200]
3644
        lea     eax, [ebx+0x200]
3601
        add     ebx, 2*0x20
3645
        add     ebx, 2*0x20
3602
.checkempty:
3646
.checkempty:
3603
        cmp     byte [ebx], 0
3647
        cmp     byte [ebx], 0
3604
        jz      .empty
3648
        jz      .empty
3605
        cmp     byte [ebx], 0xE5
3649
        cmp     byte [ebx], 0xE5
3606
        jnz     .notempty
3650
        jnz     .notempty
3607
        add     ebx, 0x20
3651
        add     ebx, 0x20
3608
        cmp     ebx, eax
3652
        cmp     ebx, eax
3609
        jb      .checkempty
3653
        jb      .checkempty
3610
        inc     ecx
3654
        inc     ecx
3611
        cmp     ecx, [ebp+FAT.SECTORS_PER_CLUSTER]
3655
        cmp     ecx, [ebp+FAT.SECTORS_PER_CLUSTER]
3612
        jb      @f
3656
        jb      @f
3613
        mov     eax, esi
3657
        mov     eax, esi
3614
        call    get_FAT
3658
        call    get_FAT
3615
        jc      .err1
3659
        jc      .err1
3616
        cmp     eax, 2
3660
        cmp     eax, 2
3617
        jb      .error_fat
3661
        jb      .error_fat
3618
        cmp     eax, [ebp+FAT.fatRESERVED]
3662
        cmp     eax, [ebp+FAT.fatRESERVED]
3619
        jae     .empty
3663
        jae     .empty
3620
        mov     esi, eax
3664
        mov     esi, eax
3621
        xor     ecx, ecx
3665
        xor     ecx, ecx
3622
@@:
3666
@@:
3623
        lea     eax, [esi-2]
3667
        lea     eax, [esi-2]
3624
        imul    eax, [ebp+FAT.SECTORS_PER_CLUSTER]
3668
        imul    eax, [ebp+FAT.SECTORS_PER_CLUSTER]
3625
        add     eax, [ebp+FAT.DATA_START]
3669
        add     eax, [ebp+FAT.DATA_START]
3626
        add     eax, ecx
3670
        add     eax, ecx
3627
        lea     ebx, [ebp+FAT.buffer]
3671
        lea     ebx, [ebp+FAT.buffer]
3628
        call    fs_read32_sys
3672
        call    fs_read32_sys
3629
        test    eax, eax
3673
        test    eax, eax
3630
        lea     eax, [ebx+0x200]
3674
        lea     eax, [ebx+0x200]
3631
        jz      .checkempty
3675
        jz      .checkempty
3632
.err1:
3676
.err1:
3633
        popad
3677
        popad
3634
.err2:
3678
.err2:
3635
        pop     edi
3679
        pop     edi
3636
        call    fat_unlock
3680
        call    fat_unlock
3637
        movi    eax, ERROR_DEVICE
3681
        movi    eax, ERROR_DEVICE
3638
        ret
3682
        ret
3639
.error_fat:
3683
.error_fat:
3640
        popad
3684
        popad
3641
        pop     edi
3685
        pop     edi
3642
        call    fat_unlock
3686
        call    fat_unlock
3643
        movi    eax, ERROR_FAT_TABLE
3687
        movi    eax, ERROR_FAT_TABLE
3644
        ret
3688
        ret
3645
.notempty:
3689
.notempty:
3646
        popad
3690
        popad
3647
.access_denied2:
3691
.access_denied2:
3648
        pop     edi
3692
        pop     edi
3649
        call    fat_unlock
3693
        call    fat_unlock
3650
        movi    eax, ERROR_ACCESS_DENIED
3694
        movi    eax, ERROR_ACCESS_DENIED
3651
        ret
3695
        ret
3652
.empty:
3696
.empty:
3653
        popad
3697
        popad
3654
        push    eax ebx
3698
        push    eax ebx
3655
        lea     ebx, [ebp+FAT.buffer]
3699
        lea     ebx, [ebp+FAT.buffer]
3656
        call    fs_read32_sys
3700
        call    fs_read32_sys
3657
        test    eax, eax
3701
        test    eax, eax
3658
        pop     ebx eax
3702
        pop     ebx eax
3659
        jnz     .err2
3703
        jnz     .err2
3660
.dodel:
3704
.dodel:
3661
        push    eax
3705
        push    eax
3662
        mov     eax, [edi+20-2]
3706
        mov     eax, [edi+20-2]
3663
        mov     ax, [edi+26]
3707
        mov     ax, [edi+26]
3664
        xchg    eax, [esp]
3708
        xchg    eax, [esp]
3665
; delete folder entry
3709
; delete folder entry
3666
        mov     byte [edi], 0xE5
3710
        mov     byte [edi], 0xE5
3667
; delete LFN (if present)
3711
; delete LFN (if present)
3668
.lfndel:
3712
.lfndel:
3669
        lea     edx, [ebp+FAT.buffer]
3713
        lea     edx, [ebp+FAT.buffer]
3670
        cmp     edi, edx
3714
        cmp     edi, edx
3671
        ja      @f
3715
        ja      @f
3672
        cmp     [ebp+FAT.longname_sec2], 0
3716
        cmp     [ebp+FAT.longname_sec2], 0
3673
        jz      .lfndone
3717
        jz      .lfndone
3674
        push    [ebp+FAT.longname_sec2]
3718
        push    [ebp+FAT.longname_sec2]
3675
        push    [ebp+FAT.longname_sec1]
3719
        push    [ebp+FAT.longname_sec1]
3676
        pop     [ebp+FAT.longname_sec2]
3720
        pop     [ebp+FAT.longname_sec2]
3677
        and     [ebp+FAT.longname_sec1], 0
3721
        and     [ebp+FAT.longname_sec1], 0
3678
        push    ebx
3722
        push    ebx
3679
        mov     ebx, edx
3723
        mov     ebx, edx
3680
        call    fs_write32_sys
3724
        call    fs_write32_sys
3681
        mov     eax, [esp+4]
3725
        mov     eax, [esp+4]
3682
        call    fs_read32_sys
3726
        call    fs_read32_sys
3683
        pop     ebx
3727
        pop     ebx
3684
        pop     eax
3728
        pop     eax
3685
        lea     edi, [ebp+FAT.buffer+0x200]
3729
        lea     edi, [ebp+FAT.buffer+0x200]
3686
@@:
3730
@@:
3687
        sub     edi, 0x20
3731
        sub     edi, 0x20
3688
        cmp     byte [edi], 0xE5
3732
        cmp     byte [edi], 0xE5
3689
        jz      .lfndone
3733
        jz      .lfndone
3690
        cmp     byte [edi+11], 0xF
3734
        cmp     byte [edi+11], 0xF
3691
        jnz     .lfndone
3735
        jnz     .lfndone
3692
        mov     byte [edi], 0xE5
3736
        mov     byte [edi], 0xE5
3693
        jmp     .lfndel
3737
        jmp     .lfndel
3694
.lfndone:
3738
.lfndone:
3695
        push    ebx
3739
        push    ebx
3696
        lea     ebx, [ebp+FAT.buffer]
3740
        lea     ebx, [ebp+FAT.buffer]
3697
        call    fs_write32_sys
3741
        call    fs_write32_sys
3698
        pop     ebx
3742
        pop     ebx
3699
; delete FAT chain
3743
; delete FAT chain
3700
        pop     eax
3744
        pop     eax
3701
        call    clear_cluster_chain
3745
        call    clear_cluster_chain
3702
        call    update_disk
3746
        call    update_disk
3703
        call    fat_unlock
3747
        call    fat_unlock
3704
        pop     edi
3748
        pop     edi
3705
        xor     eax, eax
3749
        xor     eax, eax
3706
        ret
3750
        ret
3707
 
3751
 
3708
; \end{diamond}
3752
; \end{diamond}
3709
>
3753
>
3710
>
3754
>