mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 10:04:49 +00:00
- Fixed lots of bugs in NTFS code and added correct update sequence
fixups handling and untested NTFS 3+ sparse file support. svn path=/trunk/; revision=10467
This commit is contained in:
parent
99e5dd3e01
commit
5775259453
4 changed files with 140 additions and 80 deletions
|
@ -1,3 +1,8 @@
|
||||||
|
Changes in v1.8.22 (21/05/2004) (navaraf)
|
||||||
|
|
||||||
|
- Fixed lots of bugs in NTFS code and added correct update sequence
|
||||||
|
fixups handling and untested NTFS 3+ sparse file support.
|
||||||
|
|
||||||
Changes in v1.8.21 (21/05/2004) (navaraf)
|
Changes in v1.8.21 (21/05/2004) (navaraf)
|
||||||
|
|
||||||
- Experimental NTFS reading support with no boot code yet.
|
- Experimental NTFS reading support with no boot code yet.
|
||||||
|
|
|
@ -1,7 +1,4 @@
|
||||||
/*
|
/*
|
||||||
* FreeLoader
|
|
||||||
* Copyright (C) 1998-2003 Brian Palmer <brianp@sginet.com>
|
|
||||||
*
|
|
||||||
* FreeLoader NTFS support
|
* FreeLoader NTFS support
|
||||||
* Copyright (C) 2004 Filip Navara <xnavara@volny.cz>
|
* Copyright (C) 2004 Filip Navara <xnavara@volny.cz>
|
||||||
*
|
*
|
||||||
|
@ -25,10 +22,6 @@
|
||||||
* - No support for compressed files.
|
* - No support for compressed files.
|
||||||
* - No attribute list support.
|
* - No attribute list support.
|
||||||
* - May crash on currupted filesystem.
|
* - May crash on currupted filesystem.
|
||||||
*
|
|
||||||
* Bugs:
|
|
||||||
* - I encountered file names like 'KERNEL~1.EE' stored on
|
|
||||||
* the disk. These aren't handled correctly yet.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <freeldr.h>
|
#include <freeldr.h>
|
||||||
|
@ -40,7 +33,6 @@
|
||||||
#include <debug.h>
|
#include <debug.h>
|
||||||
#include <cache.h>
|
#include <cache.h>
|
||||||
|
|
||||||
#define NTFS_DEFS
|
|
||||||
#include "ntfs.h"
|
#include "ntfs.h"
|
||||||
|
|
||||||
PNTFS_BOOTSECTOR NtfsBootSector;
|
PNTFS_BOOTSECTOR NtfsBootSector;
|
||||||
|
@ -56,7 +48,7 @@ PUCHAR NtfsDecodeRun(PUCHAR DataRun, S64 *DataRunOffset, U64 *DataRunLength)
|
||||||
{
|
{
|
||||||
U8 DataRunOffsetSize;
|
U8 DataRunOffsetSize;
|
||||||
U8 DataRunLengthSize;
|
U8 DataRunLengthSize;
|
||||||
U8 i;
|
S8 i;
|
||||||
|
|
||||||
DataRunOffsetSize = (*DataRun >> 4) & 0xF;
|
DataRunOffsetSize = (*DataRun >> 4) & 0xF;
|
||||||
DataRunLengthSize = *DataRun & 0xF;
|
DataRunLengthSize = *DataRun & 0xF;
|
||||||
|
@ -68,16 +60,27 @@ PUCHAR NtfsDecodeRun(PUCHAR DataRun, S64 *DataRunOffset, U64 *DataRunLength)
|
||||||
*DataRunLength += *DataRun << (i << 3);
|
*DataRunLength += *DataRun << (i << 3);
|
||||||
DataRun++;
|
DataRun++;
|
||||||
}
|
}
|
||||||
for (i = 0; i < DataRunOffsetSize; i++)
|
|
||||||
|
/* NTFS 3+ sparse files */
|
||||||
|
if (DataRunOffsetSize == 0)
|
||||||
{
|
{
|
||||||
*DataRunOffset += *DataRun << (i << 3);
|
*DataRunOffset = -1;
|
||||||
DataRun++;
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (i = 0; i < DataRunOffsetSize - 1; i++)
|
||||||
|
{
|
||||||
|
*DataRunOffset += *DataRun << (i << 3);
|
||||||
|
DataRun++;
|
||||||
|
}
|
||||||
|
/* The last byte contains sign so we must process it different way. */
|
||||||
|
*DataRunOffset = ((S8)(*(DataRun++)) << (i << 3)) + *DataRunOffset;
|
||||||
}
|
}
|
||||||
|
|
||||||
DbgPrint((DPRINT_FILESYSTEM, "DataRunOffsetSize: %x\n", DataRunOffsetSize));
|
DbgPrint((DPRINT_FILESYSTEM, "DataRunOffsetSize: %x\n", DataRunOffsetSize));
|
||||||
DbgPrint((DPRINT_FILESYSTEM, "DataRunLengthSize: %x\n", DataRunLengthSize));
|
DbgPrint((DPRINT_FILESYSTEM, "DataRunLengthSize: %x\n", DataRunLengthSize));
|
||||||
DbgPrint((DPRINT_FILESYSTEM, "DataRunOffset: %x\n", DataRunOffset));
|
DbgPrint((DPRINT_FILESYSTEM, "DataRunOffset: %x\n", *DataRunOffset));
|
||||||
DbgPrint((DPRINT_FILESYSTEM, "DataRunLength: %x\n", DataRunLength));
|
DbgPrint((DPRINT_FILESYSTEM, "DataRunLength: %x\n", *DataRunLength));
|
||||||
|
|
||||||
return DataRun;
|
return DataRun;
|
||||||
}
|
}
|
||||||
|
@ -97,7 +100,7 @@ BOOL NtfsFindAttribute(PNTFS_ATTR_CONTEXT Context, PNTFS_MFT_RECORD MftRecord, U
|
||||||
|
|
||||||
while (AttrRecord < AttrRecordEnd)
|
while (AttrRecord < AttrRecordEnd)
|
||||||
{
|
{
|
||||||
if (AttrRecord->Type == ATTR_TYPE_END)
|
if (AttrRecord->Type == NTFS_ATTR_TYPE_END)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (AttrRecord->Type == Type)
|
if (AttrRecord->Type == Type)
|
||||||
|
@ -117,6 +120,7 @@ BOOL NtfsFindAttribute(PNTFS_ATTR_CONTEXT Context, PNTFS_MFT_RECORD MftRecord, U
|
||||||
Context->CacheRun = (PUCHAR)Context->Record + Context->Record->NonResident.MappingPairsOffset;
|
Context->CacheRun = (PUCHAR)Context->Record + Context->Record->NonResident.MappingPairsOffset;
|
||||||
Context->CacheRunOffset = 0;
|
Context->CacheRunOffset = 0;
|
||||||
Context->CacheRun = NtfsDecodeRun(Context->CacheRun, &DataRunOffset, &DataRunLength);
|
Context->CacheRun = NtfsDecodeRun(Context->CacheRun, &DataRunOffset, &DataRunLength);
|
||||||
|
Context->CacheRunLength = DataRunLength;
|
||||||
if (DataRunOffset != -1)
|
if (DataRunOffset != -1)
|
||||||
{
|
{
|
||||||
/* Normal run. */
|
/* Normal run. */
|
||||||
|
@ -147,6 +151,9 @@ BOOL NtfsDiskRead(U64 Offset, U64 Length, PCHAR Buffer)
|
||||||
{
|
{
|
||||||
U16 ReadLength;
|
U16 ReadLength;
|
||||||
|
|
||||||
|
DbgPrint((DPRINT_FILESYSTEM, "NtfsDiskRead - Offset: %I64d Length: %I64d\n", Offset, Length));
|
||||||
|
RtlZeroMemory((PCHAR)DISKREADBUFFER, 0x1000);
|
||||||
|
|
||||||
/* I. Read partial first sector if needed */
|
/* I. Read partial first sector if needed */
|
||||||
if (Offset % NtfsBootSector->BytesPerSector)
|
if (Offset % NtfsBootSector->BytesPerSector)
|
||||||
{
|
{
|
||||||
|
@ -216,6 +223,7 @@ U64 NtfsReadAttribute(PNTFS_ATTR_CONTEXT Context, U64 Offset, PCHAR Buffer, U64
|
||||||
DataRun = Context->CacheRun;
|
DataRun = Context->CacheRun;
|
||||||
LastLCN = Context->CacheRunLastLCN;
|
LastLCN = Context->CacheRunLastLCN;
|
||||||
DataRunStartLCN = Context->CacheRunStartLCN;
|
DataRunStartLCN = Context->CacheRunStartLCN;
|
||||||
|
DataRunLength = Context->CacheRunLength;
|
||||||
CurrentOffset = Context->CacheRunCurrentOffset;
|
CurrentOffset = Context->CacheRunCurrentOffset;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -239,6 +247,8 @@ U64 NtfsReadAttribute(PNTFS_ATTR_CONTEXT Context, U64 Offset, PCHAR Buffer, U64
|
||||||
DataRunStartLCN = -1;
|
DataRunStartLCN = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DbgPrint((DPRINT_FILESYSTEM, "YYY - %I64x\n", DataRunStartLCN));
|
||||||
|
|
||||||
if (Offset >= CurrentOffset &&
|
if (Offset >= CurrentOffset &&
|
||||||
Offset < CurrentOffset + (DataRunLength * NtfsClusterSize))
|
Offset < CurrentOffset + (DataRunLength * NtfsClusterSize))
|
||||||
{
|
{
|
||||||
|
@ -270,6 +280,10 @@ U64 NtfsReadAttribute(PNTFS_ATTR_CONTEXT Context, U64 Offset, PCHAR Buffer, U64
|
||||||
Buffer += ReadLength;
|
Buffer += ReadLength;
|
||||||
AlreadyRead += ReadLength;
|
AlreadyRead += ReadLength;
|
||||||
|
|
||||||
|
/* We finished this request, but there still data in this data run. */
|
||||||
|
if (Length == 0 && ReadLength != DataRunLength * NtfsClusterSize)
|
||||||
|
break;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Go to next run in the list.
|
* Go to next run in the list.
|
||||||
*/
|
*/
|
||||||
|
@ -294,15 +308,47 @@ U64 NtfsReadAttribute(PNTFS_ATTR_CONTEXT Context, U64 Offset, PCHAR Buffer, U64
|
||||||
Context->CacheRun = DataRun;
|
Context->CacheRun = DataRun;
|
||||||
Context->CacheRunOffset = Offset + AlreadyRead;
|
Context->CacheRunOffset = Offset + AlreadyRead;
|
||||||
Context->CacheRunStartLCN = DataRunStartLCN;
|
Context->CacheRunStartLCN = DataRunStartLCN;
|
||||||
|
Context->CacheRunLength = DataRunLength;
|
||||||
Context->CacheRunLastLCN = LastLCN;
|
Context->CacheRunLastLCN = LastLCN;
|
||||||
Context->CacheRunCurrentOffset = CurrentOffset;
|
Context->CacheRunCurrentOffset = CurrentOffset;
|
||||||
|
|
||||||
return AlreadyRead;
|
return AlreadyRead;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BOOL NtfsFixupRecord(PNTFS_RECORD Record)
|
||||||
|
{
|
||||||
|
U16 *USA;
|
||||||
|
U16 USANumber;
|
||||||
|
U16 USACount;
|
||||||
|
U16 *Block;
|
||||||
|
|
||||||
|
USA = (U16*)((PCHAR)Record + Record->USAOffset);
|
||||||
|
USANumber = *(USA++);
|
||||||
|
USACount = Record->USACount - 1; /* Exclude the USA Number. */
|
||||||
|
Block = (U16*)((PCHAR)Record + NtfsBootSector->BytesPerSector - 2);
|
||||||
|
|
||||||
|
while (USACount)
|
||||||
|
{
|
||||||
|
if (*Block != USANumber)
|
||||||
|
return FALSE;
|
||||||
|
*Block = *(USA++);
|
||||||
|
Block = (U16*)((PCHAR)Block + NtfsBootSector->BytesPerSector);
|
||||||
|
USACount--;
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
BOOL NtfsReadMftRecord(U32 MFTIndex, PNTFS_MFT_RECORD Buffer)
|
BOOL NtfsReadMftRecord(U32 MFTIndex, PNTFS_MFT_RECORD Buffer)
|
||||||
{
|
{
|
||||||
return NtfsReadAttribute(&NtfsMFTContext, MFTIndex * NtfsMftRecordSize, (PCHAR)Buffer, NtfsMftRecordSize) == NtfsMftRecordSize;
|
U64 BytesRead;
|
||||||
|
|
||||||
|
BytesRead = NtfsReadAttribute(&NtfsMFTContext, MFTIndex * NtfsMftRecordSize, (PCHAR)Buffer, NtfsMftRecordSize);
|
||||||
|
if (BytesRead != NtfsMftRecordSize)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
/* Apply update sequence array fixups. */
|
||||||
|
return NtfsFixupRecord((PNTFS_RECORD)Buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
|
@ -341,7 +387,7 @@ BOOL NtfsCompareFileName(PCHAR FileName, PNTFS_INDEX_ENTRY IndexEntry)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
/* Do case-sensitive compares for Posix file names. */
|
/* Do case-sensitive compares for Posix file names. */
|
||||||
if (IndexEntry->FileName.FileNameType == FILE_NAME_POSIX)
|
if (IndexEntry->FileName.FileNameType == NTFS_FILE_NAME_POSIX)
|
||||||
{
|
{
|
||||||
for (i = 0; i < EntryFileNameLength; i++)
|
for (i = 0; i < EntryFileNameLength; i++)
|
||||||
if (EntryFileName[i] != FileName[i])
|
if (EntryFileName[i] != FileName[i])
|
||||||
|
@ -383,7 +429,7 @@ BOOL NtfsFindMftRecord(U32 MFTIndex, PCHAR FileName, U32 *OutMFTIndex)
|
||||||
{
|
{
|
||||||
Magic = MftRecord->Magic;
|
Magic = MftRecord->Magic;
|
||||||
|
|
||||||
if (!NtfsFindAttribute(&IndexRootCtx, MftRecord, ATTR_TYPE_INDEX_ROOT, L"$I30"))
|
if (!NtfsFindAttribute(&IndexRootCtx, MftRecord, NTFS_ATTR_TYPE_INDEX_ROOT, L"$I30"))
|
||||||
{
|
{
|
||||||
MmFreeMemory(MftRecord);
|
MmFreeMemory(MftRecord);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
@ -405,7 +451,7 @@ BOOL NtfsFindMftRecord(U32 MFTIndex, PCHAR FileName, U32 *OutMFTIndex)
|
||||||
DbgPrint((DPRINT_FILESYSTEM, "NtfsIndexRecordSize: %x IndexBlockSize: %x\n", NtfsIndexRecordSize, IndexRoot->IndexBlockSize));
|
DbgPrint((DPRINT_FILESYSTEM, "NtfsIndexRecordSize: %x IndexBlockSize: %x\n", NtfsIndexRecordSize, IndexRoot->IndexBlockSize));
|
||||||
|
|
||||||
while (IndexEntry < IndexEntryEnd &&
|
while (IndexEntry < IndexEntryEnd &&
|
||||||
!(IndexEntry->Flags & INDEX_ENTRY_END))
|
!(IndexEntry->Flags & NTFS_INDEX_ENTRY_END))
|
||||||
{
|
{
|
||||||
if (NtfsCompareFileName(FileName, IndexEntry))
|
if (NtfsCompareFileName(FileName, IndexEntry))
|
||||||
{
|
{
|
||||||
|
@ -417,13 +463,13 @@ BOOL NtfsFindMftRecord(U32 MFTIndex, PCHAR FileName, U32 *OutMFTIndex)
|
||||||
IndexEntry = (PNTFS_INDEX_ENTRY)((PCHAR)IndexEntry + IndexEntry->Length);
|
IndexEntry = (PNTFS_INDEX_ENTRY)((PCHAR)IndexEntry + IndexEntry->Length);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IndexRoot->IndexHeader.Flags & LARGE_INDEX)
|
if (IndexRoot->IndexHeader.Flags & NTFS_LARGE_INDEX)
|
||||||
{
|
{
|
||||||
DbgPrint((DPRINT_FILESYSTEM, "Large Index!\n"));
|
DbgPrint((DPRINT_FILESYSTEM, "Large Index!\n"));
|
||||||
|
|
||||||
IndexBlockSize = IndexRoot->IndexBlockSize;
|
IndexBlockSize = IndexRoot->IndexBlockSize;
|
||||||
|
|
||||||
if (!NtfsFindAttribute(&IndexBitmapCtx, MftRecord, ATTR_TYPE_BITMAP, L"$I30"))
|
if (!NtfsFindAttribute(&IndexBitmapCtx, MftRecord, NTFS_ATTR_TYPE_BITMAP, L"$I30"))
|
||||||
{
|
{
|
||||||
DbgPrint((DPRINT_FILESYSTEM, "Corrupted filesystem!\n"));
|
DbgPrint((DPRINT_FILESYSTEM, "Corrupted filesystem!\n"));
|
||||||
MmFreeMemory(MftRecord);
|
MmFreeMemory(MftRecord);
|
||||||
|
@ -443,7 +489,7 @@ BOOL NtfsFindMftRecord(U32 MFTIndex, PCHAR FileName, U32 *OutMFTIndex)
|
||||||
}
|
}
|
||||||
NtfsReadAttribute(&IndexBitmapCtx, 0, BitmapData, BitmapDataSize);
|
NtfsReadAttribute(&IndexBitmapCtx, 0, BitmapData, BitmapDataSize);
|
||||||
|
|
||||||
if (!NtfsFindAttribute(&IndexAllocationCtx, MftRecord, ATTR_TYPE_INDEX_ALLOCATION, L"$I30"))
|
if (!NtfsFindAttribute(&IndexAllocationCtx, MftRecord, NTFS_ATTR_TYPE_INDEX_ALLOCATION, L"$I30"))
|
||||||
{
|
{
|
||||||
DbgPrint((DPRINT_FILESYSTEM, "Corrupted filesystem!\n"));
|
DbgPrint((DPRINT_FILESYSTEM, "Corrupted filesystem!\n"));
|
||||||
MmFreeMemory(BitmapData);
|
MmFreeMemory(BitmapData);
|
||||||
|
@ -463,7 +509,7 @@ BOOL NtfsFindMftRecord(U32 MFTIndex, PCHAR FileName, U32 *OutMFTIndex)
|
||||||
DbgPrint((DPRINT_FILESYSTEM, "RecordOffset: %x IndexAllocationSize: %x\n", RecordOffset, IndexAllocationSize));
|
DbgPrint((DPRINT_FILESYSTEM, "RecordOffset: %x IndexAllocationSize: %x\n", RecordOffset, IndexAllocationSize));
|
||||||
for (; RecordOffset < IndexAllocationSize;)
|
for (; RecordOffset < IndexAllocationSize;)
|
||||||
{
|
{
|
||||||
U8 Bit = 1 << ((RecordOffset / IndexBlockSize) & 3);
|
U8 Bit = 1 << ((RecordOffset / IndexBlockSize) & 7);
|
||||||
U32 Byte = (RecordOffset / IndexBlockSize) >> 3;
|
U32 Byte = (RecordOffset / IndexBlockSize) >> 3;
|
||||||
if ((BitmapData[Byte] & Bit))
|
if ((BitmapData[Byte] & Bit))
|
||||||
break;
|
break;
|
||||||
|
@ -471,16 +517,23 @@ BOOL NtfsFindMftRecord(U32 MFTIndex, PCHAR FileName, U32 *OutMFTIndex)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (RecordOffset >= IndexAllocationSize)
|
if (RecordOffset >= IndexAllocationSize)
|
||||||
|
{
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
NtfsReadAttribute(&IndexAllocationCtx, RecordOffset, IndexRecord, IndexBlockSize);
|
NtfsReadAttribute(&IndexAllocationCtx, RecordOffset, IndexRecord, IndexBlockSize);
|
||||||
|
|
||||||
|
if (!NtfsFixupRecord((PNTFS_RECORD)IndexRecord))
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
/* FIXME */
|
/* FIXME */
|
||||||
IndexEntry = (PNTFS_INDEX_ENTRY)(IndexRecord + 0x18 + *(U16 *)(IndexRecord + 0x18));
|
IndexEntry = (PNTFS_INDEX_ENTRY)(IndexRecord + 0x18 + *(U16 *)(IndexRecord + 0x18));
|
||||||
IndexEntryEnd = (PNTFS_INDEX_ENTRY)(IndexRecord + IndexBlockSize);
|
IndexEntryEnd = (PNTFS_INDEX_ENTRY)(IndexRecord + IndexBlockSize);
|
||||||
|
|
||||||
while (IndexEntry < IndexEntryEnd &&
|
while (IndexEntry < IndexEntryEnd &&
|
||||||
!(IndexEntry->Flags & INDEX_ENTRY_END))
|
!(IndexEntry->Flags & NTFS_INDEX_ENTRY_END))
|
||||||
{
|
{
|
||||||
if (NtfsCompareFileName(FileName, IndexEntry))
|
if (NtfsCompareFileName(FileName, IndexEntry))
|
||||||
{
|
{
|
||||||
|
@ -520,7 +573,7 @@ BOOL NtfsLookupFile(PUCHAR FileName, PNTFS_MFT_RECORD MftRecord, PNTFS_ATTR_CONT
|
||||||
|
|
||||||
DbgPrint((DPRINT_FILESYSTEM, "NtfsLookupFile() FileName = %s\n", FileName));
|
DbgPrint((DPRINT_FILESYSTEM, "NtfsLookupFile() FileName = %s\n", FileName));
|
||||||
|
|
||||||
CurrentMFTIndex = FILE_ROOT;
|
CurrentMFTIndex = NTFS_FILE_ROOT;
|
||||||
NumberOfPathParts = FsGetNumPathParts(FileName);
|
NumberOfPathParts = FsGetNumPathParts(FileName);
|
||||||
for (i = 0; i < NumberOfPathParts; i++)
|
for (i = 0; i < NumberOfPathParts; i++)
|
||||||
{
|
{
|
||||||
|
@ -545,7 +598,7 @@ BOOL NtfsLookupFile(PUCHAR FileName, PNTFS_MFT_RECORD MftRecord, PNTFS_ATTR_CONT
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!NtfsFindAttribute(DataContext, MftRecord, ATTR_TYPE_DATA, L""))
|
if (!NtfsFindAttribute(DataContext, MftRecord, NTFS_ATTR_TYPE_DATA, L""))
|
||||||
{
|
{
|
||||||
DbgPrint((DPRINT_FILESYSTEM, "NtfsLookupFile: Can't find data attribute\n"));
|
DbgPrint((DPRINT_FILESYSTEM, "NtfsLookupFile: Can't find data attribute\n"));
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
@ -619,7 +672,7 @@ BOOL NtfsOpenVolume(U32 DriveNumber, U32 VolumeStartSector)
|
||||||
RtlCopyMemory(NtfsMasterFileTable, (PCHAR)DISKREADBUFFER, NtfsMftRecordSize);
|
RtlCopyMemory(NtfsMasterFileTable, (PCHAR)DISKREADBUFFER, NtfsMftRecordSize);
|
||||||
|
|
||||||
DbgPrint((DPRINT_FILESYSTEM, "Searching for DATA attribute...\n"));
|
DbgPrint((DPRINT_FILESYSTEM, "Searching for DATA attribute...\n"));
|
||||||
if (!NtfsFindAttribute(&NtfsMFTContext, NtfsMasterFileTable, ATTR_TYPE_DATA, L""))
|
if (!NtfsFindAttribute(&NtfsMFTContext, NtfsMasterFileTable, NTFS_ATTR_TYPE_DATA, L""))
|
||||||
{
|
{
|
||||||
FileSystemError("Can't find data attribute for Master File Table.");
|
FileSystemError("Can't find data attribute for Master File Table.");
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
|
@ -1,7 +1,4 @@
|
||||||
/*
|
/*
|
||||||
* FreeLoader
|
|
||||||
* Copyright (C) 1998-2003 Brian Palmer <brianp@sginet.com>
|
|
||||||
*
|
|
||||||
* FreeLoader NTFS support
|
* FreeLoader NTFS support
|
||||||
* Copyright (C) 2004 Filip Navara <xnavara@volny.cz>
|
* Copyright (C) 2004 Filip Navara <xnavara@volny.cz>
|
||||||
*
|
*
|
||||||
|
@ -23,76 +20,80 @@
|
||||||
#ifndef __NTFS_H
|
#ifndef __NTFS_H
|
||||||
#define __NTFS_H
|
#define __NTFS_H
|
||||||
|
|
||||||
#ifdef NTFS_DEFS
|
#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 FILE_MFT 0
|
#define NTFS_ATTR_TYPE_STANDARD_INFORMATION 0x10
|
||||||
#define FILE_MFTMIRR 1
|
#define NTFS_ATTR_TYPE_ATTRIBUTE_LIST 0x20
|
||||||
#define FILE_LOGFILE 2
|
#define NTFS_ATTR_TYPE_FILENAME 0x30
|
||||||
#define FILE_VOLUME 3
|
#define NTFS_ATTR_TYPE_SECURITY_DESCRIPTOR 0x50
|
||||||
#define FILE_ATTRDEF 4
|
#define NTFS_ATTR_TYPE_DATA 0x80
|
||||||
#define FILE_ROOT 5
|
#define NTFS_ATTR_TYPE_INDEX_ROOT 0x90
|
||||||
#define FILE_BITMAP 6
|
#define NTFS_ATTR_TYPE_INDEX_ALLOCATION 0xa0
|
||||||
#define FILE_BOOT 7
|
#define NTFS_ATTR_TYPE_BITMAP 0xb0
|
||||||
#define FILE_BADCLUS 8
|
#define NTFS_ATTR_TYPE_SYMLINK 0xc0
|
||||||
#define FILE_QUOTA 9
|
#define NTFS_ATTR_TYPE_END 0xffffffff
|
||||||
#define FILE_UPCASE 10
|
|
||||||
|
|
||||||
#define ATTR_TYPE_STANDARD_INFORMATION 0x10
|
#define NTFS_ATTR_NORMAL 0
|
||||||
#define ATTR_TYPE_ATTRIBUTE_LIST 0x20
|
#define NTFS_ATTR_COMPRESSED 1
|
||||||
#define ATTR_TYPE_FILENAME 0x30
|
#define NTFS_ATTR_RESIDENT 2
|
||||||
#define ATTR_TYPE_SECURITY_DESCRIPTOR 0x50
|
#define NTFS_ATTR_ENCRYPTED 0x4000
|
||||||
#define ATTR_TYPE_DATA 0x80
|
|
||||||
#define ATTR_TYPE_INDEX_ROOT 0x90
|
|
||||||
#define ATTR_TYPE_INDEX_ALLOCATION 0xa0
|
|
||||||
#define ATTR_TYPE_BITMAP 0xb0
|
|
||||||
#define ATTR_TYPE_SYMLINK 0xc0
|
|
||||||
#define ATTR_TYPE_END 0xffffffff
|
|
||||||
|
|
||||||
#define ATTR_NORMAL 0
|
#define NTFS_SMALL_INDEX 0
|
||||||
#define ATTR_COMPRESSED 1
|
#define NTFS_LARGE_INDEX 1
|
||||||
#define ATTR_RESIDENT 2
|
|
||||||
#define ATTR_ENCRYPTED 0x4000
|
|
||||||
|
|
||||||
#define SMALL_INDEX 0
|
#define NTFS_INDEX_ENTRY_NODE 1
|
||||||
#define LARGE_INDEX 1
|
#define NTFS_INDEX_ENTRY_END 2
|
||||||
|
|
||||||
#define INDEX_ENTRY_NODE 1
|
#define NTFS_FILE_NAME_POSIX 0
|
||||||
#define INDEX_ENTRY_END 2
|
#define NTFS_FILE_NAME_WIN32 1
|
||||||
|
#define NTFS_FILE_NAME_DOS 2
|
||||||
#define FILE_NAME_POSIX 0
|
#define NTFS_FILE_NAME_WIN32_AND_DOS 3
|
||||||
#define FILE_NAME_WIN32 1
|
|
||||||
#define FILE_NAME_DOS 2
|
|
||||||
#define FILE_NAME_WIN32_AND_DOS 3
|
|
||||||
#endif
|
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
U8 JumpBoot[3]; // Jump to the boot loader routine
|
U8 JumpBoot[3]; // Jump to the boot loader routine
|
||||||
U8 SystemId[8]; // System Id ("NTFS ")
|
U8 SystemId[8]; // System Id ("NTFS ")
|
||||||
U16 BytesPerSector; // Bytes per sector
|
U16 BytesPerSector; // Bytes per sector
|
||||||
U8 SectorsPerCluster; // Number of sectors in a cluster
|
U8 SectorsPerCluster; // Number of sectors in a cluster
|
||||||
U8 Unused1[7];
|
U8 Unused1[7];
|
||||||
U8 MediaDescriptor; // Media descriptor byte
|
U8 MediaDescriptor; // Media descriptor byte
|
||||||
U8 Unused2[2];
|
U8 Unused2[2];
|
||||||
U16 SectorsPerTrack; // Number of sectors in a track
|
U16 SectorsPerTrack; // Number of sectors in a track
|
||||||
U16 NumberOfHeads; // Number of heads on the disk
|
U16 NumberOfHeads; // Number of heads on the disk
|
||||||
U8 Unused3[8];
|
U8 Unused3[8];
|
||||||
U8 DriveNumber; // Int 0x13 drive number (e.g. 0x80)
|
U8 DriveNumber; // Int 0x13 drive number (e.g. 0x80)
|
||||||
U8 CurrentHead;
|
U8 CurrentHead;
|
||||||
U8 BootSignature; // Extended boot signature (0x80)
|
U8 BootSignature; // Extended boot signature (0x80)
|
||||||
U8 Unused4;
|
U8 Unused4;
|
||||||
U64 VolumeSectorCount; // Number of sectors in the volume
|
U64 VolumeSectorCount; // Number of sectors in the volume
|
||||||
U64 MftLocation;
|
U64 MftLocation;
|
||||||
U64 MftMirrorLocation;
|
U64 MftMirrorLocation;
|
||||||
S8 ClustersPerMftRecord; // Clusters per MFT Record
|
S8 ClustersPerMftRecord; // Clusters per MFT Record
|
||||||
U8 Unused5[3];
|
U8 Unused5[3];
|
||||||
S8 ClustersPerIndexRecord; // Clusters per Index Record
|
S8 ClustersPerIndexRecord; // Clusters per Index Record
|
||||||
U8 Unused6[3];
|
U8 Unused6[3];
|
||||||
U64 VolumeSerialNumber; // Volume serial number
|
U64 VolumeSerialNumber; // Volume serial number
|
||||||
U8 BootCodeAndData[430]; // The remainder of the boot sector
|
U8 BootCodeAndData[430]; // The remainder of the boot sector
|
||||||
U16 BootSectorMagic; // 0xAA55
|
U16 BootSectorMagic; // 0xAA55
|
||||||
} PACKED NTFS_BOOTSECTOR, *PNTFS_BOOTSECTOR;
|
} PACKED NTFS_BOOTSECTOR, *PNTFS_BOOTSECTOR;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
U32 Magic;
|
||||||
|
U16 USAOffset; // Offset to the Update Sequence Array from the start of the ntfs record
|
||||||
|
U16 USACount;
|
||||||
|
} PACKED NTFS_RECORD, *PNTFS_RECORD;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
U32 Magic;
|
U32 Magic;
|
||||||
|
@ -206,6 +207,7 @@ typedef struct
|
||||||
PUCHAR CacheRun;
|
PUCHAR CacheRun;
|
||||||
U64 CacheRunOffset;
|
U64 CacheRunOffset;
|
||||||
S64 CacheRunStartLCN;
|
S64 CacheRunStartLCN;
|
||||||
|
U64 CacheRunLength;
|
||||||
S64 CacheRunLastLCN;
|
S64 CacheRunLastLCN;
|
||||||
U64 CacheRunCurrentOffset;
|
U64 CacheRunCurrentOffset;
|
||||||
} NTFS_ATTR_CONTEXT, *PNTFS_ATTR_CONTEXT;
|
} NTFS_ATTR_CONTEXT, *PNTFS_ATTR_CONTEXT;
|
||||||
|
|
|
@ -22,7 +22,7 @@
|
||||||
|
|
||||||
|
|
||||||
/* just some stuff */
|
/* just some stuff */
|
||||||
#define VERSION "FreeLoader v1.8.21"
|
#define VERSION "FreeLoader v1.8.22"
|
||||||
#define COPYRIGHT "Copyright (C) 1998-2003 Brian Palmer <brianp@sginet.com>"
|
#define COPYRIGHT "Copyright (C) 1998-2003 Brian Palmer <brianp@sginet.com>"
|
||||||
#define AUTHOR_EMAIL "<brianp@sginet.com>"
|
#define AUTHOR_EMAIL "<brianp@sginet.com>"
|
||||||
#define BY_AUTHOR "by Brian Palmer"
|
#define BY_AUTHOR "by Brian Palmer"
|
||||||
|
@ -36,7 +36,7 @@
|
||||||
//
|
//
|
||||||
#define FREELOADER_MAJOR_VERSION 1
|
#define FREELOADER_MAJOR_VERSION 1
|
||||||
#define FREELOADER_MINOR_VERSION 8
|
#define FREELOADER_MINOR_VERSION 8
|
||||||
#define FREELOADER_PATCH_VERSION 21
|
#define FREELOADER_PATCH_VERSION 22
|
||||||
|
|
||||||
|
|
||||||
#ifndef ASM
|
#ifndef ASM
|
||||||
|
|
Loading…
Reference in a new issue