extern tVFS_NodeType gNTFS_DirType;
extern tVFS_NodeType gNTFS_FileType;
+extern int NTFS_int_ApplyUpdateSequence(void *Buf, size_t BufLen, const Uint16 *Sequence, size_t NumEntries);
// -- MFT Access / Manipulation
extern tNTFS_FILE_Header *NTFS_GetMFT(tNTFS_Disk *Disk, Uint32 MFTEntry);
extern void NTFS_ReleaseMFT(tNTFS_Disk *Disk, Uint32 MFTEntry, tNTFS_FILE_Header *Entry);
// Check allocation
struct sNTFS_IndexHeader *hdr = (void*)buf;
ASSERT(hdr->EntriesOffset + 0x18 < len);
+ // Apply update sequence
+ ASSERT(hdr->UpdateSequenceOfs + 2*hdr->UpdateSequenceSize <= len);
+ NTFS_int_ApplyUpdateSequence(buf,len, (void*)(buf+hdr->UpdateSequenceOfs), hdr->UpdateSequenceSize);
size_t ofs = hdr->EntriesOffset + 0x18;
ent = NTFS_int_IterateIndex(buf + ofs, len - ofs, &Pos);
vcn ++;
while( (len = NTFS_ReadAttribData(Allocation, vcn*block_size, block_size, buf)) )
{
struct sNTFS_IndexHeader *hdr = (void*)buf;
+ // Apply update sequence
+ ASSERT(hdr->UpdateSequenceOfs + 2*hdr->UpdateSequenceSize <= len);
+ NTFS_int_ApplyUpdateSequence(buf,len, (void*)(buf+hdr->UpdateSequenceOfs), hdr->UpdateSequenceSize);
+
LOG("VCN %x: Ofs=%x, Size=%x",
vcn, hdr->EntriesOffset, hdr->EntriesSize);
if( hdr->ThisVCN != vcn ) {
if( len == 0 )
break;
tNTFS_IndexHeader *hdr = (void*)buf;
+ // Apply update sequence
+ ASSERT(hdr->UpdateSequenceOfs + 2*hdr->UpdateSequenceSize <= len);
+ NTFS_int_ApplyUpdateSequence(buf,len, (void*)(buf+hdr->UpdateSequenceOfs), hdr->UpdateSequenceSize);
+ // Search
//mftent = NTFS_BTreeSearch(len, (void*)buf, NTFS_BTreeSearch_CmpI30, name16len*2, name16);
mftent = NTFS_BTreeSearch(
len-(hdr->EntriesOffset+0x18), buf+hdr->EntriesOffset+0x18,
free(Disk);
}
+int NTFS_int_ApplyUpdateSequence(void *Buffer, size_t BufLen, const Uint16 *Sequence, size_t NumEntries)
+{
+ Uint16 cksum = Sequence[0];
+ LOG("cksum = %04x", cksum);
+ Sequence ++;
+ Uint16 *buf16 = Buffer;
+ for( int i = 0; i < NumEntries-1; i ++ )
+ {
+ size_t ofs = (i+1)*512 - 2;
+ if( ofs + 2 > BufLen ) {
+ // Oops?
+ Log_Warning("NTFS", "%x > %x", ofs+2, BufLen);
+ }
+ Uint16 *cksum_word = &buf16[ofs/2];
+ LOG("[%i]: %04x => %04x", i, Sequence[i], *cksum_word);
+ if( *cksum_word != cksum ) {
+ Log_Warning("NTFS", "Disk corruption detected");
+ return 1;
+ }
+ *cksum_word = Sequence[i];
+ }
+ return 0;
+}
+
tNTFS_FILE_Header *NTFS_GetMFT(tNTFS_Disk *Disk, Uint32 MFTEntry)
{
- void *ret = malloc( Disk->MFTRecSize );
+ tNTFS_FILE_Header *ret = malloc( Disk->MFTRecSize );
if(!ret) {
Log_Warning("FS_NTFS", "malloc() fail!");
return NULL;
else {
NTFS_ReadAttribData(Disk->MFTDataAttr, MFTEntry * Disk->MFTRecSize, Disk->MFTRecSize, ret);
}
-
+
+ NTFS_int_ApplyUpdateSequence(ret, Disk->MFTRecSize,
+ (void*)((char*)ret + ret->UpdateSequenceOfs), ret->UpdateSequenceSize
+ );
+
return ret;
}