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;
722 for (
i = 0;
i < NumberOfPathParts;
i++)
730 TRACE(
"- Lookup: %s\n", PathPart);
736 TRACE(
"- Lookup: %x\n", CurrentMFTIndex);
741 TRACE(
"NtfsLookupFile: Can't read MFT record\n");
746 if (*DataContext ==
NULL)
748 TRACE(
"NtfsLookupFile: Can't find data attribute\n");
773 TRACE(
"NtfsGetFileInformation(%lu) -> FileSize = %llu, FilePointer = 0x%llx\n",
798 TRACE(
"NtfsOpen() FileName = %s\n",
Path);
888 TRACE(
"Enter NtfsMount(%lu)\n", DeviceId);
927 Volume->ClusterSize =
Volume->BootSector.SectorsPerCluster *
Volume->BootSector.BytesPerSector;
928 if (
Volume->BootSector.ClustersPerMftRecord > 0)
929 Volume->MftRecordSize =
Volume->BootSector.ClustersPerMftRecord *
Volume->ClusterSize;
931 Volume->MftRecordSize = 1 << (-
Volume->BootSector.ClustersPerMftRecord);
932 if (
Volume->BootSector.ClustersPerIndexRecord > 0)
933 Volume->IndexRecordSize =
Volume->BootSector.ClustersPerIndexRecord *
Volume->ClusterSize;
935 Volume->IndexRecordSize = 1 << (-
Volume->BootSector.ClustersPerIndexRecord);
938 TRACE(
"ClustersPerMftRecord: %d\n",
Volume->BootSector.ClustersPerMftRecord);
939 TRACE(
"ClustersPerIndexRecord: %d\n",
Volume->BootSector.ClustersPerIndexRecord);
940 TRACE(
"MftRecordSize: 0x%x\n",
Volume->MftRecordSize);
941 TRACE(
"IndexRecordSize: 0x%x\n",
Volume->IndexRecordSize);
946 TRACE(
"Reading MFT index...\n");
948 if (!
Volume->MasterFileTable)
975 if (!
Volume->TemporarySector)
986 Volume->DeviceId = DeviceId;
991 TRACE(
"Searching for DATA attribute...\n");
1009 TRACE(
"NtfsMount(%lu) success\n", DeviceId);
while(CdLookupNextInitialFileDirent(IrpContext, Fcb, FileContext))
#define TAG_NTFS_INDEX_REC
#define NTFS_ATTR_TYPE_ATTRIBUTE_LIST
struct NTFS_MFT_RECORD * PNTFS_MFT_RECORD
_In_ ULONG _In_ ULONG _In_ ULONG Length
VOID FsGetFirstNameFromPath(PCHAR Buffer, PCSTR Path)
ARC_STATUS NtfsOpen(CHAR *Path, OPENMODE OpenMode, ULONG *FileId)
ACPI_SIZE strlen(const char *String)
struct NTFS_ATTR_RECORD * PNTFS_ATTR_RECORD
NTFS_INDEX_HEADER IndexHeader
ARC_STATUS NtfsGetFileInformation(ULONG FileId, FILEINFORMATION *Information)
ULONG FsGetNumPathParts(PCSTR Path)
static PNTFS_ATTR_CONTEXT NtfsFindAttributeHelper(PNTFS_VOLUME_INFO Volume, PNTFS_ATTR_RECORD AttrRecord, PNTFS_ATTR_RECORD AttrRecordEnd, ULONG Type, const WCHAR *Name, ULONG NameLength)
#define NTFS_ATTR_TYPE_DATA
#define NTFS_ATTR_TYPE_INDEX_ALLOCATION
_In_ WDFREQUEST _In_ NTSTATUS _In_ ULONG_PTR Information
#define NTFS_INDEX_ENTRY_END
VOID * FsGetDeviceSpecific(ULONG FileId)
NTFS_FILE_NAME_ATTR FileName
ARC_STATUS NtfsSeek(ULONG FileId, LARGE_INTEGER *Position, SEEKMODE SeekMode)
_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
PNTFS_MFT_RECORD MasterFileTable
const DEVVTBL * NtfsMount(ULONG DeviceId)
ARC_STATUS NtfsRead(ULONG FileId, VOID *Buffer, ULONG N, ULONG *Count)
struct _NTFS_VOLUME_INFO NTFS_VOLUME_INFO
_In_ struct _KBUGCHECK_REASON_CALLBACK_RECORD * Record
VOID FileSystemError(PCSTR ErrorString)
#define NTFS_FILE_NAME_POSIX
ARC_STATUS NtfsClose(ULONG FileId)
FORCEINLINE PVOID FrLdrTempAlloc(_In_ SIZE_T Size, _In_ ULONG Tag)
static BOOLEAN NtfsReadMftRecord(PNTFS_VOLUME_INFO Volume, ULONGLONG MFTIndex, PNTFS_MFT_RECORD Buffer)
#define NTFS_ATTR_TYPE_BITMAP
static PNTFS_ATTR_CONTEXT NtfsPrepareAttributeContext(PNTFS_ATTR_RECORD AttrRecord)
union NTFS_INDEX_ENTRY::@167 Data
static BOOLEAN NtfsDiskRead(PNTFS_VOLUME_INFO Volume, ULONGLONG Offset, ULONGLONG Length, PCHAR Buffer)
struct NTFS_INDEX_ROOT * PNTFS_INDEX_ROOT
NTSYSAPI ULONG NTAPI RtlEqualMemory(CONST VOID *Source1, CONST VOID *Source2, ULONG Length)
static BOOLEAN NtfsLookupFile(PNTFS_VOLUME_INFO Volume, PCSTR FileName, PNTFS_MFT_RECORD MftRecord, PNTFS_ATTR_CONTEXT *DataContext)
static PNTFS_ATTR_CONTEXT NtfsFindAttribute(PNTFS_VOLUME_INFO Volume, PNTFS_MFT_RECORD MftRecord, ULONG Type, const WCHAR *Name)
#define NTFS_ATTR_TYPE_END
struct BitmapData BitmapData
VOID FsSetDeviceSpecific(ULONG FileId, VOID *Specific)
static BOOLEAN NtfsFixupRecord(PNTFS_VOLUME_INFO Volume, PNTFS_RECORD Record)
ARC_STATUS ArcRead(ULONG FileId, VOID *Buffer, ULONG N, ULONG *Count)
static VOID NtfsReleaseAttributeContext(PNTFS_ATTR_CONTEXT Context)
PNTFS_VOLUME_INFO NtfsVolumes[MAX_FDS]
ARC_STATUS ArcSeek(ULONG FileId, LARGE_INTEGER *Position, SEEKMODE SeekMode)
static ULONGLONG NtfsGetAttributeSize(PNTFS_ATTR_RECORD AttrRecord)
NTFS_BOOTSECTOR BootSector
_Must_inspect_result_ _In_ PFILE_OBJECT _In_opt_ HANDLE _In_ ULONG FileNameLength
#define NTFS_ATTR_TYPE_INDEX_ROOT
static PUCHAR NtfsDecodeRun(PUCHAR DataRun, LONGLONG *DataRunOffset, ULONGLONG *DataRunLength)
static ULONG NtfsReadAttribute(PNTFS_VOLUME_INFO Volume, PNTFS_ATTR_CONTEXT Context, ULONGLONG Offset, PCHAR Buffer, ULONG Length)
_In_ ULONG _In_ ULONG Offset
PNTFS_ATTR_CONTEXT MFTContext
struct _FileName FileName
PRTL_UNICODE_STRING_BUFFER Path
struct NTFS_ATTR_RECORD::@163::@165 Resident
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 FIELD_OFFSET(t, f)
struct tagContext Context
struct NTFS_ATTR_RECORD::@163::@166 NonResident
ULONG FsGetDeviceId(ULONG FileId)
struct NTFS_INDEX_ENTRY::@167::@168 Directory
static BOOLEAN NtfsCompareFileName(PCHAR FileName, PNTFS_INDEX_ENTRY IndexEntry)
#define RtlZeroMemory(Destination, Length)
#define RtlCopyMemory(Destination, Source, Length)
static BOOLEAN NtfsFindMftRecord(PNTFS_VOLUME_INFO Volume, ULONGLONG MFTIndex, PCHAR FileName, ULONGLONG *OutMFTIndex)
struct NTFS_INDEX_ENTRY * PNTFS_INDEX_ENTRY
const DEVVTBL NtfsFuncTable
DBG_DEFAULT_CHANNEL(FILESYSTEM)
FORCEINLINE VOID FrLdrTempFree(PVOID Allocation, ULONG Tag)