hal/hald/linux/volume_id volume_id.c,1.7,1.8 volume_id.h,1.3,1.4
David Zeuthen
david at pdx.freedesktop.org
Mon Jul 5 12:27:27 PDT 2004
Update of /cvs/hal/hal/hald/linux/volume_id
In directory pdx:/tmp/cvs-serv21526/hald/linux/volume_id
Modified Files:
volume_id.c volume_id.h
Log Message:
2004-07-05 David Zeuthen <david at fubar.dk>
Patch from Kay Sievers <kay.sievers at vrfy.org>. Add hfs support
Index: volume_id.c
===================================================================
RCS file: /cvs/hal/hal/hald/linux/volume_id/volume_id.c,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -d -r1.7 -r1.8
--- volume_id.c 28 Jun 2004 15:22:08 -0000 1.7
+++ volume_id.c 5 Jul 2004 19:27:25 -0000 1.8
@@ -3,13 +3,10 @@
*
* Copyright (C) 2004 Kay Sievers <kay.sievers at vrfy.org>
*
- * The superblock structs are taken from the libblkid living inside
- * the e2fsprogs. This is a simple straightforward implementation for
- * reading the label strings of only the most common filesystems.
- * If you need a full featured library with attribute caching, support for
- * much more partition/media types or non-root disk access, you may have
- * a look at:
- * http://e2fsprogs.sourceforge.net.
+ * The superblock structs are taken from the linux kernel sources
+ * and the libblkid living inside the e2fsprogs. This is a simple
+ * straightforward implementation for reading the label strings of the
+ * most common filesystems.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -72,16 +69,20 @@
#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
/* size of superblock buffer, reiser block is at 64k */
#define SB_BUFFER_SIZE 0x11000
-/* size of seek buffer 2k */
-#define SEEK_BUFFER_SIZE 0x800
+/* size of seek buffer 4k */
+#define SEEK_BUFFER_SIZE 0x1000
static void set_label_raw(struct volume_id *id,
@@ -697,6 +698,213 @@
return 0;
}
+#define HFS_SUPERBLOCK_OFFSET 0x400
+static int probe_hfs(struct volume_id *id)
+{
+ 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 finder_info {
+ __u32 boot_folder;
+ __u32 start_app;
+ __u32 open_folder;
+ __u32 os9_folder;
+ __u32 reserved;
+ __u32 osx_folder;
+ __u8 id[8];
+ } __attribute__((__packed__)) finfo;
+
+ } __attribute__((__packed__)) *hfs;
+
+ hfs = (struct hfs_mdb *) get_buffer(id, HFS_SUPERBLOCK_OFFSET, 0x200);
+ if (hfs == NULL)
+ return -1;
+
+ if (strncmp(hfs->signature, "BD", 2) != 0)
+ return -1;
+
+ if (hfs->label_len > 0 && hfs->label_len < 28) {
+ set_label_raw(id, hfs->label, hfs->label_len);
+ set_label_string(id, hfs->label, hfs->label_len) ;
+ }
+
+ set_uuid(id, hfs->finfo.id, 8);
+
+ id->fs_type = HFS;
+ id->fs_name = "hfs";
+
+ return 0;
+}
+
+#define HFS_NODE_LEAF 0xff
+#define HFSPLUS_POR_CNID 1
+static int probe_hfsplus(struct volume_id *id)
+{
+ 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[8];
+ } __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 finder_info {
+ __u32 boot_folder;
+ __u32 start_app;
+ __u32 open_folder;
+ __u32 os9_folder;
+ __u32 reserved;
+ __u32 osx_folder;
+ __u8 id[8];
+ } __attribute__((__packed__)) finfo;
+ 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 cat_block_count;
+ unsigned int cat_off;
+ unsigned int cat_len;
+ unsigned int leaf_node_head;
+ unsigned int leaf_node_size;
+ struct hfsplus_bnode_descriptor *descr;
+ struct hfsplus_bheader_record *bnode;
+ struct hfsplus_catalog_key *key;
+ unsigned int label_len;
+ const __u8 *buf;
+
+ hfsplus = (struct hfsplus_vol_header *)
+ get_buffer(id, HFS_SUPERBLOCK_OFFSET, 0x200);
+ if (hfsplus == NULL)
+ return -1;
+
+ if (strncmp(hfsplus->signature, "H+", 2) == 0)
+ goto label;
+ if (strncmp(hfsplus->signature, "HX", 2) == 0)
+ goto label;
+ return -1;
+
+label:
+ blocksize = be32_to_cpu(hfsplus->blocksize);
+ cat_block = be32_to_cpu(hfsplus->cat_file.extents[0].start_block);
+ cat_block_count = be32_to_cpu(hfsplus->cat_file.extents[0].block_count);
+ cat_off = cat_block * blocksize;
+ cat_len = cat_block_count * blocksize;
+ dbg("catalog start 0x%x, len 0x%x", cat_off, cat_len);
+
+ buf = get_buffer(id, cat_off, 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);
+ leaf_node_size = be16_to_cpu(bnode->node_size);
+
+ dbg("catalog leaf node 0x%x, size 0x%x", leaf_node_head, leaf_node_size);
+
+ buf = get_buffer(id, cat_off + leaf_node_size, leaf_node_size);
+ if (buf == NULL)
+ goto found;
+
+ descr = (struct hfsplus_bnode_descriptor *) buf;
+ if (descr->type != HFS_NODE_LEAF)
+ goto found;
+
+ key = (struct hfsplus_catalog_key *)
+ &buf[sizeof(struct hfsplus_bnode_descriptor)];
+
+ 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);
+ set_label_raw(id, key->unicode, label_len);
+ set_label_unicode16(id, key->unicode, BE, label_len);
+
+found:
+ id->fs_type = HFSPLUS;
+ id->fs_name = "hfsplus";
+
+ return 0;
+}
+
#define MFT_RECORD_VOLUME 3
#define MFT_RECORD_ATTR_VOLUME_NAME 0x60u
#define MFT_RECORD_ATTR_OBJECT_ID 0x40u
@@ -910,6 +1118,12 @@
case ISO9660:
rc = probe_iso9660(id);
break;
+ case HFS:
+ rc = probe_hfs(id);
+ break;
+ case HFSPLUS:
+ rc = probe_hfsplus(id);
+ break;
case NTFS:
rc = probe_ntfs(id);
break;
@@ -920,6 +1134,9 @@
default:
/* fill buffer with maximum */
get_buffer(id, 0, SB_BUFFER_SIZE);
+ rc = probe_swap(id);
+ if (rc == 0)
+ break;
rc = probe_ext(id);
if (rc == 0)
break;
@@ -947,7 +1164,10 @@
rc = probe_ntfs(id);
if (rc == 0)
break;
- rc = probe_swap(id);
+ rc = probe_hfsplus(id);
+ if (rc == 0)
+ break;
+ rc = probe_hfs(id);
if (rc == 0)
break;
rc = -1;
Index: volume_id.h
===================================================================
RCS file: /cvs/hal/hal/hald/linux/volume_id/volume_id.h,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -d -r1.3 -r1.4
--- volume_id.h 20 Jun 2004 13:55:48 -0000 1.3
+++ volume_id.h 5 Jul 2004 19:27:25 -0000 1.4
@@ -21,7 +21,7 @@
#ifndef _VOLUME_ID_H_
#define _VOLUME_ID_H_
-#define VOLUME_ID_VERSION 004
+#define VOLUME_ID_VERSION 005
#define VOLUME_ID_LABEL_SIZE 64
#define VOLUME_ID_UUID_SIZE 16
@@ -41,6 +41,8 @@
UDF,
ISO9660,
NTFS,
+ HFS,
+ HFSPLUS,
SWAP
};
More information about the hal-commit
mailing list