Fixed alias creation bugs

This commit is contained in:
Michael Chisholm 2007-11-04 09:52:39 +00:00
parent 634887aa0f
commit 62745e4b21
2 changed files with 61 additions and 61 deletions

View File

@ -52,6 +52,9 @@
2007-11-01 - Chishm 2007-11-01 - Chishm
* Added unicode support * Added unicode support
2007-11-04 - Chishm
* Fixed alias creation bugs
*/ */
#include <string.h> #include <string.h>
@ -831,6 +834,7 @@ static int _FAT_directory_createAlias (char* alias, const char* lfn) {
lossyConversion = true; lossyConversion = true;
} }
if (lfnExt != NULL && lfnExt[1] != '\0') { if (lfnExt != NULL && lfnExt[1] != '\0') {
lfnExt++;
alias[aliasPos] = '.'; alias[aliasPos] = '.';
aliasPos++; aliasPos++;
memset (&ps, 0, sizeof(ps)); memset (&ps, 0, sizeof(ps));
@ -940,76 +944,71 @@ bool _FAT_directory_addEntry (PARTITION* partition, DIR_ENTRY* entry, u32 dirClu
} else if (aliasLen == 0) { } else if (aliasLen == 0) {
// It's a normal short filename // It's a normal short filename
entrySize = 1; entrySize = 1;
// Copy into alias
for (i = 0, j = 0; (j < 8) && (alias[i] != '.') && (alias[i] != '\0'); i++, j++) {
entry->entryData[j] = alias[i];
}
while (j < 8) {
entry->entryData[j] = ' ';
++ j;
}
if (entry->filename[i] == '.') {
// Copy extension
++ i;
while ((alias[i] != '\0') && (j < 11)) {
entry->entryData[j] = alias[i];
++ i;
++ j;
}
}
while (j < 11) {
entry->entryData[j] = ' ';
++ j;
}
} else { } else {
// It's a long filename with an alias // It's a long filename with an alias
entrySize = ((lfnLen + LFN_ENTRY_LENGTH - 1) / LFN_ENTRY_LENGTH) + 1; entrySize = ((lfnLen + LFN_ENTRY_LENGTH - 1) / LFN_ENTRY_LENGTH) + 1;
// expand primary part to 8 characters long by padding the end with underscores
i = MAX_ALIAS_LENGTH - MAX_ALIAS_EXT_LENGTH - 2; // 1 char for '.', one for NUL, 3 for extension
// Move extension to last 3 characters
while (alias[i] != '.' && i > 0) i--;
if (i > 0) {
j = MAX_ALIAS_LENGTH - MAX_ALIAS_EXT_LENGTH - 2; // 1 char for '.', one for NUL, 3 for extension
memmove (alias + j, alias + i, strlen(alias) - i);
// Pad primary component
memset (alias + i, '_', j - i);
}
// Generate numeric tail // Generate full alias for all cases except when the alias is simply an upper case version of the LFN
for (i = 1; i <= MAX_NUMERIC_TAIL; i++) { if (strncasecmp (alias, entry->filename, MAX_ALIAS_LENGTH) != 0) {
j = i; // expand primary part to 8 characters long by padding the end with underscores
tmpCharPtr = alias + MAX_ALIAS_PRI_LENGTH - 1; i = MAX_ALIAS_PRI_LENGTH - 1;
while (j > 0) { // Move extension to last 3 characters
*tmpCharPtr = j % 10; while (alias[i] != '.' && i > 0) i--;
tmpCharPtr--; if (i > 0) {
j /= 10; j = MAX_ALIAS_LENGTH - MAX_ALIAS_EXT_LENGTH - 2; // 1 char for '.', one for NUL, 3 for extension
memmove (alias + j, alias + i, strlen(alias) - i);
// Pad primary component
memset (alias + i, '_', j - i);
} }
*tmpCharPtr = '~';
if (!_FAT_directory_entryExists (partition, alias, dirCluster)) {
break;
}
}
if (i > MAX_NUMERIC_TAIL) {
// Couldn't get a valid alias
return false;
}
// Now copy it into the directory entry data // Generate numeric tail
memcpy (entry->entryData, alias, MAX_ALIAS_PRI_LENGTH); for (i = 1; i <= MAX_NUMERIC_TAIL; i++) {
memcpy (entry->entryData + MAX_ALIAS_PRI_LENGTH, alias + MAX_ALIAS_PRI_LENGTH + 1, MAX_ALIAS_EXT_LENGTH); j = i;
for (i = 0; i < MAX_ALIAS_PRI_LENGTH+MAX_ALIAS_EXT_LENGTH; i++) { tmpCharPtr = alias + MAX_ALIAS_PRI_LENGTH - 1;
if (entry->entryData[i] < ' ') { while (j > 0) {
// Replace null and control characters with spaces *tmpCharPtr = '0' + (j % 10); // ASCII numeric value
entry->entryData[i] = ' '; tmpCharPtr--;
j /= 10;
}
*tmpCharPtr = '~';
if (!_FAT_directory_entryExists (partition, alias, dirCluster)) {
break;
}
}
if (i > MAX_NUMERIC_TAIL) {
// Couldn't get a valid alias
return false;
} }
} }
// Generate alias checksum }
for (i=0; i < MAX_ALIAS_PRI_LENGTH+MAX_ALIAS_EXT_LENGTH; i++)
{ // Copy alias or short file name into directory entry data
// NOTE: The operation is an unsigned char rotate right for (i = 0, j = 0; (j < 8) && (alias[i] != '.') && (alias[i] != '\0'); i++, j++) {
aliasCheckSum = ((aliasCheckSum & 1) ? 0x80 : 0) + (aliasCheckSum >> 1) + entry->entryData[i]; entry->entryData[j] = alias[i];
}
while (j < 8) {
entry->entryData[j] = ' ';
++ j;
}
if (alias[i] == '.') {
// Copy extension
++ i;
while ((alias[i] != '\0') && (j < 11)) {
entry->entryData[j] = alias[i];
++ i;
++ j;
} }
} }
while (j < 11) {
entry->entryData[j] = ' ';
++ j;
}
// Generate alias checksum
for (i=0; i < ALIAS_ENTRY_LENGTH; i++) {
// NOTE: The operation is an unsigned char rotate right
aliasCheckSum = ((aliasCheckSum & 1) ? 0x80 : 0) + (aliasCheckSum >> 1) + entry->entryData[i];
}
} }
// Find or create space for the entry // Find or create space for the entry

View File

@ -46,6 +46,7 @@
#define MAX_FILENAME_LENGTH 768 // 256 UCS-2 characters encoded into UTF-8 can use up to 768 UTF-8 chars #define MAX_FILENAME_LENGTH 768 // 256 UCS-2 characters encoded into UTF-8 can use up to 768 UTF-8 chars
#define MAX_ALIAS_LENGTH 13 #define MAX_ALIAS_LENGTH 13
#define LFN_ENTRY_LENGTH 13 #define LFN_ENTRY_LENGTH 13
#define ALIAS_ENTRY_LENGTH 11
#define MAX_ALIAS_EXT_LENGTH 3 #define MAX_ALIAS_EXT_LENGTH 3
#define MAX_ALIAS_PRI_LENGTH 8 #define MAX_ALIAS_PRI_LENGTH 8
#define MAX_NUMERIC_TAIL 999999 #define MAX_NUMERIC_TAIL 999999