#include "ulib.hxx" #include "logrecio.hxx" #include "attrib.hxx" #include "mftfile.hxx" #include "diskedit.h" extern "C" { #include "lfs.h" #include "lfsdisk.h" #include } const int three = 3; STATIC LSN Lsn; BOOLEAN LOG_RECORD_IO::Setup( IN PMEM Mem, IN PLOG_IO_DP_DRIVE Drive, IN HANDLE Application, IN HWND WindowHandle, OUT PBOOLEAN Error ) { NTFS_SA ntfssa; MESSAGE msg; NTFS_MFT_FILE mft; ULONG PageOffset; LONGLONG FileOffset; BOOLEAN error; _drive = Drive; if (!DialogBox((HINSTANCE)Application, TEXT("ReadLogRecordBox"), WindowHandle, ReadLogRecord)) { *Error = FALSE; return FALSE; } *Error = TRUE; if (!_drive || !ntfssa.Initialize(_drive, &msg) || !ntfssa.Read() || !mft.Initialize(_drive, ntfssa.QueryMftStartingLcn(), ntfssa.QueryClusterFactor(), ntfssa.QueryFrsSize(), ntfssa.QueryVolumeSectors(), NULL, NULL) || !mft.Read() || !_frs.Initialize((VCN)LOG_FILE_NUMBER, &mft) || !_frs.Read()) { return FALSE; } if (!_frs.QueryAttribute(&_attrib, &error, $DATA, NULL)) { return FALSE; } LfsTruncateLsnToLogPage(Drive, Lsn, &FileOffset); PageOffset = LfsLsnToPageOffset(Drive, Lsn); swprintf(_header_text, TEXT("DiskEdit - Log record: page @ %x, offset %x"), (ULONG)FileOffset, PageOffset); return TRUE; } BOOLEAN LOG_RECORD_IO::Read( OUT PULONG pError ) { LFS_RECORD_HEADER RecordHeader; ULONG PageOffset; LONGLONG FileOffset; ULONG bytes_read; ULONG RemainingLength, CurrentPos, ThisPagePortion; *pError = 0; (void)GetLogPageSize(_drive); LfsTruncateLsnToLogPage(_drive, Lsn, &FileOffset); PageOffset = LfsLsnToPageOffset(_drive, Lsn); // // Read in the record header to see how big the total record // is. // if (!_attrib.Read((PVOID)&RecordHeader, ULONG(PageOffset | FileOffset), LFS_RECORD_HEADER_SIZE, &bytes_read) || bytes_read != LFS_RECORD_HEADER_SIZE) { *pError = _drive->QueryLastNtStatus(); return FALSE; } _length = LFS_RECORD_HEADER_SIZE + RecordHeader.ClientDataLength; if (NULL == (_buffer = MALLOC(_length))) { *pError = (ULONG)STATUS_INSUFFICIENT_RESOURCES; return FALSE; } RemainingLength = _length; CurrentPos = 0; while (RemainingLength > 0) { ThisPagePortion = MIN(GetLogPageSize(_drive) - PageOffset, RemainingLength); if (!_attrib.Read((PUCHAR)_buffer + CurrentPos, ULONG(FileOffset | PageOffset), ThisPagePortion, &bytes_read) || bytes_read != ThisPagePortion) { *pError = _drive->QueryLastNtStatus(); return FALSE; } CurrentPos += ThisPagePortion; RemainingLength -= ThisPagePortion; FileOffset += GetLogPageSize(_drive); PageOffset = LFS_PACKED_RECORD_PAGE_HEADER_SIZE; } return TRUE; } BOOLEAN LOG_RECORD_IO::Write( ) { return FALSE; } PVOID LOG_RECORD_IO::GetBuf( OUT PULONG Size ) { if (Size) { *Size = _length; } return _buffer; } PTCHAR LOG_RECORD_IO::GetHeaderText( ) { return _header_text; } INT_PTR ReadLogRecord( IN HWND hDlg, IN UINT message, IN WPARAM wParam, IN LPARAM lParam ) { UNREFERENCED_PARAMETER(lParam); TCHAR buf[1024]; PTCHAR pch; INT n; switch (message) { case WM_INITDIALOG: swprintf(buf, TEXT("%x:%x"), Lsn.HighPart, Lsn.LowPart); SetDlgItemText(hDlg, IDTEXT, buf); return TRUE; case WM_COMMAND: if (LOWORD(wParam) == IDCANCEL) { EndDialog(hDlg, FALSE); return TRUE; } if (LOWORD(wParam) == IDOK) { n = GetDlgItemText(hDlg, IDTEXT, buf, sizeof(buf)/sizeof(TCHAR)); buf[n] = 0; if (NULL == (pch = wcschr(buf, ':'))) { Lsn.HighPart = 0; swscanf(buf, TEXT("%x"), &Lsn.LowPart); } else { *pch = 0; swscanf(buf, TEXT("%x"), &Lsn.HighPart); swscanf(pch + 1, TEXT("%x"), &Lsn.LowPart); *pch = ':'; } EndDialog(hDlg, TRUE); return TRUE; } break; } return FALSE; }