26#ifdef BUILDING_USBHDFSD
29#ifdef BUILDING_IEEE1394_DISK
32#include "usbhd_common.h"
33#include "fat_driver.h"
36#ifdef BUILDING_USBHDFSD
39#ifdef BUILDING_IEEE1394_DISK
45#include "mass_debug.h"
50#define READ_SECTOR(d, a, b) scache_readSector((d)->cache, (a), (void **)&b)
51#define ALLOC_SECTOR(d, a, b) scache_readSector((d)->cache, (a), (void **)&b)
52#define WRITE_SECTOR(d, a) scache_writeSector((d)->cache, (a))
53#define FLUSH_SECTORS(d) scache_flushSectors((d)->cache)
54#if !defined(BUILDING_IEEE1394_DISK) && !defined(BUILDING_USBHDFSD)
55#define DEV_ACCESSOR(d) (d)
57#define DEV_ACCESSOR(d) ((d)->dev)
59#ifdef BUILDING_USBHDFSD
60#define WRITE_SECTORS_RAW(d, a, c, b) mass_stor_writeSector((d), a, b, c);
61#define INVALIDATE_SECTORS(d, s, c) scache_invalidate((d)->cache, s, c)
68static void swapClStack(
fat_driver *fatd,
int startIndex,
int endIndex)
73 size = endIndex - startIndex;
79 for (i = 0; i < size; i++) {
83 offset1 = startIndex + i;
84 offset2 = endIndex - 1 - i;
85 tmp = fatd->clStack[offset1];
86 fatd->clStack[offset1] = fatd->clStack[offset2];
87 fatd->clStack[offset2] = tmp;
96static int fat_readEmptyClusters12(
fat_driver *fatd)
100 unsigned int cluster;
101 unsigned int clusterValue;
102 unsigned char xbuf[4];
104 unsigned char *sbuf = NULL;
106 oldClStackIndex = fatd->clStackIndex;
109 cluster = fatd->clStackLast;
111 while (fatd->clStackIndex < MAX_CLUSTER_STACK) {
116 recordOffset = (cluster * 3) / 2;
117 fatSector = recordOffset / fatd->partBpb.sectorSize;
119 if ((recordOffset % fatd->partBpb.sectorSize) == (fatd->partBpb.sectorSize - 1)) {
122 if (lastFatSector != fatSector || sectorSpan) {
123 ret = READ_SECTOR(DEV_ACCESSOR(fatd), fatd->partBpb.partStart + fatd->partBpb.resSectors + fatSector, sbuf);
125 XPRINTF(
"Read fat12 sector failed! sector=%u! \n", fatd->partBpb.partStart + fatd->partBpb.resSectors + fatSector);
128 lastFatSector = fatSector;
131 xbuf[0] = sbuf[fatd->partBpb.sectorSize - 2];
132 xbuf[1] = sbuf[fatd->partBpb.sectorSize - 1];
133 ret = READ_SECTOR(DEV_ACCESSOR(fatd), fatd->partBpb.partStart + fatd->partBpb.resSectors + fatSector + 1, sbuf);
135 XPRINTF(
"Read fat12 sector failed sector=%u! \n", fatd->partBpb.partStart + fatd->partBpb.resSectors + fatSector + 1);
143 clusterValue = fat_getClusterRecord12(xbuf + (recordOffset % fatd->partBpb.sectorSize) - (fatd->partBpb.sectorSize - 2), cluster % 2);
145 clusterValue = fat_getClusterRecord12(sbuf + (recordOffset % fatd->partBpb.sectorSize), cluster % 2);
147 if (clusterValue == 0) {
148 fatd->clStackLast = cluster;
149 fatd->clStack[fatd->clStackIndex] = cluster;
150 fatd->clStackIndex++;
158 swapClStack(fatd, oldClStackIndex, fatd->clStackIndex);
159 return fatd->clStackIndex;
167static int fat_readEmptyClusters32(
fat_driver *fatd)
170 unsigned int indexCount;
171 unsigned int fatStartSector;
172 unsigned int cluster;
173 unsigned int clusterValue;
178 oldClStackIndex = fatd->clStackIndex;
181 indexCount = fatd->partBpb.sectorSize / 4;
183 sectorSkip = fatd->clStackLast / indexCount;
184 recordSkip = fatd->clStackLast % indexCount;
186 fatStartSector = fatd->partBpb.partStart + fatd->partBpb.resSectors;
188 for (i = sectorSkip; i < fatd->partBpb.fatSize && fatd->clStackIndex < MAX_CLUSTER_STACK; i++) {
191 unsigned char *sbuf = NULL;
193 ret = READ_SECTOR(DEV_ACCESSOR(fatd), fatStartSector + i, sbuf);
195 XPRINTF(
"Read fat32 sector failed! sector=%u! \n", fatStartSector + i);
198 for (j = recordSkip; j < indexCount && fatd->clStackIndex < MAX_CLUSTER_STACK; j++) {
199 cluster = getUI32(sbuf + (j * 4));
201 clusterValue = (i * indexCount) + j;
202 if (clusterValue < 0xFFFFFF7) {
203 fatd->clStackLast = clusterValue;
204 fatd->clStack[fatd->clStackIndex] = clusterValue;
205 fatd->clStackIndex++;
215 swapClStack(fatd, oldClStackIndex, fatd->clStackIndex);
216 return fatd->clStackIndex;
223static int fat_readEmptyClusters16(
fat_driver *fatd)
226 unsigned int indexCount;
227 unsigned int fatStartSector;
228 unsigned int cluster;
233 oldClStackIndex = fatd->clStackIndex;
237 indexCount = fatd->partBpb.sectorSize / 2;
240 sectorSkip = fatd->clStackLast / indexCount;
241 recordSkip = fatd->clStackLast % indexCount;
243 fatStartSector = fatd->partBpb.partStart + fatd->partBpb.resSectors;
245 for (i = sectorSkip; i < fatd->partBpb.fatSize && fatd->clStackIndex < MAX_CLUSTER_STACK; i++) {
248 unsigned char *sbuf = NULL;
250 ret = READ_SECTOR(DEV_ACCESSOR(fatd), fatStartSector + i, sbuf);
252 XPRINTF(
"Read fat16 sector failed! sector=%u! \n", fatStartSector + i);
255 for (j = recordSkip; j < indexCount && fatd->clStackIndex < MAX_CLUSTER_STACK; j++) {
256 cluster = getUI16(sbuf + (j * 2));
258 fatd->clStackLast = (i * indexCount) + j;
259 fatd->clStack[fatd->clStackIndex] = fatd->clStackLast;
260 XPRINTF(
"%u ", fatd->clStack[fatd->clStackIndex]);
261 fatd->clStackIndex++;
271 swapClStack(fatd, oldClStackIndex, fatd->clStackIndex);
272 return fatd->clStackIndex;
279static int fat_readEmptyClusters(
fat_driver *fatd)
281 switch (fatd->partBpb.fatType) {
283 return fat_readEmptyClusters12(fatd);
285 return fat_readEmptyClusters16(fatd);
287 return fat_readEmptyClusters32(fatd);
306static void fat_setClusterRecord12(
unsigned char *buf,
unsigned int cluster,
int type)
310 buf[0] = (buf[0] & 0x0F) + ((cluster & 0x0F) << 4);
311 buf[1] = (cluster & 0xFF0) >> 4;
313 buf[0] = (cluster & 0xFF);
314 buf[1] = (buf[1] & 0xF0) + ((cluster & 0xF00) >> 8);
319static void fat_setClusterRecord12part1(
unsigned char *buf,
unsigned int cluster,
int type)
322 buf[0] = (buf[0] & 0x0F) + ((cluster & 0x0F) << 4);
324 buf[0] = (cluster & 0xFF);
329static void fat_setClusterRecord12part2(
unsigned char *buf,
unsigned int cluster,
int type)
332 buf[0] = (cluster & 0xFF0) >> 4;
334 buf[0] = (buf[0] & 0xF0) + ((cluster & 0xF00) >> 8);
342static int fat_saveClusterRecord12(
fat_driver *fatd,
unsigned int currentCluster,
unsigned int value)
350 recordOffset = (currentCluster * 3) / 2;
353 for (fatNumber = 0; fatNumber < fatd->partBpb.fatCount; fatNumber++) {
356 unsigned int fatSector;
358 unsigned char *sbuf = NULL;
360 fatSector = fatd->partBpb.partStart + fatd->partBpb.resSectors + (fatNumber * fatd->partBpb.fatSize);
361 fatSector += recordOffset / fatd->partBpb.sectorSize;
362 sectorSpan = fatd->partBpb.sectorSize - (recordOffset % fatd->partBpb.sectorSize);
363 if (sectorSpan > 1) {
366 recordType = currentCluster % 2;
368 ret = READ_SECTOR(DEV_ACCESSOR(fatd), fatSector, sbuf);
370 XPRINTF(
"Read fat16 sector failed! sector=%u! \n", fatSector);
374 fat_setClusterRecord12(sbuf + (recordOffset % fatd->partBpb.sectorSize), value, recordType);
375 ret = WRITE_SECTOR(DEV_ACCESSOR(fatd), fatSector);
377 XPRINTF(
"Write fat12 sector failed! sector=%u! \n", fatSector);
382 fat_setClusterRecord12part1(sbuf + (recordOffset % fatd->partBpb.sectorSize), value, recordType);
384 ret = WRITE_SECTOR(DEV_ACCESSOR(fatd), fatSector);
386 XPRINTF(
"Write fat12 sector failed! sector=%u! \n", fatSector);
391 ret = READ_SECTOR(DEV_ACCESSOR(fatd), fatSector, sbuf);
393 XPRINTF(
"Read fat16 sector failed! sector=%u! \n", fatSector);
397 fat_setClusterRecord12part2(sbuf, value, recordType);
399 ret = WRITE_SECTOR(DEV_ACCESSOR(fatd), fatSector);
401 XPRINTF(
"Write fat12 sector failed! sector=%u! \n", fatSector);
413static int fat_saveClusterRecord16(
fat_driver *fatd,
unsigned int currentCluster,
unsigned int value)
421 indexCount = fatd->partBpb.sectorSize / 2;
424 for (fatNumber = 0; fatNumber < fatd->partBpb.fatCount; fatNumber++) {
426 unsigned int fatSector;
428 unsigned char *sbuf = NULL;
430 fatSector = fatd->partBpb.partStart + fatd->partBpb.resSectors + (fatNumber * fatd->partBpb.fatSize);
431 fatSector += currentCluster / indexCount;
433 ret = READ_SECTOR(DEV_ACCESSOR(fatd), fatSector, sbuf);
435 XPRINTF(
"Read fat16 sector failed! sector=%u! \n", fatSector);
438 i = currentCluster % indexCount;
440 sbuf[i++] = value & 0xFF;
441 sbuf[i] = ((value & 0xFF00) >> 8);
442 ret = WRITE_SECTOR(DEV_ACCESSOR(fatd), fatSector);
444 XPRINTF(
"Write fat16 sector failed! sector=%u! \n", fatSector);
455static int fat_saveClusterRecord32(
fat_driver *fatd,
unsigned int currentCluster,
unsigned int value)
463 indexCount = fatd->partBpb.sectorSize / 4;
466 for (fatNumber = 0; fatNumber < fatd->partBpb.fatCount; fatNumber++) {
468 unsigned int fatSector;
470 unsigned char *sbuf = NULL;
472 fatSector = fatd->partBpb.partStart + fatd->partBpb.resSectors + (fatNumber * fatd->partBpb.fatSize);
473 fatSector += currentCluster / indexCount;
475 ret = READ_SECTOR(DEV_ACCESSOR(fatd), fatSector, sbuf);
477 XPRINTF(
"Read fat32 sector failed! sector=%u! \n", fatSector);
480 i = currentCluster % indexCount;
482 sbuf[i++] = value & 0xFF;
483 sbuf[i++] = ((value & 0xFF00) >> 8);
484 sbuf[i++] = ((value & 0xFF0000) >> 16);
485 sbuf[i] = (sbuf[i] & 0xF0) + ((value >> 24) & 0x0F);
487 ret = WRITE_SECTOR(DEV_ACCESSOR(fatd), fatSector);
489 XPRINTF(
"Write fat32 sector failed! sector=%u! \n", fatSector);
525static int fat_appendClusterChain(
fat_driver *fatd,
unsigned int currentCluster,
unsigned int endCluster)
529 switch (fatd->partBpb.fatType) {
531 ret = fat_saveClusterRecord12(fatd, currentCluster, endCluster);
534 ret = fat_saveClusterRecord12(fatd, endCluster, 0xFFF);
538 XPRINTF(
"I: appending cluster chain : current=%u end=%u \n", currentCluster, endCluster);
539 ret = fat_saveClusterRecord16(fatd, currentCluster, endCluster);
542 ret = fat_saveClusterRecord16(fatd, endCluster, 0xFFFF);
546 ret = fat_saveClusterRecord32(fatd, currentCluster, endCluster);
549 ret = fat_saveClusterRecord32(fatd, endCluster, 0xFFFFFFF);
559static int fat_createClusterChain(
fat_driver *fatd,
unsigned int cluster)
561 switch (fatd->partBpb.fatType) {
563 return fat_saveClusterRecord12(fatd, cluster, 0xFFF);
565 return fat_saveClusterRecord16(fatd, cluster, 0xFFFF);
567 return fat_saveClusterRecord32(fatd, cluster, 0xFFFFFFF);
576static int fat_modifyClusterChain(
fat_driver *fatd,
unsigned int cluster,
unsigned int value)
578 switch (fatd->partBpb.fatType) {
580 return fat_saveClusterRecord12(fatd, cluster, value);
582 return fat_saveClusterRecord16(fatd, cluster, value);
584 return fat_saveClusterRecord32(fatd, cluster, value);
593static int fat_deleteClusterChain(
fat_driver *fatd,
unsigned int cluster)
602 XPRINTF(
"I: delete cluster chain starting at cluster=%u\n", cluster);
610 size = fat_getClusterChain(fatd, cluster, fatd->cbuf, MAX_DIR_CLUSTER, 1);
614 for (i = 0; i < end; i++) {
615 ret = fat_modifyClusterChain(fatd, fatd->cbuf[i], 0);
621 if (size == MAX_DIR_CLUSTER) {
622 cluster = fatd->cbuf[end];
625 ret = fat_modifyClusterChain(fatd, fatd->cbuf[end], 0);
631 fat_invalidateLastChainResult(fatd);
642static unsigned int fat_getFreeCluster(
fat_driver *fatd,
unsigned int currentCluster)
649 if (fatd->clStackIndex <= 0) {
650 fatd->clStackIndex = 0;
651 ret = fat_readEmptyClusters(fatd);
654 fatd->clStackIndex = ret;
657 fatd->clStackIndex--;
658 result = fatd->clStack[fatd->clStackIndex];
660 if (currentCluster) {
661 ret = fat_appendClusterChain(fatd, currentCluster, result);
663 ret = fat_createClusterChain(fatd, result);
675static int getDirentrySize(
const char *lname)
690static unsigned char computeNameChecksum(
const char *sname)
692 unsigned char result;
696 for (i = 0; i < 11; i++) {
697 result = (0x80 * (0x01 & result)) + (result >> 1);
707static void setLfnEntry(
const char *lname,
int nameSize,
unsigned char chsum,
fat_direntry_lfn *dlfn,
int part,
int maxPart)
710 unsigned char name[26];
713 nameStart = 13 * (part - 1);
714 j = nameSize - nameStart;
720 for (i = 0; i < j; i++) {
721 name[i * 2] = (
unsigned char)lname[nameStart + i];
726 for (i = j; i < 13; i++) {
732 name[i * 2 + 1] = 0xFF;
736 dlfn->entrySeq = part;
738 dlfn->entrySeq |= 0x40;
739 dlfn->checksum = chsum;
741 for (i = 0; i < 10; i++)
742 dlfn->name1[i] = name[i];
744 for (i = 0; i < 12; i++)
745 dlfn->name2[i] = name[i + 10];
747 for (i = 0; i < 4; i++)
748 dlfn->name3[i] = name[i + 22];
751 dlfn->reserved2[0] = 0;
752 dlfn->reserved2[1] = 0;
761 int year, month, day, hour, minute, sec;
762 unsigned char tmpClk[4];
776 sec = btoi(cdtime.
second);
777 minute = btoi(cdtime.
minute);
778 hour = btoi(cdtime.
hour);
779 day = btoi(cdtime.
day);
780 month = btoi(cdtime.
month & 0x7F);
781 year = btoi(cdtime.
year) + 2000;
792 if (dsfn == NULL || mode == 0) {
796 tmpClk[0] = (sec / 2) & 0x1F;
797 tmpClk[0] += (minute & 0x07) << 5;
798 tmpClk[1] = (minute & 0x38) >> 3;
799 tmpClk[1] += (hour & 0x1F) << 3;
801 tmpClk[2] = (day & 0x1F);
802 tmpClk[2] += (month & 0x07) << 5;
803 tmpClk[3] = (month & 0x08) >> 3;
804 tmpClk[3] += ((year - 1980) & 0x7F) << 1;
806 XPRINTF(
"year=%d, month=%d, day=%d h=%d m=%d s=%d \n", year, month, day, hour, minute, sec);
808 if (mode & DATE_CREATE) {
809 dsfn->timeCreate[0] = tmpClk[0];
810 dsfn->timeCreate[1] = tmpClk[1];
811 dsfn->dateCreate[0] = tmpClk[2];
812 dsfn->dateCreate[1] = tmpClk[3];
813 dsfn->dateAccess[0] = tmpClk[2];
814 dsfn->dateAccess[1] = tmpClk[3];
817 if (mode & DATE_MODIFY) {
818 dsfn->timeWrite[0] = tmpClk[0];
819 dsfn->timeWrite[1] = tmpClk[1];
820 dsfn->dateWrite[0] = tmpClk[2];
821 dsfn->dateWrite[1] = tmpClk[3];
829static void setSfnEntry(
const char *shortName,
char directory,
fat_direntry_sfn *dsfn,
unsigned int cluster)
834 for (i = 0; i < 8; i++)
835 dsfn->name[i] = shortName[i];
836 for (i = 0; i < 3; i++)
837 dsfn->ext[i] = shortName[i + 8];
840 dsfn->attr = FAT_ATTR_DIRECTORY;
842 dsfn->attr = FAT_ATTR_ARCHIVE;
844 dsfn->reservedNT = 0;
845 dsfn->clusterH[0] = (cluster & 0xFF0000) >> 16;
846 dsfn->clusterH[1] = (cluster & 0xFF000000) >> 24;
847 dsfn->clusterL[0] = (cluster & 0x00FF);
848 dsfn->clusterL[1] = (cluster & 0xFF00) >> 8;
851 for (i = 0; i < 4; i++)
854 setSfnDate(dsfn, DATE_CREATE | DATE_MODIFY);
864 for (i = 0; i < 8; i++)
865 dsfn->name[i] = shortName[i];
866 for (i = 0; i < 3; i++)
867 dsfn->ext[i] = shortName[i + 8];
880static int createShortNameMask(
char *lname,
char *sname)
887 if ((lname[0] ==
'.') && ((lname[1] == 0) || ((lname[1] ==
'.') && (lname[2] == 0)))) {
893 for (i = 0; i < 11; i++)
895 XPRINTF(
"Clear short name ='%s'\n", sname);
899 for (i = 0; lname[i] != 0; i++) {
902 else if (lname[i] ==
' ')
911 for (i = 0; lname[i] != 0 && lname[i] !=
'.' && i < 8; i++) {
912 sname[i] = toupper(lname[i]);
918 if (lname[i] ==
'.' || lname[i] == 0) {
924 size = strlen(lname);
927 for (i = size; i > 0 && lname[i] !=
'.'; i--)
929 if (lname[i] ==
'.') {
931 for (j = 0; lname[i] != 0 && j < 3; i++, j++) {
932 sname[j + 8] = toupper(lname[i]);
946 XPRINTF(
"Short name is loseles!\n");
952 for (i = 0; i < 8; i++) {
966static int separatePathAndName(
const char *fname,
char *path,
char *name)
971 if (!(sp = strrchr(fname,
'/')))
975 if (strlen(np) >= FAT_MAX_NAME)
978 if ((path_len = (np - fname)) >= FAT_MAX_PATH)
980 strncpy(path, fname, path_len);
989static int getShortNameSequence(
const char *name,
const char *ext,
const char *sname)
998 for (i = 0; i < 3; i++) {
999 if (ext[i] != tmp[i])
1004 for (i = 7; i > 0 && name[i] !=
'~'; i--)
1012 for (j = 0; j < i; j++) {
1013 if (name[j] != sname[j])
1019 for (j = i + 1; j < 8; j++)
1020 buf[j - i - 1] = name[j];
1023 XPRINTF(
"found short name sequence number='%s' \n", buf);
1024 return strtol(buf, NULL, 10);
1031static int setShortNameSequence(
fat_driver *fatd,
char *sname)
1043 seq = SEQ_MASK_SIZE;
1044 for (i = 0; (i < (SEQ_MASK_SIZE >> 3)); i++) {
1047 if ((mask = fatd->seq_mask[i]) != 0xFF) {
1048 for (j = 0; j < 8; j++, mask >>= 1) {
1049 if ((mask & 1) == 0) {
1058 memset(number, 0, 8);
1059 sprintf(number,
"%d", seq);
1062 buf = sname + 7 - j;
1065 for (i = 0; i < j; i++)
1075static int getDirentryStoreOffset(
fat_driver *fatd,
int entryCount,
int direntrySize)
1084 int mask_ix, mask_sh;
1097 for (i = 0; i < entryCount && cont; i++) {
1100 id = fatd->dir_used_mask[mask_ix] & (1 << mask_sh);
1102 if (slotStart >= 0) {
1107 XPRINTF(
"*Start slot at index=%d ", slotStart);
1110 if (tightIndex < 0 && slotSize == direntrySize) {
1111 tightIndex = slotStart;
1112 XPRINTF(
"!Set tight index= %d\n", tightIndex);
1114 if (looseIndex < 0 && slotSize > direntrySize) {
1115 looseIndex = slotStart + slotSize - direntrySize;
1116 XPRINTF(
"!Set loose index= %d\n", looseIndex);
1118 if (tightIndex >= 0 && looseIndex >= 0) {
1137 if (tightIndex >= 0) {
1140 if (looseIndex >= 0) {
1144 mask_ix = (entryCount - 1) >> 3;
1145 mask_sh = (entryCount - 1) & 7;
1146 id = fatd->dir_used_mask[mask_ix] & (1 << mask_sh);
1148 return entryCount - 1;
1169static int fat_fillDirentryInfo(
fat_driver *fatd,
const char *lname,
const char *sname,
1170 char directory,
unsigned int *startCluster,
1171 unsigned int *retSector,
int *retOffset)
1175 unsigned int startSector, dirSector;
1178 int mask_ix, mask_sh;
1180#ifdef BUILDING_USBHDFSD
1183#ifdef BUILDING_IEEE1394_DISK
1188 memset(fatd->dir_used_mask, 0, DIR_MASK_SIZE / 8);
1189 memset(fatd->seq_mask, 0, SEQ_MASK_SIZE / 8);
1198 directory = FAT_ATTR_DIRECTORY;
1200 fat_getDirentrySectorData(fatd, startCluster, &startSector, &dirSector);
1202 XPRINTF(
"dirCluster=%u startSector=%u (%u) dirSector=%u \n", *startCluster, startSector, startSector
1203#
if !defined(BUILDING_IEEE1394_DISK) && !defined(BUILDING_USBHDFSD)
1204 * fatd->bd->sectorSize,
1206 * mass_device->sectorSize,
1212 for (i = 0; (
unsigned int)i < dirSector && cont; i++) {
1213 unsigned int theSector;
1215 unsigned int dirPos;
1217 unsigned char *sbuf = NULL;
1220 if ((*startCluster != 0) && (i % fatd->partBpb.clusterSize == 0)) {
1221 startSector = fat_cluster2sector(&fatd->partBpb, fatd->cbuf[(i / fatd->partBpb.clusterSize)]) - i;
1223 theSector = startSector + i;
1224 ret = READ_SECTOR(DEV_ACCESSOR(fatd), theSector, sbuf);
1226 XPRINTF(
"read directory sector failed ! sector=%u\n", theSector);
1229 XPRINTF(
"read sector ok, scanning sector for direntries...\n");
1233 while (cont && (dirPos < fatd->partBpb.sectorSize) && (j < DIR_MASK_SIZE)) {
1235 cont = fat_getDirentry(fatd->partBpb.fatType, dir_entry, &dir);
1240 fatd->dir_used_mask[mask_ix] |= (1 << mask_sh);
1241 if (!(dir.attr & FAT_ATTR_VOLUME_LABEL)) {
1242 if ((strEqual(dir.sname, lname) == 0) || (strEqual(dir.name, lname) == 0)) {
1244 if ((directory >= 0) && ((dir.attr & FAT_ATTR_DIRECTORY) != directory)) {
1250 XPRINTF(
"I: entry found! %s, %s = %s\n", dir.name, dir.sname, lname);
1251 *retSector = theSector;
1252 *retOffset = dirPos;
1253 *startCluster = dir.cluster;
1254 fatd->deSec[fatd->deIdx] = theSector;
1255 fatd->deOfs[fatd->deIdx] = dirPos;
1259 seq = getShortNameSequence((
char *)dir_entry->sfn.name, (
char *)dir_entry->sfn.ext, sname);
1260 if (seq < SEQ_MASK_SIZE)
1261 fatd->seq_mask[seq >> 3] |= (1 << (seq & 7));
1272 fatd->dir_used_mask[mask_ix] |= (1 << mask_sh);
1273 fatd->deSec[fatd->deIdx] = theSector;
1274 fatd->deOfs[fatd->deIdx] = dirPos;
1286 if (j >= DIR_MASK_SIZE) {
1304static int enlargeDirentryClusterSpace(
fat_driver *fatd,
unsigned int startCluster,
int entryCount,
int entryIndex,
int direntrySize)
1306 unsigned int startSector, dirSector;
1309 int entriesPerSector;
1311 unsigned int currentCluster;
1312 unsigned int newCluster;
1314 i = entryIndex + direntrySize;
1315 XPRINTF(
"cur=%d ecount=%d \n", i, entryCount);
1317 if (i <= entryCount)
1320 entriesPerSector = fatd->partBpb.sectorSize / 32;
1321 maxSector = i / entriesPerSector;
1322 if (i % entriesPerSector) {
1326 chainSize = fat_getDirentrySectorData(fatd, &startCluster, &startSector, &dirSector);
1328 XPRINTF(
"maxSector=%u dirSector=%u\n", maxSector, dirSector);
1330 if ((
unsigned int)maxSector <= dirSector)
1334 if (startCluster == 0 && fatd->partBpb.fatType < FAT32) {
1341 currentCluster = fatd->cbuf[chainSize - 1];
1342 XPRINTF(
"current (last) cluster=%u \n", currentCluster);
1345 newCluster = fat_getFreeCluster(fatd, currentCluster);
1346 XPRINTF(
"new cluster=%u \n", newCluster);
1347 fat_invalidateLastChainResult(fatd);
1349 if (newCluster == 0) {
1354 startSector = fat_cluster2sector(&fatd->partBpb, newCluster);
1355 for (i = 0; i < fatd->partBpb.clusterSize; i++) {
1358 unsigned char *sbuf = NULL;
1360 ret = ALLOC_SECTOR(DEV_ACCESSOR(fatd), startSector + i, sbuf);
1363 memset(sbuf, 0, fatd->partBpb.sectorSize);
1364 ret = WRITE_SECTOR(DEV_ACCESSOR(fatd), startSector + i);
1378static int createDirectorySpace(
fat_driver *fatd,
unsigned int dirCluster,
unsigned int parentDirCluster)
1381 unsigned int startSector;
1384 if (dirCluster < 2) {
1390 startSector = fat_cluster2sector(&fatd->partBpb, dirCluster);
1391 XPRINTF(
"I: create dir space: cluster=%u sector=%u (%u) \n", dirCluster, startSector, startSector * fatd->partBpb.sectorSize);
1394 for (i = 0; i < fatd->partBpb.clusterSize; i++) {
1397 unsigned char *sbuf = NULL;
1399 ret = ALLOC_SECTOR(DEV_ACCESSOR(fatd), startSector + i, sbuf);
1401 XPRINTF(
"alloc directory sector failed ! sector=%u\n", startSector + i);
1404 memset(sbuf, 0, fatd->partBpb.sectorSize);
1408 for (j = 1; j < 11; j++)
1411 setSfnEntry(name, 1, dsfn + 0, dirCluster);
1413 setSfnEntry(name, 1, dsfn + 1, parentDirCluster);
1415 ret = WRITE_SECTOR(DEV_ACCESSOR(fatd), startSector + i);
1417 XPRINTF(
"write directory sector failed ! sector=%u\n", startSector + i);
1428static int updateDirectoryParent(
fat_driver *fatd,
unsigned int dirCluster,
unsigned int parentDirCluster)
1431 unsigned int startSector;
1434 if (dirCluster < 2) {
1440 startSector = fat_cluster2sector(&fatd->partBpb, dirCluster);
1441 XPRINTF(
"I: update dir parent: cluster=%u sector=%u (%u) \n", dirCluster, startSector, startSector * fatd->partBpb.sectorSize);
1444 for (i = 0; i < fatd->partBpb.clusterSize; i++) {
1447 unsigned char *sbuf = NULL;
1449 ret = READ_SECTOR(DEV_ACCESSOR(fatd), startSector + i, sbuf);
1451 XPRINTF(
"read directory sector failed ! sector=%u\n", startSector + i);
1455 for (j = 0; (
unsigned int)j < fatd->partBpb.sectorSize; j +=
sizeof(
fat_direntry_sfn), dsfn++) {
1456 if (memcmp(dsfn->name,
".. ",
sizeof(dsfn->name)) == 0) {
1457 dsfn->clusterH[0] = (parentDirCluster & 0xFF0000) >> 16;
1458 dsfn->clusterH[1] = (parentDirCluster & 0xFF000000) >> 24;
1459 dsfn->clusterL[0] = (parentDirCluster & 0x00FF);
1460 dsfn->clusterL[1] = (parentDirCluster & 0xFF00) >> 8;
1462 ret = WRITE_SECTOR(DEV_ACCESSOR(fatd), startSector + i);
1464 XPRINTF(
"write directory sector failed ! sector=%u\n", startSector + i);
1495static int saveDirentry(
fat_driver *fatd,
unsigned int startCluster,
1496 const char *lname,
const char *sname,
char directory,
unsigned int cluster,
1497 int entrySize,
int entryIndex,
unsigned int *retSector,
int *retOffset,
const fat_direntry_sfn *orig_dsfn)
1500 unsigned int dirSector;
1501 unsigned int startSector;
1505#ifdef BUILDING_USBHDFSD
1508#ifdef BUILDING_IEEE1394_DISK
1512 int part = entrySize - 1;
1514 unsigned char chsum;
1516 chsum = computeNameChecksum(sname);
1517 nameSize = strlen(lname);
1521 entryEndIndex = entryIndex + entrySize;
1525 fat_getDirentrySectorData(fatd, &startCluster, &startSector, &dirSector);
1527 XPRINTF(
"dirCluster=%u startSector=%u (%u) dirSector=%u \n", startCluster, startSector, startSector
1528#
if !defined(BUILDING_IEEE1394_DISK) && !defined(BUILDING_USBHDFSD)
1529 * fatd->bd->sectorSize,
1531 * mass_device->sectorSize,
1537 for (i = 0; (
unsigned int)i < dirSector && cont; i++) {
1538 unsigned int theSector;
1540 unsigned int dirPos;
1543 unsigned char *sbuf = NULL;
1546 if ((startCluster != 0) && (i % fatd->partBpb.clusterSize == 0)) {
1547 startSector = fat_cluster2sector(&fatd->partBpb, fatd->cbuf[(i / fatd->partBpb.clusterSize)]) - i;
1549 theSector = startSector + i;
1550 ret = READ_SECTOR(DEV_ACCESSOR(fatd), theSector, sbuf);
1552 XPRINTF(
"read directory sector failed ! sector=%u\n", theSector);
1555 XPRINTF(
"read sector ok, scanning sector for direntries...\n");
1559 while (dirPos < fatd->partBpb.sectorSize) {
1560 if (j >= entryIndex && j < entryEndIndex) {
1563 if (orig_dsfn == NULL)
1564 setSfnEntry(sname, directory, &dir_entry->sfn, cluster);
1566 setSfnEntryFromOld(sname, &dir_entry->sfn, orig_dsfn);
1568 setLfnEntry(lname, nameSize, chsum, &dir_entry->lfn, part, entrySize - 1);
1572 if (j == entryEndIndex - 1) {
1573 *retSector = theSector;
1574 *retOffset = dirPos;
1583 ret = WRITE_SECTOR(DEV_ACCESSOR(fatd), theSector);
1585 XPRINTF(
"write directory sector failed ! sector=%u\n", theSector);
1589 if (j >= entryEndIndex) {
1611static int fat_modifyDirSpace(
fat_driver *fatd,
char *lname,
char directory,
char escapeNotExist,
unsigned int *startCluster,
unsigned int *retSector,
int *retOffset,
const fat_direntry_sfn *orig_dsfn)
1614 unsigned int newCluster, parentDirCluster;
1615 int ret, entryCount, compressShortName, entryIndex, direntrySize;
1650 ret = createShortNameMask(lname, sname);
1652 XPRINTF(
"E: short name invalid!\n");
1655 compressShortName = ret;
1659 parentDirCluster = *startCluster;
1660 ret = fat_fillDirentryInfo(fatd, lname, sname, directory,
1661 startCluster, retSector, retOffset);
1663 XPRINTF(
"E: direntry data invalid!\n");
1672 if (escapeNotExist) {
1676 if (ret > DIR_MASK_SIZE) {
1677 XPRINTF(
"W: Direntry count is larger than number of records!\n");
1678 ret = DIR_MASK_SIZE;
1681 XPRINTF(
"I: direntry count=%d\n", entryCount);
1683 if (compressShortName) {
1684 setShortNameSequence(fatd, sname);
1686 XPRINTF(
"I: new short name='%s' \n", sname);
1689 direntrySize = getDirentrySize(lname) + 1;
1690 XPRINTF(
"Direntry size=%d\n", direntrySize);
1693 entryIndex = getDirentryStoreOffset(fatd, entryCount, direntrySize);
1694 XPRINTF(
"I: direntry store offset=%d\n", entryIndex);
1698 ret = enlargeDirentryClusterSpace(fatd, parentDirCluster, entryCount, entryIndex, direntrySize);
1699 XPRINTF(
"I: enlarge direntry cluster space ret=%d\n", ret);
1704 if (orig_dsfn == NULL) {
1706 newCluster = fat_getFreeCluster(fatd, 0);
1707 if (newCluster == 0) {
1710 XPRINTF(
"I: new file/dir cluster=%u\n", newCluster);
1711 *startCluster = newCluster;
1713 *startCluster = (fatd->partBpb.fatType == FAT32) ? getUI32_2(orig_dsfn->clusterL, orig_dsfn->clusterH) : getUI16(orig_dsfn->clusterL);
1718 ret = saveDirentry(fatd, parentDirCluster, lname, sname, directory, newCluster, direntrySize, entryIndex, retSector, retOffset, orig_dsfn);
1719 XPRINTF(
"I: save direntry ret=%d\n", ret);
1725 if ((orig_dsfn == NULL) && directory) {
1726 ret = createDirectorySpace(fatd, newCluster, parentDirCluster);
1727 XPRINTF(
"I: create directory space ret=%d\n", ret);
1746static int checkDirspaceEmpty(
fat_driver *fatd,
unsigned int startCluster)
1753 unsigned int retSector;
1756 XPRINTF(
"I: checkDirspaceEmpty directory cluster=%u \n", startCluster);
1757 if (startCluster < 2) {
1764 ret = fat_fillDirentryInfo(fatd, sname, sname, 1,
1765 &startCluster, &retSector, &retOffset);
1766 if (ret > DIR_MASK_SIZE) {
1767 XPRINTF(
"W: Direntry count is larger than number of records! directory space cluster =%u maxRecords=%u\n", startCluster, DIR_MASK_SIZE);
1768 ret = DIR_MASK_SIZE;
1772 if ((fatd->dir_used_mask[0] & 0xFC) != 0)
1774 for (i = 1; i < (entryCount / 8); i++) {
1775 if (fatd->dir_used_mask[i] != 0) {
1777 XPRINTF(
"I: directory not empty!\n");
1781 XPRINTF(
"I: directory is empty.\n");
1786static int fat_wipeDirEntries(
fat_driver *fatd)
1789 unsigned int i, theSector;
1790 unsigned char *sbuf = NULL;
1795 for (i = 0; i < (u32)(fatd->deIdx); i++) {
1796 if (fatd->deSec[i] != theSector) {
1797 if (theSector > 0) {
1798 ret = WRITE_SECTOR(DEV_ACCESSOR(fatd), theSector);
1800 XPRINTF(
"write directory sector failed ! sector=%u\n", theSector);
1805 theSector = fatd->deSec[i];
1806 ret = READ_SECTOR(DEV_ACCESSOR(fatd), theSector, sbuf);
1808 XPRINTF(
"read directory sector failed ! sector=%u\n", theSector);
1813 sbuf[fatd->deOfs[i]] = 0xE5;
1815 if (theSector > 0) {
1816 ret = WRITE_SECTOR(DEV_ACCESSOR(fatd), theSector);
1818 XPRINTF(
"write directory sector failed ! sector=%u\n", theSector);
1835static int fat_clearDirSpace(
fat_driver *fatd,
char *lname,
char directory,
unsigned int *startCluster)
1839 unsigned int dirCluster;
1840 unsigned int sfnSector;
1846 dirCluster = *startCluster;
1850 ret = fat_fillDirentryInfo(fatd, lname, sname, directory,
1851 startCluster, &sfnSector, &sfnOffset);
1853 XPRINTF(
"E: direntry not found!\n");
1856 XPRINTF(
"clear dir space: dir found at cluster=%u \n ", *startCluster);
1865 ret = checkDirspaceEmpty(fatd, *startCluster);
1870 *startCluster = dirCluster;
1872 ret = fat_fillDirentryInfo(fatd, lname, sname, directory,
1873 startCluster, &sfnSector, &sfnOffset);
1875 XPRINTF(
"E: direntry not found!\n");
1881 ret = fat_wipeDirEntries(fatd);
1883 XPRINTF(
"E: wipe direntries failed!\n");
1888 ret = fat_deleteClusterChain(fatd, *startCluster);
1890 XPRINTF(
"E: delete cluster chain failed!\n");
1905int fat_truncateFile(
fat_driver *fatd,
unsigned int cluster,
unsigned int sfnSector,
int sfnOffset)
1909 unsigned char *sbuf = NULL;
1911 if (cluster == 0 || sfnSector == 0) {
1916 ret = fat_deleteClusterChain(fatd, cluster);
1918 XPRINTF(
"E: delete cluster chain failed!\n");
1923 ret = fat_createClusterChain(fatd, cluster);
1925 XPRINTF(
"E: truncate cluster chain failed!\n");
1929 ret = READ_SECTOR(DEV_ACCESSOR(fatd), sfnSector, sbuf);
1931 XPRINTF(
"read direntry sector failed ! sector=%u\n", sfnSector);
1940 ret = WRITE_SECTOR(DEV_ACCESSOR(fatd), sfnSector);
1942 XPRINTF(
"write directory sector failed ! sector=%u\n", sfnSector);
1957int fat_updateSfn(
fat_driver *fatd,
int size,
unsigned int sfnSector,
int sfnOffset)
1961 unsigned char *sbuf = NULL;
1963 if (sfnSector == 0) {
1968 ret = READ_SECTOR(DEV_ACCESSOR(fatd), sfnSector, sbuf);
1970 XPRINTF(
"read direntry sector failed ! sector=%u\n", sfnSector);
1974 dsfn->size[0] = size & 0xFF;
1975 dsfn->size[1] = (size & 0xFF00) >> 8;
1976 dsfn->size[2] = (size & 0xFF0000) >> 16;
1977 dsfn->size[3] = (size & 0xFF000000) >> 24;
1979 setSfnDate(dsfn, DATE_MODIFY);
1981 ret = WRITE_SECTOR(DEV_ACCESSOR(fatd), sfnSector);
1983 XPRINTF(
"write directory sector failed ! sector=%u\n", sfnSector);
1986 XPRINTF(
"I: sfn updated, file size=%d \n", size);
2003int fat_createFile(
fat_driver *fatd,
const char *fname,
char directory,
char escapeNotExist,
unsigned int *cluster,
unsigned int *sfnSector,
int *sfnOffset)
2006 unsigned int startCluster;
2007 unsigned int directoryCluster;
2008 char lname[FAT_MAX_NAME], pathToDirent[FAT_MAX_PATH];
2011 ret = separatePathAndName(fname, pathToDirent, lname);
2014 || ((lname[0] ==
'.') && ((lname[1] == 0)
2015 || ((lname[1] ==
'.') && (lname[2] == 0)
2017 XPRINTF(
"E: file name not exist or not valid!");
2021 XPRINTF(
"Calling fat_getFileStartCluster from fat_createFile\n");
2024 ret = fat_getFileStartCluster(fatd, pathToDirent, &startCluster, &fatdir);
2026 XPRINTF(
"E: directory not found! \n");
2030 if (!(fatdir.attr & FAT_ATTR_DIRECTORY)) {
2031 XPRINTF(
"E: directory not found! \n");
2035 XPRINTF(
"directory=%s name=%s cluster=%u \n", pathToDirent, lname, startCluster);
2037 if (fatdir.attr & FAT_ATTR_READONLY)
2042 directoryCluster = startCluster;
2043 ret = fat_modifyDirSpace(fatd, lname, directory, escapeNotExist, &startCluster, sfnSector, sfnOffset, NULL);
2045 XPRINTF(
"E: modifyDirSpace failed!\n");
2048 XPRINTF(
"I: SFN info: sector=%u (%u) offset=%u (%u) startCluster=%u\n", *sfnSector, *sfnSector * fatd->partBpb.sectorSize, *sfnOffset, *sfnOffset + (*sfnSector * fatd->partBpb.sectorSize), startCluster);
2049 *cluster = startCluster;
2060 || ((directoryCluster || !directory)
2061 && (startCluster != directoryCluster)
2063 XPRINTF(
"I: file already exists at cluster=%u\n", startCluster);
2071int fat_deleteFile(
fat_driver *fatd,
const char *fname,
char directory)
2074 unsigned int startCluster;
2075 unsigned int directoryCluster;
2076 char lname[FAT_MAX_NAME], pathToDirent[FAT_MAX_PATH];
2079 ret = separatePathAndName(fname, pathToDirent, lname);
2082 || ((lname[0] ==
'.') && ((lname[1] == 0)
2083 || ((lname[1] ==
'.') && (lname[2] == 0)
2085 XPRINTF(
"E: file name not exist or not valid!");
2089 XPRINTF(
"Calling fat_getFileStartCluster from fat_deleteFile\n");
2092 ret = fat_getFileStartCluster(fatd, pathToDirent, &startCluster, &fatdir);
2094 XPRINTF(
"E: directory not found! \n");
2098 if (!(fatdir.attr & FAT_ATTR_DIRECTORY)) {
2099 XPRINTF(
"E: directory not found! \n");
2103 XPRINTF(
"directory=%s name=%s cluster=%u \n", pathToDirent, lname, startCluster);
2105 if (fatdir.attr & FAT_ATTR_READONLY) {
2106 XPRINTF(
"E: directory read only! \n");
2111 directoryCluster = startCluster;
2112 ret = fat_clearDirSpace(fatd, lname, directory, &startCluster);
2114 XPRINTF(
"E: cleanDirSpace failed!\n");
2117 if (startCluster != directoryCluster) {
2118 XPRINTF(
"I: file/dir removed from cluster=%u\n", startCluster);
2129 unsigned int sDirCluster;
2130 unsigned int dDirCluster, dParentDirCluster;
2131 char lname[FAT_MAX_NAME], pathToDirent[FAT_MAX_PATH];
2132 unsigned int sfnSector, new_sfnSector, startCluster;
2133 int sfnOffset, new_sfnOffset;
2135 unsigned char *sbuf = NULL;
2136 unsigned char srcIsDirectory;
2139 ret = separatePathAndName(fname, pathToDirent, lname);
2142 || ((lname[0] ==
'.') && ((lname[1] == 0)
2143 || ((lname[1] ==
'.') && (lname[2] == 0)
2145 XPRINTF(
"E: destination file name not exist or not valid!");
2150 sDirCluster = fatdir->parentDirCluster;
2152 XPRINTF(
"Calling fat_getFileStartCluster from fat_renameFile\n");
2154 ret = fat_getFileStartCluster(fatd, pathToDirent, &dDirCluster, NULL);
2156 XPRINTF(
"E: destination directory not found! \n");
2159 dParentDirCluster = dDirCluster;
2163 ret = fat_fillDirentryInfo(fatd, fatdir->name, sname, -1, &sDirCluster, &sfnSector, &sfnOffset);
2165 XPRINTF(
"E: direntry not found! %d\n", ret);
2169 XPRINTF(
"fat_renameFile: dir found at cluster=%u \n ", sDirCluster);
2172 if ((ret = READ_SECTOR(DEV_ACCESSOR(fatd), sfnSector, sbuf)) < 0) {
2173 XPRINTF(
"E: I/O error! %d\n", ret);
2177 srcIsDirectory = ((
fat_direntry_sfn *)(sbuf + sfnOffset))->attr & FAT_ATTR_DIRECTORY;
2179 ret = fat_fillDirentryInfo(fatd, lname, sname, srcIsDirectory, &dDirCluster, &new_sfnSector, &new_sfnOffset);
2182 if (srcIsDirectory) {
2184 dDirCluster = dParentDirCluster;
2185 if ((ret = fat_clearDirSpace(fatd, lname, 1, &dDirCluster)) < 0)
2194 startCluster = dParentDirCluster;
2195 if ((ret = fat_modifyDirSpace(fatd, lname, srcIsDirectory, 0, &startCluster, &sfnSector, &sfnOffset, &OriginalSFN)) < 0) {
2196 XPRINTF(
"E: fat_modifyDirSpace failed! %d\n", ret);
2201 if (srcIsDirectory) {
2202 dDirCluster = (fatd->partBpb.fatType == FAT32) ? getUI32_2(OriginalSFN.clusterL, OriginalSFN.clusterH) : getUI16(OriginalSFN.clusterL);
2203 if ((ret = updateDirectoryParent(fatd, dDirCluster, dParentDirCluster)) != 0) {
2204 XPRINTF(
"E: could not update \"..\" entry! %d\n", ret);
2211 sDirCluster = fatdir->parentDirCluster;
2212 ret = fat_fillDirentryInfo(fatd, fatdir->name, sname, -1, &sDirCluster, &sfnSector, &sfnOffset);
2214 XPRINTF(
"E: direntry not found! %d\n", ret);
2219 ret = fat_wipeDirEntries(fatd);
2221 XPRINTF(
"E: wipe direntries failed!\n");
2225 fatdir->parentDirCluster = dParentDirCluster;
2226 strcpy(fatdir->name, lname);
2232#ifdef BUILDING_USBHDFSD
2233static int fat_writeSingleSector(
mass_dev *dev,
unsigned int sector,
const void *buffer,
int size,
int dataSkip)
2235 unsigned char *sbuf = NULL;
2238 if ((dataSkip > 0) || ((
unsigned int)size < dev->sectorSize) || (((
int)buffer & 3) != 0)) {
2240 ret = READ_SECTOR(dev, sector, sbuf);
2242 XPRINTF(
"Read sector failed ! sector=%u\n", sector);
2246 memcpy(sbuf + dataSkip, buffer, size);
2248 ret = WRITE_SECTOR(dev, sector);
2250 printf(
"USBHDFSD: Write sector failed ! sector=%u\n", sector);
2255 INVALIDATE_SECTORS(dev, sector, 1);
2257 ret = WRITE_SECTORS_RAW(dev, sector, 1, buffer);
2259 XPRINTF(
"Write sector failed ! sector=%u\n", sector);
2268int fat_writeFile(
fat_driver *fatd,
fat_dir *fatDir,
int *updateClusterIndices,
unsigned int filePos,
unsigned char *buffer,
unsigned int size)
2273 unsigned int bufSize;
2278 unsigned int bufferPos;
2279 unsigned int fileCluster;
2280 unsigned int clusterPos;
2281 unsigned int endPosFile;
2282 unsigned int endPosCluster;
2284 int clusterChainStart;
2286#ifdef BUILDING_USBHDFSD
2290#ifdef BUILDING_IEEE1394_DISK
2295 i = fatd->partBpb.clusterSize * fatd->partBpb.sectorSize;
2296 j = fatDir->size / i;
2297 if (fatDir->size % i) {
2303 endPosCluster = j * i;
2304 endPosFile = filePos + size;
2306 *updateClusterIndices = 0;
2309 if (endPosFile > endPosCluster) {
2310 unsigned int lastCluster;
2312 ret = endPosFile - endPosCluster;
2317 lastCluster = fatDir->lastCluster;
2318 XPRINTF(
"I: writeFile: last cluster= %u \n", lastCluster);
2320 if (lastCluster == 0)
2322 for (i = 0; i < j; i++) {
2323 lastCluster = fat_getFreeCluster(fatd, lastCluster);
2324 if (lastCluster == 0)
2327 fatDir->lastCluster = lastCluster;
2328 *updateClusterIndices = j;
2329 fat_invalidateLastChainResult(fatd);
2331 XPRINTF(
"I: writeFile: new clusters allocated = %u new lastCluster=%u \n", j, lastCluster);
2333 XPRINTF(
"I: write file: filePos=%d dataSize=%d \n", filePos, size);
2336 fat_getClusterAtFilePos(fatd, fatDir, filePos, &fileCluster, &clusterPos);
2337 sectorSkip = (filePos - clusterPos) / fatd->partBpb.sectorSize;
2338 clusterSkip = sectorSkip / fatd->partBpb.clusterSize;
2339 sectorSkip %= fatd->partBpb.clusterSize;
2340 dataSkip = filePos % fatd->partBpb.sectorSize;
2344 XPRINTF(
"fileCluster = %u, clusterPos= %u clusterSkip=%u, sectorSkip=%u dataSkip=%u \n",
2345 fileCluster, clusterPos, clusterSkip, sectorSkip, dataSkip);
2347 if (fileCluster < 2) {
2351#if !defined(BUILDING_IEEE1394_DISK) && !defined(BUILDING_USBHDFSD)
2352 bufSize = fatd->bd->sectorSize;
2354 bufSize = mass_device->sectorSize;
2357 clusterChainStart = 1;
2359 while (nextChain && size > 0) {
2362 chainSize = fat_getClusterChain(fatd, fileCluster, fatd->cbuf, MAX_DIR_CLUSTER, clusterChainStart);
2363 clusterChainStart = 0;
2364 if (chainSize >= MAX_DIR_CLUSTER) {
2365 fileCluster = fatd->cbuf[MAX_DIR_CLUSTER - 1];
2369 while (clusterSkip >= MAX_DIR_CLUSTER) {
2370 chainSize = fat_getClusterChain(fatd, fileCluster, fatd->cbuf, MAX_DIR_CLUSTER, clusterChainStart);
2371 clusterChainStart = 0;
2372 if (chainSize >= MAX_DIR_CLUSTER) {
2373 fileCluster = fatd->cbuf[MAX_DIR_CLUSTER - 1];
2377 clusterSkip -= MAX_DIR_CLUSTER;
2381 for (i = 0 + clusterSkip; i < chainSize && size > 0; i++) {
2385 startSector = fat_cluster2sector(&fatd->partBpb, fatd->cbuf[i]);
2387#ifdef BUILDING_USBHDFSD
2393 if (((u32)(buffer + bufferPos) & 3) == 0) {
2397 j = (size + dataSkip) / fatd->partBpb.sectorSize + sectorSkip;
2400 if (j >= fatd->partBpb.clusterSize) {
2401 toWrite += fatd->partBpb.clusterSize;
2402 j -= fatd->partBpb.clusterSize;
2409 if ((i >= chainSize - 1) || (fatd->cbuf[i] != (fatd->cbuf[i + 1] - 1)))
2417 startSector += sectorSkip;
2418 toWrite -= sectorSkip;
2422 bufSize = mass_device->sectorSize - dataSkip;
2426 ret = fat_writeSingleSector(fatd->dev, startSector, buffer + bufferPos, bufSize, dataSkip);
2431 if (size + dataSkip >= mass_device->sectorSize)
2435 bufferPos += bufSize;
2441 INVALIDATE_SECTORS(DEV_ACCESSOR(fatd), startSector, toWrite);
2442 ret = WRITE_SECTORS_RAW(DEV_ACCESSOR(fatd), startSector, toWrite, buffer + bufferPos);
2444 XPRINTF(
"Write sectors failed ! sector=%u (%u)\n", startSector, toWrite);
2448 bufSize = toWrite * mass_device->sectorSize;
2450 bufferPos += bufSize;
2451 startSector += toWrite;
2454 if (size > 0 && size <= mass_device->sectorSize) {
2455 ret = fat_writeSingleSector(fatd->dev, startSector, buffer + bufferPos, size, 0);
2462 bufferPos += bufSize;
2467 for (j = 0 + sectorSkip; j < fatd->partBpb.clusterSize && size > 0; j++) {
2469 if (size < bufSize) {
2472 if (bufSize > mass_device->sectorSize - dataSkip) {
2473 bufSize = mass_device->sectorSize - dataSkip;
2476 ret = fat_writeSingleSector(fatd->dev, startSector + j, buffer + bufferPos, bufSize, dataSkip);
2482 bufferPos += bufSize;
2484 bufSize = mass_device->sectorSize;
2489 for (j = 0 + sectorSkip; j < fatd->partBpb.clusterSize && size > 0; j++) {
2490 unsigned char *sbuf = NULL;
2493 if (size < bufSize) {
2494 bufSize = size + dataSkip;
2496#ifdef BUILDING_IEEE1394_DISK
2497 if (bufSize > mass_device->sectorSize) {
2498 bufSize = mass_device->sectorSize;
2501 if (bufSize > fatd->bd->sectorSize) {
2502 bufSize = fatd->bd->sectorSize;
2506 ret = READ_SECTOR(DEV_ACCESSOR(fatd), startSector + j, sbuf);
2508 M_DEBUG(
"Read sector failed ! sector=%u\n", startSector + j);
2512 M_DEBUG(
"memcopy dst=%u, src=%u, size=%u bufSize=%u \n", dataSkip, bufferPos, bufSize - dataSkip, bufSize);
2513 memcpy(sbuf + dataSkip, buffer + bufferPos, bufSize - dataSkip);
2514 ret = WRITE_SECTOR(DEV_ACCESSOR(fatd), startSector + j);
2516 M_DEBUG(
"Write sector failed ! sector=%u\n", startSector + j);
2520 size -= (bufSize - dataSkip);
2521 bufferPos += (bufSize - dataSkip);
2523#ifdef BUILDING_IEEE1394_DISK
2524 bufSize = mass_device->sectorSize;
2526 bufSize = fatd->bd->sectorSize;
2541 FLUSH_SECTORS(DEV_ACCESSOR(fatd));
int sceCdReadClock(sceCdCLOCK *clock)