ReactOS  0.4.15-dev-494-g1d8c567
nfi.c File Reference
#include <windows.h>
#include <tchar.h>
#include <stdio.h>
Include dependency graph for nfi.c:

Go to the source code of this file.

Classes

struct  NTFS_RECORD_HEADER
 
struct  _FILE_RECORD_HEADER
 
struct  NTFS_ATTR_RECORD
 
struct  FILENAME_ATTRIBUTE
 
struct  _NAME_CACHE_ENTRY
 

Macros

#define NRH_FILE_TYPE   0x454C4946
 
#define NTFS_FILE_NAME_POSIX   0
 
#define NTFS_FILE_NAME_WIN32   1
 
#define NTFS_FILE_NAME_DOS   2
 
#define NTFS_FILE_NAME_WIN32_AND_DOS   3
 
#define NTFS_FILE_MFT   0
 
#define NTFS_FILE_MFTMIRR   1
 
#define NTFS_FILE_LOGFILE   2
 
#define NTFS_FILE_VOLUME   3
 
#define NTFS_FILE_ATTRDEF   4
 
#define NTFS_FILE_ROOT   5
 
#define NTFS_FILE_BITMAP   6
 
#define NTFS_FILE_BOOT   7
 
#define NTFS_FILE_BADCLUS   8
 
#define NTFS_FILE_QUOTA   9
 
#define NTFS_FILE_UPCASE   10
 
#define NTFS_FILE_EXTEND   11
 
#define NTFS_MFT_MASK   0x0000FFFFFFFFFFFFULL
 
#define NTFS_FILE_TYPE_DIRECTORY   0x10000000
 

Typedefs

typedef struct NTFS_RECORD_HEADERPNTFS_RECORD_HEADER
 
typedef enum ATTRIBUTE_TYPEPATTRIBUTE_TYPE
 
typedef struct _FILE_RECORD_HEADER FILE_RECORD_HEADER
 
typedef struct _FILE_RECORD_HEADERPFILE_RECORD_HEADER
 
typedef struct NTFS_ATTR_RECORDPNTFS_ATTR_RECORD
 
typedef struct FILENAME_ATTRIBUTEPFILENAME_ATTRIBUTE
 
typedef struct _NAME_CACHE_ENTRY NAME_CACHE_ENTRY
 
typedef struct _NAME_CACHE_ENTRYPNAME_CACHE_ENTRY
 

Enumerations

enum  ATTRIBUTE_TYPE {
  AttributeStandardInformation = 0x10, AttributeAttributeList = 0x20, AttributeFileName = 0x30, AttributeObjectId = 0x40,
  AttributeSecurityDescriptor = 0x50, AttributeVolumeName = 0x60, AttributeVolumeInformation = 0x70, AttributeData = 0x80,
  AttributeIndexRoot = 0x90, AttributeIndexAllocation = 0xA0, AttributeBitmap = 0xB0, AttributeReparsePoint = 0xC0,
  AttributeEAInformation = 0xD0, AttributeEA = 0xE0, AttributePropertySet = 0xF0, AttributeLoggedUtilityStream = 0x100,
  AttributeEnd = 0xFFFFFFFF, AttributeStandardInformation = 0x10, AttributeAttributeList = 0x20, AttributeFileName = 0x30,
  AttributeObjectId = 0x40, AttributeSecurityDescriptor = 0x50, AttributeVolumeName = 0x60, AttributeVolumeInformation = 0x70,
  AttributeData = 0x80, AttributeIndexRoot = 0x90, AttributeIndexAllocation = 0xA0, AttributeBitmap = 0xB0,
  AttributeReparsePoint = 0xC0, AttributeEAInformation = 0xD0, AttributeEA = 0xE0, AttributePropertySet = 0xF0,
  AttributeLoggedUtilityStream = 0x100, AttributeEnd = 0xFFFFFFFF
}
 

Functions

void PrintUsage (void)
 
PNAME_CACHE_ENTRY FindInCache (ULONGLONG MftId)
 
PNAME_CACHE_ENTRY AddToCache (PWSTR Name, DWORD Length, ULONGLONG MftId)
 
PNAME_CACHE_ENTRY HandleFile (HANDLE VolumeHandle, PNTFS_VOLUME_DATA_BUFFER VolumeInfo, ULONGLONG Id, PNTFS_FILE_RECORD_OUTPUT_BUFFER OutputBuffer, BOOLEAN Silent)
 
PNAME_CACHE_ENTRY PrintPrettyName (HANDLE VolumeHandle, PNTFS_VOLUME_DATA_BUFFER VolumeInfo, PNTFS_ATTR_RECORD Attributes, PNTFS_ATTR_RECORD AttributesEnd, ULONGLONG MftId, BOOLEAN Silent)
 
PUCHAR DecodeRun (PUCHAR DataRun, LONGLONG *DataRunOffset, ULONGLONG *DataRunLength)
 
void PrintAttributeInfo (PNTFS_ATTR_RECORD Attribute, DWORD MaxSize)
 
int __cdecl _tmain (int argc, const TCHAR *argv[])
 

Variables

