33#define TAG_NTFS_CONTEXT 'CftN'
34#define TAG_NTFS_LIST 'LftN'
35#define TAG_NTFS_MFT 'MftN'
36#define TAG_NTFS_INDEX_REC 'IftN'
37#define TAG_NTFS_BITMAP 'BftN'
38#define TAG_NTFS_FILE 'FftN'
39#define TAG_NTFS_VOLUME 'VftN'
40#define TAG_NTFS_DATA 'DftN'
62 return AttrRecord->
Resident.ValueLength;
67 UCHAR DataRunOffsetSize;
68 UCHAR DataRunLengthSize;
71 DataRunOffsetSize = (*DataRun >> 4) & 0xF;
72 DataRunLengthSize = *DataRun & 0xF;
76 for (
i = 0;
i < DataRunLengthSize;
i++)
78 *DataRunLength += ((
ULONG64)*DataRun) << (
i * 8);
83 if (DataRunOffsetSize == 0)
89 for (
i = 0;
i < DataRunOffsetSize - 1;
i++)
91 *DataRunOffset += ((
ULONG64)*DataRun) << (
i * 8);
95 *DataRunOffset = ((
LONG64)(
CHAR)(*(DataRun++)) << (
i * 8)) + *DataRunOffset;
98 TRACE(
"DataRunOffsetSize: %x\n", DataRunOffsetSize);
99 TRACE(
"DataRunLengthSize: %x\n", DataRunLengthSize);
100 TRACE(
"DataRunOffset: %x\n", *DataRunOffset);
101 TRACE(
"DataRunLength: %x\n", *DataRunLength);
121 Context->CacheRunLength = DataRunLength;
122 if (DataRunOffset != -1)
126 Context->CacheRunLastLCN = DataRunOffset;
131 Context->CacheRunStartLCN = -1;
134 Context->CacheRunCurrentOffset = 0;
233 if (!
Context->Record.IsNonResident)
258 LastLCN =
Context->CacheRunLastLCN;
259 DataRunStartLCN =
Context->CacheRunStartLCN;
260 DataRunLength =
Context->CacheRunLength;
261 CurrentOffset =
Context->CacheRunCurrentOffset;
271 DataRun =
NtfsDecodeRun(DataRun, &DataRunOffset, &DataRunLength);
272 if (DataRunOffset != -1)
275 DataRunStartLCN = LastLCN + DataRunOffset;
276 LastLCN = DataRunStartLCN;
281 DataRunStartLCN = -1;
284 if (
Offset >= CurrentOffset &&
285 Offset < CurrentOffset + (DataRunLength *
Volume->ClusterSize))
295 CurrentOffset += DataRunLength *
Volume->ClusterSize;
304 if (DataRunStartLCN == -1)
314 CurrentOffset += DataRunLength *
Volume->ClusterSize;
315 DataRun =
NtfsDecodeRun(DataRun, &DataRunOffset, &DataRunLength);
318 DataRunStartLCN = LastLCN + DataRunOffset;
319 LastLCN = DataRunStartLCN;
322 DataRunStartLCN = -1;
328 if (DataRunStartLCN == -1)
347 CurrentOffset += DataRunLength *
Volume->ClusterSize;
348 DataRun =
NtfsDecodeRun(DataRun, &DataRunOffset, &DataRunLength);
349 if (DataRunOffset != -1)
352 DataRunStartLCN = LastLCN + DataRunOffset;
353 LastLCN = DataRunStartLCN;
358 DataRunStartLCN = -1;
366 Context->CacheRunStartLCN = DataRunStartLCN;
367 Context->CacheRunLength = DataRunLength;
368 Context->CacheRunLastLCN = LastLCN;
369 Context->CacheRunCurrentOffset = CurrentOffset;
376 while (AttrRecord < AttrRecordEnd)
393 if(ListSize <= 0xFFFFFFFF)
400 TRACE(
"Failed to allocate memory: %x\n", (
ULONG)ListSize);
435 if (AttrRecord->
Length == 0)
451 for (NameLength = 0;
Name[NameLength] != 0; NameLength++)
465 USANumber = *(USA++);
466 USACount =
Record->USACount - 1;
471 if (*Block != USANumber)
498 CHAR AnsiFileName[256];
519 UCHAR EntryFileNameLength;
522 EntryFileName = IndexEntry->FileName.FileName;
523 EntryFileNameLength = IndexEntry->FileName.FileNameLength;
526 NtfsPrintFile(IndexEntry);
538 for (
i = 0;
i < EntryFileNameLength;
i++)
567 ULONG IndexBlockSize;
573 if (MftRecord ==
NULL)
583 if (IndexRootCtx ==
NULL)
590 if (IndexRecord ==
NULL)
605 while (IndexEntry < IndexEntryEnd &&
621 TRACE(
"Large Index!\n");
626 if (IndexBitmapCtx ==
NULL)
628 TRACE(
"Corrupted filesystem!\n");
633 TRACE(
"BitmapDataSize: %x\n", (
ULONG)BitmapDataSize);
634 if(BitmapDataSize <= 0xFFFFFFFF)
649 if (IndexAllocationCtx ==
NULL)
651 TRACE(
"Corrupted filesystem!\n");
663 TRACE(
"RecordOffset: %x IndexAllocationSize: %x\n", RecordOffset, IndexAllocationSize);
664 for (; RecordOffset < IndexAllocationSize;)
666 UCHAR Bit = 1 << ((RecordOffset / IndexBlockSize) & 7);
667 ULONG Byte = (RecordOffset / IndexBlockSize) >> 3;
670 RecordOffset += IndexBlockSize;
673 if (RecordOffset >= IndexAllocationSize)
689 while (IndexEntry < IndexEntryEnd &&
694 TRACE(
"File found\n");
706 RecordOffset += IndexBlockSize;
717 TRACE(
"Can't read MFT record\n");
726 ULONG NumberOfPathParts;
743 for (
i = 0;
i < NumberOfPathParts;
i++)
751 TRACE(
"- Lookup: %s\n", PathPart);
757 TRACE(
"- Lookup: %x\n", CurrentMFTIndex);
762 TRACE(
"NtfsLookupFile: Can't read MFT record\n");
769 TRACE(
"NtfsLookupFile: Can't find data attribute\n");
820 TRACE(
"NtfsGetFileInformation(%lu) -> FileSize = %llu, FilePointer = 0x%llx\n",
845 TRACE(
"NtfsOpen() FileName = %s\n",
Path);
924 return Volume->BootSector.VolumeSectorCount *
Volume->BootSector.BytesPerSector;
945 TRACE(
"Enter NtfsMount(%lu)\n", DeviceId);
984 Volume->ClusterSize =
Volume->BootSector.SectorsPerCluster *
Volume->BootSector.BytesPerSector;
985 if (
Volume->BootSector.ClustersPerMftRecord > 0)
986 Volume->MftRecordSize =
Volume->BootSector.ClustersPerMftRecord *
Volume->ClusterSize;
988 Volume->MftRecordSize = 1 << (-
Volume->BootSector.ClustersPerMftRecord);
989 if (
Volume->BootSector.ClustersPerIndexRecord > 0)
990 Volume->IndexRecordSize =
Volume->BootSector.ClustersPerIndexRecord *
Volume->ClusterSize;
992 Volume->IndexRecordSize = 1 << (-
Volume->BootSector.ClustersPerIndexRecord);
995 TRACE(
"ClustersPerMftRecord: %d\n",
Volume->BootSector.ClustersPerMftRecord);
996 TRACE(
"ClustersPerIndexRecord: %d\n",
Volume->BootSector.ClustersPerIndexRecord);
997 TRACE(
"MftRecordSize: 0x%x\n",
Volume->MftRecordSize);
998 TRACE(
"IndexRecordSize: 0x%x\n",
Volume->IndexRecordSize);
1003 TRACE(
"Reading MFT index...\n");
1005 if (!
Volume->MasterFileTable)
1032 if (!
Volume->TemporarySector)
1043 Volume->DeviceId = DeviceId;
1048 TRACE(
"Searching for DATA attribute...\n");
1066 TRACE(
"NtfsMount(%lu) success\n", DeviceId);
PRTL_UNICODE_STRING_BUFFER Path
ACPI_SIZE strlen(const char *String)
#define DBG_DEFAULT_CHANNEL(ch)
struct NTFS_ATTR_RECORD * PNTFS_ATTR_RECORD
#define NTFS_FILE_ATTR_ARCHIVE
struct NTFS_INDEX_ENTRY * PNTFS_INDEX_ENTRY
#define NTFS_ATTR_TYPE_INDEX_ROOT
#define NTFS_FILE_ATTR_SYSTEM
#define NTFS_FILE_ATTR_DIRECTORY
#define NTFS_ATTR_TYPE_BITMAP
#define NTFS_ATTR_TYPE_DATA
#define NTFS_INDEX_ENTRY_END
#define NTFS_ATTR_TYPE_ATTRIBUTE_LIST
#define NTFS_ATTR_TYPE_END
#define NTFS_ATTR_TYPE_INDEX_ALLOCATION
#define NTFS_FILE_ATTR_READONLY
struct NTFS_MFT_RECORD * PNTFS_MFT_RECORD
#define NTFS_FILE_ATTR_HIDDEN
struct NTFS_INDEX_ROOT * PNTFS_INDEX_ROOT
ARC_STATUS ArcSeek(ULONG FileId, LARGE_INTEGER *Position, SEEKMODE SeekMode)
PVOID FsGetDeviceSpecific(ULONG FileId)
ULONG FsGetNumPathParts(PCSTR Path)
VOID FsSetDeviceSpecific(ULONG FileId, PVOID Specific)
VOID FileSystemError(PCSTR ErrorString)
ULONG FsGetDeviceId(ULONG FileId)
ARC_STATUS ArcRead(ULONG FileId, VOID *Buffer, ULONG N, ULONG *Count)
VOID FsGetFirstNameFromPath(PCHAR Buffer, PCSTR Path)
VOID FrLdrTempFree(PVOID Allocation, ULONG Tag)
PVOID FrLdrTempAlloc(_In_ SIZE_T Size, _In_ ULONG Tag)
static BOOLEAN NtfsDiskRead(PNTFS_VOLUME_INFO Volume, ULONGLONG Offset, ULONGLONG Length, PCHAR Buffer)
ARC_STATUS NtfsSeek(ULONG FileId, LARGE_INTEGER *Position, SEEKMODE SeekMode)
static BOOLEAN NtfsFixupRecord(PNTFS_VOLUME_INFO Volume, PNTFS_RECORD Record)
ULONGLONG NtfsGetVolumeSize(_In_ ULONG DeviceId)
Returns the size of the NTFS volume laid on the storage media device opened via DeviceId.
PNTFS_VOLUME_INFO NtfsVolumes[MAX_FDS]
ARC_STATUS NtfsOpen(CHAR *Path, OPENMODE OpenMode, ULONG *FileId)
static PNTFS_ATTR_CONTEXT NtfsFindAttributeHelper(PNTFS_VOLUME_INFO Volume, PNTFS_ATTR_RECORD AttrRecord, PNTFS_ATTR_RECORD AttrRecordEnd, ULONG Type, const WCHAR *Name, ULONG NameLength)
ARC_STATUS NtfsGetFileInformation(ULONG FileId, FILEINFORMATION *Information)
static BOOLEAN NtfsLookupFile(PNTFS_VOLUME_INFO Volume, PCSTR FileName, PNTFS_MFT_RECORD MftRecord, PNTFS_FILE_HANDLE FileHandle)
static VOID NtfsReleaseAttributeContext(PNTFS_ATTR_CONTEXT Context)
static ULONG NtfsReadAttribute(PNTFS_VOLUME_INFO Volume, PNTFS_ATTR_CONTEXT Context, ULONGLONG Offset, PCHAR Buffer, ULONG Length)
static PNTFS_ATTR_CONTEXT NtfsPrepareAttributeContext(PNTFS_ATTR_RECORD AttrRecord)
const DEVVTBL NtfsFuncTable
static BOOLEAN NtfsCompareFileName(_In_ PCCH FileName, _In_ SIZE_T FileNameLen, _In_ PNTFS_INDEX_ENTRY IndexEntry)
#define TAG_NTFS_INDEX_REC
struct _NTFS_VOLUME_INFO NTFS_VOLUME_INFO
ARC_STATUS NtfsClose(ULONG FileId)
static PNTFS_ATTR_CONTEXT NtfsFindAttribute(PNTFS_VOLUME_INFO Volume, PNTFS_MFT_RECORD MftRecord, ULONG Type, const WCHAR *Name)
static BOOLEAN NtfsFindMftRecord(_In_ PNTFS_VOLUME_INFO Volume, _In_ ULONGLONG MFTIndex, _In_ PCSTR FileName, _Out_ PULONGLONG OutMFTIndex, _Out_ PULONG FileAttributes)
static ULONGLONG NtfsGetAttributeSize(PNTFS_ATTR_RECORD AttrRecord)
static PUCHAR NtfsDecodeRun(PUCHAR DataRun, LONGLONG *DataRunOffset, ULONGLONG *DataRunLength)
static BOOLEAN NtfsReadMftRecord(PNTFS_VOLUME_INFO Volume, ULONGLONG MFTIndex, PNTFS_MFT_RECORD Buffer)
const DEVVTBL * NtfsMount(ULONG DeviceId)
ARC_STATUS NtfsRead(ULONG FileId, VOID *Buffer, ULONG N, ULONG *Count)
while(CdLookupNextInitialFileDirent(IrpContext, Fcb, FileContext))
struct _FileName FileName
_Must_inspect_result_ _In_opt_ PFLT_INSTANCE _Out_ PHANDLE _In_ ACCESS_MASK _In_ POBJECT_ATTRIBUTES _Out_ PIO_STATUS_BLOCK _In_opt_ PLARGE_INTEGER _In_ ULONG FileAttributes
_Must_inspect_result_ _In_opt_ PFLT_INSTANCE _Out_ PHANDLE FileHandle
_Must_inspect_result_ _In_ PFILE_OBJECT _In_opt_ HANDLE _In_ ULONG FileNameLength
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
#define RtlEqualMemory(dst, src, len)
__GNU_EXTENSION typedef unsigned __int64 * PULONGLONG
_In_ ULONG _In_ ULONG Offset
_In_ ULONG _In_ ULONG _In_ ULONG Length
struct NTFS_ATTR_RECORD::@206::@208 Resident
struct NTFS_ATTR_RECORD::@206::@209 NonResident
struct NTFS_INDEX_ENTRY::@210::@211 Directory
union NTFS_INDEX_ENTRY::@210 Data
NTFS_FILE_NAME_ATTR FileName
NTFS_INDEX_HEADER IndexHeader
NTFS_BOOTSECTOR BootSector
PNTFS_MFT_RECORD MasterFileTable
PNTFS_ATTR_CONTEXT MFTContext
#define FIELD_OFFSET(t, f)
#define RtlCopyMemory(Destination, Source, Length)
#define RtlZeroMemory(Destination, Length)
_Must_inspect_result_ _In_ WDFIOTARGET _In_opt_ WDFREQUEST _In_opt_ PWDF_MEMORY_DESCRIPTOR _In_opt_ PLONGLONG _In_opt_ PWDF_REQUEST_SEND_OPTIONS _Out_opt_ PULONG_PTR BytesRead
_In_ WDFREQUEST _In_ NTSTATUS _In_ ULONG_PTR Information
_In_ struct _KBUGCHECK_REASON_CALLBACK_RECORD * Record