1987da915Sopenharmony_ci/** 2987da915Sopenharmony_ci * ntfsinfo - Part of the Linux-NTFS project. 3987da915Sopenharmony_ci * 4987da915Sopenharmony_ci * Copyright (c) 2002-2004 Matthew J. Fanto 5987da915Sopenharmony_ci * Copyright (c) 2002-2006 Anton Altaparmakov 6987da915Sopenharmony_ci * Copyright (c) 2002-2005 Richard Russon 7987da915Sopenharmony_ci * Copyright (c) 2003-2006 Szabolcs Szakacsits 8987da915Sopenharmony_ci * Copyright (c) 2004-2005 Yuval Fledel 9987da915Sopenharmony_ci * Copyright (c) 2004-2007 Yura Pakhuchiy 10987da915Sopenharmony_ci * Copyright (c) 2005 Cristian Klein 11987da915Sopenharmony_ci * Copyright (c) 2011-2020 Jean-Pierre Andre 12987da915Sopenharmony_ci * 13987da915Sopenharmony_ci * This utility will dump a file's attributes. 14987da915Sopenharmony_ci * 15987da915Sopenharmony_ci * This program is free software; you can redistribute it and/or modify 16987da915Sopenharmony_ci * it under the terms of the GNU General Public License as published by 17987da915Sopenharmony_ci * the Free Software Foundation; either version 2 of the License, or 18987da915Sopenharmony_ci * (at your option) any later version. 19987da915Sopenharmony_ci * 20987da915Sopenharmony_ci * This program is distributed in the hope that it will be useful, 21987da915Sopenharmony_ci * but WITHOUT ANY WARRANTY; without even the implied warranty of 22987da915Sopenharmony_ci * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 23987da915Sopenharmony_ci * GNU General Public License for more details. 24987da915Sopenharmony_ci * 25987da915Sopenharmony_ci * You should have received a copy of the GNU General Public License 26987da915Sopenharmony_ci * along with this program (in the main directory of the Linux-NTFS 27987da915Sopenharmony_ci * distribution in the file COPYING); if not, write to the Free Software 28987da915Sopenharmony_ci * Foundation,Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 29987da915Sopenharmony_ci */ 30987da915Sopenharmony_ci/* 31987da915Sopenharmony_ci * TODO LIST: 32987da915Sopenharmony_ci * - Better error checking. (focus on ntfs_dump_volume) 33987da915Sopenharmony_ci * - Comment things better. 34987da915Sopenharmony_ci * - More things at verbose mode. 35987da915Sopenharmony_ci * - Dump ACLs when security_id exists (NTFS 3+ only). 36987da915Sopenharmony_ci * - Clean ups. 37987da915Sopenharmony_ci * - Internationalization. 38987da915Sopenharmony_ci * - Add more Indexed Attr Types. 39987da915Sopenharmony_ci * - Make formatting look more like www.flatcap.org/ntfs/info 40987da915Sopenharmony_ci * 41987da915Sopenharmony_ci * Still not dumping certain attributes. Need to find the best 42987da915Sopenharmony_ci * way to output some of these attributes. 43987da915Sopenharmony_ci * 44987da915Sopenharmony_ci * Still need to do: 45987da915Sopenharmony_ci * $REPARSE_POINT/$SYMBOLIC_LINK 46987da915Sopenharmony_ci * $LOGGED_UTILITY_STREAM 47987da915Sopenharmony_ci */ 48987da915Sopenharmony_ci 49987da915Sopenharmony_ci#include "config.h" 50987da915Sopenharmony_ci 51987da915Sopenharmony_ci#ifdef HAVE_STDIO_H 52987da915Sopenharmony_ci#include <stdio.h> 53987da915Sopenharmony_ci#endif 54987da915Sopenharmony_ci#ifdef HAVE_STDLIB_H 55987da915Sopenharmony_ci#include <stdlib.h> 56987da915Sopenharmony_ci#endif 57987da915Sopenharmony_ci#ifdef HAVE_STRING_H 58987da915Sopenharmony_ci#include <string.h> 59987da915Sopenharmony_ci#endif 60987da915Sopenharmony_ci#ifdef HAVE_TIME_H 61987da915Sopenharmony_ci#include <time.h> 62987da915Sopenharmony_ci#endif 63987da915Sopenharmony_ci#ifdef HAVE_GETOPT_H 64987da915Sopenharmony_ci#include <getopt.h> 65987da915Sopenharmony_ci#endif 66987da915Sopenharmony_ci#ifdef HAVE_ERRNO_H 67987da915Sopenharmony_ci#include <errno.h> 68987da915Sopenharmony_ci#endif 69987da915Sopenharmony_ci 70987da915Sopenharmony_ci#include "types.h" 71987da915Sopenharmony_ci#include "mft.h" 72987da915Sopenharmony_ci#include "attrib.h" 73987da915Sopenharmony_ci#include "layout.h" 74987da915Sopenharmony_ci#include "inode.h" 75987da915Sopenharmony_ci#include "index.h" 76987da915Sopenharmony_ci#include "utils.h" 77987da915Sopenharmony_ci#include "security.h" 78987da915Sopenharmony_ci#include "mst.h" 79987da915Sopenharmony_ci#include "dir.h" 80987da915Sopenharmony_ci#include "ntfstime.h" 81987da915Sopenharmony_ci/* #include "version.h" */ 82987da915Sopenharmony_ci#include "support.h" 83987da915Sopenharmony_ci#include "misc.h" 84987da915Sopenharmony_ci 85987da915Sopenharmony_cistatic const char *EXEC_NAME = "ntfsinfo"; 86987da915Sopenharmony_ci 87987da915Sopenharmony_cistatic struct options { 88987da915Sopenharmony_ci const char *device; /* Device/File to work with */ 89987da915Sopenharmony_ci const char *filename; /* Resolve this filename to mft number */ 90987da915Sopenharmony_ci s64 inode; /* Info for this inode */ 91987da915Sopenharmony_ci int quiet; /* Less output */ 92987da915Sopenharmony_ci int verbose; /* Extra output */ 93987da915Sopenharmony_ci int force; /* Override common sense */ 94987da915Sopenharmony_ci int notime; /* Don't report timestamps at all */ 95987da915Sopenharmony_ci int mft; /* Dump information about the volume as well */ 96987da915Sopenharmony_ci} opts; 97987da915Sopenharmony_ci 98987da915Sopenharmony_cistruct RUNCOUNT { 99987da915Sopenharmony_ci unsigned long runs; 100987da915Sopenharmony_ci unsigned long fragments; 101987da915Sopenharmony_ci} ; 102987da915Sopenharmony_ci 103987da915Sopenharmony_ci/** 104987da915Sopenharmony_ci * version - Print version information about the program 105987da915Sopenharmony_ci * 106987da915Sopenharmony_ci * Print a copyright statement and a brief description of the program. 107987da915Sopenharmony_ci * 108987da915Sopenharmony_ci * Return: none 109987da915Sopenharmony_ci */ 110987da915Sopenharmony_cistatic void version(void) 111987da915Sopenharmony_ci{ 112987da915Sopenharmony_ci printf("\n%s v%s (libntfs-3g) - Display information about an NTFS " 113987da915Sopenharmony_ci "Volume.\n\n", EXEC_NAME, VERSION); 114987da915Sopenharmony_ci printf("Copyright (c)\n"); 115987da915Sopenharmony_ci printf(" 2002-2004 Matthew J. Fanto\n"); 116987da915Sopenharmony_ci printf(" 2002-2006 Anton Altaparmakov\n"); 117987da915Sopenharmony_ci printf(" 2002-2005 Richard Russon\n"); 118987da915Sopenharmony_ci printf(" 2003-2006 Szabolcs Szakacsits\n"); 119987da915Sopenharmony_ci printf(" 2003 Leonard Norrgård\n"); 120987da915Sopenharmony_ci printf(" 2004-2005 Yuval Fledel\n"); 121987da915Sopenharmony_ci printf(" 2004-2007 Yura Pakhuchiy\n"); 122987da915Sopenharmony_ci printf(" 2011-2018 Jean-Pierre Andre\n"); 123987da915Sopenharmony_ci printf("\n%s\n%s%s\n", ntfs_gpl, ntfs_bugs, ntfs_home); 124987da915Sopenharmony_ci} 125987da915Sopenharmony_ci 126987da915Sopenharmony_ci/** 127987da915Sopenharmony_ci * usage - Print a list of the parameters to the program 128987da915Sopenharmony_ci * 129987da915Sopenharmony_ci * Print a list of the parameters and options for the program. 130987da915Sopenharmony_ci * 131987da915Sopenharmony_ci * Return: none 132987da915Sopenharmony_ci */ 133987da915Sopenharmony_cistatic void usage(void) 134987da915Sopenharmony_ci{ 135987da915Sopenharmony_ci printf("\nUsage: %s [options] device\n" 136987da915Sopenharmony_ci " -i, --inode NUM Display information about this inode\n" 137987da915Sopenharmony_ci " -F, --file FILE Display information about this file (absolute path)\n" 138987da915Sopenharmony_ci " -m, --mft Dump information about the volume\n" 139987da915Sopenharmony_ci " -t, --notime Don't report timestamps\n" 140987da915Sopenharmony_ci "\n" 141987da915Sopenharmony_ci " -f, --force Use less caution\n" 142987da915Sopenharmony_ci " -q, --quiet Less output\n" 143987da915Sopenharmony_ci " -v, --verbose More output\n" 144987da915Sopenharmony_ci " -V, --version Display version information\n" 145987da915Sopenharmony_ci " -h, --help Display this help\n" 146987da915Sopenharmony_ci "\n", 147987da915Sopenharmony_ci EXEC_NAME); 148987da915Sopenharmony_ci printf("%s%s\n", ntfs_bugs, ntfs_home); 149987da915Sopenharmony_ci} 150987da915Sopenharmony_ci 151987da915Sopenharmony_ci/** 152987da915Sopenharmony_ci * parse_options - Read and validate the programs command line 153987da915Sopenharmony_ci * 154987da915Sopenharmony_ci * Read the command line, verify the syntax and parse the options. 155987da915Sopenharmony_ci * This function is very long, but quite simple. 156987da915Sopenharmony_ci * 157987da915Sopenharmony_ci * Return: 1 Success 158987da915Sopenharmony_ci * 0 Error, one or more problems 159987da915Sopenharmony_ci */ 160987da915Sopenharmony_cistatic int parse_options(int argc, char *argv[]) 161987da915Sopenharmony_ci{ 162987da915Sopenharmony_ci static const char *sopt = "-:dfhi:F:mqtTvV"; 163987da915Sopenharmony_ci static const struct option lopt[] = { 164987da915Sopenharmony_ci { "force", no_argument, NULL, 'f' }, 165987da915Sopenharmony_ci { "help", no_argument, NULL, 'h' }, 166987da915Sopenharmony_ci { "inode", required_argument, NULL, 'i' }, 167987da915Sopenharmony_ci { "file", required_argument, NULL, 'F' }, 168987da915Sopenharmony_ci { "quiet", no_argument, NULL, 'q' }, 169987da915Sopenharmony_ci { "verbose", no_argument, NULL, 'v' }, 170987da915Sopenharmony_ci { "version", no_argument, NULL, 'V' }, 171987da915Sopenharmony_ci { "notime", no_argument, NULL, 'T' }, 172987da915Sopenharmony_ci { "mft", no_argument, NULL, 'm' }, 173987da915Sopenharmony_ci { NULL, 0, NULL, 0 } 174987da915Sopenharmony_ci }; 175987da915Sopenharmony_ci 176987da915Sopenharmony_ci int c = -1; 177987da915Sopenharmony_ci int err = 0; 178987da915Sopenharmony_ci int ver = 0; 179987da915Sopenharmony_ci int help = 0; 180987da915Sopenharmony_ci int levels = 0; 181987da915Sopenharmony_ci 182987da915Sopenharmony_ci opterr = 0; /* We'll handle the errors, thank you. */ 183987da915Sopenharmony_ci 184987da915Sopenharmony_ci opts.inode = -1; 185987da915Sopenharmony_ci opts.filename = NULL; 186987da915Sopenharmony_ci 187987da915Sopenharmony_ci while ((c = getopt_long(argc, argv, sopt, lopt, NULL)) != -1) { 188987da915Sopenharmony_ci switch (c) { 189987da915Sopenharmony_ci case 1: 190987da915Sopenharmony_ci if (!opts.device) 191987da915Sopenharmony_ci opts.device = optarg; 192987da915Sopenharmony_ci else 193987da915Sopenharmony_ci err++; 194987da915Sopenharmony_ci break; 195987da915Sopenharmony_ci case 'i': 196987da915Sopenharmony_ci if ((opts.inode != -1) || 197987da915Sopenharmony_ci (!utils_parse_size(optarg, &opts.inode, FALSE))) { 198987da915Sopenharmony_ci err++; 199987da915Sopenharmony_ci } 200987da915Sopenharmony_ci break; 201987da915Sopenharmony_ci case 'F': 202987da915Sopenharmony_ci if (opts.filename == NULL) { 203987da915Sopenharmony_ci /* The inode can not be resolved here, 204987da915Sopenharmony_ci store the filename */ 205987da915Sopenharmony_ci opts.filename = argv[optind-1]; 206987da915Sopenharmony_ci } else { 207987da915Sopenharmony_ci /* "-F" can't appear more than once */ 208987da915Sopenharmony_ci err++; 209987da915Sopenharmony_ci } 210987da915Sopenharmony_ci break; 211987da915Sopenharmony_ci case 'f': 212987da915Sopenharmony_ci opts.force++; 213987da915Sopenharmony_ci break; 214987da915Sopenharmony_ci case 'h': 215987da915Sopenharmony_ci help++; 216987da915Sopenharmony_ci break; 217987da915Sopenharmony_ci case 'q': 218987da915Sopenharmony_ci opts.quiet++; 219987da915Sopenharmony_ci ntfs_log_clear_levels(NTFS_LOG_LEVEL_QUIET); 220987da915Sopenharmony_ci break; 221987da915Sopenharmony_ci case 't': 222987da915Sopenharmony_ci opts.notime++; 223987da915Sopenharmony_ci break; 224987da915Sopenharmony_ci case 'T': 225987da915Sopenharmony_ci /* 'T' is deprecated, notify */ 226987da915Sopenharmony_ci ntfs_log_error("Option 'T' is deprecated, it was " 227987da915Sopenharmony_ci "replaced by 't'.\n"); 228987da915Sopenharmony_ci err++; 229987da915Sopenharmony_ci break; 230987da915Sopenharmony_ci case 'v': 231987da915Sopenharmony_ci opts.verbose++; 232987da915Sopenharmony_ci ntfs_log_set_levels(NTFS_LOG_LEVEL_VERBOSE); 233987da915Sopenharmony_ci break; 234987da915Sopenharmony_ci case 'V': 235987da915Sopenharmony_ci ver++; 236987da915Sopenharmony_ci break; 237987da915Sopenharmony_ci case 'm': 238987da915Sopenharmony_ci opts.mft++; 239987da915Sopenharmony_ci break; 240987da915Sopenharmony_ci case '?': 241987da915Sopenharmony_ci if (optopt=='?') { 242987da915Sopenharmony_ci help++; 243987da915Sopenharmony_ci continue; 244987da915Sopenharmony_ci } 245987da915Sopenharmony_ci if (ntfs_log_parse_option(argv[optind-1])) 246987da915Sopenharmony_ci continue; 247987da915Sopenharmony_ci ntfs_log_error("Unknown option '%s'.\n", 248987da915Sopenharmony_ci argv[optind-1]); 249987da915Sopenharmony_ci err++; 250987da915Sopenharmony_ci break; 251987da915Sopenharmony_ci case ':': 252987da915Sopenharmony_ci ntfs_log_error("Option '%s' requires an " 253987da915Sopenharmony_ci "argument.\n", argv[optind-1]); 254987da915Sopenharmony_ci err++; 255987da915Sopenharmony_ci break; 256987da915Sopenharmony_ci default: 257987da915Sopenharmony_ci ntfs_log_error("Unhandled option case: %d.\n", c); 258987da915Sopenharmony_ci err++; 259987da915Sopenharmony_ci break; 260987da915Sopenharmony_ci } 261987da915Sopenharmony_ci } 262987da915Sopenharmony_ci 263987da915Sopenharmony_ci /* Make sure we're in sync with the log levels */ 264987da915Sopenharmony_ci levels = ntfs_log_get_levels(); 265987da915Sopenharmony_ci if (levels & NTFS_LOG_LEVEL_VERBOSE) 266987da915Sopenharmony_ci opts.verbose++; 267987da915Sopenharmony_ci if (!(levels & NTFS_LOG_LEVEL_QUIET)) 268987da915Sopenharmony_ci opts.quiet++; 269987da915Sopenharmony_ci 270987da915Sopenharmony_ci if (help || ver) { 271987da915Sopenharmony_ci opts.quiet = 0; 272987da915Sopenharmony_ci } else { 273987da915Sopenharmony_ci if (opts.device == NULL) { 274987da915Sopenharmony_ci if (argc > 1) 275987da915Sopenharmony_ci ntfs_log_error("You must specify exactly one " 276987da915Sopenharmony_ci "device.\n"); 277987da915Sopenharmony_ci err++; 278987da915Sopenharmony_ci } 279987da915Sopenharmony_ci 280987da915Sopenharmony_ci if (opts.inode == -1 && !opts.filename && !opts.mft) { 281987da915Sopenharmony_ci if (argc > 1) 282987da915Sopenharmony_ci ntfs_log_error("You must specify an inode to " 283987da915Sopenharmony_ci "learn about.\n"); 284987da915Sopenharmony_ci err++; 285987da915Sopenharmony_ci } 286987da915Sopenharmony_ci 287987da915Sopenharmony_ci if (opts.quiet && opts.verbose) { 288987da915Sopenharmony_ci ntfs_log_error("You may not use --quiet and --verbose " 289987da915Sopenharmony_ci "at the same time.\n"); 290987da915Sopenharmony_ci err++; 291987da915Sopenharmony_ci } 292987da915Sopenharmony_ci 293987da915Sopenharmony_ci if ((opts.inode != -1) && (opts.filename != NULL)) { 294987da915Sopenharmony_ci if (argc > 1) 295987da915Sopenharmony_ci ntfs_log_error("You may not specify --inode " 296987da915Sopenharmony_ci "and --file together.\n"); 297987da915Sopenharmony_ci err++; 298987da915Sopenharmony_ci } 299987da915Sopenharmony_ci 300987da915Sopenharmony_ci } 301987da915Sopenharmony_ci 302987da915Sopenharmony_ci if (ver) 303987da915Sopenharmony_ci version(); 304987da915Sopenharmony_ci if (help || err) 305987da915Sopenharmony_ci usage(); 306987da915Sopenharmony_ci 307987da915Sopenharmony_ci /* tri-state 0 : done, 1 : error, -1 : proceed */ 308987da915Sopenharmony_ci return (err ? 1 : (help || ver ? 0 : -1)); 309987da915Sopenharmony_ci} 310987da915Sopenharmony_ci 311987da915Sopenharmony_ci 312987da915Sopenharmony_ci/* *************** utility functions ******************** */ 313987da915Sopenharmony_ci/** 314987da915Sopenharmony_ci * ntfsinfo_time_to_str() - 315987da915Sopenharmony_ci * @sle_ntfs_clock: on disk time format in 100ns units since 1st jan 1601 316987da915Sopenharmony_ci * in little-endian format 317987da915Sopenharmony_ci * 318987da915Sopenharmony_ci * Return char* in a format 'Thu Jan 1 00:00:00 1970'. 319987da915Sopenharmony_ci * No need to free the returned memory. 320987da915Sopenharmony_ci * 321987da915Sopenharmony_ci * Example of usage: 322987da915Sopenharmony_ci * char *time_str = ntfsinfo_time_to_str( 323987da915Sopenharmony_ci * sle64_to_cpu(standard_attr->creation_time)); 324987da915Sopenharmony_ci * printf("\tFile Creation Time:\t %s", time_str); 325987da915Sopenharmony_ci */ 326987da915Sopenharmony_cistatic char *ntfsinfo_time_to_str(const sle64 sle_ntfs_clock) 327987da915Sopenharmony_ci{ 328987da915Sopenharmony_ci /* JPA display timestamps in UTC */ 329987da915Sopenharmony_ci static const char *months[] 330987da915Sopenharmony_ci = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", 331987da915Sopenharmony_ci "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" } ; 332987da915Sopenharmony_ci static const char *wdays[] 333987da915Sopenharmony_ci = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" } ; 334987da915Sopenharmony_ci static char str[50]; 335987da915Sopenharmony_ci long long stamp; 336987da915Sopenharmony_ci u32 days; 337987da915Sopenharmony_ci u32 seconds; 338987da915Sopenharmony_ci unsigned int year; 339987da915Sopenharmony_ci unsigned int wday; 340987da915Sopenharmony_ci int mon; 341987da915Sopenharmony_ci int cnt; 342987da915Sopenharmony_ci 343987da915Sopenharmony_ci stamp = sle64_to_cpu(sle_ntfs_clock); 344987da915Sopenharmony_ci days = (stamp/(86400*10000000LL)) & 0x7ffff; 345987da915Sopenharmony_ci seconds = ((stamp/10000000LL)%86400) & 0x1ffff; 346987da915Sopenharmony_ci wday = (days + 1)%7; 347987da915Sopenharmony_ci year = 1601; 348987da915Sopenharmony_ci /* periods of 400 years */ 349987da915Sopenharmony_ci cnt = days/146097; 350987da915Sopenharmony_ci days -= 146097*cnt; 351987da915Sopenharmony_ci year += 400*cnt; 352987da915Sopenharmony_ci /* periods of 100 years */ 353987da915Sopenharmony_ci cnt = (3*days + 3)/109573; 354987da915Sopenharmony_ci days -= 36524*cnt; 355987da915Sopenharmony_ci year += 100*cnt; 356987da915Sopenharmony_ci /* periods of 4 years */ 357987da915Sopenharmony_ci cnt = days/1461; 358987da915Sopenharmony_ci days -= 1461*cnt; 359987da915Sopenharmony_ci year += 4*cnt; 360987da915Sopenharmony_ci /* periods of a single year */ 361987da915Sopenharmony_ci cnt = (3*days + 3)/1096; 362987da915Sopenharmony_ci days -= 365*cnt; 363987da915Sopenharmony_ci year += cnt; 364987da915Sopenharmony_ci 365987da915Sopenharmony_ci if ((!(year % 100) ? (year % 400) : (year % 4)) 366987da915Sopenharmony_ci && (days > 58)) days++; 367987da915Sopenharmony_ci if (days > 59) { 368987da915Sopenharmony_ci mon = (5*days + 161)/153; 369987da915Sopenharmony_ci days -= (153*mon - 162)/5; 370987da915Sopenharmony_ci } else { 371987da915Sopenharmony_ci mon = days/31 + 1; 372987da915Sopenharmony_ci days -= 31*(mon - 1) - 1; 373987da915Sopenharmony_ci } 374987da915Sopenharmony_ci snprintf(str, sizeof(str), "%3s %3s %2u %02u:%02u:%02u %4u UTC\n", 375987da915Sopenharmony_ci wdays[wday], 376987da915Sopenharmony_ci months[mon-1],(unsigned int)days, 377987da915Sopenharmony_ci (unsigned int)(seconds/3600), 378987da915Sopenharmony_ci (unsigned int)(seconds/60%60), 379987da915Sopenharmony_ci (unsigned int)(seconds%60), 380987da915Sopenharmony_ci (unsigned int)year); 381987da915Sopenharmony_ci return (str); 382987da915Sopenharmony_ci} 383987da915Sopenharmony_ci 384987da915Sopenharmony_ci/** 385987da915Sopenharmony_ci * ntfs_attr_get_name() 386987da915Sopenharmony_ci * @attr: a valid attribute record 387987da915Sopenharmony_ci * 388987da915Sopenharmony_ci * return multi-byte string containing the attribute name if exist. the user 389987da915Sopenharmony_ci * is then responsible of freeing that memory. 390987da915Sopenharmony_ci * null if no name exists (attr->name_length==0). no memory allocated. 391987da915Sopenharmony_ci * null if cannot convert to multi-byte string. errno would contain the 392987da915Sopenharmony_ci * error id. no memory allocated in that case 393987da915Sopenharmony_ci */ 394987da915Sopenharmony_cistatic char *ntfs_attr_get_name_mbs(ATTR_RECORD *attr) 395987da915Sopenharmony_ci{ 396987da915Sopenharmony_ci ntfschar *ucs_attr_name; 397987da915Sopenharmony_ci char *mbs_attr_name = NULL; 398987da915Sopenharmony_ci int mbs_attr_name_size; 399987da915Sopenharmony_ci 400987da915Sopenharmony_ci /* Get name in unicode. */ 401987da915Sopenharmony_ci ucs_attr_name = ntfs_attr_get_name(attr); 402987da915Sopenharmony_ci /* Convert unicode to printable format. */ 403987da915Sopenharmony_ci mbs_attr_name_size = ntfs_ucstombs(ucs_attr_name, attr->name_length, 404987da915Sopenharmony_ci &mbs_attr_name, 0); 405987da915Sopenharmony_ci if (mbs_attr_name_size > 0) 406987da915Sopenharmony_ci return mbs_attr_name; 407987da915Sopenharmony_ci else 408987da915Sopenharmony_ci return NULL; 409987da915Sopenharmony_ci} 410987da915Sopenharmony_ci 411987da915Sopenharmony_cistatic const char *reparse_type_name(le32 tag) 412987da915Sopenharmony_ci{ 413987da915Sopenharmony_ci const char *name; 414987da915Sopenharmony_ci le32 seltag; 415987da915Sopenharmony_ci 416987da915Sopenharmony_ci seltag = tag & IO_REPARSE_PLUGIN_SELECT; 417987da915Sopenharmony_ci switch (seltag) { 418987da915Sopenharmony_ci case IO_REPARSE_TAG_MOUNT_POINT : 419987da915Sopenharmony_ci name = " (mount point)"; 420987da915Sopenharmony_ci break; 421987da915Sopenharmony_ci case IO_REPARSE_TAG_SYMLINK : 422987da915Sopenharmony_ci name = " (symlink)"; 423987da915Sopenharmony_ci break; 424987da915Sopenharmony_ci case IO_REPARSE_TAG_WOF : 425987da915Sopenharmony_ci name = " (Wof compressed)"; 426987da915Sopenharmony_ci break; 427987da915Sopenharmony_ci case IO_REPARSE_TAG_DEDUP : 428987da915Sopenharmony_ci name = " (deduplicated)"; 429987da915Sopenharmony_ci break; 430987da915Sopenharmony_ci case IO_REPARSE_TAG_WCI : 431987da915Sopenharmony_ci name = " (Windows container)"; 432987da915Sopenharmony_ci break; 433987da915Sopenharmony_ci case IO_REPARSE_TAG_CLOUD : 434987da915Sopenharmony_ci name = " (Cloud)"; 435987da915Sopenharmony_ci break; 436987da915Sopenharmony_ci case IO_REPARSE_TAG_NFS : 437987da915Sopenharmony_ci name = " (NFS symlink)"; 438987da915Sopenharmony_ci break; 439987da915Sopenharmony_ci case IO_REPARSE_TAG_LX_SYMLINK : 440987da915Sopenharmony_ci name = " (Linux symlink)"; 441987da915Sopenharmony_ci break; 442987da915Sopenharmony_ci case IO_REPARSE_TAG_LX_FIFO : 443987da915Sopenharmony_ci name = " (Linux fifo)"; 444987da915Sopenharmony_ci break; 445987da915Sopenharmony_ci case IO_REPARSE_TAG_LX_CHR : 446987da915Sopenharmony_ci name = " (Linux character device)"; 447987da915Sopenharmony_ci break; 448987da915Sopenharmony_ci case IO_REPARSE_TAG_LX_BLK : 449987da915Sopenharmony_ci name = " (Linux block device)"; 450987da915Sopenharmony_ci break; 451987da915Sopenharmony_ci case IO_REPARSE_TAG_AF_UNIX : 452987da915Sopenharmony_ci name = " (Unix socket)"; 453987da915Sopenharmony_ci break; 454987da915Sopenharmony_ci case IO_REPARSE_TAG_APPEXECLINK : 455987da915Sopenharmony_ci name = " (Exec link)"; 456987da915Sopenharmony_ci break; 457987da915Sopenharmony_ci default : 458987da915Sopenharmony_ci name = ""; 459987da915Sopenharmony_ci break; 460987da915Sopenharmony_ci } 461987da915Sopenharmony_ci return (name); 462987da915Sopenharmony_ci} 463987da915Sopenharmony_ci 464987da915Sopenharmony_ci/* *************** functions for dumping global info ******************** */ 465987da915Sopenharmony_ci/** 466987da915Sopenharmony_ci * ntfs_dump_volume - dump information about the volume 467987da915Sopenharmony_ci */ 468987da915Sopenharmony_cistatic void ntfs_dump_volume(ntfs_volume *vol) 469987da915Sopenharmony_ci{ 470987da915Sopenharmony_ci printf("Volume Information \n"); 471987da915Sopenharmony_ci printf("\tName of device: %s\n", vol->dev->d_name); 472987da915Sopenharmony_ci printf("\tDevice state: %lu\n", vol->dev->d_state); 473987da915Sopenharmony_ci printf("\tVolume Name: %s\n", vol->vol_name); 474987da915Sopenharmony_ci printf("\tVolume State: %lu\n", vol->state); 475987da915Sopenharmony_ci printf("\tVolume Flags: 0x%04x", (int)le16_to_cpu(vol->flags)); 476987da915Sopenharmony_ci if (vol->flags & VOLUME_IS_DIRTY) 477987da915Sopenharmony_ci printf(" DIRTY"); 478987da915Sopenharmony_ci if (vol->flags & VOLUME_MODIFIED_BY_CHKDSK) 479987da915Sopenharmony_ci printf(" MODIFIED_BY_CHKDSK"); 480987da915Sopenharmony_ci printf("\n"); 481987da915Sopenharmony_ci printf("\tVolume Version: %u.%u\n", vol->major_ver, vol->minor_ver); 482987da915Sopenharmony_ci printf("\tSector Size: %hu\n", vol->sector_size); 483987da915Sopenharmony_ci printf("\tCluster Size: %u\n", (unsigned int)vol->cluster_size); 484987da915Sopenharmony_ci printf("\tIndex Block Size: %u\n", (unsigned int)vol->indx_record_size); 485987da915Sopenharmony_ci printf("\tVolume Size in Clusters: %lld\n", 486987da915Sopenharmony_ci (long long)vol->nr_clusters); 487987da915Sopenharmony_ci 488987da915Sopenharmony_ci printf("MFT Information \n"); 489987da915Sopenharmony_ci printf("\tMFT Record Size: %u\n", (unsigned int)vol->mft_record_size); 490987da915Sopenharmony_ci printf("\tMFT Zone Multiplier: %u\n", vol->mft_zone_multiplier); 491987da915Sopenharmony_ci printf("\tMFT Data Position: %lld\n", (long long)vol->mft_data_pos); 492987da915Sopenharmony_ci printf("\tMFT Zone Start: %lld\n", (long long)vol->mft_zone_start); 493987da915Sopenharmony_ci printf("\tMFT Zone End: %lld\n", (long long)vol->mft_zone_end); 494987da915Sopenharmony_ci printf("\tMFT Zone Position: %lld\n", (long long)vol->mft_zone_pos); 495987da915Sopenharmony_ci printf("\tCurrent Position in First Data Zone: %lld\n", 496987da915Sopenharmony_ci (long long)vol->data1_zone_pos); 497987da915Sopenharmony_ci printf("\tCurrent Position in Second Data Zone: %lld\n", 498987da915Sopenharmony_ci (long long)vol->data2_zone_pos); 499987da915Sopenharmony_ci printf("\tAllocated clusters %lld (%2.1lf%%)\n", 500987da915Sopenharmony_ci (long long)vol->mft_na->allocated_size 501987da915Sopenharmony_ci >> vol->cluster_size_bits, 502987da915Sopenharmony_ci 100.0*(vol->mft_na->allocated_size 503987da915Sopenharmony_ci >> vol->cluster_size_bits) 504987da915Sopenharmony_ci / vol->nr_clusters); 505987da915Sopenharmony_ci printf("\tLCN of Data Attribute for FILE_MFT: %lld\n", 506987da915Sopenharmony_ci (long long)vol->mft_lcn); 507987da915Sopenharmony_ci printf("\tFILE_MFTMirr Size: %d\n", vol->mftmirr_size); 508987da915Sopenharmony_ci printf("\tLCN of Data Attribute for File_MFTMirr: %lld\n", 509987da915Sopenharmony_ci (long long)vol->mftmirr_lcn); 510987da915Sopenharmony_ci printf("\tSize of Attribute Definition Table: %d\n", 511987da915Sopenharmony_ci (int)vol->attrdef_len); 512987da915Sopenharmony_ci printf("\tNumber of Attached Extent Inodes: %d\n", 513987da915Sopenharmony_ci (int)vol->mft_ni->nr_extents); 514987da915Sopenharmony_ci 515987da915Sopenharmony_ci printf("FILE_Bitmap Information \n"); 516987da915Sopenharmony_ci printf("\tFILE_Bitmap MFT Record Number: %llu\n", 517987da915Sopenharmony_ci (unsigned long long)vol->lcnbmp_ni->mft_no); 518987da915Sopenharmony_ci printf("\tState of FILE_Bitmap Inode: %lu\n", vol->lcnbmp_ni->state); 519987da915Sopenharmony_ci printf("\tLength of Attribute List: %u\n", 520987da915Sopenharmony_ci (unsigned int)vol->lcnbmp_ni->attr_list_size); 521987da915Sopenharmony_ci /* JPA printf("\tAttribute List: %s\n", vol->lcnbmp_ni->attr_list); */ 522987da915Sopenharmony_ci printf("\tNumber of Attached Extent Inodes: %d\n", 523987da915Sopenharmony_ci (int)vol->lcnbmp_ni->nr_extents); 524987da915Sopenharmony_ci /* FIXME: need to add code for the union if nr_extens != 0, but 525987da915Sopenharmony_ci i dont know if it will ever != 0 with FILE_Bitmap */ 526987da915Sopenharmony_ci 527987da915Sopenharmony_ci printf("FILE_Bitmap Data Attribute Information\n"); 528987da915Sopenharmony_ci printf("\tDecompressed Runlist: not done yet\n"); 529987da915Sopenharmony_ci printf("\tBase Inode: %llu\n", 530987da915Sopenharmony_ci (unsigned long long)vol->lcnbmp_na->ni->mft_no); 531987da915Sopenharmony_ci printf("\tAttribute Types: not done yet\n"); 532987da915Sopenharmony_ci //printf("\tAttribute Name: %s\n", vol->lcnbmp_na->name); 533987da915Sopenharmony_ci printf("\tAttribute Name Length: %u\n", 534987da915Sopenharmony_ci (unsigned int)vol->lcnbmp_na->name_len); 535987da915Sopenharmony_ci printf("\tAttribute State: %lu\n", vol->lcnbmp_na->state); 536987da915Sopenharmony_ci printf("\tAttribute Allocated Size: %lld\n", 537987da915Sopenharmony_ci (long long)vol->lcnbmp_na->allocated_size); 538987da915Sopenharmony_ci printf("\tAttribute Data Size: %lld\n", 539987da915Sopenharmony_ci (long long)vol->lcnbmp_na->data_size); 540987da915Sopenharmony_ci printf("\tAttribute Initialized Size: %lld\n", 541987da915Sopenharmony_ci (long long)vol->lcnbmp_na->initialized_size); 542987da915Sopenharmony_ci printf("\tAttribute Compressed Size: %lld\n", 543987da915Sopenharmony_ci (long long)vol->lcnbmp_na->compressed_size); 544987da915Sopenharmony_ci printf("\tCompression Block Size: %u\n", 545987da915Sopenharmony_ci (unsigned int)vol->lcnbmp_na->compression_block_size); 546987da915Sopenharmony_ci printf("\tCompression Block Size Bits: %u\n", 547987da915Sopenharmony_ci vol->lcnbmp_na->compression_block_size_bits); 548987da915Sopenharmony_ci printf("\tCompression Block Clusters: %u\n", 549987da915Sopenharmony_ci vol->lcnbmp_na->compression_block_clusters); 550987da915Sopenharmony_ci if (!ntfs_volume_get_free_space(vol)) 551987da915Sopenharmony_ci printf("\tFree Clusters: %lld (%2.1lf%%)\n", 552987da915Sopenharmony_ci (long long)vol->free_clusters, 553987da915Sopenharmony_ci 100.0*vol->free_clusters 554987da915Sopenharmony_ci /(double)vol->nr_clusters); 555987da915Sopenharmony_ci 556987da915Sopenharmony_ci //TODO: Still need to add a few more attributes 557987da915Sopenharmony_ci} 558987da915Sopenharmony_ci 559987da915Sopenharmony_ci/** 560987da915Sopenharmony_ci * ntfs_dump_flags - Dump flags for STANDARD_INFORMATION and FILE_NAME. 561987da915Sopenharmony_ci * @type: dump flags for this attribute type 562987da915Sopenharmony_ci * @flags: flags for dumping 563987da915Sopenharmony_ci */ 564987da915Sopenharmony_cistatic void ntfs_dump_flags(const char *indent, ATTR_TYPES type, le32 flags) 565987da915Sopenharmony_ci{ 566987da915Sopenharmony_ci const le32 original_flags = flags; 567987da915Sopenharmony_ci 568987da915Sopenharmony_ci printf("%sFile attributes:\t", indent); 569987da915Sopenharmony_ci if (flags & FILE_ATTR_READONLY) { 570987da915Sopenharmony_ci printf(" READONLY"); 571987da915Sopenharmony_ci flags &= ~FILE_ATTR_READONLY; 572987da915Sopenharmony_ci } 573987da915Sopenharmony_ci if (flags & FILE_ATTR_HIDDEN) { 574987da915Sopenharmony_ci printf(" HIDDEN"); 575987da915Sopenharmony_ci flags &= ~FILE_ATTR_HIDDEN; 576987da915Sopenharmony_ci } 577987da915Sopenharmony_ci if (flags & FILE_ATTR_SYSTEM) { 578987da915Sopenharmony_ci printf(" SYSTEM"); 579987da915Sopenharmony_ci flags &= ~FILE_ATTR_SYSTEM; 580987da915Sopenharmony_ci } 581987da915Sopenharmony_ci if (flags & FILE_ATTR_DIRECTORY) { 582987da915Sopenharmony_ci printf(" DIRECTORY"); 583987da915Sopenharmony_ci flags &= ~FILE_ATTR_DIRECTORY; 584987da915Sopenharmony_ci } 585987da915Sopenharmony_ci if (flags & FILE_ATTR_ARCHIVE) { 586987da915Sopenharmony_ci printf(" ARCHIVE"); 587987da915Sopenharmony_ci flags &= ~FILE_ATTR_ARCHIVE; 588987da915Sopenharmony_ci } 589987da915Sopenharmony_ci if (flags & FILE_ATTR_DEVICE) { 590987da915Sopenharmony_ci printf(" DEVICE"); 591987da915Sopenharmony_ci flags &= ~FILE_ATTR_DEVICE; 592987da915Sopenharmony_ci } 593987da915Sopenharmony_ci if (flags & FILE_ATTR_NORMAL) { 594987da915Sopenharmony_ci printf(" NORMAL"); 595987da915Sopenharmony_ci flags &= ~FILE_ATTR_NORMAL; 596987da915Sopenharmony_ci } 597987da915Sopenharmony_ci if (flags & FILE_ATTR_TEMPORARY) { 598987da915Sopenharmony_ci printf(" TEMPORARY"); 599987da915Sopenharmony_ci flags &= ~FILE_ATTR_TEMPORARY; 600987da915Sopenharmony_ci } 601987da915Sopenharmony_ci if (flags & FILE_ATTR_SPARSE_FILE) { 602987da915Sopenharmony_ci printf(" SPARSE_FILE"); 603987da915Sopenharmony_ci flags &= ~FILE_ATTR_SPARSE_FILE; 604987da915Sopenharmony_ci } 605987da915Sopenharmony_ci if (flags & FILE_ATTR_REPARSE_POINT) { 606987da915Sopenharmony_ci printf(" REPARSE_POINT"); 607987da915Sopenharmony_ci flags &= ~FILE_ATTR_REPARSE_POINT; 608987da915Sopenharmony_ci } 609987da915Sopenharmony_ci if (flags & FILE_ATTR_COMPRESSED) { 610987da915Sopenharmony_ci printf(" COMPRESSED"); 611987da915Sopenharmony_ci flags &= ~FILE_ATTR_COMPRESSED; 612987da915Sopenharmony_ci } 613987da915Sopenharmony_ci if (flags & FILE_ATTR_OFFLINE) { 614987da915Sopenharmony_ci printf(" OFFLINE"); 615987da915Sopenharmony_ci flags &= ~FILE_ATTR_OFFLINE; 616987da915Sopenharmony_ci } 617987da915Sopenharmony_ci if (flags & FILE_ATTR_NOT_CONTENT_INDEXED) { 618987da915Sopenharmony_ci printf(" NOT_CONTENT_INDEXED"); 619987da915Sopenharmony_ci flags &= ~FILE_ATTR_NOT_CONTENT_INDEXED; 620987da915Sopenharmony_ci } 621987da915Sopenharmony_ci if (flags & FILE_ATTR_ENCRYPTED) { 622987da915Sopenharmony_ci printf(" ENCRYPTED"); 623987da915Sopenharmony_ci flags &= ~FILE_ATTR_ENCRYPTED; 624987da915Sopenharmony_ci } 625987da915Sopenharmony_ci /* We know that FILE_ATTR_I30_INDEX_PRESENT only exists on $FILE_NAME, 626987da915Sopenharmony_ci and in case we are wrong, let it appear as UNKNOWN */ 627987da915Sopenharmony_ci if (type == AT_FILE_NAME) { 628987da915Sopenharmony_ci if (flags & FILE_ATTR_I30_INDEX_PRESENT) { 629987da915Sopenharmony_ci printf(" I30_INDEX"); 630987da915Sopenharmony_ci flags &= ~FILE_ATTR_I30_INDEX_PRESENT; 631987da915Sopenharmony_ci } 632987da915Sopenharmony_ci } 633987da915Sopenharmony_ci if (flags & FILE_ATTR_VIEW_INDEX_PRESENT) { 634987da915Sopenharmony_ci printf(" VIEW_INDEX"); 635987da915Sopenharmony_ci flags &= ~FILE_ATTR_VIEW_INDEX_PRESENT; 636987da915Sopenharmony_ci } 637987da915Sopenharmony_ci if (flags & FILE_ATTRIBUTE_RECALL_ON_OPEN) { 638987da915Sopenharmony_ci printf(" RECALL_ON_OPEN"); 639987da915Sopenharmony_ci flags &= ~FILE_ATTRIBUTE_RECALL_ON_OPEN; 640987da915Sopenharmony_ci } 641987da915Sopenharmony_ci if (flags) 642987da915Sopenharmony_ci printf(" UNKNOWN: 0x%08x", (unsigned int)le32_to_cpu(flags)); 643987da915Sopenharmony_ci /* Print all the flags in hex. */ 644987da915Sopenharmony_ci printf(" (0x%08x)\n", (unsigned)le32_to_cpu(original_flags)); 645987da915Sopenharmony_ci} 646987da915Sopenharmony_ci 647987da915Sopenharmony_ci/** 648987da915Sopenharmony_ci * ntfs_dump_namespace 649987da915Sopenharmony_ci */ 650987da915Sopenharmony_cistatic void ntfs_dump_namespace(const char *indent, u8 file_name_type) 651987da915Sopenharmony_ci{ 652987da915Sopenharmony_ci const char *mbs_file_type; 653987da915Sopenharmony_ci 654987da915Sopenharmony_ci /* name space */ 655987da915Sopenharmony_ci switch (file_name_type) { 656987da915Sopenharmony_ci case FILE_NAME_POSIX: 657987da915Sopenharmony_ci mbs_file_type = "POSIX"; 658987da915Sopenharmony_ci break; 659987da915Sopenharmony_ci case FILE_NAME_WIN32: 660987da915Sopenharmony_ci mbs_file_type = "Win32"; 661987da915Sopenharmony_ci break; 662987da915Sopenharmony_ci case FILE_NAME_DOS: 663987da915Sopenharmony_ci mbs_file_type = "DOS"; 664987da915Sopenharmony_ci break; 665987da915Sopenharmony_ci case FILE_NAME_WIN32_AND_DOS: 666987da915Sopenharmony_ci mbs_file_type = "Win32 & DOS"; 667987da915Sopenharmony_ci break; 668987da915Sopenharmony_ci default: 669987da915Sopenharmony_ci mbs_file_type = "(unknown)"; 670987da915Sopenharmony_ci } 671987da915Sopenharmony_ci printf("%sNamespace:\t\t %s\n", indent, mbs_file_type); 672987da915Sopenharmony_ci} 673987da915Sopenharmony_ci 674987da915Sopenharmony_ci/* *************** functions for dumping attributes ******************** */ 675987da915Sopenharmony_ci/** 676987da915Sopenharmony_ci * ntfs_dump_standard_information 677987da915Sopenharmony_ci */ 678987da915Sopenharmony_cistatic void ntfs_dump_attr_standard_information(ATTR_RECORD *attr) 679987da915Sopenharmony_ci{ 680987da915Sopenharmony_ci STANDARD_INFORMATION *standard_attr = NULL; 681987da915Sopenharmony_ci u32 value_length; 682987da915Sopenharmony_ci 683987da915Sopenharmony_ci standard_attr = (STANDARD_INFORMATION*)((char *)attr + 684987da915Sopenharmony_ci le16_to_cpu(attr->value_offset)); 685987da915Sopenharmony_ci 686987da915Sopenharmony_ci /* time conversion stuff */ 687987da915Sopenharmony_ci if (!opts.notime) { 688987da915Sopenharmony_ci char *ntfs_time_str = NULL; 689987da915Sopenharmony_ci 690987da915Sopenharmony_ci ntfs_time_str = ntfsinfo_time_to_str(standard_attr->creation_time); 691987da915Sopenharmony_ci printf("\tFile Creation Time:\t %s",ntfs_time_str); 692987da915Sopenharmony_ci 693987da915Sopenharmony_ci ntfs_time_str = ntfsinfo_time_to_str( 694987da915Sopenharmony_ci standard_attr->last_data_change_time); 695987da915Sopenharmony_ci printf("\tFile Altered Time:\t %s",ntfs_time_str); 696987da915Sopenharmony_ci 697987da915Sopenharmony_ci ntfs_time_str = ntfsinfo_time_to_str( 698987da915Sopenharmony_ci standard_attr->last_mft_change_time); 699987da915Sopenharmony_ci printf("\tMFT Changed Time:\t %s",ntfs_time_str); 700987da915Sopenharmony_ci 701987da915Sopenharmony_ci ntfs_time_str = ntfsinfo_time_to_str(standard_attr->last_access_time); 702987da915Sopenharmony_ci printf("\tLast Accessed Time:\t %s",ntfs_time_str); 703987da915Sopenharmony_ci } 704987da915Sopenharmony_ci ntfs_dump_flags("\t", attr->type, standard_attr->file_attributes); 705987da915Sopenharmony_ci 706987da915Sopenharmony_ci value_length = le32_to_cpu(attr->value_length); 707987da915Sopenharmony_ci if (value_length == 48) { 708987da915Sopenharmony_ci /* Only 12 reserved bytes here */ 709987da915Sopenharmony_ci } else if (value_length == 72) { 710987da915Sopenharmony_ci printf("\tMaximum versions:\t %u \n", (unsigned int) 711987da915Sopenharmony_ci le32_to_cpu(standard_attr->maximum_versions)); 712987da915Sopenharmony_ci printf("\tVersion number:\t\t %u \n", (unsigned int) 713987da915Sopenharmony_ci le32_to_cpu(standard_attr->version_number)); 714987da915Sopenharmony_ci printf("\tClass ID:\t\t %u \n", 715987da915Sopenharmony_ci (unsigned int)le32_to_cpu(standard_attr->class_id)); 716987da915Sopenharmony_ci printf("\tUser ID:\t\t %u (0x%x)\n", 717987da915Sopenharmony_ci (unsigned int)le32_to_cpu(standard_attr->owner_id), 718987da915Sopenharmony_ci (unsigned int)le32_to_cpu(standard_attr->owner_id)); 719987da915Sopenharmony_ci printf("\tSecurity ID:\t\t %u (0x%x)\n", 720987da915Sopenharmony_ci (unsigned int)le32_to_cpu(standard_attr->security_id), 721987da915Sopenharmony_ci (unsigned int)le32_to_cpu(standard_attr->security_id)); 722987da915Sopenharmony_ci printf("\tQuota charged:\t\t %llu (0x%llx)\n", 723987da915Sopenharmony_ci (unsigned long long) 724987da915Sopenharmony_ci le64_to_cpu(standard_attr->quota_charged), 725987da915Sopenharmony_ci (unsigned long long) 726987da915Sopenharmony_ci le64_to_cpu(standard_attr->quota_charged)); 727987da915Sopenharmony_ci printf("\tUpdate Sequence Number:\t %llu (0x%llx)\n", 728987da915Sopenharmony_ci (unsigned long long) 729987da915Sopenharmony_ci le64_to_cpu(standard_attr->usn), 730987da915Sopenharmony_ci (unsigned long long) 731987da915Sopenharmony_ci le64_to_cpu(standard_attr->usn)); 732987da915Sopenharmony_ci } else { 733987da915Sopenharmony_ci printf("\tSize of STANDARD_INFORMATION is %u (0x%x). It " 734987da915Sopenharmony_ci "should be either 72 or 48, something is " 735987da915Sopenharmony_ci "wrong...\n", (unsigned int)value_length, 736987da915Sopenharmony_ci (unsigned)value_length); 737987da915Sopenharmony_ci } 738987da915Sopenharmony_ci} 739987da915Sopenharmony_ci 740987da915Sopenharmony_cistatic void ntfs_dump_bytes(u8 *buf, int start, int stop) 741987da915Sopenharmony_ci{ 742987da915Sopenharmony_ci int i; 743987da915Sopenharmony_ci 744987da915Sopenharmony_ci for (i = start; i < stop; i++) { 745987da915Sopenharmony_ci printf("%02x ", buf[i]); 746987da915Sopenharmony_ci } 747987da915Sopenharmony_ci} 748987da915Sopenharmony_ci 749987da915Sopenharmony_ci/** 750987da915Sopenharmony_ci * ntfs_dump_attr_list() 751987da915Sopenharmony_ci */ 752987da915Sopenharmony_cistatic void ntfs_dump_attr_list(ATTR_RECORD *attr, ntfs_volume *vol) 753987da915Sopenharmony_ci{ 754987da915Sopenharmony_ci ATTR_LIST_ENTRY *entry; 755987da915Sopenharmony_ci u8 *value; 756987da915Sopenharmony_ci s64 l; 757987da915Sopenharmony_ci 758987da915Sopenharmony_ci if (!opts.verbose) 759987da915Sopenharmony_ci return; 760987da915Sopenharmony_ci 761987da915Sopenharmony_ci l = ntfs_get_attribute_value_length(attr); 762987da915Sopenharmony_ci if (!l) { 763987da915Sopenharmony_ci ntfs_log_perror("ntfs_get_attribute_value_length failed"); 764987da915Sopenharmony_ci return; 765987da915Sopenharmony_ci } 766987da915Sopenharmony_ci value = ntfs_malloc(l); 767987da915Sopenharmony_ci if (!value) 768987da915Sopenharmony_ci return; 769987da915Sopenharmony_ci 770987da915Sopenharmony_ci l = ntfs_get_attribute_value(vol, attr, value); 771987da915Sopenharmony_ci if (!l) { 772987da915Sopenharmony_ci ntfs_log_perror("ntfs_get_attribute_value failed"); 773987da915Sopenharmony_ci free(value); 774987da915Sopenharmony_ci return; 775987da915Sopenharmony_ci } 776987da915Sopenharmony_ci printf("\tDumping attribute list:"); 777987da915Sopenharmony_ci entry = (ATTR_LIST_ENTRY *) value; 778987da915Sopenharmony_ci for (;(u8 *)entry < (u8 *) value + l; entry = (ATTR_LIST_ENTRY *) 779987da915Sopenharmony_ci ((u8 *) entry + le16_to_cpu(entry->length))) { 780987da915Sopenharmony_ci printf("\n"); 781987da915Sopenharmony_ci printf("\t\tAttribute type:\t0x%x\n", 782987da915Sopenharmony_ci (unsigned int)le32_to_cpu(entry->type)); 783987da915Sopenharmony_ci printf("\t\tRecord length:\t%u (0x%x)\n", 784987da915Sopenharmony_ci (unsigned)le16_to_cpu(entry->length), 785987da915Sopenharmony_ci (unsigned)le16_to_cpu(entry->length)); 786987da915Sopenharmony_ci printf("\t\tName length:\t%u (0x%x)\n", 787987da915Sopenharmony_ci (unsigned)entry->name_length, 788987da915Sopenharmony_ci (unsigned)entry->name_length); 789987da915Sopenharmony_ci printf("\t\tName offset:\t%u (0x%x)\n", 790987da915Sopenharmony_ci (unsigned)entry->name_offset, 791987da915Sopenharmony_ci (unsigned)entry->name_offset); 792987da915Sopenharmony_ci printf("\t\tStarting VCN:\t%lld (0x%llx)\n", 793987da915Sopenharmony_ci (long long)sle64_to_cpu(entry->lowest_vcn), 794987da915Sopenharmony_ci (unsigned long long) 795987da915Sopenharmony_ci sle64_to_cpu(entry->lowest_vcn)); 796987da915Sopenharmony_ci printf("\t\tMFT reference:\t%lld (0x%llx)\n", 797987da915Sopenharmony_ci (unsigned long long) 798987da915Sopenharmony_ci MREF_LE(entry->mft_reference), 799987da915Sopenharmony_ci (unsigned long long) 800987da915Sopenharmony_ci MREF_LE(entry->mft_reference)); 801987da915Sopenharmony_ci printf("\t\tInstance:\t%u (0x%x)\n", 802987da915Sopenharmony_ci (unsigned)le16_to_cpu(entry->instance), 803987da915Sopenharmony_ci (unsigned)le16_to_cpu(entry->instance)); 804987da915Sopenharmony_ci printf("\t\tName:\t\t"); 805987da915Sopenharmony_ci if (entry->name_length) { 806987da915Sopenharmony_ci char *name = NULL; 807987da915Sopenharmony_ci int name_size; 808987da915Sopenharmony_ci 809987da915Sopenharmony_ci name_size = ntfs_ucstombs(entry->name, 810987da915Sopenharmony_ci entry->name_length, &name, 0); 811987da915Sopenharmony_ci 812987da915Sopenharmony_ci if (name_size > 0) { 813987da915Sopenharmony_ci printf("%s\n", name); 814987da915Sopenharmony_ci free(name); 815987da915Sopenharmony_ci } else 816987da915Sopenharmony_ci ntfs_log_perror("ntfs_ucstombs failed"); 817987da915Sopenharmony_ci } else 818987da915Sopenharmony_ci printf("unnamed\n"); 819987da915Sopenharmony_ci printf("\t\tPadding:\t"); 820987da915Sopenharmony_ci ntfs_dump_bytes((u8 *)entry, entry->name_offset + 821987da915Sopenharmony_ci sizeof(ntfschar) * entry->name_length, 822987da915Sopenharmony_ci le16_to_cpu(entry->length)); 823987da915Sopenharmony_ci printf("\n"); 824987da915Sopenharmony_ci } 825987da915Sopenharmony_ci free(value); 826987da915Sopenharmony_ci printf("\tEnd of attribute list reached.\n"); 827987da915Sopenharmony_ci} 828987da915Sopenharmony_ci 829987da915Sopenharmony_ci/** 830987da915Sopenharmony_ci * ntfs_dump_filename() 831987da915Sopenharmony_ci */ 832987da915Sopenharmony_cistatic void ntfs_dump_filename(const char *indent, 833987da915Sopenharmony_ci FILE_NAME_ATTR *file_name_attr) 834987da915Sopenharmony_ci{ 835987da915Sopenharmony_ci le32 tag; 836987da915Sopenharmony_ci 837987da915Sopenharmony_ci printf("%sParent directory:\t %lld (0x%llx)\n", indent, 838987da915Sopenharmony_ci (long long)MREF_LE(file_name_attr->parent_directory), 839987da915Sopenharmony_ci (long long)MREF_LE(file_name_attr->parent_directory)); 840987da915Sopenharmony_ci /* time stuff */ 841987da915Sopenharmony_ci if (!opts.notime) { 842987da915Sopenharmony_ci char *ntfs_time_str; 843987da915Sopenharmony_ci 844987da915Sopenharmony_ci ntfs_time_str = ntfsinfo_time_to_str( 845987da915Sopenharmony_ci file_name_attr->creation_time); 846987da915Sopenharmony_ci printf("%sFile Creation Time:\t %s", indent, ntfs_time_str); 847987da915Sopenharmony_ci 848987da915Sopenharmony_ci ntfs_time_str = ntfsinfo_time_to_str( 849987da915Sopenharmony_ci file_name_attr->last_data_change_time); 850987da915Sopenharmony_ci printf("%sFile Altered Time:\t %s", indent, ntfs_time_str); 851987da915Sopenharmony_ci 852987da915Sopenharmony_ci ntfs_time_str = ntfsinfo_time_to_str( 853987da915Sopenharmony_ci file_name_attr->last_mft_change_time); 854987da915Sopenharmony_ci printf("%sMFT Changed Time:\t %s", indent, ntfs_time_str); 855987da915Sopenharmony_ci 856987da915Sopenharmony_ci ntfs_time_str = ntfsinfo_time_to_str( 857987da915Sopenharmony_ci file_name_attr->last_access_time); 858987da915Sopenharmony_ci printf("%sLast Accessed Time:\t %s", indent, ntfs_time_str); 859987da915Sopenharmony_ci } 860987da915Sopenharmony_ci /* other basic stuff about the file */ 861987da915Sopenharmony_ci printf("%sAllocated Size:\t\t %lld (0x%llx)\n", indent, (long long) 862987da915Sopenharmony_ci sle64_to_cpu(file_name_attr->allocated_size), 863987da915Sopenharmony_ci (unsigned long long) 864987da915Sopenharmony_ci sle64_to_cpu(file_name_attr->allocated_size)); 865987da915Sopenharmony_ci printf("%sData Size:\t\t %lld (0x%llx)\n", indent, 866987da915Sopenharmony_ci (long long)sle64_to_cpu(file_name_attr->data_size), 867987da915Sopenharmony_ci (unsigned long long) 868987da915Sopenharmony_ci sle64_to_cpu(file_name_attr->data_size)); 869987da915Sopenharmony_ci printf("%sFilename Length:\t %d (0x%x)\n", indent, 870987da915Sopenharmony_ci (unsigned)file_name_attr->file_name_length, 871987da915Sopenharmony_ci (unsigned)file_name_attr->file_name_length); 872987da915Sopenharmony_ci ntfs_dump_flags(indent, AT_FILE_NAME, file_name_attr->file_attributes); 873987da915Sopenharmony_ci if (file_name_attr->file_attributes & FILE_ATTR_REPARSE_POINT && 874987da915Sopenharmony_ci file_name_attr->reparse_point_tag) { 875987da915Sopenharmony_ci tag = file_name_attr->reparse_point_tag; 876987da915Sopenharmony_ci printf("%sReparse point tag:\t 0x%08lx%s\n", indent, 877987da915Sopenharmony_ci (long)le32_to_cpu(tag), 878987da915Sopenharmony_ci reparse_type_name(tag)); 879987da915Sopenharmony_ci } else if (file_name_attr->reparse_point_tag) { 880987da915Sopenharmony_ci printf("%sEA Length:\t\t %d (0x%x)\n", indent, (unsigned) 881987da915Sopenharmony_ci le16_to_cpu(file_name_attr->packed_ea_size), 882987da915Sopenharmony_ci (unsigned) 883987da915Sopenharmony_ci le16_to_cpu(file_name_attr->packed_ea_size)); 884987da915Sopenharmony_ci if (file_name_attr->reserved) 885987da915Sopenharmony_ci printf("%sReserved:\t\t %d (0x%x)\n", indent, 886987da915Sopenharmony_ci (unsigned) 887987da915Sopenharmony_ci le16_to_cpu(file_name_attr->reserved), 888987da915Sopenharmony_ci (unsigned) 889987da915Sopenharmony_ci le16_to_cpu(file_name_attr->reserved)); 890987da915Sopenharmony_ci } 891987da915Sopenharmony_ci /* The filename. */ 892987da915Sopenharmony_ci ntfs_dump_namespace(indent, file_name_attr->file_name_type); 893987da915Sopenharmony_ci if (file_name_attr->file_name_length > 0) { 894987da915Sopenharmony_ci /* but first we need to convert the little endian unicode string 895987da915Sopenharmony_ci into a printable format */ 896987da915Sopenharmony_ci char *mbs_file_name = NULL; 897987da915Sopenharmony_ci int mbs_file_name_size; 898987da915Sopenharmony_ci 899987da915Sopenharmony_ci mbs_file_name_size = ntfs_ucstombs(file_name_attr->file_name, 900987da915Sopenharmony_ci file_name_attr->file_name_length,&mbs_file_name,0); 901987da915Sopenharmony_ci 902987da915Sopenharmony_ci if (mbs_file_name_size>0) { 903987da915Sopenharmony_ci printf("%sFilename:\t\t '%s'\n", indent, mbs_file_name); 904987da915Sopenharmony_ci free(mbs_file_name); 905987da915Sopenharmony_ci } else { 906987da915Sopenharmony_ci /* an error occurred, errno holds the reason - notify the user */ 907987da915Sopenharmony_ci ntfs_log_perror("ntfsinfo error: could not parse file name"); 908987da915Sopenharmony_ci } 909987da915Sopenharmony_ci } else { 910987da915Sopenharmony_ci printf("%sFile Name:\t\t unnamed?!?\n", indent); 911987da915Sopenharmony_ci } 912987da915Sopenharmony_ci} 913987da915Sopenharmony_ci 914987da915Sopenharmony_ci/** 915987da915Sopenharmony_ci * ntfs_dump_attr_file_name() 916987da915Sopenharmony_ci */ 917987da915Sopenharmony_cistatic void ntfs_dump_attr_file_name(ATTR_RECORD *attr) 918987da915Sopenharmony_ci{ 919987da915Sopenharmony_ci ntfs_dump_filename("\t", (FILE_NAME_ATTR*)((u8*)attr + 920987da915Sopenharmony_ci le16_to_cpu(attr->value_offset))); 921987da915Sopenharmony_ci} 922987da915Sopenharmony_ci 923987da915Sopenharmony_ci/** 924987da915Sopenharmony_ci * ntfs_dump_object_id 925987da915Sopenharmony_ci * 926987da915Sopenharmony_ci * dump the $OBJECT_ID attribute - not present on all systems 927987da915Sopenharmony_ci */ 928987da915Sopenharmony_cistatic void ntfs_dump_attr_object_id(ATTR_RECORD *attr,ntfs_volume *vol) 929987da915Sopenharmony_ci{ 930987da915Sopenharmony_ci OBJECT_ID_ATTR *obj_id_attr = NULL; 931987da915Sopenharmony_ci 932987da915Sopenharmony_ci obj_id_attr = (OBJECT_ID_ATTR *)((u8*)attr + 933987da915Sopenharmony_ci le16_to_cpu(attr->value_offset)); 934987da915Sopenharmony_ci 935987da915Sopenharmony_ci if (vol->major_ver >= 3.0) { 936987da915Sopenharmony_ci u32 value_length; 937987da915Sopenharmony_ci char printable_GUID[37]; 938987da915Sopenharmony_ci 939987da915Sopenharmony_ci value_length = le32_to_cpu(attr->value_length); 940987da915Sopenharmony_ci 941987da915Sopenharmony_ci /* Object ID is mandatory. */ 942987da915Sopenharmony_ci ntfs_guid_to_mbs(&obj_id_attr->object_id, printable_GUID); 943987da915Sopenharmony_ci printf("\tObject ID:\t\t %s\n", printable_GUID); 944987da915Sopenharmony_ci 945987da915Sopenharmony_ci /* Dump Birth Volume ID. */ 946987da915Sopenharmony_ci if ((value_length > sizeof(GUID)) && !ntfs_guid_is_zero( 947987da915Sopenharmony_ci &obj_id_attr->birth_volume_id)) { 948987da915Sopenharmony_ci ntfs_guid_to_mbs(&obj_id_attr->birth_volume_id, 949987da915Sopenharmony_ci printable_GUID); 950987da915Sopenharmony_ci printf("\tBirth Volume ID:\t\t %s\n", printable_GUID); 951987da915Sopenharmony_ci } else 952987da915Sopenharmony_ci printf("\tBirth Volume ID:\t missing\n"); 953987da915Sopenharmony_ci 954987da915Sopenharmony_ci /* Dumping Birth Object ID */ 955987da915Sopenharmony_ci if ((value_length > sizeof(GUID)) && !ntfs_guid_is_zero( 956987da915Sopenharmony_ci &obj_id_attr->birth_object_id)) { 957987da915Sopenharmony_ci ntfs_guid_to_mbs(&obj_id_attr->birth_object_id, 958987da915Sopenharmony_ci printable_GUID); 959987da915Sopenharmony_ci printf("\tBirth Object ID:\t\t %s\n", printable_GUID); 960987da915Sopenharmony_ci } else 961987da915Sopenharmony_ci printf("\tBirth Object ID:\t missing\n"); 962987da915Sopenharmony_ci 963987da915Sopenharmony_ci /* Dumping Domain_id - reserved for now */ 964987da915Sopenharmony_ci if ((value_length > sizeof(GUID)) && !ntfs_guid_is_zero( 965987da915Sopenharmony_ci &obj_id_attr->domain_id)) { 966987da915Sopenharmony_ci ntfs_guid_to_mbs(&obj_id_attr->domain_id, 967987da915Sopenharmony_ci printable_GUID); 968987da915Sopenharmony_ci printf("\tDomain ID:\t\t\t %s\n", printable_GUID); 969987da915Sopenharmony_ci } else 970987da915Sopenharmony_ci printf("\tDomain ID:\t\t missing\n"); 971987da915Sopenharmony_ci } else 972987da915Sopenharmony_ci printf("\t$OBJECT_ID not present. Only NTFS versions > 3.0\n" 973987da915Sopenharmony_ci "\thave $OBJECT_ID. Your version of NTFS is %d.\n", 974987da915Sopenharmony_ci vol->major_ver); 975987da915Sopenharmony_ci} 976987da915Sopenharmony_ci 977987da915Sopenharmony_ci/** 978987da915Sopenharmony_ci * ntfs_dump_acl 979987da915Sopenharmony_ci * 980987da915Sopenharmony_ci * given an acl, print it in a beautiful & lovely way. 981987da915Sopenharmony_ci */ 982987da915Sopenharmony_cistatic void ntfs_dump_acl(const char *prefix, ACL *acl) 983987da915Sopenharmony_ci{ 984987da915Sopenharmony_ci unsigned int i; 985987da915Sopenharmony_ci u16 ace_count; 986987da915Sopenharmony_ci ACCESS_ALLOWED_ACE *ace; 987987da915Sopenharmony_ci 988987da915Sopenharmony_ci printf("%sRevision\t %u\n", prefix, acl->revision); 989987da915Sopenharmony_ci 990987da915Sopenharmony_ci /* 991987da915Sopenharmony_ci * Do not recalculate le16_to_cpu every iteration (minor speedup on 992987da915Sopenharmony_ci * big-endian machines. 993987da915Sopenharmony_ci */ 994987da915Sopenharmony_ci ace_count = le16_to_cpu(acl->ace_count); 995987da915Sopenharmony_ci 996987da915Sopenharmony_ci /* initialize 'ace' to the first ace (if any) */ 997987da915Sopenharmony_ci ace = (ACCESS_ALLOWED_ACE *)((char *)acl + 8); 998987da915Sopenharmony_ci 999987da915Sopenharmony_ci /* iterate through ACE's */ 1000987da915Sopenharmony_ci for (i = 1; i <= ace_count; i++) { 1001987da915Sopenharmony_ci const char *ace_type; 1002987da915Sopenharmony_ci char *sid; 1003987da915Sopenharmony_ci 1004987da915Sopenharmony_ci /* set ace_type. */ 1005987da915Sopenharmony_ci switch (ace->type) { 1006987da915Sopenharmony_ci case ACCESS_ALLOWED_ACE_TYPE: 1007987da915Sopenharmony_ci ace_type = "allow"; 1008987da915Sopenharmony_ci break; 1009987da915Sopenharmony_ci case ACCESS_DENIED_ACE_TYPE: 1010987da915Sopenharmony_ci ace_type = "deny"; 1011987da915Sopenharmony_ci break; 1012987da915Sopenharmony_ci case SYSTEM_AUDIT_ACE_TYPE: 1013987da915Sopenharmony_ci ace_type = "audit"; 1014987da915Sopenharmony_ci break; 1015987da915Sopenharmony_ci default: 1016987da915Sopenharmony_ci ace_type = "unknown"; 1017987da915Sopenharmony_ci break; 1018987da915Sopenharmony_ci } 1019987da915Sopenharmony_ci 1020987da915Sopenharmony_ci printf("%sACE:\t\t type:%s flags:0x%x access:0x%x\n", prefix, 1021987da915Sopenharmony_ci ace_type, (unsigned int)ace->flags, 1022987da915Sopenharmony_ci (unsigned int)le32_to_cpu(ace->mask)); 1023987da915Sopenharmony_ci /* get a SID string */ 1024987da915Sopenharmony_ci sid = ntfs_sid_to_mbs(&ace->sid, NULL, 0); 1025987da915Sopenharmony_ci printf("%s\t\t SID: %s\n", prefix, sid); 1026987da915Sopenharmony_ci free(sid); 1027987da915Sopenharmony_ci 1028987da915Sopenharmony_ci /* proceed to next ACE */ 1029987da915Sopenharmony_ci ace = (ACCESS_ALLOWED_ACE *)(((char *)ace) + 1030987da915Sopenharmony_ci le16_to_cpu(ace->size)); 1031987da915Sopenharmony_ci } 1032987da915Sopenharmony_ci} 1033987da915Sopenharmony_ci 1034987da915Sopenharmony_ci 1035987da915Sopenharmony_cistatic void ntfs_dump_security_descriptor(SECURITY_DESCRIPTOR_ATTR *sec_desc, 1036987da915Sopenharmony_ci const char *indent) 1037987da915Sopenharmony_ci{ 1038987da915Sopenharmony_ci char *sid; 1039987da915Sopenharmony_ci 1040987da915Sopenharmony_ci printf("%s\tRevision:\t\t %u\n", indent, sec_desc->revision); 1041987da915Sopenharmony_ci 1042987da915Sopenharmony_ci /* TODO: parse the flags */ 1043987da915Sopenharmony_ci printf("%s\tControl:\t\t 0x%04x\n", indent, 1044987da915Sopenharmony_ci le16_to_cpu(sec_desc->control)); 1045987da915Sopenharmony_ci 1046987da915Sopenharmony_ci if (~sec_desc->control & SE_SELF_RELATIVE) { 1047987da915Sopenharmony_ci SECURITY_DESCRIPTOR *sd = (SECURITY_DESCRIPTOR *)sec_desc; 1048987da915Sopenharmony_ci 1049987da915Sopenharmony_ci printf("%s\tOwner SID pointer:\t %p\n", indent, sd->owner); 1050987da915Sopenharmony_ci printf("%s\tGroup SID pointer:\t %p\n", indent, sd->group); 1051987da915Sopenharmony_ci printf("%s\tSACL pointer:\t\t %p\n", indent, sd->sacl); 1052987da915Sopenharmony_ci printf("%s\tDACL pointer:\t\t %p\n", indent, sd->dacl); 1053987da915Sopenharmony_ci 1054987da915Sopenharmony_ci return; 1055987da915Sopenharmony_ci } 1056987da915Sopenharmony_ci 1057987da915Sopenharmony_ci if (sec_desc->owner) { 1058987da915Sopenharmony_ci sid = ntfs_sid_to_mbs((SID *)((char *)sec_desc + 1059987da915Sopenharmony_ci le32_to_cpu(sec_desc->owner)), NULL, 0); 1060987da915Sopenharmony_ci printf("%s\tOwner SID:\t\t %s\n", indent, sid); 1061987da915Sopenharmony_ci free(sid); 1062987da915Sopenharmony_ci } else 1063987da915Sopenharmony_ci printf("%s\tOwner SID:\t\t missing\n", indent); 1064987da915Sopenharmony_ci 1065987da915Sopenharmony_ci if (sec_desc->group) { 1066987da915Sopenharmony_ci sid = ntfs_sid_to_mbs((SID *)((char *)sec_desc + 1067987da915Sopenharmony_ci le32_to_cpu(sec_desc->group)), NULL, 0); 1068987da915Sopenharmony_ci printf("%s\tGroup SID:\t\t %s\n", indent, sid); 1069987da915Sopenharmony_ci free(sid); 1070987da915Sopenharmony_ci } else 1071987da915Sopenharmony_ci printf("%s\tGroup SID:\t\t missing\n", indent); 1072987da915Sopenharmony_ci 1073987da915Sopenharmony_ci printf("%s\tSystem ACL:\t\t ", indent); 1074987da915Sopenharmony_ci if (sec_desc->control & SE_SACL_PRESENT) { 1075987da915Sopenharmony_ci if (sec_desc->control & SE_SACL_DEFAULTED) { 1076987da915Sopenharmony_ci printf("defaulted"); 1077987da915Sopenharmony_ci } 1078987da915Sopenharmony_ci printf("\n"); 1079987da915Sopenharmony_ci ntfs_dump_acl(indent ? "\t\t\t" : "\t\t", 1080987da915Sopenharmony_ci (ACL *)((char *)sec_desc + 1081987da915Sopenharmony_ci le32_to_cpu(sec_desc->sacl))); 1082987da915Sopenharmony_ci } else { 1083987da915Sopenharmony_ci printf("missing\n"); 1084987da915Sopenharmony_ci } 1085987da915Sopenharmony_ci 1086987da915Sopenharmony_ci printf("%s\tDiscretionary ACL:\t ", indent); 1087987da915Sopenharmony_ci if (sec_desc->control & SE_DACL_PRESENT) { 1088987da915Sopenharmony_ci if (sec_desc->control & SE_SACL_DEFAULTED) { 1089987da915Sopenharmony_ci printf("defaulted"); 1090987da915Sopenharmony_ci } 1091987da915Sopenharmony_ci printf("\n"); 1092987da915Sopenharmony_ci ntfs_dump_acl(indent ? "\t\t\t" : "\t\t", 1093987da915Sopenharmony_ci (ACL *)((char *)sec_desc + 1094987da915Sopenharmony_ci le32_to_cpu(sec_desc->dacl))); 1095987da915Sopenharmony_ci } else { 1096987da915Sopenharmony_ci printf("missing\n"); 1097987da915Sopenharmony_ci } 1098987da915Sopenharmony_ci} 1099987da915Sopenharmony_ci 1100987da915Sopenharmony_ci/** 1101987da915Sopenharmony_ci * ntfs_dump_security_descriptor() 1102987da915Sopenharmony_ci * 1103987da915Sopenharmony_ci * dump the security information about the file 1104987da915Sopenharmony_ci */ 1105987da915Sopenharmony_cistatic void ntfs_dump_attr_security_descriptor(ATTR_RECORD *attr, ntfs_volume *vol) 1106987da915Sopenharmony_ci{ 1107987da915Sopenharmony_ci SECURITY_DESCRIPTOR_ATTR *sec_desc_attr; 1108987da915Sopenharmony_ci 1109987da915Sopenharmony_ci if (attr->non_resident) { 1110987da915Sopenharmony_ci /* FIXME: We don't handle fragmented mapping pairs case. */ 1111987da915Sopenharmony_ci runlist *rl = ntfs_mapping_pairs_decompress(vol, attr, NULL); 1112987da915Sopenharmony_ci if (rl) { 1113987da915Sopenharmony_ci s64 data_size, bytes_read; 1114987da915Sopenharmony_ci 1115987da915Sopenharmony_ci data_size = sle64_to_cpu(attr->data_size); 1116987da915Sopenharmony_ci sec_desc_attr = ntfs_malloc(data_size); 1117987da915Sopenharmony_ci if (!sec_desc_attr) { 1118987da915Sopenharmony_ci free(rl); 1119987da915Sopenharmony_ci return; 1120987da915Sopenharmony_ci } 1121987da915Sopenharmony_ci bytes_read = ntfs_rl_pread(vol, rl, 0, 1122987da915Sopenharmony_ci data_size, sec_desc_attr); 1123987da915Sopenharmony_ci if (bytes_read != data_size) { 1124987da915Sopenharmony_ci ntfs_log_error("ntfsinfo error: could not " 1125987da915Sopenharmony_ci "read security descriptor\n"); 1126987da915Sopenharmony_ci free(rl); 1127987da915Sopenharmony_ci free(sec_desc_attr); 1128987da915Sopenharmony_ci return; 1129987da915Sopenharmony_ci } 1130987da915Sopenharmony_ci free(rl); 1131987da915Sopenharmony_ci } else { 1132987da915Sopenharmony_ci ntfs_log_error("ntfsinfo error: could not " 1133987da915Sopenharmony_ci "decompress runlist\n"); 1134987da915Sopenharmony_ci return; 1135987da915Sopenharmony_ci } 1136987da915Sopenharmony_ci } else { 1137987da915Sopenharmony_ci sec_desc_attr = (SECURITY_DESCRIPTOR_ATTR *)((u8*)attr + 1138987da915Sopenharmony_ci le16_to_cpu(attr->value_offset)); 1139987da915Sopenharmony_ci } 1140987da915Sopenharmony_ci 1141987da915Sopenharmony_ci ntfs_dump_security_descriptor(sec_desc_attr, ""); 1142987da915Sopenharmony_ci 1143987da915Sopenharmony_ci if (attr->non_resident) 1144987da915Sopenharmony_ci free(sec_desc_attr); 1145987da915Sopenharmony_ci} 1146987da915Sopenharmony_ci 1147987da915Sopenharmony_ci/** 1148987da915Sopenharmony_ci * ntfs_dump_volume_name() 1149987da915Sopenharmony_ci * 1150987da915Sopenharmony_ci * dump the name of the volume the inode belongs to 1151987da915Sopenharmony_ci */ 1152987da915Sopenharmony_cistatic void ntfs_dump_attr_volume_name(ATTR_RECORD *attr) 1153987da915Sopenharmony_ci{ 1154987da915Sopenharmony_ci ntfschar *ucs_vol_name = NULL; 1155987da915Sopenharmony_ci 1156987da915Sopenharmony_ci if (le32_to_cpu(attr->value_length) > 0) { 1157987da915Sopenharmony_ci char *mbs_vol_name = NULL; 1158987da915Sopenharmony_ci int mbs_vol_name_size; 1159987da915Sopenharmony_ci /* calculate volume name position */ 1160987da915Sopenharmony_ci ucs_vol_name = (ntfschar*)((u8*)attr + 1161987da915Sopenharmony_ci le16_to_cpu(attr->value_offset)); 1162987da915Sopenharmony_ci /* convert the name to current locale multibyte sequence */ 1163987da915Sopenharmony_ci mbs_vol_name_size = ntfs_ucstombs(ucs_vol_name, 1164987da915Sopenharmony_ci le32_to_cpu(attr->value_length) / 1165987da915Sopenharmony_ci sizeof(ntfschar), &mbs_vol_name, 0); 1166987da915Sopenharmony_ci 1167987da915Sopenharmony_ci if (mbs_vol_name_size>0) { 1168987da915Sopenharmony_ci /* output the converted name. */ 1169987da915Sopenharmony_ci printf("\tVolume Name:\t\t '%s'\n", mbs_vol_name); 1170987da915Sopenharmony_ci free(mbs_vol_name); 1171987da915Sopenharmony_ci } else 1172987da915Sopenharmony_ci ntfs_log_perror("ntfsinfo error: could not parse " 1173987da915Sopenharmony_ci "volume name"); 1174987da915Sopenharmony_ci } else 1175987da915Sopenharmony_ci printf("\tVolume Name:\t\t unnamed\n"); 1176987da915Sopenharmony_ci} 1177987da915Sopenharmony_ci 1178987da915Sopenharmony_ci/** 1179987da915Sopenharmony_ci * ntfs_dump_volume_information() 1180987da915Sopenharmony_ci * 1181987da915Sopenharmony_ci * dump the information for the volume the inode belongs to 1182987da915Sopenharmony_ci * 1183987da915Sopenharmony_ci */ 1184987da915Sopenharmony_cistatic void ntfs_dump_attr_volume_information(ATTR_RECORD *attr) 1185987da915Sopenharmony_ci{ 1186987da915Sopenharmony_ci VOLUME_INFORMATION *vol_information = NULL; 1187987da915Sopenharmony_ci 1188987da915Sopenharmony_ci vol_information = (VOLUME_INFORMATION*)((char *)attr+ 1189987da915Sopenharmony_ci le16_to_cpu(attr->value_offset)); 1190987da915Sopenharmony_ci 1191987da915Sopenharmony_ci printf("\tVolume Version:\t\t %d.%d\n", vol_information->major_ver, 1192987da915Sopenharmony_ci vol_information->minor_ver); 1193987da915Sopenharmony_ci printf("\tVolume Flags:\t\t "); 1194987da915Sopenharmony_ci if (vol_information->flags & VOLUME_IS_DIRTY) 1195987da915Sopenharmony_ci printf("DIRTY "); 1196987da915Sopenharmony_ci if (vol_information->flags & VOLUME_RESIZE_LOG_FILE) 1197987da915Sopenharmony_ci printf("RESIZE_LOG "); 1198987da915Sopenharmony_ci if (vol_information->flags & VOLUME_UPGRADE_ON_MOUNT) 1199987da915Sopenharmony_ci printf("UPG_ON_MOUNT "); 1200987da915Sopenharmony_ci if (vol_information->flags & VOLUME_MOUNTED_ON_NT4) 1201987da915Sopenharmony_ci printf("MOUNTED_NT4 "); 1202987da915Sopenharmony_ci if (vol_information->flags & VOLUME_DELETE_USN_UNDERWAY) 1203987da915Sopenharmony_ci printf("DEL_USN "); 1204987da915Sopenharmony_ci if (vol_information->flags & VOLUME_REPAIR_OBJECT_ID) 1205987da915Sopenharmony_ci printf("REPAIR_OBJID "); 1206987da915Sopenharmony_ci if (vol_information->flags & VOLUME_CHKDSK_UNDERWAY) 1207987da915Sopenharmony_ci printf("CHKDSK_UNDERWAY "); 1208987da915Sopenharmony_ci if (vol_information->flags & VOLUME_MODIFIED_BY_CHKDSK) 1209987da915Sopenharmony_ci printf("MOD_BY_CHKDSK "); 1210987da915Sopenharmony_ci if (vol_information->flags & VOLUME_FLAGS_MASK) { 1211987da915Sopenharmony_ci printf("(0x%04x)\n", 1212987da915Sopenharmony_ci (unsigned)le16_to_cpu(vol_information->flags)); 1213987da915Sopenharmony_ci } else 1214987da915Sopenharmony_ci printf("none set (0x0000)\n"); 1215987da915Sopenharmony_ci if (vol_information->flags & (~VOLUME_FLAGS_MASK)) 1216987da915Sopenharmony_ci printf("\t\t\t\t Unknown Flags: 0x%04x\n", 1217987da915Sopenharmony_ci le16_to_cpu(vol_information->flags & 1218987da915Sopenharmony_ci (~VOLUME_FLAGS_MASK))); 1219987da915Sopenharmony_ci} 1220987da915Sopenharmony_ci 1221987da915Sopenharmony_cistatic ntfschar NTFS_DATA_SDS[5] = { const_cpu_to_le16('$'), 1222987da915Sopenharmony_ci const_cpu_to_le16('S'), const_cpu_to_le16('D'), 1223987da915Sopenharmony_ci const_cpu_to_le16('S'), const_cpu_to_le16('\0') }; 1224987da915Sopenharmony_ci 1225987da915Sopenharmony_cistatic void ntfs_dump_sds_entry(SECURITY_DESCRIPTOR_HEADER *sds) 1226987da915Sopenharmony_ci{ 1227987da915Sopenharmony_ci SECURITY_DESCRIPTOR_RELATIVE *sd; 1228987da915Sopenharmony_ci 1229987da915Sopenharmony_ci ntfs_log_verbose("\n"); 1230987da915Sopenharmony_ci ntfs_log_verbose("\t\tHash:\t\t\t 0x%08x\n", 1231987da915Sopenharmony_ci (unsigned)le32_to_cpu(sds->hash)); 1232987da915Sopenharmony_ci ntfs_log_verbose("\t\tSecurity id:\t\t %u (0x%x)\n", 1233987da915Sopenharmony_ci (unsigned)le32_to_cpu(sds->security_id), 1234987da915Sopenharmony_ci (unsigned)le32_to_cpu(sds->security_id)); 1235987da915Sopenharmony_ci ntfs_log_verbose("\t\tOffset:\t\t\t %llu (0x%llx)\n", 1236987da915Sopenharmony_ci (unsigned long long)le64_to_cpu(sds->offset), 1237987da915Sopenharmony_ci (unsigned long long)le64_to_cpu(sds->offset)); 1238987da915Sopenharmony_ci ntfs_log_verbose("\t\tLength:\t\t\t %u (0x%x)\n", 1239987da915Sopenharmony_ci (unsigned)le32_to_cpu(sds->length), 1240987da915Sopenharmony_ci (unsigned)le32_to_cpu(sds->length)); 1241987da915Sopenharmony_ci 1242987da915Sopenharmony_ci sd = (SECURITY_DESCRIPTOR_RELATIVE *)((char *)sds + 1243987da915Sopenharmony_ci sizeof(SECURITY_DESCRIPTOR_HEADER)); 1244987da915Sopenharmony_ci 1245987da915Sopenharmony_ci ntfs_dump_security_descriptor(sd, "\t"); 1246987da915Sopenharmony_ci} 1247987da915Sopenharmony_ci 1248987da915Sopenharmony_cistatic void ntfs_dump_sds(ATTR_RECORD *attr, ntfs_inode *ni) 1249987da915Sopenharmony_ci{ 1250987da915Sopenharmony_ci SECURITY_DESCRIPTOR_HEADER *sds, *sd; 1251987da915Sopenharmony_ci ntfschar *name; 1252987da915Sopenharmony_ci int name_len; 1253987da915Sopenharmony_ci s64 data_size; 1254987da915Sopenharmony_ci u64 inode; 1255987da915Sopenharmony_ci 1256987da915Sopenharmony_ci inode = ni->mft_no; 1257987da915Sopenharmony_ci if (ni->nr_extents < 0) 1258987da915Sopenharmony_ci inode = ni->base_ni->mft_no; 1259987da915Sopenharmony_ci if (FILE_Secure != inode) 1260987da915Sopenharmony_ci return; 1261987da915Sopenharmony_ci 1262987da915Sopenharmony_ci name_len = attr->name_length; 1263987da915Sopenharmony_ci if (!name_len) 1264987da915Sopenharmony_ci return; 1265987da915Sopenharmony_ci 1266987da915Sopenharmony_ci name = (ntfschar *)((u8 *)attr + le16_to_cpu(attr->name_offset)); 1267987da915Sopenharmony_ci if (!ntfs_names_are_equal(NTFS_DATA_SDS, sizeof(NTFS_DATA_SDS) / 2 - 1, 1268987da915Sopenharmony_ci name, name_len, CASE_SENSITIVE, NULL, 0)) 1269987da915Sopenharmony_ci return; 1270987da915Sopenharmony_ci 1271987da915Sopenharmony_ci sd = sds = ntfs_attr_readall(ni, AT_DATA, name, name_len, &data_size); 1272987da915Sopenharmony_ci if (!sd) { 1273987da915Sopenharmony_ci ntfs_log_perror("Failed to read $SDS attribute"); 1274987da915Sopenharmony_ci return; 1275987da915Sopenharmony_ci } 1276987da915Sopenharmony_ci /* 1277987da915Sopenharmony_ci * FIXME: The right way is based on the indexes, so we couldn't 1278987da915Sopenharmony_ci * miss real entries. For now, dump until it makes sense. 1279987da915Sopenharmony_ci */ 1280987da915Sopenharmony_ci while (sd->length && sd->hash && 1281987da915Sopenharmony_ci le64_to_cpu(sd->offset) < (u64)data_size && 1282987da915Sopenharmony_ci le32_to_cpu(sd->length) < (u64)data_size && 1283987da915Sopenharmony_ci le64_to_cpu(sd->offset) + 1284987da915Sopenharmony_ci le32_to_cpu(sd->length) < (u64)data_size) { 1285987da915Sopenharmony_ci ntfs_dump_sds_entry(sd); 1286987da915Sopenharmony_ci sd = (SECURITY_DESCRIPTOR_HEADER *)((char*)sd + 1287987da915Sopenharmony_ci ((le32_to_cpu(sd->length) + 15) & ~15)); 1288987da915Sopenharmony_ci } 1289987da915Sopenharmony_ci free(sds); 1290987da915Sopenharmony_ci} 1291987da915Sopenharmony_ci 1292987da915Sopenharmony_cistatic const char *get_attribute_type_name(le32 type) 1293987da915Sopenharmony_ci{ 1294987da915Sopenharmony_ci switch (type) { 1295987da915Sopenharmony_ci case AT_UNUSED: return "$UNUSED"; 1296987da915Sopenharmony_ci case AT_STANDARD_INFORMATION: return "$STANDARD_INFORMATION"; 1297987da915Sopenharmony_ci case AT_ATTRIBUTE_LIST: return "$ATTRIBUTE_LIST"; 1298987da915Sopenharmony_ci case AT_FILE_NAME: return "$FILE_NAME"; 1299987da915Sopenharmony_ci case AT_OBJECT_ID: return "$OBJECT_ID"; 1300987da915Sopenharmony_ci case AT_SECURITY_DESCRIPTOR: return "$SECURITY_DESCRIPTOR"; 1301987da915Sopenharmony_ci case AT_VOLUME_NAME: return "$VOLUME_NAME"; 1302987da915Sopenharmony_ci case AT_VOLUME_INFORMATION: return "$VOLUME_INFORMATION"; 1303987da915Sopenharmony_ci case AT_DATA: return "$DATA"; 1304987da915Sopenharmony_ci case AT_INDEX_ROOT: return "$INDEX_ROOT"; 1305987da915Sopenharmony_ci case AT_INDEX_ALLOCATION: return "$INDEX_ALLOCATION"; 1306987da915Sopenharmony_ci case AT_BITMAP: return "$BITMAP"; 1307987da915Sopenharmony_ci case AT_REPARSE_POINT: return "$REPARSE_POINT"; 1308987da915Sopenharmony_ci case AT_EA_INFORMATION: return "$EA_INFORMATION"; 1309987da915Sopenharmony_ci case AT_EA: return "$EA"; 1310987da915Sopenharmony_ci case AT_PROPERTY_SET: return "$PROPERTY_SET"; 1311987da915Sopenharmony_ci case AT_LOGGED_UTILITY_STREAM: return "$LOGGED_UTILITY_STREAM"; 1312987da915Sopenharmony_ci case AT_END: return "$END"; 1313987da915Sopenharmony_ci } 1314987da915Sopenharmony_ci 1315987da915Sopenharmony_ci return "$UNKNOWN"; 1316987da915Sopenharmony_ci} 1317987da915Sopenharmony_ci 1318987da915Sopenharmony_cistatic const char * ntfs_dump_lcn(LCN lcn) 1319987da915Sopenharmony_ci{ 1320987da915Sopenharmony_ci switch (lcn) { 1321987da915Sopenharmony_ci case LCN_HOLE: 1322987da915Sopenharmony_ci return "<HOLE>\t"; 1323987da915Sopenharmony_ci case LCN_RL_NOT_MAPPED: 1324987da915Sopenharmony_ci return "<RL_NOT_MAPPED>"; 1325987da915Sopenharmony_ci case LCN_ENOENT: 1326987da915Sopenharmony_ci return "<ENOENT>\t"; 1327987da915Sopenharmony_ci case LCN_EINVAL: 1328987da915Sopenharmony_ci return "<EINVAL>\t"; 1329987da915Sopenharmony_ci case LCN_EIO: 1330987da915Sopenharmony_ci return "<EIO>\t"; 1331987da915Sopenharmony_ci default: 1332987da915Sopenharmony_ci ntfs_log_error("Invalid LCN value %llx passed to " 1333987da915Sopenharmony_ci "ntfs_dump_lcn().\n", (long long)lcn); 1334987da915Sopenharmony_ci return "???\t"; 1335987da915Sopenharmony_ci } 1336987da915Sopenharmony_ci} 1337987da915Sopenharmony_ci 1338987da915Sopenharmony_cistatic void ntfs_dump_attribute_header(ntfs_attr_search_ctx *ctx, 1339987da915Sopenharmony_ci ntfs_volume *vol, struct RUNCOUNT *runcount) 1340987da915Sopenharmony_ci{ 1341987da915Sopenharmony_ci ATTR_RECORD *a = ctx->attr; 1342987da915Sopenharmony_ci 1343987da915Sopenharmony_ci printf("Dumping attribute %s (0x%x) from mft record %lld (0x%llx)\n", 1344987da915Sopenharmony_ci get_attribute_type_name(a->type), 1345987da915Sopenharmony_ci (unsigned)le32_to_cpu(a->type), 1346987da915Sopenharmony_ci (unsigned long long)ctx->ntfs_ino->mft_no, 1347987da915Sopenharmony_ci (unsigned long long)ctx->ntfs_ino->mft_no); 1348987da915Sopenharmony_ci 1349987da915Sopenharmony_ci ntfs_log_verbose("\tAttribute length:\t %u (0x%x)\n", 1350987da915Sopenharmony_ci (unsigned)le32_to_cpu(a->length), 1351987da915Sopenharmony_ci (unsigned)le32_to_cpu(a->length)); 1352987da915Sopenharmony_ci printf("\tResident: \t\t %s\n", a->non_resident ? "No" : "Yes"); 1353987da915Sopenharmony_ci ntfs_log_verbose("\tName length:\t\t %u (0x%x)\n", 1354987da915Sopenharmony_ci (unsigned)a->name_length, (unsigned)a->name_length); 1355987da915Sopenharmony_ci ntfs_log_verbose("\tName offset:\t\t %u (0x%x)\n", 1356987da915Sopenharmony_ci (unsigned)le16_to_cpu(a->name_offset), 1357987da915Sopenharmony_ci (unsigned)le16_to_cpu(a->name_offset)); 1358987da915Sopenharmony_ci 1359987da915Sopenharmony_ci /* Dump the attribute (stream) name */ 1360987da915Sopenharmony_ci if (a->name_length) { 1361987da915Sopenharmony_ci char *attribute_name = NULL; 1362987da915Sopenharmony_ci 1363987da915Sopenharmony_ci attribute_name = ntfs_attr_get_name_mbs(a); 1364987da915Sopenharmony_ci if (attribute_name) { 1365987da915Sopenharmony_ci printf("\tAttribute name:\t\t '%s'\n", attribute_name); 1366987da915Sopenharmony_ci free(attribute_name); 1367987da915Sopenharmony_ci } else 1368987da915Sopenharmony_ci ntfs_log_perror("Error: couldn't parse attribute name"); 1369987da915Sopenharmony_ci } 1370987da915Sopenharmony_ci 1371987da915Sopenharmony_ci /* TODO: parse the flags */ 1372987da915Sopenharmony_ci printf("\tAttribute flags:\t 0x%04x\n", 1373987da915Sopenharmony_ci (unsigned)le16_to_cpu(a->flags)); 1374987da915Sopenharmony_ci printf("\tAttribute instance:\t %u (0x%x)\n", 1375987da915Sopenharmony_ci (unsigned)le16_to_cpu(a->instance), 1376987da915Sopenharmony_ci (unsigned)le16_to_cpu(a->instance)); 1377987da915Sopenharmony_ci 1378987da915Sopenharmony_ci /* Resident attribute */ 1379987da915Sopenharmony_ci if (!a->non_resident) { 1380987da915Sopenharmony_ci printf("\tData size:\t\t %u (0x%x)\n", 1381987da915Sopenharmony_ci (unsigned)le32_to_cpu(a->value_length), 1382987da915Sopenharmony_ci (unsigned)le32_to_cpu(a->value_length)); 1383987da915Sopenharmony_ci ntfs_log_verbose("\tData offset:\t\t %u (0x%x)\n", 1384987da915Sopenharmony_ci (unsigned)le16_to_cpu(a->value_offset), 1385987da915Sopenharmony_ci (unsigned)le16_to_cpu(a->value_offset)); 1386987da915Sopenharmony_ci /* TODO: parse the flags */ 1387987da915Sopenharmony_ci printf("\tResident flags:\t\t 0x%02x\n", 1388987da915Sopenharmony_ci (unsigned)a->resident_flags); 1389987da915Sopenharmony_ci ntfs_log_verbose("\tReservedR:\t\t %d (0x%x)\n", 1390987da915Sopenharmony_ci (unsigned)a->reservedR, (unsigned)a->reservedR); 1391987da915Sopenharmony_ci return; 1392987da915Sopenharmony_ci } 1393987da915Sopenharmony_ci 1394987da915Sopenharmony_ci /* Non-resident attribute */ 1395987da915Sopenharmony_ci ntfs_log_verbose("\tLowest VCN\t\t %lld (0x%llx)\n", 1396987da915Sopenharmony_ci (long long)sle64_to_cpu(a->lowest_vcn), 1397987da915Sopenharmony_ci (unsigned long long)sle64_to_cpu(a->lowest_vcn)); 1398987da915Sopenharmony_ci ntfs_log_verbose("\tHighest VCN:\t\t %lld (0x%llx)\n", 1399987da915Sopenharmony_ci (long long)sle64_to_cpu(a->highest_vcn), 1400987da915Sopenharmony_ci (unsigned long long)sle64_to_cpu(a->highest_vcn)); 1401987da915Sopenharmony_ci ntfs_log_verbose("\tMapping pairs offset:\t %u (0x%x)\n", 1402987da915Sopenharmony_ci (unsigned)le16_to_cpu(a->mapping_pairs_offset), 1403987da915Sopenharmony_ci (unsigned)le16_to_cpu(a->mapping_pairs_offset)); 1404987da915Sopenharmony_ci printf("\tCompression unit:\t %u (0x%x)\n", 1405987da915Sopenharmony_ci (unsigned)a->compression_unit, 1406987da915Sopenharmony_ci (unsigned)a->compression_unit); 1407987da915Sopenharmony_ci /* TODO: dump the 5 reserved bytes here in verbose mode */ 1408987da915Sopenharmony_ci 1409987da915Sopenharmony_ci if (!a->lowest_vcn) { 1410987da915Sopenharmony_ci printf("\tData size:\t\t %llu (0x%llx)\n", 1411987da915Sopenharmony_ci (long long)sle64_to_cpu(a->data_size), 1412987da915Sopenharmony_ci (unsigned long long)sle64_to_cpu(a->data_size)); 1413987da915Sopenharmony_ci printf("\tAllocated size:\t\t %llu (0x%llx)\n", 1414987da915Sopenharmony_ci (long long)sle64_to_cpu(a->allocated_size), 1415987da915Sopenharmony_ci (unsigned long long) 1416987da915Sopenharmony_ci sle64_to_cpu(a->allocated_size)); 1417987da915Sopenharmony_ci printf("\tInitialized size:\t %llu (0x%llx)\n", 1418987da915Sopenharmony_ci (long long)sle64_to_cpu(a->initialized_size), 1419987da915Sopenharmony_ci (unsigned long long) 1420987da915Sopenharmony_ci sle64_to_cpu(a->initialized_size)); 1421987da915Sopenharmony_ci if (a->compression_unit || a->flags & ATTR_IS_COMPRESSED || 1422987da915Sopenharmony_ci a->flags & ATTR_IS_SPARSE) 1423987da915Sopenharmony_ci printf("\tCompressed size:\t %llu (0x%llx)\n", 1424987da915Sopenharmony_ci (signed long long) 1425987da915Sopenharmony_ci sle64_to_cpu(a->compressed_size), 1426987da915Sopenharmony_ci (signed long long) 1427987da915Sopenharmony_ci sle64_to_cpu(a->compressed_size)); 1428987da915Sopenharmony_ci } 1429987da915Sopenharmony_ci 1430987da915Sopenharmony_ci if (opts.verbose) { 1431987da915Sopenharmony_ci runlist *rl; 1432987da915Sopenharmony_ci 1433987da915Sopenharmony_ci rl = ntfs_mapping_pairs_decompress(vol, a, NULL); 1434987da915Sopenharmony_ci if (rl) { 1435987da915Sopenharmony_ci runlist *rlc = rl; 1436987da915Sopenharmony_ci LCN next_lcn; 1437987da915Sopenharmony_ci 1438987da915Sopenharmony_ci next_lcn = LCN_HOLE; 1439987da915Sopenharmony_ci // TODO: Switch this to properly aligned hex... 1440987da915Sopenharmony_ci printf("\tRunlist:\tVCN\t\tLCN\t\tLength\n"); 1441987da915Sopenharmony_ci runcount->fragments++; 1442987da915Sopenharmony_ci while (rlc->length) { 1443987da915Sopenharmony_ci runcount->runs++; 1444987da915Sopenharmony_ci if (rlc->lcn >= 0) { 1445987da915Sopenharmony_ci printf("\t\t\t0x%llx\t\t0x%llx\t\t" 1446987da915Sopenharmony_ci "0x%llx\n", 1447987da915Sopenharmony_ci (long long)rlc->vcn, 1448987da915Sopenharmony_ci (long long)rlc->lcn, 1449987da915Sopenharmony_ci (long long)rlc->length); 1450987da915Sopenharmony_ci if ((next_lcn >= 0) 1451987da915Sopenharmony_ci && (rlc->lcn != next_lcn)) 1452987da915Sopenharmony_ci runcount->fragments++; 1453987da915Sopenharmony_ci next_lcn = rlc->lcn + rlc->length; 1454987da915Sopenharmony_ci } else 1455987da915Sopenharmony_ci printf("\t\t\t0x%llx\t\t%s\t" 1456987da915Sopenharmony_ci "0x%llx\n", 1457987da915Sopenharmony_ci (long long)rlc->vcn, 1458987da915Sopenharmony_ci ntfs_dump_lcn(rlc->lcn), 1459987da915Sopenharmony_ci (long long)rlc->length); 1460987da915Sopenharmony_ci rlc++; 1461987da915Sopenharmony_ci } 1462987da915Sopenharmony_ci free(rl); 1463987da915Sopenharmony_ci } else 1464987da915Sopenharmony_ci ntfs_log_error("Error: couldn't decompress runlist\n"); 1465987da915Sopenharmony_ci } 1466987da915Sopenharmony_ci} 1467987da915Sopenharmony_ci 1468987da915Sopenharmony_ci/** 1469987da915Sopenharmony_ci * ntfs_dump_data_attr() 1470987da915Sopenharmony_ci * 1471987da915Sopenharmony_ci * dump some info about the data attribute if it's metadata 1472987da915Sopenharmony_ci */ 1473987da915Sopenharmony_cistatic void ntfs_dump_attr_data(ATTR_RECORD *attr, ntfs_inode *ni) 1474987da915Sopenharmony_ci{ 1475987da915Sopenharmony_ci if (opts.verbose) 1476987da915Sopenharmony_ci ntfs_dump_sds(attr, ni); 1477987da915Sopenharmony_ci} 1478987da915Sopenharmony_ci 1479987da915Sopenharmony_citypedef enum { 1480987da915Sopenharmony_ci INDEX_ATTR_UNKNOWN, 1481987da915Sopenharmony_ci INDEX_ATTR_DIRECTORY_I30, 1482987da915Sopenharmony_ci INDEX_ATTR_SECURE_SII, 1483987da915Sopenharmony_ci INDEX_ATTR_SECURE_SDH, 1484987da915Sopenharmony_ci INDEX_ATTR_OBJID_O, 1485987da915Sopenharmony_ci INDEX_ATTR_REPARSE_R, 1486987da915Sopenharmony_ci INDEX_ATTR_QUOTA_O, 1487987da915Sopenharmony_ci INDEX_ATTR_QUOTA_Q, 1488987da915Sopenharmony_ci} INDEX_ATTR_TYPE; 1489987da915Sopenharmony_ci 1490987da915Sopenharmony_cistatic void ntfs_dump_index_key(INDEX_ENTRY *entry, INDEX_ATTR_TYPE type) 1491987da915Sopenharmony_ci{ 1492987da915Sopenharmony_ci char *sid; 1493987da915Sopenharmony_ci char printable_GUID[37]; 1494987da915Sopenharmony_ci le32 tag; 1495987da915Sopenharmony_ci 1496987da915Sopenharmony_ci switch (type) { 1497987da915Sopenharmony_ci case INDEX_ATTR_SECURE_SII: 1498987da915Sopenharmony_ci ntfs_log_verbose("\t\tKey security id:\t %u (0x%x)\n", 1499987da915Sopenharmony_ci (unsigned) 1500987da915Sopenharmony_ci le32_to_cpu(entry->key.sii.security_id), 1501987da915Sopenharmony_ci (unsigned) 1502987da915Sopenharmony_ci le32_to_cpu(entry->key.sii.security_id)); 1503987da915Sopenharmony_ci break; 1504987da915Sopenharmony_ci case INDEX_ATTR_SECURE_SDH: 1505987da915Sopenharmony_ci ntfs_log_verbose("\t\tKey hash:\t\t 0x%08x\n", 1506987da915Sopenharmony_ci (unsigned)le32_to_cpu(entry->key.sdh.hash)); 1507987da915Sopenharmony_ci ntfs_log_verbose("\t\tKey security id:\t %u (0x%x)\n", 1508987da915Sopenharmony_ci (unsigned) 1509987da915Sopenharmony_ci le32_to_cpu(entry->key.sdh.security_id), 1510987da915Sopenharmony_ci (unsigned) 1511987da915Sopenharmony_ci le32_to_cpu(entry->key.sdh.security_id)); 1512987da915Sopenharmony_ci break; 1513987da915Sopenharmony_ci case INDEX_ATTR_OBJID_O: 1514987da915Sopenharmony_ci ntfs_guid_to_mbs(&entry->key.object_id, printable_GUID); 1515987da915Sopenharmony_ci ntfs_log_verbose("\t\tKey GUID:\t\t %s\n", printable_GUID); 1516987da915Sopenharmony_ci break; 1517987da915Sopenharmony_ci case INDEX_ATTR_REPARSE_R: 1518987da915Sopenharmony_ci tag = entry->key.reparse.reparse_tag; 1519987da915Sopenharmony_ci ntfs_log_verbose("\t\tKey reparse tag:\t 0x%08lx%s\n", 1520987da915Sopenharmony_ci (long)le32_to_cpu(tag), 1521987da915Sopenharmony_ci reparse_type_name(tag)); 1522987da915Sopenharmony_ci ntfs_log_verbose("\t\tKey file id:\t\t %llu (0x%llx)\n", 1523987da915Sopenharmony_ci (unsigned long long) 1524987da915Sopenharmony_ci le64_to_cpu(entry->key.reparse.file_id), 1525987da915Sopenharmony_ci (unsigned long long) 1526987da915Sopenharmony_ci le64_to_cpu(entry->key.reparse.file_id)); 1527987da915Sopenharmony_ci break; 1528987da915Sopenharmony_ci case INDEX_ATTR_QUOTA_O: 1529987da915Sopenharmony_ci sid = ntfs_sid_to_mbs(&entry->key.sid, NULL, 0); 1530987da915Sopenharmony_ci ntfs_log_verbose("\t\tKey SID:\t\t %s\n", sid); 1531987da915Sopenharmony_ci free(sid); 1532987da915Sopenharmony_ci break; 1533987da915Sopenharmony_ci case INDEX_ATTR_QUOTA_Q: 1534987da915Sopenharmony_ci ntfs_log_verbose("\t\tKey owner id:\t\t %u (0x%x)\n", 1535987da915Sopenharmony_ci (unsigned)le32_to_cpu(entry->key.owner_id), 1536987da915Sopenharmony_ci (unsigned)le32_to_cpu(entry->key.owner_id)); 1537987da915Sopenharmony_ci break; 1538987da915Sopenharmony_ci default: 1539987da915Sopenharmony_ci ntfs_log_verbose("\t\tIndex attr type is UNKNOWN: \t 0x%08x\n", 1540987da915Sopenharmony_ci (unsigned)type); 1541987da915Sopenharmony_ci break; 1542987da915Sopenharmony_ci } 1543987da915Sopenharmony_ci} 1544987da915Sopenharmony_ci 1545987da915Sopenharmony_citypedef union { 1546987da915Sopenharmony_ci SII_INDEX_DATA sii; /* $SII index data in $Secure */ 1547987da915Sopenharmony_ci SDH_INDEX_DATA sdh; /* $SDH index data in $Secure */ 1548987da915Sopenharmony_ci QUOTA_O_INDEX_DATA quota_o; /* $O index data in $Quota */ 1549987da915Sopenharmony_ci QUOTA_CONTROL_ENTRY quota_q; /* $Q index data in $Quota */ 1550987da915Sopenharmony_ci} __attribute__((__packed__)) INDEX_ENTRY_DATA; 1551987da915Sopenharmony_ci 1552987da915Sopenharmony_cistatic void ntfs_dump_index_data(INDEX_ENTRY *entry, INDEX_ATTR_TYPE type) 1553987da915Sopenharmony_ci{ 1554987da915Sopenharmony_ci INDEX_ENTRY_DATA *data; 1555987da915Sopenharmony_ci 1556987da915Sopenharmony_ci data = (INDEX_ENTRY_DATA *)((u8 *)entry + 1557987da915Sopenharmony_ci le16_to_cpu(entry->data_offset)); 1558987da915Sopenharmony_ci 1559987da915Sopenharmony_ci switch (type) { 1560987da915Sopenharmony_ci case INDEX_ATTR_SECURE_SII: 1561987da915Sopenharmony_ci ntfs_log_verbose("\t\tHash:\t\t\t 0x%08x\n", 1562987da915Sopenharmony_ci (unsigned)le32_to_cpu(data->sii.hash)); 1563987da915Sopenharmony_ci ntfs_log_verbose("\t\tSecurity id:\t\t %u (0x%x)\n", 1564987da915Sopenharmony_ci (unsigned)le32_to_cpu(data->sii.security_id), 1565987da915Sopenharmony_ci (unsigned)le32_to_cpu(data->sii.security_id)); 1566987da915Sopenharmony_ci ntfs_log_verbose("\t\tOffset in $SDS:\t\t %llu (0x%llx)\n", 1567987da915Sopenharmony_ci (unsigned long long) 1568987da915Sopenharmony_ci le64_to_cpu(data->sii.offset), 1569987da915Sopenharmony_ci (unsigned long long) 1570987da915Sopenharmony_ci le64_to_cpu(data->sii.offset)); 1571987da915Sopenharmony_ci ntfs_log_verbose("\t\tLength in $SDS:\t\t %u (0x%x)\n", 1572987da915Sopenharmony_ci (unsigned)le32_to_cpu(data->sii.length), 1573987da915Sopenharmony_ci (unsigned)le32_to_cpu(data->sii.length)); 1574987da915Sopenharmony_ci break; 1575987da915Sopenharmony_ci case INDEX_ATTR_SECURE_SDH: 1576987da915Sopenharmony_ci ntfs_log_verbose("\t\tHash:\t\t\t 0x%08x\n", 1577987da915Sopenharmony_ci (unsigned)le32_to_cpu(data->sdh.hash)); 1578987da915Sopenharmony_ci ntfs_log_verbose("\t\tSecurity id:\t\t %u (0x%x)\n", 1579987da915Sopenharmony_ci (unsigned)le32_to_cpu(data->sdh.security_id), 1580987da915Sopenharmony_ci (unsigned)le32_to_cpu(data->sdh.security_id)); 1581987da915Sopenharmony_ci ntfs_log_verbose("\t\tOffset in $SDS:\t\t %llu (0x%llx)\n", 1582987da915Sopenharmony_ci (unsigned long long) 1583987da915Sopenharmony_ci le64_to_cpu(data->sdh.offset), 1584987da915Sopenharmony_ci (unsigned long long) 1585987da915Sopenharmony_ci le64_to_cpu(data->sdh.offset)); 1586987da915Sopenharmony_ci ntfs_log_verbose("\t\tLength in $SDS:\t\t %u (0x%x)\n", 1587987da915Sopenharmony_ci (unsigned)le32_to_cpu(data->sdh.length), 1588987da915Sopenharmony_ci (unsigned)le32_to_cpu(data->sdh.length)); 1589987da915Sopenharmony_ci ntfs_log_verbose("\t\tUnknown (padding):\t 0x%08x\n", 1590987da915Sopenharmony_ci (unsigned)le32_to_cpu(data->sdh.reserved_II)); 1591987da915Sopenharmony_ci break; 1592987da915Sopenharmony_ci case INDEX_ATTR_OBJID_O: { 1593987da915Sopenharmony_ci OBJ_ID_INDEX_DATA *object_id_data; 1594987da915Sopenharmony_ci char printable_GUID[37]; 1595987da915Sopenharmony_ci 1596987da915Sopenharmony_ci object_id_data = (OBJ_ID_INDEX_DATA*)((u8*)entry + 1597987da915Sopenharmony_ci le16_to_cpu(entry->data_offset)); 1598987da915Sopenharmony_ci ntfs_log_verbose("\t\tMFT Number:\t\t 0x%llx\n", 1599987da915Sopenharmony_ci (unsigned long long) 1600987da915Sopenharmony_ci MREF_LE(object_id_data->mft_reference)); 1601987da915Sopenharmony_ci ntfs_log_verbose("\t\tMFT Sequence Number:\t 0x%x\n", 1602987da915Sopenharmony_ci (unsigned) 1603987da915Sopenharmony_ci MSEQNO_LE(object_id_data->mft_reference)); 1604987da915Sopenharmony_ci ntfs_guid_to_mbs(&object_id_data->birth_volume_id, 1605987da915Sopenharmony_ci printable_GUID); 1606987da915Sopenharmony_ci ntfs_log_verbose("\t\tBirth volume id GUID:\t %s\n", 1607987da915Sopenharmony_ci printable_GUID); 1608987da915Sopenharmony_ci ntfs_guid_to_mbs(&object_id_data->birth_object_id, 1609987da915Sopenharmony_ci printable_GUID); 1610987da915Sopenharmony_ci ntfs_log_verbose("\t\tBirth object id GUID:\t %s\n", 1611987da915Sopenharmony_ci printable_GUID); 1612987da915Sopenharmony_ci ntfs_guid_to_mbs(&object_id_data->domain_id, printable_GUID); 1613987da915Sopenharmony_ci ntfs_log_verbose("\t\tDomain id GUID:\t\t %s\n", 1614987da915Sopenharmony_ci printable_GUID); 1615987da915Sopenharmony_ci } 1616987da915Sopenharmony_ci break; 1617987da915Sopenharmony_ci case INDEX_ATTR_REPARSE_R: 1618987da915Sopenharmony_ci /* TODO */ 1619987da915Sopenharmony_ci break; 1620987da915Sopenharmony_ci case INDEX_ATTR_QUOTA_O: 1621987da915Sopenharmony_ci ntfs_log_verbose("\t\tOwner id:\t\t %u (0x%x)\n", 1622987da915Sopenharmony_ci (unsigned)le32_to_cpu(data->quota_o.owner_id), 1623987da915Sopenharmony_ci (unsigned)le32_to_cpu(data->quota_o.owner_id)); 1624987da915Sopenharmony_ci ntfs_log_verbose("\t\tUnknown:\t\t %u (0x%x)\n", 1625987da915Sopenharmony_ci (unsigned)le32_to_cpu(data->quota_o.unknown), 1626987da915Sopenharmony_ci (unsigned)le32_to_cpu(data->quota_o.unknown)); 1627987da915Sopenharmony_ci break; 1628987da915Sopenharmony_ci case INDEX_ATTR_QUOTA_Q: 1629987da915Sopenharmony_ci ntfs_log_verbose("\t\tVersion:\t\t %u\n", 1630987da915Sopenharmony_ci (unsigned)le32_to_cpu(data->quota_q.version)); 1631987da915Sopenharmony_ci ntfs_log_verbose("\t\tQuota flags:\t\t 0x%08x\n", 1632987da915Sopenharmony_ci (unsigned)le32_to_cpu(data->quota_q.flags)); 1633987da915Sopenharmony_ci ntfs_log_verbose("\t\tBytes used:\t\t %llu (0x%llx)\n", 1634987da915Sopenharmony_ci (unsigned long long) 1635987da915Sopenharmony_ci le64_to_cpu(data->quota_q.bytes_used), 1636987da915Sopenharmony_ci (unsigned long long) 1637987da915Sopenharmony_ci le64_to_cpu(data->quota_q.bytes_used)); 1638987da915Sopenharmony_ci ntfs_log_verbose("\t\tLast changed:\t\t %s", 1639987da915Sopenharmony_ci ntfsinfo_time_to_str( 1640987da915Sopenharmony_ci data->quota_q.change_time)); 1641987da915Sopenharmony_ci ntfs_log_verbose("\t\tThreshold:\t\t %lld (0x%llx)\n", 1642987da915Sopenharmony_ci (unsigned long long) 1643987da915Sopenharmony_ci sle64_to_cpu(data->quota_q.threshold), 1644987da915Sopenharmony_ci (unsigned long long) 1645987da915Sopenharmony_ci sle64_to_cpu(data->quota_q.threshold)); 1646987da915Sopenharmony_ci ntfs_log_verbose("\t\tLimit:\t\t\t %lld (0x%llx)\n", 1647987da915Sopenharmony_ci (unsigned long long) 1648987da915Sopenharmony_ci sle64_to_cpu(data->quota_q.limit), 1649987da915Sopenharmony_ci (unsigned long long) 1650987da915Sopenharmony_ci sle64_to_cpu(data->quota_q.limit)); 1651987da915Sopenharmony_ci ntfs_log_verbose("\t\tExceeded time:\t\t %lld (0x%llx)\n", 1652987da915Sopenharmony_ci (unsigned long long) 1653987da915Sopenharmony_ci sle64_to_cpu(data->quota_q.exceeded_time), 1654987da915Sopenharmony_ci (unsigned long long) 1655987da915Sopenharmony_ci sle64_to_cpu(data->quota_q.exceeded_time)); 1656987da915Sopenharmony_ci if (le16_to_cpu(entry->data_length) > 48) { 1657987da915Sopenharmony_ci char *sid; 1658987da915Sopenharmony_ci sid = ntfs_sid_to_mbs(&data->quota_q.sid, NULL, 0); 1659987da915Sopenharmony_ci ntfs_log_verbose("\t\tOwner SID:\t\t %s\n", sid); 1660987da915Sopenharmony_ci free(sid); 1661987da915Sopenharmony_ci } 1662987da915Sopenharmony_ci break; 1663987da915Sopenharmony_ci default: 1664987da915Sopenharmony_ci ntfs_log_verbose("\t\tIndex attr type is UNKNOWN: \t 0x%08x\n", 1665987da915Sopenharmony_ci (unsigned)type); 1666987da915Sopenharmony_ci break; 1667987da915Sopenharmony_ci } 1668987da915Sopenharmony_ci} 1669987da915Sopenharmony_ci 1670987da915Sopenharmony_ci/** 1671987da915Sopenharmony_ci * ntfs_dump_index_entries() 1672987da915Sopenharmony_ci * 1673987da915Sopenharmony_ci * dump sequence of index_entries and return number of entries dumped. 1674987da915Sopenharmony_ci */ 1675987da915Sopenharmony_cistatic int ntfs_dump_index_entries(INDEX_ENTRY *entry, INDEX_ATTR_TYPE type) 1676987da915Sopenharmony_ci{ 1677987da915Sopenharmony_ci int numb_entries = 1; 1678987da915Sopenharmony_ci while (1) { 1679987da915Sopenharmony_ci if (!opts.verbose) { 1680987da915Sopenharmony_ci if (entry->ie_flags & INDEX_ENTRY_END) 1681987da915Sopenharmony_ci break; 1682987da915Sopenharmony_ci entry = (INDEX_ENTRY *)((u8 *)entry + 1683987da915Sopenharmony_ci le16_to_cpu(entry->length)); 1684987da915Sopenharmony_ci numb_entries++; 1685987da915Sopenharmony_ci continue; 1686987da915Sopenharmony_ci } 1687987da915Sopenharmony_ci ntfs_log_verbose("\t\tEntry length:\t\t %u (0x%x)\n", 1688987da915Sopenharmony_ci (unsigned)le16_to_cpu(entry->length), 1689987da915Sopenharmony_ci (unsigned)le16_to_cpu(entry->length)); 1690987da915Sopenharmony_ci ntfs_log_verbose("\t\tKey length:\t\t %u (0x%x)\n", 1691987da915Sopenharmony_ci (unsigned)le16_to_cpu(entry->key_length), 1692987da915Sopenharmony_ci (unsigned)le16_to_cpu(entry->key_length)); 1693987da915Sopenharmony_ci ntfs_log_verbose("\t\tIndex entry flags:\t 0x%02x\n", 1694987da915Sopenharmony_ci (unsigned)le16_to_cpu(entry->ie_flags)); 1695987da915Sopenharmony_ci 1696987da915Sopenharmony_ci if (entry->ie_flags & INDEX_ENTRY_NODE) 1697987da915Sopenharmony_ci ntfs_log_verbose("\t\tSubnode VCN:\t\t %lld (0x%llx)\n", 1698987da915Sopenharmony_ci (long long)ntfs_ie_get_vcn(entry), 1699987da915Sopenharmony_ci (long long)ntfs_ie_get_vcn(entry)); 1700987da915Sopenharmony_ci if (entry->ie_flags & INDEX_ENTRY_END) 1701987da915Sopenharmony_ci break; 1702987da915Sopenharmony_ci 1703987da915Sopenharmony_ci switch (type) { 1704987da915Sopenharmony_ci case INDEX_ATTR_DIRECTORY_I30: 1705987da915Sopenharmony_ci ntfs_log_verbose("\t\tFILE record number:\t %llu " 1706987da915Sopenharmony_ci "(0x%llx)\n", (unsigned long long) 1707987da915Sopenharmony_ci MREF_LE(entry->indexed_file), 1708987da915Sopenharmony_ci (unsigned long long) 1709987da915Sopenharmony_ci MREF_LE(entry->indexed_file)); 1710987da915Sopenharmony_ci ntfs_dump_filename("\t\t", &entry->key.file_name); 1711987da915Sopenharmony_ci break; 1712987da915Sopenharmony_ci default: 1713987da915Sopenharmony_ci ntfs_log_verbose("\t\tData offset:\t\t %u (0x%x)\n", 1714987da915Sopenharmony_ci (unsigned) 1715987da915Sopenharmony_ci le16_to_cpu(entry->data_offset), 1716987da915Sopenharmony_ci (unsigned) 1717987da915Sopenharmony_ci le16_to_cpu(entry->data_offset)); 1718987da915Sopenharmony_ci ntfs_log_verbose("\t\tData length:\t\t %u (0x%x)\n", 1719987da915Sopenharmony_ci (unsigned) 1720987da915Sopenharmony_ci le16_to_cpu(entry->data_length), 1721987da915Sopenharmony_ci (unsigned) 1722987da915Sopenharmony_ci le16_to_cpu(entry->data_length)); 1723987da915Sopenharmony_ci ntfs_dump_index_key(entry, type); 1724987da915Sopenharmony_ci ntfs_log_verbose("\t\tKey Data:\n"); 1725987da915Sopenharmony_ci ntfs_dump_index_data(entry, type); 1726987da915Sopenharmony_ci break; 1727987da915Sopenharmony_ci } 1728987da915Sopenharmony_ci if (!entry->length) { 1729987da915Sopenharmony_ci ntfs_log_verbose("\tWARNING: Corrupt index entry, " 1730987da915Sopenharmony_ci "skipping the remainder of this index " 1731987da915Sopenharmony_ci "block.\n"); 1732987da915Sopenharmony_ci break; 1733987da915Sopenharmony_ci } 1734987da915Sopenharmony_ci entry = (INDEX_ENTRY*)((u8*)entry + le16_to_cpu(entry->length)); 1735987da915Sopenharmony_ci numb_entries++; 1736987da915Sopenharmony_ci ntfs_log_verbose("\n"); 1737987da915Sopenharmony_ci } 1738987da915Sopenharmony_ci ntfs_log_verbose("\tEnd of index block reached\n"); 1739987da915Sopenharmony_ci return numb_entries; 1740987da915Sopenharmony_ci} 1741987da915Sopenharmony_ci 1742987da915Sopenharmony_ci#define COMPARE_INDEX_NAMES(attr, name) \ 1743987da915Sopenharmony_ci ntfs_names_are_equal((name), sizeof(name) / 2 - 1, \ 1744987da915Sopenharmony_ci (ntfschar*)((char*)(attr) + le16_to_cpu((attr)->name_offset)), \ 1745987da915Sopenharmony_ci (attr)->name_length, CASE_SENSITIVE, NULL, 0) 1746987da915Sopenharmony_ci 1747987da915Sopenharmony_cistatic INDEX_ATTR_TYPE get_index_attr_type(ntfs_inode *ni, ATTR_RECORD *attr, 1748987da915Sopenharmony_ci INDEX_ROOT *index_root) 1749987da915Sopenharmony_ci{ 1750987da915Sopenharmony_ci char file_name[64]; 1751987da915Sopenharmony_ci 1752987da915Sopenharmony_ci if (!attr->name_length) 1753987da915Sopenharmony_ci return INDEX_ATTR_UNKNOWN; 1754987da915Sopenharmony_ci 1755987da915Sopenharmony_ci if (index_root->type) { 1756987da915Sopenharmony_ci if (index_root->type == AT_FILE_NAME) 1757987da915Sopenharmony_ci return INDEX_ATTR_DIRECTORY_I30; 1758987da915Sopenharmony_ci else 1759987da915Sopenharmony_ci /* weird, this should be illegal */ 1760987da915Sopenharmony_ci ntfs_log_error("Unknown index attribute type: 0x%0X\n", 1761987da915Sopenharmony_ci le32_to_cpu(index_root->type)); 1762987da915Sopenharmony_ci return INDEX_ATTR_UNKNOWN; 1763987da915Sopenharmony_ci } 1764987da915Sopenharmony_ci 1765987da915Sopenharmony_ci if (utils_is_metadata(ni) <= 0) 1766987da915Sopenharmony_ci return INDEX_ATTR_UNKNOWN; 1767987da915Sopenharmony_ci if (utils_inode_get_name(ni, file_name, sizeof(file_name)) <= 0) 1768987da915Sopenharmony_ci return INDEX_ATTR_UNKNOWN; 1769987da915Sopenharmony_ci 1770987da915Sopenharmony_ci if (COMPARE_INDEX_NAMES(attr, NTFS_INDEX_SDH)) 1771987da915Sopenharmony_ci return INDEX_ATTR_SECURE_SDH; 1772987da915Sopenharmony_ci else if (COMPARE_INDEX_NAMES(attr, NTFS_INDEX_SII)) 1773987da915Sopenharmony_ci return INDEX_ATTR_SECURE_SII; 1774987da915Sopenharmony_ci else if (COMPARE_INDEX_NAMES(attr, NTFS_INDEX_SII)) 1775987da915Sopenharmony_ci return INDEX_ATTR_SECURE_SII; 1776987da915Sopenharmony_ci else if (COMPARE_INDEX_NAMES(attr, NTFS_INDEX_Q)) 1777987da915Sopenharmony_ci return INDEX_ATTR_QUOTA_Q; 1778987da915Sopenharmony_ci else if (COMPARE_INDEX_NAMES(attr, NTFS_INDEX_R)) 1779987da915Sopenharmony_ci return INDEX_ATTR_REPARSE_R; 1780987da915Sopenharmony_ci else if (COMPARE_INDEX_NAMES(attr, NTFS_INDEX_O)) { 1781987da915Sopenharmony_ci if (!strcmp(file_name, "/$Extend/$Quota")) 1782987da915Sopenharmony_ci return INDEX_ATTR_QUOTA_O; 1783987da915Sopenharmony_ci else if (!strcmp(file_name, "/$Extend/$ObjId")) 1784987da915Sopenharmony_ci return INDEX_ATTR_OBJID_O; 1785987da915Sopenharmony_ci } 1786987da915Sopenharmony_ci 1787987da915Sopenharmony_ci return INDEX_ATTR_UNKNOWN; 1788987da915Sopenharmony_ci} 1789987da915Sopenharmony_ci 1790987da915Sopenharmony_cistatic void ntfs_dump_index_attr_type(INDEX_ATTR_TYPE type) 1791987da915Sopenharmony_ci{ 1792987da915Sopenharmony_ci if (type == INDEX_ATTR_DIRECTORY_I30) 1793987da915Sopenharmony_ci printf("DIRECTORY_I30"); 1794987da915Sopenharmony_ci else if (type == INDEX_ATTR_SECURE_SDH) 1795987da915Sopenharmony_ci printf("SECURE_SDH"); 1796987da915Sopenharmony_ci else if (type == INDEX_ATTR_SECURE_SII) 1797987da915Sopenharmony_ci printf("SECURE_SII"); 1798987da915Sopenharmony_ci else if (type == INDEX_ATTR_OBJID_O) 1799987da915Sopenharmony_ci printf("OBJID_O"); 1800987da915Sopenharmony_ci else if (type == INDEX_ATTR_QUOTA_O) 1801987da915Sopenharmony_ci printf("QUOTA_O"); 1802987da915Sopenharmony_ci else if (type == INDEX_ATTR_QUOTA_Q) 1803987da915Sopenharmony_ci printf("QUOTA_Q"); 1804987da915Sopenharmony_ci else if (type == INDEX_ATTR_REPARSE_R) 1805987da915Sopenharmony_ci printf("REPARSE_R"); 1806987da915Sopenharmony_ci else 1807987da915Sopenharmony_ci printf("UNKNOWN"); 1808987da915Sopenharmony_ci printf("\n"); 1809987da915Sopenharmony_ci} 1810987da915Sopenharmony_ci 1811987da915Sopenharmony_cistatic void ntfs_dump_index_header(const char *indent, INDEX_HEADER *idx) 1812987da915Sopenharmony_ci{ 1813987da915Sopenharmony_ci printf("%sEntries Offset:\t\t %u (0x%x)\n", indent, 1814987da915Sopenharmony_ci (unsigned)le32_to_cpu(idx->entries_offset), 1815987da915Sopenharmony_ci (unsigned)le32_to_cpu(idx->entries_offset)); 1816987da915Sopenharmony_ci printf("%sIndex Size:\t\t %u (0x%x)\n", indent, 1817987da915Sopenharmony_ci (unsigned)le32_to_cpu(idx->index_length), 1818987da915Sopenharmony_ci (unsigned)le32_to_cpu(idx->index_length)); 1819987da915Sopenharmony_ci printf("%sAllocated Size:\t\t %u (0x%x)\n", indent, 1820987da915Sopenharmony_ci (unsigned)le32_to_cpu(idx->allocated_size), 1821987da915Sopenharmony_ci (unsigned)le32_to_cpu(idx->allocated_size)); 1822987da915Sopenharmony_ci printf("%sIndex header flags:\t 0x%02x\n", indent, idx->ih_flags); 1823987da915Sopenharmony_ci 1824987da915Sopenharmony_ci /* FIXME: there are 3 reserved bytes here */ 1825987da915Sopenharmony_ci} 1826987da915Sopenharmony_ci 1827987da915Sopenharmony_ci/** 1828987da915Sopenharmony_ci * ntfs_dump_attr_index_root() 1829987da915Sopenharmony_ci * 1830987da915Sopenharmony_ci * dump the index_root attribute 1831987da915Sopenharmony_ci */ 1832987da915Sopenharmony_cistatic void ntfs_dump_attr_index_root(ATTR_RECORD *attr, ntfs_inode *ni) 1833987da915Sopenharmony_ci{ 1834987da915Sopenharmony_ci INDEX_ATTR_TYPE type; 1835987da915Sopenharmony_ci INDEX_ROOT *index_root = NULL; 1836987da915Sopenharmony_ci INDEX_ENTRY *entry; 1837987da915Sopenharmony_ci 1838987da915Sopenharmony_ci index_root = (INDEX_ROOT*)((u8*)attr + le16_to_cpu(attr->value_offset)); 1839987da915Sopenharmony_ci 1840987da915Sopenharmony_ci /* attr_type dumping */ 1841987da915Sopenharmony_ci type = get_index_attr_type(ni, attr, index_root); 1842987da915Sopenharmony_ci printf("\tIndexed Attr Type:\t "); 1843987da915Sopenharmony_ci ntfs_dump_index_attr_type(type); 1844987da915Sopenharmony_ci 1845987da915Sopenharmony_ci /* collation rule dumping */ 1846987da915Sopenharmony_ci printf("\tCollation Rule:\t\t %u (0x%x)\n", 1847987da915Sopenharmony_ci (unsigned)le32_to_cpu(index_root->collation_rule), 1848987da915Sopenharmony_ci (unsigned)le32_to_cpu(index_root->collation_rule)); 1849987da915Sopenharmony_ci/* COLLATION_BINARY, COLLATION_FILE_NAME, COLLATION_UNICODE_STRING, 1850987da915Sopenharmony_ci COLLATION_NTOFS_ULONG, COLLATION_NTOFS_SID, 1851987da915Sopenharmony_ci COLLATION_NTOFS_SECURITY_HASH, COLLATION_NTOFS_ULONGS */ 1852987da915Sopenharmony_ci 1853987da915Sopenharmony_ci printf("\tIndex Block Size:\t %u (0x%x)\n", 1854987da915Sopenharmony_ci (unsigned)le32_to_cpu(index_root->index_block_size), 1855987da915Sopenharmony_ci (unsigned)le32_to_cpu(index_root->index_block_size)); 1856987da915Sopenharmony_ci if (le32_to_cpu(index_root->index_block_size) < ni->vol->cluster_size) 1857987da915Sopenharmony_ci printf("\t512-byte Units Per Block:\t %u (0x%x)\n", 1858987da915Sopenharmony_ci (unsigned)index_root->clusters_per_index_block, 1859987da915Sopenharmony_ci (unsigned)index_root->clusters_per_index_block); 1860987da915Sopenharmony_ci else 1861987da915Sopenharmony_ci printf("\tClusters Per Block:\t %u (0x%x)\n", 1862987da915Sopenharmony_ci (unsigned)index_root->clusters_per_index_block, 1863987da915Sopenharmony_ci (unsigned)index_root->clusters_per_index_block); 1864987da915Sopenharmony_ci 1865987da915Sopenharmony_ci ntfs_dump_index_header("\t", &index_root->index); 1866987da915Sopenharmony_ci 1867987da915Sopenharmony_ci entry = (INDEX_ENTRY*)((u8*)index_root + 1868987da915Sopenharmony_ci le32_to_cpu(index_root->index.entries_offset) + 0x10); 1869987da915Sopenharmony_ci ntfs_log_verbose("\tDumping index root:\n"); 1870987da915Sopenharmony_ci printf("\tIndex entries total:\t %d\n", 1871987da915Sopenharmony_ci ntfs_dump_index_entries(entry, type)); 1872987da915Sopenharmony_ci} 1873987da915Sopenharmony_ci 1874987da915Sopenharmony_cistatic void ntfs_dump_usa_lsn(const char *indent, MFT_RECORD *mrec) 1875987da915Sopenharmony_ci{ 1876987da915Sopenharmony_ci printf("%sUpd. Seq. Array Off.:\t %u (0x%x)\n", indent, 1877987da915Sopenharmony_ci (unsigned)le16_to_cpu(mrec->usa_ofs), 1878987da915Sopenharmony_ci (unsigned)le16_to_cpu(mrec->usa_ofs)); 1879987da915Sopenharmony_ci printf("%sUpd. Seq. Array Count:\t %u (0x%x)\n", indent, 1880987da915Sopenharmony_ci (unsigned)le16_to_cpu(mrec->usa_count), 1881987da915Sopenharmony_ci (unsigned)le16_to_cpu(mrec->usa_count)); 1882987da915Sopenharmony_ci printf("%sUpd. Seq. Number:\t %u (0x%x)\n", indent, 1883987da915Sopenharmony_ci (unsigned)le16_to_cpup((le16*)((u8*)mrec + 1884987da915Sopenharmony_ci le16_to_cpu(mrec->usa_ofs))), 1885987da915Sopenharmony_ci (unsigned)le16_to_cpup((le16*)((u8*)mrec + 1886987da915Sopenharmony_ci le16_to_cpu(mrec->usa_ofs)))); 1887987da915Sopenharmony_ci printf("%sLogFile Seq. Number:\t 0x%llx\n", indent, 1888987da915Sopenharmony_ci (unsigned long long)sle64_to_cpu(mrec->lsn)); 1889987da915Sopenharmony_ci} 1890987da915Sopenharmony_ci 1891987da915Sopenharmony_ci 1892987da915Sopenharmony_cistatic s32 ntfs_dump_index_block(INDEX_BLOCK *ib, INDEX_ATTR_TYPE type, 1893987da915Sopenharmony_ci u32 ib_size) 1894987da915Sopenharmony_ci{ 1895987da915Sopenharmony_ci INDEX_ENTRY *entry; 1896987da915Sopenharmony_ci 1897987da915Sopenharmony_ci if (ntfs_mst_post_read_fixup((NTFS_RECORD*)ib, ib_size)) { 1898987da915Sopenharmony_ci ntfs_log_perror("Damaged INDX record"); 1899987da915Sopenharmony_ci return -1; 1900987da915Sopenharmony_ci } 1901987da915Sopenharmony_ci ntfs_log_verbose("\tDumping index block:\n"); 1902987da915Sopenharmony_ci if (opts.verbose) 1903987da915Sopenharmony_ci ntfs_dump_usa_lsn("\t\t", (MFT_RECORD*)ib); 1904987da915Sopenharmony_ci 1905987da915Sopenharmony_ci ntfs_log_verbose("\t\tNode VCN:\t\t %lld (0x%llx)\n", 1906987da915Sopenharmony_ci (unsigned long long)sle64_to_cpu(ib->index_block_vcn), 1907987da915Sopenharmony_ci (unsigned long long)sle64_to_cpu(ib->index_block_vcn)); 1908987da915Sopenharmony_ci 1909987da915Sopenharmony_ci entry = (INDEX_ENTRY*)((u8*)ib + 1910987da915Sopenharmony_ci le32_to_cpu(ib->index.entries_offset) + 0x18); 1911987da915Sopenharmony_ci 1912987da915Sopenharmony_ci if (opts.verbose) { 1913987da915Sopenharmony_ci ntfs_dump_index_header("\t\t", &ib->index); 1914987da915Sopenharmony_ci printf("\n"); 1915987da915Sopenharmony_ci } 1916987da915Sopenharmony_ci 1917987da915Sopenharmony_ci return ntfs_dump_index_entries(entry, type); 1918987da915Sopenharmony_ci} 1919987da915Sopenharmony_ci 1920987da915Sopenharmony_ci/** 1921987da915Sopenharmony_ci * ntfs_dump_attr_index_allocation() 1922987da915Sopenharmony_ci * 1923987da915Sopenharmony_ci * dump context of the index_allocation attribute 1924987da915Sopenharmony_ci */ 1925987da915Sopenharmony_cistatic void ntfs_dump_attr_index_allocation(ATTR_RECORD *attr, ntfs_inode *ni) 1926987da915Sopenharmony_ci{ 1927987da915Sopenharmony_ci INDEX_ALLOCATION *allocation, *tmp_alloc; 1928987da915Sopenharmony_ci INDEX_ROOT *ir; 1929987da915Sopenharmony_ci INDEX_ATTR_TYPE type; 1930987da915Sopenharmony_ci int total_entries = 0; 1931987da915Sopenharmony_ci int total_indx_blocks = 0; 1932987da915Sopenharmony_ci u8 *bitmap, *byte; 1933987da915Sopenharmony_ci int bit; 1934987da915Sopenharmony_ci ntfschar *name; 1935987da915Sopenharmony_ci u32 name_len; 1936987da915Sopenharmony_ci s64 data_size; 1937987da915Sopenharmony_ci 1938987da915Sopenharmony_ci ir = ntfs_index_root_get(ni, attr); 1939987da915Sopenharmony_ci if (!ir) { 1940987da915Sopenharmony_ci ntfs_log_perror("Failed to read $INDEX_ROOT attribute"); 1941987da915Sopenharmony_ci return; 1942987da915Sopenharmony_ci } 1943987da915Sopenharmony_ci 1944987da915Sopenharmony_ci type = get_index_attr_type(ni, attr, ir); 1945987da915Sopenharmony_ci 1946987da915Sopenharmony_ci name = (ntfschar *)((u8 *)attr + le16_to_cpu(attr->name_offset)); 1947987da915Sopenharmony_ci name_len = attr->name_length; 1948987da915Sopenharmony_ci 1949987da915Sopenharmony_ci byte = bitmap = ntfs_attr_readall(ni, AT_BITMAP, name, name_len, NULL); 1950987da915Sopenharmony_ci if (!byte) { 1951987da915Sopenharmony_ci ntfs_log_perror("Failed to read $BITMAP attribute"); 1952987da915Sopenharmony_ci goto out_index_root; 1953987da915Sopenharmony_ci } 1954987da915Sopenharmony_ci 1955987da915Sopenharmony_ci tmp_alloc = allocation = ntfs_attr_readall(ni, AT_INDEX_ALLOCATION, 1956987da915Sopenharmony_ci name, name_len, &data_size); 1957987da915Sopenharmony_ci if (!tmp_alloc) { 1958987da915Sopenharmony_ci ntfs_log_perror("Failed to read $INDEX_ALLOCATION attribute"); 1959987da915Sopenharmony_ci goto out_bitmap; 1960987da915Sopenharmony_ci } 1961987da915Sopenharmony_ci 1962987da915Sopenharmony_ci bit = 0; 1963987da915Sopenharmony_ci while ((u8 *)tmp_alloc < (u8 *)allocation + data_size) { 1964987da915Sopenharmony_ci if (*byte & (1 << bit)) { 1965987da915Sopenharmony_ci int entries; 1966987da915Sopenharmony_ci 1967987da915Sopenharmony_ci entries = ntfs_dump_index_block(tmp_alloc, type, 1968987da915Sopenharmony_ci le32_to_cpu( 1969987da915Sopenharmony_ci ir->index_block_size)); 1970987da915Sopenharmony_ci if (entries != -1) { 1971987da915Sopenharmony_ci total_entries += entries; 1972987da915Sopenharmony_ci total_indx_blocks++; 1973987da915Sopenharmony_ci ntfs_log_verbose("\tIndex entries:\t\t %d\n", 1974987da915Sopenharmony_ci entries); 1975987da915Sopenharmony_ci } 1976987da915Sopenharmony_ci } 1977987da915Sopenharmony_ci tmp_alloc = (INDEX_ALLOCATION *)((u8 *)tmp_alloc + 1978987da915Sopenharmony_ci le32_to_cpu( 1979987da915Sopenharmony_ci ir->index_block_size)); 1980987da915Sopenharmony_ci bit++; 1981987da915Sopenharmony_ci if (bit > 7) { 1982987da915Sopenharmony_ci bit = 0; 1983987da915Sopenharmony_ci byte++; 1984987da915Sopenharmony_ci } 1985987da915Sopenharmony_ci } 1986987da915Sopenharmony_ci 1987987da915Sopenharmony_ci printf("\tIndex entries total:\t %d\n", total_entries); 1988987da915Sopenharmony_ci printf("\tINDX blocks total:\t %d\n", total_indx_blocks); 1989987da915Sopenharmony_ci 1990987da915Sopenharmony_ci free(allocation); 1991987da915Sopenharmony_ciout_bitmap: 1992987da915Sopenharmony_ci free(bitmap); 1993987da915Sopenharmony_ciout_index_root: 1994987da915Sopenharmony_ci free(ir); 1995987da915Sopenharmony_ci} 1996987da915Sopenharmony_ci 1997987da915Sopenharmony_ci/** 1998987da915Sopenharmony_ci * ntfs_dump_attr_bitmap() 1999987da915Sopenharmony_ci * 2000987da915Sopenharmony_ci * dump the bitmap attribute 2001987da915Sopenharmony_ci */ 2002987da915Sopenharmony_cistatic void ntfs_dump_attr_bitmap(ATTR_RECORD *attr __attribute__((unused))) 2003987da915Sopenharmony_ci{ 2004987da915Sopenharmony_ci /* TODO */ 2005987da915Sopenharmony_ci} 2006987da915Sopenharmony_ci 2007987da915Sopenharmony_ci/** 2008987da915Sopenharmony_ci * ntfs_dump_attr_reparse_point() 2009987da915Sopenharmony_ci * 2010987da915Sopenharmony_ci * of ntfs 3.x dumps the reparse_point attribute 2011987da915Sopenharmony_ci */ 2012987da915Sopenharmony_cistatic void ntfs_dump_attr_reparse_point(ATTR_RECORD *attr 2013987da915Sopenharmony_ci __attribute__((unused)), ntfs_inode *inode) 2014987da915Sopenharmony_ci{ 2015987da915Sopenharmony_ci REPARSE_POINT *reparse; 2016987da915Sopenharmony_ci le32 tag; 2017987da915Sopenharmony_ci const char *name; 2018987da915Sopenharmony_ci u8 *pvalue; 2019987da915Sopenharmony_ci s64 size; 2020987da915Sopenharmony_ci unsigned int length; 2021987da915Sopenharmony_ci unsigned int cnt; 2022987da915Sopenharmony_ci 2023987da915Sopenharmony_ci if (attr->non_resident) { 2024987da915Sopenharmony_ci reparse = ntfs_attr_readall(inode, AT_REPARSE_POINT, 2025987da915Sopenharmony_ci (ntfschar*)NULL, 0, &size); 2026987da915Sopenharmony_ci } else { 2027987da915Sopenharmony_ci reparse = (REPARSE_POINT*)((u8*)attr + 2028987da915Sopenharmony_ci le16_to_cpu(attr->value_offset)); 2029987da915Sopenharmony_ci } 2030987da915Sopenharmony_ci if (reparse) { 2031987da915Sopenharmony_ci tag = reparse->reparse_tag; 2032987da915Sopenharmony_ci name = reparse_type_name(tag); 2033987da915Sopenharmony_ci printf("\tReparse tag:\t\t 0x%08lx%s\n", 2034987da915Sopenharmony_ci (long)le32_to_cpu(tag),name); 2035987da915Sopenharmony_ci length = le16_to_cpu(reparse->reparse_data_length); 2036987da915Sopenharmony_ci printf("\tData length:\t\t %u (0x%x)\n", 2037987da915Sopenharmony_ci (unsigned int)length,(unsigned int)length); 2038987da915Sopenharmony_ci cnt = length; 2039987da915Sopenharmony_ci pvalue = reparse->reparse_data; 2040987da915Sopenharmony_ci printf("\tData:\t\t\t"); 2041987da915Sopenharmony_ci printf(cnt ? " 0x" : "(NONE)"); 2042987da915Sopenharmony_ci if (cnt > 32) 2043987da915Sopenharmony_ci cnt = 32; 2044987da915Sopenharmony_ci while (cnt-- > 0) 2045987da915Sopenharmony_ci printf("%02x",*pvalue++); 2046987da915Sopenharmony_ci if (length > 32) 2047987da915Sopenharmony_ci printf("...\n"); 2048987da915Sopenharmony_ci else 2049987da915Sopenharmony_ci printf("\n"); 2050987da915Sopenharmony_ci if (attr->non_resident) 2051987da915Sopenharmony_ci free(reparse); 2052987da915Sopenharmony_ci } else { 2053987da915Sopenharmony_ci ntfs_log_perror("Failed to get the reparse data"); 2054987da915Sopenharmony_ci } 2055987da915Sopenharmony_ci} 2056987da915Sopenharmony_ci 2057987da915Sopenharmony_ci/** 2058987da915Sopenharmony_ci * ntfs_dump_attr_ea_information() 2059987da915Sopenharmony_ci * 2060987da915Sopenharmony_ci * dump the ea_information attribute 2061987da915Sopenharmony_ci */ 2062987da915Sopenharmony_cistatic void ntfs_dump_attr_ea_information(ATTR_RECORD *attr) 2063987da915Sopenharmony_ci{ 2064987da915Sopenharmony_ci EA_INFORMATION *ea_info; 2065987da915Sopenharmony_ci 2066987da915Sopenharmony_ci ea_info = (EA_INFORMATION*)((u8*)attr + 2067987da915Sopenharmony_ci le16_to_cpu(attr->value_offset)); 2068987da915Sopenharmony_ci printf("\tPacked EA length:\t %u (0x%x)\n", 2069987da915Sopenharmony_ci (unsigned)le16_to_cpu(ea_info->ea_length), 2070987da915Sopenharmony_ci (unsigned)le16_to_cpu(ea_info->ea_length)); 2071987da915Sopenharmony_ci printf("\tNEED_EA count:\t\t %u (0x%x)\n", 2072987da915Sopenharmony_ci (unsigned)le16_to_cpu(ea_info->need_ea_count), 2073987da915Sopenharmony_ci (unsigned)le16_to_cpu(ea_info->need_ea_count)); 2074987da915Sopenharmony_ci printf("\tUnpacked EA length:\t %u (0x%x)\n", 2075987da915Sopenharmony_ci (unsigned)le32_to_cpu(ea_info->ea_query_length), 2076987da915Sopenharmony_ci (unsigned)le32_to_cpu(ea_info->ea_query_length)); 2077987da915Sopenharmony_ci} 2078987da915Sopenharmony_ci 2079987da915Sopenharmony_ci/** 2080987da915Sopenharmony_ci * ntfs_dump_attr_ea() 2081987da915Sopenharmony_ci * 2082987da915Sopenharmony_ci * dump the ea attribute 2083987da915Sopenharmony_ci */ 2084987da915Sopenharmony_cistatic void ntfs_dump_attr_ea(ATTR_RECORD *attr, ntfs_volume *vol) 2085987da915Sopenharmony_ci{ 2086987da915Sopenharmony_ci const EA_ATTR *ea; 2087987da915Sopenharmony_ci const u8 *pvalue; 2088987da915Sopenharmony_ci u8 *buf = NULL; 2089987da915Sopenharmony_ci const le32 *pval; 2090987da915Sopenharmony_ci int offset; 2091987da915Sopenharmony_ci int cnt; 2092987da915Sopenharmony_ci s64 data_size; 2093987da915Sopenharmony_ci 2094987da915Sopenharmony_ci if (attr->non_resident) { 2095987da915Sopenharmony_ci runlist *rl; 2096987da915Sopenharmony_ci 2097987da915Sopenharmony_ci data_size = sle64_to_cpu(attr->data_size); 2098987da915Sopenharmony_ci if (!opts.verbose) 2099987da915Sopenharmony_ci return; 2100987da915Sopenharmony_ci /* FIXME: We don't handle fragmented mapping pairs case. */ 2101987da915Sopenharmony_ci rl = ntfs_mapping_pairs_decompress(vol, attr, NULL); 2102987da915Sopenharmony_ci if (rl) { 2103987da915Sopenharmony_ci s64 bytes_read; 2104987da915Sopenharmony_ci 2105987da915Sopenharmony_ci buf = ntfs_malloc(data_size); 2106987da915Sopenharmony_ci if (!buf) { 2107987da915Sopenharmony_ci free(rl); 2108987da915Sopenharmony_ci return; 2109987da915Sopenharmony_ci } 2110987da915Sopenharmony_ci bytes_read = ntfs_rl_pread(vol, rl, 0, data_size, buf); 2111987da915Sopenharmony_ci if (bytes_read != data_size) { 2112987da915Sopenharmony_ci ntfs_log_perror("ntfs_rl_pread failed"); 2113987da915Sopenharmony_ci free(buf); 2114987da915Sopenharmony_ci free(rl); 2115987da915Sopenharmony_ci return; 2116987da915Sopenharmony_ci } 2117987da915Sopenharmony_ci free(rl); 2118987da915Sopenharmony_ci ea = (EA_ATTR*)buf; 2119987da915Sopenharmony_ci } else { 2120987da915Sopenharmony_ci ntfs_log_perror("ntfs_mapping_pairs_decompress failed"); 2121987da915Sopenharmony_ci return; 2122987da915Sopenharmony_ci } 2123987da915Sopenharmony_ci } else { 2124987da915Sopenharmony_ci data_size = le32_to_cpu(attr->value_length); 2125987da915Sopenharmony_ci if (!opts.verbose) 2126987da915Sopenharmony_ci return; 2127987da915Sopenharmony_ci ea = (EA_ATTR*)((u8*)attr + le16_to_cpu(attr->value_offset)); 2128987da915Sopenharmony_ci } 2129987da915Sopenharmony_ci offset = 0; 2130987da915Sopenharmony_ci while (1) { 2131987da915Sopenharmony_ci printf("\n\tEA flags:\t\t "); 2132987da915Sopenharmony_ci if (ea->flags) { 2133987da915Sopenharmony_ci if (ea->flags == NEED_EA) 2134987da915Sopenharmony_ci printf("NEED_EA\n"); 2135987da915Sopenharmony_ci else 2136987da915Sopenharmony_ci printf("Unknown (0x%02x)\n", 2137987da915Sopenharmony_ci (unsigned)ea->flags); 2138987da915Sopenharmony_ci } else 2139987da915Sopenharmony_ci printf("NONE\n"); 2140987da915Sopenharmony_ci printf("\tName length:\t %d (0x%x)\n", 2141987da915Sopenharmony_ci (unsigned)ea->name_length, 2142987da915Sopenharmony_ci (unsigned)ea->name_length); 2143987da915Sopenharmony_ci printf("\tValue length:\t %d (0x%x)\n", 2144987da915Sopenharmony_ci (unsigned)le16_to_cpu(ea->value_length), 2145987da915Sopenharmony_ci (unsigned)le16_to_cpu(ea->value_length)); 2146987da915Sopenharmony_ci /* Name expected to be null terminated ? */ 2147987da915Sopenharmony_ci printf("\tName:\t\t '%s'\n", ea->name); 2148987da915Sopenharmony_ci printf("\tValue:\t\t "); 2149987da915Sopenharmony_ci if (ea->name_length == 11 && 2150987da915Sopenharmony_ci !strncmp((const char*)"SETFILEBITS", 2151987da915Sopenharmony_ci (const char*)ea->name, 11)) { 2152987da915Sopenharmony_ci pval = (const le32*)(ea->value + ea->name_length + 1); 2153987da915Sopenharmony_ci printf("0%lo\n", (unsigned long)le32_to_cpu(*pval)); 2154987da915Sopenharmony_ci } else { 2155987da915Sopenharmony_ci /* No alignment for value */ 2156987da915Sopenharmony_ci pvalue = ea->value + ea->name_length + 1; 2157987da915Sopenharmony_ci /* Hex show a maximum of 32 bytes */ 2158987da915Sopenharmony_ci cnt = le16_to_cpu(ea->value_length); 2159987da915Sopenharmony_ci printf(cnt ? "0x" : "(NONE)"); 2160987da915Sopenharmony_ci if (cnt > 32) 2161987da915Sopenharmony_ci cnt = 32; 2162987da915Sopenharmony_ci while (cnt-- > 0) 2163987da915Sopenharmony_ci printf("%02x",*pvalue++); 2164987da915Sopenharmony_ci if (le16_to_cpu(ea->value_length) > 32) 2165987da915Sopenharmony_ci printf("...\n"); 2166987da915Sopenharmony_ci else 2167987da915Sopenharmony_ci printf("\n"); 2168987da915Sopenharmony_ci } 2169987da915Sopenharmony_ci if (ea->next_entry_offset) { 2170987da915Sopenharmony_ci offset += le32_to_cpu(ea->next_entry_offset); 2171987da915Sopenharmony_ci ea = (const EA_ATTR*)((const u8*)ea 2172987da915Sopenharmony_ci + le32_to_cpu(ea->next_entry_offset)); 2173987da915Sopenharmony_ci } else 2174987da915Sopenharmony_ci break; 2175987da915Sopenharmony_ci if (offset >= data_size) 2176987da915Sopenharmony_ci break; 2177987da915Sopenharmony_ci } 2178987da915Sopenharmony_ci free(buf); 2179987da915Sopenharmony_ci} 2180987da915Sopenharmony_ci 2181987da915Sopenharmony_ci/** 2182987da915Sopenharmony_ci * ntfs_dump_attr_property_set() 2183987da915Sopenharmony_ci * 2184987da915Sopenharmony_ci * dump the property_set attribute 2185987da915Sopenharmony_ci */ 2186987da915Sopenharmony_cistatic void ntfs_dump_attr_property_set(ATTR_RECORD *attr __attribute__((unused))) 2187987da915Sopenharmony_ci{ 2188987da915Sopenharmony_ci /* TODO */ 2189987da915Sopenharmony_ci} 2190987da915Sopenharmony_ci 2191987da915Sopenharmony_cistatic void ntfs_hex_dump(void *buf,unsigned int length); 2192987da915Sopenharmony_ci 2193987da915Sopenharmony_ci/** 2194987da915Sopenharmony_ci * ntfs_dump_attr_logged_utility_stream() 2195987da915Sopenharmony_ci * 2196987da915Sopenharmony_ci * dump the property_set attribute 2197987da915Sopenharmony_ci */ 2198987da915Sopenharmony_cistatic void ntfs_dump_attr_logged_utility_stream(ATTR_RECORD *attr, 2199987da915Sopenharmony_ci ntfs_inode *ni) 2200987da915Sopenharmony_ci{ 2201987da915Sopenharmony_ci char *buf; 2202987da915Sopenharmony_ci s64 size; 2203987da915Sopenharmony_ci 2204987da915Sopenharmony_ci if (!opts.verbose) 2205987da915Sopenharmony_ci return; 2206987da915Sopenharmony_ci buf = ntfs_attr_readall(ni, AT_LOGGED_UTILITY_STREAM, 2207987da915Sopenharmony_ci ntfs_attr_get_name(attr), attr->name_length, &size); 2208987da915Sopenharmony_ci if (buf) 2209987da915Sopenharmony_ci ntfs_hex_dump(buf, size); 2210987da915Sopenharmony_ci free(buf); 2211987da915Sopenharmony_ci /* TODO */ 2212987da915Sopenharmony_ci} 2213987da915Sopenharmony_ci 2214987da915Sopenharmony_ci/** 2215987da915Sopenharmony_ci * ntfs_hex_dump 2216987da915Sopenharmony_ci */ 2217987da915Sopenharmony_cistatic void ntfs_hex_dump(void *buf,unsigned int length) 2218987da915Sopenharmony_ci{ 2219987da915Sopenharmony_ci unsigned int i=0; 2220987da915Sopenharmony_ci while (i<length) { 2221987da915Sopenharmony_ci unsigned int j; 2222987da915Sopenharmony_ci 2223987da915Sopenharmony_ci /* line start */ 2224987da915Sopenharmony_ci printf("\t%04X ",i); 2225987da915Sopenharmony_ci 2226987da915Sopenharmony_ci /* hex content */ 2227987da915Sopenharmony_ci for (j=i;(j<length) && (j<i+16);j++) { 2228987da915Sopenharmony_ci unsigned char c = *((char *)buf + j); 2229987da915Sopenharmony_ci printf("%02hhX ",c); 2230987da915Sopenharmony_ci } 2231987da915Sopenharmony_ci 2232987da915Sopenharmony_ci /* realign */ 2233987da915Sopenharmony_ci for (;j<i+16;j++) { 2234987da915Sopenharmony_ci printf(" "); 2235987da915Sopenharmony_ci } 2236987da915Sopenharmony_ci 2237987da915Sopenharmony_ci /* char content */ 2238987da915Sopenharmony_ci for (j=i;(j<length) && (j<i+16);j++) { 2239987da915Sopenharmony_ci unsigned char c = *((char *)buf + j); 2240987da915Sopenharmony_ci /* display unprintable chars as '.' */ 2241987da915Sopenharmony_ci if ((c<32) || (c>126)) { 2242987da915Sopenharmony_ci c = '.'; 2243987da915Sopenharmony_ci } 2244987da915Sopenharmony_ci printf("%c",c); 2245987da915Sopenharmony_ci } 2246987da915Sopenharmony_ci 2247987da915Sopenharmony_ci /* end line */ 2248987da915Sopenharmony_ci printf("\n"); 2249987da915Sopenharmony_ci i=j; 2250987da915Sopenharmony_ci } 2251987da915Sopenharmony_ci} 2252987da915Sopenharmony_ci 2253987da915Sopenharmony_ci/** 2254987da915Sopenharmony_ci * ntfs_dump_attr_unknown 2255987da915Sopenharmony_ci */ 2256987da915Sopenharmony_cistatic void ntfs_dump_attr_unknown(ATTR_RECORD *attr) 2257987da915Sopenharmony_ci{ 2258987da915Sopenharmony_ci printf("===== Please report this unknown attribute type to %s =====\n", 2259987da915Sopenharmony_ci NTFS_DEV_LIST); 2260987da915Sopenharmony_ci 2261987da915Sopenharmony_ci if (!attr->non_resident) { 2262987da915Sopenharmony_ci /* hex dump */ 2263987da915Sopenharmony_ci printf("\tDumping some of the attribute data:\n"); 2264987da915Sopenharmony_ci ntfs_hex_dump((u8*)attr + le16_to_cpu(attr->value_offset), 2265987da915Sopenharmony_ci (le32_to_cpu(attr->value_length) > 128) ? 2266987da915Sopenharmony_ci 128 : le32_to_cpu(attr->value_length)); 2267987da915Sopenharmony_ci } 2268987da915Sopenharmony_ci} 2269987da915Sopenharmony_ci 2270987da915Sopenharmony_ci/** 2271987da915Sopenharmony_ci * ntfs_dump_inode_general_info 2272987da915Sopenharmony_ci */ 2273987da915Sopenharmony_cistatic void ntfs_dump_inode_general_info(ntfs_inode *inode) 2274987da915Sopenharmony_ci{ 2275987da915Sopenharmony_ci MFT_RECORD *mrec = inode->mrec; 2276987da915Sopenharmony_ci le16 inode_flags = mrec->flags; 2277987da915Sopenharmony_ci 2278987da915Sopenharmony_ci printf("Dumping Inode %llu (0x%llx)\n", 2279987da915Sopenharmony_ci (long long)inode->mft_no, 2280987da915Sopenharmony_ci (unsigned long long)inode->mft_no); 2281987da915Sopenharmony_ci 2282987da915Sopenharmony_ci ntfs_dump_usa_lsn("", mrec); 2283987da915Sopenharmony_ci printf("MFT Record Seq. Numb.:\t %u (0x%x)\n", 2284987da915Sopenharmony_ci (unsigned)le16_to_cpu(mrec->sequence_number), 2285987da915Sopenharmony_ci (unsigned)le16_to_cpu(mrec->sequence_number)); 2286987da915Sopenharmony_ci printf("Number of Hard Links:\t %u (0x%x)\n", 2287987da915Sopenharmony_ci (unsigned)le16_to_cpu(mrec->link_count), 2288987da915Sopenharmony_ci (unsigned)le16_to_cpu(mrec->link_count)); 2289987da915Sopenharmony_ci printf("Attribute Offset:\t %u (0x%x)\n", 2290987da915Sopenharmony_ci (unsigned)le16_to_cpu(mrec->attrs_offset), 2291987da915Sopenharmony_ci (unsigned)le16_to_cpu(mrec->attrs_offset)); 2292987da915Sopenharmony_ci 2293987da915Sopenharmony_ci printf("MFT Record Flags:\t "); 2294987da915Sopenharmony_ci if (inode_flags) { 2295987da915Sopenharmony_ci if (MFT_RECORD_IN_USE & inode_flags) { 2296987da915Sopenharmony_ci printf("IN_USE "); 2297987da915Sopenharmony_ci inode_flags &= ~MFT_RECORD_IN_USE; 2298987da915Sopenharmony_ci } 2299987da915Sopenharmony_ci if (MFT_RECORD_IS_DIRECTORY & inode_flags) { 2300987da915Sopenharmony_ci printf("DIRECTORY "); 2301987da915Sopenharmony_ci inode_flags &= ~MFT_RECORD_IS_DIRECTORY; 2302987da915Sopenharmony_ci } 2303987da915Sopenharmony_ci /* The meaning of IS_4 is illusive but not its existence. */ 2304987da915Sopenharmony_ci if (MFT_RECORD_IS_4 & inode_flags) { 2305987da915Sopenharmony_ci printf("IS_4 "); 2306987da915Sopenharmony_ci inode_flags &= ~MFT_RECORD_IS_4; 2307987da915Sopenharmony_ci } 2308987da915Sopenharmony_ci if (MFT_RECORD_IS_VIEW_INDEX & inode_flags) { 2309987da915Sopenharmony_ci printf("VIEW_INDEX "); 2310987da915Sopenharmony_ci inode_flags &= ~MFT_RECORD_IS_VIEW_INDEX; 2311987da915Sopenharmony_ci } 2312987da915Sopenharmony_ci if (inode_flags) 2313987da915Sopenharmony_ci printf("UNKNOWN: 0x%04x", (unsigned)le16_to_cpu( 2314987da915Sopenharmony_ci inode_flags)); 2315987da915Sopenharmony_ci } else { 2316987da915Sopenharmony_ci printf("none"); 2317987da915Sopenharmony_ci } 2318987da915Sopenharmony_ci printf("\n"); 2319987da915Sopenharmony_ci 2320987da915Sopenharmony_ci printf("Bytes Used:\t\t %u (0x%x) bytes\n", 2321987da915Sopenharmony_ci (unsigned)le32_to_cpu(mrec->bytes_in_use), 2322987da915Sopenharmony_ci (unsigned)le32_to_cpu(mrec->bytes_in_use)); 2323987da915Sopenharmony_ci printf("Bytes Allocated:\t %u (0x%x) bytes\n", 2324987da915Sopenharmony_ci (unsigned)le32_to_cpu(mrec->bytes_allocated), 2325987da915Sopenharmony_ci (unsigned)le32_to_cpu(mrec->bytes_allocated)); 2326987da915Sopenharmony_ci 2327987da915Sopenharmony_ci if (mrec->base_mft_record) { 2328987da915Sopenharmony_ci printf("Base MFT Record:\t %llu (0x%llx)\n", 2329987da915Sopenharmony_ci (unsigned long long) 2330987da915Sopenharmony_ci MREF_LE(mrec->base_mft_record), 2331987da915Sopenharmony_ci (unsigned long long) 2332987da915Sopenharmony_ci MREF_LE(mrec->base_mft_record)); 2333987da915Sopenharmony_ci } 2334987da915Sopenharmony_ci printf("Next Attribute Instance: %u (0x%x)\n", 2335987da915Sopenharmony_ci (unsigned)le16_to_cpu(mrec->next_attr_instance), 2336987da915Sopenharmony_ci (unsigned)le16_to_cpu(mrec->next_attr_instance)); 2337987da915Sopenharmony_ci 2338987da915Sopenharmony_ci printf("MFT Padding:\t"); 2339987da915Sopenharmony_ci ntfs_dump_bytes((u8 *)mrec, le16_to_cpu(mrec->usa_ofs) + 2340987da915Sopenharmony_ci 2 * le16_to_cpu(mrec->usa_count), 2341987da915Sopenharmony_ci le16_to_cpu(mrec->attrs_offset)); 2342987da915Sopenharmony_ci printf("\n"); 2343987da915Sopenharmony_ci} 2344987da915Sopenharmony_ci 2345987da915Sopenharmony_ci/** 2346987da915Sopenharmony_ci * ntfs_get_file_attributes 2347987da915Sopenharmony_ci */ 2348987da915Sopenharmony_cistatic void ntfs_dump_file_attributes(ntfs_inode *inode) 2349987da915Sopenharmony_ci{ 2350987da915Sopenharmony_ci struct RUNCOUNT runcount; 2351987da915Sopenharmony_ci ntfs_attr_search_ctx *ctx = NULL; 2352987da915Sopenharmony_ci 2353987da915Sopenharmony_ci runcount.runs = 0; 2354987da915Sopenharmony_ci runcount.fragments = 0; 2355987da915Sopenharmony_ci /* then start enumerating attributes 2356987da915Sopenharmony_ci see ntfs_attr_lookup documentation for detailed explanation */ 2357987da915Sopenharmony_ci ctx = ntfs_attr_get_search_ctx(inode, NULL); 2358987da915Sopenharmony_ci while (!ntfs_attr_lookup(AT_UNUSED, NULL, 0, CASE_SENSITIVE, 2359987da915Sopenharmony_ci 0, NULL, 0, ctx)) { 2360987da915Sopenharmony_ci if (ctx->attr->type == AT_END || ctx->attr->type == AT_UNUSED) { 2361987da915Sopenharmony_ci printf("Weird: %s attribute type was found, please " 2362987da915Sopenharmony_ci "report this.\n", 2363987da915Sopenharmony_ci get_attribute_type_name( 2364987da915Sopenharmony_ci ctx->attr->type)); 2365987da915Sopenharmony_ci continue; 2366987da915Sopenharmony_ci } 2367987da915Sopenharmony_ci 2368987da915Sopenharmony_ci ntfs_dump_attribute_header(ctx, inode->vol, &runcount); 2369987da915Sopenharmony_ci 2370987da915Sopenharmony_ci switch (ctx->attr->type) { 2371987da915Sopenharmony_ci case AT_STANDARD_INFORMATION: 2372987da915Sopenharmony_ci ntfs_dump_attr_standard_information(ctx->attr); 2373987da915Sopenharmony_ci break; 2374987da915Sopenharmony_ci case AT_ATTRIBUTE_LIST: 2375987da915Sopenharmony_ci ntfs_dump_attr_list(ctx->attr, inode->vol); 2376987da915Sopenharmony_ci break; 2377987da915Sopenharmony_ci case AT_FILE_NAME: 2378987da915Sopenharmony_ci ntfs_dump_attr_file_name(ctx->attr); 2379987da915Sopenharmony_ci break; 2380987da915Sopenharmony_ci case AT_OBJECT_ID: 2381987da915Sopenharmony_ci ntfs_dump_attr_object_id(ctx->attr, inode->vol); 2382987da915Sopenharmony_ci break; 2383987da915Sopenharmony_ci case AT_SECURITY_DESCRIPTOR: 2384987da915Sopenharmony_ci ntfs_dump_attr_security_descriptor(ctx->attr, 2385987da915Sopenharmony_ci inode->vol); 2386987da915Sopenharmony_ci break; 2387987da915Sopenharmony_ci case AT_VOLUME_NAME: 2388987da915Sopenharmony_ci ntfs_dump_attr_volume_name(ctx->attr); 2389987da915Sopenharmony_ci break; 2390987da915Sopenharmony_ci case AT_VOLUME_INFORMATION: 2391987da915Sopenharmony_ci ntfs_dump_attr_volume_information(ctx->attr); 2392987da915Sopenharmony_ci break; 2393987da915Sopenharmony_ci case AT_DATA: 2394987da915Sopenharmony_ci ntfs_dump_attr_data(ctx->attr, inode); 2395987da915Sopenharmony_ci break; 2396987da915Sopenharmony_ci case AT_INDEX_ROOT: 2397987da915Sopenharmony_ci ntfs_dump_attr_index_root(ctx->attr, inode); 2398987da915Sopenharmony_ci break; 2399987da915Sopenharmony_ci case AT_INDEX_ALLOCATION: 2400987da915Sopenharmony_ci ntfs_dump_attr_index_allocation(ctx->attr, inode); 2401987da915Sopenharmony_ci break; 2402987da915Sopenharmony_ci case AT_BITMAP: 2403987da915Sopenharmony_ci ntfs_dump_attr_bitmap(ctx->attr); 2404987da915Sopenharmony_ci break; 2405987da915Sopenharmony_ci case AT_REPARSE_POINT: 2406987da915Sopenharmony_ci ntfs_dump_attr_reparse_point(ctx->attr, inode); 2407987da915Sopenharmony_ci break; 2408987da915Sopenharmony_ci case AT_EA_INFORMATION: 2409987da915Sopenharmony_ci ntfs_dump_attr_ea_information(ctx->attr); 2410987da915Sopenharmony_ci break; 2411987da915Sopenharmony_ci case AT_EA: 2412987da915Sopenharmony_ci ntfs_dump_attr_ea(ctx->attr, inode->vol); 2413987da915Sopenharmony_ci break; 2414987da915Sopenharmony_ci case AT_PROPERTY_SET: 2415987da915Sopenharmony_ci ntfs_dump_attr_property_set(ctx->attr); 2416987da915Sopenharmony_ci break; 2417987da915Sopenharmony_ci case AT_LOGGED_UTILITY_STREAM: 2418987da915Sopenharmony_ci ntfs_dump_attr_logged_utility_stream(ctx->attr, inode); 2419987da915Sopenharmony_ci break; 2420987da915Sopenharmony_ci default: 2421987da915Sopenharmony_ci ntfs_dump_attr_unknown(ctx->attr); 2422987da915Sopenharmony_ci } 2423987da915Sopenharmony_ci } 2424987da915Sopenharmony_ci 2425987da915Sopenharmony_ci /* if we exited the loop before we're done - notify the user */ 2426987da915Sopenharmony_ci if (errno != ENOENT) { 2427987da915Sopenharmony_ci ntfs_log_perror("ntfsinfo error: stopped before finished " 2428987da915Sopenharmony_ci "enumerating attributes"); 2429987da915Sopenharmony_ci } else { 2430987da915Sopenharmony_ci printf("End of inode reached\n"); 2431987da915Sopenharmony_ci if (opts.verbose) { 2432987da915Sopenharmony_ci printf("Total runs: %lu (fragments: %lu)\n", 2433987da915Sopenharmony_ci runcount.runs, runcount.fragments); 2434987da915Sopenharmony_ci } 2435987da915Sopenharmony_ci } 2436987da915Sopenharmony_ci 2437987da915Sopenharmony_ci /* close all data-structures we used */ 2438987da915Sopenharmony_ci ntfs_attr_put_search_ctx(ctx); 2439987da915Sopenharmony_ci ntfs_inode_close(inode); 2440987da915Sopenharmony_ci} 2441987da915Sopenharmony_ci 2442987da915Sopenharmony_ci/** 2443987da915Sopenharmony_ci * main() - Begin here 2444987da915Sopenharmony_ci * 2445987da915Sopenharmony_ci * Start from here. 2446987da915Sopenharmony_ci * 2447987da915Sopenharmony_ci * Return: 0 Success, the program worked 2448987da915Sopenharmony_ci * 1 Error, something went wrong 2449987da915Sopenharmony_ci */ 2450987da915Sopenharmony_ciint main(int argc, char **argv) 2451987da915Sopenharmony_ci{ 2452987da915Sopenharmony_ci ntfs_volume *vol; 2453987da915Sopenharmony_ci int res; 2454987da915Sopenharmony_ci 2455987da915Sopenharmony_ci setlinebuf(stdout); 2456987da915Sopenharmony_ci 2457987da915Sopenharmony_ci ntfs_log_set_handler(ntfs_log_handler_outerr); 2458987da915Sopenharmony_ci 2459987da915Sopenharmony_ci res = parse_options(argc, argv); 2460987da915Sopenharmony_ci if (res > 0) 2461987da915Sopenharmony_ci printf("Failed to parse command line options\n"); 2462987da915Sopenharmony_ci if (res >= 0) 2463987da915Sopenharmony_ci exit(res); 2464987da915Sopenharmony_ci 2465987da915Sopenharmony_ci utils_set_locale(); 2466987da915Sopenharmony_ci 2467987da915Sopenharmony_ci vol = utils_mount_volume(opts.device, NTFS_MNT_RDONLY | 2468987da915Sopenharmony_ci (opts.force ? NTFS_MNT_RECOVER : 0)); 2469987da915Sopenharmony_ci if (!vol) { 2470987da915Sopenharmony_ci printf("Failed to open '%s'.\n", opts.device); 2471987da915Sopenharmony_ci exit(1); 2472987da915Sopenharmony_ci } 2473987da915Sopenharmony_ci 2474987da915Sopenharmony_ci /* 2475987da915Sopenharmony_ci * if opts.mft is not 0, then we will print out information about 2476987da915Sopenharmony_ci * the volume, such as the sector size and whatnot. 2477987da915Sopenharmony_ci */ 2478987da915Sopenharmony_ci if (opts.mft) 2479987da915Sopenharmony_ci ntfs_dump_volume(vol); 2480987da915Sopenharmony_ci 2481987da915Sopenharmony_ci if ((opts.inode != -1) || opts.filename) { 2482987da915Sopenharmony_ci ntfs_inode *inode; 2483987da915Sopenharmony_ci /* obtain the inode */ 2484987da915Sopenharmony_ci if (opts.filename) { 2485987da915Sopenharmony_ci#ifdef HAVE_WINDOWS_H 2486987da915Sopenharmony_ci char *unix_name; 2487987da915Sopenharmony_ci 2488987da915Sopenharmony_ci unix_name = ntfs_utils_unix_path(opts.filename); 2489987da915Sopenharmony_ci if (unix_name) { 2490987da915Sopenharmony_ci inode = ntfs_pathname_to_inode(vol, NULL, 2491987da915Sopenharmony_ci unix_name); 2492987da915Sopenharmony_ci free(unix_name); 2493987da915Sopenharmony_ci } else 2494987da915Sopenharmony_ci inode = (ntfs_inode*)NULL; 2495987da915Sopenharmony_ci#else 2496987da915Sopenharmony_ci inode = ntfs_pathname_to_inode(vol, NULL, 2497987da915Sopenharmony_ci opts.filename); 2498987da915Sopenharmony_ci#endif 2499987da915Sopenharmony_ci } else { 2500987da915Sopenharmony_ci inode = ntfs_inode_open(vol, MK_MREF(opts.inode, 0)); 2501987da915Sopenharmony_ci } 2502987da915Sopenharmony_ci 2503987da915Sopenharmony_ci /* dump the inode information */ 2504987da915Sopenharmony_ci if (inode) { 2505987da915Sopenharmony_ci /* general info about the inode's mft record */ 2506987da915Sopenharmony_ci ntfs_dump_inode_general_info(inode); 2507987da915Sopenharmony_ci /* dump attributes */ 2508987da915Sopenharmony_ci ntfs_dump_file_attributes(inode); 2509987da915Sopenharmony_ci } else { 2510987da915Sopenharmony_ci /* can't open inode */ 2511987da915Sopenharmony_ci /* 2512987da915Sopenharmony_ci * note: when the specified inode does not exist, either 2513987da915Sopenharmony_ci * EIO or or ESPIPE is returned, we should notify better 2514987da915Sopenharmony_ci * in those cases 2515987da915Sopenharmony_ci */ 2516987da915Sopenharmony_ci ntfs_log_perror("Error loading node"); 2517987da915Sopenharmony_ci } 2518987da915Sopenharmony_ci } 2519987da915Sopenharmony_ci 2520987da915Sopenharmony_ci ntfs_umount(vol, FALSE); 2521987da915Sopenharmony_ci return 0; 2522987da915Sopenharmony_ci} 2523987da915Sopenharmony_ci 2524