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];
515 UCHAR EntryFileNameLength;
522 NtfsPrintFile(IndexEntry);
534 for (
i = 0;
i < EntryFileNameLength;
i++)
557 ULONG IndexBlockSize;
560 if (MftRecord ==
NULL)
570 if (IndexRootCtx ==
NULL)
577 if (IndexRecord ==
NULL)
592 while (IndexEntry < IndexEntryEnd &&
607 TRACE(
"Large Index!\n");
612 if (IndexBitmapCtx ==
NULL)
614 TRACE(
"Corrupted filesystem!\n");
619 TRACE(
"BitmapDataSize: %x\n", (
ULONG)BitmapDataSize);
620 if(BitmapDataSize <= 0xFFFFFFFF)
635 if (IndexAllocationCtx ==
NULL)
637 TRACE(
"Corrupted filesystem!\n");
649 TRACE(
"RecordOffset: %x IndexAllocationSize: %x\n", RecordOffset, IndexAllocationSize);
650 for (; RecordOffset < IndexAllocationSize;)
652 UCHAR Bit = 1 << ((RecordOffset / IndexBlockSize) & 7);
653 ULONG Byte = (RecordOffset / IndexBlockSize) >> 3;
656 RecordOffset += IndexBlockSize;
659 if (RecordOffset >= IndexAllocationSize)
675 while (IndexEntry < IndexEntryEnd &&
680 TRACE(
"File found\n");
691 RecordOffset += IndexBlockSize;
702 TRACE(
"Can't read MFT record\n");
711 ULONG NumberOfPathParts;
725 for (
i = 0;
i < NumberOfPathParts;
i++)
733 TRACE(
"- Lookup: %s\n", PathPart);
739 TRACE(
"- Lookup: %x\n", CurrentMFTIndex);
744 TRACE(
"NtfsLookupFile: Can't read MFT record\n");
749 if (*DataContext ==
NULL)
751 TRACE(
"NtfsLookupFile: Can't find data attribute\n");
776 TRACE(
"NtfsGetFileInformation(%lu) -> FileSize = %llu, FilePointer = 0x%llx\n",
801 TRACE(
"NtfsOpen() FileName = %s\n",
Path);
891 TRACE(
"Enter NtfsMount(%lu)\n", DeviceId);
930 Volume->ClusterSize =
Volume->BootSector.SectorsPerCluster *
Volume->BootSector.BytesPerSector;
931 if (
Volume->BootSector.ClustersPerMftRecord > 0)
932 Volume->MftRecordSize =
Volume->BootSector.ClustersPerMftRecord *
Volume->ClusterSize;
934 Volume->MftRecordSize = 1 << (-
Volume->BootSector.ClustersPerMftRecord);
935 if (
Volume->BootSector.ClustersPerIndexRecord > 0)
936 Volume->IndexRecordSize =
Volume->BootSector.ClustersPerIndexRecord *
Volume->ClusterSize;
938 Volume->IndexRecordSize = 1 << (-
Volume->BootSector.ClustersPerIndexRecord);
941 TRACE(
"ClustersPerMftRecord: %d\n",
Volume->BootSector.ClustersPerMftRecord);
942 TRACE(
"ClustersPerIndexRecord: %d\n",
Volume->BootSector.ClustersPerIndexRecord);
943 TRACE(
"MftRecordSize: 0x%x\n",
Volume->MftRecordSize);
944 TRACE(
"IndexRecordSize: 0x%x\n",
Volume->IndexRecordSize);
949 TRACE(
"Reading MFT index...\n");
951 if (!
Volume->MasterFileTable)
978 if (!
Volume->TemporarySector)
989 Volume->DeviceId = DeviceId;
994 TRACE(
"Searching for DATA attribute...\n");
1012 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
struct NTFS_INDEX_ENTRY * PNTFS_INDEX_ENTRY
#define NTFS_ATTR_TYPE_INDEX_ROOT
#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
struct NTFS_MFT_RECORD * PNTFS_MFT_RECORD
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)
static BOOLEAN NtfsCompareFileName(PCHAR FileName, PNTFS_INDEX_ENTRY IndexEntry)
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)
static BOOLEAN NtfsFindMftRecord(PNTFS_VOLUME_INFO Volume, ULONGLONG MFTIndex, PCHAR FileName, ULONGLONG *OutMFTIndex)
ARC_STATUS NtfsGetFileInformation(ULONG FileId, FILEINFORMATION *Information)
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
#define TAG_NTFS_INDEX_REC
struct _NTFS_VOLUME_INFO NTFS_VOLUME_INFO
static BOOLEAN NtfsLookupFile(PNTFS_VOLUME_INFO Volume, PCSTR FileName, PNTFS_MFT_RECORD MftRecord, PNTFS_ATTR_CONTEXT *DataContext)
ARC_STATUS NtfsClose(ULONG FileId)
static PNTFS_ATTR_CONTEXT NtfsFindAttribute(PNTFS_VOLUME_INFO Volume, PNTFS_MFT_RECORD MftRecord, ULONG Type, const WCHAR *Name)
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 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)
_In_ ULONG _In_ ULONG Offset
_In_ ULONG _In_ ULONG _In_ ULONG Length
struct NTFS_ATTR_RECORD::@213::@215 Resident
struct NTFS_ATTR_RECORD::@213::@216 NonResident
union NTFS_INDEX_ENTRY::@217 Data
struct NTFS_INDEX_ENTRY::@217::@218 Directory
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