00001 #include "sysincludes.h"
00002 #include "msdos.h"
00003 #include "stream.h"
00004 #include "mtools.h"
00005 #include "fsP.h"
00006
00007 extern Stream_t *default_drive;
00008
00009 #ifdef HAVE_LONG_LONG
00010 typedef long long fatBitMask;
00011 #else
00012 typedef long fatBitMask;
00013 #endif
00014
00015 typedef struct FatMap_t {
00016 unsigned char *data;
00017 fatBitMask dirty;
00018 fatBitMask valid;
00019 } FatMap_t;
00020
00021 #define SECT_PER_ENTRY (sizeof(fatBitMask)*8)
00022 #define ONE ((fatBitMask) 1)
00023
00024 static inline int readSector(Fs_t *This, char *buf, unsigned int off,
00025 size_t size)
00026 {
00027 return READS(This->Next, buf, sectorsToBytes((Stream_t *)This, off),
00028 size << This->sectorShift);
00029 }
00030
00031
00032 static inline int forceReadSector(Fs_t *This, char *buf, unsigned int off,
00033 size_t size)
00034 {
00035 return force_read(This->Next, buf, sectorsToBytes((Stream_t *)This, off),
00036 size << This->sectorShift);
00037 }
00038
00039
00040 static inline int writeSector(Fs_t *This, char *buf, unsigned int off,
00041 size_t size)
00042 {
00043 return WRITES(This->Next, buf, sectorsToBytes((Stream_t*)This, off),
00044 size << This->sectorShift);
00045 }
00046
00047 static inline int forceWriteSector(Fs_t *This, char *buf, unsigned int off,
00048 size_t size)
00049 {
00050 return force_write(This->Next, buf, sectorsToBytes((Stream_t*)This, off),
00051 size << This->sectorShift);
00052 }
00053
00054
00055 static FatMap_t *GetFatMap(Fs_t *Stream)
00056 {
00057 int nr_entries,i;
00058 FatMap_t *map;
00059
00060 Stream->fat_error = 0;
00061 nr_entries = (Stream->fat_len + SECT_PER_ENTRY - 1) / SECT_PER_ENTRY;
00062 map = NewArray(nr_entries, FatMap_t);
00063 if(!map)
00064 return 0;
00065
00066 for(i=0; i< nr_entries; i++) {
00067 map[i].data = 0;
00068 map[i].valid = 0;
00069 map[i].dirty = 0;
00070 }
00071
00072 return map;
00073 }
00074
00075 static inline int locate(Fs_t *Stream, int offset, int *slot, int *bit)
00076 {
00077 if(offset >= Stream->fat_len)
00078 return -1;
00079 *slot = offset / SECT_PER_ENTRY;
00080 *bit = offset % SECT_PER_ENTRY;
00081 return 0;
00082 }
00083
00084 static inline int fatReadSector(Fs_t *This, int sector, int slot,
00085 int bit, int dupe)
00086 {
00087 int fat_start, ret;
00088
00089 dupe = (dupe + This->primaryFat) % This->num_fat;
00090 fat_start = This->fat_start + This->fat_len * dupe;
00091
00092
00093 ret = readSector(This,
00094 (char *)(This->FatMap[slot].data+(bit<<This->sectorShift)),
00095 fat_start+sector,
00096 (SECT_PER_ENTRY - bit%SECT_PER_ENTRY));
00097 if(ret < 0)
00098 return 0;
00099
00100 if(ret < This->sector_size) {
00101
00102
00103 ret = forceReadSector(This,
00104 (char *) (This->FatMap[slot].data +
00105 (bit << This->sectorShift)),
00106 fat_start+sector, 1);
00107 if(ret < This->sector_size)
00108 return 0;
00109 return 1;
00110 }
00111
00112 return ret >> This->sectorShift;
00113 }
00114
00115
00116 static int fatWriteSector(Fs_t *This, int sector, int slot, int bit, int dupe)
00117 {
00118 int fat_start;
00119
00120 dupe = (dupe + This->primaryFat) % This->num_fat;
00121 if(dupe && !This->writeAllFats)
00122 return This->sector_size;
00123
00124 fat_start = This->fat_start + This->fat_len * dupe;
00125
00126 return forceWriteSector(This,
00127 (char *)
00128 (This->FatMap[slot].data + bit * This->sector_size),
00129 fat_start+sector, 1);
00130 }
00131
00132 static unsigned char *loadSector(Fs_t *This,
00133 unsigned int sector, fatAccessMode_t mode,
00134 int recurs)
00135 {
00136 int slot, bit, i, ret;
00137
00138 if(locate(This,sector, &slot, &bit) < 0)
00139 return 0;
00140 #if 0
00141 if (((This->fat_len + SECT_PER_ENTRY - 1) / SECT_PER_ENTRY) <= slot) {
00142 fprintf(stderr,"This should not happen\n");
00143 fprintf(stderr, "fat_len = %d\n", This->fat_len);
00144 fprintf(stderr, "SECT_PER_ENTRY=%d\n", (int)SECT_PER_ENTRY);
00145 fprintf(stderr, "sector = %d slot = %d bit=%d\n",
00146 sector, slot, bit);
00147 fprintf(stderr, "left = %d",(int)
00148 ((This->fat_len+SECT_PER_ENTRY-1) / SECT_PER_ENTRY));
00149 return 0;
00150 }
00151 #endif
00152 if(!This->FatMap[slot].data) {
00153
00154 This->FatMap[slot].data =
00155 malloc(This->sector_size * SECT_PER_ENTRY);
00156 if(!This->FatMap[slot].data)
00157 return 0;
00158 memset(This->FatMap[slot].data, 0xee,
00159 This->sector_size * SECT_PER_ENTRY);
00160 }
00161
00162 if(! (This->FatMap[slot].valid & (ONE << bit))) {
00163 ret = -1;
00164 for(i=0; i< This->num_fat; i++) {
00165
00166 ret = fatReadSector(This, sector, slot, bit, i);
00167
00168 if(ret == 0) {
00169 fprintf(stderr,
00170 "Error reading fat number %d\n", i);
00171 continue;
00172 }
00173 break;
00174 }
00175
00176
00177 if(ret == 0)
00178 return 0;
00179
00180 for(i=0; i < ret; i++)
00181 This->FatMap[slot].valid |= ONE << (bit + i);
00182
00183 if(!recurs && ret == 1)
00184
00185
00186 loadSector(This, sector+1, mode, 1);
00187 if(!recurs && batchmode)
00188 for(i=0; i < 1024; i++)
00189 loadSector(This, sector+i, mode, 1);
00190 }
00191
00192 if(mode == FAT_ACCESS_WRITE) {
00193 This->FatMap[slot].dirty |= ONE << bit;
00194 This->fat_dirty = 1;
00195 }
00196 return This->FatMap[slot].data + (bit << This->sectorShift);
00197 }
00198
00199
00200 static unsigned char *getAddress(Fs_t *Stream,
00201 unsigned int num, fatAccessMode_t mode)
00202 {
00203 unsigned char *ret;
00204 int sector;
00205 int offset;
00206
00207 sector = num >> Stream->sectorShift;
00208 ret = 0;
00209 if(sector == Stream->lastFatSectorNr &&
00210 Stream->lastFatAccessMode >= mode)
00211 ret = Stream->lastFatSectorData;
00212 if(!ret) {
00213 ret = loadSector(Stream, sector, mode, 0);
00214 if(!ret)
00215 return 0;
00216 Stream->lastFatSectorNr = sector;
00217 Stream->lastFatSectorData = ret;
00218 Stream->lastFatAccessMode = mode;
00219 }
00220 offset = num & Stream->sectorMask;
00221 return ret+offset;
00222 }
00223
00224
00225 static int readByte(Fs_t *Stream, int start)
00226 {
00227 unsigned char *address;
00228
00229 address = getAddress(Stream, start, FAT_ACCESS_READ);
00230 if(!address)
00231 return -1;
00232 return *address;
00233 }
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254 static unsigned int fat12_decode(Fs_t *Stream, unsigned int num)
00255 {
00256 unsigned int start = num * 3 / 2;
00257 int byte0 = readByte(Stream, start);
00258 int byte1 = readByte(Stream, start+1);
00259
00260 if (num < 2 || byte0 < 0 || byte1 < 0 || num > Stream->num_clus+1) {
00261 fprintf(stderr,"[1] Bad address %d\n", num);
00262 return 1;
00263 }
00264
00265 if (num & 1)
00266 return (byte1 << 4) | ((byte0 & 0xf0)>>4);
00267 else
00268 return ((byte1 & 0xf) << 8) | byte0;
00269 }
00270
00271
00272
00273
00274
00275
00276 static void fat12_encode(Fs_t *Stream, unsigned int num, unsigned int code)
00277 {
00278 int start = num * 3 / 2;
00279 unsigned char *address0 = getAddress(Stream, start, FAT_ACCESS_WRITE);
00280 unsigned char *address1 = getAddress(Stream, start+1, FAT_ACCESS_WRITE);
00281
00282 if (num & 1) {
00283
00284 *address0 = (*address0 & 0x0f) | ((code << 4) & 0xf0);
00285 *address1 = (code >> 4) & 0xff;
00286 } else {
00287
00288 *address0 = code & 0xff;
00289 *address1 = (*address1 & 0xf0) | ((code >> 8) & 0x0f);
00290 }
00291 }
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302 static unsigned int fat16_decode(Fs_t *Stream, unsigned int num)
00303 {
00304 unsigned char *address = getAddress(Stream, num << 1, FAT_ACCESS_READ);
00305 return _WORD(address);
00306 }
00307
00308 static void fat16_encode(Fs_t *Stream, unsigned int num, unsigned int code)
00309 {
00310 unsigned char *address = getAddress(Stream, num << 1, FAT_ACCESS_WRITE);
00311 set_word(address, code);
00312 }
00313
00314
00315 static unsigned int fast_fat16_decode(Fs_t *Stream, unsigned int num)
00316 {
00317 unsigned short *address =
00318 (unsigned short *) getAddress(Stream, num << 1,
00319 FAT_ACCESS_READ);
00320 return *address;
00321 }
00322
00323 static void fast_fat16_encode(Fs_t *Stream, unsigned int num, unsigned int code)
00324 {
00325 unsigned short *address =
00326 (unsigned short *) getAddress(Stream, num << 1,
00327 FAT_ACCESS_WRITE);
00328 *address = code;
00329 }
00330
00331
00332
00333
00334
00335
00336
00337 static unsigned int fat32_decode(Fs_t *Stream, unsigned int num)
00338 {
00339 unsigned char *address = getAddress(Stream, num << 2, FAT_ACCESS_READ);
00340 return _DWORD(address);
00341 }
00342
00343 static void fat32_encode(Fs_t *Stream, unsigned int num, unsigned int code)
00344 {
00345 unsigned char *address = getAddress(Stream, num << 2, FAT_ACCESS_WRITE);
00346 set_dword(address, code);
00347 }
00348
00349
00350 static unsigned int fast_fat32_decode(Fs_t *Stream, unsigned int num)
00351 {
00352 unsigned int *address =
00353 (unsigned int *) getAddress(Stream, num << 2,
00354 FAT_ACCESS_READ);
00355 return *address;
00356 }
00357
00358 static void fast_fat32_encode(Fs_t *Stream, unsigned int num, unsigned int code)
00359 {
00360 unsigned int *address =
00361 (unsigned int *) getAddress(Stream, num << 2,
00362 FAT_ACCESS_WRITE);
00363 *address = code;
00364 }
00365
00366
00367
00368
00369
00370
00371
00372
00373 void fat_write(Fs_t *This)
00374 {
00375 int i, j, dups, ret, bit, slot;
00376 int fat_start;
00377
00378
00379
00380 if (!This->fat_dirty)
00381 return;
00382
00383 dups = This->num_fat;
00384 if (This->fat_error)
00385 dups = 1;
00386
00387
00388 for(i=0; i<dups; i++){
00389 j = 0;
00390 fat_start = This->fat_start + i*This->fat_len;
00391 for(slot=0;j<This->fat_len;slot++) {
00392 if(!This->FatMap[slot].dirty) {
00393 j += SECT_PER_ENTRY;
00394 continue;
00395 }
00396 for(bit=0;
00397 bit < SECT_PER_ENTRY && j<This->fat_len;
00398 bit++,j++) {
00399 if(!(This->FatMap[slot].dirty & (ONE << bit)))
00400 continue;
00401 ret = fatWriteSector(This,j,slot, bit, i);
00402 if (ret < This->sector_size){
00403 if (ret < 0 ){
00404 perror("error in fat_write");
00405 exit(1);
00406 } else {
00407 fprintf(stderr,
00408 "end of file in fat_write\n");
00409 exit(1);
00410 }
00411 }
00412
00413 if(i==dups-1)
00414 This->FatMap[slot].dirty &= ~(1<<bit);
00415 }
00416 }
00417 }
00418
00419 if(This->infoSectorLoc && This->infoSectorLoc != MAX32) {
00420
00421 InfoSector_t *infoSector;
00422 infoSector = (InfoSector_t *) safe_malloc(This->sector_size);
00423 set_dword(infoSector->signature1, INFOSECT_SIGNATURE1);
00424 memset(infoSector->filler1, sizeof(infoSector->filler1),0);
00425 memset(infoSector->filler2, sizeof(infoSector->filler2),0);
00426 set_dword(infoSector->signature2, INFOSECT_SIGNATURE2);
00427 set_dword(infoSector->pos, This->last);
00428 set_dword(infoSector->count, This->freeSpace);
00429 set_dword(infoSector->signature3, 0xaa55);
00430 if(forceWriteSector(This, (char *)infoSector, This->infoSectorLoc, 1) !=
00431 This->sector_size)
00432 fprintf(stderr,"Trouble writing the info sector\n");
00433 free(infoSector);
00434 }
00435 This->fat_dirty = 0;
00436 This->lastFatAccessMode = FAT_ACCESS_READ;
00437 }
00438
00439
00440
00441
00442
00443
00444
00445 int zero_fat(Fs_t *Stream, int media_descriptor)
00446 {
00447 int i, j;
00448 int fat_start;
00449 unsigned char *buf;
00450
00451 buf = malloc(Stream->sector_size);
00452 if(!buf) {
00453 perror("alloc fat sector buffer");
00454 return -1;
00455 }
00456 for(i=0; i< Stream->num_fat; i++) {
00457 fat_start = Stream->fat_start + i*Stream->fat_len;
00458 for(j = 0; j < Stream->fat_len; j++) {
00459 if(j <= 1)
00460 memset(buf, 0, Stream->sector_size);
00461 if(!j) {
00462 buf[0] = media_descriptor;
00463 buf[2] = buf[1] = 0xff;
00464 if(Stream->fat_bits > 12)
00465 buf[3] = 0xff;
00466 if(Stream->fat_bits > 16) {
00467 buf[4] = 0xff;
00468 buf[5] = 0xff;
00469 buf[6] = 0xff;
00470 buf[7] = 0x0f;
00471 }
00472 }
00473
00474 if(forceWriteSector(Stream, (char *)buf,
00475 fat_start + j, 1) !=
00476 Stream->sector_size) {
00477 fprintf(stderr,
00478 "Trouble initializing a FAT sector\n");
00479 free(buf);
00480 return -1;
00481 }
00482 }
00483 }
00484
00485 free(buf);
00486 Stream->FatMap = GetFatMap(Stream);
00487 if (Stream->FatMap == NULL) {
00488 perror("alloc fat map");
00489 return -1;
00490 }
00491 return 0;
00492 }
00493
00494
00495 void set_fat12(Fs_t *This)
00496 {
00497 This->fat_bits = 12;
00498 This->end_fat = 0xfff;
00499 This->last_fat = 0xff6;
00500 This->fat_decode = fat12_decode;
00501 This->fat_encode = fat12_encode;
00502 }
00503
00504 static char word_endian_test[] = { 0x34, 0x12 };
00505
00506 void set_fat16(Fs_t *This)
00507 {
00508 This->fat_bits = 16;
00509 This->end_fat = 0xffff;
00510 This->last_fat = 0xfff6;
00511
00512 if(sizeof(unsigned short) == 2 &&
00513 * (unsigned short *) word_endian_test == 0x1234) {
00514 This->fat_decode = fast_fat16_decode;
00515 This->fat_encode = fast_fat16_encode;
00516 } else {
00517 This->fat_decode = fat16_decode;
00518 This->fat_encode = fat16_encode;
00519 }
00520 }
00521
00522 static char dword_endian_test[] = { 0x78, 0x56, 0x34, 0x12 };
00523
00524 void set_fat32(Fs_t *This)
00525 {
00526 This->fat_bits = 32;
00527 This->end_fat = 0xfffffff;
00528 This->last_fat = 0xffffff6;
00529
00530 if(sizeof(unsigned int) == 4 &&
00531 * (unsigned int *) dword_endian_test == 0x12345678) {
00532 This->fat_decode = fast_fat32_decode;
00533 This->fat_encode = fast_fat32_encode;
00534 } else {
00535 This->fat_decode = fat32_decode;
00536 This->fat_encode = fat32_encode;
00537 }
00538 }
00539
00540
00541 static int check_fat(Fs_t *This)
00542 {
00543
00544
00545
00546
00547
00548 int i, f, tocheck;
00549 if(mtools_skip_check)
00550 return 0;
00551
00552
00553 if(This->fat_len < NEEDED_FAT_SIZE(This))
00554 return -1;
00555
00556
00557
00558
00559 tocheck = This->num_clus;
00560 if (tocheck < 0 || tocheck + 1 >= This->last_fat) {
00561 fprintf(stderr, "Too many clusters in FAT\n");
00562 return -1;
00563 }
00564
00565 if(tocheck > 4096)
00566 tocheck = 4096;
00567
00568 for ( i= 3 ; i < tocheck; i++){
00569 f = This->fat_decode(This,i);
00570 if (f == 1 || (f < This->last_fat && f > This->num_clus)){
00571 fprintf(stderr,
00572 "Cluster # at %d too big(%#x)\n", i,f);
00573 fprintf(stderr,"Probably non MS-DOS disk\n");
00574 return -1;
00575 }
00576 }
00577 return 0;
00578 }
00579
00580
00581
00582
00583
00584
00585 static int check_media_type(Fs_t *This, struct bootsector *boot,
00586 unsigned int tot_sectors)
00587 {
00588 unsigned char *address;
00589
00590 This->num_clus = (tot_sectors - This->clus_start) / This->cluster_size;
00591
00592 This->FatMap = GetFatMap(This);
00593 if (This->FatMap == NULL) {
00594 perror("alloc fat map");
00595 return -1;
00596 }
00597
00598 address = getAddress(This, 0, FAT_ACCESS_READ);
00599 if(!address) {
00600 fprintf(stderr,
00601 "Could not read first FAT sector\n");
00602 return -1;
00603 }
00604
00605 if(mtools_skip_check)
00606 return 0;
00607
00608 if(!address[0] && !address[1] && !address[2])
00609
00610
00611 return 0;
00612
00613 if((address[0] != boot->descr && boot->descr >= 0xf0 &&
00614 ((address[0] != 0xf9 && address[0] != 0xf7)
00615 || boot->descr != 0xf0)) || address[0] < 0xf0) {
00616 fprintf(stderr,
00617 "Bad media types %02x/%02x, probably non-MSDOS disk\n",
00618 address[0],
00619 boot->descr);
00620 return -1;
00621 }
00622
00623 if(address[1] != 0xff || address[2] != 0xff){
00624 fprintf(stderr,"Initial byte of fat is not 0xff\n");
00625 return -1;
00626 }
00627
00628 return 0;
00629 }
00630
00631 static int fat_32_read(Fs_t *This, struct bootsector *boot,
00632 unsigned int tot_sectors)
00633 {
00634 int size;
00635
00636 This->fat_len = DWORD(ext.fat32.bigFat);
00637 This->writeAllFats = !(boot->ext.fat32.extFlags[0] & 0x80);
00638 This->primaryFat = boot->ext.fat32.extFlags[0] & 0xf;
00639 This->rootCluster = DWORD(ext.fat32.rootCluster);
00640 This->clus_start = This->fat_start + This->num_fat * This->fat_len;
00641
00642
00643 size = This->sector_size;
00644 This->infoSectorLoc = WORD(ext.fat32.infoSector);
00645 if(This->sector_size >= 512 &&
00646 This->infoSectorLoc && This->infoSectorLoc != MAX32) {
00647 InfoSector_t *infoSector;
00648 infoSector = (InfoSector_t *) safe_malloc(size);
00649 if(forceReadSector(This, (char *)infoSector,
00650 This->infoSectorLoc, 1) == This->sector_size &&
00651 _DWORD(infoSector->signature1) == INFOSECT_SIGNATURE1 &&
00652 _DWORD(infoSector->signature2) == INFOSECT_SIGNATURE2) {
00653 This->freeSpace = _DWORD(infoSector->count);
00654 This->last = _DWORD(infoSector->pos);
00655 }
00656 free(infoSector);
00657 }
00658
00659 set_fat32(This);
00660 return(check_media_type(This,boot, tot_sectors) ||
00661 check_fat(This));
00662 }
00663
00664
00665 static int old_fat_read(Fs_t *This, struct bootsector *boot,
00666 int config_fat_bits,
00667 size_t tot_sectors, int nodups)
00668 {
00669 This->writeAllFats = 1;
00670 This->primaryFat = 0;
00671 This->dir_start = This->fat_start + This->num_fat * This->fat_len;
00672 This->clus_start = This->dir_start + This->dir_len;
00673 This->infoSectorLoc = MAX32;
00674
00675 if(nodups)
00676 This->num_fat = 1;
00677
00678 if(check_media_type(This,boot, tot_sectors))
00679 return -1;
00680
00681 if(This->num_clus > FAT12) {
00682 set_fat16(This);
00683
00684 if(!mtools_skip_check && readByte(This, 3) != 0xff)
00685 return -1;
00686 } else
00687 set_fat12(This);
00688
00689 return check_fat(This);
00690 }
00691
00692
00693
00694
00695
00696 int fat_read(Fs_t *This, struct bootsector *boot, int fat_bits,
00697 size_t tot_sectors, int nodups)
00698 {
00699 This->fat_error = 0;
00700 This->fat_dirty = 0;
00701 This->last = MAX32;
00702 This->freeSpace = MAX32;
00703 This->lastFatSectorNr = 0;
00704 This->lastFatSectorData = 0;
00705
00706 if(This->fat_len)
00707 return old_fat_read(This, boot, fat_bits, tot_sectors, nodups);
00708 else
00709 return fat_32_read(This, boot, tot_sectors);
00710 }
00711
00712
00713 unsigned int fatDecode(Fs_t *This, unsigned int pos)
00714 {
00715 int ret;
00716
00717 ret = This->fat_decode(This, pos);
00718 if(ret && (ret < 2 || ret > This->num_clus+1) && ret < This->last_fat) {
00719 fprintf(stderr, "Bad FAT entry %d at %d\n", ret, pos);
00720 This->fat_error++;
00721 }
00722 return ret;
00723 }
00724
00725
00726 void fatAppend(Fs_t *This, unsigned int pos, unsigned int newpos)
00727 {
00728 This->fat_encode(This, pos, newpos);
00729 This->fat_encode(This, newpos, This->end_fat);
00730 if(This->freeSpace != MAX32)
00731 This->freeSpace--;
00732 }
00733
00734
00735 void fatDeallocate(Fs_t *This, unsigned int pos)
00736 {
00737 This->fat_encode(This, pos, 0);
00738 if(This->freeSpace != MAX32)
00739 This->freeSpace++;
00740 }
00741
00742
00743 void fatAllocate(Fs_t *This, unsigned int pos, unsigned int value)
00744 {
00745 This->fat_encode(This, pos, value);
00746 if(This->freeSpace != MAX32)
00747 This->freeSpace--;
00748 }
00749
00750 void fatEncode(Fs_t *This, unsigned int pos, unsigned int value)
00751 {
00752 unsigned int oldvalue = This->fat_decode(This, pos);
00753 This->fat_encode(This, pos, value);
00754 if(This->freeSpace != MAX32) {
00755 if(oldvalue)
00756 This->freeSpace++;
00757 if(value)
00758 This->freeSpace--;
00759 }
00760 }
00761
00762 unsigned int get_next_free_cluster(Fs_t *This, unsigned int last)
00763 {
00764 int i;
00765
00766 if(This->last != MAX32)
00767 last = This->last;
00768
00769 if (last < 2 ||
00770 last >= This->num_clus+1)
00771 last = 1;
00772
00773 for (i=last+1; i< This->num_clus+2; i++) {
00774 if (!fatDecode(This, i)) {
00775 This->last = i;
00776 return i;
00777 }
00778 }
00779
00780 for(i=2; i < last+1; i++) {
00781 if (!fatDecode(This, i)) {
00782 This->last = i;
00783 return i;
00784 }
00785 }
00786
00787
00788 fprintf(stderr,"No free cluster %d %d\n", This->preallocatedClusters,
00789 This->last);
00790 return 1;
00791 }
00792
00793 int fat_error(Stream_t *Dir)
00794 {
00795 Stream_t *Stream = GetFs(Dir);
00796 DeclareThis(Fs_t);
00797
00798 if(This->fat_error)
00799 fprintf(stderr,"Fat error detected\n");
00800
00801 return This->fat_error;
00802 }
00803
00804 int fat32RootCluster(Stream_t *Dir)
00805 {
00806 Stream_t *Stream = GetFs(Dir);
00807 DeclareThis(Fs_t);
00808
00809 if(This->fat_bits == 32)
00810 return This->rootCluster;
00811 else
00812 return 0;
00813 }
00814
00815
00816
00817
00818
00819
00820 mt_size_t getfree(Stream_t *Dir)
00821 {
00822 Stream_t *Stream = GetFs(Dir);
00823 DeclareThis(Fs_t);
00824
00825 if(This->freeSpace == MAX32 || This->freeSpace == 0) {
00826 register unsigned int i;
00827 size_t total;
00828
00829 total = 0L;
00830 for (i = 2; i < This->num_clus + 2; i++)
00831 if (!fatDecode(This,i))
00832 total++;
00833 This->freeSpace = total;
00834 }
00835 return sectorsToBytes((Stream_t*)This,
00836 This->freeSpace * This->cluster_size);
00837 }
00838
00839
00840
00841
00842
00843 int getfreeMinClusters(Stream_t *Dir, size_t size)
00844 {
00845 Stream_t *Stream = GetFs(Dir);
00846 DeclareThis(Fs_t);
00847 register unsigned int i, last;
00848 size_t total;
00849
00850 if(batchmode && This->freeSpace == MAX32)
00851 getfree(Stream);
00852
00853 if(This->freeSpace != MAX32) {
00854 if(This->freeSpace >= size)
00855 return 1;
00856 else {
00857 fprintf(stderr, "Disk full\n");
00858 got_signal = 1;
00859 return 0;
00860 }
00861 }
00862
00863 total = 0L;
00864
00865
00866
00867
00868
00869 last = This->last;
00870
00871 if ( last < 2 || last >= This->num_clus + 2)
00872 last = 1;
00873 for (i=last+1; i< This->num_clus+2; i++){
00874 if (!fatDecode(This, i))
00875 total++;
00876 if(total >= size)
00877 return 1;
00878 }
00879 for(i=2; i < last+1; i++){
00880 if (!fatDecode(This, i))
00881 total++;
00882 if(total >= size)
00883 return 1;
00884 }
00885 fprintf(stderr, "Disk full\n");
00886 got_signal = 1;
00887 return 0;
00888 }
00889
00890
00891 int getfreeMinBytes(Stream_t *Dir, mt_size_t size)
00892 {
00893 Stream_t *Stream = GetFs(Dir);
00894 DeclareThis(Fs_t);
00895 size_t size2;
00896
00897 size2 = size / (This->sector_size * This->cluster_size);
00898 if(size % (This->sector_size * This->cluster_size))
00899 size2++;
00900 return getfreeMinClusters(Dir, size2);
00901 }
00902
00903
00904 unsigned int getStart(Stream_t *Dir, struct directory *dir)
00905 {
00906 Stream_t *Stream = GetFs(Dir);
00907 unsigned int first;
00908
00909 first = START(dir);
00910 if(fat32RootCluster(Stream))
00911 first |= STARTHI(dir) << 16;
00912 return first;
00913 }
00914
00915 int fs_free(Stream_t *Stream)
00916 {
00917 DeclareThis(Fs_t);
00918
00919 if(This->FatMap) {
00920 int i, nr_entries;
00921 nr_entries = (This->fat_len + SECT_PER_ENTRY - 1) /
00922 SECT_PER_ENTRY;
00923 for(i=0; i< nr_entries; i++)
00924 if(This->FatMap[i].data)
00925 free(This->FatMap[i].data);
00926 free(This->FatMap);
00927 }
00928 return 0;
00929 }