Subversion Repositories Kolibri OS

Rev

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

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