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.

1684 lines
46 KiB

  1. #include "ulib.hxx"
  2. #include "list.hxx"
  3. #include "iterator.hxx"
  4. #include "drive.hxx"
  5. #include "ifssys.hxx"
  6. #include "ntfssa.hxx"
  7. #include "frs.hxx"
  8. #include "attrib.hxx"
  9. #include "mftfile.hxx"
  10. #include "bitfrs.hxx"
  11. #include "ntfsbit.hxx"
  12. #include "upfile.hxx"
  13. #include "upcase.hxx"
  14. #include "rfatsa.hxx"
  15. #include "secio.hxx"
  16. #include "clusio.hxx"
  17. #include "frsio.hxx"
  18. #include "rootio.hxx"
  19. #include "chainio.hxx"
  20. #include "fileio.hxx"
  21. #include "logrecio.hxx"
  22. #include "secedit.hxx"
  23. #include "frsedit.hxx"
  24. #include "indxedit.hxx"
  25. #include "secstr.hxx"
  26. #include "bootedit.hxx"
  27. #include "nbedit.hxx"
  28. #include "ofsbedit.hxx"
  29. #include "partedit.hxx"
  30. #include "gptedit.hxx"
  31. #include "restarea.hxx"
  32. #include "logreced.hxx"
  33. #include "rcache.hxx"
  34. #include "hmem.hxx"
  35. #include "attrio.hxx"
  36. #include "recordpg.hxx"
  37. #include "crack.hxx"
  38. #include "atrlsted.hxx"
  39. #include "diskedit.h"
  40. extern "C" {
  41. #include <stdio.h>
  42. }
  43. DECLARE_CLASS( IO_COUPLE );
  44. class IO_COUPLE : public OBJECT {
  45. public:
  46. DECLARE_CONSTRUCTOR( IO_COUPLE );
  47. VIRTUAL
  48. ~IO_COUPLE(
  49. ) { Destroy(); };
  50. PHMEM Mem;
  51. PIO_OBJECT IoObject;
  52. PEDIT_OBJECT EditObject;
  53. PEDIT_OBJECT OtherEditObject;
  54. PEDIT_OBJECT SplitEditObject;
  55. private:
  56. NONVIRTUAL
  57. VOID
  58. Construct() {
  59. Mem = NULL;
  60. IoObject = NULL;
  61. EditObject = NULL;
  62. OtherEditObject = NULL;
  63. SplitEditObject = NULL;
  64. };
  65. NONVIRTUAL
  66. VOID
  67. Destroy(
  68. );
  69. };
  70. enum SPLIT_OPERATION {
  71. eSplitToggle,
  72. eSplitCreate,
  73. eSplitDestroy,
  74. eSplitQuery
  75. };
  76. extern BOOLEAN SplitView(HWND, SPLIT_OPERATION);
  77. DEFINE_CONSTRUCTOR( IO_COUPLE, OBJECT );
  78. VOID
  79. IO_COUPLE::Destroy(
  80. )
  81. {
  82. DELETE(Mem);
  83. DELETE(IoObject);
  84. DELETE(EditObject);
  85. DELETE(OtherEditObject);
  86. DELETE(SplitEditObject);
  87. }
  88. #define IoCoupleSetEdit(IoCouple,type,hWnd,hwndChild,ClientHeight,ClientWidth,Drive) \
  89. { \
  90. VERTICAL_TEXT_SCROLL *V = NEW type; \
  91. \
  92. do { \
  93. \
  94. if (NULL == V) { \
  95. ReportError(hwndChild, 0); \
  96. continue; \
  97. } \
  98. if (!V->Initialize(hwndChild, ClientHeight, ClientWidth, Drive)) { \
  99. DELETE(V); \
  100. ReportError(hWnd, 0); \
  101. continue; \
  102. } \
  103. \
  104. IoCouple->EditObject->KillFocus(hwndChild); \
  105. DELETE(IoCouple->OtherEditObject); \
  106. IoCouple->OtherEditObject = IoCouple->EditObject; \
  107. IoCouple->EditObject = V; \
  108. IoCouple->IoObject->GetBuf(&size); \
  109. IoCouple->EditObject->SetBuf(hwndChild, \
  110. IoCouple->IoObject->GetBuf(), size); \
  111. IoCouple->EditObject->SetFocus(hwndChild); \
  112. InvalidateRect(hwndChild, NULL, TRUE); \
  113. \
  114. if (NULL != hwndSplit) { \
  115. if (NULL == (V = NEW type)) { \
  116. ReportError(hwndSplit, 0); \
  117. continue; \
  118. } \
  119. if (!V->Initialize(hwndSplit, ClientHeight, \
  120. ClientWidth, Drive)) { \
  121. DELETE(V); \
  122. ReportError(hWnd, 0); \
  123. continue; \
  124. } \
  125. \
  126. IoCouple->SplitEditObject = V; \
  127. IoCouple->IoObject->GetBuf(&size); \
  128. IoCouple->SplitEditObject->SetBuf(hwndSplit, \
  129. IoCouple->IoObject->GetBuf(), size); \
  130. } \
  131. } while ( 0 ); \
  132. }
  133. PLOG_IO_DP_DRIVE Drive = NULL;
  134. LSN Lsn;
  135. STATIC HINSTANCE hInst;
  136. STATIC PIO_COUPLE IoCouple = NULL;
  137. STATIC PLIST IoList = NULL;
  138. STATIC PITERATOR IoListIterator = NULL;
  139. STATIC INT ClientHeight = 0;
  140. STATIC INT ClientWidth = 0;
  141. STATIC INT BacktrackFileNumber;
  142. BOOLEAN
  143. DbgOutput(
  144. PCHAR Stuff
  145. )
  146. {
  147. OutputDebugStringA(Stuff);
  148. return TRUE;
  149. }
  150. VOID
  151. ReportError(
  152. IN HWND hWnd,
  153. IN ULONG Error
  154. )
  155. {
  156. FARPROC lpProc;
  157. TCHAR message[64];
  158. lpProc = MakeProcInstance((FARPROC) About, hInst);
  159. DialogBox(hInst, TEXT("ErrorBox"), hWnd, (DLGPROC) lpProc);
  160. FreeProcInstance(lpProc);
  161. if (0 != Error) {
  162. wsprintf(message, TEXT("Error code: 0x%x\n"), Error);
  163. MessageBox(hWnd, message, TEXT("Error Information"), MB_OK|MB_ICONINFORMATION);
  164. }
  165. }
  166. INT
  167. WinMain(
  168. IN HINSTANCE hInstance,
  169. IN HINSTANCE hPrevInstance,
  170. IN LPSTR lpCmdLine,
  171. IN INT nCmdShow
  172. )
  173. {
  174. MSG msg;
  175. HACCEL hAccel;
  176. HWND hWnd;
  177. HICON hIcon;
  178. if (!hPrevInstance && !InitApplication(hInstance)) {
  179. return FALSE;
  180. }
  181. if (!InitInstance(hInstance, nCmdShow, &hWnd, &hAccel)) {
  182. return FALSE;
  183. }
  184. while (GetMessage(&msg, NULL, NULL, NULL)) {
  185. if (!TranslateAccelerator(hWnd, hAccel, &msg)) {
  186. TranslateMessage(&msg);
  187. DispatchMessage(&msg);
  188. }
  189. }
  190. return (int)msg.wParam;
  191. }
  192. BOOLEAN
  193. InitApplication(
  194. IN HINSTANCE hInstance
  195. )
  196. {
  197. WNDCLASS wc;
  198. //
  199. // Class for the normal viewing window
  200. //
  201. wc.style = NULL;
  202. wc.lpfnWndProc = ChildWndProc;
  203. wc.cbClsExtra = 0;
  204. wc.cbWndExtra = 0;
  205. wc.hInstance = hInstance;
  206. wc.hIcon = LoadIcon(hInstance, TEXT("diskedit"));
  207. wc.hCursor = LoadCursor(NULL, IDC_ARROW);
  208. wc.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH);
  209. wc.lpszMenuName = NULL;
  210. wc.lpszClassName = TEXT("ChildWinClass");
  211. if (0 == RegisterClass(&wc))
  212. return 0;
  213. //
  214. // Class for the split, byte-view window.
  215. //
  216. wc.style = NULL;
  217. wc.lpfnWndProc = SplitWndProc;
  218. wc.cbClsExtra = 0;
  219. wc.cbWndExtra = 0;
  220. wc.hInstance = hInstance;
  221. wc.hIcon = NULL;
  222. wc.hCursor = LoadCursor(NULL, IDC_ARROW);
  223. wc.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH);
  224. wc.lpszMenuName = NULL;
  225. wc.lpszClassName = TEXT("SplitWinClass");
  226. if (0 == RegisterClass(&wc))
  227. return 0;
  228. //
  229. // Class for the parent window.
  230. //
  231. wc.style = NULL;
  232. wc.lpfnWndProc = MainWndProc;
  233. wc.cbClsExtra = 0;
  234. wc.cbWndExtra = 0;
  235. wc.hInstance = hInstance;
  236. wc.hIcon = LoadIcon(hInstance, TEXT("diskedit"));
  237. wc.hCursor = LoadCursor(NULL, IDC_ARROW);
  238. wc.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH);
  239. wc.lpszMenuName = TEXT("DiskEditMenu");
  240. wc.lpszClassName = TEXT("DiskEditWinClass");
  241. if (0 == RegisterClass(&wc))
  242. return 0;
  243. return 1;
  244. }
  245. BOOLEAN
  246. InitInstance(
  247. IN HINSTANCE hInstance,
  248. IN INT nCmdShow,
  249. OUT HWND* phWnd,
  250. OUT HACCEL* hAccel
  251. )
  252. {
  253. HDC hdc;
  254. TEXTMETRIC textmetric;
  255. hInst = hInstance;
  256. hdc = GetDC(NULL);
  257. if (hdc == NULL)
  258. return FALSE;
  259. SelectObject(hdc, GetStockObject(ANSI_FIXED_FONT));
  260. GetTextMetrics(hdc, &textmetric);
  261. ReleaseDC(NULL, hdc);
  262. *phWnd = CreateWindow(
  263. TEXT("DiskEditWinClass"),
  264. TEXT("DiskEdit"),
  265. WS_OVERLAPPEDWINDOW,
  266. CW_USEDEFAULT,
  267. CW_USEDEFAULT,
  268. 84*textmetric.tmMaxCharWidth,
  269. 36*(textmetric.tmExternalLeading + textmetric.tmHeight),
  270. NULL,
  271. NULL,
  272. hInstance,
  273. NULL
  274. );
  275. if (NULL == *phWnd) {
  276. return FALSE;
  277. }
  278. *hAccel = (HACCEL) LoadAccelerators(hInst, TEXT("DiskEditAccel"));
  279. ShowWindow(*phWnd, nCmdShow);
  280. UpdateWindow(*phWnd);
  281. return TRUE;
  282. }
  283. BOOL
  284. FrsNumberDialogProc(
  285. IN HWND hDlg,
  286. IN UINT message,
  287. IN WPARAM wParam,
  288. IN LPARAM lParam
  289. )
  290. /*++
  291. Routine Description:
  292. This is the dialog procedure for the dialog box which queries
  293. an FRS number to backtrack.
  294. Arguments:
  295. hDlg -- identifies the dialog box
  296. message -- supplies the message ID received by the dialog box
  297. wParam -- message-type-dependent parameter
  298. lParam -- message-type-dependent parameter
  299. Returns:
  300. TRUE if this procedure handled the message, FALSE if it
  301. did not.
  302. --*/
  303. {
  304. UNREFERENCED_PARAMETER(lParam);
  305. switch (message) {
  306. case WM_INITDIALOG:
  307. return TRUE;
  308. case WM_COMMAND:
  309. if (LOWORD(wParam) == IDCANCEL) {
  310. EndDialog(hDlg, FALSE);
  311. return TRUE;
  312. }
  313. if (LOWORD(wParam) == IDOK) {
  314. TCHAR buf[1024];
  315. INT n;
  316. n = GetDlgItemText(hDlg, IDTEXT, buf, sizeof(buf)/sizeof(TCHAR));
  317. buf[n] = 0;
  318. swscanf(buf, TEXT("%x"), &BacktrackFileNumber);
  319. EndDialog(hDlg, TRUE);
  320. return TRUE;
  321. }
  322. break;
  323. }
  324. return FALSE;
  325. }
  326. STATIC HWND hwndChild = NULL;
  327. STATIC HWND hwndSplit = NULL;
  328. LRESULT
  329. MainWndProc(
  330. IN HWND hWnd,
  331. IN UINT message,
  332. IN WPARAM wParam,
  333. IN LPARAM lParam
  334. )
  335. {
  336. FARPROC lpProc;
  337. HDC hDC;
  338. PAINTSTRUCT ps;
  339. PDOS_BOOT_EDIT boot_edit;
  340. PNTFS_BOOT_EDIT ntboot_edit;
  341. PPARTITION_TABLE_EDIT part_edit;
  342. PGUID_PARTITION_TABLE_EDIT guid_part_edit;
  343. PRESTART_AREA_EDIT rest_area_edit;
  344. PRECORD_PAGE_EDIT rec_page_edit;
  345. PLOG_RECORD_EDIT log_rec_edit;
  346. ULONG size;
  347. WORD command;
  348. BOOLEAN error;
  349. ULONG error_status = 0;
  350. PIO_COUPLE next_couple;
  351. PEDIT_OBJECT tmp_edit;
  352. switch (message) {
  353. case WM_SETFOCUS:
  354. IoCouple->EditObject->SetFocus(hwndChild);
  355. break;
  356. case WM_CREATE:
  357. if (!DEFINE_CLASS_DESCRIPTOR( IO_COUPLE ) ||
  358. !(IoCouple = NEW IO_COUPLE) ||
  359. !(IoCouple->IoObject = NEW IO_OBJECT) ||
  360. !(IoCouple->EditObject = NEW EDIT_OBJECT) ||
  361. !(IoCouple->OtherEditObject = NEW EDIT_OBJECT) ||
  362. !(IoList = NEW LIST) ||
  363. !IoList->Initialize() ||
  364. !IoList->Put((POBJECT) IoCouple) ||
  365. !(IoListIterator = IoList->QueryIterator()) ||
  366. !IoListIterator->GetNext()) {
  367. PostQuitMessage(0);
  368. }
  369. hwndChild = CreateWindow(
  370. TEXT("ChildWinClass"),
  371. TEXT("PrimaryView"),
  372. WS_CHILD|WS_CLIPSIBLINGS|WS_VISIBLE,
  373. 0, 0,
  374. ClientWidth, ClientHeight,
  375. hWnd,
  376. NULL,
  377. hInst,
  378. NULL
  379. );
  380. if (NULL == hwndChild) {
  381. int error = GetLastError();
  382. PostQuitMessage(0);
  383. }
  384. ShowWindow(hwndChild, SW_SHOW);
  385. UpdateWindow(hwndChild);
  386. SetWindowPos(hwndChild, HWND_TOP, 0, 0, ClientWidth, ClientHeight,
  387. SWP_SHOWWINDOW);
  388. break;
  389. case WM_SIZE:
  390. ClientHeight = HIWORD(lParam);
  391. ClientWidth = LOWORD(lParam);
  392. if (NULL == hwndSplit) {
  393. IoCouple->EditObject->ClientSize(ClientHeight, ClientWidth);
  394. SetWindowPos(hwndChild, HWND_TOP, 0, 0, ClientWidth, ClientHeight,
  395. SWP_SHOWWINDOW);
  396. } else {
  397. IoCouple->EditObject->ClientSize(ClientHeight, ClientWidth / 2);
  398. IoCouple->SplitEditObject->ClientSize(ClientHeight, ClientWidth / 2);
  399. SetWindowPos(hwndChild, HWND_TOP, 0, 0, ClientWidth / 2,
  400. ClientHeight, SWP_SHOWWINDOW);
  401. SetWindowPos(hwndSplit, HWND_TOP, ClientWidth / 2, 0,
  402. ClientWidth / 2, ClientHeight, SWP_SHOWWINDOW);
  403. }
  404. break;
  405. case WM_COMMAND:
  406. switch (LOWORD(wParam)) {
  407. case IDM_ABOUT:
  408. lpProc = MakeProcInstance((FARPROC) About, hInst);
  409. DialogBox(hInst, TEXT("AboutBox"), hWnd, (DLGPROC) lpProc);
  410. FreeProcInstance(lpProc);
  411. break;
  412. case IDM_EXIT:
  413. DestroyWindow(hWnd);
  414. break;
  415. case IDM_OPEN:
  416. lpProc = MakeProcInstance((FARPROC) OpenVolume, hInst);
  417. if (!DialogBox(hInst, TEXT("OpenVolumeBox"), hWnd, (DLGPROC) lpProc)) {
  418. ReportError(hWnd, 0);
  419. }
  420. FreeProcInstance(lpProc);
  421. SplitView(hWnd, eSplitDestroy);
  422. IoCouple->EditObject->KillFocus(hwndChild);
  423. IoListIterator->Reset();
  424. IoList->DeleteAllMembers();
  425. if (!(IoCouple = NEW IO_COUPLE) ||
  426. !(IoCouple->IoObject = NEW IO_OBJECT) ||
  427. !(IoCouple->EditObject = NEW EDIT_OBJECT) ||
  428. !(IoCouple->OtherEditObject = NEW EDIT_OBJECT) ||
  429. !IoList->Initialize() ||
  430. !IoList->Put(IoCouple) ||
  431. !IoListIterator->GetNext()) {
  432. PostQuitMessage(0);
  433. }
  434. SetWindowText(hWnd, TEXT("DiskEdit"));
  435. InvalidateRect(hWnd, NULL, TRUE);
  436. InvalidateRect(hwndChild, NULL, TRUE);
  437. break;
  438. case IDM_READ_SECTORS:
  439. case IDM_READ_CLUSTERS:
  440. case IDM_READ_FRS:
  441. case IDM_READ_ROOT:
  442. case IDM_READ_CHAIN:
  443. case IDM_READ_FILE:
  444. case IDM_READ_ATTRIBUTE:
  445. case IDM_READ_LOG_RECORD:
  446. if (!(next_couple = NEW IO_COUPLE)) {
  447. break;
  448. }
  449. switch (LOWORD(wParam)) {
  450. case IDM_READ_SECTORS:
  451. next_couple->IoObject = NEW SECTOR_IO;
  452. command = IDM_VIEW_BYTES;
  453. break;
  454. case IDM_READ_CLUSTERS:
  455. next_couple->IoObject = NEW CLUSTER_IO;
  456. command = IDM_VIEW_BYTES;
  457. break;
  458. case IDM_READ_FRS:
  459. next_couple->IoObject = NEW FRS_IO;
  460. command = IDM_VIEW_FRS;
  461. break;
  462. case IDM_READ_ATTRIBUTE:
  463. next_couple->IoObject = NEW ATTR_IO;
  464. command = IDM_VIEW_BYTES;
  465. break;
  466. case IDM_READ_LOG_RECORD:
  467. next_couple->IoObject = NEW LOG_RECORD_IO;
  468. command = IDM_VIEW_LOG_RECORD;
  469. break;
  470. case IDM_READ_ROOT:
  471. next_couple->IoObject = NEW ROOT_IO;
  472. command = IDM_VIEW_BYTES;
  473. break;
  474. case IDM_READ_CHAIN:
  475. next_couple->IoObject = NEW CHAIN_IO;
  476. command = IDM_VIEW_BYTES;
  477. break;
  478. case IDM_READ_FILE:
  479. next_couple->IoObject = NEW FILE_IO;
  480. command = IDM_VIEW_BYTES;
  481. break;
  482. default:
  483. next_couple->IoObject = NULL;
  484. break;
  485. }
  486. error = TRUE;
  487. if (next_couple->IoObject && (next_couple->Mem = NEW HMEM) &&
  488. next_couple->Mem->Initialize() &&
  489. next_couple->IoObject->Setup(next_couple->Mem,
  490. Drive, hInst, hwndChild, &error) &&
  491. next_couple->IoObject->Read(&error_status) &&
  492. (next_couple->EditObject = NEW EDIT_OBJECT) &&
  493. (next_couple->OtherEditObject = NEW EDIT_OBJECT) &&
  494. IoList->Put(next_couple)) {
  495. if (NULL != hwndSplit) {
  496. next_couple->SplitEditObject = NEW EDIT_OBJECT;
  497. if (NULL == next_couple->SplitEditObject) {
  498. DELETE(next_couple);
  499. break;
  500. }
  501. }
  502. IoCouple->EditObject->KillFocus(hwndChild);
  503. IoCouple = next_couple;
  504. IoCouple->EditObject->SetFocus(hwndChild);
  505. IoListIterator->Reset();
  506. IoListIterator->GetPrevious();
  507. SetWindowText(hWnd, IoCouple->IoObject->GetHeaderText());
  508. SendMessage(hWnd, WM_COMMAND, command, 0);
  509. if (NULL != hwndSplit) {
  510. SendMessage(hwndSplit, WM_COMMAND, command, 0);
  511. }
  512. } else {
  513. if (error) {
  514. ReportError(hWnd, error_status);
  515. }
  516. DELETE(next_couple);
  517. }
  518. break;
  519. case IDM_READ_PREVIOUS:
  520. if (NULL != IoListIterator->GetPrevious()) {
  521. IoCouple->EditObject->KillFocus(hwndChild);
  522. IoCouple = (PIO_COUPLE)IoListIterator->GetCurrent();
  523. IoCouple->EditObject->SetFocus(hwndChild);
  524. InvalidateRect(hWnd, NULL, TRUE);
  525. if (NULL != IoCouple->SplitEditObject && NULL == hwndSplit) {
  526. SplitView(hwndChild, eSplitCreate);
  527. InvalidateRect(hwndSplit, NULL, TRUE);
  528. }
  529. if (NULL == IoCouple->SplitEditObject && NULL != hwndSplit) {
  530. SplitView(hwndChild, eSplitDestroy);
  531. }
  532. SetWindowText(hWnd, IoCouple->IoObject->GetHeaderText());
  533. } else {
  534. ReportError(hwndChild, 0);
  535. IoListIterator->GetNext();
  536. }
  537. break;
  538. case IDM_READ_NEXT:
  539. if (IoListIterator->GetNext()) {
  540. IoCouple->EditObject->KillFocus(hwndChild);
  541. IoCouple = (PIO_COUPLE) IoListIterator->GetCurrent();
  542. IoCouple->EditObject->SetFocus(hwndChild);
  543. InvalidateRect(hwndChild, NULL, TRUE);
  544. if (NULL != IoCouple->SplitEditObject && NULL == hwndSplit) {
  545. SplitView(hwndChild, eSplitCreate);
  546. InvalidateRect(hwndSplit, NULL, TRUE);
  547. }
  548. if (NULL == IoCouple->SplitEditObject && NULL != hwndSplit) {
  549. SplitView(hwndChild, eSplitDestroy);
  550. }
  551. SetWindowText(hWnd, IoCouple->IoObject->GetHeaderText());
  552. } else {
  553. ReportError(hwndChild, 0);
  554. IoListIterator->GetPrevious();
  555. }
  556. break;
  557. case IDM_READ_REMOVE:
  558. if (IoList->QueryMemberCount() > 1) {
  559. IoCouple->EditObject->KillFocus(hwndChild);
  560. IoCouple = (PIO_COUPLE) IoList->Remove(IoListIterator);
  561. DELETE(IoCouple);
  562. IoCouple = (PIO_COUPLE) IoListIterator->GetCurrent();
  563. if (!IoCouple) {
  564. IoCouple = (PIO_COUPLE) IoListIterator->GetPrevious();
  565. }
  566. IoCouple->EditObject->SetFocus(hwndChild);
  567. InvalidateRect(hwndChild, NULL, TRUE);
  568. SetWindowText(hWnd, IoCouple->IoObject->GetHeaderText());
  569. }
  570. break;
  571. case IDM_RELOCATE_SECTORS:
  572. case IDM_RELOCATE_CLUSTERS:
  573. case IDM_RELOCATE_FRS:
  574. case IDM_RELOCATE_ROOT:
  575. case IDM_RELOCATE_CHAIN:
  576. case IDM_RELOCATE_FILE:
  577. IoCouple->IoObject->GetBuf(&size);
  578. DELETE(IoCouple->IoObject);
  579. switch (LOWORD(wParam)) {
  580. case IDM_RELOCATE_SECTORS:
  581. IoCouple->IoObject = NEW SECTOR_IO;
  582. command = IDM_VIEW_BYTES;
  583. break;
  584. case IDM_RELOCATE_CLUSTERS:
  585. IoCouple->IoObject = NEW CLUSTER_IO;
  586. command = IDM_VIEW_BYTES;
  587. break;
  588. case IDM_RELOCATE_FRS:
  589. IoCouple->IoObject = NEW FRS_IO;
  590. command = IDM_VIEW_FRS;
  591. break;
  592. case IDM_RELOCATE_ROOT:
  593. IoCouple->IoObject = NEW ROOT_IO;
  594. command = IDM_VIEW_BYTES;
  595. break;
  596. case IDM_RELOCATE_CHAIN:
  597. IoCouple->IoObject = NEW CHAIN_IO;
  598. command = IDM_VIEW_BYTES;
  599. break;
  600. case IDM_RELOCATE_FILE:
  601. IoCouple->IoObject = NEW FILE_IO;
  602. if (IoCouple->IoObject) {
  603. if (!((PFILE_IO) IoCouple->IoObject)->Initialize(size)) {
  604. DELETE(IoCouple->IoObject);
  605. }
  606. }
  607. command = IDM_VIEW_BYTES;
  608. break;
  609. default:
  610. IoCouple->IoObject = NULL;
  611. break;
  612. }
  613. error = TRUE;
  614. if (IoCouple->IoObject && IoCouple->IoObject->Setup(IoCouple->Mem,
  615. Drive, hInst, hwndChild, &error)) {
  616. SetWindowText(hWnd, IoCouple->IoObject->GetHeaderText());
  617. } else {
  618. if (error) {
  619. ReportError(hWnd, 0);
  620. }
  621. }
  622. break;
  623. case IDM_VIEW_BYTES:
  624. IoCoupleSetEdit( IoCouple,
  625. SECTOR_EDIT,
  626. hWnd, hwndChild,
  627. ClientHeight, ClientWidth,
  628. Drive );
  629. break;
  630. case IDM_VIEW_FRS:
  631. IoCoupleSetEdit( IoCouple,
  632. FRS_EDIT,
  633. hWnd, hwndChild,
  634. ClientHeight, ClientWidth,
  635. Drive );
  636. break;
  637. case IDM_VIEW_ATTR_LIST:
  638. IoCoupleSetEdit( IoCouple,
  639. ATTR_LIST_EDIT,
  640. hWnd, hwndChild,
  641. ClientHeight, ClientWidth,
  642. Drive );
  643. break;
  644. case IDM_VIEW_NTFS_INDEX:
  645. IoCoupleSetEdit( IoCouple,
  646. NAME_INDEX_BUFFER_EDIT,
  647. hWnd, hwndChild,
  648. ClientHeight, ClientWidth,
  649. Drive );
  650. break;
  651. case IDM_VIEW_NTFS_SECURITY_ID:
  652. IoCoupleSetEdit( IoCouple,
  653. SECURITY_ID_INDEX_BUFFER_EDIT,
  654. hWnd, hwndChild,
  655. ClientHeight, ClientWidth,
  656. Drive );
  657. break;
  658. case IDM_VIEW_NTFS_SECURITY_HASH:
  659. IoCoupleSetEdit( IoCouple,
  660. SECURITY_HASH_INDEX_BUFFER_EDIT,
  661. hWnd, hwndChild,
  662. ClientHeight, ClientWidth,
  663. Drive );
  664. break;
  665. case IDM_VIEW_NTFS_SECURITY_STREAM:
  666. IoCoupleSetEdit( IoCouple,
  667. SECURITY_STREAM_EDIT,
  668. hWnd, hwndChild,
  669. ClientHeight, ClientWidth,
  670. Drive );
  671. break;
  672. case IDM_VIEW_FAT_BOOT:
  673. if (NULL == (boot_edit = NEW DOS_BOOT_EDIT)) {
  674. ReportError(hwndChild, 0);
  675. break;
  676. }
  677. IoCouple->EditObject->KillFocus(hwndChild);
  678. DELETE(IoCouple->OtherEditObject);
  679. IoCouple->OtherEditObject = IoCouple->EditObject;
  680. IoCouple->EditObject = boot_edit;
  681. IoCouple->IoObject->GetBuf(&size);
  682. IoCouple->EditObject->SetBuf(hwndChild,
  683. IoCouple->IoObject->GetBuf(), size);
  684. IoCouple->EditObject->SetFocus(hwndChild);
  685. InvalidateRect(hwndChild, NULL, TRUE);
  686. break;
  687. case IDM_VIEW_NTFS_BOOT:
  688. if (ntboot_edit = NEW NTFS_BOOT_EDIT) {
  689. IoCouple->EditObject->KillFocus(hwndChild);
  690. DELETE(IoCouple->OtherEditObject);
  691. IoCouple->OtherEditObject = IoCouple->EditObject;
  692. IoCouple->EditObject = ntboot_edit;
  693. IoCouple->IoObject->GetBuf(&size);
  694. IoCouple->EditObject->SetBuf(hwndChild,
  695. IoCouple->IoObject->GetBuf(), size);
  696. IoCouple->EditObject->SetFocus(hwndChild);
  697. InvalidateRect(hwndChild, NULL, TRUE);
  698. } else {
  699. DELETE(ntboot_edit);
  700. ReportError(hWnd, 0);
  701. }
  702. break;
  703. case IDM_VIEW_PARTITION_TABLE:
  704. if ( (part_edit = NEW PARTITION_TABLE_EDIT) &&
  705. part_edit->Initialize(hwndChild, ClientHeight, ClientWidth, Drive)) {
  706. IoCouple->EditObject->KillFocus(hwndChild);
  707. DELETE(IoCouple->OtherEditObject);
  708. IoCouple->OtherEditObject = IoCouple->EditObject;
  709. IoCouple->EditObject = part_edit;
  710. IoCouple->IoObject->GetBuf(&size);
  711. IoCouple->EditObject->SetBuf(hwndChild,
  712. IoCouple->IoObject->GetBuf(), size);
  713. IoCouple->EditObject->SetFocus(hwndChild);
  714. InvalidateRect(hwndChild, NULL, TRUE);
  715. } else {
  716. DELETE( part_edit );
  717. ReportError(hWnd, 0);
  718. }
  719. break;
  720. case IDM_VIEW_GPT:
  721. if ( (guid_part_edit = NEW GUID_PARTITION_TABLE_EDIT) &&
  722. guid_part_edit->Initialize(hwndChild, ClientHeight, ClientWidth, Drive)) {
  723. IoCouple->EditObject->KillFocus(hwndChild);
  724. DELETE(IoCouple->OtherEditObject);
  725. IoCouple->OtherEditObject = IoCouple->EditObject;
  726. IoCouple->EditObject = guid_part_edit;
  727. IoCouple->IoObject->GetBuf(&size);
  728. IoCouple->EditObject->SetBuf(hwndChild,
  729. IoCouple->IoObject->GetBuf(), size);
  730. IoCouple->EditObject->SetFocus(hwndChild);
  731. InvalidateRect(hwndChild, NULL, TRUE);
  732. } else {
  733. DELETE( guid_part_edit );
  734. ReportError(hWnd, 0);
  735. }
  736. break;
  737. case IDM_VIEW_RESTART_AREA:
  738. if ((rest_area_edit = NEW RESTART_AREA_EDIT) &&
  739. rest_area_edit->Initialize(hwndChild, ClientHeight, ClientWidth, Drive )) {
  740. IoCouple->EditObject->KillFocus(hwndChild);
  741. DELETE(IoCouple->OtherEditObject);
  742. IoCouple->OtherEditObject = IoCouple->EditObject;
  743. IoCouple->EditObject = rest_area_edit;
  744. IoCouple->IoObject->GetBuf(&size);
  745. IoCouple->EditObject->SetBuf(hwndChild,
  746. IoCouple->IoObject->GetBuf(), size);
  747. IoCouple->EditObject->SetFocus(hwndChild);
  748. InvalidateRect(hwndChild, NULL, TRUE);
  749. } else {
  750. DELETE(rest_area_edit);
  751. ReportError(hWnd, 0);
  752. }
  753. break;
  754. case IDM_VIEW_RECORD_PAGE:
  755. if ((rec_page_edit = NEW RECORD_PAGE_EDIT) &&
  756. rec_page_edit->Initialize(hwndChild, ClientHeight, ClientWidth, Drive)) {
  757. IoCouple->EditObject->KillFocus(hwndChild);
  758. DELETE(IoCouple->OtherEditObject);
  759. IoCouple->OtherEditObject = IoCouple->EditObject;
  760. IoCouple->EditObject = rec_page_edit;
  761. IoCouple->IoObject->GetBuf(&size);
  762. IoCouple->EditObject->SetBuf(hwndChild,
  763. IoCouple->IoObject->GetBuf(), size);
  764. IoCouple->EditObject->SetFocus(hwndChild);
  765. InvalidateRect(hwndChild, NULL, TRUE);
  766. } else {
  767. DELETE(rec_page_edit);
  768. ReportError(hWnd, 0);
  769. }
  770. break;
  771. case IDM_VIEW_LOG_RECORD:
  772. if ((log_rec_edit = NEW LOG_RECORD_EDIT) &&
  773. log_rec_edit->Initialize(hwndChild, ClientHeight,
  774. ClientWidth, Drive)) {
  775. IoCouple->EditObject->KillFocus(hwndChild);
  776. DELETE(IoCouple->OtherEditObject);
  777. IoCouple->OtherEditObject = IoCouple->EditObject;
  778. IoCouple->EditObject = log_rec_edit;
  779. IoCouple->IoObject->GetBuf(&size);
  780. IoCouple->EditObject->SetBuf(hwndChild,
  781. IoCouple->IoObject->GetBuf(), size);
  782. IoCouple->EditObject->SetFocus(hwndChild);
  783. InvalidateRect(hwndChild, NULL, TRUE);
  784. } else {
  785. DELETE(log_rec_edit);
  786. ReportError(hWnd, 0);
  787. }
  788. break;
  789. case IDM_VIEW_LAST:
  790. IoCouple->EditObject->KillFocus(hwndChild);
  791. tmp_edit = IoCouple->EditObject;
  792. IoCouple->EditObject = IoCouple->OtherEditObject;
  793. IoCouple->OtherEditObject = tmp_edit;
  794. IoCouple->EditObject->SetFocus(hwndChild);
  795. InvalidateRect(hwndChild, NULL, TRUE);
  796. break;
  797. case IDM_VIEW_SPLIT:
  798. SplitView(hWnd, eSplitToggle);
  799. break;
  800. case IDM_WRITE_IT:
  801. if (!IoCouple->IoObject->Write()) {
  802. ReportError(hWnd, 0);
  803. }
  804. break;
  805. case IDM_CRACK_NTFS:
  806. lpProc = MakeProcInstance((FARPROC)InputPath, hInst);
  807. if (DialogBox(hInst, TEXT("InputPathBox"), hWnd, (DLGPROC)lpProc)) {
  808. CrackNtfsPath(hWnd);
  809. }
  810. FreeProcInstance(lpProc);
  811. break;
  812. case IDM_CRACK_FAT:
  813. lpProc = MakeProcInstance((FARPROC)InputPath, hInst);
  814. if (DialogBox(hInst, TEXT("InputPathBox"), hWnd, (DLGPROC)lpProc)) {
  815. CrackFatPath(hWnd);
  816. }
  817. FreeProcInstance(lpProc);
  818. break;
  819. case IDM_CRACK_LSN:
  820. lpProc = MakeProcInstance((FARPROC)InputLsn, hInst);
  821. if (DialogBox(hInst, TEXT("CrackLsnBox"), hWnd, (DLGPROC)lpProc)) {
  822. CrackLsn(hWnd);
  823. }
  824. FreeProcInstance(lpProc);
  825. break;
  826. case IDM_CRACK_NEXT_LSN:
  827. lpProc = MakeProcInstance((FARPROC)InputLsn, hInst);
  828. if (DialogBox(hInst, TEXT("CrackNextLsnBox"), hWnd, (DLGPROC)lpProc)) {
  829. CrackNextLsn(hWnd);
  830. }
  831. FreeProcInstance(lpProc);
  832. break;
  833. case IDM_BACKTRACK_FRS:
  834. lpProc = MakeProcInstance((FARPROC)FrsNumberDialogProc, hInst);
  835. if (DialogBox(hInst, TEXT("BacktrackFrsBox"), hWnd, (DLGPROC)lpProc)) {
  836. BacktrackFrsFromScratch(hWnd, BacktrackFileNumber);
  837. }
  838. FreeProcInstance(lpProc);
  839. break;
  840. default:
  841. return DefWindowProc(hWnd, message, wParam, lParam);
  842. }
  843. break;
  844. case WM_PAINT:
  845. hDC = BeginPaint(hWnd, &ps);
  846. EndPaint(hWnd, &ps);
  847. break;
  848. case WM_DESTROY:
  849. IoCouple->EditObject->KillFocus(hwndChild);
  850. IoList->DeleteAllMembers();
  851. DELETE(IoListIterator);
  852. DELETE(IoList);
  853. DELETE(Drive);
  854. PostQuitMessage(0);
  855. break;
  856. default:
  857. return DefWindowProc(hWnd, message, wParam, lParam);
  858. }
  859. return 0;
  860. }
  861. BOOL
  862. About(
  863. IN HWND hDlg,
  864. IN UINT message,
  865. IN UINT wParam,
  866. IN LONG lParam
  867. )
  868. {
  869. switch (message) {
  870. case WM_INITDIALOG:
  871. return TRUE;
  872. case WM_COMMAND:
  873. if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL) {
  874. EndDialog(hDlg, TRUE);
  875. return TRUE;
  876. }
  877. break;
  878. }
  879. return FALSE;
  880. }
  881. BOOL
  882. OpenVolume(
  883. IN HWND hDlg,
  884. IN UINT message,
  885. IN UINT wParam,
  886. IN LONG lParam
  887. )
  888. {
  889. PREAD_CACHE rcache;
  890. switch (message) {
  891. case WM_INITDIALOG:
  892. return TRUE;
  893. case WM_COMMAND:
  894. if (LOWORD(wParam) == IDCANCEL) {
  895. EndDialog(hDlg, TRUE);
  896. return TRUE;
  897. }
  898. if (LOWORD(wParam) == IDOK) {
  899. DSTRING dos_name, nt_name, tmp_name;
  900. DSTRING volfile_name, volfile_path, backslash;
  901. TCHAR volume_buf[32];
  902. TCHAR volfile_buf[32];
  903. INT n;
  904. n = GetDlgItemText(hDlg, IDTEXT, volume_buf, sizeof(volume_buf)/sizeof(TCHAR));
  905. volume_buf[n] = 0;
  906. n = GetDlgItemText(hDlg, IDTEXT2, volfile_buf, sizeof(volfile_buf)/sizeof(TCHAR));
  907. volfile_buf[n] = 0;
  908. DELETE(Drive);
  909. if (!backslash.Initialize("\\") ||
  910. !dos_name.Initialize(volume_buf)) {
  911. EndDialog(hDlg, FALSE);
  912. return TRUE;
  913. }
  914. if (dos_name.QueryChCount() > 0 &&
  915. dos_name.QueryChAt(0) >= '0' &&
  916. dos_name.QueryChAt(0) <= '9') {
  917. if (!nt_name.Initialize("\\device\\harddisk") ||
  918. !nt_name.Strcat(&dos_name) ||
  919. !tmp_name.Initialize("\\partition0") ||
  920. !nt_name.Strcat(&tmp_name)) {
  921. EndDialog(hDlg, FALSE);
  922. return TRUE;
  923. }
  924. } else {
  925. if (!IFS_SYSTEM::DosDriveNameToNtDriveName(&dos_name,
  926. &nt_name)) {
  927. EndDialog(hDlg, FALSE);
  928. return TRUE;
  929. }
  930. }
  931. if (!volfile_name.Initialize(volfile_buf)) {
  932. EndDialog(hDlg, FALSE);
  933. return TRUE;
  934. }
  935. if (0 != wcslen(volfile_buf)) {
  936. if (!volfile_path.Initialize(&nt_name) ||
  937. !volfile_path.Strcat(&backslash) ||
  938. !volfile_path.Strcat(&volfile_name)) {
  939. EndDialog(hDlg, FALSE);
  940. return TRUE;
  941. }
  942. if (NULL == (Drive = NEW LOG_IO_DP_DRIVE) ||
  943. !Drive->Initialize(&nt_name, &volfile_path)) {
  944. EndDialog(hDlg, FALSE);
  945. return TRUE;
  946. }
  947. } else {
  948. if (NULL == (Drive = NEW LOG_IO_DP_DRIVE) ||
  949. !Drive->Initialize(&nt_name)) {
  950. EndDialog(hDlg, FALSE);
  951. return TRUE;
  952. }
  953. }
  954. if ((rcache = NEW READ_CACHE) &&
  955. rcache->Initialize(Drive, 1024)) {
  956. Drive->SetCache(rcache);
  957. } else {
  958. DELETE(rcache);
  959. }
  960. if (IsDlgButtonChecked(hDlg, IDCHECKBOX) &&
  961. !Drive->Lock()) {
  962. EndDialog(hDlg, FALSE);
  963. return TRUE;
  964. }
  965. EndDialog(hDlg, TRUE);
  966. return TRUE;
  967. }
  968. break;
  969. }
  970. return FALSE;
  971. }
  972. BOOL
  973. InputPath(
  974. IN HWND hDlg,
  975. IN UINT message,
  976. IN UINT wParam,
  977. IN LONG lParam
  978. )
  979. {
  980. INT n;
  981. switch (message) {
  982. case WM_INITDIALOG:
  983. return TRUE;
  984. case WM_COMMAND:
  985. if (LOWORD(wParam) == IDCANCEL) {
  986. EndDialog(hDlg, FALSE);
  987. return TRUE;
  988. }
  989. if (LOWORD(wParam) == IDOK) {
  990. n = GetDlgItemText(hDlg, IDTEXT, Path, MAX_PATH/sizeof(TCHAR));
  991. Path[n] = 0;
  992. EndDialog(hDlg, TRUE);
  993. return TRUE;
  994. }
  995. break;
  996. }
  997. return FALSE;
  998. }
  999. BOOL
  1000. InputLsn(
  1001. IN HWND hDlg,
  1002. IN UINT message,
  1003. IN UINT wParam,
  1004. IN LONG lParam
  1005. )
  1006. {
  1007. INT n;
  1008. TCHAR buf[40];
  1009. PTCHAR pch;
  1010. switch (message) {
  1011. case WM_INITDIALOG:
  1012. wsprintf(buf, TEXT("%x:%x"), Lsn.HighPart, Lsn.LowPart);
  1013. SetDlgItemText(hDlg, IDTEXT, buf);
  1014. return TRUE;
  1015. case WM_COMMAND:
  1016. if (LOWORD(wParam) == IDCANCEL) {
  1017. EndDialog(hDlg, FALSE);
  1018. return TRUE;
  1019. }
  1020. if (LOWORD(wParam) == IDOK) {
  1021. n = GetDlgItemText(hDlg, IDTEXT, buf, sizeof(buf)/sizeof(TCHAR));
  1022. buf[n] = 0;
  1023. if (NULL == (pch = wcschr(buf, ':'))) {
  1024. Lsn.HighPart = 0;
  1025. swscanf(buf, TEXT("%x"), &Lsn.LowPart);
  1026. } else {
  1027. *pch = 0;
  1028. swscanf(buf, TEXT("%x"), &Lsn.HighPart);
  1029. swscanf(pch + 1, TEXT("%x"), &Lsn.LowPart);
  1030. *pch = ':';
  1031. }
  1032. EndDialog(hDlg, TRUE);
  1033. return TRUE;
  1034. }
  1035. break;
  1036. }
  1037. return FALSE;
  1038. }
  1039. static ULONG SeqNumberBits;
  1040. ULONG
  1041. GetLogPageSize(
  1042. PLOG_IO_DP_DRIVE Drive
  1043. )
  1044. {
  1045. static ULONG PageSize;
  1046. static BOOLEAN been_here = FALSE;
  1047. static UCHAR buf[0x600];
  1048. NTFS_SA NtfsSa;
  1049. MESSAGE Msg;
  1050. NTFS_MFT_FILE Mft;
  1051. NTFS_FILE_RECORD_SEGMENT Frs;
  1052. NTFS_ATTRIBUTE Attrib;
  1053. PLFS_RESTART_PAGE_HEADER pRestPageHdr;
  1054. PLFS_RESTART_AREA pRestArea;
  1055. ULONG bytes_read;
  1056. BOOLEAN error;
  1057. if (been_here) {
  1058. return PageSize;
  1059. }
  1060. pRestPageHdr = (PLFS_RESTART_PAGE_HEADER)buf;
  1061. if (!Drive ||
  1062. !NtfsSa.Initialize(Drive, &Msg) ||
  1063. !NtfsSa.Read() ||
  1064. !Mft.Initialize(Drive, NtfsSa.QueryMftStartingLcn(),
  1065. NtfsSa.QueryClusterFactor(), NtfsSa.QueryFrsSize(),
  1066. NtfsSa.QueryVolumeSectors(), NULL, NULL) ||
  1067. !Mft.Read() ||
  1068. !Frs.Initialize((VCN)LOG_FILE_NUMBER, &Mft) ||
  1069. !Frs.Read() ||
  1070. !Frs.QueryAttribute(&Attrib, &error, $DATA) ||
  1071. !Attrib.Read((PVOID)pRestPageHdr, 0, 0x600,
  1072. &bytes_read) ||
  1073. bytes_read != 0x600) {
  1074. return 0;
  1075. }
  1076. PageSize = pRestPageHdr->LogPageSize;
  1077. pRestArea = PLFS_RESTART_AREA(PUCHAR(pRestPageHdr) + pRestPageHdr->RestartOffset);
  1078. SeqNumberBits = pRestArea->SeqNumberBits;
  1079. been_here = 1;
  1080. return PageSize;
  1081. }
  1082. ULONG
  1083. GetSeqNumberBits(
  1084. PLOG_IO_DP_DRIVE Drive
  1085. )
  1086. {
  1087. (void)GetLogPageSize(Drive);
  1088. return SeqNumberBits;
  1089. }
  1090. BOOLEAN
  1091. SplitView(
  1092. HWND hWnd,
  1093. SPLIT_OPERATION Op
  1094. )
  1095. {
  1096. static BOOLEAN CheckState = FALSE;
  1097. int flags;
  1098. PSECTOR_EDIT sector_edit;
  1099. CREATESTRUCT cs;
  1100. ULONG size;
  1101. HMENU hMenu = GetMenu(hWnd);
  1102. if (Op == eSplitToggle) {
  1103. CheckState = !CheckState;
  1104. } else if (Op == eSplitCreate) {
  1105. CheckState = TRUE;
  1106. } else if (Op == eSplitDestroy) {
  1107. CheckState = FALSE;
  1108. } else if (Op == eSplitQuery) {
  1109. DebugAssert(hWnd == NULL);
  1110. return CheckState;
  1111. } else {
  1112. return FALSE;
  1113. }
  1114. if (!CheckState) {
  1115. // Destroy the extra window, remove the checkbox from
  1116. // the menu entry.
  1117. if (NULL == hwndSplit) {
  1118. return 0;
  1119. }
  1120. DestroyWindow(hwndSplit);
  1121. hwndSplit = NULL;
  1122. flags = MF_BYCOMMAND | MF_UNCHECKED;
  1123. if (hMenu == NULL) {
  1124. return FALSE;
  1125. }
  1126. CheckMenuItem(hMenu, IDM_VIEW_SPLIT, flags);
  1127. SetWindowPos(hwndChild, HWND_TOP, 0, 0, ClientWidth, ClientHeight,
  1128. SWP_SHOWWINDOW);
  1129. IoCouple->EditObject->SetFocus(hwndChild);
  1130. SetFocus(hwndChild);
  1131. return TRUE;
  1132. }
  1133. //
  1134. // Split the window.
  1135. //
  1136. memset(&cs, 0, sizeof(cs));
  1137. cs.y = ClientWidth / 2;
  1138. cs.x = 0;
  1139. cs.cy = ClientWidth / 2;
  1140. cs.cx = ClientHeight;
  1141. hwndSplit = CreateWindow(TEXT("SplitWinClass"), TEXT("hwndSplit"),
  1142. WS_CHILD|WS_CLIPSIBLINGS|WS_VISIBLE,
  1143. ClientWidth / 2, 0,
  1144. ClientWidth / 2, ClientHeight,
  1145. hWnd,
  1146. NULL,
  1147. hInst,
  1148. &cs);
  1149. if (NULL == hwndSplit) {
  1150. int error = GetLastError();
  1151. return FALSE;
  1152. }
  1153. SetWindowPos(hwndChild, HWND_TOP, 0, 0, ClientWidth / 2, ClientHeight,
  1154. SWP_SHOWWINDOW);
  1155. flags = MF_BYCOMMAND | MF_CHECKED;
  1156. CheckMenuItem(hMenu, IDM_VIEW_SPLIT, flags);
  1157. ShowWindow(hwndSplit, SW_SHOW);
  1158. UpdateWindow(hwndSplit);
  1159. if (NULL != IoCouple->SplitEditObject) {
  1160. // use the existing edit object
  1161. return TRUE;
  1162. }
  1163. if ((sector_edit = NEW SECTOR_EDIT) &&
  1164. sector_edit->Initialize(hwndSplit, ClientHeight, ClientWidth / 2, Drive)) {
  1165. IoCouple->SplitEditObject = sector_edit;
  1166. IoCouple->IoObject->GetBuf(&size);
  1167. IoCouple->SplitEditObject->SetBuf(hwndSplit,
  1168. IoCouple->IoObject->GetBuf(), size);
  1169. IoCouple->EditObject->SetFocus(hwndChild);
  1170. SetFocus(hwndChild);
  1171. } else {
  1172. DELETE(sector_edit);
  1173. DestroyWindow(hwndSplit);
  1174. ReportError(hWnd, 0);
  1175. }
  1176. return TRUE;
  1177. }
  1178. LRESULT
  1179. ChildWndProc(
  1180. IN HWND hwnd,
  1181. IN UINT message,
  1182. IN WPARAM wParam,
  1183. IN LPARAM lParam
  1184. )
  1185. {
  1186. FARPROC lpProc;
  1187. HDC hdc;
  1188. PAINTSTRUCT ps;
  1189. ULONG size;
  1190. WORD command;
  1191. BOOLEAN error;
  1192. ULONG error_status;
  1193. switch (message) {
  1194. default:
  1195. return DefWindowProc(hwnd, message, wParam, lParam);
  1196. case WM_PAINT:
  1197. hdc = BeginPaint(hwnd, &ps);
  1198. IoCouple->EditObject->Paint(hdc, ps.rcPaint, hwnd);
  1199. EndPaint(hwnd, &ps);
  1200. return 0;
  1201. case WM_CHAR:
  1202. IoCouple->EditObject->Character(hwnd, (CHAR)wParam);
  1203. break;
  1204. case WM_VSCROLL:
  1205. switch (LOWORD(wParam)) {
  1206. case SB_LINEUP:
  1207. IoCouple->EditObject->ScrollUp(hwnd);
  1208. break;
  1209. case SB_LINEDOWN:
  1210. IoCouple->EditObject->ScrollDown(hwnd);
  1211. break;
  1212. case SB_PAGEUP:
  1213. IoCouple->EditObject->PageUp(hwnd);
  1214. break;
  1215. case SB_PAGEDOWN:
  1216. IoCouple->EditObject->PageDown(hwnd);
  1217. break;
  1218. case SB_THUMBPOSITION:
  1219. IoCouple->EditObject->ThumbPosition(hwnd, HIWORD(wParam));
  1220. break;
  1221. default:
  1222. break;
  1223. }
  1224. break;
  1225. case WM_KEYDOWN:
  1226. switch (LOWORD(wParam)) {
  1227. case VK_UP:
  1228. IoCouple->EditObject->KeyUp(hwnd);
  1229. break;
  1230. case VK_DOWN:
  1231. IoCouple->EditObject->KeyDown(hwnd);
  1232. break;
  1233. case VK_LEFT:
  1234. IoCouple->EditObject->KeyLeft(hwnd);
  1235. break;
  1236. case VK_RIGHT:
  1237. IoCouple->EditObject->KeyRight(hwnd);
  1238. break;
  1239. case VK_PRIOR:
  1240. IoCouple->EditObject->PageUp(hwnd);
  1241. break;
  1242. case VK_NEXT:
  1243. IoCouple->EditObject->PageDown(hwnd);
  1244. break;
  1245. default:
  1246. break;
  1247. }
  1248. break;
  1249. case WM_SETFOCUS:
  1250. IoCouple->EditObject->SetFocus(hwnd);
  1251. break;
  1252. case WM_KILLFOCUS:
  1253. IoCouple->EditObject->KillFocus(hwnd);
  1254. break;
  1255. case WM_LBUTTONDOWN:
  1256. IoCouple->EditObject->Click(hwnd, LOWORD(lParam), HIWORD(lParam));
  1257. break;
  1258. }
  1259. return 0;
  1260. }
  1261. LRESULT
  1262. SplitWndProc(
  1263. IN HWND hwnd,
  1264. IN UINT message,
  1265. IN WPARAM wParam,
  1266. IN LPARAM lParam
  1267. )
  1268. {
  1269. FARPROC lpProc;
  1270. HDC hdc;
  1271. PAINTSTRUCT ps;
  1272. ULONG size;
  1273. WORD command;
  1274. BOOLEAN error;
  1275. ULONG error_status;
  1276. switch (message) {
  1277. default:
  1278. return DefWindowProc(hwnd, message, wParam, lParam);
  1279. case WM_PAINT:
  1280. hdc = BeginPaint(hwnd, &ps);
  1281. if (NULL != IoCouple->SplitEditObject) {
  1282. IoCouple->SplitEditObject->Paint(hdc, ps.rcPaint, hwnd);
  1283. }
  1284. EndPaint(hwnd, &ps);
  1285. return 0;
  1286. case WM_CHAR:
  1287. IoCouple->SplitEditObject->Character(hwnd, (CHAR)wParam);
  1288. break;
  1289. case WM_VSCROLL:
  1290. switch (LOWORD(wParam)) {
  1291. case SB_LINEUP:
  1292. IoCouple->SplitEditObject->ScrollUp(hwnd);
  1293. break;
  1294. case SB_LINEDOWN:
  1295. IoCouple->SplitEditObject->ScrollDown(hwnd);
  1296. break;
  1297. case SB_PAGEUP:
  1298. IoCouple->SplitEditObject->PageUp(hwnd);
  1299. break;
  1300. case SB_PAGEDOWN:
  1301. IoCouple->SplitEditObject->PageDown(hwnd);
  1302. break;
  1303. case SB_THUMBPOSITION:
  1304. IoCouple->SplitEditObject->ThumbPosition(hwnd, HIWORD(wParam));
  1305. break;
  1306. default:
  1307. break;
  1308. }
  1309. break;
  1310. case WM_KEYDOWN:
  1311. switch (LOWORD(wParam)) {
  1312. case VK_UP:
  1313. IoCouple->SplitEditObject->KeyUp(hwnd);
  1314. break;
  1315. case VK_DOWN:
  1316. IoCouple->SplitEditObject->KeyDown(hwnd);
  1317. break;
  1318. case VK_LEFT:
  1319. IoCouple->SplitEditObject->KeyLeft(hwnd);
  1320. break;
  1321. case VK_RIGHT:
  1322. IoCouple->SplitEditObject->KeyRight(hwnd);
  1323. break;
  1324. case VK_PRIOR:
  1325. IoCouple->SplitEditObject->PageUp(hwnd);
  1326. break;
  1327. case VK_NEXT:
  1328. IoCouple->SplitEditObject->PageDown(hwnd);
  1329. break;
  1330. default:
  1331. break;
  1332. }
  1333. break;
  1334. case WM_SETFOCUS:
  1335. IoCouple->SplitEditObject->SetFocus(hwnd);
  1336. break;
  1337. case WM_KILLFOCUS:
  1338. IoCouple->SplitEditObject->KillFocus(hwnd);
  1339. break;
  1340. case WM_LBUTTONDOWN:
  1341. IoCouple->SplitEditObject->Click(hwnd, LOWORD(lParam), HIWORD(lParam));
  1342. break;
  1343. }
  1344. return 0;
  1345. }