Subversion Repositories Kolibri OS

Rev

Rev 593 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

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