
grub4dos-chenall - issue #167
FAT32 file name/directory name upper/lower case issue
What steps will reproduce the problem:
If a USB drive is formatted as FAT32, the case of the filenames and folders is not correct when listed by ls command.
See attached screenshots.
What is the expected output? What do you see instead?
This is important because if specifying a name for linux, the case needs to be correct.
Some filenames and folders are correct, but others are not???
What version of the product are you using? On what operating system? 0.4.5c 17 Jan 2014
Please provide any additional information below.
If I create two folder in the root E2B MNU A Aa
in grub4dos they are listed as e2b mnu a Aa
if I change E2B to xE2B, then grub4dos lists it as xE2B (correct!)
If I create a folder MAINMENU in the root, grub4dos lists it as mainmenu. If I change it to MAINMENUx, grub4dos lists it correctly. If I remove the x, grub4dos lists it as mainmenu again!
If I create a folder ANTIVIRUS, then grub4dos lists it correctly as ANTIVIRUS. If I shorten it to ANTIVIRU, it is listed as antiviru.
Is it to do with the sum of the letters ???
- casebug_Windows.jpg 40.47KB
- casebug.jpg 28.63KB
Comment #1
Posted on Feb 25, 2014 by Happy KangarooThis seems to be a FAT v. VFAT issue. Byte 12 in the directory entry has bit 4 = lowercase extension, bit 3=lowercase base filename. The main thing is that when specifying filenames or folder names as a kernel parameter - e.g. scan-iso/filename=/fred or from=/fred/doris.iso or from=/FRED/DORIS.ISO are linux distros case sensitive?
e.g. CentOS displays filenames in the same way that Win7 does (i.e. as determined by byte 12).
fsys_fat.c has code:
short_name: /* XXX convert to 8.3 filename format here */ { int i, j, c;
for (i = 0; i < 8 && (c = filename[i] = tolower (dir_buf[i]))
&& /*!isspace (c)*/ c != ' '; i++);
filename[i++] = '.';
for (j = 0; j < 3 && (c = filename[i + j] = tolower (dir_buf[8 + j]))
&& /*!isspace (c)*/ c != ' '; j++);
if (j == 0)
i--;
filename[i + j] = 0;
}
This should look at byte 12 bits 3 & 4 to determine whether to use uppercase or lowercase, not just convert all to lowercase.
Maybe a switch in grub4dos could control what mode it is in FAT or VFAT ???
Comment #2
Posted on Feb 25, 2014 by Happy KangarooThis (very bad!) code seems to work
short_name: /* XXX convert to 8.3 filename format here / { int i, j, c; if ( (dir_buf[12] & 8) == 8) { for (i = 0; i < 8 && (c = filename[i] = tolower (dir_buf[i])) && /!isspace (c)*/ c != ' '; i++);
}
if ( (dir_buf[12] & 8) == 0)
{
for (i = 0; i < 8 && (c = filename[i] = (dir_buf[i]))
&& /*!isspace (c)*/ c != ' '; i++);
}
filename[i++] = '.';
if ( (dir_buf[12] & 16) == 16)
{
for (j = 0; j < 3 && (c = filename[i + j] = tolower (dir_buf[8 + j]))
&& /*!isspace (c)*/ c != ' '; j++);
}
if ( (dir_buf[12] & 16) == 0)
{
for (j = 0; j < 3 && (c = filename[i + j] = (dir_buf[8 + j]))
&& /*!isspace (c)*/ c != ' '; j++);
}
if (j == 0)
i--;
filename[i + j] = 0;
}
valid_filename:
Comment #3
Posted on Feb 25, 2014 by Happy Kangaroodefine LCASE_BASE 0x08 // filename base in lower case
define LCASE_EXT 0x10 // filename extension in lower case
This is used to define the bits.
Comment #4
Posted on Feb 26, 2014 by Massive KangarooTry and see if this could work:
short_name: /* XXX convert to 8.3 filename format here */ { unsigned int i, j, c, y;
define TOLOWER(c,y) (((y) && ((unsigned)((c) - 'A') < 26)) ? ((c)|0x20) : (c))
y = (dir_buf[12] & 0x08); // filename base in lower case
for (i = 0; i < 8 && (c = filename[i] = TOLOWER (dir_buf[i], y))
&& /*!isspace (c)*/ c != ' '; i++);
filename[i++] = '.';
y = (dir_buf[12] & 0x10); // filename extension in lower case
for (j = 0; j < 3 && (c = filename[i+j] = TOLOWER (dir_buf[8+j], y))
&& /*!isspace (c)*/ c != ' '; j++);
if (j == 0)
i--;
filename[i + j] = 0;
}
Comment #5
Posted on Feb 26, 2014 by Happy KangarooYes - works fine :-)
Comment #6
Posted on Feb 26, 2014 by Happy KangarooP.S. Are tolower and TOLOWER identical in function?
Comment #7
Posted on Feb 27, 2014 by Massive Kangaroono, not identical.
TOLOWER is a "conditional tolower", it turns char to lower case if and only if y is True or Yes.
Comment #8
Posted on Feb 27, 2014 by Happy KangarooSure, but what I mean is
tolower equivalent to (((y) && ((unsigned)((c) - 'A') < 26)) ? ((c)|0x20) : (c))
Comment #9
Posted on Feb 27, 2014 by Massive Kangarooas explained above, in the case of y == True,
tolower(c) is equivalent to (((y) && ((unsigned)((c) - 'A') < 26)) ? ((c)|0x20) : (c))
Comment #10
Posted on Feb 27, 2014 by Happy KangarooOK thanks - will there be a new 0.4.5c version soon please? I want to release a new version of Easy2Boot with the new version of grldr. Thanks :-)
Comment #11
Posted on Feb 27, 2014 by Massive KangarooI think you may compile your own "new" version. And I think it will be equivalent to the upcoming release by grub4dos team.
Comment #12
Posted on Feb 28, 2014 by Helpful ElephantAdoption in GRUB4DOS 0.4.6a .
Comment #13
Posted on Mar 2, 2014 by Helpful ElephantComment deleted
Comment #14
Posted on Mar 4, 2014 by Helpful ElephantIf both long file names, another short file names, grub4dos content output by long file names. If only short file names, grub4dos uppercase to lowercase. After modification, GRUB4DOS will be 12 bytes, 3,4-bit control.
Comment #15
Posted on Jun 21, 2014 by Happy HippoThis issue was updated by revision r374.
Status: Fixed
Labels:
Type-Defect
Priority-Medium