mirror of
https://github.com/AuxXxilium/eudev.git
synced 2024-12-28 06:35:34 +07:00
[PATCH] udev_volume_id: new version of volume_id
Every filesystem has its own subdirectory. The IBM dasd label reading is included into volume_id.
This commit is contained in:
parent
61b24e5e19
commit
c033fd9f01
@ -33,8 +33,50 @@ override CFLAGS+=-Wall -fno-builtin -Wchar-subscripts \
|
||||
|
||||
override CFLAGS+=-D_FILE_OFFSET_BITS=64
|
||||
|
||||
OBJS = volume_id.o udev_volume_id.o dasdlabel.o $(SYSFS)
|
||||
HEADERS = volume_id.h dasdlabel.h
|
||||
VOLUME_ID_OBJS= \
|
||||
volume_id/ext/ext.o \
|
||||
volume_id/fat/fat.o \
|
||||
volume_id/hfs/hfs.o \
|
||||
volume_id/highpoint/highpoint.o \
|
||||
volume_id/iso9660/iso9660.o \
|
||||
volume_id/jfs/jfs.o \
|
||||
volume_id/linux_raid/linux_raid.o \
|
||||
volume_id/linux_swap/linux_swap.o \
|
||||
volume_id/lvm/lvm.o \
|
||||
volume_id/mac/mac.o \
|
||||
volume_id/msdos/msdos.o \
|
||||
volume_id/ntfs/ntfs.o \
|
||||
volume_id/reiserfs/reiserfs.o \
|
||||
volume_id/udf/udf.o \
|
||||
volume_id/ufs/ufs.o \
|
||||
volume_id/xfs/xfs.o \
|
||||
volume_id/dasd/dasd.o \
|
||||
volume_id/volume_id.o \
|
||||
volume_id/util.o
|
||||
|
||||
VOLUME_ID_HEADERS= \
|
||||
volume_id/ext/ext.h \
|
||||
volume_id/fat/fat.h \
|
||||
volume_id/hfs/hfs.h \
|
||||
volume_id/highpoint/highpoint.h \
|
||||
volume_id/iso9660/iso9660.h \
|
||||
volume_id/jfs/jfs.h \
|
||||
volume_id/linux_raid/linux_raid.h \
|
||||
volume_id/linux_swap/linux_swap.h \
|
||||
volume_id/lvm/lvm.h \
|
||||
volume_id/mac/mac.h \
|
||||
volume_id/msdos/msdos.h \
|
||||
volume_id/ntfs/ntfs.h \
|
||||
volume_id/reiserfs/reiserfs.h \
|
||||
volume_id/udf/udf.h \
|
||||
volume_id/ufs/ufs.h \
|
||||
volume_id/xfs/xfs.h \
|
||||
volume_id/dasd/dasd.h \
|
||||
volume_id/volume_id.h \
|
||||
volume_id/util.h
|
||||
|
||||
OBJS = udev_volume_id.o $(VOLUME_ID_OBJS) $(SYSFS)
|
||||
HEADERS = $(VOLUME_ID_HEADERS)
|
||||
|
||||
$(OBJS): $(HEADERS)
|
||||
|
||||
@ -54,4 +96,3 @@ install: all
|
||||
|
||||
uninstall:
|
||||
- rm $(DESTDIR)$(sbindir)/$(PROG)
|
||||
|
||||
|
@ -31,8 +31,8 @@
|
||||
#include "../../libsysfs/sysfs/libsysfs.h"
|
||||
#include "../../udev_utils.h"
|
||||
#include "../../logging.h"
|
||||
#include "volume_id.h"
|
||||
#include "dasdlabel.h"
|
||||
#include "volume_id/volume_id.h"
|
||||
#include "volume_id/dasd/dasd.h"
|
||||
|
||||
#define BLKGETSIZE64 _IOR(0x12,114,size_t)
|
||||
|
||||
@ -74,26 +74,6 @@ static struct volume_id *open_classdev(struct sysfs_class_device *class_dev)
|
||||
return vid;
|
||||
}
|
||||
|
||||
static char *usage_id_name(enum volume_id_usage usage)
|
||||
{
|
||||
switch(usage) {
|
||||
case VOLUME_ID_UNUSED:
|
||||
return "unused";
|
||||
case VOLUME_ID_UNPROBED:
|
||||
return "unprobed";
|
||||
case VOLUME_ID_OTHER:
|
||||
return "other";
|
||||
case VOLUME_ID_PARTITIONTABLE:
|
||||
return "partitiontable";
|
||||
case VOLUME_ID_FILESYSTEM:
|
||||
return "filesystem";
|
||||
case VOLUME_ID_RAID:
|
||||
return "raid";
|
||||
default:
|
||||
return "unknown type_id";
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
const char help[] = "usage: udev_volume_id [-t|-l|-u|-d]\n"
|
||||
@ -111,7 +91,6 @@ int main(int argc, char *argv[])
|
||||
char *devpath;
|
||||
char probe = 'p';
|
||||
char print = 'a';
|
||||
char dasd_label[7];
|
||||
static char name[VOLUME_ID_LABEL_SIZE];
|
||||
int len, i, j;
|
||||
unsigned long long size;
|
||||
@ -177,7 +156,7 @@ int main(int argc, char *argv[])
|
||||
if (ioctl(vid->fd, BLKGETSIZE64, &size) != 0)
|
||||
size = 0;
|
||||
|
||||
if (volume_id_probe(vid, VOLUME_ID_ALL, 0, size) == 0)
|
||||
if (volume_id_probe_all(vid, 0, size) == 0)
|
||||
goto print;
|
||||
break;
|
||||
case 'd' :
|
||||
@ -190,12 +169,8 @@ int main(int argc, char *argv[])
|
||||
if (vid == NULL)
|
||||
goto exit;
|
||||
|
||||
if (probe_ibm_partition(vid->fd, dasd_label) == 0) {
|
||||
vid->type = "dasd";
|
||||
strncpy(vid->label, dasd_label, 6);
|
||||
vid->label[6] = '\0';
|
||||
if (probe_ibm_partition(vid) == 0)
|
||||
goto print;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
@ -247,7 +222,7 @@ print:
|
||||
printf("%s\n", vid->uuid);
|
||||
break;
|
||||
case 'a':
|
||||
printf("F:%s\n", usage_id_name(vid->usage_id));
|
||||
printf("F:%s\n", vid->usage);
|
||||
printf("T:%s\n", vid->type);
|
||||
printf("V:%s\n", vid->type_version);
|
||||
printf("L:%s\n", vid->label);
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -18,6 +18,13 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _GNU_SOURCE
|
||||
#define _GNU_SOURCE 1
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
@ -25,8 +32,11 @@
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <asm/types.h>
|
||||
|
||||
#include "dasdlabel.h"
|
||||
#include "../volume_id.h"
|
||||
#include "../util.h"
|
||||
#include "dasd.h"
|
||||
|
||||
static unsigned char EBCtoASC[256] =
|
||||
{
|
||||
@ -100,7 +110,7 @@ static unsigned char EBCtoASC[256] =
|
||||
0x38, 0x39, 0x07, 0x07, 0x9A, 0x07, 0x07, 0x07
|
||||
};
|
||||
|
||||
static void vtoc_ebcdic_dec (unsigned char *source, unsigned char *target, int l)
|
||||
static void vtoc_ebcdic_dec (const unsigned char *source, unsigned char *target, int l)
|
||||
{
|
||||
int i;
|
||||
|
||||
@ -150,29 +160,35 @@ typedef struct dasd_information_t {
|
||||
#define BIODASDINFO _IOR(DASD_IOCTL_LETTER,1,dasd_information_t)
|
||||
#define BLKSSZGET _IO(0x12,104)
|
||||
|
||||
int probe_ibm_partition(int fd, char *out)
|
||||
int probe_ibm_partition(struct volume_id *id)
|
||||
{
|
||||
int blocksize;
|
||||
dasd_information_t info;
|
||||
char name[7] = {0,};
|
||||
unsigned char data[16];
|
||||
__u8 *data;
|
||||
__u8 *label_raw;
|
||||
unsigned char name[7];
|
||||
|
||||
if (ioctl(fd, BIODASDINFO, (unsigned long)&info) != 0)
|
||||
if (ioctl(id->fd, BIODASDINFO, &info) != 0)
|
||||
return -1;
|
||||
|
||||
if (ioctl(fd, BLKSSZGET, (unsigned long)&blocksize))
|
||||
if (ioctl(id->fd, BLKSSZGET, &blocksize) != 0)
|
||||
return -1;
|
||||
|
||||
lseek(fd, info.label_block * blocksize, SEEK_SET);
|
||||
if (read(fd, &data, 16) != 16)
|
||||
data = volume_id_get_buffer(id, info.label_block * blocksize, 16);
|
||||
if (data == NULL)
|
||||
return -1;
|
||||
|
||||
if ((!info.FBA_layout) && (!strcmp(info.type, "ECKD")))
|
||||
strncpy(name, data + 8, 6);
|
||||
label_raw = &data[8];
|
||||
else
|
||||
strncpy(name, data + 4, 6);
|
||||
label_raw = &data[4];
|
||||
|
||||
vtoc_ebcdic_dec(name, out, 6);
|
||||
name[6] = '\0';
|
||||
volume_id_set_usage(id, VOLUME_ID_DISKLABEL);
|
||||
id->type = "dasd";
|
||||
volume_id_set_label_raw(id, label_raw, 6);
|
||||
vtoc_ebcdic_dec(label_raw, name, 6);
|
||||
volume_id_set_label_string(id, name, 6);
|
||||
|
||||
return 0;
|
||||
}
|
@ -18,9 +18,9 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _DASDLABEL_H_
|
||||
#define _DASDLABEL_H_
|
||||
#ifndef _VOLUME_ID_DASDLABEL_
|
||||
#define _VOLUME_ID_DASDLABEL_
|
||||
|
||||
extern int probe_ibm_partition(int fd, char *out);
|
||||
extern int probe_ibm_partition(struct volume_id *id);
|
||||
|
||||
#endif
|
86
extras/volume_id/volume_id/ext/ext.c
Normal file
86
extras/volume_id/volume_id/ext/ext.c
Normal file
@ -0,0 +1,86 @@
|
||||
/*
|
||||
* volume_id - reads filesystem label and uuid
|
||||
*
|
||||
* Copyright (C) 2004 Kay Sievers <kay.sievers@vrfy.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef _GNU_SOURCE
|
||||
#define _GNU_SOURCE 1
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <ctype.h>
|
||||
#include <asm/types.h>
|
||||
|
||||
#include "../volume_id.h"
|
||||
#include "../util.h"
|
||||
#include "../logging.h"
|
||||
#include "ext.h"
|
||||
|
||||
#define EXT3_FEATURE_COMPAT_HAS_JOURNAL 0x00000004
|
||||
#define EXT3_FEATURE_INCOMPAT_JOURNAL_DEV 0x00000008
|
||||
#define EXT_SUPERBLOCK_OFFSET 0x400
|
||||
|
||||
int volume_id_probe_ext(struct volume_id *id, __u64 off)
|
||||
{
|
||||
struct ext2_super_block {
|
||||
__u32 inodes_count;
|
||||
__u32 blocks_count;
|
||||
__u32 r_blocks_count;
|
||||
__u32 free_blocks_count;
|
||||
__u32 free_inodes_count;
|
||||
__u32 first_data_block;
|
||||
__u32 log_block_size;
|
||||
__u32 dummy3[7];
|
||||
__u8 magic[2];
|
||||
__u16 state;
|
||||
__u32 dummy5[8];
|
||||
__u32 feature_compat;
|
||||
__u32 feature_incompat;
|
||||
__u32 feature_ro_compat;
|
||||
__u8 uuid[16];
|
||||
__u8 volume_name[16];
|
||||
} __attribute__((__packed__)) *es;
|
||||
|
||||
es = (struct ext2_super_block *) volume_id_get_buffer(id, off + EXT_SUPERBLOCK_OFFSET, 0x200);
|
||||
if (es == NULL)
|
||||
return -1;
|
||||
|
||||
if (es->magic[0] != 0123 ||
|
||||
es->magic[1] != 0357)
|
||||
return -1;
|
||||
|
||||
volume_id_set_usage(id, VOLUME_ID_FILESYSTEM);
|
||||
volume_id_set_label_raw(id, es->volume_name, 16);
|
||||
volume_id_set_label_string(id, es->volume_name, 16);
|
||||
volume_id_set_uuid(id, es->uuid, UUID_DCE);
|
||||
|
||||
if ((le32_to_cpu(es->feature_compat) & EXT3_FEATURE_COMPAT_HAS_JOURNAL) != 0)
|
||||
id->type = "ext3";
|
||||
else
|
||||
id->type = "ext2";
|
||||
|
||||
return 0;
|
||||
}
|
26
extras/volume_id/volume_id/ext/ext.h
Normal file
26
extras/volume_id/volume_id/ext/ext.h
Normal file
@ -0,0 +1,26 @@
|
||||
/*
|
||||
* volume_id - reads filesystem label and uuid
|
||||
*
|
||||
* Copyright (C) 2004 Kay Sievers <kay.sievers@vrfy.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef _VOLUME_ID_EXT_
|
||||
#define _VOLUME_ID_EXT_
|
||||
|
||||
extern int volume_id_probe_ext(struct volume_id *id, __u64 off);
|
||||
|
||||
#endif
|
350
extras/volume_id/volume_id/fat/fat.c
Normal file
350
extras/volume_id/volume_id/fat/fat.c
Normal file
@ -0,0 +1,350 @@
|
||||
/*
|
||||
* volume_id - reads filesystem label and uuid
|
||||
*
|
||||
* Copyright (C) 2004 Kay Sievers <kay.sievers@vrfy.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef _GNU_SOURCE
|
||||
#define _GNU_SOURCE 1
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <ctype.h>
|
||||
#include <asm/types.h>
|
||||
|
||||
#include "../volume_id.h"
|
||||
#include "../logging.h"
|
||||
#include "../util.h"
|
||||
#include "fat.h"
|
||||
|
||||
#define FAT12_MAX 0xff5
|
||||
#define FAT16_MAX 0xfff5
|
||||
#define FAT_ATTR_VOLUME_ID 0x08
|
||||
#define FAT_ATTR_DIR 0x10
|
||||
#define FAT_ATTR_LONG_NAME 0x0f
|
||||
#define FAT_ATTR_MASK 0x3f
|
||||
#define FAT_ENTRY_FREE 0xe5
|
||||
|
||||
struct vfat_super_block {
|
||||
__u8 boot_jump[3];
|
||||
__u8 sysid[8];
|
||||
__u16 sector_size;
|
||||
__u8 sectors_per_cluster;
|
||||
__u16 reserved;
|
||||
__u8 fats;
|
||||
__u16 dir_entries;
|
||||
__u16 sectors;
|
||||
__u8 media;
|
||||
__u16 fat_length;
|
||||
__u16 secs_track;
|
||||
__u16 heads;
|
||||
__u32 hidden;
|
||||
__u32 total_sect;
|
||||
union {
|
||||
struct fat_super_block {
|
||||
__u8 unknown[3];
|
||||
__u8 serno[4];
|
||||
__u8 label[11];
|
||||
__u8 magic[8];
|
||||
__u8 dummy2[192];
|
||||
__u8 pmagic[2];
|
||||
} __attribute__((__packed__)) fat;
|
||||
struct fat32_super_block {
|
||||
__u32 fat32_length;
|
||||
__u16 flags;
|
||||
__u8 version[2];
|
||||
__u32 root_cluster;
|
||||
__u16 insfo_sector;
|
||||
__u16 backup_boot;
|
||||
__u16 reserved2[6];
|
||||
__u8 unknown[3];
|
||||
__u8 serno[4];
|
||||
__u8 label[11];
|
||||
__u8 magic[8];
|
||||
__u8 dummy2[164];
|
||||
__u8 pmagic[2];
|
||||
} __attribute__((__packed__)) fat32;
|
||||
} __attribute__((__packed__)) type;
|
||||
} __attribute__((__packed__));
|
||||
|
||||
struct vfat_dir_entry {
|
||||
__u8 name[11];
|
||||
__u8 attr;
|
||||
__u16 time_creat;
|
||||
__u16 date_creat;
|
||||
__u16 time_acc;
|
||||
__u16 date_acc;
|
||||
__u16 cluster_high;
|
||||
__u16 time_write;
|
||||
__u16 date_write;
|
||||
__u16 cluster_low;
|
||||
__u32 size;
|
||||
} __attribute__((__packed__));
|
||||
|
||||
static char *get_attr_volume_id(struct vfat_dir_entry *dir, unsigned int count)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
/* end marker */
|
||||
if (dir[i].name[0] == 0x00) {
|
||||
dbg("end of dir");
|
||||
break;
|
||||
}
|
||||
|
||||
/* empty entry */
|
||||
if (dir[i].name[0] == FAT_ENTRY_FREE)
|
||||
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) {
|
||||
/* 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");
|
||||
return dir[i].name;
|
||||
}
|
||||
|
||||
dbg("skip dir entry");
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int volume_id_probe_vfat(struct volume_id *id, __u64 off)
|
||||
{
|
||||
struct vfat_super_block *vs;
|
||||
struct vfat_dir_entry *dir;
|
||||
__u16 sector_size;
|
||||
__u16 dir_entries;
|
||||
__u32 sect_count;
|
||||
__u16 reserved;
|
||||
__u32 fat_size;
|
||||
__u32 root_cluster;
|
||||
__u32 dir_size;
|
||||
__u32 cluster_count;
|
||||
__u32 fat_length;
|
||||
__u64 root_start;
|
||||
__u32 start_data_sect;
|
||||
__u16 root_dir_entries;
|
||||
__u8 *buf;
|
||||
__u32 buf_size;
|
||||
__u8 *label = NULL;
|
||||
__u32 next;
|
||||
int maxloop;
|
||||
|
||||
vs = (struct vfat_super_block *) volume_id_get_buffer(id, off, 0x200);
|
||||
if (vs == NULL)
|
||||
return -1;
|
||||
|
||||
/* believe only that's fat, don't trust the version
|
||||
* the cluster_count will tell us
|
||||
*/
|
||||
if (strncmp(vs->sysid, "NTFS", 4) == 0)
|
||||
return -1;
|
||||
|
||||
if (strncmp(vs->type.fat32.magic, "MSWIN", 5) == 0)
|
||||
goto valid;
|
||||
|
||||
if (strncmp(vs->type.fat32.magic, "FAT32 ", 8) == 0)
|
||||
goto valid;
|
||||
|
||||
if (strncmp(vs->type.fat.magic, "FAT16 ", 8) == 0)
|
||||
goto valid;
|
||||
|
||||
if (strncmp(vs->type.fat.magic, "MSDOS", 5) == 0)
|
||||
goto valid;
|
||||
|
||||
if (strncmp(vs->type.fat.magic, "FAT12 ", 8) == 0)
|
||||
goto valid;
|
||||
|
||||
/*
|
||||
* There are old floppies out there without a magic, so we check
|
||||
* for well known values and guess if it's a fat volume
|
||||
*/
|
||||
|
||||
/* boot jump address check */
|
||||
if ((vs->boot_jump[0] != 0xeb || vs->boot_jump[2] != 0x90) &&
|
||||
vs->boot_jump[0] != 0xe9)
|
||||
return -1;
|
||||
|
||||
/* heads check */
|
||||
if (vs->heads == 0)
|
||||
return -1;
|
||||
|
||||
/* cluster size check*/
|
||||
if (vs->sectors_per_cluster == 0 ||
|
||||
(vs->sectors_per_cluster & (vs->sectors_per_cluster-1)))
|
||||
return -1;
|
||||
|
||||
/* media check */
|
||||
if (vs->media < 0xf8 && vs->media != 0xf0)
|
||||
return -1;
|
||||
|
||||
/* fat count*/
|
||||
if (vs->fats != 2)
|
||||
return -1;
|
||||
|
||||
valid:
|
||||
/* sector size check */
|
||||
sector_size = le16_to_cpu(vs->sector_size);
|
||||
if (sector_size != 0x200 && sector_size != 0x400 &&
|
||||
sector_size != 0x800 && sector_size != 0x1000)
|
||||
return -1;
|
||||
|
||||
dbg("sector_size 0x%x", sector_size);
|
||||
dbg("sectors_per_cluster 0x%x", vs->sectors_per_cluster);
|
||||
|
||||
dir_entries = le16_to_cpu(vs->dir_entries);
|
||||
reserved = le16_to_cpu(vs->reserved);
|
||||
dbg("reserved 0x%x", reserved);
|
||||
|
||||
sect_count = le16_to_cpu(vs->sectors);
|
||||
if (sect_count == 0)
|
||||
sect_count = le32_to_cpu(vs->total_sect);
|
||||
dbg("sect_count 0x%x", sect_count);
|
||||
|
||||
fat_length = le16_to_cpu(vs->fat_length);
|
||||
if (fat_length == 0)
|
||||
fat_length = le32_to_cpu(vs->type.fat32.fat32_length);
|
||||
dbg("fat_length 0x%x", fat_length);
|
||||
|
||||
fat_size = fat_length * vs->fats;
|
||||
dir_size = ((dir_entries * sizeof(struct vfat_dir_entry)) +
|
||||
(sector_size-1)) / sector_size;
|
||||
dbg("dir_size 0x%x", dir_size);
|
||||
|
||||
cluster_count = sect_count - (reserved + fat_size + dir_size);
|
||||
cluster_count /= vs->sectors_per_cluster;
|
||||
dbg("cluster_count 0x%x", cluster_count);
|
||||
|
||||
if (cluster_count < FAT12_MAX) {
|
||||
strcpy(id->type_version, "FAT12");
|
||||
} else if (cluster_count < FAT16_MAX) {
|
||||
strcpy(id->type_version, "FAT16");
|
||||
} else {
|
||||
strcpy(id->type_version, "FAT32");
|
||||
goto fat32;
|
||||
}
|
||||
|
||||
/* the label may be an attribute in the root directory */
|
||||
root_start = (reserved + fat_size) * sector_size;
|
||||
dbg("root dir start 0x%llx", root_start);
|
||||
root_dir_entries = le16_to_cpu(vs->dir_entries);
|
||||
dbg("expected entries 0x%x", root_dir_entries);
|
||||
|
||||
buf_size = root_dir_entries * sizeof(struct vfat_dir_entry);
|
||||
buf = volume_id_get_buffer(id, off + root_start, buf_size);
|
||||
if (buf == NULL)
|
||||
goto found;
|
||||
|
||||
dir = (struct vfat_dir_entry*) buf;
|
||||
|
||||
label = get_attr_volume_id(dir, root_dir_entries);
|
||||
|
||||
vs = (struct vfat_super_block *) volume_id_get_buffer(id, off, 0x200);
|
||||
if (vs == NULL)
|
||||
return -1;
|
||||
|
||||
if (label != NULL && strncmp(label, "NO NAME ", 11) != 0) {
|
||||
volume_id_set_label_raw(id, label, 11);
|
||||
volume_id_set_label_string(id, label, 11);
|
||||
} else if (strncmp(vs->type.fat.label, "NO NAME ", 11) != 0) {
|
||||
volume_id_set_label_raw(id, vs->type.fat.label, 11);
|
||||
volume_id_set_label_string(id, vs->type.fat.label, 11);
|
||||
}
|
||||
volume_id_set_uuid(id, vs->type.fat.serno, UUID_DOS);
|
||||
goto found;
|
||||
|
||||
fat32:
|
||||
/* FAT32 root dir is a cluster chain like any other directory */
|
||||
buf_size = vs->sectors_per_cluster * sector_size;
|
||||
root_cluster = le32_to_cpu(vs->type.fat32.root_cluster);
|
||||
dbg("root dir cluster %u", root_cluster);
|
||||
start_data_sect = reserved + fat_size;
|
||||
|
||||
next = root_cluster;
|
||||
maxloop = 100;
|
||||
while (--maxloop) {
|
||||
__u32 next_sect_off;
|
||||
__u64 next_off;
|
||||
__u64 fat_entry_off;
|
||||
int count;
|
||||
|
||||
dbg("next cluster %u", next);
|
||||
next_sect_off = (next - 2) * vs->sectors_per_cluster;
|
||||
next_off = (start_data_sect + next_sect_off) * sector_size;
|
||||
dbg("cluster offset 0x%llx", next_off);
|
||||
|
||||
/* get cluster */
|
||||
buf = volume_id_get_buffer(id, off + next_off, buf_size);
|
||||
if (buf == NULL)
|
||||
goto found;
|
||||
|
||||
dir = (struct vfat_dir_entry*) buf;
|
||||
count = buf_size / sizeof(struct vfat_dir_entry);
|
||||
dbg("expected entries 0x%x", count);
|
||||
|
||||
label = get_attr_volume_id(dir, count);
|
||||
if (label)
|
||||
break;
|
||||
|
||||
/* get FAT entry */
|
||||
fat_entry_off = (reserved * sector_size) + (next * sizeof(__u32));
|
||||
buf = volume_id_get_buffer(id, off + fat_entry_off, buf_size);
|
||||
if (buf == NULL)
|
||||
goto found;
|
||||
|
||||
/* set next cluster */
|
||||
next = le32_to_cpu(*((__u32 *) buf) & 0x0fffffff);
|
||||
if (next == 0)
|
||||
break;
|
||||
}
|
||||
if (maxloop == 0)
|
||||
dbg("reached maximum follow count of root cluster chain, give up");
|
||||
|
||||
vs = (struct vfat_super_block *) volume_id_get_buffer(id, off, 0x200);
|
||||
if (vs == NULL)
|
||||
return -1;
|
||||
|
||||
if (label != NULL && strncmp(label, "NO NAME ", 11) != 0) {
|
||||
volume_id_set_label_raw(id, label, 11);
|
||||
volume_id_set_label_string(id, label, 11);
|
||||
} else if (strncmp(vs->type.fat32.label, "NO NAME ", 11) != 0) {
|
||||
volume_id_set_label_raw(id, vs->type.fat32.label, 11);
|
||||
volume_id_set_label_string(id, vs->type.fat32.label, 11);
|
||||
}
|
||||
volume_id_set_uuid(id, vs->type.fat32.serno, UUID_DOS);
|
||||
|
||||
found:
|
||||
volume_id_set_usage(id, VOLUME_ID_DISKLABEL);
|
||||
id->type = "vfat";
|
||||
|
||||
return 0;
|
||||
}
|
26
extras/volume_id/volume_id/fat/fat.h
Normal file
26
extras/volume_id/volume_id/fat/fat.h
Normal file
@ -0,0 +1,26 @@
|
||||
/*
|
||||
* volume_id - reads filesystem label and uuid
|
||||
*
|
||||
* Copyright (C) 2004 Kay Sievers <kay.sievers@vrfy.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef _VOLUME_ID_FAT_
|
||||
#define _VOLUME_ID_FAT_
|
||||
|
||||
extern int volume_id_probe_vfat(struct volume_id *id, __u64 off);
|
||||
|
||||
#endif
|
308
extras/volume_id/volume_id/hfs/hfs.c
Normal file
308
extras/volume_id/volume_id/hfs/hfs.c
Normal file
@ -0,0 +1,308 @@
|
||||
/*
|
||||
* volume_id - reads filesystem label and uuid
|
||||
*
|
||||
* Copyright (C) 2004 Kay Sievers <kay.sievers@vrfy.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef _GNU_SOURCE
|
||||
#define _GNU_SOURCE 1
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <ctype.h>
|
||||
#include <asm/types.h>
|
||||
|
||||
#include "../volume_id.h"
|
||||
#include "../logging.h"
|
||||
#include "../util.h"
|
||||
#include "hfs.h"
|
||||
|
||||
#define HFS_SUPERBLOCK_OFFSET 0x400
|
||||
#define HFS_NODE_LEAF 0xff
|
||||
#define HFSPLUS_POR_CNID 1
|
||||
#define HFSPLUS_EXTENT_COUNT 8
|
||||
|
||||
int volume_id_probe_hfs_hfsplus(struct volume_id *id, __u64 off)
|
||||
{
|
||||
struct hfs_finder_info{
|
||||
__u32 boot_folder;
|
||||
__u32 start_app;
|
||||
__u32 open_folder;
|
||||
__u32 os9_folder;
|
||||
__u32 reserved;
|
||||
__u32 osx_folder;
|
||||
__u8 id[8];
|
||||
} __attribute__((__packed__));
|
||||
|
||||
struct hfs_mdb {
|
||||
__u8 signature[2];
|
||||
__u32 cr_date;
|
||||
__u32 ls_Mod;
|
||||
__u16 atrb;
|
||||
__u16 nm_fls;
|
||||
__u16 vbm_st;
|
||||
__u16 alloc_ptr;
|
||||
__u16 nm_al_blks;
|
||||
__u32 al_blk_size;
|
||||
__u32 clp_size;
|
||||
__u16 al_bl_st;
|
||||
__u32 nxt_cnid;
|
||||
__u16 free_bks;
|
||||
__u8 label_len;
|
||||
__u8 label[27];
|
||||
__u32 vol_bkup;
|
||||
__u16 vol_seq_num;
|
||||
__u32 wr_cnt;
|
||||
__u32 xt_clump_size;
|
||||
__u32 ct_clump_size;
|
||||
__u16 num_root_dirs;
|
||||
__u32 file_count;
|
||||
__u32 dir_count;
|
||||
struct hfs_finder_info finder_info;
|
||||
__u8 embed_sig[2];
|
||||
__u16 embed_startblock;
|
||||
__u16 embed_blockcount;
|
||||
} __attribute__((__packed__)) *hfs;
|
||||
|
||||
struct hfsplus_bnode_descriptor {
|
||||
__u32 next;
|
||||
__u32 prev;
|
||||
__u8 type;
|
||||
__u8 height;
|
||||
__u16 num_recs;
|
||||
__u16 reserved;
|
||||
} __attribute__((__packed__));
|
||||
|
||||
struct hfsplus_bheader_record {
|
||||
__u16 depth;
|
||||
__u32 root;
|
||||
__u32 leaf_count;
|
||||
__u32 leaf_head;
|
||||
__u32 leaf_tail;
|
||||
__u16 node_size;
|
||||
} __attribute__((__packed__));
|
||||
|
||||
struct hfsplus_catalog_key {
|
||||
__u16 key_len;
|
||||
__u32 parent_id;
|
||||
__u16 unicode_len;
|
||||
__u8 unicode[255 * 2];
|
||||
} __attribute__((__packed__));
|
||||
|
||||
struct hfsplus_extent {
|
||||
__u32 start_block;
|
||||
__u32 block_count;
|
||||
} __attribute__((__packed__));
|
||||
|
||||
struct hfsplus_fork {
|
||||
__u64 total_size;
|
||||
__u32 clump_size;
|
||||
__u32 total_blocks;
|
||||
struct hfsplus_extent extents[HFSPLUS_EXTENT_COUNT];
|
||||
} __attribute__((__packed__));
|
||||
|
||||
struct hfsplus_vol_header {
|
||||
__u8 signature[2];
|
||||
__u16 version;
|
||||
__u32 attributes;
|
||||
__u32 last_mount_vers;
|
||||
__u32 reserved;
|
||||
__u32 create_date;
|
||||
__u32 modify_date;
|
||||
__u32 backup_date;
|
||||
__u32 checked_date;
|
||||
__u32 file_count;
|
||||
__u32 folder_count;
|
||||
__u32 blocksize;
|
||||
__u32 total_blocks;
|
||||
__u32 free_blocks;
|
||||
__u32 next_alloc;
|
||||
__u32 rsrc_clump_sz;
|
||||
__u32 data_clump_sz;
|
||||
__u32 next_cnid;
|
||||
__u32 write_count;
|
||||
__u64 encodings_bmp;
|
||||
struct hfs_finder_info finder_info;
|
||||
struct hfsplus_fork alloc_file;
|
||||
struct hfsplus_fork ext_file;
|
||||
struct hfsplus_fork cat_file;
|
||||
struct hfsplus_fork attr_file;
|
||||
struct hfsplus_fork start_file;
|
||||
} __attribute__((__packed__)) *hfsplus;
|
||||
|
||||
unsigned int blocksize;
|
||||
unsigned int cat_block;
|
||||
unsigned int ext_block_start;
|
||||
unsigned int ext_block_count;
|
||||
int ext;
|
||||
unsigned int leaf_node_head;
|
||||
unsigned int leaf_node_count;
|
||||
unsigned int leaf_node_size;
|
||||
unsigned int leaf_block;
|
||||
__u64 leaf_off;
|
||||
unsigned int alloc_block_size;
|
||||
unsigned int alloc_first_block;
|
||||
unsigned int embed_first_block;
|
||||
unsigned int record_count;
|
||||
struct hfsplus_bnode_descriptor *descr;
|
||||
struct hfsplus_bheader_record *bnode;
|
||||
struct hfsplus_catalog_key *key;
|
||||
unsigned int label_len;
|
||||
struct hfsplus_extent extents[HFSPLUS_EXTENT_COUNT];
|
||||
const __u8 *buf;
|
||||
|
||||
buf = volume_id_get_buffer(id, off + HFS_SUPERBLOCK_OFFSET, 0x200);
|
||||
if (buf == NULL)
|
||||
return -1;
|
||||
|
||||
hfs = (struct hfs_mdb *) buf;
|
||||
if (strncmp(hfs->signature, "BD", 2) != 0)
|
||||
goto checkplus;
|
||||
|
||||
/* it may be just a hfs wrapper for hfs+ */
|
||||
if (strncmp(hfs->embed_sig, "H+", 2) == 0) {
|
||||
alloc_block_size = be32_to_cpu(hfs->al_blk_size);
|
||||
dbg("alloc_block_size 0x%x", alloc_block_size);
|
||||
|
||||
alloc_first_block = be16_to_cpu(hfs->al_bl_st);
|
||||
dbg("alloc_first_block 0x%x", alloc_first_block);
|
||||
|
||||
embed_first_block = be16_to_cpu(hfs->embed_startblock);
|
||||
dbg("embed_first_block 0x%x", embed_first_block);
|
||||
|
||||
off += (alloc_first_block * 512) +
|
||||
(embed_first_block * alloc_block_size);
|
||||
dbg("hfs wrapped hfs+ found at offset 0x%llx", off);
|
||||
|
||||
buf = volume_id_get_buffer(id, off + HFS_SUPERBLOCK_OFFSET, 0x200);
|
||||
if (buf == NULL)
|
||||
return -1;
|
||||
goto checkplus;
|
||||
}
|
||||
|
||||
if (hfs->label_len > 0 && hfs->label_len < 28) {
|
||||
volume_id_set_label_raw(id, hfs->label, hfs->label_len);
|
||||
volume_id_set_label_string(id, hfs->label, hfs->label_len) ;
|
||||
}
|
||||
|
||||
volume_id_set_uuid(id, hfs->finder_info.id, UUID_HFS);
|
||||
|
||||
volume_id_set_usage(id, VOLUME_ID_FILESYSTEM);
|
||||
id->type = "hfs";
|
||||
|
||||
return 0;
|
||||
|
||||
checkplus:
|
||||
hfsplus = (struct hfsplus_vol_header *) buf;
|
||||
if (strncmp(hfsplus->signature, "H+", 2) == 0)
|
||||
goto hfsplus;
|
||||
if (strncmp(hfsplus->signature, "HX", 2) == 0)
|
||||
goto hfsplus;
|
||||
return -1;
|
||||
|
||||
hfsplus:
|
||||
volume_id_set_uuid(id, hfsplus->finder_info.id, UUID_HFS);
|
||||
|
||||
blocksize = be32_to_cpu(hfsplus->blocksize);
|
||||
dbg("blocksize %u", blocksize);
|
||||
|
||||
memcpy(extents, hfsplus->cat_file.extents, sizeof(extents));
|
||||
cat_block = be32_to_cpu(extents[0].start_block);
|
||||
dbg("catalog start block 0x%x", cat_block);
|
||||
|
||||
buf = volume_id_get_buffer(id, off + (cat_block * blocksize), 0x2000);
|
||||
if (buf == NULL)
|
||||
goto found;
|
||||
|
||||
bnode = (struct hfsplus_bheader_record *)
|
||||
&buf[sizeof(struct hfsplus_bnode_descriptor)];
|
||||
|
||||
leaf_node_head = be32_to_cpu(bnode->leaf_head);
|
||||
dbg("catalog leaf node 0x%x", leaf_node_head);
|
||||
|
||||
leaf_node_size = be16_to_cpu(bnode->node_size);
|
||||
dbg("leaf node size 0x%x", leaf_node_size);
|
||||
|
||||
leaf_node_count = be32_to_cpu(bnode->leaf_count);
|
||||
dbg("leaf node count 0x%x", leaf_node_count);
|
||||
if (leaf_node_count == 0)
|
||||
goto found;
|
||||
|
||||
leaf_block = (leaf_node_head * leaf_node_size) / blocksize;
|
||||
|
||||
/* get physical location */
|
||||
for (ext = 0; ext < HFSPLUS_EXTENT_COUNT; ext++) {
|
||||
ext_block_start = be32_to_cpu(extents[ext].start_block);
|
||||
ext_block_count = be32_to_cpu(extents[ext].block_count);
|
||||
dbg("extent start block 0x%x, count 0x%x", ext_block_start, ext_block_count);
|
||||
|
||||
if (ext_block_count == 0)
|
||||
goto found;
|
||||
|
||||
/* this is our extent */
|
||||
if (leaf_block < ext_block_count)
|
||||
break;
|
||||
|
||||
leaf_block -= ext_block_count;
|
||||
}
|
||||
if (ext == HFSPLUS_EXTENT_COUNT)
|
||||
goto found;
|
||||
dbg("found block in extent %i", ext);
|
||||
|
||||
leaf_off = (ext_block_start + leaf_block) * blocksize;
|
||||
|
||||
buf = volume_id_get_buffer(id, off + leaf_off, leaf_node_size);
|
||||
if (buf == NULL)
|
||||
goto found;
|
||||
|
||||
descr = (struct hfsplus_bnode_descriptor *) buf;
|
||||
dbg("descriptor type 0x%x", descr->type);
|
||||
|
||||
record_count = be16_to_cpu(descr->num_recs);
|
||||
dbg("number of records %u", record_count);
|
||||
if (record_count == 0)
|
||||
goto found;
|
||||
|
||||
if (descr->type != HFS_NODE_LEAF)
|
||||
goto found;
|
||||
|
||||
key = (struct hfsplus_catalog_key *)
|
||||
&buf[sizeof(struct hfsplus_bnode_descriptor)];
|
||||
|
||||
dbg("parent id 0x%x", be32_to_cpu(key->parent_id));
|
||||
if (be32_to_cpu(key->parent_id) != HFSPLUS_POR_CNID)
|
||||
goto found;
|
||||
|
||||
label_len = be16_to_cpu(key->unicode_len) * 2;
|
||||
dbg("label unicode16 len %i", label_len);
|
||||
volume_id_set_label_raw(id, key->unicode, label_len);
|
||||
volume_id_set_label_unicode16(id, key->unicode, BE, label_len);
|
||||
|
||||
found:
|
||||
volume_id_set_usage(id, VOLUME_ID_FILESYSTEM);
|
||||
id->type = "hfsplus";
|
||||
|
||||
return 0;
|
||||
}
|
26
extras/volume_id/volume_id/hfs/hfs.h
Normal file
26
extras/volume_id/volume_id/hfs/hfs.h
Normal file
@ -0,0 +1,26 @@
|
||||
/*
|
||||
* volume_id - reads filesystem label and uuid
|
||||
*
|
||||
* Copyright (C) 2004 Kay Sievers <kay.sievers@vrfy.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef _VOLUME_ID_HFS_
|
||||
#define _VOLUME_ID_HFS_
|
||||
|
||||
extern int volume_id_probe_hfs_hfsplus(struct volume_id *id, __u64 off);
|
||||
|
||||
#endif
|
70
extras/volume_id/volume_id/highpoint/highpoint.c
Normal file
70
extras/volume_id/volume_id/highpoint/highpoint.c
Normal file
@ -0,0 +1,70 @@
|
||||
/*
|
||||
* volume_id - reads filesystem label and uuid
|
||||
*
|
||||
* Copyright (C) 2004 Kay Sievers <kay.sievers@vrfy.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef _GNU_SOURCE
|
||||
#define _GNU_SOURCE 1
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <ctype.h>
|
||||
#include <asm/types.h>
|
||||
|
||||
#include "../volume_id.h"
|
||||
#include "../logging.h"
|
||||
#include "../util.h"
|
||||
#include "highpoint.h"
|
||||
|
||||
#define HPT37X_CONFIG_OFF 0x1200
|
||||
#define HPT37X_MAGIC_OK 0x5a7816f0
|
||||
#define HPT37X_MAGIC_BAD 0x5a7816fd
|
||||
|
||||
int volume_id_probe_highpoint_ataraid(struct volume_id *id, __u64 off)
|
||||
{
|
||||
struct hpt37x {
|
||||
__u8 filler1[32];
|
||||
__u32 magic;
|
||||
__u32 magic_0;
|
||||
__u32 magic_1;
|
||||
} __attribute__((packed)) *hpt;
|
||||
|
||||
const __u8 *buf;
|
||||
|
||||
buf = volume_id_get_buffer(id, off + HPT37X_CONFIG_OFF, 0x200);
|
||||
if (buf == NULL)
|
||||
return -1;
|
||||
|
||||
hpt = (struct hpt37x *) buf;
|
||||
|
||||
if (hpt->magic != HPT37X_MAGIC_OK && hpt->magic != HPT37X_MAGIC_BAD)
|
||||
return -1;
|
||||
|
||||
volume_id_set_usage(id, VOLUME_ID_RAID);
|
||||
id->type = "hpt_ataraid_member";
|
||||
|
||||
return 0;
|
||||
}
|
26
extras/volume_id/volume_id/highpoint/highpoint.h
Normal file
26
extras/volume_id/volume_id/highpoint/highpoint.h
Normal file
@ -0,0 +1,26 @@
|
||||
/*
|
||||
* volume_id - reads filesystem label and uuid
|
||||
*
|
||||
* Copyright (C) 2004 Kay Sievers <kay.sievers@vrfy.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef _VOLUME_ID_HIGHPOINT_
|
||||
#define _VOLUME_ID_HIGHPOINT_
|
||||
|
||||
extern int volume_id_probe_highpoint_ataraid(struct volume_id *id, __u64 off);
|
||||
|
||||
#endif
|
115
extras/volume_id/volume_id/iso9660/iso9660.c
Normal file
115
extras/volume_id/volume_id/iso9660/iso9660.c
Normal file
@ -0,0 +1,115 @@
|
||||
/*
|
||||
* volume_id - reads filesystem label and uuid
|
||||
*
|
||||
* Copyright (C) 2004 Kay Sievers <kay.sievers@vrfy.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef _GNU_SOURCE
|
||||
#define _GNU_SOURCE 1
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <ctype.h>
|
||||
#include <asm/types.h>
|
||||
|
||||
#include "../volume_id.h"
|
||||
#include "../logging.h"
|
||||
#include "../util.h"
|
||||
#include "iso9660.h"
|
||||
|
||||
#define ISO_SUPERBLOCK_OFFSET 0x8000
|
||||
#define ISO_SECTOR_SIZE 0x800
|
||||
#define ISO_VD_OFFSET (ISO_SUPERBLOCK_OFFSET + ISO_SECTOR_SIZE)
|
||||
#define ISO_VD_PRIMARY 0x1
|
||||
#define ISO_VD_SUPPLEMENTARY 0x2
|
||||
#define ISO_VD_END 0xff
|
||||
#define ISO_VD_MAX 16
|
||||
|
||||
int volume_id_probe_iso9660(struct volume_id *id, __u64 off)
|
||||
{
|
||||
union iso_super_block {
|
||||
struct iso_header {
|
||||
__u8 type;
|
||||
__u8 id[5];
|
||||
__u8 version;
|
||||
__u8 unused1;
|
||||
__u8 system_id[32];
|
||||
__u8 volume_id[32];
|
||||
} __attribute__((__packed__)) iso;
|
||||
struct hs_header {
|
||||
__u8 foo[8];
|
||||
__u8 type;
|
||||
__u8 id[4];
|
||||
__u8 version;
|
||||
} __attribute__((__packed__)) hs;
|
||||
} __attribute__((__packed__)) *is;
|
||||
|
||||
is = (union iso_super_block *) volume_id_get_buffer(id, off + ISO_SUPERBLOCK_OFFSET, 0x200);
|
||||
if (is == NULL)
|
||||
return -1;
|
||||
|
||||
if (strncmp(is->iso.id, "CD001", 5) == 0) {
|
||||
char root_label[VOLUME_ID_LABEL_SIZE+1];
|
||||
int vd_offset;
|
||||
int i;
|
||||
int found_svd;
|
||||
|
||||
memset(root_label, 0, sizeof(root_label));
|
||||
strncpy(root_label, is->iso.volume_id, sizeof(root_label)-1);
|
||||
|
||||
found_svd = 0;
|
||||
vd_offset = ISO_VD_OFFSET;
|
||||
for (i = 0; i < ISO_VD_MAX; i++) {
|
||||
is = (union iso_super_block *) volume_id_get_buffer(id, off + vd_offset, 0x200);
|
||||
if (is == NULL || is->iso.type == ISO_VD_END)
|
||||
break;
|
||||
if (is->iso.type == ISO_VD_SUPPLEMENTARY) {
|
||||
dbg("found ISO supplementary VD at offset 0x%llx", off + vd_offset);
|
||||
volume_id_set_label_raw(id, is->iso.volume_id, 32);
|
||||
volume_id_set_label_unicode16(id, is->iso.volume_id, BE, 32);
|
||||
found_svd = 1;
|
||||
break;
|
||||
}
|
||||
vd_offset += ISO_SECTOR_SIZE;
|
||||
}
|
||||
|
||||
if (!found_svd ||
|
||||
(found_svd && !strncmp(root_label, id->label, 16)))
|
||||
{
|
||||
volume_id_set_label_raw(id, root_label, 32);
|
||||
volume_id_set_label_string(id, root_label, 32);
|
||||
}
|
||||
goto found;
|
||||
}
|
||||
if (strncmp(is->hs.id, "CDROM", 5) == 0)
|
||||
goto found;
|
||||
return -1;
|
||||
|
||||
found:
|
||||
volume_id_set_usage(id, VOLUME_ID_FILESYSTEM);
|
||||
id->type = "iso9660";
|
||||
|
||||
return 0;
|
||||
}
|
26
extras/volume_id/volume_id/iso9660/iso9660.h
Normal file
26
extras/volume_id/volume_id/iso9660/iso9660.h
Normal file
@ -0,0 +1,26 @@
|
||||
/*
|
||||
* volume_id - reads filesystem label and uuid
|
||||
*
|
||||
* Copyright (C) 2004 Kay Sievers <kay.sievers@vrfy.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef _VOLUME_ID_ISO9660_
|
||||
#define _VOLUME_ID_ISO9660_
|
||||
|
||||
extern int volume_id_probe_iso9660(struct volume_id *id, __u64 off);
|
||||
|
||||
#endif
|
74
extras/volume_id/volume_id/jfs/jfs.c
Normal file
74
extras/volume_id/volume_id/jfs/jfs.c
Normal file
@ -0,0 +1,74 @@
|
||||
/*
|
||||
* volume_id - reads filesystem label and uuid
|
||||
*
|
||||
* Copyright (C) 2004 Kay Sievers <kay.sievers@vrfy.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef _GNU_SOURCE
|
||||
#define _GNU_SOURCE 1
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <ctype.h>
|
||||
#include <asm/types.h>
|
||||
|
||||
#include "../volume_id.h"
|
||||
#include "../logging.h"
|
||||
#include "../util.h"
|
||||
#include "jfs.h"
|
||||
|
||||
#define JFS_SUPERBLOCK_OFFSET 0x8000
|
||||
|
||||
int volume_id_probe_jfs(struct volume_id *id, __u64 off)
|
||||
{
|
||||
struct jfs_super_block {
|
||||
__u8 magic[4];
|
||||
__u32 version;
|
||||
__u64 size;
|
||||
__u32 bsize;
|
||||
__u32 dummy1;
|
||||
__u32 pbsize;
|
||||
__u32 dummy2[27];
|
||||
__u8 uuid[16];
|
||||
__u8 label[16];
|
||||
__u8 loguuid[16];
|
||||
} __attribute__((__packed__)) *js;
|
||||
|
||||
js = (struct jfs_super_block *) volume_id_get_buffer(id, off + JFS_SUPERBLOCK_OFFSET, 0x200);
|
||||
if (js == NULL)
|
||||
return -1;
|
||||
|
||||
if (strncmp(js->magic, "JFS1", 4) != 0)
|
||||
return -1;
|
||||
|
||||
volume_id_set_label_raw(id, js->label, 16);
|
||||
volume_id_set_label_string(id, js->label, 16);
|
||||
volume_id_set_uuid(id, js->uuid, UUID_DCE);
|
||||
|
||||
volume_id_set_usage(id, VOLUME_ID_FILESYSTEM);
|
||||
id->type = "jfs";
|
||||
|
||||
return 0;
|
||||
}
|
26
extras/volume_id/volume_id/jfs/jfs.h
Normal file
26
extras/volume_id/volume_id/jfs/jfs.h
Normal file
@ -0,0 +1,26 @@
|
||||
/*
|
||||
* volume_id - reads filesystem label and uuid
|
||||
*
|
||||
* Copyright (C) 2004 Kay Sievers <kay.sievers@vrfy.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef _VOLUME_ID_JFS_
|
||||
#define _VOLUME_ID_JFS_
|
||||
|
||||
extern int volume_id_probe_jfs(struct volume_id *id, __u64 off);
|
||||
|
||||
#endif
|
97
extras/volume_id/volume_id/linux_raid/linux_raid.c
Normal file
97
extras/volume_id/volume_id/linux_raid/linux_raid.c
Normal file
@ -0,0 +1,97 @@
|
||||
/*
|
||||
* volume_id - reads filesystem label and uuid
|
||||
*
|
||||
* Copyright (C) 2004 Kay Sievers <kay.sievers@vrfy.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef _GNU_SOURCE
|
||||
#define _GNU_SOURCE 1
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <ctype.h>
|
||||
#include <asm/types.h>
|
||||
|
||||
#include "../volume_id.h"
|
||||
#include "../logging.h"
|
||||
#include "../util.h"
|
||||
#include "linux_raid.h"
|
||||
|
||||
#define MD_RESERVED_BYTES 0x10000
|
||||
#define MD_MAGIC 0xa92b4efc
|
||||
|
||||
int volume_id_probe_linux_raid(struct volume_id *id, __u64 off, __u64 size)
|
||||
{
|
||||
struct mdp_super_block {
|
||||
__u32 md_magic;
|
||||
__u32 major_version;
|
||||
__u32 minor_version;
|
||||
__u32 patch_version;
|
||||
__u32 gvalid_words;
|
||||
__u32 set_uuid0;
|
||||
__u32 ctime;
|
||||
__u32 level;
|
||||
__u32 size;
|
||||
__u32 nr_disks;
|
||||
__u32 raid_disks;
|
||||
__u32 md_minor;
|
||||
__u32 not_persistent;
|
||||
__u32 set_uuid1;
|
||||
__u32 set_uuid2;
|
||||
__u32 set_uuid3;
|
||||
} __attribute__((packed)) *mdp;
|
||||
|
||||
const __u8 *buf;
|
||||
__u64 sboff;
|
||||
__u8 uuid[16];
|
||||
|
||||
if (size < 0x10000)
|
||||
return -1;
|
||||
|
||||
sboff = (size & ~(MD_RESERVED_BYTES - 1)) - MD_RESERVED_BYTES;
|
||||
buf = volume_id_get_buffer(id, off + sboff, 0x800);
|
||||
if (buf == NULL)
|
||||
return -1;
|
||||
|
||||
mdp = (struct mdp_super_block *) buf;
|
||||
|
||||
if (le32_to_cpu(mdp->md_magic) != MD_MAGIC)
|
||||
return -1;
|
||||
|
||||
memcpy(uuid, &mdp->set_uuid0, 4);
|
||||
memcpy(&uuid[4], &mdp->set_uuid1, 12);
|
||||
volume_id_set_uuid(id, uuid, UUID_DCE);
|
||||
|
||||
snprintf(id->type_version, VOLUME_ID_FORMAT_SIZE-1, "%u.%u.%u",
|
||||
le32_to_cpu(mdp->major_version),
|
||||
le32_to_cpu(mdp->minor_version),
|
||||
le32_to_cpu(mdp->patch_version));
|
||||
|
||||
dbg("found raid signature");
|
||||
volume_id_set_usage(id, VOLUME_ID_RAID);
|
||||
id->type = "linux_raid_member";
|
||||
|
||||
return 0;
|
||||
}
|
26
extras/volume_id/volume_id/linux_raid/linux_raid.h
Normal file
26
extras/volume_id/volume_id/linux_raid/linux_raid.h
Normal file
@ -0,0 +1,26 @@
|
||||
/*
|
||||
* volume_id - reads filesystem label and uuid
|
||||
*
|
||||
* Copyright (C) 2004 Kay Sievers <kay.sievers@vrfy.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef _VOLUME_ID_LINUX_RAID_
|
||||
#define _VOLUME_ID_LINUX_RAID_
|
||||
|
||||
extern int volume_id_probe_linux_raid(struct volume_id *id, __u64 off, __u64 size);
|
||||
|
||||
#endif
|
87
extras/volume_id/volume_id/linux_swap/linux_swap.c
Normal file
87
extras/volume_id/volume_id/linux_swap/linux_swap.c
Normal file
@ -0,0 +1,87 @@
|
||||
/*
|
||||
* volume_id - reads filesystem label and uuid
|
||||
*
|
||||
* Copyright (C) 2004 Kay Sievers <kay.sievers@vrfy.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef _GNU_SOURCE
|
||||
#define _GNU_SOURCE 1
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <ctype.h>
|
||||
#include <asm/types.h>
|
||||
|
||||
#include "../volume_id.h"
|
||||
#include "../logging.h"
|
||||
#include "../util.h"
|
||||
#include "linux_swap.h"
|
||||
|
||||
#define LARGEST_PAGESIZE 0x4000
|
||||
|
||||
int volume_id_probe_linux_swap(struct volume_id *id, __u64 off)
|
||||
{
|
||||
struct swap_header_v1_2 {
|
||||
__u8 bootbits[1024];
|
||||
__u32 version;
|
||||
__u32 last_page;
|
||||
__u32 nr_badpages;
|
||||
__u8 uuid[16];
|
||||
__u8 volume_name[16];
|
||||
} __attribute__((__packed__)) *sw;
|
||||
|
||||
const __u8 *buf;
|
||||
unsigned int page;
|
||||
|
||||
/* the swap signature is at the end of the PAGE_SIZE */
|
||||
for (page = 0x1000; page <= LARGEST_PAGESIZE; page <<= 1) {
|
||||
buf = volume_id_get_buffer(id, off + page-10, 10);
|
||||
if (buf == NULL)
|
||||
return -1;
|
||||
|
||||
if (strncmp(buf, "SWAP-SPACE", 10) == 0) {
|
||||
strcpy(id->type_version, "1");
|
||||
goto found;
|
||||
}
|
||||
|
||||
if (strncmp(buf, "SWAPSPACE2", 10) == 0) {
|
||||
sw = (struct swap_header_v1_2 *) volume_id_get_buffer(id, off, sizeof(struct swap_header_v1_2));
|
||||
if (sw == NULL)
|
||||
return -1;
|
||||
strcpy(id->type_version, "2");
|
||||
volume_id_set_label_raw(id, sw->volume_name, 16);
|
||||
volume_id_set_label_string(id, sw->volume_name, 16);
|
||||
volume_id_set_uuid(id, sw->uuid, UUID_DCE);
|
||||
goto found;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
|
||||
found:
|
||||
volume_id_set_usage(id, VOLUME_ID_OTHER);
|
||||
id->type = "swap";
|
||||
|
||||
return 0;
|
||||
}
|
26
extras/volume_id/volume_id/linux_swap/linux_swap.h
Normal file
26
extras/volume_id/volume_id/linux_swap/linux_swap.h
Normal file
@ -0,0 +1,26 @@
|
||||
/*
|
||||
* volume_id - reads filesystem label and uuid
|
||||
*
|
||||
* Copyright (C) 2004 Kay Sievers <kay.sievers@vrfy.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef _VOLUME_ID_LINUX_SWAP_
|
||||
#define _VOLUME_ID_LINUX_SWAP_
|
||||
|
||||
extern int volume_id_probe_linux_swap(struct volume_id *id, __u64 off);
|
||||
|
||||
#endif
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* volume_id_logging - this file is used to map the dbg() function
|
||||
* to the host logging facility
|
||||
* to the user's logging facility
|
||||
*
|
||||
*/
|
||||
|
||||
@ -15,7 +15,7 @@
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
/* just use the udev version*/
|
||||
/* just use the udev version */
|
||||
#include "../../logging.h"
|
||||
|
||||
#endif /* _VOLUME_ID_LOGGING_H_ */
|
104
extras/volume_id/volume_id/lvm/lvm.c
Normal file
104
extras/volume_id/volume_id/lvm/lvm.c
Normal file
@ -0,0 +1,104 @@
|
||||
/*
|
||||
* volume_id - reads filesystem label and uuid
|
||||
*
|
||||
* Copyright (C) 2004 Kay Sievers <kay.sievers@vrfy.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef _GNU_SOURCE
|
||||
#define _GNU_SOURCE 1
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <ctype.h>
|
||||
#include <asm/types.h>
|
||||
|
||||
#include "../volume_id.h"
|
||||
#include "../logging.h"
|
||||
#include "../util.h"
|
||||
#include "lvm.h"
|
||||
|
||||
#define LVM1_SB_OFF 0x400
|
||||
#define LVM1_MAGIC "HM"
|
||||
|
||||
int volume_id_probe_lvm1(struct volume_id *id, __u64 off)
|
||||
{
|
||||
struct lvm2_super_block {
|
||||
__u8 id[2];
|
||||
} __attribute__((packed)) *lvm;
|
||||
|
||||
const __u8 *buf;
|
||||
|
||||
buf = volume_id_get_buffer(id, off + LVM1_SB_OFF, 0x800);
|
||||
if (buf == NULL)
|
||||
return -1;
|
||||
|
||||
lvm = (struct lvm2_super_block *) buf;
|
||||
|
||||
if (strncmp(lvm->id, LVM1_MAGIC, 2) != 0)
|
||||
return -1;
|
||||
|
||||
volume_id_set_usage(id, VOLUME_ID_RAID);
|
||||
id->type = "LVM1_member";
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define LVM2_LABEL_ID "LABELONE"
|
||||
#define LVM2LABEL_SCAN_SECTORS 4
|
||||
|
||||
int volume_id_probe_lvm2(struct volume_id *id, __u64 off)
|
||||
{
|
||||
struct lvm2_super_block {
|
||||
__u8 id[8];
|
||||
__u64 sector_xl;
|
||||
__u32 crc_xl;
|
||||
__u32 offset_xl;
|
||||
__u8 type[8];
|
||||
} __attribute__((packed)) *lvm;
|
||||
|
||||
const __u8 *buf;
|
||||
unsigned int soff;
|
||||
|
||||
buf = volume_id_get_buffer(id, off, LVM2LABEL_SCAN_SECTORS * 0x200);
|
||||
if (buf == NULL)
|
||||
return -1;
|
||||
|
||||
|
||||
for (soff = 0; soff < LVM2LABEL_SCAN_SECTORS * 0x200; soff += 0x200) {
|
||||
lvm = (struct lvm2_super_block *) &buf[soff];
|
||||
|
||||
if (strncmp(lvm->id, LVM2_LABEL_ID, 8) == 0)
|
||||
goto found;
|
||||
}
|
||||
|
||||
return -1;
|
||||
|
||||
found:
|
||||
strncpy(id->type_version, lvm->type, 8);
|
||||
volume_id_set_usage(id, VOLUME_ID_RAID);
|
||||
id->type = "LVM2_member";
|
||||
|
||||
return 0;
|
||||
}
|
27
extras/volume_id/volume_id/lvm/lvm.h
Normal file
27
extras/volume_id/volume_id/lvm/lvm.h
Normal file
@ -0,0 +1,27 @@
|
||||
/*
|
||||
* volume_id - reads filesystem label and uuid
|
||||
*
|
||||
* Copyright (C) 2004 Kay Sievers <kay.sievers@vrfy.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef _VOLUME_ID_LVM_
|
||||
#define _VOLUME_ID_LVM_
|
||||
|
||||
extern int volume_id_probe_lvm1(struct volume_id *id, __u64 off);
|
||||
extern int volume_id_probe_lvm2(struct volume_id *id, __u64 off);
|
||||
|
||||
#endif
|
140
extras/volume_id/volume_id/mac/mac.c
Normal file
140
extras/volume_id/volume_id/mac/mac.c
Normal file
@ -0,0 +1,140 @@
|
||||
/*
|
||||
* volume_id - reads filesystem label and uuid
|
||||
*
|
||||
* Copyright (C) 2004 Kay Sievers <kay.sievers@vrfy.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef _GNU_SOURCE
|
||||
#define _GNU_SOURCE 1
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <ctype.h>
|
||||
#include <asm/types.h>
|
||||
|
||||
#include "../volume_id.h"
|
||||
#include "../logging.h"
|
||||
#include "../util.h"
|
||||
#include "mac.h"
|
||||
|
||||
int volume_id_probe_mac_partition_map(struct volume_id *id, __u64 off)
|
||||
{
|
||||
struct mac_driver_desc {
|
||||
__u8 signature[2];
|
||||
__u16 block_size;
|
||||
__u32 block_count;
|
||||
} __attribute__((__packed__)) *driver;
|
||||
|
||||
struct mac_partition {
|
||||
__u8 signature[2];
|
||||
__u16 res1;
|
||||
__u32 map_count;
|
||||
__u32 start_block;
|
||||
__u32 block_count;
|
||||
__u8 name[32];
|
||||
__u8 type[32];
|
||||
} __attribute__((__packed__)) *part;
|
||||
|
||||
const __u8 *buf;
|
||||
|
||||
buf = volume_id_get_buffer(id, off, 0x200);
|
||||
if (buf == NULL)
|
||||
return -1;
|
||||
|
||||
part = (struct mac_partition *) buf;
|
||||
if ((strncmp(part->signature, "PM", 2) == 0) &&
|
||||
(strncmp(part->type, "Apple_partition_map", 19) == 0)) {
|
||||
/* linux creates an own subdevice for the map
|
||||
* just return the type if the drive header is missing */
|
||||
volume_id_set_usage(id, VOLUME_ID_PARTITIONTABLE);
|
||||
id->type = "mac_partition_map";
|
||||
return 0;
|
||||
}
|
||||
|
||||
driver = (struct mac_driver_desc *) buf;
|
||||
if (strncmp(driver->signature, "ER", 2) == 0) {
|
||||
/* we are on a main device, like a CD
|
||||
* just try to probe the first partition from the map */
|
||||
unsigned int bsize = be16_to_cpu(driver->block_size);
|
||||
int part_count;
|
||||
int i;
|
||||
|
||||
/* get first entry of partition table */
|
||||
buf = volume_id_get_buffer(id, off + bsize, 0x200);
|
||||
if (buf == NULL)
|
||||
return -1;
|
||||
|
||||
part = (struct mac_partition *) buf;
|
||||
if (strncmp(part->signature, "PM", 2) != 0)
|
||||
return -1;
|
||||
|
||||
part_count = be32_to_cpu(part->map_count);
|
||||
dbg("expecting %d partition entries", part_count);
|
||||
|
||||
if (id->partitions != NULL)
|
||||
free(id->partitions);
|
||||
id->partitions =
|
||||
malloc(part_count * sizeof(struct volume_id_partition));
|
||||
if (id->partitions == NULL)
|
||||
return -1;
|
||||
memset(id->partitions, 0x00, sizeof(struct volume_id_partition));
|
||||
|
||||
id->partition_count = part_count;
|
||||
|
||||
for (i = 0; i < part_count; i++) {
|
||||
__u64 poff;
|
||||
__u64 plen;
|
||||
|
||||
buf = volume_id_get_buffer(id, off + ((i+1) * bsize), 0x200);
|
||||
if (buf == NULL)
|
||||
return -1;
|
||||
|
||||
part = (struct mac_partition *) buf;
|
||||
if (strncmp(part->signature, "PM", 2) != 0)
|
||||
return -1;
|
||||
|
||||
poff = be32_to_cpu(part->start_block) * bsize;
|
||||
plen = be32_to_cpu(part->block_count) * bsize;
|
||||
dbg("found '%s' partition entry at 0x%llx, len 0x%llx",
|
||||
part->type, poff, plen);
|
||||
|
||||
id->partitions[i].off = poff;
|
||||
id->partitions[i].len = plen;
|
||||
|
||||
if (strncmp(part->type, "Apple_Free", 10) == 0) {
|
||||
volume_id_set_usage_part(&id->partitions[i], VOLUME_ID_UNUSED);
|
||||
} else if (strncmp(part->type, "Apple_partition_map", 19) == 0) {
|
||||
volume_id_set_usage_part(&id->partitions[i], VOLUME_ID_PARTITIONTABLE);
|
||||
} else {
|
||||
volume_id_set_usage_part(&id->partitions[i], VOLUME_ID_UNPROBED);
|
||||
}
|
||||
}
|
||||
volume_id_set_usage(id, VOLUME_ID_PARTITIONTABLE);
|
||||
id->type = "mac_partition_map";
|
||||
return 0;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
26
extras/volume_id/volume_id/mac/mac.h
Normal file
26
extras/volume_id/volume_id/mac/mac.h
Normal file
@ -0,0 +1,26 @@
|
||||
/*
|
||||
* volume_id - reads filesystem label and uuid
|
||||
*
|
||||
* Copyright (C) 2004 Kay Sievers <kay.sievers@vrfy.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef _VOLUME_ID_MAC_
|
||||
#define _VOLUME_ID_MAC_
|
||||
|
||||
extern int volume_id_probe_mac_partition_map(struct volume_id *id, __u64 off);
|
||||
|
||||
#endif
|
212
extras/volume_id/volume_id/msdos/msdos.c
Normal file
212
extras/volume_id/volume_id/msdos/msdos.c
Normal file
@ -0,0 +1,212 @@
|
||||
/*
|
||||
* volume_id - reads filesystem label and uuid
|
||||
*
|
||||
* Copyright (C) 2004 Kay Sievers <kay.sievers@vrfy.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef _GNU_SOURCE
|
||||
#define _GNU_SOURCE 1
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <ctype.h>
|
||||
#include <asm/types.h>
|
||||
|
||||
#include "../volume_id.h"
|
||||
#include "../logging.h"
|
||||
#include "../util.h"
|
||||
#include "msdos.h"
|
||||
|
||||
#define MSDOS_MAGIC "\x55\xaa"
|
||||
#define MSDOS_PARTTABLE_OFFSET 0x1be
|
||||
#define MSDOS_SIG_OFF 0x1fe
|
||||
#define BSIZE 0x200
|
||||
#define DOS_EXTENDED_PARTITION 0x05
|
||||
#define LINUX_EXTENDED_PARTITION 0x85
|
||||
#define WIN98_EXTENDED_PARTITION 0x0f
|
||||
#define LINUX_RAID_PARTITION 0xfd
|
||||
#define is_extended(type) \
|
||||
(type == DOS_EXTENDED_PARTITION || \
|
||||
type == WIN98_EXTENDED_PARTITION || \
|
||||
type == LINUX_EXTENDED_PARTITION)
|
||||
#define is_raid(type) \
|
||||
(type == LINUX_RAID_PARTITION)
|
||||
|
||||
int volume_id_probe_msdos_part_table(struct volume_id *id, __u64 off)
|
||||
{
|
||||
struct msdos_partition_entry {
|
||||
__u8 boot_ind;
|
||||
__u8 head;
|
||||
__u8 sector;
|
||||
__u8 cyl;
|
||||
__u8 sys_ind;
|
||||
__u8 end_head;
|
||||
__u8 end_sector;
|
||||
__u8 end_cyl;
|
||||
__u32 start_sect;
|
||||
__u32 nr_sects;
|
||||
} __attribute__((packed)) *part;
|
||||
|
||||
const __u8 *buf;
|
||||
int i;
|
||||
__u64 poff;
|
||||
__u64 plen;
|
||||
__u64 extended = 0;
|
||||
__u64 current;
|
||||
__u64 next;
|
||||
int limit;
|
||||
int empty = 1;
|
||||
struct volume_id_partition *p;
|
||||
|
||||
buf = volume_id_get_buffer(id, off, 0x200);
|
||||
if (buf == NULL)
|
||||
return -1;
|
||||
|
||||
if (strncmp(&buf[MSDOS_SIG_OFF], MSDOS_MAGIC, 2) != 0)
|
||||
return -1;
|
||||
|
||||
/* check flags on all entries for a valid partition table */
|
||||
part = (struct msdos_partition_entry*) &buf[MSDOS_PARTTABLE_OFFSET];
|
||||
for (i = 0; i < 4; i++) {
|
||||
if (part[i].boot_ind != 0 &&
|
||||
part[i].boot_ind != 0x80)
|
||||
return -1;
|
||||
|
||||
if (le32_to_cpu(part[i].nr_sects) != 0)
|
||||
empty = 0;
|
||||
}
|
||||
if (empty == 1)
|
||||
return -1;
|
||||
|
||||
if (id->partitions != NULL)
|
||||
free(id->partitions);
|
||||
id->partitions = malloc(VOLUME_ID_PARTITIONS_MAX *
|
||||
sizeof(struct volume_id_partition));
|
||||
if (id->partitions == NULL)
|
||||
return -1;
|
||||
memset(id->partitions, 0x00,
|
||||
VOLUME_ID_PARTITIONS_MAX * sizeof(struct volume_id_partition));
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
poff = (__u64) le32_to_cpu(part[i].start_sect) * BSIZE;
|
||||
plen = (__u64) le32_to_cpu(part[i].nr_sects) * BSIZE;
|
||||
|
||||
if (plen == 0)
|
||||
continue;
|
||||
|
||||
p = &id->partitions[i];
|
||||
|
||||
p->partition_type_raw = part[i].sys_ind;
|
||||
|
||||
if (is_extended(part[i].sys_ind)) {
|
||||
dbg("found extended partition at 0x%llx", poff);
|
||||
volume_id_set_usage_part(p, VOLUME_ID_PARTITIONTABLE);
|
||||
p->type = "msdos_extended_partition";
|
||||
if (extended == 0)
|
||||
extended = off + poff;
|
||||
} else {
|
||||
dbg("found 0x%x data partition at 0x%llx, len 0x%llx",
|
||||
part[i].sys_ind, poff, plen);
|
||||
|
||||
if (is_raid(part[i].sys_ind))
|
||||
volume_id_set_usage_part(p, VOLUME_ID_RAID);
|
||||
else
|
||||
volume_id_set_usage_part(p, VOLUME_ID_UNPROBED);
|
||||
}
|
||||
|
||||
p->off = off + poff;
|
||||
p->len = plen;
|
||||
id->partition_count = i+1;
|
||||
}
|
||||
|
||||
next = extended;
|
||||
current = extended;
|
||||
limit = 50;
|
||||
|
||||
/* follow extended partition chain and add data partitions */
|
||||
while (next != 0) {
|
||||
if (limit-- == 0) {
|
||||
dbg("extended chain limit reached");
|
||||
break;
|
||||
}
|
||||
|
||||
buf = volume_id_get_buffer(id, current, 0x200);
|
||||
if (buf == NULL)
|
||||
break;
|
||||
|
||||
part = (struct msdos_partition_entry*) &buf[MSDOS_PARTTABLE_OFFSET];
|
||||
|
||||
if (strncmp(&buf[MSDOS_SIG_OFF], MSDOS_MAGIC, 2) != 0)
|
||||
break;
|
||||
|
||||
next = 0;
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
poff = (__u64) le32_to_cpu(part[i].start_sect) * BSIZE;
|
||||
plen = (__u64) le32_to_cpu(part[i].nr_sects) * BSIZE;
|
||||
|
||||
if (plen == 0)
|
||||
continue;
|
||||
|
||||
if (is_extended(part[i].sys_ind)) {
|
||||
dbg("found extended partition at 0x%llx", poff);
|
||||
if (next == 0)
|
||||
next = extended + poff;
|
||||
} else {
|
||||
dbg("found 0x%x data partition at 0x%llx, len 0x%llx",
|
||||
part[i].sys_ind, poff, plen);
|
||||
|
||||
/* we always start at the 5th entry */
|
||||
while (id->partition_count < 4)
|
||||
volume_id_set_usage_part(&id->partitions[id->partition_count++], VOLUME_ID_UNUSED);
|
||||
|
||||
p = &id->partitions[id->partition_count];
|
||||
|
||||
if (is_raid(part[i].sys_ind))
|
||||
volume_id_set_usage_part(p, VOLUME_ID_RAID);
|
||||
else
|
||||
volume_id_set_usage_part(p, VOLUME_ID_UNPROBED);
|
||||
|
||||
p->off = current + poff;
|
||||
p->len = plen;
|
||||
id->partition_count++;
|
||||
|
||||
p->partition_type_raw = part[i].sys_ind;
|
||||
|
||||
if (id->partition_count >= VOLUME_ID_PARTITIONS_MAX) {
|
||||
dbg("too many partitions");
|
||||
next = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
current = next;
|
||||
}
|
||||
|
||||
volume_id_set_usage(id, VOLUME_ID_PARTITIONTABLE);
|
||||
id->type = "msdos_partition_table";
|
||||
|
||||
return 0;
|
||||
}
|
26
extras/volume_id/volume_id/msdos/msdos.h
Normal file
26
extras/volume_id/volume_id/msdos/msdos.h
Normal file
@ -0,0 +1,26 @@
|
||||
/*
|
||||
* volume_id - reads filesystem label and uuid
|
||||
*
|
||||
* Copyright (C) 2004 Kay Sievers <kay.sievers@vrfy.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef _VOLUME_ID_MSDOS_
|
||||
#define _VOLUME_ID_MSDOS_
|
||||
|
||||
extern int volume_id_probe_msdos_part_table(struct volume_id *id, __u64 off);
|
||||
|
||||
#endif
|
205
extras/volume_id/volume_id/ntfs/ntfs.c
Normal file
205
extras/volume_id/volume_id/ntfs/ntfs.c
Normal file
@ -0,0 +1,205 @@
|
||||
/*
|
||||
* volume_id - reads filesystem label and uuid
|
||||
*
|
||||
* Copyright (C) 2004 Kay Sievers <kay.sievers@vrfy.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef _GNU_SOURCE
|
||||
#define _GNU_SOURCE 1
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <ctype.h>
|
||||
#include <asm/types.h>
|
||||
|
||||
#include "../volume_id.h"
|
||||
#include "../logging.h"
|
||||
#include "../util.h"
|
||||
#include "ntfs.h"
|
||||
|
||||
#define MFT_RECORD_VOLUME 3
|
||||
#define MFT_RECORD_ATTR_VOLUME_NAME 0x60
|
||||
#define MFT_RECORD_ATTR_VOLUME_INFO 0x70
|
||||
#define MFT_RECORD_ATTR_OBJECT_ID 0x40
|
||||
#define MFT_RECORD_ATTR_END 0xffffffffu
|
||||
|
||||
int volume_id_probe_ntfs(struct volume_id *id, __u64 off)
|
||||
{
|
||||
struct ntfs_super_block {
|
||||
__u8 jump[3];
|
||||
__u8 oem_id[8];
|
||||
__u16 bytes_per_sector;
|
||||
__u8 sectors_per_cluster;
|
||||
__u16 reserved_sectors;
|
||||
__u8 fats;
|
||||
__u16 root_entries;
|
||||
__u16 sectors;
|
||||
__u8 media_type;
|
||||
__u16 sectors_per_fat;
|
||||
__u16 sectors_per_track;
|
||||
__u16 heads;
|
||||
__u32 hidden_sectors;
|
||||
__u32 large_sectors;
|
||||
__u16 unused[2];
|
||||
__u64 number_of_sectors;
|
||||
__u64 mft_cluster_location;
|
||||
__u64 mft_mirror_cluster_location;
|
||||
__s8 cluster_per_mft_record;
|
||||
__u8 reserved1[3];
|
||||
__s8 cluster_per_index_record;
|
||||
__u8 reserved2[3];
|
||||
__u8 volume_serial[8];
|
||||
__u16 checksum;
|
||||
} __attribute__((__packed__)) *ns;
|
||||
|
||||
struct master_file_table_record {
|
||||
__u8 magic[4];
|
||||
__u16 usa_ofs;
|
||||
__u16 usa_count;
|
||||
__u64 lsn;
|
||||
__u16 sequence_number;
|
||||
__u16 link_count;
|
||||
__u16 attrs_offset;
|
||||
__u16 flags;
|
||||
__u32 bytes_in_use;
|
||||
__u32 bytes_allocated;
|
||||
} __attribute__((__packed__)) *mftr;
|
||||
|
||||
struct file_attribute {
|
||||
__u32 type;
|
||||
__u32 len;
|
||||
__u8 non_resident;
|
||||
__u8 name_len;
|
||||
__u16 name_offset;
|
||||
__u16 flags;
|
||||
__u16 instance;
|
||||
__u32 value_len;
|
||||
__u16 value_offset;
|
||||
} __attribute__((__packed__)) *attr;
|
||||
|
||||
struct volume_info {
|
||||
__u64 reserved;
|
||||
__u8 major_ver;
|
||||
__u8 minor_ver;
|
||||
} __attribute__((__packed__)) *info;
|
||||
|
||||
unsigned int sector_size;
|
||||
unsigned int cluster_size;
|
||||
__u64 mft_cluster;
|
||||
__u64 mft_off;
|
||||
unsigned int mft_record_size;
|
||||
unsigned int attr_type;
|
||||
unsigned int attr_off;
|
||||
unsigned int attr_len;
|
||||
unsigned int val_off;
|
||||
unsigned int val_len;
|
||||
const __u8 *buf;
|
||||
const __u8 *val;
|
||||
|
||||
ns = (struct ntfs_super_block *) volume_id_get_buffer(id, off, 0x200);
|
||||
if (ns == NULL)
|
||||
return -1;
|
||||
|
||||
if (strncmp(ns->oem_id, "NTFS", 4) != 0)
|
||||
return -1;
|
||||
|
||||
volume_id_set_uuid(id, ns->volume_serial, UUID_NTFS);
|
||||
|
||||
sector_size = le16_to_cpu(ns->bytes_per_sector);
|
||||
cluster_size = ns->sectors_per_cluster * sector_size;
|
||||
mft_cluster = le64_to_cpu(ns->mft_cluster_location);
|
||||
mft_off = mft_cluster * cluster_size;
|
||||
|
||||
if (ns->cluster_per_mft_record < 0)
|
||||
/* size = -log2(mft_record_size); normally 1024 Bytes */
|
||||
mft_record_size = 1 << -ns->cluster_per_mft_record;
|
||||
else
|
||||
mft_record_size = ns->cluster_per_mft_record * cluster_size;
|
||||
|
||||
dbg("sectorsize 0x%x", sector_size);
|
||||
dbg("clustersize 0x%x", cluster_size);
|
||||
dbg("mftcluster %lli", mft_cluster);
|
||||
dbg("mftoffset 0x%llx", mft_off);
|
||||
dbg("cluster per mft_record %i", ns->cluster_per_mft_record);
|
||||
dbg("mft record size %i", mft_record_size);
|
||||
|
||||
buf = volume_id_get_buffer(id, off + mft_off + (MFT_RECORD_VOLUME * mft_record_size),
|
||||
mft_record_size);
|
||||
if (buf == NULL)
|
||||
goto found;
|
||||
|
||||
mftr = (struct master_file_table_record*) buf;
|
||||
|
||||
dbg("mftr->magic '%c%c%c%c'", mftr->magic[0], mftr->magic[1], mftr->magic[2], mftr->magic[3]);
|
||||
if (strncmp(mftr->magic, "FILE", 4) != 0)
|
||||
goto found;
|
||||
|
||||
attr_off = le16_to_cpu(mftr->attrs_offset);
|
||||
dbg("file $Volume's attributes are at offset %i", attr_off);
|
||||
|
||||
while (1) {
|
||||
attr = (struct file_attribute*) &buf[attr_off];
|
||||
attr_type = le32_to_cpu(attr->type);
|
||||
attr_len = le16_to_cpu(attr->len);
|
||||
val_off = le16_to_cpu(attr->value_offset);
|
||||
val_len = le32_to_cpu(attr->value_len);
|
||||
attr_off += attr_len;
|
||||
|
||||
if (attr_len == 0)
|
||||
break;
|
||||
|
||||
if (attr_off >= mft_record_size)
|
||||
break;
|
||||
|
||||
if (attr_type == MFT_RECORD_ATTR_END)
|
||||
break;
|
||||
|
||||
dbg("found attribute type 0x%x, len %i, at offset %i",
|
||||
attr_type, attr_len, attr_off);
|
||||
|
||||
if (attr_type == MFT_RECORD_ATTR_VOLUME_INFO) {
|
||||
dbg("found info, len %i", val_len);
|
||||
info = (struct volume_info*) (((__u8 *) attr) + val_off);
|
||||
snprintf(id->type_version, VOLUME_ID_FORMAT_SIZE-1,
|
||||
"%u.%u", info->major_ver, info->minor_ver);
|
||||
}
|
||||
|
||||
if (attr_type == MFT_RECORD_ATTR_VOLUME_NAME) {
|
||||
dbg("found label, len %i", val_len);
|
||||
if (val_len > VOLUME_ID_LABEL_SIZE)
|
||||
val_len = VOLUME_ID_LABEL_SIZE;
|
||||
|
||||
val = ((__u8 *) attr) + val_off;
|
||||
volume_id_set_label_raw(id, val, val_len);
|
||||
volume_id_set_label_unicode16(id, val, LE, val_len);
|
||||
}
|
||||
}
|
||||
|
||||
found:
|
||||
volume_id_set_usage(id, VOLUME_ID_FILESYSTEM);
|
||||
id->type = "ntfs";
|
||||
|
||||
return 0;
|
||||
}
|
26
extras/volume_id/volume_id/ntfs/ntfs.h
Normal file
26
extras/volume_id/volume_id/ntfs/ntfs.h
Normal file
@ -0,0 +1,26 @@
|
||||
/*
|
||||
* volume_id - reads filesystem label and uuid
|
||||
*
|
||||
* Copyright (C) 2004 Kay Sievers <kay.sievers@vrfy.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef _VOLUME_ID_NTFS_
|
||||
#define _VOLUME_ID_NTFS_
|
||||
|
||||
extern int volume_id_probe_ntfs(struct volume_id *id, __u64 off);
|
||||
|
||||
#endif
|
97
extras/volume_id/volume_id/reiserfs/reiserfs.c
Normal file
97
extras/volume_id/volume_id/reiserfs/reiserfs.c
Normal file
@ -0,0 +1,97 @@
|
||||
/*
|
||||
* volume_id - reads filesystem label and uuid
|
||||
*
|
||||
* Copyright (C) 2004 Kay Sievers <kay.sievers@vrfy.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef _GNU_SOURCE
|
||||
#define _GNU_SOURCE 1
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <ctype.h>
|
||||
#include <asm/types.h>
|
||||
|
||||
#include "../volume_id.h"
|
||||
#include "../logging.h"
|
||||
#include "../util.h"
|
||||
#include "reiserfs.h"
|
||||
|
||||
#define REISERFS1_SUPERBLOCK_OFFSET 0x2000
|
||||
#define REISERFS_SUPERBLOCK_OFFSET 0x10000
|
||||
|
||||
int volume_id_probe_reiserfs(struct volume_id *id, __u64 off)
|
||||
{
|
||||
struct reiserfs_super_block {
|
||||
__u32 blocks_count;
|
||||
__u32 free_blocks;
|
||||
__u32 root_block;
|
||||
__u32 journal_block;
|
||||
__u32 journal_dev;
|
||||
__u32 orig_journal_size;
|
||||
__u32 dummy2[5];
|
||||
__u16 blocksize;
|
||||
__u16 dummy3[3];
|
||||
__u8 magic[12];
|
||||
__u32 dummy4[5];
|
||||
__u8 uuid[16];
|
||||
__u8 label[16];
|
||||
} __attribute__((__packed__)) *rs;
|
||||
|
||||
rs = (struct reiserfs_super_block *) volume_id_get_buffer(id, off + REISERFS_SUPERBLOCK_OFFSET, 0x200);
|
||||
if (rs == NULL)
|
||||
return -1;
|
||||
|
||||
if (strncmp(rs->magic, "ReIsEr2Fs", 9) == 0) {
|
||||
strcpy(id->type_version, "3.6");
|
||||
goto found;
|
||||
}
|
||||
|
||||
if (strncmp(rs->magic, "ReIsEr3Fs", 9) == 0) {
|
||||
strcpy(id->type_version, "JR");
|
||||
goto found;
|
||||
}
|
||||
|
||||
rs = (struct reiserfs_super_block *) volume_id_get_buffer(id, off + REISERFS1_SUPERBLOCK_OFFSET, 0x200);
|
||||
if (rs == NULL)
|
||||
return -1;
|
||||
|
||||
if (strncmp(rs->magic, "ReIsErFs", 8) == 0) {
|
||||
strcpy(id->type_version, "3.5");
|
||||
goto found;
|
||||
}
|
||||
|
||||
return -1;
|
||||
|
||||
found:
|
||||
volume_id_set_label_raw(id, rs->label, 16);
|
||||
volume_id_set_label_string(id, rs->label, 16);
|
||||
volume_id_set_uuid(id, rs->uuid, UUID_DCE);
|
||||
|
||||
volume_id_set_usage(id, VOLUME_ID_FILESYSTEM);
|
||||
id->type = "reiserfs";
|
||||
|
||||
return 0;
|
||||
}
|
26
extras/volume_id/volume_id/reiserfs/reiserfs.h
Normal file
26
extras/volume_id/volume_id/reiserfs/reiserfs.h
Normal file
@ -0,0 +1,26 @@
|
||||
/*
|
||||
* volume_id - reads filesystem label and uuid
|
||||
*
|
||||
* Copyright (C) 2004 Kay Sievers <kay.sievers@vrfy.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef _VOLUME_ID_REISERFS_
|
||||
#define _VOLUME_ID_REISERFS_
|
||||
|
||||
extern int volume_id_probe_reiserfs(struct volume_id *id, __u64 off);
|
||||
|
||||
#endif
|
187
extras/volume_id/volume_id/udf/udf.c
Normal file
187
extras/volume_id/volume_id/udf/udf.c
Normal file
@ -0,0 +1,187 @@
|
||||
/*
|
||||
* volume_id - reads filesystem label and uuid
|
||||
*
|
||||
* Copyright (C) 2004 Kay Sievers <kay.sievers@vrfy.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef _GNU_SOURCE
|
||||
#define _GNU_SOURCE 1
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <ctype.h>
|
||||
#include <asm/types.h>
|
||||
|
||||
#include "../volume_id.h"
|
||||
#include "../logging.h"
|
||||
#include "../util.h"
|
||||
#include "udf.h"
|
||||
|
||||
#define UDF_VSD_OFFSET 0x8000
|
||||
|
||||
int volume_id_probe_udf(struct volume_id *id, __u64 off)
|
||||
{
|
||||
struct volume_descriptor {
|
||||
struct descriptor_tag {
|
||||
__u16 id;
|
||||
__u16 version;
|
||||
__u8 checksum;
|
||||
__u8 reserved;
|
||||
__u16 serial;
|
||||
__u16 crc;
|
||||
__u16 crc_len;
|
||||
__u32 location;
|
||||
} __attribute__((__packed__)) tag;
|
||||
union {
|
||||
struct anchor_descriptor {
|
||||
__u32 length;
|
||||
__u32 location;
|
||||
} __attribute__((__packed__)) anchor;
|
||||
struct primary_descriptor {
|
||||
__u32 seq_num;
|
||||
__u32 desc_num;
|
||||
struct dstring {
|
||||
__u8 clen;
|
||||
__u8 c[31];
|
||||
} __attribute__((__packed__)) ident;
|
||||
} __attribute__((__packed__)) primary;
|
||||
} __attribute__((__packed__)) type;
|
||||
} __attribute__((__packed__)) *vd;
|
||||
|
||||
struct volume_structure_descriptor {
|
||||
__u8 type;
|
||||
__u8 id[5];
|
||||
__u8 version;
|
||||
} *vsd;
|
||||
|
||||
unsigned int bs;
|
||||
unsigned int b;
|
||||
unsigned int type;
|
||||
unsigned int count;
|
||||
unsigned int loc;
|
||||
unsigned int clen;
|
||||
|
||||
vsd = (struct volume_structure_descriptor *) volume_id_get_buffer(id, off + UDF_VSD_OFFSET, 0x200);
|
||||
if (vsd == NULL)
|
||||
return -1;
|
||||
|
||||
if (strncmp(vsd->id, "NSR02", 5) == 0)
|
||||
goto blocksize;
|
||||
if (strncmp(vsd->id, "NSR03", 5) == 0)
|
||||
goto blocksize;
|
||||
if (strncmp(vsd->id, "BEA01", 5) == 0)
|
||||
goto blocksize;
|
||||
if (strncmp(vsd->id, "BOOT2", 5) == 0)
|
||||
goto blocksize;
|
||||
if (strncmp(vsd->id, "CD001", 5) == 0)
|
||||
goto blocksize;
|
||||
if (strncmp(vsd->id, "CDW02", 5) == 0)
|
||||
goto blocksize;
|
||||
if (strncmp(vsd->id, "TEA03", 5) == 0)
|
||||
goto blocksize;
|
||||
return -1;
|
||||
|
||||
blocksize:
|
||||
/* search the next VSD to get the logical block size of the volume */
|
||||
for (bs = 0x800; bs < 0x8000; bs += 0x800) {
|
||||
vsd = (struct volume_structure_descriptor *) volume_id_get_buffer(id, off + UDF_VSD_OFFSET + bs, 0x800);
|
||||
if (vsd == NULL)
|
||||
return -1;
|
||||
dbg("test for blocksize: 0x%x", bs);
|
||||
if (vsd->id[0] != '\0')
|
||||
goto nsr;
|
||||
}
|
||||
return -1;
|
||||
|
||||
nsr:
|
||||
/* search the list of VSDs for a NSR descriptor */
|
||||
for (b = 0; b < 64; b++) {
|
||||
vsd = (struct volume_structure_descriptor *) volume_id_get_buffer(id, off + UDF_VSD_OFFSET + (b * bs), 0x800);
|
||||
if (vsd == NULL)
|
||||
return -1;
|
||||
|
||||
dbg("vsd: %c%c%c%c%c",
|
||||
vsd->id[0], vsd->id[1], vsd->id[2], vsd->id[3], vsd->id[4]);
|
||||
|
||||
if (vsd->id[0] == '\0')
|
||||
return -1;
|
||||
if (strncmp(vsd->id, "NSR02", 5) == 0)
|
||||
goto anchor;
|
||||
if (strncmp(vsd->id, "NSR03", 5) == 0)
|
||||
goto anchor;
|
||||
}
|
||||
return -1;
|
||||
|
||||
anchor:
|
||||
/* read anchor volume descriptor */
|
||||
vd = (struct volume_descriptor *) volume_id_get_buffer(id, off + (256 * bs), 0x200);
|
||||
if (vd == NULL)
|
||||
return -1;
|
||||
|
||||
type = le16_to_cpu(vd->tag.id);
|
||||
if (type != 2) /* TAG_ID_AVDP */
|
||||
goto found;
|
||||
|
||||
/* get desriptor list address and block count */
|
||||
count = le32_to_cpu(vd->type.anchor.length) / bs;
|
||||
loc = le32_to_cpu(vd->type.anchor.location);
|
||||
dbg("0x%x descriptors starting at logical secor 0x%x", count, loc);
|
||||
|
||||
/* pick the primary descriptor from the list */
|
||||
for (b = 0; b < count; b++) {
|
||||
vd = (struct volume_descriptor *) volume_id_get_buffer(id, off + ((loc + b) * bs), 0x200);
|
||||
if (vd == NULL)
|
||||
return -1;
|
||||
|
||||
type = le16_to_cpu(vd->tag.id);
|
||||
dbg("descriptor type %i", type);
|
||||
|
||||
/* check validity */
|
||||
if (type == 0)
|
||||
goto found;
|
||||
if (le32_to_cpu(vd->tag.location) != loc + b)
|
||||
goto found;
|
||||
|
||||
if (type == 1) /* TAG_ID_PVD */
|
||||
goto pvd;
|
||||
}
|
||||
goto found;
|
||||
|
||||
pvd:
|
||||
volume_id_set_label_raw(id, &(vd->type.primary.ident.clen), 32);
|
||||
|
||||
clen = vd->type.primary.ident.clen;
|
||||
dbg("label string charsize=%i bit", clen);
|
||||
if (clen == 8)
|
||||
volume_id_set_label_string(id, vd->type.primary.ident.c, 31);
|
||||
else if (clen == 16)
|
||||
volume_id_set_label_unicode16(id, vd->type.primary.ident.c, BE,31);
|
||||
|
||||
found:
|
||||
volume_id_set_usage(id, VOLUME_ID_FILESYSTEM);
|
||||
id->type = "udf";
|
||||
|
||||
return 0;
|
||||
}
|
26
extras/volume_id/volume_id/udf/udf.h
Normal file
26
extras/volume_id/volume_id/udf/udf.h
Normal file
@ -0,0 +1,26 @@
|
||||
/*
|
||||
* volume_id - reads filesystem label and uuid
|
||||
*
|
||||
* Copyright (C) 2004 Kay Sievers <kay.sievers@vrfy.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef _VOLUME_ID_UDF_
|
||||
#define _VOLUME_ID_UDF_
|
||||
|
||||
extern int volume_id_probe_udf(struct volume_id *id, __u64 off);
|
||||
|
||||
#endif
|
220
extras/volume_id/volume_id/ufs/ufs.c
Normal file
220
extras/volume_id/volume_id/ufs/ufs.c
Normal file
@ -0,0 +1,220 @@
|
||||
/*
|
||||
* volume_id - reads filesystem label and uuid
|
||||
*
|
||||
* Copyright (C) 2004 Kay Sievers <kay.sievers@vrfy.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef _GNU_SOURCE
|
||||
#define _GNU_SOURCE 1
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <ctype.h>
|
||||
#include <asm/types.h>
|
||||
|
||||
#include "../volume_id.h"
|
||||
#include "../logging.h"
|
||||
#include "../util.h"
|
||||
#include "ufs.h"
|
||||
|
||||
#define UFS_MAGIC 0x00011954
|
||||
#define UFS2_MAGIC 0x19540119
|
||||
#define UFS_MAGIC_FEA 0x00195612
|
||||
#define UFS_MAGIC_LFN 0x00095014
|
||||
|
||||
int volume_id_probe_ufs(struct volume_id *id, __u64 off)
|
||||
{
|
||||
struct ufs_super_block {
|
||||
__u32 fs_link;
|
||||
__u32 fs_rlink;
|
||||
__u32 fs_sblkno;
|
||||
__u32 fs_cblkno;
|
||||
__u32 fs_iblkno;
|
||||
__u32 fs_dblkno;
|
||||
__u32 fs_cgoffset;
|
||||
__u32 fs_cgmask;
|
||||
__u32 fs_time;
|
||||
__u32 fs_size;
|
||||
__u32 fs_dsize;
|
||||
__u32 fs_ncg;
|
||||
__u32 fs_bsize;
|
||||
__u32 fs_fsize;
|
||||
__u32 fs_frag;
|
||||
__u32 fs_minfree;
|
||||
__u32 fs_rotdelay;
|
||||
__u32 fs_rps;
|
||||
__u32 fs_bmask;
|
||||
__u32 fs_fmask;
|
||||
__u32 fs_bshift;
|
||||
__u32 fs_fshift;
|
||||
__u32 fs_maxcontig;
|
||||
__u32 fs_maxbpg;
|
||||
__u32 fs_fragshift;
|
||||
__u32 fs_fsbtodb;
|
||||
__u32 fs_sbsize;
|
||||
__u32 fs_csmask;
|
||||
__u32 fs_csshift;
|
||||
__u32 fs_nindir;
|
||||
__u32 fs_inopb;
|
||||
__u32 fs_nspf;
|
||||
__u32 fs_optim;
|
||||
__u32 fs_npsect_state;
|
||||
__u32 fs_interleave;
|
||||
__u32 fs_trackskew;
|
||||
__u32 fs_id[2];
|
||||
__u32 fs_csaddr;
|
||||
__u32 fs_cssize;
|
||||
__u32 fs_cgsize;
|
||||
__u32 fs_ntrak;
|
||||
__u32 fs_nsect;
|
||||
__u32 fs_spc;
|
||||
__u32 fs_ncyl;
|
||||
__u32 fs_cpg;
|
||||
__u32 fs_ipg;
|
||||
__u32 fs_fpg;
|
||||
struct ufs_csum {
|
||||
__u32 cs_ndir;
|
||||
__u32 cs_nbfree;
|
||||
__u32 cs_nifree;
|
||||
__u32 cs_nffree;
|
||||
} __attribute__((__packed__)) fs_cstotal;
|
||||
__s8 fs_fmod;
|
||||
__s8 fs_clean;
|
||||
__s8 fs_ronly;
|
||||
__s8 fs_flags;
|
||||
union {
|
||||
struct {
|
||||
__s8 fs_fsmnt[512];
|
||||
__u32 fs_cgrotor;
|
||||
__u32 fs_csp[31];
|
||||
__u32 fs_maxcluster;
|
||||
__u32 fs_cpc;
|
||||
__u16 fs_opostbl[16][8];
|
||||
} __attribute__((__packed__)) fs_u1;
|
||||
struct {
|
||||
__s8 fs_fsmnt[468];
|
||||
__u8 fs_volname[32];
|
||||
__u64 fs_swuid;
|
||||
__s32 fs_pad;
|
||||
__u32 fs_cgrotor;
|
||||
__u32 fs_ocsp[28];
|
||||
__u32 fs_contigdirs;
|
||||
__u32 fs_csp;
|
||||
__u32 fs_maxcluster;
|
||||
__u32 fs_active;
|
||||
__s32 fs_old_cpc;
|
||||
__s32 fs_maxbsize;
|
||||
__s64 fs_sparecon64[17];
|
||||
__s64 fs_sblockloc;
|
||||
struct ufs2_csum_total {
|
||||
__u64 cs_ndir;
|
||||
__u64 cs_nbfree;
|
||||
__u64 cs_nifree;
|
||||
__u64 cs_nffree;
|
||||
__u64 cs_numclusters;
|
||||
__u64 cs_spare[3];
|
||||
} __attribute__((__packed__)) fs_cstotal;
|
||||
struct ufs_timeval {
|
||||
__s32 tv_sec;
|
||||
__s32 tv_usec;
|
||||
} __attribute__((__packed__)) fs_time;
|
||||
__s64 fs_size;
|
||||
__s64 fs_dsize;
|
||||
__u64 fs_csaddr;
|
||||
__s64 fs_pendingblocks;
|
||||
__s32 fs_pendinginodes;
|
||||
} __attribute__((__packed__)) fs_u2;
|
||||
} fs_u11;
|
||||
union {
|
||||
struct {
|
||||
__s32 fs_sparecon[53];
|
||||
__s32 fs_reclaim;
|
||||
__s32 fs_sparecon2[1];
|
||||
__s32 fs_state;
|
||||
__u32 fs_qbmask[2];
|
||||
__u32 fs_qfmask[2];
|
||||
} __attribute__((__packed__)) fs_sun;
|
||||
struct {
|
||||
__s32 fs_sparecon[53];
|
||||
__s32 fs_reclaim;
|
||||
__s32 fs_sparecon2[1];
|
||||
__u32 fs_npsect;
|
||||
__u32 fs_qbmask[2];
|
||||
__u32 fs_qfmask[2];
|
||||
} __attribute__((__packed__)) fs_sunx86;
|
||||
struct {
|
||||
__s32 fs_sparecon[50];
|
||||
__s32 fs_contigsumsize;
|
||||
__s32 fs_maxsymlinklen;
|
||||
__s32 fs_inodefmt;
|
||||
__u32 fs_maxfilesize[2];
|
||||
__u32 fs_qbmask[2];
|
||||
__u32 fs_qfmask[2];
|
||||
__s32 fs_state;
|
||||
} __attribute__((__packed__)) fs_44;
|
||||
} fs_u2;
|
||||
__s32 fs_postblformat;
|
||||
__s32 fs_nrpos;
|
||||
__s32 fs_postbloff;
|
||||
__s32 fs_rotbloff;
|
||||
__u32 fs_magic;
|
||||
__u8 fs_space[1];
|
||||
} __attribute__((__packed__)) *ufs;
|
||||
|
||||
__u32 magic;
|
||||
int i;
|
||||
int offsets[] = {0, 8, 64, 256, -1};
|
||||
|
||||
for (i = 0; offsets[i] >= 0; i++) {
|
||||
ufs = (struct ufs_super_block *) volume_id_get_buffer(id, off + (offsets[i] * 0x400), 0x800);
|
||||
if (ufs == NULL)
|
||||
return -1;
|
||||
|
||||
dbg("offset 0x%x", offsets[i] * 0x400);
|
||||
magic = be32_to_cpu(ufs->fs_magic);
|
||||
if ((magic == UFS_MAGIC) ||
|
||||
(magic == UFS2_MAGIC) ||
|
||||
(magic == UFS_MAGIC_FEA) ||
|
||||
(magic == UFS_MAGIC_LFN)) {
|
||||
dbg("magic 0x%08x(be)", magic);
|
||||
goto found;
|
||||
}
|
||||
magic = le32_to_cpu(ufs->fs_magic);
|
||||
if ((magic == UFS_MAGIC) ||
|
||||
(magic == UFS2_MAGIC) ||
|
||||
(magic == UFS_MAGIC_FEA) ||
|
||||
(magic == UFS_MAGIC_LFN)) {
|
||||
dbg("magic 0x%08x(le)", magic);
|
||||
goto found;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
|
||||
found:
|
||||
volume_id_set_usage(id, VOLUME_ID_FILESYSTEM);
|
||||
id->type = "ufs";
|
||||
|
||||
return 0;
|
||||
}
|
26
extras/volume_id/volume_id/ufs/ufs.h
Normal file
26
extras/volume_id/volume_id/ufs/ufs.h
Normal file
@ -0,0 +1,26 @@
|
||||
/*
|
||||
* volume_id - reads filesystem label and uuid
|
||||
*
|
||||
* Copyright (C) 2004 Kay Sievers <kay.sievers@vrfy.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef _VOLUME_ID_UFS_
|
||||
#define _VOLUME_ID_UFS_
|
||||
|
||||
extern int volume_id_probe_ufs(struct volume_id *id, __u64 off);
|
||||
|
||||
#endif
|
245
extras/volume_id/volume_id/util.c
Normal file
245
extras/volume_id/volume_id/util.c
Normal file
@ -0,0 +1,245 @@
|
||||
/*
|
||||
* volume_id - reads filesystem label and uuid
|
||||
*
|
||||
* Copyright (C) 2005 Kay Sievers <kay.sievers@vrfy.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef _GNU_SOURCE
|
||||
#define _GNU_SOURCE 1
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <ctype.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/stat.h>
|
||||
#include <asm/types.h>
|
||||
|
||||
#include "volume_id.h"
|
||||
#include "logging.h"
|
||||
#include "util.h"
|
||||
|
||||
static char *usage_to_string(enum volume_id_usage usage_id)
|
||||
{
|
||||
switch (usage_id) {
|
||||
case VOLUME_ID_FILESYSTEM:
|
||||
return "filesystem";
|
||||
case VOLUME_ID_PARTITIONTABLE:
|
||||
return "partitiontable";
|
||||
case VOLUME_ID_OTHER:
|
||||
return "other";
|
||||
case VOLUME_ID_RAID:
|
||||
return "raid";
|
||||
case VOLUME_ID_DISKLABEL:
|
||||
return "disklabel";
|
||||
case VOLUME_ID_UNPROBED:
|
||||
return "unprobed";
|
||||
case VOLUME_ID_UNUSED:
|
||||
return "unused";
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void volume_id_set_usage_part(struct volume_id_partition *part, enum volume_id_usage usage_id)
|
||||
{
|
||||
part->usage_id = usage_id;
|
||||
part->usage = usage_to_string(usage_id);
|
||||
}
|
||||
|
||||
void volume_id_set_usage(struct volume_id *id, enum volume_id_usage usage_id)
|
||||
{
|
||||
id->usage_id = usage_id;
|
||||
id->usage = usage_to_string(usage_id);
|
||||
}
|
||||
|
||||
void volume_id_set_label_raw(struct volume_id *id, const __u8 *buf, unsigned int count)
|
||||
{
|
||||
memcpy(id->label_raw, buf, count);
|
||||
id->label_raw_len = count;
|
||||
}
|
||||
|
||||
void volume_id_set_label_string(struct volume_id *id, const __u8 *buf, unsigned int count)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
memcpy(id->label, buf, count);
|
||||
|
||||
/* remove trailing whitespace */
|
||||
i = strnlen(id->label, count);
|
||||
while (i--) {
|
||||
if (!isspace(id->label[i]))
|
||||
break;
|
||||
}
|
||||
id->label[i+1] = '\0';
|
||||
}
|
||||
|
||||
void volume_id_set_label_unicode16(struct volume_id *id, const __u8 *buf, enum endian endianess, unsigned int count)
|
||||
{
|
||||
unsigned int i, j;
|
||||
__u16 c;
|
||||
|
||||
j = 0;
|
||||
for (i = 0; i + 2 <= count; i += 2) {
|
||||
if (endianess == LE)
|
||||
c = (buf[i+1] << 8) | buf[i];
|
||||
else
|
||||
c = (buf[i] << 8) | buf[i+1];
|
||||
if (c == 0) {
|
||||
id->label[j] = '\0';
|
||||
break;
|
||||
} else if (c < 0x80) {
|
||||
id->label[j++] = (__u8) c;
|
||||
} else if (c < 0x800) {
|
||||
id->label[j++] = (__u8) (0xc0 | (c >> 6));
|
||||
id->label[j++] = (__u8) (0x80 | (c & 0x3f));
|
||||
} else {
|
||||
id->label[j++] = (__u8) (0xe0 | (c >> 12));
|
||||
id->label[j++] = (__u8) (0x80 | ((c >> 6) & 0x3f));
|
||||
id->label[j++] = (__u8) (0x80 | (c & 0x3f));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void volume_id_set_uuid(struct volume_id *id, const __u8 *buf, enum uuid_format format)
|
||||
{
|
||||
unsigned int i;
|
||||
unsigned int count = 0;
|
||||
|
||||
switch(format) {
|
||||
case UUID_DOS:
|
||||
count = 4;
|
||||
break;
|
||||
case UUID_NTFS:
|
||||
case UUID_HFS:
|
||||
count = 8;
|
||||
break;
|
||||
case UUID_DCE:
|
||||
count = 16;
|
||||
}
|
||||
memcpy(id->uuid_raw, buf, count);
|
||||
|
||||
/* if set, create string in the same format, the native platform uses */
|
||||
for (i = 0; i < count; i++)
|
||||
if (buf[i] != 0)
|
||||
goto set;
|
||||
return;
|
||||
|
||||
set:
|
||||
switch(format) {
|
||||
case UUID_DOS:
|
||||
sprintf(id->uuid, "%02X%02X-%02X%02X",
|
||||
buf[3], buf[2], buf[1], buf[0]);
|
||||
break;
|
||||
case UUID_NTFS:
|
||||
sprintf(id->uuid,"%02X%02X%02X%02X%02X%02X%02X%02X",
|
||||
buf[7], buf[6], buf[5], buf[4],
|
||||
buf[3], buf[2], buf[1], buf[0]);
|
||||
break;
|
||||
case UUID_HFS:
|
||||
sprintf(id->uuid,"%02X%02X%02X%02X%02X%02X%02X%02X",
|
||||
buf[0], buf[1], buf[2], buf[3],
|
||||
buf[4], buf[5], buf[6], buf[7]);
|
||||
break;
|
||||
case UUID_DCE:
|
||||
sprintf(id->uuid,
|
||||
"%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x",
|
||||
buf[0], buf[1], buf[2], buf[3],
|
||||
buf[4], buf[5],
|
||||
buf[6], buf[7],
|
||||
buf[8], buf[9],
|
||||
buf[10], buf[11], buf[12], buf[13], buf[14],buf[15]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
__u8 *volume_id_get_buffer(struct volume_id *id, __u64 off, unsigned int len)
|
||||
{
|
||||
unsigned int buf_len;
|
||||
|
||||
dbg("get buffer off 0x%llx(%llu), len 0x%x", off, off, len);
|
||||
/* check if requested area fits in superblock buffer */
|
||||
if (off + len <= SB_BUFFER_SIZE) {
|
||||
if (id->sbbuf == NULL) {
|
||||
id->sbbuf = malloc(SB_BUFFER_SIZE);
|
||||
if (id->sbbuf == NULL)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* check if we need to read */
|
||||
if ((off + len) > id->sbbuf_len) {
|
||||
dbg("read sbbuf len:0x%llx", off + len);
|
||||
lseek(id->fd, 0, SEEK_SET);
|
||||
buf_len = read(id->fd, id->sbbuf, off + len);
|
||||
dbg("got 0x%x (%i) bytes", buf_len, buf_len);
|
||||
id->sbbuf_len = buf_len;
|
||||
if (buf_len < off + len)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return &(id->sbbuf[off]);
|
||||
} else {
|
||||
if (len > SEEK_BUFFER_SIZE) {
|
||||
dbg("seek buffer too small %d", SEEK_BUFFER_SIZE);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* get seek buffer */
|
||||
if (id->seekbuf == NULL) {
|
||||
id->seekbuf = malloc(SEEK_BUFFER_SIZE);
|
||||
if (id->seekbuf == NULL)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* check if we need to read */
|
||||
if ((off < id->seekbuf_off) || ((off + len) > (id->seekbuf_off + id->seekbuf_len))) {
|
||||
dbg("read seekbuf off:0x%llx len:0x%x", off, len);
|
||||
if (lseek(id->fd, off, SEEK_SET) == -1)
|
||||
return NULL;
|
||||
buf_len = read(id->fd, id->seekbuf, len);
|
||||
dbg("got 0x%x (%i) bytes", buf_len, buf_len);
|
||||
id->seekbuf_off = off;
|
||||
id->seekbuf_len = buf_len;
|
||||
if (buf_len < len) {
|
||||
dbg("requested 0x%x bytes, got only 0x%x bytes", len, buf_len);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return &(id->seekbuf[off - id->seekbuf_off]);
|
||||
}
|
||||
}
|
||||
|
||||
void volume_id_free_buffer(struct volume_id *id)
|
||||
{
|
||||
if (id->sbbuf != NULL) {
|
||||
free(id->sbbuf);
|
||||
id->sbbuf = NULL;
|
||||
id->sbbuf_len = 0;
|
||||
}
|
||||
if (id->seekbuf != NULL) {
|
||||
free(id->seekbuf);
|
||||
id->seekbuf = NULL;
|
||||
id->seekbuf_len = 0;
|
||||
}
|
||||
}
|
91
extras/volume_id/volume_id/util.h
Normal file
91
extras/volume_id/volume_id/util.h
Normal file
@ -0,0 +1,91 @@
|
||||
/*
|
||||
* volume_id - reads filesystem label and uuid
|
||||
*
|
||||
* Copyright (C) 2005 Kay Sievers <kay.sievers@vrfy.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef _VOLUME_ID_UTIL_
|
||||
#define _VOLUME_ID_UTIL_
|
||||
|
||||
#ifndef _GNU_SOURCE
|
||||
#define _GNU_SOURCE 1
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
/* size of superblock buffer, reiserfs block is at 64k */
|
||||
#define SB_BUFFER_SIZE 0x11000
|
||||
/* size of seek buffer, FAT cluster is 32k max */
|
||||
#define SEEK_BUFFER_SIZE 0x10000
|
||||
|
||||
/* probe volume for all known filesystems in specific order */
|
||||
#define bswap16(x) (__u16)((((__u16)(x) & 0x00ffu) << 8) | \
|
||||
(((__u16)(x) & 0xff00u) >> 8))
|
||||
|
||||
#define bswap32(x) (__u32)((((__u32)(x) & 0xff000000u) >> 24) | \
|
||||
(((__u32)(x) & 0x00ff0000u) >> 8) | \
|
||||
(((__u32)(x) & 0x0000ff00u) << 8) | \
|
||||
(((__u32)(x) & 0x000000ffu) << 24))
|
||||
|
||||
#define bswap64(x) (__u64)((((__u64)(x) & 0xff00000000000000ull) >> 56) | \
|
||||
(((__u64)(x) & 0x00ff000000000000ull) >> 40) | \
|
||||
(((__u64)(x) & 0x0000ff0000000000ull) >> 24) | \
|
||||
(((__u64)(x) & 0x000000ff00000000ull) >> 8) | \
|
||||
(((__u64)(x) & 0x00000000ff000000ull) << 8) | \
|
||||
(((__u64)(x) & 0x0000000000ff0000ull) << 24) | \
|
||||
(((__u64)(x) & 0x000000000000ff00ull) << 40) | \
|
||||
(((__u64)(x) & 0x00000000000000ffull) << 56))
|
||||
|
||||
#if (__BYTE_ORDER == __LITTLE_ENDIAN)
|
||||
#define le16_to_cpu(x) (x)
|
||||
#define le32_to_cpu(x) (x)
|
||||
#define le64_to_cpu(x) (x)
|
||||
#define be16_to_cpu(x) bswap16(x)
|
||||
#define be32_to_cpu(x) bswap32(x)
|
||||
#elif (__BYTE_ORDER == __BIG_ENDIAN)
|
||||
#define le16_to_cpu(x) bswap16(x)
|
||||
#define le32_to_cpu(x) bswap32(x)
|
||||
#define le64_to_cpu(x) bswap64(x)
|
||||
#define be16_to_cpu(x) (x)
|
||||
#define be32_to_cpu(x) (x)
|
||||
#endif
|
||||
|
||||
enum uuid_format {
|
||||
UUID_DCE,
|
||||
UUID_DOS,
|
||||
UUID_NTFS,
|
||||
UUID_HFS,
|
||||
};
|
||||
|
||||
enum endian {
|
||||
LE = 0,
|
||||
BE = 1
|
||||
};
|
||||
|
||||
extern void volume_id_set_usage(struct volume_id *id, enum volume_id_usage usage_id);
|
||||
extern void volume_id_set_usage_part(struct volume_id_partition *part, enum volume_id_usage usage_id);
|
||||
extern void volume_id_set_label_raw(struct volume_id *id, const __u8 *buf, unsigned int count);
|
||||
extern void volume_id_set_label_string(struct volume_id *id, const __u8 *buf, unsigned int count);
|
||||
extern void volume_id_set_label_unicode16(struct volume_id *id, const __u8 *buf, enum endian endianess, unsigned int count);
|
||||
extern void volume_id_set_uuid(struct volume_id *id, const __u8 *buf, enum uuid_format format);
|
||||
extern __u8 *volume_id_get_buffer(struct volume_id *id, __u64 off, unsigned int len);
|
||||
extern void volume_id_free_buffer(struct volume_id *id);
|
||||
|
||||
#endif /* _VOLUME_ID_UTIL_ */
|
||||
|
202
extras/volume_id/volume_id/volume_id.c
Normal file
202
extras/volume_id/volume_id/volume_id.c
Normal file
@ -0,0 +1,202 @@
|
||||
/*
|
||||
* volume_id - reads filesystem label and uuid
|
||||
*
|
||||
* Copyright (C) 2005 Kay Sievers <kay.sievers@vrfy.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef _GNU_SOURCE
|
||||
#define _GNU_SOURCE 1
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <errno.h>
|
||||
#include <ctype.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/stat.h>
|
||||
#include <asm/types.h>
|
||||
|
||||
#include "volume_id.h"
|
||||
#include "logging.h"
|
||||
#include "util.h"
|
||||
|
||||
#include "ext/ext.h"
|
||||
#include "reiserfs/reiserfs.h"
|
||||
#include "fat/fat.h"
|
||||
#include "hfs/hfs.h"
|
||||
#include "jfs/jfs.h"
|
||||
#include "xfs/xfs.h"
|
||||
#include "ufs/ufs.h"
|
||||
#include "ntfs/ntfs.h"
|
||||
#include "iso9660/iso9660.h"
|
||||
#include "udf/udf.h"
|
||||
#include "highpoint/highpoint.h"
|
||||
#include "linux_swap/linux_swap.h"
|
||||
#include "linux_raid/linux_raid.h"
|
||||
#include "lvm/lvm.h"
|
||||
#include "mac/mac.h"
|
||||
#include "msdos/msdos.h"
|
||||
|
||||
int volume_id_probe_all(struct volume_id *id, unsigned long long off, unsigned long long size)
|
||||
{
|
||||
if (id == NULL)
|
||||
return -EINVAL;
|
||||
|
||||
/* probe for raid first, cause fs probes may be successful on raid members */
|
||||
if (volume_id_probe_linux_raid(id, off, size) == 0)
|
||||
goto exit;
|
||||
|
||||
if (volume_id_probe_lvm1(id, off) == 0)
|
||||
goto exit;
|
||||
|
||||
if (volume_id_probe_lvm2(id, off) == 0)
|
||||
goto exit;
|
||||
|
||||
if (volume_id_probe_highpoint_ataraid(id, off) == 0)
|
||||
goto exit;
|
||||
|
||||
/* signature in the first block, only small buffer needed */
|
||||
if (volume_id_probe_vfat(id, off) == 0)
|
||||
goto exit;
|
||||
|
||||
if (volume_id_probe_mac_partition_map(id, off) == 0)
|
||||
goto exit;
|
||||
|
||||
if (volume_id_probe_xfs(id, off) == 0)
|
||||
goto exit;
|
||||
|
||||
/* fill buffer with maximum */
|
||||
volume_id_get_buffer(id, 0, SB_BUFFER_SIZE);
|
||||
|
||||
if (volume_id_probe_linux_swap(id, off) == 0)
|
||||
goto exit;
|
||||
|
||||
if (volume_id_probe_ext(id, off) == 0)
|
||||
goto exit;
|
||||
|
||||
if (volume_id_probe_reiserfs(id, off) == 0)
|
||||
goto exit;
|
||||
|
||||
if (volume_id_probe_jfs(id, off) == 0)
|
||||
goto exit;
|
||||
|
||||
if (volume_id_probe_udf(id, off) == 0)
|
||||
goto exit;
|
||||
|
||||
if (volume_id_probe_iso9660(id, off) == 0)
|
||||
goto exit;
|
||||
|
||||
if (volume_id_probe_hfs_hfsplus(id, off) == 0)
|
||||
goto exit;
|
||||
|
||||
if (volume_id_probe_ufs(id, off) == 0)
|
||||
goto exit;
|
||||
|
||||
if (volume_id_probe_ntfs(id, off) == 0)
|
||||
goto exit;
|
||||
|
||||
return -1;
|
||||
|
||||
exit:
|
||||
/* If the filestystem in recognized, we free the allocated buffers,
|
||||
otherwise they will stay in place for the possible next probe call */
|
||||
volume_id_free_buffer(id);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* open volume by already open file descriptor */
|
||||
struct volume_id *volume_id_open_fd(int fd)
|
||||
{
|
||||
struct volume_id *id;
|
||||
|
||||
id = malloc(sizeof(struct volume_id));
|
||||
if (id == NULL)
|
||||
return NULL;
|
||||
memset(id, 0x00, sizeof(struct volume_id));
|
||||
|
||||
id->fd = fd;
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
/* open volume by device node */
|
||||
struct volume_id *volume_id_open_node(const char *path)
|
||||
{
|
||||
struct volume_id *id;
|
||||
int fd;
|
||||
|
||||
fd = open(path, O_RDONLY);
|
||||
if (fd < 0) {
|
||||
dbg("unable to open '%s'", path);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
id = volume_id_open_fd(fd);
|
||||
if (id == NULL)
|
||||
return NULL;
|
||||
|
||||
/* close fd on device close */
|
||||
id->fd_close = 1;
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
/* open volume by major/minor */
|
||||
struct volume_id *volume_id_open_dev_t(dev_t devt)
|
||||
{
|
||||
struct volume_id *id;
|
||||
__u8 tmp_node[VOLUME_ID_PATH_MAX];
|
||||
|
||||
snprintf(tmp_node, VOLUME_ID_PATH_MAX,
|
||||
"/dev/.volume_id-%u-%u-%u", getpid(), major(devt), minor(devt));
|
||||
tmp_node[VOLUME_ID_PATH_MAX] = '\0';
|
||||
|
||||
/* create tempory node to open the block device */
|
||||
unlink(tmp_node);
|
||||
if (mknod(tmp_node, (S_IFBLK | 0600), devt) != 0)
|
||||
return NULL;
|
||||
|
||||
id = volume_id_open_node(tmp_node);
|
||||
|
||||
unlink(tmp_node);
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
void volume_id_close(struct volume_id *id)
|
||||
{
|
||||
if (id == NULL)
|
||||
return;
|
||||
|
||||
if (id->fd_close != 0)
|
||||
close(id->fd);
|
||||
|
||||
volume_id_free_buffer(id);
|
||||
|
||||
if (id->partitions != NULL)
|
||||
free(id->partitions);
|
||||
|
||||
free(id);
|
||||
}
|
@ -1,7 +1,7 @@
|
||||
/*
|
||||
* volume_id - reads partition label and uuid
|
||||
*
|
||||
* Copyright (C) 2004 Kay Sievers <kay.sievers@vrfy.org>
|
||||
* Copyright (C) 2005 Kay Sievers <kay.sievers@vrfy.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
@ -21,7 +21,7 @@
|
||||
#ifndef _VOLUME_ID_H_
|
||||
#define _VOLUME_ID_H_
|
||||
|
||||
#define VOLUME_ID_VERSION 28
|
||||
#define VOLUME_ID_VERSION 31
|
||||
|
||||
#define VOLUME_ID_LABEL_SIZE 64
|
||||
#define VOLUME_ID_UUID_SIZE 16
|
||||
@ -37,35 +37,12 @@ enum volume_id_usage {
|
||||
VOLUME_ID_FILESYSTEM,
|
||||
VOLUME_ID_PARTITIONTABLE,
|
||||
VOLUME_ID_RAID,
|
||||
};
|
||||
|
||||
enum volume_id_type {
|
||||
VOLUME_ID_ALL,
|
||||
VOLUME_ID_MSDOSPARTTABLE,
|
||||
VOLUME_ID_MSDOSEXTENDED,
|
||||
VOLUME_ID_SWAP,
|
||||
VOLUME_ID_EXT2,
|
||||
VOLUME_ID_EXT3,
|
||||
VOLUME_ID_REISERFS,
|
||||
VOLUME_ID_XFS,
|
||||
VOLUME_ID_JFS,
|
||||
VOLUME_ID_VFAT,
|
||||
VOLUME_ID_UDF,
|
||||
VOLUME_ID_ISO9660,
|
||||
VOLUME_ID_NTFS,
|
||||
VOLUME_ID_MACPARTMAP,
|
||||
VOLUME_ID_HFS,
|
||||
VOLUME_ID_HFSPLUS,
|
||||
VOLUME_ID_UFS,
|
||||
VOLUME_ID_LINUX_RAID,
|
||||
VOLUME_ID_LVM1,
|
||||
VOLUME_ID_LVM2,
|
||||
VOLUME_ID_HPTRAID,
|
||||
VOLUME_ID_DISKLABEL,
|
||||
};
|
||||
|
||||
struct volume_id_partition {
|
||||
enum volume_id_usage usage_id;
|
||||
enum volume_id_type type_id;
|
||||
char *usage;
|
||||
char *type;
|
||||
unsigned long long off;
|
||||
unsigned long long len;
|
||||
@ -79,11 +56,13 @@ struct volume_id {
|
||||
unsigned char uuid_raw[VOLUME_ID_UUID_SIZE];
|
||||
char uuid[VOLUME_ID_UUID_STRING_SIZE];
|
||||
enum volume_id_usage usage_id;
|
||||
enum volume_id_type type_id;
|
||||
char *usage;
|
||||
char *type;
|
||||
char type_version[VOLUME_ID_FORMAT_SIZE];
|
||||
|
||||
struct volume_id_partition *partitions;
|
||||
unsigned int partition_count;
|
||||
|
||||
int fd;
|
||||
unsigned char *sbbuf;
|
||||
unsigned int sbbuf_len;
|
||||
@ -93,20 +72,10 @@ struct volume_id {
|
||||
int fd_close;
|
||||
};
|
||||
|
||||
/* open volume by already open file descriptor */
|
||||
extern struct volume_id *volume_id_open_fd(int fd);
|
||||
|
||||
/* open volume by device node */
|
||||
extern struct volume_id *volume_id_open_node(const char *path);
|
||||
|
||||
/* open volume by major/minor */
|
||||
extern struct volume_id *volume_id_open_dev_t(dev_t devt);
|
||||
|
||||
/* probe volume for filesystem type and try to read label/uuid */
|
||||
extern int volume_id_probe(struct volume_id *id, enum volume_id_type type,
|
||||
unsigned long long off, unsigned long long size);
|
||||
|
||||
/* free allocated device info */
|
||||
extern int volume_id_probe_all(struct volume_id *id, unsigned long long off, unsigned long long size);
|
||||
extern void volume_id_close(struct volume_id *id);
|
||||
|
||||
#endif
|
74
extras/volume_id/volume_id/xfs/xfs.c
Normal file
74
extras/volume_id/volume_id/xfs/xfs.c
Normal file
@ -0,0 +1,74 @@
|
||||
/*
|
||||
* volume_id - reads filesystem label and uuid
|
||||
*
|
||||
* Copyright (C) 2004 Kay Sievers <kay.sievers@vrfy.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef _GNU_SOURCE
|
||||
#define _GNU_SOURCE 1
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <ctype.h>
|
||||
#include <asm/types.h>
|
||||
|
||||
#include "../volume_id.h"
|
||||
#include "../logging.h"
|
||||
#include "../util.h"
|
||||
#include "xfs.h"
|
||||
|
||||
int volume_id_probe_xfs(struct volume_id *id, __u64 off)
|
||||
{
|
||||
struct xfs_super_block {
|
||||
__u8 magic[4];
|
||||
__u32 blocksize;
|
||||
__u64 dblocks;
|
||||
__u64 rblocks;
|
||||
__u32 dummy1[2];
|
||||
__u8 uuid[16];
|
||||
__u32 dummy2[15];
|
||||
__u8 fname[12];
|
||||
__u32 dummy3[2];
|
||||
__u64 icount;
|
||||
__u64 ifree;
|
||||
__u64 fdblocks;
|
||||
} __attribute__((__packed__)) *xs;
|
||||
|
||||
xs = (struct xfs_super_block *) volume_id_get_buffer(id, off, 0x200);
|
||||
if (xs == NULL)
|
||||
return -1;
|
||||
|
||||
if (strncmp(xs->magic, "XFSB", 4) != 0)
|
||||
return -1;
|
||||
|
||||
volume_id_set_label_raw(id, xs->fname, 12);
|
||||
volume_id_set_label_string(id, xs->fname, 12);
|
||||
volume_id_set_uuid(id, xs->uuid, UUID_DCE);
|
||||
|
||||
volume_id_set_usage(id, VOLUME_ID_FILESYSTEM);
|
||||
id->type = "xfs";
|
||||
|
||||
return 0;
|
||||
}
|
26
extras/volume_id/volume_id/xfs/xfs.h
Normal file
26
extras/volume_id/volume_id/xfs/xfs.h
Normal file
@ -0,0 +1,26 @@
|
||||
/*
|
||||
* volume_id - reads filesystem label and uuid
|
||||
*
|
||||
* Copyright (C) 2004 Kay Sievers <kay.sievers@vrfy.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef _VOLUME_ID__
|
||||
#define _VOLUME_ID__
|
||||
|
||||
extern int volume_id_probe_xfs(struct volume_id *id, __u64 off);
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue
Block a user