PWSTR KnownEntries [NTFS_FILE_EXTEND+1]
 
PNAME_CACHE_ENTRY CacheHead = NULL
 

Macro Definition Documentation

◆ NRH_FILE_TYPE

#define NRH_FILE_TYPE   0x454C4946

Definition at line 21 of file nfi.c.

◆ NTFS_FILE_ATTRDEF

#define NTFS_FILE_ATTRDEF   4

Definition at line 123 of file nfi.c.

◆ NTFS_FILE_BADCLUS

#define NTFS_FILE_BADCLUS   8

Definition at line 127 of file nfi.c.

◆ NTFS_FILE_BITMAP

#define NTFS_FILE_BITMAP   6

Definition at line 125 of file nfi.c.

◆ NTFS_FILE_BOOT

#define NTFS_FILE_BOOT   7

Definition at line 126 of file nfi.c.

◆ NTFS_FILE_EXTEND

#define NTFS_FILE_EXTEND   11

Definition at line 130 of file nfi.c.

◆ NTFS_FILE_LOGFILE

#define NTFS_FILE_LOGFILE   2

Definition at line 121 of file nfi.c.

◆ NTFS_FILE_MFT

#define NTFS_FILE_MFT   0

Definition at line 119 of file nfi.c.

◆ NTFS_FILE_MFTMIRR

#define NTFS_FILE_MFTMIRR   1

Definition at line 120 of file nfi.c.

◆ NTFS_FILE_NAME_DOS

#define NTFS_FILE_NAME_DOS   2

Definition at line 116 of file nfi.c.

◆ NTFS_FILE_NAME_POSIX

#define NTFS_FILE_NAME_POSIX   0

Definition at line 114 of file nfi.c.

◆ NTFS_FILE_NAME_WIN32

#define NTFS_FILE_NAME_WIN32   1

Definition at line 115 of file nfi.c.

◆ NTFS_FILE_NAME_WIN32_AND_DOS

#define NTFS_FILE_NAME_WIN32_AND_DOS   3

Definition at line 117 of file nfi.c.

◆ NTFS_FILE_QUOTA

#define NTFS_FILE_QUOTA   9

Definition at line 128 of file nfi.c.

◆ NTFS_FILE_ROOT

#define NTFS_FILE_ROOT   5

Definition at line 124 of file nfi.c.

◆ NTFS_FILE_TYPE_DIRECTORY

#define NTFS_FILE_TYPE_DIRECTORY   0x10000000

Definition at line 150 of file nfi.c.

◆ NTFS_FILE_UPCASE

#define NTFS_FILE_UPCASE   10

Definition at line 129 of file nfi.c.

◆ NTFS_FILE_VOLUME

#define NTFS_FILE_VOLUME   3

Definition at line 122 of file nfi.c.

◆ NTFS_MFT_MASK

#define NTFS_MFT_MASK   0x0000FFFFFFFFFFFFULL

Definition at line 148 of file nfi.c.

Typedef Documentation

◆ FILE_RECORD_HEADER

◆ NAME_CACHE_ENTRY

◆ PATTRIBUTE_TYPE

◆ PFILE_RECORD_HEADER

◆ PFILENAME_ATTRIBUTE

◆ PNAME_CACHE_ENTRY

◆ PNTFS_ATTR_RECORD

◆ PNTFS_RECORD_HEADER

Enumeration Type Documentation

◆ ATTRIBUTE_TYPE

Enumerator
AttributeStandardInformation 
AttributeAttributeList 
AttributeFileName 
AttributeObjectId 
AttributeSecurityDescriptor 
AttributeVolumeName 
AttributeVolumeInformation 
AttributeData 
AttributeIndexRoot 
AttributeIndexAllocation 
AttributeBitmap 
AttributeReparsePoint 
AttributeEAInformation 
AttributeEA 
AttributePropertySet 
AttributeLoggedUtilityStream 
AttributeEnd 
AttributeStandardInformation 
AttributeAttributeList 
AttributeFileName 
AttributeObjectId 
AttributeSecurityDescriptor 
AttributeVolumeName 
AttributeVolumeInformation 
AttributeData 
AttributeIndexRoot 
AttributeIndexAllocation 
AttributeBitmap 
AttributeReparsePoint 
AttributeEAInformation 
AttributeEA 
AttributePropertySet 
AttributeLoggedUtilityStream 
AttributeEnd 

Definition at line 23 of file nfi.c.

Function Documentation

◆ _tmain()

int __cdecl _tmain ( int  argc,
const TCHAR argv[] 
)

Definition at line 568 of file nfi.c.

