Subversion Repositories Kolibri OS

Rev

Rev 1664 | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

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