|
|
/*++
Copyright (c) 1998 Microsoft Corporation
Module Name:
keytree.c
Abstract:
functions handling the operation of the treeview that displays the keys in a memdb tree in memdbe.exe
Author:
Matthew Vanderzee (mvander) 13-Aug-1999
Revision History:
--*/
#include "pch.h"
#include "dbeditp.h"
#include <commdlg.h>
#include "dialogs.h"
//
// controls in display
//
HWND g_hTreeKey;
//
// distance from corner of client window to
// corner of tree view
//
int g_TreeView_OffsetX, g_TreeView_OffsetY;
//
// handle of item being dragged
//
HTREEITEM g_hDragItem;
CHAR g_Key1[MEMDB_MAX] = ""; CHAR g_Key2[MEMDB_MAX] = "";
CHAR g_FindString[MEMDB_MAX] = ""; HTREEITEM g_hFindItem = NULL; PPARSEDPATTERNA g_FindParsedPattern = NULL;
BOOL g_UpdateSel = TRUE;
extern VOID AlertBadNewItemName ( HTREEITEM hItem, PSTR ErrorStr );
HTREEITEM pKeyTreeEnumNextItem ( HTREEITEM hItem ) { HTREEITEM hNext;
if (!hItem) { return TreeView_GetRoot (g_hTreeKey); }
if (hNext = TreeView_GetChild (g_hTreeKey, hItem)) { return hNext; }
do { if (hNext = TreeView_GetNextSibling (g_hTreeKey, hItem)) { return hNext; } } while (hItem = TreeView_GetParent (g_hTreeKey, hItem));
return NULL; }
PSTR pIsChildKey ( PSTR Parent, PSTR Child ) { INT ParentLen; ParentLen = CharCountA (Parent); if ((ParentLen > 0) && StringIMatchCharCountA (Parent, Child, ParentLen) && (Child[ParentLen] == '\\')) { return Child + ParentLen + 1; } else { return NULL; } }
BOOL IsKeyTree ( HWND hwnd ) { return (hwnd == g_hTreeKey); }
BOOL KeyTreeInit ( HWND hdlg ) { HBITMAP hBmp; HIMAGELIST ImgList; RECT r1, r2;
g_hTreeKey = GetDlgItem (hdlg, IDC_TREE_KEY);
GetWindowRect (g_hTreeKey, &r1); GetWindowRect (hdlg, &r2);
g_TreeView_OffsetX = r1.left - r2.left; g_TreeView_OffsetY = r1.top - r2.top;
if ((ImgList = ImageList_Create (16, 16, ILC_COLOR, 2, 0)) == NULL) return FALSE;
hBmp = LoadBitmap (g_hInst, MAKEINTRESOURCE(IDB_BITMAP_KEY)); ImageList_AddMasked (ImgList, hBmp, RGB (0, 255, 0)); DeleteObject (hBmp); hBmp = LoadBitmap (g_hInst, MAKEINTRESOURCE(IDB_BITMAP_KEYSEL)); ImageList_AddMasked (ImgList, hBmp, RGB (0, 255, 0)); DeleteObject (hBmp);
TreeView_SetImageList (g_hTreeKey, ImgList, TVSIL_NORMAL);
return TRUE; }
VOID KeyTreeDestroy ( VOID ) { if (g_FindParsedPattern) { DestroyParsedPatternA (g_FindParsedPattern); } }
BOOL KeyTreeClear ( VOID ) { g_UpdateSel = FALSE; if (!TreeView_DeleteAllItems (g_hTreeKey)) { DEBUGMSG ((DBG_ERROR, "Could not clear Tree View!")); return FALSE; } g_UpdateSel = TRUE;
KeyTreeSelectItem (NULL);
KeyAddClear (); g_hFindItem = NULL;
g_hDragItem = NULL; return TRUE; }
BOOL KeyTreeRefresh ( VOID ) { TurnOnWaitCursor ();
if (!KeyTreeClear ()) { return FALSE; }
if (!KeyAddSubLevels (NULL)) { DEBUGMSG ((DBG_ERROR, "Could not fill Tree View!")); TurnOffWaitCursor (); return FALSE; }
InvalidateRect (g_hTreeKey, NULL, TRUE);
TurnOffWaitCursor ();
return TRUE; }
UINT KeyTreeGetIndexOfItem ( HTREEITEM hItem ) { TVITEM tvi;
if (!hItem) { return INVALID_KEY_HANDLE; }
tvi.hItem = hItem; tvi.mask = TVIF_PARAM; TreeView_GetItem (g_hTreeKey, &tvi);
return tvi.lParam; }
BOOL KeyTreeGetNameOfItem ( HTREEITEM hItem, PSTR Buffer ) { UINT Index; PCSTR key;
Index = KeyTreeGetIndexOfItem (hItem);
if (Index == INVALID_KEY_HANDLE) { return FALSE; }
key = MemDbGetKeyFromHandleA (Index, 0);
if (!key) { return FALSE; }
StringCopyA (Buffer, key); MemDbReleaseMemory (key);
return TRUE; }
VOID KeyTreeSelectItem ( HTREEITEM hItem ) { HTREEITEM hItemCur; hItemCur = TreeView_GetDropHilight (g_hTreeKey); if (hItemCur != hItem) { TreeView_SelectDropTarget (g_hTreeKey, hItem); } hItemCur = TreeView_GetSelection (g_hTreeKey); if (hItemCur != hItem) { TreeView_SelectItem (g_hTreeKey, hItem); } }
VOID KeyTreeSelectKey ( UINT Index ) { HTREEITEM hItem = NULL; PSTR Ptr; PCSTR key;
key = MemDbGetKeyFromHandleA (Index, 0); if (!key) { return; }
StringCopy (g_Key1, key); MemDbReleaseMemory (key);
Ptr = g_Key1;
while (Ptr = GetPieceOfKey (Ptr, g_Key2)) {
if (!(hItem = KeyTreeFindChildItem (hItem, g_Key2))) { return; } }
KeyTreeSelectItem (hItem); }
VOID KeyTreeSelectRClickItem ( VOID ) { HTREEITEM hItem; hItem = TreeView_GetDropHilight (g_hTreeKey); KeyTreeSelectItem (hItem); }
VOID pKeyTreeDisplayItemData ( HTREEITEM hItem ) { INT i, j; INT count; CHAR Linkage[MEMDB_MAX]; KEYHANDLE memdbHandle; UINT value; UINT flags; UINT size; PBYTE p; KEYHANDLE *keyArray; PCSTR key;
DataListClear ();
//
// Fill control with values and flags
//
memdbHandle = KeyTreeGetIndexOfItem (hItem); if (!memdbHandle) { return; }
if (MemDbGetValueAndFlagsByHandle (memdbHandle, &value, &flags)) { DataListAddData (DATAFLAG_VALUE, value, NULL); DataListAddData (DATAFLAG_FLAGS, flags, NULL); }
//
// Fill control with unordered binary blobs
//
for (i = 0 ; i < 4 ; i++) { p = MemDbGetUnorderedBlobByKeyHandle (memdbHandle, (BYTE) i, &size); if (p) { DataListAddData (DATAFLAG_UNORDERED, size, p); MemDbReleaseMemory (p); } }
//
// Fill control with unidirectional linkage
//
for (i = 0 ; i < 4 ; i++) { keyArray = MemDbGetSingleLinkageArrayByKeyHandle (memdbHandle, (BYTE) i, &size); if (keyArray) { count = (INT) size / sizeof (KEYHANDLE); for (j = 0 ; j < count ; j++) { key = MemDbGetKeyFromHandle (keyArray[j], 0); DataListAddData (DATAFLAG_SINGLELINK, keyArray[j], (PBYTE) key); MemDbReleaseMemory (key); }
MemDbReleaseMemory (keyArray); } }
//
// Fill control with bi-directional linkage
//
for (i = 0 ; i < 4 ; i++) { keyArray = MemDbGetDoubleLinkageArrayByKeyHandle (memdbHandle, (BYTE) i, &size); if (keyArray) { count = (INT) size / sizeof (KEYHANDLE); for (j = 0 ; j < count ; j++) { key = MemDbGetKeyFromHandle (keyArray[j], 0); DataListAddData (DATAFLAG_DOUBLELINK, keyArray[j], (PBYTE) key); MemDbReleaseMemory (key); }
MemDbReleaseMemory (keyArray); } } }
HTREEITEM KeyTreeSelChanged ( HWND hdlg, LPNMTREEVIEW pnmtv ) { if (!g_UpdateSel) { return NULL; }
KeyTreeSelectItem (pnmtv->itemNew.hItem);
if (!pnmtv->itemNew.hItem) { SetDlgItemText (hdlg, IDC_STATIC_KEYNAME, ""); DataListClear (); } else {
if (KeyTreeGetNameOfItem (pnmtv->itemNew.hItem, g_Key1)) { SetDlgItemText (hdlg, IDC_STATIC_KEYNAME, g_Key1); }
pKeyTreeDisplayItemData (pnmtv->itemNew.hItem); }
return pnmtv->itemNew.hItem; }
BOOL KeyTreeBeginDrag ( HWND hWnd, LPNMTREEVIEW pnmtv ) { HIMAGELIST hDragImgList;
if (!(hDragImgList = TreeView_CreateDragImage (g_hTreeKey, pnmtv->itemNew.hItem))) { DEBUGMSG ((DBG_ERROR, "Could not get drag image!")); return FALSE; }
if (!ImageList_BeginDrag (hDragImgList, 0, 8, 8)) { DEBUGMSG ((DBG_ERROR, "Could not begin drag!")); return FALSE; }
if (!ImageList_DragEnter(g_hTreeKey, pnmtv->ptDrag.x, pnmtv->ptDrag.y)) { DEBUGMSG ((DBG_ERROR, "Could not enter drag!")); return FALSE; }
SetCapture (hWnd); g_hDragItem = pnmtv->itemNew.hItem;
return TRUE; }
BOOL KeyTreeMoveDrag ( POINTS pt ) { static HTREEITEM hItem, hItem2; static RECT TreeRect; static TVHITTESTINFO tvht; static int x, y, count;
x = pt.x-g_TreeView_OffsetX; y = pt.y-g_TreeView_OffsetY;
if (!ImageList_DragLeave (g_hTreeKey)) { DEBUGMSG ((DBG_ERROR, "Could not leave drag!")); return FALSE; }
if (!ImageList_DragMove (x, y)) { DEBUGMSG ((DBG_ERROR, "Could not move drag!")); return FALSE; }
tvht.pt.x = x; tvht.pt.y = y; TreeView_HitTest (g_hTreeKey, &tvht); if (tvht.flags & TVHT_ONITEM) { //
// if we are over an item and it is not already selected, select it.
//
if (TreeView_GetSelection (g_hTreeKey) != tvht.hItem) { KeyTreeSelectItem (tvht.hItem); } } else if (tvht.flags & TVHT_ONITEMBUTTON) { //
// if we are over a plus/minus sign, expand tree
//
TreeView_Expand (g_hTreeKey, tvht.hItem, TVE_EXPAND); } else if (tvht.flags & TVHT_ABOVE) { if (hItem = TreeView_GetFirstVisible (g_hTreeKey)) { if (hItem2 = TreeView_GetPrevVisible (g_hTreeKey, hItem)) { TreeView_EnsureVisible (g_hTreeKey, hItem2); } } } else if (tvht.flags & TVHT_BELOW) { if ((hItem = TreeView_GetFirstVisible (g_hTreeKey)) && ((count = TreeView_GetVisibleCount (g_hTreeKey)) > 0)) { hItem2 = hItem; while (hItem2 && count > 0) { hItem = hItem2; hItem2 = TreeView_GetNextVisible (g_hTreeKey, hItem); count --; }
if (hItem2) { TreeView_EnsureVisible (g_hTreeKey, hItem2); } } }
UpdateWindow (g_hTreeKey);
if (!ImageList_DragEnter(g_hTreeKey, x, y)) { DEBUGMSG ((DBG_ERROR, "Could not enter drag!")); return FALSE; }
return TRUE; }
BOOL KeyTreeEndDrag ( BOOL TakeAction, POINTS *pt ) /*++
only returns TRUE if the memdb database is altered
--*/ { TVITEM Item; HTREEITEM hItem; TVINSERTSTRUCT tvis; static TVHITTESTINFO tvht; int x, y;
ReleaseCapture ();
if (!ImageList_DragLeave (g_hTreeKey)) { DEBUGMSG ((DBG_ERROR, "Could not leave drag!")); return FALSE; }
ImageList_EndDrag();
if (!TakeAction) { KeyTreeSelectItem (NULL); return FALSE; }
x = pt->x-g_TreeView_OffsetX; y = pt->y-g_TreeView_OffsetY;
tvht.pt.x = x; tvht.pt.y = y; TreeView_HitTest (g_hTreeKey, &tvht); if (!(tvht.flags & TVHT_ONITEM)) { return FALSE; }
if (!KeyTreeGetNameOfItem (g_hDragItem, g_Key1) || !KeyTreeGetNameOfItem (tvht.hItem, g_Key2)) { return FALSE; }
StringCatA (g_Key2, "\\"); Item.hItem = g_hDragItem; Item.mask = TVIF_TEXT; Item.pszText = GetEndOfStringA (g_Key2); Item.cchTextMax = MEMDB_MAX; TreeView_GetItem (g_hTreeKey, &Item);
//
// MemDbMoveTree is not implemented
//
return FALSE; /*
if (!MemDbMoveTreeA (g_Key1, g_Key2)) { Beep (200, 50); return FALSE; }
//
// get the dragitem data, then delete it and children,
// then add to new parent, then fill in child levels.
//
tvis.item.hItem = g_hDragItem; tvis.item.mask = TVIF_TEXT | TVIF_PARAM | TVIF_IMAGE | TVIF_SELECTEDIMAGE; tvis.item.pszText = g_Key1; tvis.item.cchTextMax = MEMDB_MAX; if (!TreeView_GetItem (g_hTreeKey, &tvis.item)) { DEBUGMSG ((DBG_ERROR, "Could not get item data!")); }
if (!TreeView_DeleteItem (g_hTreeKey, g_hDragItem)) { DEBUGMSG ((DBG_ERROR, "Could not delete item!")); }
tvis.hParent = tvht.hItem; tvis.hInsertAfter = TVI_FIRST; if (!(hItem = TreeView_InsertItem (g_hTreeKey, &tvis))) { DEBUGMSG ((DBG_ERROR, "Could not insert item!")); }
KeyAddSubLevels (hItem);
KeyTreeSelectItem (hItem);
return TRUE; */ }
BOOL KeyTreeCreateItem ( HWND hdlg ) { HTREEITEM hItem;
if (!CreateKeyDialog (hdlg, g_Key1)) { return FALSE; }
if (!(hItem = KeyAddCreateItem (g_Key1))) { return FALSE; }
KeyTreeSelectItem (hItem); return TRUE; }
BOOL KeyTreeCreateChildItem ( HWND hdlg, HTREEITEM hItem ) { if (!(hItem = KeyAddItem ("", hItem, INVALID_KEY_HANDLE))) { return FALSE; }
KeyTreeSelectItem (hItem);
if (!KeyTreeForceEditLabel (hItem)) { return FALSE; }
return TRUE; }
BOOL KeyTreeRenameItem ( HTREEITEM hItem, LPSTR Name ) /*++
only returns TRUE if the memdb database is altered
--*/ { HTREEITEM hParent; TVITEM Item; BOOL NewItem;
if (!hItem || !Name) { return FALSE; }
//
// MemDbMove is not implemented
//
return FALSE;
/*
hParent = TreeView_GetParent (g_hTreeKey, hItem);
NewItem = (KeyTreeGetIndexOfItem (hItem) == INVALID_KEY_HANDLE);
if (KeyTreeFindChildItem (hParent, Name)) { if (NewItem) { AlertBadNewItemName (hItem, "Name already exists at this level"); } else { MessageBox (NULL, "Name already exists at this level", "Error", MB_OK|MB_ICONEXCLAMATION); } return FALSE; }
if (NewItem) { if (Name[0]=='\0') { AlertBadNewItemName (hItem, "New keys must have name"); return FALSE; } } else { if (!KeyTreeGetNameOfItem (hItem, g_Key1) || !KeyTreeGetNameOfItem (hParent, g_Key2)) { return FALSE; }
StringCatA (g_Key2, "\\"); StringCatA (g_Key2, Name);
if (!MemDbMoveTreeA (g_Key1, g_Key2)) { MessageBox (NULL, "Could not rename item", "Error", MB_OK|MB_ICONEXCLAMATION); return FALSE; } }
Item.hItem = hItem; Item.mask = TVIF_TEXT; Item.pszText = Name; TreeView_SetItem (g_hTreeKey, &Item);
return TRUE; */ }
BOOL KeyTreeDeleteKey ( HTREEITEM hItem ) /*++
only returns TRUE if the memdb database is altered
--*/ { CHAR Key[MEMDB_MAX]; HTREEITEM hParent;
if (!hItem || !KeyTreeGetNameOfItem (hItem, Key)) { return FALSE; }
do { //
// move up tree, deleting parents if they have no other children
// and they are not an endpoint (memdbgetvalue returns false)
//
hParent = TreeView_GetParent (g_hTreeKey, hItem); TreeView_DeleteItem (g_hTreeKey, hItem);
hItem = hParent; } while (hItem && !TreeView_GetChild (g_hTreeKey, hItem) && !(KeyTreeGetNameOfItem (hItem, g_Key1) && MemDbGetValueA (g_Key1, NULL)));
MemDbDeleteTreeA (Key);
return TRUE; }
BOOL KeyTreeDeleteItem ( HTREEITEM hItem ) { return TreeView_DeleteItem (g_hTreeKey, hItem); }
VOID KeyTreeExpandItem ( HTREEITEM hItem, BOOL Expand, BOOL Recurse ) { HTREEITEM hChildItem; if (!hItem) { if (!(hItem = TreeView_GetRoot (g_hTreeKey))) { return; } }
if (!Recurse) { TreeView_Expand (g_hTreeKey, hItem, Expand ? TVE_EXPAND : TVE_COLLAPSE); } else {
do { hChildItem = TreeView_GetChild (g_hTreeKey, hItem);
if (hChildItem) { TreeView_Expand (g_hTreeKey, hItem, Expand ? TVE_EXPAND : TVE_COLLAPSE); KeyTreeExpandItem (hChildItem, Expand, TRUE); } } while (hItem = TreeView_GetNextSibling (g_hTreeKey, hItem)); } }
BOOL KeyTreeRightClick ( HWND hdlg, HTREEITEM hItem ) { RECT TVrect, rect; HMENU hMenu;
if (!hItem || !GetWindowRect (g_hTreeKey, &TVrect)) { return FALSE; }
TreeView_EnsureVisible (g_hTreeKey, hItem);
if (!TreeView_GetItemRect (g_hTreeKey, hItem, &rect, TRUE)) { DEBUGMSG ((DBG_ERROR, "Error getting item rectangle!")); }
if (!(hMenu = LoadMenu (g_hInst, MAKEINTRESOURCE(IDR_MENU_POPUP))) || (!(hMenu = GetSubMenu (hMenu, MENUINDEX_POPUP_KEY)))) { return FALSE; }
if (!TrackPopupMenu ( hMenu, TPM_LEFTALIGN, TVrect.left + rect.right + 4, TVrect.top + rect.top, 0, hdlg, NULL )) { return FALSE; }
return TRUE; }
BOOL KeyTreeForceEditLabel ( HTREEITEM hItem ) { if (!hItem) { return FALSE; } if (!TreeView_EditLabel (g_hTreeKey, hItem)) { TreeView_DeleteItem (g_hTreeKey, hItem); return FALSE; } return TRUE; }
HTREEITEM KeyTreeFindChildItem ( HTREEITEM hItem, PSTR Str ) { TVITEM Item; static CHAR PieceBuf[MEMDB_MAX];
Item.mask = TVIF_TEXT; Item.pszText = PieceBuf; Item.cchTextMax = MEMDB_MAX; if (hItem == NULL) { Item.hItem = TreeView_GetRoot (g_hTreeKey); } else { Item.hItem = TreeView_GetChild (g_hTreeKey, hItem); }
while (Item.hItem) { TreeView_GetItem (g_hTreeKey, &Item);
if (StringIMatchA (PieceBuf, Str)) { return Item.hItem; }
Item.hItem = TreeView_GetNextSibling (g_hTreeKey, Item.hItem); }
return NULL;
}
BOOL KeyTreeFindNext ( VOID ) { BOOL b; TurnOnWaitCursor ();
while (g_hFindItem = pKeyTreeEnumNextItem (g_hFindItem)) { if (!KeyTreeGetNameOfItem (g_hFindItem, g_Key1)) { TurnOffWaitCursor (); return FALSE; }
if (MemDbGetValueA (g_Key1, NULL)) { //
// if we are looking at an endpoint, see if it matches
//
if (g_FindParsedPattern) { b = TestParsedPatternA (g_FindParsedPattern, g_Key1); } else { b = (_mbsistr (g_Key1, g_FindString) != NULL); }
if (b) { KeyTreeSelectItem (g_hFindItem); TurnOffWaitCursor (); return TRUE; } } } TurnOffWaitCursor ();
MessageBox (NULL, "No more keys found", "MemDb Editor", MB_OK|MB_ICONINFORMATION); return FALSE; }
BOOL KeyTreeFind ( HWND hwnd ) { BOOL UsePattern;
if (!KeyFindDialog (hwnd, g_FindString, &UsePattern)) { return FALSE; }
if (g_FindParsedPattern) { //
// if we have an old pattern, destroy it.
//
DestroyParsedPatternA (g_FindParsedPattern); g_FindParsedPattern = NULL; }
if (UsePattern) { g_FindParsedPattern = CreateParsedPatternA (g_FindString); } g_hFindItem = NULL;
return KeyTreeFindNext (); }
BOOL KeyTreeCreateEmptyKey ( HTREEITEM hItem ) { TVITEM Item; UINT Index; HTREEITEM hParent;
if (hParent = TreeView_GetParent (g_hTreeKey, hItem)) { if (!KeyTreeGetNameOfItem (hParent, g_Key1)) { return FALSE; } StringCatA (g_Key1, "\\"); } else { g_Key1[0] = '\0'; }
Item.hItem = hItem; Item.mask = TVIF_TEXT; Item.pszText = GetEndOfStringA (g_Key1);
if (!TreeView_GetItem (g_hTreeKey, &Item)) { return FALSE; }
Index = MemDbAddKeyA (g_Key1);
if (!Index) { return FALSE; }
Item.mask = TVIF_PARAM; Item.lParam = Index; return TreeView_SetItem (g_hTreeKey, &Item); }
BOOL KeyTreeAddShortData ( HWND hwnd, HTREEITEM hItem, BYTE DataFlag ) { DWORD dataValue; BOOL addData; BYTE instance;
if (!hItem || (DataFlag != DATAFLAG_VALUE) && (DataFlag != DATAFLAG_FLAGS)) { return FALSE; }
if (!KeyTreeGetNameOfItem (hItem, g_Key1)) { DEBUGMSG ((DBG_ERROR, "Could not get item name!")); return FALSE; }
if (!ShortDataDialog (hwnd, DataFlag, &dataValue, &addData, &instance)) { return FALSE; }
if (addData) { if (!MemDbAddUnorderedBlobA (g_Key1, instance, (PBYTE) &dataValue, sizeof (dataValue))) { DEBUGMSG ((DBG_ERROR, "Could not add data to item!")); return FALSE; } } else if (DataFlag == DATAFLAG_VALUE) {
if (!MemDbSetValue (g_Key1, dataValue)) { DEBUGMSG ((DBG_ERROR, "Could not set value of item!")); return FALSE; } } else if (DataFlag == DATAFLAG_FLAGS) {
if (!MemDbSetFlags (g_Key1, dataValue, (UINT) -1)) { DEBUGMSG ((DBG_ERROR, "Could not set flag of item!")); return FALSE; } }
pKeyTreeDisplayItemData (hItem);
return TRUE; }
BOOL KeyTreeClearData ( HTREEITEM hItem ) { if (!hItem || !KeyTreeGetNameOfItem (hItem, g_Key1)) { return FALSE; }
if (MemDbTestKey (g_Key1)) { MemDbDeleteKey (g_Key1); if (!MemDbAddKey (g_Key1)) { return FALSE; } }
pKeyTreeDisplayItemData (hItem); return TRUE; }
VOID KeyTreeSetFilterPattern ( PSTR Pattern ) { KeyAddSetFilterPattern (Pattern); }
BOOL KeyTreeCreateLinkage ( HWND hdlg, HTREEITEM hItem, BOOL SingleLinkage, BYTE Instance ) { BOOL b = TRUE;
if (hItem) { KeyTreeGetNameOfItem (hItem, g_Key1); } else { g_Key1[0] = '\0'; } g_Key2[0] = '\0';
if (!LinkageDialog (hdlg, g_Key1, g_Key2)) { return FALSE; }
if (SingleLinkage) { if (!MemDbAddSingleLinkage (g_Key1, g_Key2, Instance)) { DEBUGMSG ((DBG_ERROR, "Could not create linkage between %s and %s!", g_Key1, g_Key2)); return FALSE; } } else { if (!MemDbAddDoubleLinkage (g_Key1, g_Key2, Instance)) { DEBUGMSG ((DBG_ERROR, "Could not create double linkage between %s and %s!", g_Key1, g_Key2)); return FALSE; } }
pKeyTreeDisplayItemData (hItem);
return TRUE; }
|