Subversion Repositories Kolibri OS

Rev

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