kxylxp / grub4dos-chenall

Automatically exported from code.google.com/p/grub4dos-chenall
0 stars 0 forks source link

FAT32 file name/directory name upper/lower case issue #167

Closed GoogleCodeExporter closed 8 years ago

GoogleCodeExporter commented 8 years ago
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 ???

Original issue reported on code.google.com by Steve6375 on 23 Feb 2014 at 7:21

Attachments:

GoogleCodeExporter commented 8 years ago
This 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 ???

Original comment by Steve6375 on 25 Feb 2014 at 10:26

GoogleCodeExporter commented 8 years ago
This (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:

Original comment by Steve6375 on 25 Feb 2014 at 11:12

GoogleCodeExporter commented 8 years ago
#define LCASE_BASE        0x08            // filename base in lower case
#define LCASE_EXT         0x10            // filename extension in lower case

This is used to define the bits.

Original comment by Steve6375 on 25 Feb 2014 at 1:32

GoogleCodeExporter commented 8 years ago
Try 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;
      }

Original comment by tinyb...@gmail.com on 26 Feb 2014 at 5:11

Attachments:

GoogleCodeExporter commented 8 years ago
Yes - works fine :-)

Original comment by Steve6375 on 26 Feb 2014 at 5:31

GoogleCodeExporter commented 8 years ago
P.S. Are tolower and TOLOWER identical in function?

Original comment by Steve6375 on 26 Feb 2014 at 5:42

GoogleCodeExporter commented 8 years ago
no, not identical.

TOLOWER is a "conditional tolower", it turns char to lower case if and only if 
y is True or Yes.

Original comment by tinyb...@gmail.com on 27 Feb 2014 at 12:15

GoogleCodeExporter commented 8 years ago
Sure, but what I mean is

tolower  equivalent to  (((y) && ((unsigned)((c) - 'A') < 26)) ? ((c)|0x20) : 
(c))

Original comment by Steve6375 on 27 Feb 2014 at 12:17

GoogleCodeExporter commented 8 years ago
as explained above, in the case of y == True,

tolower(c) is equivalent to  (((y) && ((unsigned)((c) - 'A') < 26)) ? 
((c)|0x20) : (c))

Original comment by tinyb...@gmail.com on 27 Feb 2014 at 7:48

GoogleCodeExporter commented 8 years ago
OK 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 :-)

Original comment by Steve6375 on 27 Feb 2014 at 9:58

GoogleCodeExporter commented 8 years ago
I think you may compile your own "new" version. And I think it will be 
equivalent to the upcoming release by grub4dos team.

Original comment by tinyb...@gmail.com on 27 Feb 2014 at 10:36

GoogleCodeExporter commented 8 years ago
Adoption in GRUB4DOS 0.4.6a .

Original comment by yaya2007_7777@126.com on 28 Feb 2014 at 12:15

GoogleCodeExporter commented 8 years ago
[deleted comment]
GoogleCodeExporter commented 8 years ago
If 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.

Original comment by yaya2007_7777@126.com on 4 Mar 2014 at 2:16

GoogleCodeExporter commented 8 years ago
This issue was updated by revision r374.

Original comment by chenall.cn on 21 Jun 2014 at 1:16