569 {
570  TCHAR VolumeName[] = _T("\\\\.\\C:");
574  ULONGLONG File;
576  TCHAR Letter;
577  PNAME_CACHE_ENTRY CacheEntry;
578 
579  if (argc == 1)
580  {
581  PrintUsage();
582  return 0;
583  }
584 
585  /* Setup volume name */
586  Letter = argv[1][0];
587  if ((Letter >= 'A' && Letter <= 'Z') ||
588  (Letter >= 'a' && Letter <= 'z'))
589  {
590  VolumeName[4] = Letter;
591  }
592 
593  /* Open volume */
596  {
597  _ftprintf(stderr, _T("Failed opening the volume '%s' (%lx)\n"), VolumeName, GetLastError());
598  return 1;
599  }
600 
601  /* Get NTFS volume info */
603  {
604  _ftprintf(stderr, _T("Failed requesting volume '%s' data (%lx)\n"), VolumeName, GetLastError());
606  return 1;
607  }
608 
609  /* Validate output */
610  if (LengthReturned < sizeof(VolumeInfo))
611  {
612  _ftprintf(stderr, _T("Failed reading volume '%s' data (%lx)\n"), VolumeName, GetLastError());
614  return 1;
615  }
616 
617  /* Allocate a buffer big enough to hold a file record */
618  OutputBuffer = HeapAlloc(GetProcessHeap(), 0, VolumeInfo.BytesPerFileRecordSegment + sizeof(NTFS_FILE_RECORD_OUTPUT_BUFFER));
619  if (OutputBuffer == NULL)
620  {
621  _ftprintf(stderr, _T("Failed to allocate %Ix bytes\n"), VolumeInfo.BytesPerFileRecordSegment + sizeof(NTFS_FILE_RECORD_OUTPUT_BUFFER));
623  return 1;
624  }
625 
626  /* Forever loop, extract all the files! */
627  for (File = 0;; ++File)
628  {
630  }
631 
632  /* Free memory! */
633  while (CacheHead != NULL)
634  {
635  CacheEntry = CacheHead;
636  CacheHead = CacheEntry->Next;
637  HeapFree(GetProcessHeap(), 0, CacheEntry);
638  }
639 
640  /* Cleanup and exit */
643  return 0;
644 }
static int argc
Definition: ServiceArgs.c:12
#define CloseHandle
Definition: compat.h:407
#define INVALID_HANDLE_VALUE
Definition: compat.h:400
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1059
#define FILE_SHARE_WRITE
Definition: nt_native.h:681
#define argv
Definition: mplay32.c:18
#define FILE_SHARE_READ
Definition: compat.h:125
struct _NAME_CACHE_ENTRY * Next
Definition: nfi.c:154
_In_opt_ PVOID _In_ PCSTR File
Definition: iofuncs.h:615
smooth NULL
Definition: ftsmooth.c:416
_Must_inspect_result_ _In_ PFILE_OBJECT _In_ ULONG _In_ FILE_INFORMATION_CLASS _Out_opt_ PULONG LengthReturned
Definition: fltkernel.h:1306
#define FSCTL_GET_NTFS_VOLUME_DATA
Definition: ntifs_ex.h:261
_Must_inspect_result_ __drv_aliasesMem _In_ PDEVICE_OBJECT _In_opt_ PVOID _In_ ULONG _Out_opt_ PVOID OutputBuffer
Definition: iofuncs.h:713
#define _ftprintf
Definition: tchar.h:518
#define OPEN_EXISTING
Definition: compat.h:435
char TCHAR
Definition: xmlstorage.h:189
#define _T(x)
Definition: vfdio.h:22
#define GetProcessHeap()
Definition: compat.h:404
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
uint64_t ULONGLONG
Definition: typedefs.h:66
unsigned long DWORD
Definition: ntddk_ex.h:95
_Must_inspect_result_ _Out_ PHANDLE VolumeHandle
Definition: fltkernel.h:2284
void PrintUsage(void)
Definition: nfi.c:162
WCHAR Letter
#define GENERIC_READ
Definition: compat.h:124
PNAME_CACHE_ENTRY CacheHead
Definition: nfi.c:160
Definition: nfi.c:152
BOOL WINAPI DeviceIoControl(IN HANDLE hDevice, IN DWORD dwIoControlCode, IN LPVOID lpInBuffer OPTIONAL, IN DWORD nInBufferSize OPTIONAL, OUT LPVOID lpOutBuffer OPTIONAL, IN DWORD nOutBufferSize OPTIONAL, OUT LPDWORD lpBytesReturned OPTIONAL, IN LPOVERLAPPED lpOverlapped OPTIONAL)
Definition: deviceio.c:136
IN OUT PVCB OUT PDIRENT OUT PBCB IN BOOLEAN CreateFile
Definition: fatprocs.h:913
_Must_inspect_result_ _Inout_opt_ PUNICODE_STRING VolumeName
Definition: fltkernel.h:1117
PNAME_CACHE_ENTRY HandleFile(HANDLE VolumeHandle, PNTFS_VOLUME_DATA_BUFFER VolumeInfo, ULONGLONG Id, PNTFS_FILE_RECORD_OUTPUT_BUFFER OutputBuffer, BOOLEAN Silent)
Definition: nfi.c:507
FILE * stderr
Definition: File.h:15
#define HeapFree(x, y, z)
Definition: compat.h:403

◆ AddToCache()

PNAME_CACHE_ENTRY AddToCache ( PWSTR  Name,
DWORD  Length,
ULONGLONG  MftId 
)

Definition at line 182 of file nfi.c.

