From 3f9c16c4d9e1329ad5ec8acbdbc0be77173443f1 Mon Sep 17 00:00:00 2001 From: Eric Biggers Date: Wed, 17 Feb 2016 20:21:43 -0600 Subject: [PATCH] Make 'wimdir --detailed' show object IDs --- include/wimlib.h | 18 +++++++++++++++++- programs/imagex.c | 26 +++++++++++++++++++++++++- src/iterate_dir.c | 10 +++++++++- 3 files changed, 51 insertions(+), 3 deletions(-) diff --git a/include/wimlib.h b/include/wimlib.h index 6a1fbde6..6865746b 100644 --- a/include/wimlib.h +++ b/include/wimlib.h @@ -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. diff --git a/programs/imagex.c b/programs/imagex.c index 4abcbac2..7a57a86f 100644 --- a/programs/imagex.c +++ b/programs/imagex.c @@ -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"), diff --git a/src/iterate_dir.c b/src/iterate_dir.c index 9fed454a..c5f5dad7 100644 --- a/src/iterate_dir.c +++ b/src/iterate_dir.c @@ -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) { -- 2.43.0