Make 'wimdir --detailed' show object IDs
authorEric Biggers <ebiggers3@gmail.com>
Thu, 18 Feb 2016 02:21:43 +0000 (20:21 -0600)
committerEric Biggers <ebiggers3@gmail.com>
Thu, 18 Feb 2016 02:57:36 +0000 (20:57 -0600)
include/wimlib.h
programs/imagex.c
src/iterate_dir.c

index 6a1fbde..6865746 100644 (file)
@@ -1437,6 +1437,18 @@ struct wimlib_stream_entry {
        uint64_t reserved[4];
 };
 
+/**
+ * An object ID, which is an extra piece of metadata that may be associated with
+ * a file on NTFS filesystems.  See:
+ * https://msdn.microsoft.com/en-us/library/windows/desktop/aa363997(v=vs.85).aspx
+ */
+struct wimlib_object_id {
+       uint8_t object_id[WIMLIB_GUID_LEN];
+       uint8_t birth_volume_id[WIMLIB_GUID_LEN];
+       uint8_t birth_object_id[WIMLIB_GUID_LEN];
+       uint8_t domain_id[WIMLIB_GUID_LEN];
+};
+
 /** Structure passed to the wimlib_iterate_dir_tree() callback function.
  * Roughly, the information about a "file" in the WIM--- but really a directory
  * entry ("dentry") because hard links are allowed.  The hard_link_group_id
@@ -1555,7 +1567,11 @@ struct wimlib_dir_entry {
         * This field is only valid if @p unix_mode != 0.  */
        uint32_t unix_rdev;
 
-       uint64_t reserved[14];
+       /* The object ID of this file, if any.  Only valid if
+        * object_id.object_id is not all zeroes.  */
+       struct wimlib_object_id object_id;
+
+       uint64_t reserved[6];
 
        /**
         * Array of streams that make up this file.
index 4abcbac..7a57a86 100644 (file)
@@ -2638,10 +2638,27 @@ default_print_security_descriptor(const uint8_t *sd, size_t size)
 }
 #endif
 
+static bool
+is_null_guid(const uint8_t *guid)
+{
+       static const uint8_t null_guid[WIMLIB_GUID_LEN];
+
+       return !memcmp(guid, null_guid, WIMLIB_GUID_LEN);
+}
+
 static void
-print_dentry_detailed(const struct wimlib_dir_entry *dentry)
+print_guid(const tchar *label, const uint8_t *guid)
 {
+       if (is_null_guid(guid))
+               return;
+       tprintf(T("%-20"TS"= 0x"), label);
+       print_byte_field(guid, WIMLIB_GUID_LEN);
+       tputchar(T('\n'));
+}
 
+static void
+print_dentry_detailed(const struct wimlib_dir_entry *dentry)
+{
        tprintf(T(
 "----------------------------------------------------------------------------\n"));
        tprintf(T("Full Path           = \"%"TS"\"\n"), dentry->full_path);
@@ -2676,6 +2693,13 @@ print_dentry_detailed(const struct wimlib_dir_entry *dentry)
                        dentry->unix_mode, dentry->unix_rdev);
        }
 
+       if (!is_null_guid(dentry->object_id.object_id)) {
+               print_guid(T("Object ID"), dentry->object_id.object_id);
+               print_guid(T("Birth Volume ID"), dentry->object_id.birth_volume_id);
+               print_guid(T("Birth Object ID"), dentry->object_id.birth_object_id);
+               print_guid(T("Domain ID"), dentry->object_id.domain_id);
+       }
+
        for (uint32_t i = 0; i <= dentry->num_named_streams; i++) {
                if (dentry->streams[i].stream_name) {
                        tprintf(T("\tNamed data stream \"%"TS"\":\n"),
index 9fed454..c5f5dad 100644 (file)
@@ -6,7 +6,7 @@
  */
 
 /*
- * Copyright (C) 2013, 2015 Eric Biggers
+ * Copyright (C) 2013-2016 Eric Biggers
  *
  * This file 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
@@ -31,6 +31,7 @@
 #include "wimlib/dentry.h"
 #include "wimlib/encoding.h"
 #include "wimlib/metadata.h"
+#include "wimlib/object_id.h"
 #include "wimlib/paths.h"
 #include "wimlib/security.h"
 #include "wimlib/timestamp.h"
@@ -90,6 +91,8 @@ init_wimlib_dentry(struct wimlib_dir_entry *wdentry, struct wim_dentry *dentry,
        const struct wim_inode *inode = dentry->d_inode;
        const struct wim_inode_stream *strm;
        struct wimlib_unix_data unix_data;
+       const void *object_id;
+       u32 object_id_len;
 
        ret = utf16le_get_tstr(dentry->d_name, dentry->d_name_nbytes,
                               &wdentry->filename, &dummy);
@@ -129,6 +132,11 @@ init_wimlib_dentry(struct wimlib_dir_entry *wdentry, struct wim_dentry *dentry,
                wdentry->unix_mode = unix_data.mode;
                wdentry->unix_rdev = unix_data.rdev;
        }
+       object_id = inode_get_object_id(inode, &object_id_len);
+       if (unlikely(object_id != NULL)) {
+               memcpy(&wdentry->object_id, object_id,
+                      min(object_id_len, sizeof(wdentry->object_id)));
+       }
 
        strm = inode_get_unnamed_stream(inode, get_default_stream_type(inode));
        if (strm) {