ReactOS 0.4.15-dev-5664-g3bf4ef6
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.

24{
27 AttributeFileName = 0x30,
28 AttributeObjectId = 0x40,
32 AttributeData = 0x80,
33 AttributeIndexRoot = 0x90,
35 AttributeBitmap = 0xB0,
38 AttributeEA = 0xE0,
41 AttributeEnd = 0xFFFFFFFF
enum ATTRIBUTE_TYPE * PATTRIBUTE_TYPE
ATTRIBUTE_TYPE
Definition: nfi.c:24
@ AttributeVolumeName
Definition: nfi.c:30
@ AttributeEnd
Definition: nfi.c:41
@ AttributeIndexRoot
Definition: nfi.c:33
@ AttributePropertySet
Definition: nfi.c:39
@ AttributeReparsePoint
Definition: nfi.c:36
@ AttributeFileName
Definition: nfi.c:27
@ AttributeEAInformation
Definition: nfi.c:37
@ AttributeStandardInformation
Definition: nfi.c:25
@ AttributeEA
Definition: nfi.c:38
@ AttributeAttributeList
Definition: nfi.c:26
@ AttributeVolumeInformation
Definition: nfi.c:31
@ AttributeSecurityDescriptor
Definition: nfi.c:29
@ AttributeIndexAllocation
Definition: nfi.c:34
@ AttributeObjectId
Definition: nfi.c:28
@ AttributeLoggedUtilityStream
Definition: nfi.c:40
@ AttributeData
Definition: nfi.c:32
@ AttributeBitmap
Definition: nfi.c:35

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:");
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}
WCHAR Letter
static int argc
Definition: ServiceArgs.c:12
Definition: File.h:16
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 NULL
Definition: types.h:112
#define FALSE
Definition: types.h:117
#define CloseHandle
Definition: compat.h:739
#define GetProcessHeap()
Definition: compat.h:736
#define OPEN_EXISTING
Definition: compat.h:775
#define INVALID_HANDLE_VALUE
Definition: compat.h:731
#define HeapAlloc
Definition: compat.h:733
#define GENERIC_READ
Definition: compat.h:135
#define HeapFree(x, y, z)
Definition: compat.h:735
#define FILE_SHARE_READ
Definition: compat.h:136
unsigned long DWORD
Definition: ntddk_ex.h:95
_Must_inspect_result_ _Inout_opt_ PUNICODE_STRING VolumeName
Definition: fltkernel.h:1117
_Must_inspect_result_ _In_ PFILE_OBJECT _In_ ULONG _In_ FILE_INFORMATION_CLASS _Out_opt_ PULONG LengthReturned
Definition: fltkernel.h:1308
_Must_inspect_result_ _Out_ PHANDLE VolumeHandle
Definition: fltkernel.h:2283
#define stderr
Definition: stdio.h:100
#define _ftprintf
Definition: tchar.h:518
#define argv
Definition: mplay32.c:18
PNAME_CACHE_ENTRY CacheHead
Definition: nfi.c:160
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
void PrintUsage(void)
Definition: nfi.c:162
#define FILE_SHARE_WRITE
Definition: nt_native.h:681
#define FSCTL_GET_NTFS_VOLUME_DATA
Definition: ntifs_ex.h:261
Definition: nfi.c:153
struct _NAME_CACHE_ENTRY * Next
Definition: nfi.c:154
uint64_t ULONGLONG
Definition: typedefs.h:67
#define _T(x)
Definition: vfdio.h:22
_Must_inspect_result_ _In_ WDFIOTARGET _In_opt_ WDFREQUEST _In_opt_ PWDF_MEMORY_DESCRIPTOR OutputBuffer
Definition: wdfiotarget.h:863
DWORD WINAPI GetLastError(void)
Definition: except.c:1040
#define CreateFile
Definition: winbase.h:3620
char TCHAR
Definition: xmlstorage.h:189

