Subversion Repositories Kolibri OS

Rev

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

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