183 {
184  PNAME_CACHE_ENTRY CacheEntry;
185 
186  /* Don't add in cache if already there! */
187  CacheEntry = FindInCache(MftId);
188  if (CacheEntry != NULL)
189  {
190  return CacheEntry;
191  }
192 
193  /* Allocate an entry big enough to store name and cache info */
194  CacheEntry = HeapAlloc(GetProcessHeap(), 0, sizeof(NAME_CACHE_ENTRY) + Length);
195  if (CacheEntry == NULL)
196  {
197  return NULL;
198  }
199 
200  /* Insert in head (likely more perf) */
201  CacheEntry->Next = CacheHead;
202  CacheHead = CacheEntry;
203  /* Set up entry with full path */
204  CacheEntry->MftId = MftId;
205  CacheEntry->NameLen = Length;
206  CopyMemory(CacheEntry->Name, Name, Length);
207 
208  return CacheEntry;
209 }
ULONG NameLen
Definition: nfi.c:156
WCHAR Name[1]
Definition: nfi.c:157
struct _NAME_CACHE_ENTRY * Next
Definition: nfi.c:154
smooth NULL
Definition: ftsmooth.c:416
#define GetProcessHeap()
Definition: compat.h:404
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
#define CopyMemory
Definition: winbase.h:1646
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
PNAME_CACHE_ENTRY CacheHead
Definition: nfi.c:160
Definition: nfi.c:152
ULONGLONG MftId
Definition: nfi.c:155
PNAME_CACHE_ENTRY FindInCache(ULONGLONG MftId)
Definition: nfi.c:167

Referenced by PrintPrettyName().

◆ DecodeRun()

PUCHAR DecodeRun ( PUCHAR  DataRun,
LONGLONG DataRunOffset,
ULONGLONG DataRunLength 
)

Definition at line 359 of file nfi.c.

360 {
361  UCHAR DataRunOffsetSize;
362  UCHAR DataRunLengthSize;
363  CHAR i;
364 
365  /* Get the offset size (in bytes) of the run */
366  DataRunOffsetSize = (*DataRun >> 4) & 0xF;
367  /* Get the length size (in bytes) of the run */
368  DataRunLengthSize = *DataRun & 0xF;
369 
370  /* Initialize values */
371  *DataRunOffset = 0;
372  *DataRunLength = 0;
373 
374  /* Move to next byte */
375  DataRun++;
376 
377  /* First, extract (byte after byte) run length with the size extracted from header */
378  for (i = 0; i < DataRunLengthSize; i++)
379  {
380  *DataRunLength += ((ULONG64)*DataRun) << (i * 8);
381  /* Next byte */
382  DataRun++;
383  }
384 
385  /* If offset size is 0, return -1 to show that's sparse run */
386  if (DataRunOffsetSize == 0)
387  {
388  *DataRunOffset = -1;
389  }
390  /* Otherwise, extract offset */
391  else
392  {
393  /* Extract (byte after byte) run offset with the size extracted from header */
394  for (i = 0; i < DataRunOffsetSize - 1; i++)
395  {
396  *DataRunOffset += ((ULONG64)*DataRun) << (i * 8);
397  /* Next byte */
398  DataRun++;
399  }
400  /* The last byte contains sign so we must process it different way. */
401  *DataRunOffset = ((LONG64)(CHAR)(*(DataRun++)) << (i * 8)) + *DataRunOffset;
402  }
403 
404  /* Return next run */
405  return DataRun;
406 }
char CHAR
Definition: xmlstorage.h:175
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
int64_t LONG64
Definition: typedefs.h:67
unsigned __int64 ULONG64
Definition: imports.h:198
unsigned char UCHAR
Definition: xmlstorage.h:181

Referenced by PrintAttributeInfo().

◆ FindInCache()

PNAME_CACHE_ENTRY FindInCache ( ULONGLONG  MftId)

Definition at line 167 of file nfi.c.

168 {
169  PNAME_CACHE_ENTRY CacheEntry;
170 
171  for (CacheEntry = CacheHead; CacheEntry != NULL; CacheEntry = CacheEntry->Next)
172  {
173  if (MftId == CacheEntry->MftId)
174  {
175  return CacheEntry;
176  }
177  }
178 
179  return NULL;
180 }
struct _NAME_CACHE_ENTRY * Next
Definition: nfi.c:154
smooth NULL
Definition: ftsmooth.c:416
PNAME_CACHE_ENTRY CacheHead
Definition: nfi.c:160
Definition: nfi.c:152
ULONGLONG MftId
Definition: nfi.c:155

Referenced by AddToCache(), and PrintPrettyName().

◆ HandleFile()

PNAME_CACHE_ENTRY HandleFile ( HANDLE  VolumeHandle,
PNTFS_VOLUME_DATA_BUFFER  VolumeInfo,
ULONGLONG  Id,
PNTFS_FILE_RECORD_OUTPUT_BUFFER  OutputBuffer,
BOOLEAN  Silent 
)

Definition at line 507 of file nfi.c.

