210 lines
4.6 KiB
C++
210 lines
4.6 KiB
C++
|
#include "ulib.hxx"
|
||
|
#include "logrecio.hxx"
|
||
|
#include "attrib.hxx"
|
||
|
#include "mftfile.hxx"
|
||
|
#include "diskedit.h"
|
||
|
|
||
|
extern "C" {
|
||
|
#include "lfs.h"
|
||
|
#include "lfsdisk.h"
|
||
|
#include <stdio.h>
|
||
|
}
|
||
|
|
||
|
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
|
||
|
)
|
||
|
{
|
||
|
FARPROC proc;
|
||
|
NTFS_SA ntfssa;
|
||
|
MESSAGE msg;
|
||
|
NTFS_MFT_FILE mft;
|
||
|
ULONG PageOffset;
|
||
|
LONGLONG FileOffset;
|
||
|
BOOLEAN error;
|
||
|
|
||
|
_drive = Drive;
|
||
|
|
||
|
proc = MakeProcInstance((FARPROC)ReadLogRecord, Application);
|
||
|
if (!DialogBox((HINSTANCE)Application, TEXT("ReadLogRecordBox"),
|
||
|
WindowHandle, (DLGPROC) proc)) {
|
||
|
*Error = FALSE;
|
||
|
return FALSE;
|
||
|
}
|
||
|
FreeProcInstance(proc);
|
||
|
|
||
|
*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;
|
||
|
}
|
||
|
|
||
|
|
||
|
BOOL
|
||
|
ReadLogRecord(
|
||
|
IN HWND hDlg,
|
||
|
IN UINT message,
|
||
|
IN UINT wParam,
|
||
|
IN LONG 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;
|
||
|
}
|