Subversion Repositories Kolibri OS

Rev

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

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