508 {
510  PFILE_RECORD_HEADER FileRecord;
511  PNTFS_ATTR_RECORD Attribute, AttributesEnd;
513  PNAME_CACHE_ENTRY CacheEntry;
514 
515  /* Get the file record */
516  InputBuffer.FileReferenceNumber.QuadPart = Id;
518  OutputBuffer, VolumeInfo->BytesPerFileRecordSegment + sizeof(NTFS_FILE_RECORD_OUTPUT_BUFFER),
519  &LengthReturned, NULL))
520  {
521  return NULL;
522  }
523 
524  /* Don't deal with it if we already browsed it
525  * FSCTL_GET_NTFS_FILE_RECORD always returns previous record if demanded
526  * isn't allocated
527  */
528  if (OutputBuffer->FileReferenceNumber.QuadPart != Id)
529  {
530  return NULL;
531  }
532 
533  /* Sanity check */
534  FileRecord = (PFILE_RECORD_HEADER)OutputBuffer->FileRecordBuffer;
535  if (FileRecord->Ntfs.Type != NRH_FILE_TYPE)
536  {
537  return NULL;
538  }
539 
540  if (!Silent)
541  {
542  /* Print ID */
543  _tprintf(_T("\nFile %I64d\n"), OutputBuffer->FileReferenceNumber.QuadPart);
544  }
545 
546  /* Get attributes list */
547  Attribute = (PNTFS_ATTR_RECORD)((ULONG_PTR)FileRecord + FileRecord->AttributeOffset);
548  AttributesEnd = (PNTFS_ATTR_RECORD)((ULONG_PTR)FileRecord + FileRecord->BytesInUse);
549 
550  /* Print the file name */
551  CacheEntry = PrintPrettyName(VolumeHandle, VolumeInfo, Attribute, AttributesEnd, Id, Silent);
552 
553  if (!Silent)
554  {
555  /* And print attributes information for each attribute */
556  while (Attribute < AttributesEnd && Attribute->Type != AttributeEnd)
557  {
558  PrintAttributeInfo(Attribute, VolumeInfo->BytesPerFileRecordSegment);
559  Attribute = (PNTFS_ATTR_RECORD)((ULONG_PTR)Attribute + Attribute->Length);
560  }
561  }
562 
563  return CacheEntry;
564 }
#define _tprintf
Definition: tchar.h:506
Type
Definition: Type.h:6
struct _FILE_RECORD_HEADER * PFILE_RECORD_HEADER
ULONG BytesInUse
Definition: ntfs.h:253
void PrintAttributeInfo(PNTFS_ATTR_RECORD Attribute, DWORD MaxSize)
Definition: nfi.c:408
CHAR InputBuffer[80]
Definition: conmgr.c:33
DWORD Id
uint32_t ULONG_PTR
Definition: typedefs.h:64
ULONG Length
Definition: ntfs.h:123
PNAME_CACHE_ENTRY PrintPrettyName(HANDLE VolumeHandle, PNTFS_VOLUME_DATA_BUFFER VolumeInfo, PNTFS_ATTR_RECORD Attributes, PNTFS_ATTR_RECORD AttributesEnd, ULONGLONG MftId, BOOLEAN Silent)
Definition: nfi.c:213
USHORT AttributeOffset
Definition: ntfs.h:251
smooth NULL
Definition: ftsmooth.c:416
_Must_inspect_result_ _In_ PFILE_OBJECT _In_ ULONG _In_ FILE_INFORMATION_CLASS _Out_opt_ PULONG LengthReturned
Definition: fltkernel.h:1306
_Must_inspect_result_ __drv_aliasesMem _In_ PDEVICE_OBJECT _In_opt_ PVOID _In_ ULONG _Out_opt_ PVOID OutputBuffer
Definition: iofuncs.h:713
#define _T(x)
Definition: vfdio.h:22
if(!(yy_init))
Definition: macro.lex.yy.c:714
unsigned long DWORD
Definition: ntddk_ex.h:95
_Must_inspect_result_ _Out_ PHANDLE VolumeHandle
Definition: fltkernel.h:2284
#define FSCTL_GET_NTFS_FILE_RECORD
Definition: ntifs_ex.h:262
Definition: nfi.c:152
struct NTFS_ATTR_RECORD * PNTFS_ATTR_RECORD
BOOL WINAPI DeviceIoControl(IN HANDLE hDevice, IN DWORD dwIoControlCode, IN LPVOID lpInBuffer OPTIONAL, IN DWORD nInBufferSize OPTIONAL, OUT LPVOID lpOutBuffer OPTIONAL, IN DWORD nOutBufferSize OPTIONAL, OUT LPDWORD lpBytesReturned OPTIONAL, IN LPOVERLAPPED lpOverlapped OPTIONAL)
Definition: deviceio.c:136
#define NRH_FILE_TYPE
Definition: nfi.c:21
NTFS_RECORD_HEADER Ntfs
Definition: ntfs.h:248

Referenced by _tmain(), and PrintPrettyName().

◆ PrintAttributeInfo()

void PrintAttributeInfo ( PNTFS_ATTR_RECORD  Attribute,
DWORD  MaxSize 
)

Definition at line 408 of file nfi.c.

