Might help to see the whole code... I ran into a few places when moving code around where I did not have pointer but instead I had object or reference and needed to chang some -> to .
Whole code in PR2: https://github.com/KurtE/UsbMscFat/pull/2
I think I have it working at least through writeMBR? Have to fix one thing and then will see. At least it doesn't look like it overriding with 0 - just not sure.
Again sounds good, may wait until morning to try format... Right now just pushed up additions to the PFsVolume that has methods to read and write the FSInfo Sector with count...
Not sure about backup sector yet.
Morning @mjs513 - Sounds great.
Volume Name - As I mentioned yesterday I added the getVolumeLabel method, to replace the code in the sketches. It is still not 100% correct. Currently it assumes it is the first directory entry at the root. I do verify that entry has the right signature. But the volume label could be added later, so should continue to check other items in case added later. Will try that today.
Also may try to add method to setVolumeLabel. That is probably next up. Other than I created a stick with no label and now will add files and then try to set the label to confirm that windows can create labels not as the first item...
There is also probably some issues with BPS throughout the code...
Then play with some more integration stuff!
I look at that one as well.Right now looks the MBR is correct but I don't have bps pointed to right partition the rest is messed up - probably same for fat. Right now just reading about FAT file systems: https://en.wikipedia.org/wiki/Design_of_the_FAT_file_system
I look at that one as well.
Also an early one by @Paull - https://www.pjrc.com/tech/8051/ide/fat32.html
Me too... I doubt the current version of Norton Utilities comes with anything like that anymore...
Quick update: Pushed up code that finds volume label if not first entry...
Next to check to see what it might take to create one that is...
pbs->bpb.bpb32.volumeLabel
for (size_t i = 0; i < sizeof(pbs->bpb.bpb32.volumeLabel); i++) {
pbs->bpb.bpb32.volumeLabel[i] = volName[i];
}
Serial.printf("Volume name pbs:(%s)\n", pbs->bpb.bpb32.volumeLabel);
nc = (m_sectorCount - m_dataStart)/m_sectorsPerCluster;
When SD media was Windows formatted and then Teensy dumped MBR it had 'No Name' showing even though Windows formatted it with a name that showed on Windows. It seems that field is ignored now by Windows?
n0rt0n is a dirty word by the way. Did a quick search and even web efforts to replace diskedit seem stalled so didn't find a usable alternative.
Got back to read posts - but otherwise distracted ... seems busy here. Quite the dilemma with 'making it work' means losing ongoing/test support from sdfat world and then not knowing if it will be integrated/taken on as a burden inside TD.
Once you format the drive the with SDformatter it seems to delete the partition name. Tried to get around it but no luck. KurtE is working on a setVolumeName function but I seem to be having problems with it. Still going to play more with the volume name though.
Yep - I did a search for Norton Disk Edit but no luck either
bool PFsVolume::setVolumeLabel(char *volume_label)
{
char buf[32];
if (!volume_label ) return false; // don't want to deal with it yet
if (*volume_label == 0) return false; // dito probably in both cases maybe delete label?
PFsFile root;
PFsFile rootRW;
uint8_t fat_type = fatType();
if (!root.openRoot(this)) return false;
if (!rootRW.open(&root, (const char *)"/", O_RDWR)) {
Serial.println("Failed to open rootRW");
return false;
}
bool label_found = false;
while (rootRW.read(buf, 32) == 32) {
//dump_hexbytes(buf, 32);
if ((fat_type == FAT_TYPE_FAT16) || (fat_type == FAT_TYPE_FAT32)) {
//N N N N N N N N N N N A CF CT CT CT CD CD AD AD FC FC MT MT MD MD FC FC SZ SZ SZ SZ
//56 4F 4C 46 41 54 33 32 20 20 20 08 00 00 00 00 00 00 00 00 00 00 5B 84 58 52 00 00 00 00 00 00 :VOLFAT32 ...........[.XR......
//56 4F 4C 46 41 54 31 36 20 20 20 08 00 00 00 00 00 00 00 00 00 00 51 84 58 52 00 00 00 00 00 00 :VOLFAT16 ...........Q.XR......
DirFat_t *dir;
dir = reinterpret_cast<DirFat_t*>(buf);
if (dir->attributes != 0x08) continue; // not a volume label...
label_found = true;
break;
} else if (fat_type == FAT_TYPE_EXFAT) {
//Ty len < Unicode name > R R R R R R R R
//83 08 56 00 6F 00 6C 00 45 00 58 00 46 00 41 00 54 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 :..V.o.l.E.X.F.A.T...............
DirLabel_t *dir;
dir = reinterpret_cast<DirLabel_t*>(buf);
if (dir->type != EXFAT_TYPE_LABEL) continue; // not a label?
label_found = true;
break;
} else return false;
}
memset(buf, 0, 32); // clear out everythign.
if (fat_type == FAT_TYPE_EXFAT) {
DirLabel_t *dir;
dir = reinterpret_cast<DirLabel_t*>(buf);
uint8_t cb = strlen(volume_label);
if (cb > 11) cb = 11; // truncate off.
dir->type = EXFAT_TYPE_LABEL;
dir->labelLength = cb;
uint8_t *puni = dir->unicode;
while (cb--) {
*puni = *volume_label++;
puni += 2;
}
} else {
// Fat16/32
// Lets get the date and time to set the volume labels modify values
DirFat_t *dir;
dir = reinterpret_cast<DirFat_t*>(buf);
if (FsDateTime::callback) {
uint16_t cur_date;
uint16_t cur_time;
uint8_t cur_ms10;
FsDateTime::callback(&cur_date, &cur_time, &cur_ms10);
setLe16(dir->modifyTime, cur_time);
setLe16(dir->modifyDate, cur_date);
}
for (size_t i = 0; i < 11; i++) {
dir->name[i] = *volume_label? *volume_label++ : ' '; // fill in the 11 spots trailing blanks
}
}
// Now lets try to write it out...
if (label_found) rootRW.seekCur(-32);
bool write_ok = (rootRW.write(buf, 32) == 32);
rootRW.close();
root.close();
return write_ok; // no volume label was found
}
Once you format the drive the with SDformatter it seems to delete the partition name. Tried to get around it but no luck. KurtE is working on a setVolumeName function but I seem to be having problems with it. Still going to play more with the volume name though.
Yep - I did a search for Norton Disk Edit but no luck either
The SDFormater (on my PC has a field for Volume Label that allows you to set one when you format on the PC.
You can also make one without Volume ID (or with) and then do a properties on the drive and the volume label is displayed there and you can set it there as well...
char noName[] = "NO NAME ";
....
memcpy(pb->volumeLabel, noName, sizeof(pb->volumeLabel));
if (partVol.getVolumeLabel(volName, sizeof(volName))) {
Serial.printf("Volume name:(%s)", volName);
}
for (size_t i = 0; i < sizeof(pbs->bpb.bpb32.volumeLabel); i++) {
pbs->bpb.bpb32.volumeLabel[i] = volName[i];
}
bool getFat16VolumeLabel(uint8_t drvType, uint8_t part, UsbFs *myMsc) {
FatVolume partVol;
uint8_t buf[512];
if (drvType == MS_DRIVE) {
partVol.begin(myMsc->usbDrive(), true, part);
partVol.chvol();
myMsc->usbDrive()->readSector(partVol.rootDirStart(), buf);
}
if (drvType == SD_DRIVE) {
sd.card()->readSector(sd.dataStartSector(), buf);
print_hexbytes(buf, 512);
}
Serial.print(F("Volume Name: "));
for (size_t i = 0; i < 11; i++) {
Serial.write(buf[i]);
}
Serial.println();
partVol.ls(LS_SIZE | LS_DATE | LS_R);
return true;
}
DirFat_t *dir;
dir = reinterpret_cast<DirFat_t*>(buf);
if (FsDateTime::callback) {
uint16_t cur_date;
uint16_t cur_time;
uint8_t cur_ms10;
FsDateTime::callback(&cur_date, &cur_time, &cur_ms10);
setLe16(dir->modifyTime, cur_time);
setLe16(dir->modifyDate, cur_date);
}
for (size_t i = 0; i < 11; i++) {
dir->name[i] = *volume_label? *volume_label++ : ' '; // fill in the 11 spots trailing blanks
}
}
const uint8_t EXTENDED_BOOT_SIGNATURE = 0X29;
typedef struct biosParameterBlockFat16 {
uint8_t bytesPerSector[2];
uint8_t sectorsPerCluster;
uint8_t reservedSectorCount[2];
uint8_t fatCount;
[COLOR="#FF0000"] uint8_t rootDirEntryCount[2];[/COLOR]
uint8_t totalSectors16[2];
uint8_t mediaType;
uint8_t sectorsPerFat16[2];
uint8_t sectorsPerTrtack[2];
uint8_t headCount[2];
uint8_t hidddenSectors[4];
uint8_t totalSectors32[4];
uint8_t physicalDriveNumber;
uint8_t extReserved;
uint8_t extSignature;
uint8_t volumeSerialNumber[4];
uint8_t volumeLabel[11];
uint8_t volumeType[8];
} BpbFat16_t;
I don't see that in the SDFormater.ino sketch. In the SDFormatter in examplesV1 they have:
which is pretty much the same in the SDFatv2. What I tried was in the format call:Code:char noName[] = "NO NAME "; .... memcpy(pb->volumeLabel, noName, sizeof(pb->volumeLabel));
and the say in make32:Code:if (partVol.getVolumeLabel(volName, sizeof(volName))) { Serial.printf("Volume name:(%s)", volName); }
but no luck - still shows blank. So either it doesn't work or I have it pointing wrong - may want to check me.Code:for (size_t i = 0; i < sizeof(pbs->bpb.bpb32.volumeLabel); i++) { pbs->bpb.bpb32.volumeLabel[i] = volName[i]; }
// Initialize first sector of root.
writeMsg(pr, "Writing root\r\n");
ns = sectorsPerCluster;
sector = partitionOffset + clusterHeapOffset + 2*sectorsPerCluster;
[COLOR="#FF0000"]memset(secBuf, 0, BYTES_PER_SECTOR);[/COLOR]
// Unused Label entry.
label = reinterpret_cast<DirLabel_t*>(secBuf);
label->type = EXFAT_TYPE_LABEL & 0X7F;
for (size_t i = 0; i < sizeof(pbs->bpb.bpb16.volumeLabel); i++) {
pbs->bpb.bpb16.volumeLabel[i] = ' ';
}
bool PFsVolume::getVolumeLabel(char *volume_label, size_t cb)
{
uint8_t buf[512];
if (!volume_label || (cb < 12)) return false; // don't want to deal with it
*volume_label = 0; // make sure if we fail later we return empty string as well.
uint8_t fat_type = fatType();
uint32_t root_dir;
// Lets go hard core here.
if (m_fVol)
{
FatFile rootFat;
if (!rootFat.openRoot(m_fVol)) return false;
uint32_t root_dir_size = rootFat.dirSize(); // how big is this directory...
rootFat.close();
if (fat_type == FAT_TYPE_FAT32) {
root_dir = m_fVol->dataStartSector();
} else {
root_dir = m_fVol->rootDirStart();
}
Serial.printf("\n$$$ PFsVolume::getVolumeLabel(%u): %u %u\n", fat_type, root_dir, root_dir_size);
uint16_t index_in_sector=0;
m_blockDev->readSector(root_dir, buf);
while (root_dir_size) {
DirFat_t *dir;
dir = reinterpret_cast<DirFat_t*>(&buf[index_in_sector]);
if (dir->name[0] == FAT_NAME_FREE) break; // at end of list...
if (dir->attributes == 0x08) {
size_t i;
for (i = 0; i < 11; i++) {
volume_label[i] = dir->name[i];
}
while ((i > 0) && (volume_label[i - 1] == ' ')) i--; // trim off trailing blanks
volume_label[i] = 0;
return true;
}
index_in_sector += 32; // increment to next entry...
root_dir_size-=32;
if (index_in_sector >= 512 && root_dir_size) {
root_dir++;
m_blockDev->readSector(root_dir, buf);
index_in_sector = 0;
}
}
} else if (m_xVol) {
//ExFatFile rootEx;
//if (!rootEx.openRoot(m_xVol)) return false;
//ExFat have not converted yet
//uint32_t root_dir_size = rootEx.fileSize(); // how big is this directory...
uint32_t chs = m_xVol->clusterHeapStartSector();
uint32_t rdc = m_xVol->rootDirectoryCluster();
uint32_t root_dir_size = m_xVol->rootLength();
uint32_t spc = m_xVol->sectorsPerCluster();
Serial.printf("\n$$$ PFsVolume::getVolumeLabel(Ex): %u %x %x %u\n", root_dir_size, chs, rdc, spc);
uint32_t root_dir = chs + (rdc-2)*spc;
Serial.printf(" $$$ Guess sector: %x\n", root_dir);
uint16_t index_in_sector=0;
m_blockDev->readSector(root_dir, buf);
while (root_dir_size) {
DirLabel_t *dir;
dir = reinterpret_cast<DirLabel_t*>(&buf[index_in_sector]);
//if (dir->name[0] == 0) break; // at end of list...
if (dir->type == EXFAT_TYPE_LABEL) {
size_t i;
for (i = 0; i < dir->labelLength; i++) {
volume_label[i] = dir->unicode[2 * i];
}
volume_label[i] = 0;
return true;
}
index_in_sector += 32; // increment to next entry...
root_dir_size-=32;
if (index_in_sector >= 512 && root_dir_size) {
root_dir++;
m_blockDev->readSector(root_dir, buf);
index_in_sector = 0;
}
}
}
return false; // no volume label was found
}
Waiting up to 5 seconds for USB drive 1
^^Initialize USB drive...UsbBase::mscBegin called 20002280 1 1
^^^ After usbDriveBegin
USB drive 1 is present.
msc # Partition Table
part,boot,bgnCHS[3],type,endCHS[3],start,length
FAT32: 1,0,0x4,0x1,0x4,0xB,0xFE,0xC2,0xFF,2048,8192000
FAT16: 2,0,0xE,0x51,0xFE,0xE,0x98,0x98,0x80,8194048,2097152
exFAT: 3,0,0x98,0x99,0x80,0x7,0xEE,0xDC,0xD2,10291200,5435392
pt_#0: 4,0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0,0
Partition 0 valid:1
Partition 1 valid:1
Partition 2 valid:1
Partition 3 valid:0
0:>> Fat32:
$$$ PFsVolume::getVolumeLabel(32): 18080 4096
Volume name:(NEWLABEL) Partition Total Size:4186095616 Used:65425408 time us: 499748
Free Clusters: API: 1006023 by CB:1006023 time us: 499741
Free Clusters: Info: 1006023 time us: 2742
1:>> Fat16:
$$$ PFsVolume::getVolumeLabel(16): 8194568 16384
Volume name:([COLOR="#FF0000"]VOLFAT16[/COLOR]) Partition Total Size:1073446912 Used:11714560 time us: 16748
Free Clusters: API: 64803 by CB:64803 time us: 16742
Free Clusters: Info: 4294967295 time us: 0
2:>> ExFat:
Initialize SD card...initialization failed.
done...
Press any key to run again
[COLOR="#FF0000"]Or enter new Volume label: <dev:12s> <Par> Name
Try to set device:20001db4 part:2 to:NEWVOLF16
[/COLOR]
$$$ PFsVolume::getVolumeLabel(16): 8194568 16384
Previous Volume name:(VOLFAT16)
$$$ PFsVolume::getVolumeLabel(16): 8194568 16384
56 4F 4C 46 41 54 31 36 20 20 20 08 00 00 00 00 00 00 00 00 00 00 51 84 58 52 00 00 00 00 00 00 :VOLFAT16 ...........Q.XR......
42 20 00 49 00 6E 00 66 00 6F 00 0F 00 72 72 00 6D 00 61 00 74 00 69 00 6F 00 00 00 6E 00 00 00 :B .I.n.f.o...rr.m.a.t.i.o...n...
01 53 00 79 00 73 00 74 00 65 00 0F 00 72 6D 00 20 00 56 00 6F 00 6C 00 75 00 00 00 6D 00 65 00 :.S.y.s.t.e...rm. .V.o.l.u...m.e.
53 59 53 54 45 4D 7E 31 20 20 20 16 00 60 AE 6D 56 52 56 52 00 00 AF 6D 56 52 02 00 00 00 00 00 :SYSTEM~1 ..`.mVRVR...mVR......
42 70 00 67 00 00 00 FF FF FF FF 0F 00 E1 FF FF FF FF FF FF FF FF FF FF FF FF 00 00 FF FF FF FF :Bp.g............................
01 54 00 34 00 2D 00 43 00 61 00 0F 00 E1 72 00 64 00 6C 00 69 00 6B 00 65 00 00 00 2E 00 6A 00 :.T.4.-.C.a....r.d.l.i.k.e.....j.
54 34 2D 43 41 52 7E 31 4A 50 47 20 00 A1 EC 6D 56 52 56 52 00 00 10 8F 2D 52 04 00 1E 32 05 00 :T4-CAR~1JPG ...mVRVR....-R...2..
E5 6D 00 65 00 6E 00 74 00 2E 00 0F 00 9F 74 00 78 00 74 00 00 00 FF FF FF FF 00 00 FF FF FF FF :.m.e.n.t......t.x.t.............
E5 4E 00 65 00 77 00 20 00 54 00 0F 00 9F 65 00 78 00 74 00 20 00 44 00 6F 00 00 00 63 00 75 00 :.N.e.w. .T....e.x.t. .D.o...c.u.
E5 45 57 54 45 58 7E 31 54 58 54 20 00 67 45 84 58 52 58 52 00 00 46 84 58 52 00 00 00 00 00 00 :.EWTEX~1TXT .gE.XRXR..F.XR......
41 4F 00 6E 00 46 00 61 00 74 00 0F 00 F5 31 00 36 00 2E 00 74 00 78 00 74 00 00 00 00 00 FF FF :AO.n.F.a.t....1.6...t.x.t.......
4F 4E 46 41 54 31 36 20 54 58 54 20 00 67 45 84 58 52 58 52 00 00 46 84 58 52 00 00 00 00 00 00 :ONFAT16 TXT .gE.XRXR..F.XR......
44 53 43 30 33 33 35 37 4A 50 47 20 00 31 2F 57 5A 52 5A 52 00 00 69 39 76 3C 1A 00 79 05 33 00 :DSC03357JPG .1/WZRZR..i9v<..y.3.
42 67 00 00 00 FF FF FF FF FF FF 0F 00 86 FF FF FF FF FF FF FF FF FF FF FF FF 00 00 FF FF FF FF :Bg..............................
01 49 00 6E 00 73 00 69 00 64 00 0F 00 86 65 00 2D 00 50 00 73 00 32 00 2E 00 00 00 6A 00 70 00 :.I.n.s.i.d....e.-.P.s.2.....j.p.
49 4E 53 49 44 45 7E 31 4A 50 47 20 00 49 2F 57 5A 52 5A 52 00 00 F1 3E CB 3C E7 00 DD 49 00 00 :INSIDE~1JPG .I/WZRZR...>.<...I..
Set new name *** succeeded ***
Initialize USB drive...UsbBase::mscBegin called 20002280 1 1
After usbDriveBegin
USB drive 1 is present.
msc # Partition Table
part,boot,bgnCHS[3],type,endCHS[3],start,length
FAT32: 1,0,0x4,0x1,0x4,0xB,0xFE,0xC2,0xFF,2048,8192000
FAT16: 2,0,0xE,0x51,0xFE,0xE,0x98,0x98,0x80,8194048,2097152
exFAT: 3,0,0x98,0x99,0x80,0x7,0xEE,0xDC,0xD2,10291200,5435392
pt_#0: 4,0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0,0
Partition 0 valid:1
Partition 1 valid:1
Partition 2 valid:1
Partition 3 valid:0
0:>> Fat32:
$$$ PFsVolume::getVolumeLabel(32): 18080 4096
Volume name:(NEWLABEL) Partition Total Size:4186095616 Used:65425408 time us: 499748
Free Clusters: API: 1006023 by CB:1006023 time us: 499741
Free Clusters: Info: 1006023 time us: 2742
1:>> Fat16:
$$$ PFsVolume::getVolumeLabel(16): 8194568 16384
Volume name:([COLOR="#FF0000"]NEWVOLF16[/COLOR]) Partition Total Size:1073446912 Used:11714560 time us: 16748
Free Clusters: API: 64803 by CB:64803 time us: 16742
Free Clusters: Info: 4294967295 time us: 0
2:>> ExFat:
$$$ PFsVolume::getVolumeLabel(Ex): 32768 9d0b80 4 64
$$$ Guess sector: 9d0c00
Volume name:(VolEXFAT) Partition Total Size:2782461952 Used:232030208 time us: 17002
Free Clusters: API: 77833 by CB:0 time us: 0
Free Clusters: Info: 4294967295 time us: 0