Leaked source code of windows server 2003
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.

1155 lines
23 KiB

  1. /*++
  2. Copyright (c) 1998 Microsoft Corporation
  3. Module Name:
  4. keytree.c
  5. Abstract:
  6. functions handling the operation of the treeview
  7. that displays the keys in a memdb tree in memdbe.exe
  8. Author:
  9. Matthew Vanderzee (mvander) 13-Aug-1999
  10. Revision History:
  11. --*/
  12. #include "pch.h"
  13. #include "dbeditp.h"
  14. #include <commdlg.h>
  15. #include "dialogs.h"
  16. //
  17. // controls in display
  18. //
  19. HWND g_hTreeKey;
  20. //
  21. // distance from corner of client window to
  22. // corner of tree view
  23. //
  24. int g_TreeView_OffsetX, g_TreeView_OffsetY;
  25. //
  26. // handle of item being dragged
  27. //
  28. HTREEITEM g_hDragItem;
  29. CHAR g_Key1[MEMDB_MAX] = "";
  30. CHAR g_Key2[MEMDB_MAX] = "";
  31. CHAR g_FindString[MEMDB_MAX] = "";
  32. HTREEITEM g_hFindItem = NULL;
  33. PPARSEDPATTERNA g_FindParsedPattern = NULL;
  34. BOOL g_UpdateSel = TRUE;
  35. extern VOID
  36. AlertBadNewItemName (
  37. HTREEITEM hItem,
  38. PSTR ErrorStr
  39. );
  40. HTREEITEM
  41. pKeyTreeEnumNextItem (
  42. HTREEITEM hItem
  43. )
  44. {
  45. HTREEITEM hNext;
  46. if (!hItem) {
  47. return TreeView_GetRoot (g_hTreeKey);
  48. }
  49. if (hNext = TreeView_GetChild (g_hTreeKey, hItem)) {
  50. return hNext;
  51. }
  52. do {
  53. if (hNext = TreeView_GetNextSibling (g_hTreeKey, hItem)) {
  54. return hNext;
  55. }
  56. } while (hItem = TreeView_GetParent (g_hTreeKey, hItem));
  57. return NULL;
  58. }
  59. PSTR
  60. pIsChildKey (
  61. PSTR Parent,
  62. PSTR Child
  63. )
  64. {
  65. INT ParentLen;
  66. ParentLen = CharCountA (Parent);
  67. if ((ParentLen > 0) &&
  68. StringIMatchCharCountA (Parent, Child, ParentLen) &&
  69. (Child[ParentLen] == '\\')) {
  70. return Child + ParentLen + 1;
  71. } else {
  72. return NULL;
  73. }
  74. }
  75. BOOL
  76. IsKeyTree (
  77. HWND hwnd
  78. )
  79. {
  80. return (hwnd == g_hTreeKey);
  81. }
  82. BOOL
  83. KeyTreeInit (
  84. HWND hdlg
  85. )
  86. {
  87. HBITMAP hBmp;
  88. HIMAGELIST ImgList;
  89. RECT r1, r2;
  90. g_hTreeKey = GetDlgItem (hdlg, IDC_TREE_KEY);
  91. GetWindowRect (g_hTreeKey, &r1);
  92. GetWindowRect (hdlg, &r2);
  93. g_TreeView_OffsetX = r1.left - r2.left;
  94. g_TreeView_OffsetY = r1.top - r2.top;
  95. if ((ImgList = ImageList_Create (16, 16, ILC_COLOR, 2, 0)) == NULL)
  96. return FALSE;
  97. hBmp = LoadBitmap (g_hInst, MAKEINTRESOURCE(IDB_BITMAP_KEY));
  98. ImageList_AddMasked (ImgList, hBmp, RGB (0, 255, 0));
  99. DeleteObject (hBmp);
  100. hBmp = LoadBitmap (g_hInst, MAKEINTRESOURCE(IDB_BITMAP_KEYSEL));
  101. ImageList_AddMasked (ImgList, hBmp, RGB (0, 255, 0));
  102. DeleteObject (hBmp);
  103. TreeView_SetImageList (g_hTreeKey, ImgList, TVSIL_NORMAL);
  104. return TRUE;
  105. }
  106. VOID
  107. KeyTreeDestroy (
  108. VOID
  109. )
  110. {
  111. if (g_FindParsedPattern) {
  112. DestroyParsedPatternA (g_FindParsedPattern);
  113. }
  114. }
  115. BOOL
  116. KeyTreeClear (
  117. VOID
  118. )
  119. {
  120. g_UpdateSel = FALSE;
  121. if (!TreeView_DeleteAllItems (g_hTreeKey)) {
  122. DEBUGMSG ((DBG_ERROR, "Could not clear Tree View!"));
  123. return FALSE;
  124. }
  125. g_UpdateSel = TRUE;
  126. KeyTreeSelectItem (NULL);
  127. KeyAddClear ();
  128. g_hFindItem = NULL;
  129. g_hDragItem = NULL;
  130. return TRUE;
  131. }
  132. BOOL
  133. KeyTreeRefresh (
  134. VOID
  135. )
  136. {
  137. TurnOnWaitCursor ();
  138. if (!KeyTreeClear ()) {
  139. return FALSE;
  140. }
  141. if (!KeyAddSubLevels (NULL)) {
  142. DEBUGMSG ((DBG_ERROR, "Could not fill Tree View!"));
  143. TurnOffWaitCursor ();
  144. return FALSE;
  145. }
  146. InvalidateRect (g_hTreeKey, NULL, TRUE);
  147. TurnOffWaitCursor ();
  148. return TRUE;
  149. }
  150. UINT
  151. KeyTreeGetIndexOfItem (
  152. HTREEITEM hItem
  153. )
  154. {
  155. TVITEM tvi;
  156. if (!hItem) {
  157. return INVALID_KEY_HANDLE;
  158. }
  159. tvi.hItem = hItem;
  160. tvi.mask = TVIF_PARAM;
  161. TreeView_GetItem (g_hTreeKey, &tvi);
  162. return tvi.lParam;
  163. }
  164. BOOL
  165. KeyTreeGetNameOfItem (
  166. HTREEITEM hItem,
  167. PSTR Buffer
  168. )
  169. {
  170. UINT Index;
  171. PCSTR key;
  172. Index = KeyTreeGetIndexOfItem (hItem);
  173. if (Index == INVALID_KEY_HANDLE) {
  174. return FALSE;
  175. }
  176. key = MemDbGetKeyFromHandleA (Index, 0);
  177. if (!key) {
  178. return FALSE;
  179. }
  180. StringCopyA (Buffer, key);
  181. MemDbReleaseMemory (key);
  182. return TRUE;
  183. }
  184. VOID
  185. KeyTreeSelectItem (
  186. HTREEITEM hItem
  187. )
  188. {
  189. HTREEITEM hItemCur;
  190. hItemCur = TreeView_GetDropHilight (g_hTreeKey);
  191. if (hItemCur != hItem) {
  192. TreeView_SelectDropTarget (g_hTreeKey, hItem);
  193. }
  194. hItemCur = TreeView_GetSelection (g_hTreeKey);
  195. if (hItemCur != hItem) {
  196. TreeView_SelectItem (g_hTreeKey, hItem);
  197. }
  198. }
  199. VOID
  200. KeyTreeSelectKey (
  201. UINT Index
  202. )
  203. {
  204. HTREEITEM hItem = NULL;
  205. PSTR Ptr;
  206. PCSTR key;
  207. key = MemDbGetKeyFromHandleA (Index, 0);
  208. if (!key) {
  209. return;
  210. }
  211. StringCopy (g_Key1, key);
  212. MemDbReleaseMemory (key);
  213. Ptr = g_Key1;
  214. while (Ptr = GetPieceOfKey (Ptr, g_Key2)) {
  215. if (!(hItem = KeyTreeFindChildItem (hItem, g_Key2))) {
  216. return;
  217. }
  218. }
  219. KeyTreeSelectItem (hItem);
  220. }
  221. VOID
  222. KeyTreeSelectRClickItem (
  223. VOID
  224. )
  225. {
  226. HTREEITEM hItem;
  227. hItem = TreeView_GetDropHilight (g_hTreeKey);
  228. KeyTreeSelectItem (hItem);
  229. }
  230. VOID
  231. pKeyTreeDisplayItemData (
  232. HTREEITEM hItem
  233. )
  234. {
  235. INT i, j;
  236. INT count;
  237. CHAR Linkage[MEMDB_MAX];
  238. KEYHANDLE memdbHandle;
  239. UINT value;
  240. UINT flags;
  241. UINT size;
  242. PBYTE p;
  243. KEYHANDLE *keyArray;
  244. PCSTR key;
  245. DataListClear ();
  246. //
  247. // Fill control with values and flags
  248. //
  249. memdbHandle = KeyTreeGetIndexOfItem (hItem);
  250. if (!memdbHandle) {
  251. return;
  252. }
  253. if (MemDbGetValueAndFlagsByHandle (memdbHandle, &value, &flags)) {
  254. DataListAddData (DATAFLAG_VALUE, value, NULL);
  255. DataListAddData (DATAFLAG_FLAGS, flags, NULL);
  256. }
  257. //
  258. // Fill control with unordered binary blobs
  259. //
  260. for (i = 0 ; i < 4 ; i++) {
  261. p = MemDbGetUnorderedBlobByKeyHandle (memdbHandle, (BYTE) i, &size);
  262. if (p) {
  263. DataListAddData (DATAFLAG_UNORDERED, size, p);
  264. MemDbReleaseMemory (p);
  265. }
  266. }
  267. //
  268. // Fill control with unidirectional linkage
  269. //
  270. for (i = 0 ; i < 4 ; i++) {
  271. keyArray = MemDbGetSingleLinkageArrayByKeyHandle (memdbHandle, (BYTE) i, &size);
  272. if (keyArray) {
  273. count = (INT) size / sizeof (KEYHANDLE);
  274. for (j = 0 ; j < count ; j++) {
  275. key = MemDbGetKeyFromHandle (keyArray[j], 0);
  276. DataListAddData (DATAFLAG_SINGLELINK, keyArray[j], (PBYTE) key);
  277. MemDbReleaseMemory (key);
  278. }
  279. MemDbReleaseMemory (keyArray);
  280. }
  281. }
  282. //
  283. // Fill control with bi-directional linkage
  284. //
  285. for (i = 0 ; i < 4 ; i++) {
  286. keyArray = MemDbGetDoubleLinkageArrayByKeyHandle (memdbHandle, (BYTE) i, &size);
  287. if (keyArray) {
  288. count = (INT) size / sizeof (KEYHANDLE);
  289. for (j = 0 ; j < count ; j++) {
  290. key = MemDbGetKeyFromHandle (keyArray[j], 0);
  291. DataListAddData (DATAFLAG_DOUBLELINK, keyArray[j], (PBYTE) key);
  292. MemDbReleaseMemory (key);
  293. }
  294. MemDbReleaseMemory (keyArray);
  295. }
  296. }
  297. }
  298. HTREEITEM
  299. KeyTreeSelChanged (
  300. HWND hdlg,
  301. LPNMTREEVIEW pnmtv
  302. )
  303. {
  304. if (!g_UpdateSel) {
  305. return NULL;
  306. }
  307. KeyTreeSelectItem (pnmtv->itemNew.hItem);
  308. if (!pnmtv->itemNew.hItem)
  309. {
  310. SetDlgItemText (hdlg, IDC_STATIC_KEYNAME, "");
  311. DataListClear ();
  312. } else {
  313. if (KeyTreeGetNameOfItem (pnmtv->itemNew.hItem, g_Key1)) {
  314. SetDlgItemText (hdlg, IDC_STATIC_KEYNAME, g_Key1);
  315. }
  316. pKeyTreeDisplayItemData (pnmtv->itemNew.hItem);
  317. }
  318. return pnmtv->itemNew.hItem;
  319. }
  320. BOOL
  321. KeyTreeBeginDrag (
  322. HWND hWnd,
  323. LPNMTREEVIEW pnmtv
  324. )
  325. {
  326. HIMAGELIST hDragImgList;
  327. if (!(hDragImgList = TreeView_CreateDragImage (g_hTreeKey, pnmtv->itemNew.hItem))) {
  328. DEBUGMSG ((DBG_ERROR, "Could not get drag image!"));
  329. return FALSE;
  330. }
  331. if (!ImageList_BeginDrag (hDragImgList, 0, 8, 8)) {
  332. DEBUGMSG ((DBG_ERROR, "Could not begin drag!"));
  333. return FALSE;
  334. }
  335. if (!ImageList_DragEnter(g_hTreeKey, pnmtv->ptDrag.x, pnmtv->ptDrag.y)) {
  336. DEBUGMSG ((DBG_ERROR, "Could not enter drag!"));
  337. return FALSE;
  338. }
  339. SetCapture (hWnd);
  340. g_hDragItem = pnmtv->itemNew.hItem;
  341. return TRUE;
  342. }
  343. BOOL
  344. KeyTreeMoveDrag (
  345. POINTS pt
  346. )
  347. {
  348. static HTREEITEM hItem, hItem2;
  349. static RECT TreeRect;
  350. static TVHITTESTINFO tvht;
  351. static int x, y, count;
  352. x = pt.x-g_TreeView_OffsetX;
  353. y = pt.y-g_TreeView_OffsetY;
  354. if (!ImageList_DragLeave (g_hTreeKey)) {
  355. DEBUGMSG ((DBG_ERROR, "Could not leave drag!"));
  356. return FALSE;
  357. }
  358. if (!ImageList_DragMove (x, y)) {
  359. DEBUGMSG ((DBG_ERROR, "Could not move drag!"));
  360. return FALSE;
  361. }
  362. tvht.pt.x = x;
  363. tvht.pt.y = y;
  364. TreeView_HitTest (g_hTreeKey, &tvht);
  365. if (tvht.flags & TVHT_ONITEM) {
  366. //
  367. // if we are over an item and it is not already selected, select it.
  368. //
  369. if (TreeView_GetSelection (g_hTreeKey) != tvht.hItem) {
  370. KeyTreeSelectItem (tvht.hItem);
  371. }
  372. } else if (tvht.flags & TVHT_ONITEMBUTTON) {
  373. //
  374. // if we are over a plus/minus sign, expand tree
  375. //
  376. TreeView_Expand (g_hTreeKey, tvht.hItem, TVE_EXPAND);
  377. } else if (tvht.flags & TVHT_ABOVE) {
  378. if (hItem = TreeView_GetFirstVisible (g_hTreeKey)) {
  379. if (hItem2 = TreeView_GetPrevVisible (g_hTreeKey, hItem)) {
  380. TreeView_EnsureVisible (g_hTreeKey, hItem2);
  381. }
  382. }
  383. } else if (tvht.flags & TVHT_BELOW) {
  384. if ((hItem = TreeView_GetFirstVisible (g_hTreeKey)) &&
  385. ((count = TreeView_GetVisibleCount (g_hTreeKey)) > 0))
  386. {
  387. hItem2 = hItem;
  388. while (hItem2 && count > 0) {
  389. hItem = hItem2;
  390. hItem2 = TreeView_GetNextVisible (g_hTreeKey, hItem);
  391. count --;
  392. }
  393. if (hItem2) {
  394. TreeView_EnsureVisible (g_hTreeKey, hItem2);
  395. }
  396. }
  397. }
  398. UpdateWindow (g_hTreeKey);
  399. if (!ImageList_DragEnter(g_hTreeKey, x, y)) {
  400. DEBUGMSG ((DBG_ERROR, "Could not enter drag!"));
  401. return FALSE;
  402. }
  403. return TRUE;
  404. }
  405. BOOL
  406. KeyTreeEndDrag (
  407. BOOL TakeAction,
  408. POINTS *pt
  409. )
  410. /*++
  411. only returns TRUE if the memdb database is altered
  412. --*/
  413. {
  414. TVITEM Item;
  415. HTREEITEM hItem;
  416. TVINSERTSTRUCT tvis;
  417. static TVHITTESTINFO tvht;
  418. int x, y;
  419. ReleaseCapture ();
  420. if (!ImageList_DragLeave (g_hTreeKey)) {
  421. DEBUGMSG ((DBG_ERROR, "Could not leave drag!"));
  422. return FALSE;
  423. }
  424. ImageList_EndDrag();
  425. if (!TakeAction) {
  426. KeyTreeSelectItem (NULL);
  427. return FALSE;
  428. }
  429. x = pt->x-g_TreeView_OffsetX;
  430. y = pt->y-g_TreeView_OffsetY;
  431. tvht.pt.x = x;
  432. tvht.pt.y = y;
  433. TreeView_HitTest (g_hTreeKey, &tvht);
  434. if (!(tvht.flags & TVHT_ONITEM)) {
  435. return FALSE;
  436. }
  437. if (!KeyTreeGetNameOfItem (g_hDragItem, g_Key1) ||
  438. !KeyTreeGetNameOfItem (tvht.hItem, g_Key2)) {
  439. return FALSE;
  440. }
  441. StringCatA (g_Key2, "\\");
  442. Item.hItem = g_hDragItem;
  443. Item.mask = TVIF_TEXT;
  444. Item.pszText = GetEndOfStringA (g_Key2);
  445. Item.cchTextMax = MEMDB_MAX;
  446. TreeView_GetItem (g_hTreeKey, &Item);
  447. //
  448. // MemDbMoveTree is not implemented
  449. //
  450. return FALSE;
  451. /*
  452. if (!MemDbMoveTreeA (g_Key1, g_Key2)) {
  453. Beep (200, 50);
  454. return FALSE;
  455. }
  456. //
  457. // get the dragitem data, then delete it and children,
  458. // then add to new parent, then fill in child levels.
  459. //
  460. tvis.item.hItem = g_hDragItem;
  461. tvis.item.mask = TVIF_TEXT | TVIF_PARAM | TVIF_IMAGE | TVIF_SELECTEDIMAGE;
  462. tvis.item.pszText = g_Key1;
  463. tvis.item.cchTextMax = MEMDB_MAX;
  464. if (!TreeView_GetItem (g_hTreeKey, &tvis.item)) {
  465. DEBUGMSG ((DBG_ERROR, "Could not get item data!"));
  466. }
  467. if (!TreeView_DeleteItem (g_hTreeKey, g_hDragItem)) {
  468. DEBUGMSG ((DBG_ERROR, "Could not delete item!"));
  469. }
  470. tvis.hParent = tvht.hItem;
  471. tvis.hInsertAfter = TVI_FIRST;
  472. if (!(hItem = TreeView_InsertItem (g_hTreeKey, &tvis))) {
  473. DEBUGMSG ((DBG_ERROR, "Could not insert item!"));
  474. }
  475. KeyAddSubLevels (hItem);
  476. KeyTreeSelectItem (hItem);
  477. return TRUE;
  478. */
  479. }
  480. BOOL
  481. KeyTreeCreateItem (
  482. HWND hdlg
  483. )
  484. {
  485. HTREEITEM hItem;
  486. if (!CreateKeyDialog (hdlg, g_Key1)) {
  487. return FALSE;
  488. }
  489. if (!(hItem = KeyAddCreateItem (g_Key1))) {
  490. return FALSE;
  491. }
  492. KeyTreeSelectItem (hItem);
  493. return TRUE;
  494. }
  495. BOOL
  496. KeyTreeCreateChildItem (
  497. HWND hdlg,
  498. HTREEITEM hItem
  499. )
  500. {
  501. if (!(hItem = KeyAddItem ("", hItem, INVALID_KEY_HANDLE))) {
  502. return FALSE;
  503. }
  504. KeyTreeSelectItem (hItem);
  505. if (!KeyTreeForceEditLabel (hItem)) {
  506. return FALSE;
  507. }
  508. return TRUE;
  509. }
  510. BOOL
  511. KeyTreeRenameItem (
  512. HTREEITEM hItem,
  513. LPSTR Name
  514. )
  515. /*++
  516. only returns TRUE if the memdb database is altered
  517. --*/
  518. {
  519. HTREEITEM hParent;
  520. TVITEM Item;
  521. BOOL NewItem;
  522. if (!hItem || !Name) {
  523. return FALSE;
  524. }
  525. //
  526. // MemDbMove is not implemented
  527. //
  528. return FALSE;
  529. /*
  530. hParent = TreeView_GetParent (g_hTreeKey, hItem);
  531. NewItem = (KeyTreeGetIndexOfItem (hItem) == INVALID_KEY_HANDLE);
  532. if (KeyTreeFindChildItem (hParent, Name)) {
  533. if (NewItem) {
  534. AlertBadNewItemName (hItem, "Name already exists at this level");
  535. } else {
  536. MessageBox (NULL, "Name already exists at this level", "Error", MB_OK|MB_ICONEXCLAMATION);
  537. }
  538. return FALSE;
  539. }
  540. if (NewItem) {
  541. if (Name[0]=='\0') {
  542. AlertBadNewItemName (hItem, "New keys must have name");
  543. return FALSE;
  544. }
  545. } else {
  546. if (!KeyTreeGetNameOfItem (hItem, g_Key1) ||
  547. !KeyTreeGetNameOfItem (hParent, g_Key2)) {
  548. return FALSE;
  549. }
  550. StringCatA (g_Key2, "\\");
  551. StringCatA (g_Key2, Name);
  552. if (!MemDbMoveTreeA (g_Key1, g_Key2)) {
  553. MessageBox (NULL, "Could not rename item", "Error", MB_OK|MB_ICONEXCLAMATION);
  554. return FALSE;
  555. }
  556. }
  557. Item.hItem = hItem;
  558. Item.mask = TVIF_TEXT;
  559. Item.pszText = Name;
  560. TreeView_SetItem (g_hTreeKey, &Item);
  561. return TRUE;
  562. */
  563. }
  564. BOOL
  565. KeyTreeDeleteKey (
  566. HTREEITEM hItem
  567. )
  568. /*++
  569. only returns TRUE if the memdb database is altered
  570. --*/
  571. {
  572. CHAR Key[MEMDB_MAX];
  573. HTREEITEM hParent;
  574. if (!hItem || !KeyTreeGetNameOfItem (hItem, Key)) {
  575. return FALSE;
  576. }
  577. do {
  578. //
  579. // move up tree, deleting parents if they have no other children
  580. // and they are not an endpoint (memdbgetvalue returns false)
  581. //
  582. hParent = TreeView_GetParent (g_hTreeKey, hItem);
  583. TreeView_DeleteItem (g_hTreeKey, hItem);
  584. hItem = hParent;
  585. } while (hItem && !TreeView_GetChild (g_hTreeKey, hItem) &&
  586. !(KeyTreeGetNameOfItem (hItem, g_Key1) && MemDbGetValueA (g_Key1, NULL)));
  587. MemDbDeleteTreeA (Key);
  588. return TRUE;
  589. }
  590. BOOL
  591. KeyTreeDeleteItem (
  592. HTREEITEM hItem
  593. )
  594. {
  595. return TreeView_DeleteItem (g_hTreeKey, hItem);
  596. }
  597. VOID
  598. KeyTreeExpandItem (
  599. HTREEITEM hItem,
  600. BOOL Expand,
  601. BOOL Recurse
  602. )
  603. {
  604. HTREEITEM hChildItem;
  605. if (!hItem) {
  606. if (!(hItem = TreeView_GetRoot (g_hTreeKey))) {
  607. return;
  608. }
  609. }
  610. if (!Recurse) {
  611. TreeView_Expand (g_hTreeKey, hItem, Expand ? TVE_EXPAND : TVE_COLLAPSE);
  612. } else {
  613. do {
  614. hChildItem = TreeView_GetChild (g_hTreeKey, hItem);
  615. if (hChildItem) {
  616. TreeView_Expand (g_hTreeKey, hItem, Expand ? TVE_EXPAND : TVE_COLLAPSE);
  617. KeyTreeExpandItem (hChildItem, Expand, TRUE);
  618. }
  619. } while (hItem = TreeView_GetNextSibling (g_hTreeKey, hItem));
  620. }
  621. }
  622. BOOL
  623. KeyTreeRightClick (
  624. HWND hdlg,
  625. HTREEITEM hItem
  626. )
  627. {
  628. RECT TVrect, rect;
  629. HMENU hMenu;
  630. if (!hItem || !GetWindowRect (g_hTreeKey, &TVrect)) {
  631. return FALSE;
  632. }
  633. TreeView_EnsureVisible (g_hTreeKey, hItem);
  634. if (!TreeView_GetItemRect (g_hTreeKey, hItem, &rect, TRUE)) {
  635. DEBUGMSG ((DBG_ERROR, "Error getting item rectangle!"));
  636. }
  637. if (!(hMenu = LoadMenu (g_hInst, MAKEINTRESOURCE(IDR_MENU_POPUP))) ||
  638. (!(hMenu = GetSubMenu (hMenu, MENUINDEX_POPUP_KEY)))) {
  639. return FALSE;
  640. }
  641. if (!TrackPopupMenu (
  642. hMenu,
  643. TPM_LEFTALIGN,
  644. TVrect.left + rect.right + 4,
  645. TVrect.top + rect.top,
  646. 0,
  647. hdlg,
  648. NULL
  649. )) {
  650. return FALSE;
  651. }
  652. return TRUE;
  653. }
  654. BOOL
  655. KeyTreeForceEditLabel (
  656. HTREEITEM hItem
  657. )
  658. {
  659. if (!hItem) {
  660. return FALSE;
  661. }
  662. if (!TreeView_EditLabel (g_hTreeKey, hItem)) {
  663. TreeView_DeleteItem (g_hTreeKey, hItem);
  664. return FALSE;
  665. }
  666. return TRUE;
  667. }
  668. HTREEITEM
  669. KeyTreeFindChildItem (
  670. HTREEITEM hItem,
  671. PSTR Str
  672. )
  673. {
  674. TVITEM Item;
  675. static CHAR PieceBuf[MEMDB_MAX];
  676. Item.mask = TVIF_TEXT;
  677. Item.pszText = PieceBuf;
  678. Item.cchTextMax = MEMDB_MAX;
  679. if (hItem == NULL) {
  680. Item.hItem = TreeView_GetRoot (g_hTreeKey);
  681. } else {
  682. Item.hItem = TreeView_GetChild (g_hTreeKey, hItem);
  683. }
  684. while (Item.hItem) {
  685. TreeView_GetItem (g_hTreeKey, &Item);
  686. if (StringIMatchA (PieceBuf, Str)) {
  687. return Item.hItem;
  688. }
  689. Item.hItem = TreeView_GetNextSibling (g_hTreeKey, Item.hItem);
  690. }
  691. return NULL;
  692. }
  693. BOOL
  694. KeyTreeFindNext (
  695. VOID
  696. )
  697. {
  698. BOOL b;
  699. TurnOnWaitCursor ();
  700. while (g_hFindItem = pKeyTreeEnumNextItem (g_hFindItem))
  701. {
  702. if (!KeyTreeGetNameOfItem (g_hFindItem, g_Key1)) {
  703. TurnOffWaitCursor ();
  704. return FALSE;
  705. }
  706. if (MemDbGetValueA (g_Key1, NULL)) {
  707. //
  708. // if we are looking at an endpoint, see if it matches
  709. //
  710. if (g_FindParsedPattern) {
  711. b = TestParsedPatternA (g_FindParsedPattern, g_Key1);
  712. } else {
  713. b = (_mbsistr (g_Key1, g_FindString) != NULL);
  714. }
  715. if (b) {
  716. KeyTreeSelectItem (g_hFindItem);
  717. TurnOffWaitCursor ();
  718. return TRUE;
  719. }
  720. }
  721. }
  722. TurnOffWaitCursor ();
  723. MessageBox (NULL, "No more keys found", "MemDb Editor", MB_OK|MB_ICONINFORMATION);
  724. return FALSE;
  725. }
  726. BOOL
  727. KeyTreeFind (
  728. HWND hwnd
  729. )
  730. {
  731. BOOL UsePattern;
  732. if (!KeyFindDialog (hwnd, g_FindString, &UsePattern)) {
  733. return FALSE;
  734. }
  735. if (g_FindParsedPattern) {
  736. //
  737. // if we have an old pattern, destroy it.
  738. //
  739. DestroyParsedPatternA (g_FindParsedPattern);
  740. g_FindParsedPattern = NULL;
  741. }
  742. if (UsePattern) {
  743. g_FindParsedPattern = CreateParsedPatternA (g_FindString);
  744. }
  745. g_hFindItem = NULL;
  746. return KeyTreeFindNext ();
  747. }
  748. BOOL
  749. KeyTreeCreateEmptyKey (
  750. HTREEITEM hItem
  751. )
  752. {
  753. TVITEM Item;
  754. UINT Index;
  755. HTREEITEM hParent;
  756. if (hParent = TreeView_GetParent (g_hTreeKey, hItem)) {
  757. if (!KeyTreeGetNameOfItem (hParent, g_Key1)) {
  758. return FALSE;
  759. }
  760. StringCatA (g_Key1, "\\");
  761. } else {
  762. g_Key1[0] = '\0';
  763. }
  764. Item.hItem = hItem;
  765. Item.mask = TVIF_TEXT;
  766. Item.pszText = GetEndOfStringA (g_Key1);
  767. if (!TreeView_GetItem (g_hTreeKey, &Item)) {
  768. return FALSE;
  769. }
  770. Index = MemDbAddKeyA (g_Key1);
  771. if (!Index) {
  772. return FALSE;
  773. }
  774. Item.mask = TVIF_PARAM;
  775. Item.lParam = Index;
  776. return TreeView_SetItem (g_hTreeKey, &Item);
  777. }
  778. BOOL
  779. KeyTreeAddShortData (
  780. HWND hwnd,
  781. HTREEITEM hItem,
  782. BYTE DataFlag
  783. )
  784. {
  785. DWORD dataValue;
  786. BOOL addData;
  787. BYTE instance;
  788. if (!hItem || (DataFlag != DATAFLAG_VALUE) && (DataFlag != DATAFLAG_FLAGS)) {
  789. return FALSE;
  790. }
  791. if (!KeyTreeGetNameOfItem (hItem, g_Key1)) {
  792. DEBUGMSG ((DBG_ERROR, "Could not get item name!"));
  793. return FALSE;
  794. }
  795. if (!ShortDataDialog (hwnd, DataFlag, &dataValue, &addData, &instance)) {
  796. return FALSE;
  797. }
  798. if (addData) {
  799. if (!MemDbAddUnorderedBlobA (g_Key1, instance, (PBYTE) &dataValue, sizeof (dataValue))) {
  800. DEBUGMSG ((DBG_ERROR, "Could not add data to item!"));
  801. return FALSE;
  802. }
  803. } else if (DataFlag == DATAFLAG_VALUE) {
  804. if (!MemDbSetValue (g_Key1, dataValue)) {
  805. DEBUGMSG ((DBG_ERROR, "Could not set value of item!"));
  806. return FALSE;
  807. }
  808. } else if (DataFlag == DATAFLAG_FLAGS) {
  809. if (!MemDbSetFlags (g_Key1, dataValue, (UINT) -1)) {
  810. DEBUGMSG ((DBG_ERROR, "Could not set flag of item!"));
  811. return FALSE;
  812. }
  813. }
  814. pKeyTreeDisplayItemData (hItem);
  815. return TRUE;
  816. }
  817. BOOL
  818. KeyTreeClearData (
  819. HTREEITEM hItem
  820. )
  821. {
  822. if (!hItem || !KeyTreeGetNameOfItem (hItem, g_Key1)) {
  823. return FALSE;
  824. }
  825. if (MemDbTestKey (g_Key1)) {
  826. MemDbDeleteKey (g_Key1);
  827. if (!MemDbAddKey (g_Key1)) {
  828. return FALSE;
  829. }
  830. }
  831. pKeyTreeDisplayItemData (hItem);
  832. return TRUE;
  833. }
  834. VOID
  835. KeyTreeSetFilterPattern (
  836. PSTR Pattern
  837. )
  838. {
  839. KeyAddSetFilterPattern (Pattern);
  840. }
  841. BOOL
  842. KeyTreeCreateLinkage (
  843. HWND hdlg,
  844. HTREEITEM hItem,
  845. BOOL SingleLinkage,
  846. BYTE Instance
  847. )
  848. {
  849. BOOL b = TRUE;
  850. if (hItem) {
  851. KeyTreeGetNameOfItem (hItem, g_Key1);
  852. } else {
  853. g_Key1[0] = '\0';
  854. }
  855. g_Key2[0] = '\0';
  856. if (!LinkageDialog (hdlg, g_Key1, g_Key2)) {
  857. return FALSE;
  858. }
  859. if (SingleLinkage) {
  860. if (!MemDbAddSingleLinkage (g_Key1, g_Key2, Instance)) {
  861. DEBUGMSG ((DBG_ERROR, "Could not create linkage between %s and %s!", g_Key1, g_Key2));
  862. return FALSE;
  863. }
  864. } else {
  865. if (!MemDbAddDoubleLinkage (g_Key1, g_Key2, Instance)) {
  866. DEBUGMSG ((DBG_ERROR, "Could not create double linkage between %s and %s!", g_Key1, g_Key2));
  867. return FALSE;
  868. }
  869. }
  870. pKeyTreeDisplayItemData (hItem);
  871. return TRUE;
  872. }