409 {
410  BOOL Known = TRUE;
411  WCHAR AttributeName[0xFF + 3];
412 
413  /* First of all, try to get attribute name */
414  if (Attribute->NameLength != 0 && Attribute->NameOffset < MaxSize && Attribute->NameOffset + Attribute->NameLength < MaxSize)
415  {
416  AttributeName[0] = L' ';
417  CopyMemory(AttributeName + 1, (PUCHAR)((ULONG_PTR)Attribute + Attribute->NameOffset), Attribute->NameLength * sizeof(WCHAR));
418  AttributeName[Attribute->NameLength + 1] = L' ';
419  AttributeName[Attribute->NameLength + 2] = UNICODE_NULL;
420  }
421  else
422  {
423  AttributeName[0] = L' ';
424  AttributeName[1] = UNICODE_NULL;
425  }
426 
427  /* Display attribute type, its name (if any) and whether it's resident */
428  switch (Attribute->Type)
429  {
430  case AttributeFileName:
431  _tprintf(_T("\t$FILE_NAME%s(%s)\n"), AttributeName, (Attribute->IsNonResident ? _T("nonresident") : _T("resident")));
432  break;
433 
435  _tprintf(_T("\t$STANDARD_INFORMATION%s(%s)\n"), AttributeName, (Attribute->IsNonResident ? _T("nonresident") : _T("resident")));
436  break;
437 
438  case AttributeData:
439  _tprintf(_T("\t$DATA%s(%s)\n"), AttributeName, (Attribute->IsNonResident ? _T("nonresident") : _T("resident")));
440  break;
441 
442  case AttributeBitmap:
443  _tprintf(_T("\t$BITMAP%s(%s)\n"), AttributeName, (Attribute->IsNonResident ? _T("nonresident") : _T("resident")));
444  break;
445 
446  case AttributeIndexRoot:
447  _tprintf(_T("\t$INDEX_ROOT%s(%s)\n"), AttributeName, (Attribute->IsNonResident ? _T("nonresident") : _T("resident")));
448  break;
449 
451  _tprintf(_T("\t$INDEX_ALLOCATION%s(%s)\n"), AttributeName, (Attribute->IsNonResident ? _T("nonresident") : _T("resident")));
452  break;
453 
454  case AttributeObjectId:
455  _tprintf(_T("\t$OBJECT_ID%s(%s)\n"), AttributeName, (Attribute->IsNonResident ? _T("nonresident") : _T("resident")));
456  break;
457 
459  _tprintf(_T("\t$SECURITY_DESCRIPTOR%s(%s)\n"), AttributeName, (Attribute->IsNonResident ? _T("nonresident") : _T("resident")));
460  break;
461 
462  case AttributeVolumeName:
463  _tprintf(_T("\t$VOLUME_NAME%s(%s)\n"), AttributeName, (Attribute->IsNonResident ? _T("nonresident") : _T("resident")));
464  break;
465 
467  _tprintf(_T("\t$VOLUME_INFORMATION%s(%s)\n"), AttributeName, (Attribute->IsNonResident ? _T("nonresident") : _T("resident")));
468  break;
469 
471  _tprintf(_T("\t$ATTRIBUTE_LIST%s(%s)\n"), AttributeName, (Attribute->IsNonResident ? _T("nonresident") : _T("resident")));
472  break;
473 
474  default:
475  _tprintf(_T("\tUnknown (%x)%s(%s)\n"), Attribute->Type, AttributeName, (Attribute->IsNonResident ? _T("nonresident") : _T("resident")));
476  Known = FALSE;
477  break;
478  }
479 
480  /* If attribute is non resident, display the logical sectors it covers */
481  if (Known && Attribute->IsNonResident)
482  {
483  PUCHAR Run;
484  ULONGLONG Offset = 0;
485 
486  /* Get the runs mapping */
487  Run = (PUCHAR)((ULONG_PTR)Attribute + Attribute->NonResident.MappingPairsOffset);
488  /* As long as header isn't 0x00, then, there's a run */
489  while (*Run != 0)
490  {
491  LONGLONG CurrOffset;
492  ULONGLONG CurrLen;
493 
494  /* Decode the run, and move to the next one */
495  Run = DecodeRun(Run, &CurrOffset, &CurrLen);
496 
497  /* We don't print sparse runs */
498  if (CurrOffset != -1)
499  {
500  Offset += CurrOffset;
501  _tprintf(_T("\t\tlogical sectors %I64d-%I64d (0x%I64x-0x%I64x)\n"), Offset, Offset + CurrLen, Offset, Offset + CurrLen);
502  }
503  }
504  }
505 }
Definition: bidi.c:433
#define _tprintf
Definition: tchar.h:506
#define TRUE
Definition: types.h:120
USHORT NameOffset
Definition: ntfs.h:126
unsigned char * PUCHAR
Definition: retypes.h:3
ULONG Type
Definition: ntfs.h:122
uint32_t ULONG_PTR
Definition: typedefs.h:64
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101
#define UNICODE_NULL
unsigned int BOOL
Definition: ntddk_ex.h:94
struct tagRun Run
int64_t LONGLONG
Definition: typedefs.h:67
#define _T(x)
Definition: vfdio.h:22
__wchar_t WCHAR
Definition: xmlstorage.h:180
uint64_t ULONGLONG
Definition: typedefs.h:66
#define CopyMemory
Definition: winbase.h:1646
static const WCHAR L[]
Definition: oid.c:1250
UCHAR IsNonResident
Definition: ntfs.h:124
UCHAR NameLength
Definition: ntfs.h:125
struct NTFS_ATTR_RECORD::@165::@168 NonResident
PUCHAR DecodeRun(PUCHAR DataRun, LONGLONG *DataRunOffset, ULONGLONG *DataRunLength)
Definition: nfi.c:359

