Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

209 lines
4.6 KiB

  1. #include "ulib.hxx"
  2. #include "logrecio.hxx"
  3. #include "attrib.hxx"
  4. #include "mftfile.hxx"
  5. #include "diskedit.h"
  6. extern "C" {
  7. #include "lfs.h"
  8. #include "lfsdisk.h"
  9. #include <stdio.h>
  10. }
  11. const int three = 3;
  12. STATIC LSN Lsn;
  13. BOOLEAN
  14. LOG_RECORD_IO::Setup(
  15. IN PMEM Mem,
  16. IN PLOG_IO_DP_DRIVE Drive,
  17. IN HANDLE Application,
  18. IN HWND WindowHandle,
  19. OUT PBOOLEAN Error
  20. )
  21. {
  22. FARPROC proc;
  23. NTFS_SA ntfssa;
  24. MESSAGE msg;
  25. NTFS_MFT_FILE mft;
  26. ULONG PageOffset;
  27. LONGLONG FileOffset;
  28. BOOLEAN error;
  29. _drive = Drive;
  30. proc = MakeProcInstance((FARPROC)ReadLogRecord, Application);
  31. if (!DialogBox((HINSTANCE)Application, TEXT("ReadLogRecordBox"),
  32. WindowHandle, (DLGPROC) proc)) {
  33. *Error = FALSE;
  34. return FALSE;
  35. }
  36. FreeProcInstance(proc);
  37. *Error = TRUE;
  38. if (!_drive ||
  39. !ntfssa.Initialize(_drive, &msg) ||
  40. !ntfssa.Read() ||
  41. !mft.Initialize(_drive, ntfssa.QueryMftStartingLcn(),
  42. ntfssa.QueryClusterFactor(), ntfssa.QueryFrsSize(),
  43. ntfssa.QueryVolumeSectors(), NULL, NULL) ||
  44. !mft.Read() ||
  45. !_frs.Initialize((VCN)LOG_FILE_NUMBER, &mft) ||
  46. !_frs.Read()) {
  47. return FALSE;
  48. }
  49. if (!_frs.QueryAttribute(&_attrib, &error, $DATA, NULL)) {
  50. return FALSE;
  51. }
  52. LfsTruncateLsnToLogPage(Drive, Lsn, &FileOffset);
  53. PageOffset = LfsLsnToPageOffset(Drive, Lsn);
  54. swprintf(_header_text, TEXT("DiskEdit - Log record: page @ %x, offset %x"),
  55. (ULONG)FileOffset, PageOffset);
  56. return TRUE;
  57. }
  58. BOOLEAN
  59. LOG_RECORD_IO::Read(
  60. OUT PULONG pError
  61. )
  62. {
  63. LFS_RECORD_HEADER RecordHeader;
  64. ULONG PageOffset;
  65. LONGLONG FileOffset;
  66. ULONG bytes_read;
  67. ULONG RemainingLength, CurrentPos, ThisPagePortion;
  68. *pError = 0;
  69. (void)GetLogPageSize(_drive);
  70. LfsTruncateLsnToLogPage(_drive, Lsn, &FileOffset);
  71. PageOffset = LfsLsnToPageOffset(_drive, Lsn);
  72. //
  73. // Read in the record header to see how big the total record
  74. // is.
  75. //
  76. if (!_attrib.Read((PVOID)&RecordHeader, ULONG(PageOffset | FileOffset),
  77. LFS_RECORD_HEADER_SIZE, &bytes_read) ||
  78. bytes_read != LFS_RECORD_HEADER_SIZE) {
  79. *pError = _drive->QueryLastNtStatus();
  80. return FALSE;
  81. }
  82. _length = LFS_RECORD_HEADER_SIZE + RecordHeader.ClientDataLength;
  83. if (NULL == (_buffer = MALLOC(_length))) {
  84. *pError = (ULONG)STATUS_INSUFFICIENT_RESOURCES;
  85. return FALSE;
  86. }
  87. RemainingLength = _length;
  88. CurrentPos = 0;
  89. while (RemainingLength > 0) {
  90. ThisPagePortion = MIN(GetLogPageSize(_drive) - PageOffset,
  91. RemainingLength);
  92. if (!_attrib.Read((PUCHAR)_buffer + CurrentPos,
  93. ULONG(FileOffset | PageOffset),
  94. ThisPagePortion, &bytes_read) ||
  95. bytes_read != ThisPagePortion) {
  96. *pError = _drive->QueryLastNtStatus();
  97. return FALSE;
  98. }
  99. CurrentPos += ThisPagePortion;
  100. RemainingLength -= ThisPagePortion;
  101. FileOffset += GetLogPageSize(_drive);
  102. PageOffset = LFS_PACKED_RECORD_PAGE_HEADER_SIZE;
  103. }
  104. return TRUE;
  105. }
  106. BOOLEAN
  107. LOG_RECORD_IO::Write(
  108. )
  109. {
  110. return FALSE;
  111. }
  112. PVOID
  113. LOG_RECORD_IO::GetBuf(
  114. OUT PULONG Size
  115. )
  116. {
  117. if (Size) {
  118. *Size = _length;
  119. }
  120. return _buffer;
  121. }
  122. PTCHAR
  123. LOG_RECORD_IO::GetHeaderText(
  124. )
  125. {
  126. return _header_text;
  127. }
  128. BOOL
  129. ReadLogRecord(
  130. IN HWND hDlg,
  131. IN UINT message,
  132. IN UINT wParam,
  133. IN LONG lParam
  134. )
  135. {
  136. UNREFERENCED_PARAMETER(lParam);
  137. TCHAR buf[1024];
  138. PTCHAR pch;
  139. INT n;
  140. switch (message) {
  141. case WM_INITDIALOG:
  142. swprintf(buf, TEXT("%x:%x"), Lsn.HighPart, Lsn.LowPart);
  143. SetDlgItemText(hDlg, IDTEXT, buf);
  144. return TRUE;
  145. case WM_COMMAND:
  146. if (LOWORD(wParam) == IDCANCEL) {
  147. EndDialog(hDlg, FALSE);
  148. return TRUE;
  149. }
  150. if (LOWORD(wParam) == IDOK) {
  151. n = GetDlgItemText(hDlg, IDTEXT, buf, sizeof(buf)/sizeof(TCHAR));
  152. buf[n] = 0;
  153. if (NULL == (pch = wcschr(buf, ':'))) {
  154. Lsn.HighPart = 0;
  155. swscanf(buf, TEXT("%x"), &Lsn.LowPart);
  156. } else {
  157. *pch = 0;
  158. swscanf(buf, TEXT("%x"), &Lsn.HighPart);
  159. swscanf(pch + 1, TEXT("%x"), &Lsn.LowPart);
  160. *pch = ':';
  161. }
  162. EndDialog(hDlg, TRUE);
  163. return TRUE;
  164. }
  165. break;
  166. }
  167. return FALSE;
  168. }