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);
531 for (
i = 0;
i < EntryFileNameLength;
i++)
537 for (
i = 0;
i < EntryFileNameLength;
i++)
559 ULONG IndexBlockSize;
562 if (MftRecord ==
NULL)
572 if (IndexRootCtx ==
NULL)
579 if (IndexRecord ==
NULL)
594 while (IndexEntry < IndexEntryEnd &&
609 TRACE(
"Large Index!\n");
614 if (IndexBitmapCtx ==
NULL)
616 TRACE(
"Corrupted filesystem!\n");
621 TRACE(
"BitmapDataSize: %x\n", (
ULONG)BitmapDataSize);
622 if(BitmapDataSize <= 0xFFFFFFFF)
637 if (IndexAllocationCtx ==
NULL)
639 TRACE(
"Corrupted filesystem!\n");
651 TRACE(
"RecordOffset: %x IndexAllocationSize: %x\n", RecordOffset, IndexAllocationSize);
652 for (; RecordOffset < IndexAllocationSize;)
654 UCHAR Bit = 1 << ((RecordOffset / IndexBlockSize) & 7);
655 ULONG Byte = (RecordOffset / IndexBlockSize) >> 3;
658 RecordOffset += IndexBlockSize;
661 if (RecordOffset >= IndexAllocationSize)
677 while (IndexEntry < IndexEntryEnd &&
682 TRACE(
"File found\n");
693 RecordOffset += IndexBlockSize;
704 TRACE(
"Can't read MFT record\n");
713 ULONG NumberOfPathParts;
727 for (
i = 0;
i < NumberOfPathParts;
i++)
735 TRACE(
"- Lookup: %s\n", PathPart);
741 TRACE(
"- Lookup: %x\n", CurrentMFTIndex);
746 TRACE(
"NtfsLookupFile: Can't read MFT record\n");
751 if (*DataContext ==
NULL)
753 TRACE(
"NtfsLookupFile: Can't find data attribute\n");
778 TRACE(
"NtfsGetFileInformation(%lu) -> FileSize = %llu, FilePointer = 0x%llx\n",
803 TRACE(
"NtfsOpen() FileName = %s\n",
Path);
893 TRACE(
"Enter NtfsMount(%lu)\n", DeviceId);
932 Volume->ClusterSize =
Volume->BootSector.SectorsPerCluster *
Volume->BootSector.BytesPerSector;
933 if (
Volume->BootSector.ClustersPerMftRecord > 0)
934 Volume->MftRecordSize =
Volume->BootSector.ClustersPerMftRecord *
Volume->ClusterSize;
936 Volume->MftRecordSize = 1 << (-
Volume->BootSector.ClustersPerMftRecord);
937 if (
Volume->BootSector.ClustersPerIndexRecord > 0)
938 Volume->IndexRecordSize =
Volume->BootSector.ClustersPerIndexRecord *
Volume->ClusterSize;
940 Volume->IndexRecordSize = 1 << (-
Volume->BootSector.ClustersPerIndexRecord);
943 TRACE(
"ClustersPerMftRecord: %d\n",
Volume->BootSector.ClustersPerMftRecord);
944 TRACE(
"ClustersPerIndexRecord: %d\n",
Volume->BootSector.ClustersPerIndexRecord);
945 TRACE(
"MftRecordSize: 0x%x\n",
Volume->MftRecordSize);
946 TRACE(
"IndexRecordSize: 0x%x\n",
Volume->IndexRecordSize);
951 TRACE(
"Reading MFT index...\n");
953 if (!
Volume->MasterFileTable)
980 if (!
Volume->TemporarySector)
991 Volume->DeviceId = DeviceId;
996 TRACE(
"Searching for DATA attribute...\n");
1014 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
#define NTFS_FILE_NAME_POSIX
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)
FORCEINLINE PVOID FrLdrTempAlloc(_In_ SIZE_T Size, _In_ ULONG Tag)
FORCEINLINE VOID FrLdrTempFree(PVOID Allocation, 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::@169::@171 Resident
struct NTFS_ATTR_RECORD::@169::@172 NonResident
NTFS_FILE_NAME_ATTR FileName
struct NTFS_INDEX_ENTRY::@173::@174 Directory
union NTFS_INDEX_ENTRY::@173 Data
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