Subversion Repositories Kolibri OS

Rev

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

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