PS2SDK
PS2 Homebrew Libraries
fat_driver.c
1 //---------------------------------------------------------------------------
2 // File name: fat_driver.c
3 //---------------------------------------------------------------------------
4 #include <stdio.h>
5 #include <errno.h>
6 #include <limits.h>
7 
8 #ifdef WIN32
9 #include <stdlib.h>
10 #include <memory.h>
11 #include <string.h>
12 #else
13 #include <sysclib.h>
14 // #include <sys/stat.h>
15 
16 #include <thbase.h>
17 #include <sysmem.h>
18 #endif
19 
20 #ifdef BUILDING_USBHDFSD
21 #include <usbhdfsd.h>
22 #endif /* BUILDING_USBHDFSD */
23 #include "usbhd_common.h"
24 #include "scache.h"
25 #include "fat_driver.h"
26 #include "fat.h"
27 #ifdef BUILDING_USBHDFSD
28 #include "mass_stor.h"
29 #endif /* BUILDING_USBHDFSD */
30 #ifdef BUILDING_IEEE1394_DISK
31 #include "sbp2_disk.h"
32 #include "scsi.h"
33 #endif /* BUILDING_IEEE1394_DISK */
34 
35 // #define DEBUG //comment out this line when not debugging
36 
37 #include "mass_debug.h"
38 
39 #define READ_SECTOR(d, a, b) scache_readSector((d)->cache, (a), (void **)&b)
40 #if !defined(BUILDING_IEEE1394_DISK) && !defined(BUILDING_USBHDFSD)
41 #define DEV_ACCESSOR(d) (d)
42 #else
43 #define DEV_ACCESSOR(d) ((d)->dev)
44 #endif
45 #ifdef BUILDING_USBHDFSD
46 #define READ_SECTORS_RAW(d, a, c, b) mass_stor_readSector((d), a, b, c);
47 #define INVALIDATE_SECTORS(d, s, c) scache_invalidate((d)->cache, s, c)
48 #endif /* BUILDING_USBHDFSD */
49 
50 #define NUM_DRIVES 10
51 static fat_driver *g_fatd[NUM_DRIVES];
52 
53 //---------------------------------------------------------------------------
54 int InitFAT(void)
55 {
56  int i;
57 
58  M_DEBUG("%s\n", __func__);
59 
60  for (i = 0; i < NUM_DRIVES; ++i)
61  g_fatd[i] = NULL;
62 
63  return 0;
64 }
65 
66 //---------------------------------------------------------------------------
67 int strEqual(const char *s1, const char *s2)
68 {
69  M_DEBUG("%s\n", __func__);
70 
71  for (;;) {
72  char u1, u2;
73 
74  u1 = *s1++;
75  u2 = *s2++;
76  if (u1 > 64 && u1 < 91)
77  u1 += 32;
78  if (u2 > 64 && u2 < 91)
79  u2 += 32;
80 
81  if (u1 != u2) {
82  return -1;
83  }
84  if (u1 == '\0') {
85  return 0;
86  }
87  }
88 }
89 
90 /*
91 
92  0x321, 0xABC
93 
94  byte| byte| byte|
95  +--+--+--+--+--+--+
96  |2 |1 |C |3 |A |B |
97  +--+--+--+--+--+--+
98 
99 */
100 
101 //---------------------------------------------------------------------------
102 unsigned int fat_getClusterRecord12(const unsigned char *buf, int type)
103 {
104  M_DEBUG("%s\n", __func__);
105 
106  if (type) { // 1
107  return ((buf[1] << 4) + (buf[0] >> 4));
108  } else { // 0
109  return (((buf[1] & 0x0F) << 8) + buf[0]);
110  }
111 }
112 
113 //---------------------------------------------------------------------------
114 // Get Cluster chain into <buf> buffer
115 // returns:
116 // 0 :if buf is full (bufSize entries) and more chain entries exist
117 // 1-n :number of filled entries of the buf
118 // -1 :error
119 //---------------------------------------------------------------------------
120 // for fat12
121 /* fat12 cluster records can overlap the edge of the sector so we need to detect and maintain
122  these cases
123 */
124 static int fat_getClusterChain12(fat_driver *fatd, unsigned int cluster, unsigned int *buf, unsigned int bufSize, int startFlag)
125 {
126  int ret;
127  unsigned int i, lastFatSector;
128  unsigned char xbuf[4], cont;
129  unsigned char *sbuf = NULL; // sector buffer
130 
131  M_DEBUG("%s\n", __func__);
132 
133  cont = 1;
134  lastFatSector = -1;
135  i = 0;
136  if (startFlag) {
137  buf[i] = cluster; // store first cluster
138  i++;
139  }
140  while (i < bufSize && cont) {
141  unsigned int recordOffset, fatSector;
142  unsigned char sectorSpan;
143 
144  recordOffset = (cluster * 3) / 2; // offset of the cluster record (in bytes) from the FAT start
145  fatSector = recordOffset / fatd->partBpb.sectorSize;
146  sectorSpan = 0;
147  if ((recordOffset % fatd->partBpb.sectorSize) == (fatd->partBpb.sectorSize - 1)) {
148  sectorSpan = 1;
149  }
150  if (lastFatSector != fatSector || sectorSpan) {
151  ret = READ_SECTOR(DEV_ACCESSOR(fatd), fatd->partBpb.partStart + fatd->partBpb.resSectors + fatSector, sbuf);
152  if (ret < 0) {
153  XPRINTF("Read fat12 sector failed! sector=%u! \n", fatd->partBpb.partStart + fatd->partBpb.resSectors + fatSector);
154  return -EIO;
155  }
156  lastFatSector = fatSector;
157 
158  if (sectorSpan) {
159  xbuf[0] = sbuf[fatd->partBpb.sectorSize - 2];
160  xbuf[1] = sbuf[fatd->partBpb.sectorSize - 1];
161  ret = READ_SECTOR(DEV_ACCESSOR(fatd), fatd->partBpb.partStart + fatd->partBpb.resSectors + fatSector + 1, sbuf);
162  if (ret < 0) {
163  XPRINTF("Read fat12 sector failed sector=%u! \n", fatd->partBpb.partStart + fatd->partBpb.resSectors + fatSector + 1);
164  return -EIO;
165  }
166  xbuf[2] = sbuf[0];
167  xbuf[3] = sbuf[1];
168  }
169  }
170  if (sectorSpan) { // use xbuf as source buffer
171  cluster = fat_getClusterRecord12(xbuf + (recordOffset % fatd->partBpb.sectorSize) - (fatd->partBpb.sectorSize - 2), cluster % 2);
172  } else { // use sector buffer as source buffer
173  cluster = fat_getClusterRecord12(sbuf + (recordOffset % fatd->partBpb.sectorSize), cluster % 2);
174  }
175 
176  if ((cluster & 0xFFF) >= 0xFF8) {
177  cont = 0; // continue = false
178  } else {
179  buf[i] = cluster & 0xFFF;
180  i++;
181  }
182  }
183  return i;
184 }
185 
186 
187 //---------------------------------------------------------------------------
188 // for fat16
189 static int fat_getClusterChain16(fat_driver *fatd, unsigned int cluster, unsigned int *buf, unsigned int bufSize, int startFlag)
190 {
191  int ret;
192  unsigned int i, indexCount, lastFatSector;
193  unsigned char cont;
194  unsigned char *sbuf = NULL; // sector buffer
195 
196  M_DEBUG("%s\n", __func__);
197 
198  cont = 1;
199  indexCount = fatd->partBpb.sectorSize / 2; // FAT16->2, FAT32->4
200  lastFatSector = -1;
201  i = 0;
202  if (startFlag) {
203  buf[i] = cluster; // store first cluster
204  i++;
205  }
206  while (i < bufSize && cont) {
207  unsigned int fatSector;
208 
209  fatSector = cluster / indexCount;
210  if (lastFatSector != fatSector) {
211  ret = READ_SECTOR(DEV_ACCESSOR(fatd), fatd->partBpb.partStart + fatd->partBpb.resSectors + fatSector, sbuf);
212  if (ret < 0) {
213  XPRINTF("Read fat16 sector failed! sector=%u! \n", fatd->partBpb.partStart + fatd->partBpb.resSectors + fatSector);
214  return -EIO;
215  }
216 
217  lastFatSector = fatSector;
218  }
219  cluster = getUI16(sbuf + ((cluster % indexCount) * 2));
220  if ((cluster & 0xFFFF) >= 0xFFF8) {
221  cont = 0; // continue = false
222  } else {
223  buf[i] = cluster & 0xFFFF;
224  i++;
225  }
226  }
227  return i;
228 }
229 
230 //---------------------------------------------------------------------------
231 // for fat32
232 static int fat_getClusterChain32(fat_driver *fatd, unsigned int cluster, unsigned int *buf, unsigned int bufSize, int startFlag)
233 {
234  int ret;
235  unsigned int i, indexCount, lastFatSector;
236  unsigned char cont;
237  unsigned char *sbuf = NULL; // sector buffer
238 
239  M_DEBUG("%s\n", __func__);
240 
241  cont = 1;
242  indexCount = fatd->partBpb.sectorSize / 4; // FAT16->2, FAT32->4
243  lastFatSector = -1;
244  i = 0;
245  if (startFlag) {
246  buf[i] = cluster; // store first cluster
247  i++;
248  }
249  while (i < bufSize && cont) {
250  unsigned int fatSector;
251 
252  fatSector = cluster / indexCount;
253  if (lastFatSector != fatSector) {
254  ret = READ_SECTOR(DEV_ACCESSOR(fatd), fatd->partBpb.partStart + fatd->partBpb.resSectors + fatSector, sbuf);
255  if (ret < 0) {
256  XPRINTF("Read fat32 sector failed sector=%u! \n", fatd->partBpb.partStart + fatd->partBpb.resSectors + fatSector);
257  return -EIO;
258  }
259 
260  lastFatSector = fatSector;
261  }
262  cluster = getUI32(sbuf + ((cluster % indexCount) * 4));
263  if ((cluster & 0xFFFFFFF) >= 0xFFFFFF8) {
264  cont = 0; // continue = false
265  } else {
266  buf[i] = cluster & 0xFFFFFFF;
267  i++;
268  }
269  }
270  return i;
271 }
272 
273 //---------------------------------------------------------------------------
274 int fat_getClusterChain(fat_driver *fatd, unsigned int cluster, unsigned int *buf, unsigned int bufSize, int startFlag)
275 {
276  M_DEBUG("%s\n", __func__);
277 
278  if (cluster == fatd->lastChainCluster) {
279  return fatd->lastChainResult;
280  }
281 
282  switch (fatd->partBpb.fatType) {
283  case FAT12:
284  fatd->lastChainResult = fat_getClusterChain12(fatd, cluster, buf, bufSize, startFlag);
285  break;
286  case FAT16:
287  fatd->lastChainResult = fat_getClusterChain16(fatd, cluster, buf, bufSize, startFlag);
288  break;
289  case FAT32:
290  fatd->lastChainResult = fat_getClusterChain32(fatd, cluster, buf, bufSize, startFlag);
291  break;
292  }
293  fatd->lastChainCluster = cluster;
294  return fatd->lastChainResult;
295 }
296 
297 //---------------------------------------------------------------------------
298 #ifndef BUILDING_IEEE1394_DISK
299 int fat_CheckChain(fat_driver *fatd, unsigned int cluster)
300 {
301  int i, nextChain = 1;
302  int clusterChainStart = 1;
303 
304  if (cluster < 2)
305  return 0;
306 
307  while (nextChain) {
308  int chainSize;
309 
310  chainSize = fat_getClusterChain(fatd, cluster, fatd->cbuf, MAX_DIR_CLUSTER, clusterChainStart);
311  clusterChainStart = 0;
312  if (chainSize >= MAX_DIR_CLUSTER) { // the chain is full, but more chain parts exist
313  cluster = fatd->cbuf[MAX_DIR_CLUSTER - 1];
314  } else { // chain fits in the chain buffer completely - no next chain needed
315  nextChain = 0;
316  }
317 
318  // process the cluster chain (fatd->cbuf) and skip leading clusters if needed
319  for (i = 0; i < (chainSize - 1); i++) {
320  if ((fatd->cbuf[i] + 1) != fatd->cbuf[i + 1])
321  return 0;
322  }
323  }
324 
325  return 1;
326 }
327 #endif /* BUILDING_IEEE1394_DISK */
328 
329 //---------------------------------------------------------------------------
330 void fat_invalidateLastChainResult(fat_driver *fatd)
331 {
332  fatd->lastChainCluster = 0;
333 }
334 
335 //---------------------------------------------------------------------------
336 static void fat_determineFatType(fat_bpb *partBpb)
337 {
338  unsigned int sector, clusterCount;
339 
340  M_DEBUG("%s\n", __func__);
341 
342  // get sector of cluster 0
343  sector = fat_cluster2sector(partBpb, 0);
344  // remove partition start sector to get BR+FAT+ROOT_DIR sector count
345  sector -= partBpb->partStart;
346  sector = partBpb->sectorCount - sector;
347  clusterCount = sector / partBpb->clusterSize;
348  // XPRINTF("Data cluster count = %u \n", clusterCount);
349 
350  if (clusterCount < 4085) {
351  partBpb->fatType = FAT12;
352  } else if (clusterCount < 65525) {
353  partBpb->fatType = FAT16;
354  } else {
355  partBpb->fatType = FAT32;
356  }
357 }
358 
359 //---------------------------------------------------------------------------
360 #if defined(BUILDING_USBHDFSD)
361 static int fat_getPartitionBootSector(mass_dev *dev, unsigned int sector, fat_bpb *partBpb)
362 #elif defined(BUILDING_IEEE1394_DISK)
363 static int fat_getPartitionBootSector(struct SBP2Device *dev, unsigned int sector, fat_bpb *partBpb)
364 #else
365 static int fat_getPartitionBootSector(struct block_device *bd, unsigned int sector, fat_bpb *partBpb)
366 #endif
367 {
368  fat_raw_bpb *bpb_raw; // fat16, fat12
369  fat32_raw_bpb *bpb32_raw; // fat32
370  int ret;
371  unsigned char *sbuf = NULL; // sector buffer
372 
373  M_DEBUG("%s\n", __func__);
374 
375 #if !defined(BUILDING_USBHDFSD) && !defined(BUILDING_IEEE1394_DISK)
376  sbuf = malloc(bd->sectorSize);
377  ret = bd->read(bd, sector, sbuf, 1); // read partition boot sector (first sector on partition)
378 #else
379  ret = READ_SECTOR(dev, sector, sbuf); // read partition boot sector (first sector on partition)
380 #endif
381 
382  if (ret < 0) {
383  XPRINTF("Read partition boot sector failed sector=%u! \n", sector);
384 #if !defined(BUILDING_USBHDFSD) && !defined(BUILDING_IEEE1394_DISK)
385  free(sbuf);
386 #endif
387  return -EIO;
388  }
389 
390  bpb_raw = (fat_raw_bpb *)sbuf;
391  bpb32_raw = (fat32_raw_bpb *)sbuf;
392 
393 #if !defined(BUILDING_USBHDFSD) && !defined(BUILDING_IEEE1394_DISK)
394  if ((bpb32_raw->bootSignature[0] != 0x55) || (bpb32_raw->bootSignature[1] != 0xAA)) {
395  M_DEBUG("Invalid bootSignature (0x%x - 0x%x)\n", bpb32_raw->bootSignature[0], bpb32_raw->bootSignature[1]);
396  free(sbuf);
397  return -EIO;
398  }
399 #endif
400 
401  // set fat common properties
402  partBpb->sectorSize = getUI16(bpb_raw->sectorSize);
403  partBpb->clusterSize = bpb_raw->clusterSize;
404  partBpb->resSectors = getUI16(bpb_raw->resSectors);
405  partBpb->fatCount = bpb_raw->fatCount;
406  partBpb->rootSize = getUI16(bpb_raw->rootSize);
407  partBpb->fatSize = getUI16(bpb_raw->fatSize);
408  partBpb->trackSize = getUI16(bpb_raw->trackSize);
409  partBpb->headCount = getUI16(bpb_raw->headCount);
410  partBpb->sectorCount = getUI16(bpb_raw->sectorCountO);
411  if (partBpb->sectorCount == 0) {
412  partBpb->sectorCount = getUI32(bpb_raw->sectorCount); // large partition
413  }
414  partBpb->partStart = sector;
415  partBpb->rootDirStart = partBpb->partStart + (partBpb->fatCount * partBpb->fatSize) + partBpb->resSectors;
416  for (ret = 0; ret < 8; ret++) {
417  partBpb->fatId[ret] = bpb_raw->fatId[ret];
418  }
419  partBpb->fatId[ret] = 0;
420  partBpb->rootDirCluster = 0;
421  partBpb->dataStart = partBpb->rootDirStart + (partBpb->rootSize / (partBpb->sectorSize >> 5));
422 
423  fat_determineFatType(partBpb);
424 
425  // fat32 specific info
426  if (partBpb->fatType == FAT32 && partBpb->fatSize == 0) {
427  partBpb->fatSize = getUI32(bpb32_raw->fatSize32);
428  partBpb->activeFat = getUI16(bpb32_raw->fatStatus);
429  if (partBpb->activeFat & 0x80) { // fat not synced
430  partBpb->activeFat = (partBpb->activeFat & 0xF);
431  } else {
432  partBpb->activeFat = 0;
433  }
434  partBpb->rootDirStart = partBpb->partStart + (partBpb->fatCount * partBpb->fatSize) + partBpb->resSectors;
435  partBpb->rootDirCluster = getUI32(bpb32_raw->rootDirCluster);
436  for (ret = 0; ret < 8; ret++) {
437  partBpb->fatId[ret] = bpb32_raw->fatId[ret];
438  }
439  partBpb->fatId[ret] = 0;
440  partBpb->dataStart = partBpb->rootDirStart;
441  }
442 
443  M_PRINTF("Fat type %u Id %s \n", partBpb->fatType, partBpb->fatId);
444 #if !defined(BUILDING_USBHDFSD) && !defined(BUILDING_IEEE1394_DISK)
445  free(sbuf);
446 #endif
447  return 1;
448 }
449 
450 //---------------------------------------------------------------------------
451 /*
452  returns:
453  0 - no more dir entries
454  1 - short name dir entry found
455  2 - long name dir entry found
456  3 - deleted dir entry found
457 */
458 int fat_getDirentry(unsigned char fatType, fat_direntry *dir_entry, fat_direntry_summary *dir)
459 {
460  int i;
461 
462  u16 character;
463 
464  M_DEBUG("%s\n", __func__);
465 
466  // detect last entry - all zeros (slight modification by radad)
467  if (dir_entry->sfn.name[0] == 0) {
468  return 0;
469  }
470  // detect deleted entry - it will be ignored
471  if (dir_entry->sfn.name[0] == 0xE5) {
472  return 3;
473  }
474 
475  // detect long filename
476  if (dir_entry->lfn.rshv == 0x0F && dir_entry->lfn.reserved1 == 0x00 && dir_entry->lfn.reserved2[0] == 0x00) {
477  unsigned int offset;
478  unsigned char cont;
479 
480  // long filename - almost whole direntry is unicode string - extract it
481  offset = dir_entry->lfn.entrySeq & 0x3f;
482  offset--;
483  offset = offset * 13;
484  // name - 1st part
485  cont = 1;
486  for (i = 0; i < 10 && cont; i += 2) {
487  character = dir_entry->lfn.name1[i] | (dir_entry->lfn.name1[i + 1] << 8);
488 
489  if (character == 0 || offset >= (FAT_MAX_NAME - 1)) {
490  dir->name[offset] = 0; // terminate
491  cont = 0; // stop
492  } else {
493  // Handle characters that we don't support.
494  dir->name[offset] = character <= UCHAR_MAX ? dir_entry->lfn.name1[i] : '?';
495  offset++;
496  }
497  }
498  // name - 2nd part
499  for (i = 0; i < 12 && cont; i += 2) {
500  character = dir_entry->lfn.name2[i] | (dir_entry->lfn.name2[i + 1] << 8);
501 
502  if (character == 0 || offset >= (FAT_MAX_NAME - 1)) {
503  dir->name[offset] = 0; // terminate
504  cont = 0; // stop
505  } else {
506  // Handle characters that we don't support.
507  dir->name[offset] = character <= UCHAR_MAX ? dir_entry->lfn.name2[i] : '?';
508  offset++;
509  }
510  }
511  // name - 3rd part
512  for (i = 0; i < 4 && cont; i += 2) {
513  character = dir_entry->lfn.name3[i] | (dir_entry->lfn.name3[i + 1] << 8);
514 
515  if (character == 0 || offset >= (FAT_MAX_NAME - 1)) {
516  dir->name[offset] = 0; // terminate
517  cont = 0; // stop
518  } else {
519  // Handle characters that we don't support.
520  dir->name[offset] = character <= UCHAR_MAX ? dir_entry->lfn.name3[i] : '?';
521  offset++;
522  }
523  }
524  if ((dir_entry->lfn.entrySeq & 0x40)) { // terminate string flag
525  dir->name[offset] = 0;
526  }
527  return 2;
528  } else {
529  int j;
530 
531  // short filename
532  // copy name
533  for (i = 0; i < 8 && dir_entry->sfn.name[i] != ' '; i++) {
534  dir->sname[i] = dir_entry->sfn.name[i];
535  // NT-adaption for LaunchELF
536  if (dir_entry->sfn.reservedNT & 0x08 &&
537  dir->sname[i] >= 'A' && dir->sname[i] <= 'Z') {
538  dir->sname[i] += 0x20; // Force standard letters in name to lower case
539  }
540  }
541  for (j = 0; j < 3 && dir_entry->sfn.ext[j] != ' '; j++) {
542  if (j == 0) {
543  dir->sname[i] = '.';
544  i++;
545  }
546  dir->sname[i + j] = dir_entry->sfn.ext[j];
547  // NT-adaption for LaunchELF
548  if (dir_entry->sfn.reservedNT & 0x10 &&
549  dir->sname[i + j] >= 'A' && dir->sname[i + j] <= 'Z') {
550  dir->sname[i + j] += 0x20; // Force standard letters in ext to lower case
551  }
552  }
553  dir->sname[i + j] = 0; // terminate
554  if (dir->name[0] == 0) { // long name desn't exit
555  for (i = 0; dir->sname[i] != 0; i++)
556  dir->name[i] = dir->sname[i];
557  dir->name[i] = 0;
558  }
559  dir->attr = dir_entry->sfn.attr;
560  dir->size = getUI32(dir_entry->sfn.size);
561  dir->cluster = (fatType == FAT32) ? getUI32_2(dir_entry->sfn.clusterL, dir_entry->sfn.clusterH) : getUI16(dir_entry->sfn.clusterL);
562 
563  return 1;
564  }
565 }
566 
567 //---------------------------------------------------------------------------
568 // Set chain info (cluster/offset) cache
569 void fat_setFatDirChain(fat_driver *fatd, fat_dir *fatDir)
570 {
571  int i, j;
572  unsigned int index, clusterChainStart, fileCluster, fileSize, blockSize;
573  unsigned char nextChain;
574  int chainSize;
575 
576  M_DEBUG("%s\n", __func__);
577  XPRINTF("reading cluster chain \n");
578  fileCluster = fatDir->chain[0].cluster;
579 
580  if (fileCluster < 2) {
581  XPRINTF(" early exit... \n");
582  return;
583  }
584 
585  fileSize = fatDir->size;
586  blockSize = fileSize / DIR_CHAIN_SIZE;
587 
588  nextChain = 1;
589  clusterChainStart = 0;
590  j = 1;
591  fileSize = 0;
592  index = 0;
593 
594  while (nextChain) {
595  if ((chainSize = fat_getClusterChain(fatd, fileCluster, fatd->cbuf, MAX_DIR_CLUSTER, 1)) >= 0) {
596  if (chainSize >= MAX_DIR_CLUSTER) { // the chain is full, but more chain parts exist
597  fileCluster = fatd->cbuf[MAX_DIR_CLUSTER - 1];
598  } else { // chain fits in the chain buffer completely - no next chain exist
599  nextChain = 0;
600  }
601  } else {
602  XPRINTF("fat_setFatDirChain(): fat_getClusterChain() failed: %d\n", chainSize);
603  return;
604  }
605 
606  // process the cluster chain (fatd->cbuf)
607  for (i = clusterChainStart; i < chainSize; i++) {
608  fileSize += (fatd->partBpb.clusterSize * fatd->partBpb.sectorSize);
609  while (fileSize >= (j * blockSize) && j < DIR_CHAIN_SIZE) {
610  fatDir->chain[j].cluster = fatd->cbuf[i];
611  fatDir->chain[j].index = index;
612  j++;
613  } // ends "while"
614  index++;
615  } // ends "for"
616  clusterChainStart = 1;
617  } // ends "while"
618  fatDir->lastCluster = fatd->cbuf[i - 1];
619 
620 #ifdef DEBUG_EXTREME // dlanor: I patched this because this bloat hid important stuff
621  // debug
622  XPRINTF("SEEK CLUSTER CHAIN CACHE fileSize=%u blockSize=%u \n", fatDir->size, blockSize);
623  for (i = 0; i < DIR_CHAIN_SIZE; i++) {
624  XPRINTF("index=%u cluster=%u offset= %u - %u start=%u \n",
625  fatDir->chain[i].index, fatDir->chain[i].cluster,
626  fatDir->chain[i].index * fatd->partBpb.clusterSize * fatd->partBpb.sectorSize,
627  (fatDir->chain[i].index + 1) * fatd->partBpb.clusterSize * fatd->partBpb.sectorSize,
628  i * blockSize);
629  }
630 #endif /* debug */
631  XPRINTF("read cluster chain done!\n");
632 }
633 
634 //---------------------------------------------------------------------------
635 /* Set base attributes of direntry */
636 static void fat_setFatDir(fat_driver *fatd, fat_dir *fatDir, unsigned int parentDirCluster, fat_direntry_sfn *dsfn, fat_direntry_summary *dir, int getClusterInfo)
637 {
638  unsigned int i;
639  char *srcName;
640 
641  M_DEBUG("%s\n", __func__);
642  XPRINTF("setting fat dir...\n");
643  srcName = dir->sname;
644  if (dir->name[0] != 0) { // long filename not empty
645  srcName = dir->name;
646  }
647  // copy name
648  for (i = 0; srcName[i] != 0; i++)
649  fatDir->name[i] = srcName[i];
650  fatDir->name[i] = 0; // terminate
651 
652  fatDir->attr = dir->attr;
653  fatDir->size = dir->size;
654 
655  // created Date: Day, Month, Year-low, Year-high
656  fatDir->cdate[0] = (dsfn->dateCreate[0] & 0x1F);
657  fatDir->cdate[1] = (dsfn->dateCreate[0] >> 5) + ((dsfn->dateCreate[1] & 0x01) << 3);
658  i = 1980 + (dsfn->dateCreate[1] >> 1);
659  fatDir->cdate[2] = (i & 0xFF);
660  fatDir->cdate[3] = ((i & 0xFF00) >> 8);
661 
662  // created Time: Hours, Minutes, Seconds
663  fatDir->ctime[0] = ((dsfn->timeCreate[1] & 0xF8) >> 3);
664  fatDir->ctime[1] = ((dsfn->timeCreate[1] & 0x07) << 3) + ((dsfn->timeCreate[0] & 0xE0) >> 5);
665  fatDir->ctime[2] = ((dsfn->timeCreate[0] & 0x1F) << 1);
666 
667  // accessed Date: Day, Month, Year-low, Year-high
668  fatDir->adate[0] = (dsfn->dateAccess[0] & 0x1F);
669  fatDir->adate[1] = (dsfn->dateAccess[0] >> 5) + ((dsfn->dateAccess[1] & 0x01) << 3);
670  i = 1980 + (dsfn->dateAccess[1] >> 1);
671  fatDir->adate[2] = (i & 0xFF);
672  fatDir->adate[3] = ((i & 0xFF00) >> 8);
673 
674  // modified Date: Day, Month, Year-low, Year-high
675  fatDir->mdate[0] = (dsfn->dateWrite[0] & 0x1F);
676  fatDir->mdate[1] = (dsfn->dateWrite[0] >> 5) + ((dsfn->dateWrite[1] & 0x01) << 3);
677  i = 1980 + (dsfn->dateWrite[1] >> 1);
678  fatDir->mdate[2] = (i & 0xFF);
679  fatDir->mdate[3] = ((i & 0xFF00) >> 8);
680 
681  // modified Time: Hours, Minutes, Seconds
682  fatDir->mtime[0] = ((dsfn->timeWrite[1] & 0xF8) >> 3);
683  fatDir->mtime[1] = ((dsfn->timeWrite[1] & 0x07) << 3) + ((dsfn->timeWrite[0] & 0xE0) >> 5);
684  fatDir->mtime[2] = ((dsfn->timeWrite[0] & 0x1F) << 1);
685 
686  fatDir->chain[0].cluster = dir->cluster;
687  fatDir->chain[0].index = 0;
688  if (getClusterInfo) {
689  fat_setFatDirChain(fatd, fatDir);
690  }
691 
692  fatDir->parentDirCluster = parentDirCluster;
693  fatDir->startCluster = dir->cluster;
694 }
695 
696 //---------------------------------------------------------------------------
697 int fat_getDirentrySectorData(fat_driver *fatd, unsigned int *startCluster, unsigned int *startSector, unsigned int *dirSector)
698 {
699  unsigned int chainSize;
700 
701  M_DEBUG("%s\n", __func__);
702 
703  if (*startCluster == 0 && fatd->partBpb.fatType < FAT32) { // Root directory
704  *startSector = fatd->partBpb.rootDirStart;
705  *dirSector = fatd->partBpb.rootSize / (fatd->partBpb.sectorSize / 32);
706  return 0;
707  }
708  // other directory or fat 32
709  if (*startCluster == 0 && fatd->partBpb.fatType == FAT32) {
710  *startCluster = fatd->partBpb.rootDirCluster;
711  }
712  *startSector = fat_cluster2sector(&fatd->partBpb, *startCluster);
713  chainSize = fat_getClusterChain(fatd, *startCluster, fatd->cbuf, MAX_DIR_CLUSTER, 1);
714  if (chainSize >= MAX_DIR_CLUSTER) {
715  XPRINTF("Chain too large\n");
716  return -EFAULT;
717  } else if (chainSize > 0) {
718  *dirSector = chainSize * fatd->partBpb.clusterSize;
719  } else {
720  XPRINTF("Error getting cluster chain! startCluster=%u \n", *startCluster);
721  return -EFAULT;
722  }
723 
724  return chainSize;
725 }
726 
727 //---------------------------------------------------------------------------
728 static int fat_getDirentryStartCluster(fat_driver *fatd, char *dirName, unsigned int *startCluster, fat_dir *fatDir)
729 {
730 #if !defined(BUILDING_IEEE1394_DISK) && !defined(BUILDING_USBHDFSD)
731  static fat_direntry_summary dir; // TOO BIG FOR STACK!
732 #else
734 #endif
735  unsigned int i, dirSector, startSector;
736  unsigned char cont;
737  int ret;
738 #ifdef DEBUG
739 #ifdef BUILDING_USBHDFSD
740  mass_dev *mass_device = fatd->dev;
741 #endif /* BUILDING_USBHDFSD */
742 #ifdef BUILDING_IEEE1394_DISK
743  struct SBP2Device *mass_device = fatd->dev;
744 #endif /* BUILDING_IEEE1394_DISK */
745 #endif
746 
747  M_DEBUG("%s(%s)\n", __func__, dirName);
748 
749  cont = 1;
750  XPRINTF("getting cluster for dir entry: %s \n", dirName);
751  // clear name strings
752  dir.sname[0] = 0;
753  dir.name[0] = 0;
754 
755  ret = fat_getDirentrySectorData(fatd, startCluster, &startSector, &dirSector);
756  if (ret < 0)
757  return ret;
758 
759  XPRINTF("dirCluster=%u startSector=%u (%u) dirSector=%u \n", *startCluster, startSector, startSector
760 #if !defined(BUILDING_IEEE1394_DISK) && !defined(BUILDING_USBHDFSD)
761  * fatd->bd->sectorSize,
762 #else
763  * mass_device->sectorSize,
764 #endif
765  dirSector);
766 
767  // go through first directory sector till the max number of directory sectors
768  // or stop when no more direntries detected
769  for (i = 0; i < dirSector && cont; i++) {
770  unsigned int dirPos;
771  unsigned char *sbuf = NULL; // sector buffer
772 
773  // At cluster borders, get correct sector from cluster chain buffer
774  if ((*startCluster != 0) && (i % fatd->partBpb.clusterSize == 0)) {
775  startSector = fat_cluster2sector(&fatd->partBpb, fatd->cbuf[(i / fatd->partBpb.clusterSize)]) - i;
776  }
777 
778  ret = READ_SECTOR(DEV_ACCESSOR(fatd), startSector + i, sbuf);
779  if (ret < 0) {
780  XPRINTF("read directory sector failed ! sector=%u\n", startSector + i);
781  return -EIO;
782  }
783  XPRINTF("read sector ok, scanning sector for direntries...\n");
784  dirPos = 0;
785 
786  // go through start of the sector till the end of sector
787  while (cont && dirPos < fatd->partBpb.sectorSize) {
788  fat_direntry *dir_entry = (fat_direntry *)(sbuf + dirPos);
789  cont = fat_getDirentry(fatd->partBpb.fatType, dir_entry, &dir); // get single directory entry from sector buffer
790  if (cont == 1) { // when short file name entry detected
791  if (!(dir.attr & FAT_ATTR_VOLUME_LABEL)) { // not volume label
792  if ((strEqual(dir.sname, dirName) == 0) ||
793  (strEqual(dir.name, dirName) == 0)) {
794  XPRINTF("found! %s\n", dir.name);
795  if (fatDir != NULL) { // fill the directory properties
796  fat_setFatDir(fatd, fatDir, *startCluster, &dir_entry->sfn, &dir, 1);
797  }
798  *startCluster = dir.cluster;
799  XPRINTF("direntry %s found at cluster: %u \n", dirName, dir.cluster);
800  return dir.attr; // returns file or directory attr
801  }
802  } // ends "if(!(dir.attr & FAT_ATTR_VOLUME_LABEL))"
803  // clear name strings
804  dir.sname[0] = 0;
805  dir.name[0] = 0;
806  } // ends "if (cont == 1)"
807  dirPos += sizeof(fat_direntry);
808  } // ends "while"
809  } // ends "for"
810  XPRINTF("direntry %s not found! \n", dirName);
811  return -ENOENT;
812 }
813 
814 //---------------------------------------------------------------------------
815 // start cluster should be 0 - if we want to search from root directory
816 // otherwise the start cluster should be correct cluster of directory
817 // to search directory - set fatDir as NULL
818 int fat_getFileStartCluster(fat_driver *fatd, const char *fname, unsigned int *startCluster, fat_dir *fatDir)
819 {
820 #if !defined(BUILDING_IEEE1394_DISK) && !defined(BUILDING_USBHDFSD)
821  static char tmpName[FAT_MAX_NAME + 1]; // TOO BIG FOR STACK!
822 #else
823  char tmpName[FAT_MAX_NAME + 1];
824 #endif
825  unsigned int i, offset;
826  int ret;
827 
828  M_DEBUG("%s\n", __func__);
829  XPRINTF("Entering fat_getFileStartCluster\n");
830 
831  offset = 0;
832  i = 0;
833 
834  *startCluster = 0;
835  if (fatDir != NULL) {
836  memset(fatDir, 0, sizeof(fat_dir));
837  fatDir->attr = FAT_ATTR_DIRECTORY;
838  }
839  if (fname[i] == '/') {
840  i++;
841  }
842 
843  for (; fname[i] != 0; i++) {
844  if (fname[i] == '/') { // directory separator
845  tmpName[offset] = 0; // terminate string
846  ret = fat_getDirentryStartCluster(fatd, tmpName, startCluster, fatDir);
847  if (ret < 0) {
848  return -ENOENT;
849  }
850  offset = 0;
851  } else {
852  tmpName[offset] = fname[i];
853  offset++;
854  }
855  } // ends "for"
856  // and the final file
857  tmpName[offset] = 0; // terminate string
858  XPRINTF("Ready to get cluster for file \"%s\"\n", tmpName);
859  if (fatDir != NULL) {
860  // if the last char of the name was slash - the name was already found -exit
861  if (offset == 0) {
862  XPRINTF("Exiting from fat_getFileStartCluster with a folder\n");
863  return 2;
864  }
865  ret = fat_getDirentryStartCluster(fatd, tmpName, startCluster, fatDir);
866  if (ret < 0) {
867  XPRINTF("Exiting from fat_getFileStartCluster with error %i\n", ret);
868  return ret;
869  }
870  XPRINTF("file's startCluster found. Name=%s, cluster=%u \n", fname, *startCluster);
871  }
872  XPRINTF("Exiting from fat_getFileStartCluster with no error.\n");
873  return 1;
874 }
875 
876 //---------------------------------------------------------------------------
877 void fat_getClusterAtFilePos(fat_driver *fatd, fat_dir *fatDir, unsigned int filePos, unsigned int *cluster, unsigned int *clusterPos)
878 {
879  unsigned int i, j, blockSize;
880 
881  M_DEBUG("%s\n", __func__);
882 
883  blockSize = fatd->partBpb.clusterSize * fatd->partBpb.sectorSize;
884 
885  for (i = 0, j = (DIR_CHAIN_SIZE - 1); i < (DIR_CHAIN_SIZE - 1); i++) {
886  if (fatDir->chain[i].index * blockSize <= filePos &&
887  fatDir->chain[i + 1].index * blockSize > filePos) {
888  j = i;
889  break;
890  }
891  }
892  *cluster = fatDir->chain[j].cluster;
893  *clusterPos = (fatDir->chain[j].index * blockSize);
894 }
895 
896 //---------------------------------------------------------------------------
897 #ifdef BUILDING_USBHDFSD
898 static int fat_readSingleSector(mass_dev *dev, unsigned int sector, void *buffer, int size, int dataSkip)
899 {
900  unsigned char *sbuf = NULL; // sector buffer
901  int ret;
902 
903  ret = READ_SECTOR(dev, sector, sbuf);
904  if (ret < 0) {
905  XPRINTF("Read sector failed ! sector=%u\n", sector);
906  return 0;
907  }
908 
909  memcpy(buffer, sbuf + dataSkip, size);
910 
911  return 1;
912 }
913 #endif /* BUILDING_USBHDFSD */
914 
915 int fat_readFile(fat_driver *fatd, fat_dir *fatDir, unsigned int filePos, unsigned char *buffer, unsigned int size)
916 {
917  int ret;
918 #ifdef BUILDING_USBHDFSD
919  unsigned int toRead;
920 #endif
921  unsigned int i, j, startSector, clusterChainStart, bufSize, sectorSkip, clusterSkip, dataSkip;
922  unsigned char nextChain;
923 #ifdef BUILDING_USBHDFSD
924  // cppcheck-suppress unreadVariable
925  mass_dev *mass_device = fatd->dev;
926 #endif /* BUILDING_USBHDFSD */
927 #ifdef BUILDING_IEEE1394_DISK
928  struct SBP2Device *mass_device = fatd->dev;
929 #endif /* BUILDING_IEEE1394_DISK */
930 
931  unsigned int bufferPos, fileCluster, clusterPos;
932 
933  M_DEBUG("%s\n", __func__);
934 
935  fat_getClusterAtFilePos(fatd, fatDir, filePos, &fileCluster, &clusterPos);
936  sectorSkip = (filePos - clusterPos) / fatd->partBpb.sectorSize;
937  clusterSkip = sectorSkip / fatd->partBpb.clusterSize;
938  sectorSkip %= fatd->partBpb.clusterSize;
939  dataSkip = filePos % fatd->partBpb.sectorSize;
940  bufferPos = 0;
941 
942  XPRINTF("fileCluster = %u, clusterPos= %u clusterSkip=%u, sectorSkip=%u dataSkip=%u \n",
943  fileCluster, clusterPos, clusterSkip, sectorSkip, dataSkip);
944 
945  if (fileCluster < 2) {
946  return 0;
947  }
948 
949 #ifdef BUILDING_IEEE1394_DISK
950  // cppcheck-suppress unreadVariable
951  bufSize = mass_device->sectorSize;
952 #endif /* BUILDING_IEEE1394_DISK */
953 #if !defined(BUILDING_IEEE1394_DISK) && !defined(BUILDING_USBHDFSD)
954  bufSize = fatd->bd->sectorSize;
955 #endif
956  nextChain = 1;
957  clusterChainStart = 1;
958 
959  while (nextChain && size > 0) {
960  int chainSize;
961 
962  if ((chainSize = fat_getClusterChain(fatd, fileCluster, fatd->cbuf, MAX_DIR_CLUSTER, clusterChainStart)) < 0) {
963  return chainSize;
964  }
965 
966  clusterChainStart = 0;
967  if (chainSize >= MAX_DIR_CLUSTER) { // the chain is full, but more chain parts exist
968  fileCluster = fatd->cbuf[MAX_DIR_CLUSTER - 1];
969  } else { // chain fits in the chain buffer completely - no next chain needed
970  nextChain = 0;
971  }
972  while (clusterSkip >= MAX_DIR_CLUSTER) {
973  chainSize = fat_getClusterChain(fatd, fileCluster, fatd->cbuf, MAX_DIR_CLUSTER, clusterChainStart);
974  clusterChainStart = 0;
975  if (chainSize >= MAX_DIR_CLUSTER) { // the chain is full, but more chain parts exist
976  fileCluster = fatd->cbuf[MAX_DIR_CLUSTER - 1];
977  } else { // chain fits in the chain buffer completely - no next chain needed
978  nextChain = 0;
979  }
980  clusterSkip -= MAX_DIR_CLUSTER;
981  }
982 
983  // process the cluster chain (fatd->cbuf) and skip leading clusters if needed
984  for (i = 0 + clusterSkip; i < (unsigned int)chainSize && size > 0; i++) {
985  // read cluster and save cluster content
986  startSector = fat_cluster2sector(&fatd->partBpb, fatd->cbuf[i]);
987 
988 #ifdef BUILDING_USBHDFSD
989  // Calculate how long we can continuously read for.
990  j = (size + dataSkip) / fatd->partBpb.sectorSize + sectorSkip;
991  toRead = 0;
992  while (1) {
993  if (j >= fatd->partBpb.clusterSize) {
994  toRead += fatd->partBpb.clusterSize;
995  j -= fatd->partBpb.clusterSize;
996  } else {
997  toRead += j;
998  j = 0;
999  }
1000 
1001  // Check that the next cluster is adjacent to this one, so we can read across.
1002  if ((i >= (unsigned int)(chainSize - 1)) || (fatd->cbuf[i] != (fatd->cbuf[i + 1] - 1)))
1003  break;
1004  if (j == 0)
1005  break;
1006  i++; // Advance to the next cluster.
1007  }
1008 
1009  // Consider the number of sectors within the cluster to skip.
1010  startSector += sectorSkip;
1011  toRead -= sectorSkip;
1012 #endif /* BUILDING_USBHDFSD */
1013 
1014  // process all sectors of the cluster (and skip leading sectors if needed)
1015 #ifndef BUILDING_USBHDFSD
1016  for (j = 0 + sectorSkip; j < fatd->partBpb.clusterSize && size > 0; j++) {
1017  unsigned char *sbuf = NULL; // sector buffer
1018 
1019  ret = READ_SECTOR(DEV_ACCESSOR(fatd), startSector + j, sbuf);
1020  if (ret < 0) {
1021  XPRINTF("Read sector failed ! sector=%u\n", startSector + j);
1022  return bufferPos;
1023  }
1024 
1025  // compute exact size of transfered bytes
1026  if (size < bufSize) {
1027  bufSize = size + dataSkip;
1028  }
1029 #ifdef BUILDING_IEEE1394_DISK
1030  if (bufSize > mass_device->sectorSize) {
1031  bufSize = mass_device->sectorSize;
1032  }
1033 #else
1034  if (bufSize > fatd->bd->sectorSize) {
1035  bufSize = fatd->bd->sectorSize;
1036  }
1037 #endif
1038  XPRINTF("memcopy dst=%u, src=%u, size=%u bufSize=%u \n", bufferPos, dataSkip, bufSize - dataSkip, bufSize);
1039  memcpy(buffer + bufferPos, sbuf + dataSkip, bufSize - dataSkip);
1040  size -= (bufSize - dataSkip);
1041  bufferPos += (bufSize - dataSkip);
1042  dataSkip = 0;
1043 #ifdef BUILDING_IEEE1394_DISK
1044  bufSize = mass_device->sectorSize;
1045 #else
1046  bufSize = fatd->bd->sectorSize;
1047 #endif
1048  }
1049 #endif /* BUILDING_USBHDFSD */
1050 
1051 #ifdef BUILDING_USBHDFSD
1052  if (dataSkip > 0) {
1053  bufSize = mass_device->sectorSize - dataSkip;
1054  if (size < bufSize)
1055  bufSize = size;
1056 
1057  ret = fat_readSingleSector(fatd->dev, startSector, buffer + bufferPos, bufSize, dataSkip);
1058  if (ret != 1) {
1059  return bufferPos;
1060  }
1061 
1062  if (size + dataSkip >= mass_device->sectorSize)
1063  toRead--;
1064 
1065  size -= bufSize;
1066  bufferPos += bufSize;
1067  dataSkip = 0;
1068  startSector++;
1069  }
1070 
1071  if (toRead > 0) {
1072  INVALIDATE_SECTORS(DEV_ACCESSOR(fatd), startSector, toRead);
1073  ret = READ_SECTORS_RAW(DEV_ACCESSOR(fatd), startSector, toRead, buffer + bufferPos);
1074  if (ret != 0) {
1075  XPRINTF("Read sectors failed ! sector=%u (%u)\n", startSector, toRead);
1076  return bufferPos;
1077  }
1078 
1079  bufSize = toRead * mass_device->sectorSize;
1080  size -= bufSize;
1081  bufferPos += bufSize;
1082  startSector += toRead;
1083  }
1084 
1085  if (size > 0 && size <= mass_device->sectorSize) {
1086  bufSize = size;
1087 
1088  ret = fat_readSingleSector(fatd->dev, startSector, buffer + bufferPos, bufSize, 0);
1089  if (ret != 1) {
1090  return bufferPos;
1091  }
1092 
1093  size -= bufSize;
1094  bufferPos += bufSize;
1095  }
1096 #endif /* BUILDING_USBHDFSD */
1097 
1098  sectorSkip = 0;
1099  }
1100  clusterSkip = 0;
1101  }
1102  return bufferPos;
1103 }
1104 
1105 //---------------------------------------------------------------------------
1106 int fat_getNextDirentry(fat_driver *fatd, fat_dir_list *fatdlist, fat_dir *fatDir)
1107 {
1108 #if !defined(BUILDING_IEEE1394_DISK) && !defined(BUILDING_USBHDFSD)
1109  static fat_direntry_summary dir; // TOO BIG FOR STACK!
1110 #else
1112 #endif
1113  int i, ret;
1114  unsigned int startSector, dirSector, dirPos, dirCluster;
1115  unsigned char cont, new_entry;
1116 #ifdef DEBUG
1117 #ifdef BUILDING_USBHDFSD
1118  mass_dev *mass_device = fatd->dev;
1119 #endif /* BUILDING_USBHDFSD */
1120 #ifdef BUILDING_IEEE1394_DISK
1121  struct SBP2Device *mass_device = fatd->dev;
1122 #endif /* BUILDING_IEEE1394_DISK */
1123 #endif
1124 
1125  M_DEBUG("%s\n", __func__);
1126 
1127  // the getFirst function was not called
1128  if (fatdlist->direntryCluster == 0xFFFFFFFF || fatDir == NULL) {
1129  return -EFAULT;
1130  }
1131 
1132  dirCluster = fatdlist->direntryCluster;
1133 
1134  // clear name strings
1135  dir.sname[0] = 0;
1136  dir.name[0] = 0;
1137 
1138  ret = fat_getDirentrySectorData(fatd, &dirCluster, &startSector, &dirSector);
1139  if (ret < 0)
1140  return ret;
1141 
1142  XPRINTF("dirCluster=%u startSector=%u (%u) dirSector=%u \n", dirCluster, startSector, startSector
1143 #if !defined(BUILDING_IEEE1394_DISK) && !defined(BUILDING_USBHDFSD)
1144  * fatd->bd->sectorSize,
1145 #else
1146  * mass_device->sectorSize,
1147 #endif
1148  dirSector);
1149 
1150  // go through first directory sector till the max number of directory sectors
1151  // or stop when no more direntries detected
1152  // dlanor: but avoid rescanning same areas redundantly (if possible)
1153  cont = 1;
1154  new_entry = 1;
1155  dirPos = (fatdlist->direntryIndex * 32) % fatd->partBpb.sectorSize;
1156  for (i = ((fatdlist->direntryIndex * 32) / fatd->partBpb.sectorSize); ((unsigned int)i < dirSector) && cont; i++) {
1157  unsigned char *sbuf = NULL; // sector buffer
1158 
1159  // At cluster borders, get correct sector from cluster chain buffer
1160  if ((dirCluster != 0) && (new_entry || (i % fatd->partBpb.clusterSize == 0))) {
1161  startSector = fat_cluster2sector(&fatd->partBpb, fatd->cbuf[(i / fatd->partBpb.clusterSize)]) - i + (i % fatd->partBpb.clusterSize);
1162  new_entry = 0;
1163  }
1164  ret = READ_SECTOR(DEV_ACCESSOR(fatd), startSector + i, sbuf);
1165  if (ret < 0) {
1166  XPRINTF("Read directory sector failed ! sector=%u\n", startSector + i);
1167  return -EIO;
1168  }
1169 
1170  // go through sector from current pos till its end
1171  while (cont && (dirPos < fatd->partBpb.sectorSize)) {
1172  fat_direntry *dir_entry = (fat_direntry *)(sbuf + dirPos);
1173  cont = fat_getDirentry(fatd->partBpb.fatType, dir_entry, &dir); // get a directory entry from sector
1174  fatdlist->direntryIndex++; // Note current entry processed
1175  if (cont == 1) { // when short file name entry detected
1176  fat_setFatDir(fatd, fatDir, dirCluster, &dir_entry->sfn, &dir, 0);
1177 #if 0
1178  XPRINTF("fat_getNextDirentry %c%c%c%c%c%c %x %s %s\n",
1179  (dir.attr & FAT_ATTR_VOLUME_LABEL) ? 'v' : '-',
1180  (dir.attr & FAT_ATTR_DIRECTORY) ? 'd' : '-',
1181  (dir.attr & FAT_ATTR_READONLY) ? 'r' : '-',
1182  (dir.attr & FAT_ATTR_ARCHIVE) ? 'a' : '-',
1183  (dir.attr & FAT_ATTR_SYSTEM) ? 's' : '-',
1184  (dir.attr & FAT_ATTR_HIDDEN) ? 'h' : '-',
1185  dir.attr,
1186  dir.sname,
1187  dir.name);
1188 #endif
1189  return 1;
1190  }
1191  dirPos += sizeof(fat_direntry);
1192  } // ends "while"
1193  dirPos = 0;
1194  } // ends "for"
1195  // when we get this far - reset the direntry cluster
1196  fatdlist->direntryCluster = 0xFFFFFFFF; // no more files
1197  return 0; // indicate that no direntry is avalable
1198 }
1199 
1200 //---------------------------------------------------------------------------
1201 int fat_getFirstDirentry(fat_driver *fatd, const char *dirName, fat_dir_list *fatdlist, fat_dir *fatDir_host, fat_dir *fatDir)
1202 {
1203  int ret;
1204  unsigned int startCluster = 0;
1205 
1206  M_DEBUG("%s\n", __func__);
1207 
1208  ret = fat_getFileStartCluster(fatd, dirName, &startCluster, fatDir_host);
1209  if (ret < 0) { // dir name not found
1210  return -ENOENT;
1211  }
1212  // check that direntry is directory
1213  if (!(fatDir_host->attr & FAT_ATTR_DIRECTORY)) {
1214  return -ENOTDIR; // it's a file - exit
1215  }
1216  fatdlist->direntryCluster = startCluster;
1217  fatdlist->direntryIndex = 0;
1218  return fat_getNextDirentry(fatd, fatdlist, fatDir);
1219 }
1220 
1221 //---------------------------------------------------------------------------
1222 #if defined(BUILDING_USBHDFSD)
1223 int fat_mount(mass_dev *dev, unsigned int start, unsigned int count)
1224 #elif defined(BUILDING_IEEE1394_DISK)
1225 int fat_mount(struct SBP2Device *dev, unsigned int start, unsigned int count)
1226 #else
1227 int fat_mount(struct block_device *bd)
1228 #endif
1229 {
1230  fat_driver *fatd = NULL;
1231  unsigned int i;
1232 
1233  M_DEBUG("%s\n", __func__);
1234 
1235 #if defined(BUILDING_USBHDFSD) || defined(BUILDING_IEEE1394_DISK)
1236  (void)count;
1237 #endif
1238 
1239  // Filter for supported partition IDs:
1240  // - 0x0b = FAT32 with CHS addressing
1241  // - 0x0c = FAT32 with LBA addressing
1242  // AKuHAK: dont filter partition, fat_getPartitionBootSector() will care about
1243  // that, this is filtering too much if (bd->parId != 0x0b && bd->parId !=
1244  // 0x0c)
1245  // return -1;
1246 
1247  for (i = 0; i < NUM_DRIVES && fatd == NULL; ++i) {
1248  if (g_fatd[i] == NULL) {
1249  XPRINTF("usb fat: allocate fat_driver %d!\n", sizeof(fat_driver));
1250  g_fatd[i] = malloc(sizeof(fat_driver));
1251  if (g_fatd[i] != NULL) {
1252 #if !defined(BUILDING_IEEE1394_DISK) && !defined(BUILDING_USBHDFSD)
1253  g_fatd[i]->bd = NULL;
1254  g_fatd[i]->cache = NULL;
1255 #else
1256  g_fatd[i]->dev = NULL;
1257 #endif
1258  }
1259  fatd = g_fatd[i];
1260  } else if (
1261 #if !defined(BUILDING_IEEE1394_DISK) && !defined(BUILDING_USBHDFSD)
1262  g_fatd[i]->bd
1263 #else
1264  g_fatd[i]->dev
1265 #endif
1266  == NULL) {
1267  fatd = g_fatd[i];
1268  }
1269  }
1270 
1271  if (fatd == NULL) {
1272  M_PRINTF("unable to allocate drive!\n");
1273  return -1;
1274  }
1275 
1276 #if !defined(BUILDING_IEEE1394_DISK) && !defined(BUILDING_USBHDFSD)
1277  if (fatd->bd != NULL) {
1278  M_PRINTF("mount ERROR: alread mounted\n");
1279  fat_forceUnmount(fatd->bd);
1280  }
1281 #else
1282  if (fatd->dev != NULL) {
1283  M_PRINTF("mount ERROR: alread mounted\n");
1284  fat_forceUnmount(fatd->dev);
1285  }
1286 #endif
1287 
1288 #if !defined(BUILDING_IEEE1394_DISK) && !defined(BUILDING_USBHDFSD)
1289  if (fatd->cache != NULL) {
1290  M_PRINTF("ERROR: cache already created\n");
1291  scache_kill(fatd->cache);
1292  fatd->cache = NULL;
1293  }
1294 #endif
1295 
1296 #if !defined(BUILDING_IEEE1394_DISK) && !defined(BUILDING_USBHDFSD)
1297  if (fat_getPartitionBootSector(bd, bd->sectorOffset, &fatd->partBpb) < 0)
1298  return -1;
1299 #else
1300  if (fat_getPartitionBootSector(dev, start, &fatd->partBpb) < 0)
1301  return -1;
1302 #endif
1303 
1304 #if !defined(BUILDING_IEEE1394_DISK) && !defined(BUILDING_USBHDFSD)
1305  fatd->cache = scache_init(bd);
1306  if (fatd->cache == NULL) {
1307  M_PRINTF("Error - scache_init failed\n");
1308  return -1;
1309  }
1310 #endif
1311 
1312 #if !defined(BUILDING_IEEE1394_DISK) && !defined(BUILDING_USBHDFSD)
1313  fatd->bd = bd;
1314 #else
1315  fatd->dev = dev;
1316 #endif
1317  fatd->deIdx = 0;
1318  fatd->clStackIndex = 0;
1319  fatd->clStackLast = 0;
1320  fatd->lastChainCluster = 0xFFFFFFFF;
1321  fatd->lastChainResult = -1;
1322  return 0;
1323 }
1324 
1325 //---------------------------------------------------------------------------
1326 #if defined(BUILDING_USBHDFSD)
1327 void fat_forceUnmount(mass_dev *dev)
1328 #elif defined(BUILDING_IEEE1394_DISK)
1329 void fat_forceUnmount(struct SBP2Device *dev)
1330 #else
1331 void fat_forceUnmount(struct block_device *bd)
1332 #endif
1333 {
1334  unsigned int i;
1335 
1336  M_DEBUG("%s\n", __func__);
1337 
1338 #ifdef BUILDING_USBHDFSD
1339  XPRINTF("usb fat: forceUnmount devId %i \n", dev->devId);
1340 #endif /* BUILDING_USBHDFSD */
1341 #ifdef BUILDING_IEEE1394_DISK
1342  XPRINTF("usb fat: forceUnmount devId %i \n", dev->nodeID);
1343 #endif /* BUILDING_IEEE1394_DISK */
1344 
1345  for (i = 0; i < NUM_DRIVES; ++i) {
1346 #if !defined(BUILDING_IEEE1394_DISK) && !defined(BUILDING_USBHDFSD)
1347  if (g_fatd[i] != NULL && g_fatd[i]->bd == bd)
1348 #else
1349  if (g_fatd[i] != NULL && g_fatd[i]->dev == dev)
1350 #endif
1351  {
1352 #if !defined(BUILDING_IEEE1394_DISK) && !defined(BUILDING_USBHDFSD)
1353  scache_kill(g_fatd[i]->cache);
1354  free(g_fatd[i]);
1355 #endif
1356  g_fatd[i] = NULL;
1357  }
1358  }
1359 }
1360 
1361 //---------------------------------------------------------------------------
1362 fat_driver *fat_getData(int device)
1363 {
1364  M_DEBUG("%s(%d)\n", __func__, device);
1365 
1366  if (device >= NUM_DRIVES)
1367  return NULL;
1368 
1369 #ifdef BUILDING_USBHDFSD
1370  while (g_fatd[device] == NULL || g_fatd[device]->dev == NULL) {
1371  if (mass_stor_configureNextDevice() <= 0)
1372  break;
1373  // Do not block USBD by busy-looping here, if the device is not ready. This function call will carry the priority of the calling thread.
1374  DelayThread(5000);
1375  }
1376 #endif /* BUILDING_USBHDFSD */
1377 
1378 #if !defined(BUILDING_IEEE1394_DISK) && !defined(BUILDING_USBHDFSD)
1379  if (g_fatd[device] == NULL || g_fatd[device]->bd == NULL)
1380 #else
1381  if (g_fatd[device] == NULL || g_fatd[device]->dev == NULL)
1382 #endif
1383  return NULL;
1384  return g_fatd[device];
1385 }
1386 
1387 //---------------------------------------------------------------------------
1388 #if !defined(BUILDING_IEEE1394_DISK) && !defined(BUILDING_USBHDFSD)
1389 int fat_stopUnit(int device)
1390 {
1391  fat_driver *fatd;
1392 
1393  fatd = fat_getData(device);
1394  return (fatd != NULL) ? fatd->bd->stop(fatd->bd) : -ENODEV;
1395 }
1396 
1397 void fat_stopAll(void)
1398 {
1399  int i;
1400 
1401  for (i = 0; i < NUM_DRIVES; i++) {
1402  fat_driver *fatd;
1403 
1404  fatd = fat_getData(i);
1405  if (fatd != NULL)
1406  fatd->bd->stop(fatd->bd);
1407  }
1408 }
1409 #endif
1410 
1411 //---------------------------------------------------------------------------
1412 // End of file: fat_driver.c
1413 //---------------------------------------------------------------------------
thbase.h
sysclib.h
_mass_dev
Definition: usbhdfsd.h:64
_fat_direntry
Definition: fat.h:133
_fat32_raw_bpb
Definition: fat.h:56
_fat_direntry_summary
Definition: fat.h:139
EIO
#define EIO
Definition: errno.h:29
ENOENT
#define ENOENT
Definition: errno.h:23
count
u32 count
start sector of fragmented bd/file
Definition: usbhdfsd-common.h:3
_fat_driver
Definition: fat_driver.h:42
stdio.h
ENOTDIR
#define ENOTDIR
Definition: errno.h:59
_fat_dir
Definition: fat_driver.h:89
sysmem.h
_fat_dir_list
Definition: fat_driver.h:77
_fat_raw_bpb
Definition: fat.h:26
_fat_direntry_sfn
Definition: fat.h:96
stdlib.h
EFAULT
#define EFAULT
Definition: errno.h:47
SBP2Device
Definition: sbp2_disk.h:125
block_device
Definition: bdm.h:21
errno.h
ENODEV
#define ENODEV
Definition: errno.h:57
usbhdfsd.h
_fat_bpb
Definition: fat_driver.h:22