Referenced by HandleFile().

◆ PrintPrettyName()

PNAME_CACHE_ENTRY PrintPrettyName ( HANDLE  VolumeHandle,
PNTFS_VOLUME_DATA_BUFFER  VolumeInfo,
PNTFS_ATTR_RECORD  Attributes,
PNTFS_ATTR_RECORD  AttributesEnd,
ULONGLONG  MftId,
BOOLEAN  Silent 
)

Definition at line 213 of file nfi.c.

214 {
215  BOOLEAN FirstRun;
216  PNTFS_ATTR_RECORD Attribute;
217 
218  FirstRun = TRUE;
219 
220  /* Setup name for "standard" files */
221  if (MftId <= NTFS_FILE_EXTEND)
222  {
223  if (!Silent)
224  {
225  _tprintf(_T("%s\n"), KnownEntries[MftId]);
226  }
227 
228  /* $Extend can contain entries, add it in cache */
229  if (MftId == NTFS_FILE_EXTEND)
230  {
231  return AddToCache(L"\\$Extend", sizeof(L"\\$Extend") - sizeof(UNICODE_NULL), NTFS_FILE_EXTEND);
232  }
233 
234  return NULL;
235  }
236 
237  /* We'll first try to use the Win32 name
238  * If we fail finding it, we'll loop again for any other name
239  */
240 TryAgain:
241  /* Loop all the attributes */
242  Attribute = Attributes;
243  while (Attribute < AttributesEnd && Attribute->Type != AttributeEnd)
244  {
247  ULONGLONG ParentId;
248  ULONG Length;
249  PNAME_CACHE_ENTRY CacheEntry;
250 
251  /* Move to the next arg if:
252  * - Not a file name
253  * - Not resident (should never happen!)
254  */
255  if (Attribute->Type != AttributeFileName || Attribute->IsNonResident)
256  {
257  Attribute = (PNTFS_ATTR_RECORD)((ULONG_PTR)Attribute + Attribute->Length);
258  continue;
259  }
260 
261  /* Get the attribute data */
262  Name = (PFILENAME_ATTRIBUTE)((ULONG_PTR)Attribute + Attribute->Resident.ValueOffset);
263  /* If not Win32, only accept if it wasn't the first run */
264  if ((Name->NameType == NTFS_FILE_NAME_POSIX || Name->NameType == NTFS_FILE_NAME_DOS) && FirstRun)
265  {
266  Attribute = (PNTFS_ATTR_RECORD)((ULONG_PTR)Attribute + Attribute->Length);
267  continue;
268  }
269 
270  /* We accepted that name, get the parent ID to setup name */
271  ParentId = Name->DirectoryFileReferenceNumber & NTFS_MFT_MASK;
272  /* If root, easy, just print \ */
273  if (ParentId == NTFS_FILE_ROOT)
274  {
275  Display[0] = L'\\';
276  CopyMemory(&Display[1], Name->Name, Name->NameLength * sizeof(WCHAR));
277  Length = Name->NameLength + 1;
279  }
280  /* Default case */
281  else
282  {
283  /* Did we already cache the name? */
284  CacheEntry = FindInCache(ParentId);
285 
286  /* It wasn't in cache? Try to get it in! */
287  if (CacheEntry == NULL)
288  {
290 
291  OutputBuffer = HeapAlloc(GetProcessHeap(), 0, VolumeInfo->BytesPerFileRecordSegment + sizeof(NTFS_FILE_RECORD_OUTPUT_BUFFER));
292  if (OutputBuffer != NULL)
293  {
294  CacheEntry = HandleFile(VolumeHandle, VolumeInfo, ParentId, OutputBuffer, TRUE);
296  }
297  }
298 
299  /* Nothing written yet */
300  Length = 0;
301 
302  /* We cached it */
303  if (CacheEntry != NULL)
304  {
305  /* Set up name. The cache entry contains full path */
306  Length = CacheEntry->NameLen / sizeof(WCHAR);
307  CopyMemory(Display, CacheEntry->Name, CacheEntry->NameLen);
308  Display[Length] = L'\\';
309  ++Length;
310  }
311  else
312  {
313  _tprintf(_T("Parent: %I64d\n"), ParentId);
314  }
315 
316  /* Copy our name */
317  CopyMemory(Display + Length, Name->Name, Name->NameLength * sizeof(WCHAR));
318  Length += Name->NameLength;
320  }
321 
322  if (!Silent)
323  {
324  /* Display the name */
325  _tprintf(_T("%s\n"), Display);
326  }
327 
328  /* Reset cache entry */
329  CacheEntry = NULL;
330 
331  /* If that's a directory, put it in the cache */
332  if (Name->FileAttributes & NTFS_FILE_TYPE_DIRECTORY)
333  {
334  CacheEntry = AddToCache(Display, Length * sizeof(WCHAR), MftId);
335  }
336 
337  /* Now, just quit */
338  FirstRun = FALSE;
339 
340  return CacheEntry;
341  }
342 
343  /* If was first run (Win32 search), retry with other names */
344  if (FirstRun)
345  {
346  FirstRun = FALSE;
347  goto TryAgain;
348  }
349 
350  /* If we couldn't find a name, print unknown */
351  if (!Silent)
352  {
353  _tprintf(_T("(unknown/unnamed)\n"));
354  }
355 
356  return NULL;
357 }
#define _tprintf
Definition: tchar.h:506
#define TRUE
Definition: types.h:120
#define NTFS_MFT_MASK
Definition: nfi.c:148
ULONG NameLen
Definition: nfi.c:156
Type
Definition: Type.h:6
WCHAR Name[1]
Definition: nfi.c:157
ULONG Type
Definition: ntfs.h:122
uint32_t ULONG_PTR
Definition: typedefs.h:64
#define UNICODE_NULL
ULONG Length
Definition: ntfs.h:123
#define NTFS_FILE_ROOT
Definition: nfi.c:124
struct NameRec_ * Name
Definition: cdprocs.h:459
Definition: bl.h:897
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
_Must_inspect_result_ __drv_aliasesMem _In_ PDEVICE_OBJECT _In_opt_ PVOID _In_ ULONG _Out_opt_ PVOID OutputBuffer
Definition: iofuncs.h:713
struct FILENAME_ATTRIBUTE * PFILENAME_ATTRIBUTE
#define _T(x)
Definition: vfdio.h:22
#define GetProcessHeap()
Definition: compat.h:404
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
__wchar_t WCHAR
Definition: xmlstorage.h:180
uint64_t ULONGLONG
Definition: typedefs.h:66
#define MAX_PATH
Definition: compat.h:26
#define CopyMemory
Definition: winbase.h:1646
_Must_inspect_result_ _Out_ PHANDLE VolumeHandle
Definition: fltkernel.h:2284
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
static const WCHAR L[]
Definition: oid.c:1250
PWSTR KnownEntries[NTFS_FILE_EXTEND+1]
Definition: nfi.c:132
UCHAR IsNonResident
Definition: ntfs.h:124
Definition: nfi.c:152
_Must_inspect_result_ _In_ USHORT _In_ PHIDP_PREPARSED_DATA _Out_writes_to_ LengthAttributes PHIDP_EXTENDED_ATTRIBUTES Attributes
Definition: hidpi.h:348
struct NTFS_ATTR_RECORD * PNTFS_ATTR_RECORD
PNAME_CACHE_ENTRY AddToCache(PWSTR Name, DWORD Length, ULONGLONG MftId)
Definition: nfi.c:182
#define NTFS_FILE_NAME_DOS
Definition: nfi.c:116
PNAME_CACHE_ENTRY HandleFile(HANDLE VolumeHandle, PNTFS_VOLUME_DATA_BUFFER VolumeInfo, ULONGLONG Id, PNTFS_FILE_RECORD_OUTPUT_BUFFER OutputBuffer, BOOLEAN Silent)
Definition: nfi.c:507
#define NTFS_FILE_NAME_POSIX
Definition: nfi.c:114
int Display
Definition: x11stubs.h:25
unsigned int ULONG
Definition: retypes.h:1
#define NTFS_FILE_EXTEND
Definition: nfi.c:130
PNAME_CACHE_ENTRY FindInCache(ULONGLONG MftId)
Definition: nfi.c:167
struct NTFS_ATTR_RECORD::@165::@167 Resident
#define HeapFree(x, y, z)
Definition: compat.h:403
#define NTFS_FILE_TYPE_DIRECTORY
Definition: nfi.c:150

Referenced by HandleFile().

◆ PrintUsage()

void PrintUsage ( void  )

Definition at line 162 of file nfi.c.

163 {
164  /* FIXME */
165 }

Referenced by _tmain().

Variable Documentation

◆ CacheHead

PNAME_CACHE_ENTRY CacheHead = NULL

Definition at line 160 of file nfi.c.

Referenced by _tmain(), AddToCache(), and FindInCache().

◆ KnownEntries

PWSTR KnownEntries[NTFS_FILE_EXTEND+1]
Initial value:
=
{
_T("Master File Table ($Mft)"),
_T("Master File Table Mirror ($MftMirr)"),
_T("Log File ($LogFile)"),
_T("DASD ($Volume)"),
_T("Attribute Definition Table ($AttrDef)"),
_T("Root Directory"),
_T("Volume Bitmap ($BitMap)"),
_T("Boot Sectors ($Boot)"),
_T("Bad Cluster List ($BadClus)"),
_T("Security ($Secure)"),
_T("Upcase Table ($UpCase)"),
}
#define _T(x)
Definition: vfdio.h:22

Definition at line 132 of file nfi.c.

Referenced by PrintPrettyName().