Subversion Repositories Kolibri OS

Rev

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

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