windows-nt/Source/XPSP1/NT/base/fs/utils/diskedit/logrecio.cxx

210 lines
4.6 KiB
C++
Raw Permalink Normal View History

2020-09-26 03:20:57 -05:00
#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;
}