Subversion Repositories Kolibri OS

Rev

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

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