Restructure FAT driver to avoid hook in label reading as it hits a
GCC bug. * include/grub/err.h (grub_err_t): New enum value GRUB_ERR_EOF. * grub-core/fs/fat.c (grub_fat_iterate_context): New struct. (grub_fat_iterate_dir): Split into ... (grub_fat_iterate_init): ... this, ... (grub_fat_iterate_fini): ... this, ... (grub_fat_iterate_dir_next): ... and this. All users updated.
This commit is contained in:
parent
9f1d654e67
commit
918a25179c
3 changed files with 183 additions and 145 deletions
12
ChangeLog
12
ChangeLog
|
@ -1,3 +1,15 @@
|
||||||
|
2012-06-20 Vladimir Serbinenko <phcoder@gmail.com>
|
||||||
|
|
||||||
|
Restructure FAT driver to avoid hook in label reading as it hits a
|
||||||
|
GCC bug.
|
||||||
|
|
||||||
|
* include/grub/err.h (grub_err_t): New enum value GRUB_ERR_EOF.
|
||||||
|
* grub-core/fs/fat.c (grub_fat_iterate_context): New struct.
|
||||||
|
(grub_fat_iterate_dir): Split into ...
|
||||||
|
(grub_fat_iterate_init): ... this, ...
|
||||||
|
(grub_fat_iterate_fini): ... this, ...
|
||||||
|
(grub_fat_iterate_dir_next): ... and this. All users updated.
|
||||||
|
|
||||||
2012-06-20 Vladimir Serbinenko <phcoder@gmail.com>
|
2012-06-20 Vladimir Serbinenko <phcoder@gmail.com>
|
||||||
|
|
||||||
* include/grub/ieee1275/ieee1275.h (grub_ieee1275_flag): New enum value
|
* include/grub/ieee1275/ieee1275.h (grub_ieee1275_flag): New enum value
|
||||||
|
|
|
@ -576,26 +576,62 @@ grub_fat_read_data (grub_disk_t disk, struct grub_fat_data *data,
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct grub_fat_iterate_context
|
||||||
|
{
|
||||||
|
#ifdef MODE_EXFAT
|
||||||
|
struct grub_fat_dir_node dir;
|
||||||
|
#else
|
||||||
|
struct grub_fat_dir_entry dir;
|
||||||
|
#endif
|
||||||
|
char *filename;
|
||||||
|
grub_uint16_t *unibuf;
|
||||||
|
grub_ssize_t offset;
|
||||||
|
};
|
||||||
|
|
||||||
|
static grub_err_t
|
||||||
|
grub_fat_iterate_init (struct grub_fat_iterate_context *ctxt)
|
||||||
|
{
|
||||||
|
ctxt->offset = -sizeof (struct grub_fat_dir_entry);
|
||||||
|
|
||||||
|
#ifndef MODE_EXFAT
|
||||||
|
/* Allocate space enough to hold a long name. */
|
||||||
|
ctxt->filename = grub_malloc (0x40 * 13 * GRUB_MAX_UTF8_PER_UTF16 + 1);
|
||||||
|
ctxt->unibuf = (grub_uint16_t *) grub_malloc (0x40 * 13 * 2);
|
||||||
|
#else
|
||||||
|
ctxt->unibuf = grub_malloc (15 * 256 * 2);
|
||||||
|
ctxt->filename = grub_malloc (15 * 256 * GRUB_MAX_UTF8_PER_UTF16 + 1);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (! ctxt->filename || ! ctxt->unibuf)
|
||||||
|
{
|
||||||
|
grub_free (ctxt->filename);
|
||||||
|
grub_free (ctxt->unibuf);
|
||||||
|
return grub_errno;
|
||||||
|
}
|
||||||
|
return GRUB_ERR_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
grub_fat_iterate_fini (struct grub_fat_iterate_context *ctxt)
|
||||||
|
{
|
||||||
|
grub_free (ctxt->filename);
|
||||||
|
grub_free (ctxt->unibuf);
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef MODE_EXFAT
|
#ifdef MODE_EXFAT
|
||||||
static grub_err_t
|
static grub_err_t
|
||||||
grub_fat_iterate_dir (grub_disk_t disk, struct grub_fat_data *data,
|
grub_fat_iterate_dir_next (grub_disk_t disk, struct grub_fat_data *data,
|
||||||
int (*hook) (const char *filename,
|
struct grub_fat_iterate_context *ctxt)
|
||||||
grub_fat_dir_node_t *node))
|
|
||||||
{
|
{
|
||||||
struct grub_fat_dir_entry dir;
|
grub_memset (&ctxt->dir, 0, sizeof (ctxt->dir));
|
||||||
grub_ssize_t offset = -sizeof(dir);
|
|
||||||
grub_uint16_t *unibuf;
|
|
||||||
char *filename;
|
|
||||||
|
|
||||||
unibuf = grub_malloc (15 * 256 * 2);
|
|
||||||
filename = grub_malloc (15 * 256 * GRUB_MAX_UTF8_PER_UTF16 + 1);
|
|
||||||
|
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
offset += sizeof (dir);
|
struct grub_fat_dir_entry dir;
|
||||||
|
|
||||||
if (grub_fat_read_data (disk, data, 0,
|
ctxt->offset += sizeof (dir);
|
||||||
offset, sizeof (dir), (char *) &dir)
|
|
||||||
|
if (grub_fat_read_data (disk, data, 0, ctxt->offset, sizeof (dir),
|
||||||
|
(char *) &dir)
|
||||||
!= sizeof (dir))
|
!= sizeof (dir))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -607,18 +643,17 @@ grub_fat_iterate_dir (grub_disk_t disk, struct grub_fat_data *data,
|
||||||
if (dir.entry_type == 0x85)
|
if (dir.entry_type == 0x85)
|
||||||
{
|
{
|
||||||
unsigned i, nsec, slots = 0;
|
unsigned i, nsec, slots = 0;
|
||||||
grub_fat_dir_node_t node;
|
|
||||||
|
|
||||||
nsec = dir.type_specific.file.secondary_count;
|
nsec = dir.type_specific.file.secondary_count;
|
||||||
|
|
||||||
node.attr = grub_cpu_to_le16 (dir.type_specific.file.attr);
|
ctxt->dir.attr = grub_cpu_to_le16 (dir.type_specific.file.attr);
|
||||||
node.have_stream = 0;
|
ctxt->dir.have_stream = 0;
|
||||||
for (i = 0; i < nsec; i++)
|
for (i = 0; i < nsec; i++)
|
||||||
{
|
{
|
||||||
struct grub_fat_dir_entry sec;
|
struct grub_fat_dir_entry sec;
|
||||||
offset += sizeof (sec);
|
ctxt->offset += sizeof (sec);
|
||||||
if (grub_fat_read_data (disk, data, 0,
|
if (grub_fat_read_data (disk, data, 0,
|
||||||
offset, sizeof (sec), (char *) &sec)
|
ctxt->offset, sizeof (sec), (char *) &sec)
|
||||||
!= sizeof (sec))
|
!= sizeof (sec))
|
||||||
break;
|
break;
|
||||||
if (!(sec.entry_type & 0x80))
|
if (!(sec.entry_type & 0x80))
|
||||||
|
@ -628,18 +663,18 @@ grub_fat_iterate_dir (grub_disk_t disk, struct grub_fat_data *data,
|
||||||
switch (sec.entry_type)
|
switch (sec.entry_type)
|
||||||
{
|
{
|
||||||
case 0xc0:
|
case 0xc0:
|
||||||
node.first_cluster = grub_cpu_to_le32 (sec.type_specific.stream_extension.first_cluster);
|
ctxt->dir.first_cluster = grub_cpu_to_le32 (sec.type_specific.stream_extension.first_cluster);
|
||||||
node.valid_size
|
ctxt->dir.valid_size
|
||||||
= grub_cpu_to_le64 (sec.type_specific.stream_extension.valid_size);
|
= grub_cpu_to_le64 (sec.type_specific.stream_extension.valid_size);
|
||||||
node.file_size
|
ctxt->dir.file_size
|
||||||
= grub_cpu_to_le64 (sec.type_specific.stream_extension.file_size);
|
= grub_cpu_to_le64 (sec.type_specific.stream_extension.file_size);
|
||||||
node.have_stream = 1;
|
ctxt->dir.have_stream = 1;
|
||||||
break;
|
break;
|
||||||
case 0xc1:
|
case 0xc1:
|
||||||
{
|
{
|
||||||
int j;
|
int j;
|
||||||
for (j = 0; j < 15; j++)
|
for (j = 0; j < 15; j++)
|
||||||
unibuf[slots * 15 + j]
|
ctxt->unibuf[slots * 15 + j]
|
||||||
= grub_le_to_cpu16 (sec.type_specific.file_name.str[j]);
|
= grub_le_to_cpu16 (sec.type_specific.file_name.str[j]);
|
||||||
slots++;
|
slots++;
|
||||||
}
|
}
|
||||||
|
@ -652,16 +687,14 @@ grub_fat_iterate_dir (grub_disk_t disk, struct grub_fat_data *data,
|
||||||
|
|
||||||
if (i != nsec)
|
if (i != nsec)
|
||||||
{
|
{
|
||||||
offset -= sizeof (dir);
|
ctxt->offset -= sizeof (dir);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
*grub_utf16_to_utf8 ((grub_uint8_t *) filename, unibuf,
|
*grub_utf16_to_utf8 ((grub_uint8_t *) ctxt->filename, ctxt->unibuf,
|
||||||
slots * 15) = '\0';
|
slots * 15) = '\0';
|
||||||
|
|
||||||
if (hook (filename, &node))
|
return 0;
|
||||||
break;
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
/* Allocation bitmap. */
|
/* Allocation bitmap. */
|
||||||
if (dir.entry_type == 0x81)
|
if (dir.entry_type == 0x81)
|
||||||
|
@ -672,60 +705,41 @@ grub_fat_iterate_dir (grub_disk_t disk, struct grub_fat_data *data,
|
||||||
/* Volume label. */
|
/* Volume label. */
|
||||||
if (dir.entry_type == 0x83)
|
if (dir.entry_type == 0x83)
|
||||||
continue;
|
continue;
|
||||||
grub_dprintf ("exfat", "unknown primary type 0x%02x\n", dir.entry_type);
|
grub_dprintf ("exfat", "unknown primary type 0x%02x\n",
|
||||||
|
dir.entry_type);
|
||||||
}
|
}
|
||||||
grub_free (filename);
|
return grub_errno ? : GRUB_ERR_EOF;
|
||||||
grub_free (unibuf);
|
|
||||||
|
|
||||||
return grub_errno;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
static grub_err_t
|
static grub_err_t
|
||||||
grub_fat_iterate_dir (grub_disk_t disk, struct grub_fat_data *data,
|
grub_fat_iterate_dir_next (grub_disk_t disk, struct grub_fat_data *data,
|
||||||
int (*hook) (const char *filename,
|
struct grub_fat_iterate_context *ctxt)
|
||||||
struct grub_fat_dir_entry *dir))
|
|
||||||
{
|
{
|
||||||
struct grub_fat_dir_entry dir;
|
|
||||||
char *filename;
|
|
||||||
char *filep = 0;
|
char *filep = 0;
|
||||||
grub_uint16_t *unibuf;
|
|
||||||
int slot = -1, slots = -1;
|
|
||||||
int checksum = -1;
|
int checksum = -1;
|
||||||
grub_ssize_t offset = -sizeof(dir);
|
int slot = -1, slots = -1;
|
||||||
|
|
||||||
if (! (data->attr & GRUB_FAT_ATTR_DIRECTORY))
|
|
||||||
return grub_error (GRUB_ERR_BAD_FILE_TYPE, N_("not a directory"));
|
|
||||||
|
|
||||||
/* Allocate space enough to hold a long name. */
|
|
||||||
filename = grub_malloc (0x40 * 13 * GRUB_MAX_UTF8_PER_UTF16 + 1);
|
|
||||||
unibuf = (grub_uint16_t *) grub_malloc (0x40 * 13 * 2);
|
|
||||||
if (! filename || ! unibuf)
|
|
||||||
{
|
|
||||||
grub_free (filename);
|
|
||||||
grub_free (unibuf);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
unsigned i;
|
unsigned i;
|
||||||
|
|
||||||
/* Adjust the offset. */
|
/* Adjust the offset. */
|
||||||
offset += sizeof (dir);
|
ctxt->offset += sizeof (ctxt->dir);
|
||||||
|
|
||||||
/* Read a directory entry. */
|
/* Read a directory entry. */
|
||||||
if (grub_fat_read_data (disk, data, 0,
|
if (grub_fat_read_data (disk, data, 0,
|
||||||
offset, sizeof (dir), (char *) &dir)
|
ctxt->offset, sizeof (ctxt->dir),
|
||||||
!= sizeof (dir) || dir.name[0] == 0)
|
(char *) &ctxt->dir)
|
||||||
|
!= sizeof (ctxt->dir) || ctxt->dir.name[0] == 0)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* Handle long name entries. */
|
/* Handle long name entries. */
|
||||||
if (dir.attr == GRUB_FAT_ATTR_LONG_NAME)
|
if (ctxt->dir.attr == GRUB_FAT_ATTR_LONG_NAME)
|
||||||
{
|
{
|
||||||
struct grub_fat_long_name_entry *long_name
|
struct grub_fat_long_name_entry *long_name
|
||||||
= (struct grub_fat_long_name_entry *) &dir;
|
= (struct grub_fat_long_name_entry *) &ctxt->dir;
|
||||||
grub_uint8_t id = long_name->id;
|
grub_uint8_t id = long_name->id;
|
||||||
|
|
||||||
if (id & 0x40)
|
if (id & 0x40)
|
||||||
|
@ -742,78 +756,72 @@ grub_fat_iterate_dir (grub_disk_t disk, struct grub_fat_data *data,
|
||||||
}
|
}
|
||||||
|
|
||||||
slot--;
|
slot--;
|
||||||
grub_memcpy (unibuf + slot * 13, long_name->name1, 5 * 2);
|
grub_memcpy (ctxt->unibuf + slot * 13, long_name->name1, 5 * 2);
|
||||||
grub_memcpy (unibuf + slot * 13 + 5, long_name->name2, 6 * 2);
|
grub_memcpy (ctxt->unibuf + slot * 13 + 5, long_name->name2, 6 * 2);
|
||||||
grub_memcpy (unibuf + slot * 13 + 11, long_name->name3, 2 * 2);
|
grub_memcpy (ctxt->unibuf + slot * 13 + 11, long_name->name3, 2 * 2);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check if this entry is valid. */
|
/* Check if this entry is valid. */
|
||||||
if (dir.name[0] == 0xe5 || (dir.attr & ~GRUB_FAT_ATTR_VALID))
|
if (ctxt->dir.name[0] == 0xe5 || (ctxt->dir.attr & ~GRUB_FAT_ATTR_VALID))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
/* This is a workaround for Japanese. */
|
/* This is a workaround for Japanese. */
|
||||||
if (dir.name[0] == 0x05)
|
if (ctxt->dir.name[0] == 0x05)
|
||||||
dir.name[0] = 0xe5;
|
ctxt->dir.name[0] = 0xe5;
|
||||||
|
|
||||||
if (checksum != -1 && slot == 0)
|
if (checksum != -1 && slot == 0)
|
||||||
{
|
{
|
||||||
grub_uint8_t sum;
|
grub_uint8_t sum;
|
||||||
|
|
||||||
for (sum = 0, i = 0; i < sizeof (dir.name); i++)
|
for (sum = 0, i = 0; i < sizeof (ctxt->dir.name); i++)
|
||||||
sum = ((sum >> 1) | (sum << 7)) + dir.name[i];
|
sum = ((sum >> 1) | (sum << 7)) + ctxt->dir.name[i];
|
||||||
|
|
||||||
if (sum == checksum)
|
if (sum == checksum)
|
||||||
{
|
{
|
||||||
int u;
|
int u;
|
||||||
|
|
||||||
for (u = 0; u < slots * 13; u++)
|
for (u = 0; u < slots * 13; u++)
|
||||||
unibuf[u] = grub_le_to_cpu16 (unibuf[u]);
|
ctxt->unibuf[u] = grub_le_to_cpu16 (ctxt->unibuf[u]);
|
||||||
|
|
||||||
*grub_utf16_to_utf8 ((grub_uint8_t *) filename, unibuf,
|
*grub_utf16_to_utf8 ((grub_uint8_t *) ctxt->filename,
|
||||||
|
ctxt->unibuf,
|
||||||
slots * 13) = '\0';
|
slots * 13) = '\0';
|
||||||
|
|
||||||
if (hook (filename, &dir))
|
return GRUB_ERR_NONE;
|
||||||
break;
|
|
||||||
|
|
||||||
checksum = -1;
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
checksum = -1;
|
checksum = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Convert the 8.3 file name. */
|
/* Convert the 8.3 file name. */
|
||||||
filep = filename;
|
filep = ctxt->filename;
|
||||||
if (dir.attr & GRUB_FAT_ATTR_VOLUME_ID)
|
if (ctxt->dir.attr & GRUB_FAT_ATTR_VOLUME_ID)
|
||||||
{
|
{
|
||||||
for (i = 0; i < sizeof (dir.name) && dir.name[i]
|
for (i = 0; i < sizeof (ctxt->dir.name) && ctxt->dir.name[i]
|
||||||
&& ! grub_isspace (dir.name[i]); i++)
|
&& ! grub_isspace (ctxt->dir.name[i]); i++)
|
||||||
*filep++ = dir.name[i];
|
*filep++ = ctxt->dir.name[i];
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
for (i = 0; i < 8 && dir.name[i] && ! grub_isspace (dir.name[i]); i++)
|
for (i = 0; i < 8 && ctxt->dir.name[i] && ! grub_isspace (ctxt->dir.name[i]); i++)
|
||||||
*filep++ = grub_tolower (dir.name[i]);
|
*filep++ = grub_tolower (ctxt->dir.name[i]);
|
||||||
|
|
||||||
*filep = '.';
|
*filep = '.';
|
||||||
|
|
||||||
for (i = 8; i < 11 && dir.name[i] && ! grub_isspace (dir.name[i]); i++)
|
for (i = 8; i < 11 && ctxt->dir.name[i] && ! grub_isspace (ctxt->dir.name[i]); i++)
|
||||||
*++filep = grub_tolower (dir.name[i]);
|
*++filep = grub_tolower (ctxt->dir.name[i]);
|
||||||
|
|
||||||
if (*filep != '.')
|
if (*filep != '.')
|
||||||
filep++;
|
filep++;
|
||||||
}
|
}
|
||||||
*filep = '\0';
|
*filep = '\0';
|
||||||
if (hook (filename, &dir))
|
return GRUB_ERR_NONE;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
grub_free (filename);
|
return grub_errno ? : GRUB_ERR_EOF;
|
||||||
grub_free (unibuf);
|
|
||||||
|
|
||||||
return grub_errno;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Find the underlying directory or file in PATH and return the
|
/* Find the underlying directory or file in PATH and return the
|
||||||
|
@ -828,47 +836,8 @@ grub_fat_find_dir (grub_disk_t disk, struct grub_fat_data *data,
|
||||||
char *dirname, *dirp;
|
char *dirname, *dirp;
|
||||||
int call_hook;
|
int call_hook;
|
||||||
int found = 0;
|
int found = 0;
|
||||||
|
struct grub_fat_iterate_context ctxt;
|
||||||
auto int iter_hook (const char *filename, grub_fat_dir_node_t *dir);
|
grub_err_t err;
|
||||||
int iter_hook (const char *filename, grub_fat_dir_node_t *dir)
|
|
||||||
{
|
|
||||||
struct grub_dirhook_info info;
|
|
||||||
grub_memset (&info, 0, sizeof (info));
|
|
||||||
|
|
||||||
info.dir = !! (dir->attr & GRUB_FAT_ATTR_DIRECTORY);
|
|
||||||
info.case_insensitive = 1;
|
|
||||||
|
|
||||||
#ifdef MODE_EXFAT
|
|
||||||
if (!dir->have_stream)
|
|
||||||
return 0;
|
|
||||||
#else
|
|
||||||
if (dir->attr & GRUB_FAT_ATTR_VOLUME_ID)
|
|
||||||
return 0;
|
|
||||||
#endif
|
|
||||||
if (*dirname == '\0' && call_hook)
|
|
||||||
return hook (filename, &info);
|
|
||||||
|
|
||||||
if (grub_strcasecmp (dirname, filename) == 0)
|
|
||||||
{
|
|
||||||
found = 1;
|
|
||||||
data->attr = dir->attr;
|
|
||||||
#ifdef MODE_EXFAT
|
|
||||||
data->file_size = dir->file_size;
|
|
||||||
data->file_cluster = dir->first_cluster;
|
|
||||||
#else
|
|
||||||
data->file_size = grub_le_to_cpu32 (dir->file_size);
|
|
||||||
data->file_cluster = ((grub_le_to_cpu16 (dir->first_cluster_high) << 16)
|
|
||||||
| grub_le_to_cpu16 (dir->first_cluster_low));
|
|
||||||
#endif
|
|
||||||
data->cur_cluster_num = ~0U;
|
|
||||||
|
|
||||||
if (call_hook)
|
|
||||||
hook (filename, &info);
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (! (data->attr & GRUB_FAT_ATTR_DIRECTORY))
|
if (! (data->attr & GRUB_FAT_ATTR_DIRECTORY))
|
||||||
{
|
{
|
||||||
|
@ -898,7 +867,61 @@ grub_fat_find_dir (grub_disk_t disk, struct grub_fat_data *data,
|
||||||
|
|
||||||
call_hook = (! dirp && hook);
|
call_hook = (! dirp && hook);
|
||||||
|
|
||||||
grub_fat_iterate_dir (disk, data, iter_hook);
|
err = grub_fat_iterate_init (&ctxt);
|
||||||
|
if (err)
|
||||||
|
{
|
||||||
|
grub_free (dirname);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (!(err = grub_fat_iterate_dir_next (disk, data, &ctxt)))
|
||||||
|
{
|
||||||
|
struct grub_dirhook_info info;
|
||||||
|
grub_memset (&info, 0, sizeof (info));
|
||||||
|
|
||||||
|
info.dir = !! (ctxt.dir.attr & GRUB_FAT_ATTR_DIRECTORY);
|
||||||
|
info.case_insensitive = 1;
|
||||||
|
|
||||||
|
#ifdef MODE_EXFAT
|
||||||
|
if (!ctxt.dir.have_stream)
|
||||||
|
continue;
|
||||||
|
#else
|
||||||
|
if (ctxt.dir.attr & GRUB_FAT_ATTR_VOLUME_ID)
|
||||||
|
continue;
|
||||||
|
#endif
|
||||||
|
if (*dirname == '\0' && call_hook)
|
||||||
|
{
|
||||||
|
if (hook (ctxt.filename, &info))
|
||||||
|
break;
|
||||||
|
else
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (grub_strcasecmp (dirname, ctxt.filename) == 0)
|
||||||
|
{
|
||||||
|
found = 1;
|
||||||
|
data->attr = ctxt.dir.attr;
|
||||||
|
#ifdef MODE_EXFAT
|
||||||
|
data->file_size = ctxt.dir.file_size;
|
||||||
|
data->file_cluster = ctxt.dir.first_cluster;
|
||||||
|
#else
|
||||||
|
data->file_size = grub_le_to_cpu32 (ctxt.dir.file_size);
|
||||||
|
data->file_cluster = ((grub_le_to_cpu16 (ctxt.dir.first_cluster_high) << 16)
|
||||||
|
| grub_le_to_cpu16 (ctxt.dir.first_cluster_low));
|
||||||
|
#endif
|
||||||
|
data->cur_cluster_num = ~0U;
|
||||||
|
|
||||||
|
if (call_hook)
|
||||||
|
hook (ctxt.filename, &info);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
grub_fat_iterate_fini (&ctxt);
|
||||||
|
if (err == GRUB_ERR_EOF)
|
||||||
|
err = 0;
|
||||||
|
|
||||||
if (grub_errno == GRUB_ERR_NONE && ! found && !call_hook)
|
if (grub_errno == GRUB_ERR_NONE && ! found && !call_hook)
|
||||||
grub_error (GRUB_ERR_FILE_NOT_FOUND, N_("file `%s' not found"), origpath);
|
grub_error (GRUB_ERR_FILE_NOT_FOUND, N_("file `%s' not found"), origpath);
|
||||||
|
|
||||||
|
@ -1072,17 +1095,10 @@ grub_fat_label (grub_device_t device, char **label)
|
||||||
{
|
{
|
||||||
struct grub_fat_data *data;
|
struct grub_fat_data *data;
|
||||||
grub_disk_t disk = device->disk;
|
grub_disk_t disk = device->disk;
|
||||||
|
grub_err_t err;
|
||||||
|
struct grub_fat_iterate_context ctxt;
|
||||||
|
|
||||||
auto int iter_hook (const char *filename, grub_fat_dir_node_t *dir);
|
*label = 0;
|
||||||
int iter_hook (const char *filename, grub_fat_dir_node_t *dir)
|
|
||||||
{
|
|
||||||
if (dir->attr == GRUB_FAT_ATTR_VOLUME_ID)
|
|
||||||
{
|
|
||||||
*label = grub_strdup (filename);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
grub_dl_ref (my_mod);
|
grub_dl_ref (my_mod);
|
||||||
|
|
||||||
|
@ -1096,9 +1112,18 @@ grub_fat_label (grub_device_t device, char **label)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
*label = 0;
|
err = grub_fat_iterate_init (&ctxt);
|
||||||
|
if (err)
|
||||||
|
goto fail;
|
||||||
|
|
||||||
grub_fat_iterate_dir (disk, data, iter_hook);
|
while (!(err = grub_fat_iterate_dir_next (disk, data, &ctxt)))
|
||||||
|
if (ctxt.dir.attr == GRUB_FAT_ATTR_VOLUME_ID)
|
||||||
|
{
|
||||||
|
*label = grub_strdup (ctxt.filename);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
grub_fat_iterate_fini (&ctxt);
|
||||||
|
|
||||||
fail:
|
fail:
|
||||||
|
|
||||||
|
|
|
@ -68,7 +68,8 @@ typedef enum
|
||||||
GRUB_ERR_NET_INVALID_RESPONSE,
|
GRUB_ERR_NET_INVALID_RESPONSE,
|
||||||
GRUB_ERR_NET_UNKNOWN_ERROR,
|
GRUB_ERR_NET_UNKNOWN_ERROR,
|
||||||
GRUB_ERR_NET_PACKET_TOO_BIG,
|
GRUB_ERR_NET_PACKET_TOO_BIG,
|
||||||
GRUB_ERR_NET_NO_DOMAIN
|
GRUB_ERR_NET_NO_DOMAIN,
|
||||||
|
GRUB_ERR_EOF
|
||||||
}
|
}
|
||||||
grub_err_t;
|
grub_err_t;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue