1
1
mirror of https://github.com/systemd/systemd-stable.git synced 2024-10-31 07:51:08 +03:00

[PATCH] udev_volume_id: fix FAT label reading

This commit is contained in:
kay.sievers@vrfy.org 2005-01-18 09:13:01 +01:00 committed by Greg KH
parent c3a8dac6ff
commit eb064000ca
2 changed files with 43 additions and 13 deletions

View File

@ -774,6 +774,8 @@ static int probe_jfs(struct volume_id *id, __u64 off)
#define FAT16_MAX 0xfff5 #define FAT16_MAX 0xfff5
#define FAT_ATTR_VOLUME_ID 0x08 #define FAT_ATTR_VOLUME_ID 0x08
#define FAT_ATTR_DIR 0x10 #define FAT_ATTR_DIR 0x10
#define FAT_ATTR_LONG_NAME 0x0f
#define FAT_ATTR_MASK 0x3f
#define FAT_ENTRY_FREE 0xe5 #define FAT_ENTRY_FREE 0xe5
static int probe_vfat(struct volume_id *id, __u64 off) static int probe_vfat(struct volume_id *id, __u64 off)
{ {
@ -859,6 +861,9 @@ static int probe_vfat(struct volume_id *id, __u64 off)
/* believe only that's fat, don't trust the version /* believe only that's fat, don't trust the version
* the cluster_count will tell us * the cluster_count will tell us
*/ */
if (strncmp(vs->sysid, "NTFS", 4) == 0)
return -1;
if (strncmp(vs->type.fat32.magic, "MSWIN", 5) == 0) if (strncmp(vs->type.fat32.magic, "MSWIN", 5) == 0)
goto valid; goto valid;
@ -956,7 +961,7 @@ valid:
dir = (struct vfat_dir_entry*) buf; dir = (struct vfat_dir_entry*) buf;
for (i = 0; i <= root_dir_entries; i++) { for (i = 0; i < root_dir_entries; i++) {
/* end marker */ /* end marker */
if (dir[i].name[0] == 0x00) { if (dir[i].name[0] == 0x00) {
dbg("end of dir"); dbg("end of dir");
@ -967,7 +972,15 @@ valid:
if (dir[i].name[0] == FAT_ENTRY_FREE) if (dir[i].name[0] == FAT_ENTRY_FREE)
continue; continue;
/* long name */
if ((dir[i].attr & FAT_ATTR_MASK) == FAT_ATTR_LONG_NAME)
continue;
if ((dir[i].attr & (FAT_ATTR_VOLUME_ID | FAT_ATTR_DIR)) == FAT_ATTR_VOLUME_ID) { if ((dir[i].attr & (FAT_ATTR_VOLUME_ID | FAT_ATTR_DIR)) == FAT_ATTR_VOLUME_ID) {
/* labels do not have file data */
if (dir[i].cluster_high != 0 || dir[i].cluster_low != 0)
continue;
dbg("found ATTR_VOLUME_ID id in root dir"); dbg("found ATTR_VOLUME_ID id in root dir");
label = dir[i].name; label = dir[i].name;
break; break;
@ -976,6 +989,10 @@ valid:
dbg("skip dir entry"); dbg("skip dir entry");
} }
vs = (struct vfat_super_block *) get_buffer(id, off, 0x200);
if (vs == NULL)
return -1;
if (label != NULL && strncmp(label, "NO NAME ", 11) != 0) { if (label != NULL && strncmp(label, "NO NAME ", 11) != 0) {
set_label_raw(id, label, 11); set_label_raw(id, label, 11);
set_label_string(id, label, 11); set_label_string(id, label, 11);
@ -1015,7 +1032,7 @@ fat32:
count = buf_size / sizeof(struct vfat_dir_entry); count = buf_size / sizeof(struct vfat_dir_entry);
dbg("expected entries 0x%x", count); dbg("expected entries 0x%x", count);
for (i = 0; i <= count; i++) { for (i = 0; i < count; i++) {
/* end marker */ /* end marker */
if (dir[i].name[0] == 0x00) { if (dir[i].name[0] == 0x00) {
dbg("end of dir"); dbg("end of dir");
@ -1026,7 +1043,15 @@ fat32:
if (dir[i].name[0] == FAT_ENTRY_FREE) if (dir[i].name[0] == FAT_ENTRY_FREE)
continue; continue;
/* long name */
if ((dir[i].attr & FAT_ATTR_MASK) == FAT_ATTR_LONG_NAME)
continue;
if ((dir[i].attr & (FAT_ATTR_VOLUME_ID | FAT_ATTR_DIR)) == FAT_ATTR_VOLUME_ID) { if ((dir[i].attr & (FAT_ATTR_VOLUME_ID | FAT_ATTR_DIR)) == FAT_ATTR_VOLUME_ID) {
/* labels do not have file data */
if (dir[i].cluster_high != 0 || dir[i].cluster_low != 0)
continue;
dbg("found ATTR_VOLUME_ID id in root dir"); dbg("found ATTR_VOLUME_ID id in root dir");
label = dir[i].name; label = dir[i].name;
goto fat32_label; goto fat32_label;
@ -1050,6 +1075,10 @@ fat32:
dbg("reached maximum follow count of root cluster chain, give up"); dbg("reached maximum follow count of root cluster chain, give up");
fat32_label: fat32_label:
vs = (struct vfat_super_block *) get_buffer(id, off, 0x200);
if (vs == NULL)
return -1;
if (label != NULL && strncmp(label, "NO NAME ", 11) != 0) { if (label != NULL && strncmp(label, "NO NAME ", 11) != 0) {
set_label_raw(id, label, 11); set_label_raw(id, label, 11);
set_label_string(id, label, 11); set_label_string(id, label, 11);
@ -1251,10 +1280,14 @@ static int probe_iso9660(struct volume_id *id, __u64 off)
return -1; return -1;
if (strncmp(is->iso.id, "CD001", 5) == 0) { if (strncmp(is->iso.id, "CD001", 5) == 0) {
char root_label[VOLUME_ID_LABEL_SIZE+1];
int vd_offset; int vd_offset;
int i; int i;
int found_svd; int found_svd;
memset(root_label, 0, sizeof(root_label));
strncpy(root_label, is->iso.volume_id, sizeof(root_label)-1);
found_svd = 0; found_svd = 0;
vd_offset = ISO_VD_OFFSET; vd_offset = ISO_VD_OFFSET;
for (i = 0; i < ISO_VD_MAX; i++) { for (i = 0; i < ISO_VD_MAX; i++) {
@ -1264,22 +1297,19 @@ static int probe_iso9660(struct volume_id *id, __u64 off)
break; break;
if (is->iso.type == ISO_VD_SUPPLEMENTARY) { if (is->iso.type == ISO_VD_SUPPLEMENTARY) {
dbg("found ISO supplementary VD at offset 0x%llx", off + vd_offset); dbg("found ISO supplementary VD at offset 0x%llx", off + vd_offset);
set_label_raw(id, is->iso.volume_id, 32);
set_label_unicode16(id, is->iso.volume_id, BE, 32);
found_svd = 1; found_svd = 1;
break; break;
} }
vd_offset += ISO_SECTOR_SIZE; vd_offset += ISO_SECTOR_SIZE;
} }
if (!found_svd) { if (!found_svd ||
is = (union iso_super_block *) (found_svd && !strncmp(root_label, id->label, 16)))
get_buffer(id, off + ISO_SUPERBLOCK_OFFSET, 0x200); {
if (is == NULL) set_label_raw(id, root_label, 32);
return -1; set_label_string(id, root_label, 32);
set_label_raw(id, is->iso.volume_id, 32);
set_label_string(id, is->iso.volume_id, 32);
} else {
set_label_raw(id, is->iso.volume_id, 32);
set_label_unicode16(id, is->iso.volume_id, BE, 32);
} }
goto found; goto found;
} }

View File

@ -21,7 +21,7 @@
#ifndef _VOLUME_ID_H_ #ifndef _VOLUME_ID_H_
#define _VOLUME_ID_H_ #define _VOLUME_ID_H_
#define VOLUME_ID_VERSION 27 #define VOLUME_ID_VERSION 28
#define VOLUME_ID_LABEL_SIZE 64 #define VOLUME_ID_LABEL_SIZE 64
#define VOLUME_ID_UUID_SIZE 16 #define VOLUME_ID_UUID_SIZE 16