◆ 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}
PNAME_CACHE_ENTRY FindInCache(ULONGLONG MftId)
Definition: nfi.c:167
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102
ULONGLONG MftId
Definition: nfi.c:155
WCHAR Name[1]
Definition: nfi.c:157
ULONG NameLen
Definition: nfi.c:156
#define CopyMemory
Definition: winbase.h:1668

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}
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
unsigned __int64 ULONG64
Definition: imports.h:198
int64_t LONG64
Definition: typedefs.h:68
unsigned char UCHAR
Definition: xmlstorage.h:181
char CHAR
Definition: xmlstorage.h:175

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}

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),
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}
DWORD Id
Type
Definition: Type.h:7
#define _tprintf
Definition: tchar.h:506
if(dx< 0)
Definition: linetemp.h:194
struct NTFS_ATTR_RECORD * PNTFS_ATTR_RECORD
#define NRH_FILE_TYPE
Definition: nfi.c:21
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
struct _FILE_RECORD_HEADER * PFILE_RECORD_HEADER
void PrintAttributeInfo(PNTFS_ATTR_RECORD Attribute, DWORD MaxSize)
Definition: nfi.c:408
#define FSCTL_GET_NTFS_FILE_RECORD
Definition: ntifs_ex.h:262
ULONG Length
Definition: ntfs.h:127
NTFS_RECORD_HEADER Ntfs
Definition: ntfs.h:252
USHORT AttributeOffset
Definition: ntfs.h:255
ULONG BytesInUse
Definition: ntfs.h:257
uint32_t ULONG_PTR
Definition: typedefs.h:65
_Must_inspect_result_ _In_ WDFIOTARGET _In_opt_ WDFREQUEST _In_opt_ PWDF_MEMORY_DESCRIPTOR InputBuffer
Definition: wdfiotarget.h:953

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 {
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
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
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
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}
#define TRUE
Definition: types.h:120
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned char * PUCHAR
Definition: retypes.h:3
PUCHAR DecodeRun(PUCHAR DataRun, LONGLONG *DataRunOffset, ULONGLONG *DataRunLength)
Definition: nfi.c:359
#define UNICODE_NULL
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101
#define L(x)
Definition: ntvdm.h:50
USHORT NameOffset
Definition: ntfs.h:130
struct NTFS_ATTR_RECORD::@165::@168 NonResident
UCHAR NameLength
Definition: ntfs.h:129
UCHAR IsNonResident
Definition: ntfs.h:128
ULONG Type
Definition: ntfs.h:126
Definition: bidi.c:434
int64_t LONGLONG
Definition: typedefs.h:68
struct tagRun Run
__wchar_t WCHAR
Definition: xmlstorage.h:180

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 */
241 /* Loop all the attributes */
242 Attribute = Attributes;
243 while (Attribute < AttributesEnd && Attribute->Type != AttributeEnd)
244 {
247 ULONGLONG ParentId;
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}
unsigned char BOOLEAN
struct NameRec_ * Name
Definition: cdprocs.h:460
@ TryAgain
Definition: bl.h:896
#define MAX_PATH
Definition: compat.h:34
unsigned int ULONG
Definition: retypes.h:1
#define NTFS_FILE_NAME_DOS
Definition: nfi.c:116
struct FILENAME_ATTRIBUTE * PFILENAME_ATTRIBUTE
#define NTFS_MFT_MASK
Definition: nfi.c:148
#define NTFS_FILE_TYPE_DIRECTORY
Definition: nfi.c:150
#define NTFS_FILE_ROOT
Definition: nfi.c:124
PWSTR KnownEntries[NTFS_FILE_EXTEND+1]
Definition: nfi.c:132
PNAME_CACHE_ENTRY AddToCache(PWSTR Name, DWORD Length, ULONGLONG MftId)
Definition: nfi.c:182
#define NTFS_FILE_NAME_POSIX
Definition: nfi.c:114
#define NTFS_FILE_EXTEND
Definition: nfi.c:130
struct NTFS_ATTR_RECORD::@165::@167 Resident
_Must_inspect_result_ _In_ WDFDMAENABLER _In_ _In_opt_ PWDF_OBJECT_ATTRIBUTES Attributes
int Display
Definition: x11stubs.h:25

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)"),
}

Definition at line 132 of file nfi.c.

Referenced by PrintPrettyName().