[regedit]

- Implement RegFindRecurse, RegFindWalk and helpers to find registry keys. Remove RegNextKey as its no longer used. Other misc fixes. Fixes searching in regedit. Patch by Katayama_Hirofumi.

svn path=/trunk/; revision=47233
This commit is contained in:
Michael Martin 2010-05-16 04:57:24 +00:00
parent fa5c83b451
commit 5ab3830ab5
4 changed files with 590 additions and 200 deletions

View file

@ -25,13 +25,531 @@ static const TCHAR s_szFindFlagsR[] = _T("FindFlagsReactOS");
static HWND s_hwndAbortDialog;
static BOOL s_bAbort;
static DWORD s_dwFlags;
static TCHAR s_szName[MAX_PATH];
static DWORD s_cbName;
static const TCHAR s_empty[] = {0};
static const TCHAR s_backslash[] = {'\\', 0};
extern VOID SetValueName(HWND hwndLV, LPCTSTR pszValueName);
BOOL DoEvents(VOID)
{
MSG msg;
if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
if (msg.message == WM_QUIT)
s_bAbort = TRUE;
if (!IsDialogMessage(s_hwndAbortDialog, &msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
return s_bAbort;
}
static LPTSTR lstrstri(LPCTSTR psz1, LPCTSTR psz2)
{
INT i, cch1, cch2;
cch1 = lstrlen(psz1);
cch2 = lstrlen(psz2);
for(i = 0; i <= cch1 - cch2; i++)
{
if (CompareString(LOCALE_SYSTEM_DEFAULT, NORM_IGNORECASE,
psz1 + i, cch2, psz2, cch2) == 2)
return (LPTSTR) (psz1 + i);
}
return NULL;
}
static BOOL CompareName(LPCTSTR pszName1, LPCTSTR pszName2)
{
if (s_dwFlags & RSF_WHOLESTRING)
{
if (s_dwFlags & RSF_MATCHCASE)
return lstrcmp(pszName1, pszName2) == 0;
else
return lstrcmpi(pszName1, pszName2) == 0;
}
else
{
if (s_dwFlags & RSF_MATCHCASE)
return _tcsstr(pszName1, pszName2) != NULL;
else
return lstrstri(pszName1, pszName2) != NULL;
}
}
static BOOL
CompareData(
DWORD dwType,
LPCTSTR psz1,
LPCTSTR psz2)
{
INT i, cch1 = lstrlen(psz1), cch2 = lstrlen(psz2);
if (dwType == REG_SZ || dwType == REG_EXPAND_SZ)
{
if (s_dwFlags & RSF_WHOLESTRING)
{
if (s_dwFlags & RSF_MATCHCASE)
return 2 == CompareString(LOCALE_SYSTEM_DEFAULT, 0,
psz1, cch1, psz2, cch2);
else
return 2 == CompareString(LOCALE_SYSTEM_DEFAULT,
NORM_IGNORECASE, psz1, cch1, psz2, cch2);
}
for(i = 0; i <= cch1 - cch2; i++)
{
if (s_dwFlags & RSF_MATCHCASE)
{
if (2 == CompareString(LOCALE_SYSTEM_DEFAULT, 0,
psz1 + i, cch2, psz2, cch2))
return TRUE;
}
else
{
if (2 == CompareString(LOCALE_SYSTEM_DEFAULT,
NORM_IGNORECASE, psz1 + i, cch2, psz2, cch2))
return TRUE;
}
}
}
return FALSE;
}
int compare(const void *x, const void *y)
{
const LPCTSTR *a = (const LPCTSTR *)x;
const LPCTSTR *b = (const LPCTSTR *)y;
return lstrcmpi(*a, *b);
}
BOOL RegFindRecurse(
HKEY hKey,
LPCTSTR pszSubKey,
LPCTSTR pszValueName,
LPTSTR *ppszFoundSubKey,
LPTSTR *ppszFoundValueName)
{
HKEY hSubKey;
LONG lResult;
TCHAR szSubKey[MAX_PATH];
DWORD i, c, cb, type;
BOOL fPast = FALSE;
LPTSTR *ppszNames = NULL;
LPBYTE pb = NULL;
if (DoEvents())
return FALSE;
lstrcpy(szSubKey, pszSubKey);
hSubKey = NULL;
lResult = RegOpenKeyEx(hKey, szSubKey, 0, KEY_ALL_ACCESS, &hSubKey);
if (lResult != ERROR_SUCCESS)
return FALSE;
if (pszValueName == NULL)
pszValueName = s_empty;
lResult = RegQueryInfoKey(hSubKey, NULL, NULL, NULL, NULL, NULL, NULL,
&c, NULL, NULL, NULL, NULL);
if (lResult != ERROR_SUCCESS)
goto err;
ppszNames = (LPTSTR *) malloc(c * sizeof(LPTSTR));
if (ppszNames == NULL)
goto err;
ZeroMemory(ppszNames, c * sizeof(LPTSTR));
for(i = 0; i < c; i++)
{
if (DoEvents())
goto err;
s_cbName = MAX_PATH * sizeof(TCHAR);
lResult = RegEnumValue(hSubKey, i, s_szName, &s_cbName, NULL, NULL,
NULL, &cb);
if (lResult == ERROR_NO_MORE_ITEMS)
{
c = i;
break;
}
if (lResult != ERROR_SUCCESS)
goto err;
if (s_cbName >= MAX_PATH * sizeof(TCHAR))
continue;
ppszNames[i] = _tcsdup(s_szName);
}
qsort(ppszNames, c, sizeof(LPTSTR), compare);
for(i = 0; i < c; i++)
{
if (DoEvents())
goto err;
if (!fPast && lstrcmpi(ppszNames[i], pszValueName) == 0)
{
fPast = TRUE;
continue;
}
if (!fPast)
continue;
if ((s_dwFlags & RSF_LOOKATVALUES) &&
CompareName(ppszNames[i], s_szFindWhat))
{
*ppszFoundSubKey = _tcsdup(szSubKey);
if (ppszNames[i][0] == 0)
*ppszFoundValueName = NULL;
else
*ppszFoundValueName = _tcsdup(ppszNames[i]);
goto success;
}
lResult = RegQueryValueEx(hSubKey, ppszNames[i], NULL, &type,
NULL, &cb);
if (lResult != ERROR_SUCCESS)
goto err;
pb = malloc(cb);
if (pb == NULL)
goto err;
lResult = RegQueryValueEx(hSubKey, ppszNames[i], NULL, &type,
pb, &cb);
if (lResult != ERROR_SUCCESS)
goto err;
if ((s_dwFlags & RSF_LOOKATDATA) &&
CompareData(type, (LPTSTR) pb, s_szFindWhat))
{
*ppszFoundSubKey = _tcsdup(szSubKey);
if (ppszNames[i][0] == 0)
*ppszFoundValueName = NULL;
else
*ppszFoundValueName = _tcsdup(ppszNames[i]);
goto success;
}
free(pb);
pb = NULL;
}
if (ppszNames != NULL)
{
for(i = 0; i < c; i++)
free(ppszNames[i]);
free(ppszNames);
}
ppszNames = NULL;
lResult = RegQueryInfoKey(hSubKey, NULL, NULL, NULL, &c, NULL, NULL,
NULL, NULL, NULL, NULL, NULL);
if (lResult != ERROR_SUCCESS)
goto err;
ppszNames = (LPTSTR *) malloc(c * sizeof(LPTSTR));
if (ppszNames == NULL)
goto err;
ZeroMemory(ppszNames, c * sizeof(LPTSTR));
for(i = 0; i < c; i++)
{
if (DoEvents())
goto err;
s_cbName = MAX_PATH * sizeof(TCHAR);
lResult = RegEnumKeyEx(hSubKey, i, s_szName, &s_cbName, NULL, NULL,
NULL, NULL);
if (lResult == ERROR_NO_MORE_ITEMS)
{
c = i;
break;
}
if (lResult != ERROR_SUCCESS)
goto err;
if (s_cbName >= MAX_PATH * sizeof(TCHAR))
continue;
ppszNames[i] = _tcsdup(s_szName);
}
qsort(ppszNames, c, sizeof(LPTSTR), compare);
for(i = 0; i < c; i++)
{
if (DoEvents())
goto err;
if ((s_dwFlags & RSF_LOOKATKEYS) &&
CompareName(ppszNames[i], s_szFindWhat))
{
*ppszFoundSubKey = malloc(
(lstrlen(szSubKey) + lstrlen(ppszNames[i]) + 2) *
sizeof(TCHAR));
if (*ppszFoundSubKey == NULL)
goto err;
if (szSubKey[0])
{
lstrcpy(*ppszFoundSubKey, szSubKey);
lstrcatW(*ppszFoundSubKey, s_backslash);
}
else
**ppszFoundSubKey = 0;
lstrcatW(*ppszFoundSubKey, ppszNames[i]);
*ppszFoundValueName = NULL;
goto success;
}
if (RegFindRecurse(hSubKey, ppszNames[i], NULL, ppszFoundSubKey,
ppszFoundValueName))
{
LPTSTR psz = *ppszFoundSubKey;
*ppszFoundSubKey = malloc(
(lstrlen(szSubKey) + lstrlen(psz) + 2) * sizeof(TCHAR));
if (*ppszFoundSubKey == NULL)
goto err;
if (szSubKey[0])
{
lstrcpy(*ppszFoundSubKey, szSubKey);
lstrcatW(*ppszFoundSubKey, s_backslash);
}
else
**ppszFoundSubKey = 0;
lstrcatW(*ppszFoundSubKey, psz);
free(psz);
goto success;
}
}
err:
if (ppszNames != NULL)
{
for(i = 0; i < c; i++)
free(ppszNames[i]);
free(ppszNames);
}
free(pb);
RegCloseKey(hSubKey);
return FALSE;
success:
if (ppszNames != NULL)
{
for(i = 0; i < c; i++)
free(ppszNames[i]);
free(ppszNames);
}
RegCloseKey(hSubKey);
return TRUE;
}
BOOL RegFindWalk(
HKEY * phKey,
LPCTSTR pszSubKey,
LPCTSTR pszValueName,
LPTSTR *ppszFoundSubKey,
LPTSTR *ppszFoundValueName)
{
LONG lResult;
DWORD i, c;
HKEY hBaseKey, hSubKey;
TCHAR szKeyName[MAX_PATH];
TCHAR szSubKey[MAX_PATH];
LPTSTR pch;
BOOL fPast;
LPTSTR *ppszNames = NULL;
hBaseKey = *phKey;
if (RegFindRecurse(hBaseKey, pszSubKey, pszValueName, ppszFoundSubKey,
ppszFoundValueName))
return TRUE;
if (lstrlen(pszSubKey) >= MAX_PATH)
return FALSE;
lstrcpy(szSubKey, pszSubKey);
while(szSubKey[0] != 0)
{
if (DoEvents())
return FALSE;
pch = _tcsrchr(szSubKey, _T('\\'));
if (pch == NULL)
{
lstrcpy(szKeyName, szSubKey);
szSubKey[0] = 0;
hSubKey = hBaseKey;
}
else
{
lstrcpyn(szKeyName, pch + 1, MAX_PATH);
*pch = 0;
lResult = RegOpenKeyEx(hBaseKey, szSubKey, 0, KEY_ALL_ACCESS,
&hSubKey);
if (lResult != ERROR_SUCCESS)
return FALSE;
}
lResult = RegQueryInfoKey(hSubKey, NULL, NULL, NULL, &c, NULL, NULL,
NULL, NULL, NULL, NULL, NULL);
if (lResult != ERROR_SUCCESS)
goto err;
ppszNames = (LPTSTR *) malloc(c * sizeof(LPTSTR));
if (ppszNames == NULL)
goto err;
ZeroMemory(ppszNames, c * sizeof(LPTSTR));
for(i = 0; i < c; i++)
{
if (DoEvents())
goto err;
s_cbName = MAX_PATH * sizeof(TCHAR);
lResult = RegEnumKeyExW(hSubKey, i, s_szName, &s_cbName,
NULL, NULL, NULL, NULL);
if (lResult == ERROR_NO_MORE_ITEMS)
{
c = i;
break;
}
if (lResult != ERROR_SUCCESS)
break;
ppszNames[i] = _tcsdup(s_szName);
}
qsort(ppszNames, c, sizeof(LPTSTR), compare);
fPast = FALSE;
for(i = 0; i < c; i++)
{
if (DoEvents())
goto err;
if (!fPast && lstrcmpi(ppszNames[i], szKeyName) == 0)
{
fPast = TRUE;
continue;
}
if (!fPast)
continue;
if ((s_dwFlags & RSF_LOOKATKEYS) &&
CompareName(ppszNames[i], s_szFindWhat))
{
*ppszFoundSubKey = malloc(
(lstrlen(szSubKey) + lstrlen(ppszNames[i]) + 2) *
sizeof(TCHAR));
if (*ppszFoundSubKey == NULL)
goto err;
if (szSubKey[0])
{
lstrcpy(*ppszFoundSubKey, szSubKey);
lstrcatW(*ppszFoundSubKey, s_backslash);
}
else
**ppszFoundSubKey = 0;
lstrcatW(*ppszFoundSubKey, ppszNames[i]);
*ppszFoundValueName = NULL;
goto success;
}
if (RegFindRecurse(hSubKey, ppszNames[i], NULL,
ppszFoundSubKey, ppszFoundValueName))
{
LPTSTR psz = *ppszFoundSubKey;
*ppszFoundSubKey = malloc(
(lstrlen(szSubKey) + lstrlen(psz) + 2) *
sizeof(TCHAR));
if (*ppszFoundSubKey == NULL)
goto err;
if (szSubKey[0])
{
lstrcpy(*ppszFoundSubKey, szSubKey);
lstrcatW(*ppszFoundSubKey, s_backslash);
}
else
**ppszFoundSubKey = 0;
lstrcatW(*ppszFoundSubKey, psz);
free(psz);
goto success;
}
}
if (ppszNames != NULL)
{
for(i = 0; i < c; i++)
free(ppszNames[i]);
free(ppszNames);
}
ppszNames = NULL;
if (hBaseKey != hSubKey)
RegCloseKey(hSubKey);
}
if (*phKey == HKEY_CLASSES_ROOT)
{
*phKey = HKEY_CURRENT_USER;
if (RegFindRecurse(*phKey, s_empty, NULL, ppszFoundSubKey,
ppszFoundValueName))
return TRUE;
}
if (*phKey == HKEY_CURRENT_USER)
{
*phKey = HKEY_LOCAL_MACHINE;
if (RegFindRecurse(*phKey, s_empty, NULL, ppszFoundSubKey,
ppszFoundValueName))
goto success;
}
if (*phKey == HKEY_LOCAL_MACHINE)
{
*phKey = HKEY_USERS;
if (RegFindRecurse(*phKey, s_empty, NULL, ppszFoundSubKey,
ppszFoundValueName))
goto success;
}
if (*phKey == HKEY_USERS)
{
*phKey = HKEY_CURRENT_CONFIG;
if (RegFindRecurse(*phKey, s_empty, NULL, ppszFoundSubKey,
ppszFoundValueName))
goto success;
}
err:
if (ppszNames != NULL)
{
for(i = 0; i < c; i++)
free(ppszNames[i]);
free(ppszNames);
}
if (hBaseKey != hSubKey)
RegCloseKey(hSubKey);
return FALSE;
success:
if (ppszNames != NULL)
{
for(i = 0; i < c; i++)
free(ppszNames[i]);
free(ppszNames);
}
if (hBaseKey != hSubKey)
RegCloseKey(hSubKey);
return TRUE;
}
static DWORD GetFindFlags(void)
{
HKEY hKey;
DWORD dwFlags = RSF_LOOKATKEYS;
DWORD dwType, dwValue, cbData;
DWORD dwFlags = RSF_LOOKATKEYS | RSF_LOOKATVALUES | RSF_LOOKATDATA;
if (RegOpenKey(HKEY_CURRENT_USER, g_szGeneralRegKey, &hKey) == ERROR_SUCCESS)
{
@ -102,45 +620,48 @@ static INT_PTR CALLBACK AbortFindDialogProc(HWND hDlg, UINT uMsg, WPARAM wParam,
return 0;
}
static BOOL RegSearchProc(LPVOID lpParam)
{
MSG msg;
UNREFERENCED_PARAMETER(lpParam);
if (s_hwndAbortDialog && PeekMessage(&msg, s_hwndAbortDialog, 0, 0, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return s_bAbort;
}
BOOL FindNext(HWND hWnd)
{
HKEY hKeyRoot;
LPCTSTR pszFindWhat;
LPCTSTR pszKeyPath;
DWORD dwFlags;
LONG lResult;
TCHAR szSubKey[512];
TCHAR szError[512];
TCHAR szTitle[64];
BOOL fSuccess;
TCHAR szFullKey[512];
LPCTSTR pszValueName;
LPTSTR pszFoundSubKey, pszFoundValueName;
pszFindWhat = s_szFindWhat;
dwFlags = GetFindFlags() & ~(RSF_LOOKATVALUES | RSF_LOOKATDATA);
s_dwFlags = GetFindFlags();
pszKeyPath = GetItemPath(g_pChildWnd->hTreeWnd, 0, &hKeyRoot);
lstrcpyn(szSubKey, pszKeyPath, sizeof(szSubKey) / sizeof(szSubKey[0]));
if (pszKeyPath == NULL)
{
hKeyRoot = HKEY_CLASSES_ROOT;
pszKeyPath = s_empty;
}
/* Create abort find dialog */
s_hwndAbortDialog = CreateDialog(GetModuleHandle(NULL), MAKEINTRESOURCE(IDD_FINDING), hWnd, AbortFindDialogProc);
s_hwndAbortDialog = CreateDialog(GetModuleHandle(NULL),
MAKEINTRESOURCE(IDD_FINDING), hWnd, AbortFindDialogProc);
if (s_hwndAbortDialog)
{
ShowWindow(s_hwndAbortDialog, SW_SHOW);
UpdateWindow(s_hwndAbortDialog);
}
s_bAbort = FALSE;
lResult = RegSearch(hKeyRoot, szSubKey, sizeof(szSubKey) / sizeof(szSubKey[0]),
pszFindWhat, 0, dwFlags, RegSearchProc, NULL);
pszValueName = GetValueName(g_pChildWnd->hListWnd, -1);
EnableWindow(hFrameWnd, FALSE);
EnableWindow(g_pChildWnd->hTreeWnd, FALSE);
EnableWindow(g_pChildWnd->hListWnd, FALSE);
EnableWindow(g_pChildWnd->hAddressBarWnd, FALSE);
fSuccess = RegFindWalk(&hKeyRoot, pszKeyPath, pszValueName,
&pszFoundSubKey, &pszFoundValueName);
EnableWindow(hFrameWnd, TRUE);
EnableWindow(g_pChildWnd->hTreeWnd, TRUE);
EnableWindow(g_pChildWnd->hListWnd, TRUE);
EnableWindow(g_pChildWnd->hAddressBarWnd, TRUE);
if (s_hwndAbortDialog)
{
@ -148,25 +669,15 @@ BOOL FindNext(HWND hWnd)
s_hwndAbortDialog = NULL;
}
/* Did the user click "Cancel"? If so, exit without displaying an error message */
if (lResult == ERROR_OPERATION_ABORTED)
return FALSE;
if (lResult != ERROR_SUCCESS)
if (fSuccess)
{
LoadString(NULL, IDS_APP_TITLE, szTitle, sizeof(szTitle) / sizeof(szTitle[0]));
if ((lResult != ERROR_NO_MORE_ITEMS) || !LoadString(NULL, IDS_FINISHEDFIND, szError, sizeof(szError) / sizeof(szError[0])))
{
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, lResult, 0,
szError, sizeof(szError) / sizeof(szError[0]), NULL);
}
MessageBox(hWnd, szError, szTitle, MB_OK);
return FALSE;
RegKeyGetName(szFullKey, COUNT_OF(szFullKey), hKeyRoot, pszFoundSubKey);
SelectNode(g_pChildWnd->hTreeWnd, szFullKey);
SetValueName(g_pChildWnd->hListWnd, pszFoundValueName);
free(pszFoundSubKey);
free(pszFoundValueName);
SetFocus(g_pChildWnd->hListWnd);
}
RegKeyGetName(szFullKey, sizeof(szFullKey) / sizeof(szFullKey[0]), hKeyRoot, szSubKey);
SelectNode(g_pChildWnd->hTreeWnd, szFullKey);
return TRUE;
}
@ -183,26 +694,17 @@ static INT_PTR CALLBACK FindDialogProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPAR
case WM_INITDIALOG:
dwFlags = GetFindFlags();
/* Looking at values is not yet implemented */
hControl = GetDlgItem(hDlg, IDC_LOOKAT_KEYS);
if (hControl)
SendMessage(hControl, BM_SETCHECK, (dwFlags & RSF_LOOKATKEYS) ? TRUE : FALSE, 0);
/* Looking at values is not yet implemented */
hControl = GetDlgItem(hDlg, IDC_LOOKAT_VALUES);
if (hControl)
{
lStyle = GetWindowLongPtr(hControl, GWL_STYLE);
SetWindowLongPtr(hControl, GWL_STYLE, lStyle | WS_DISABLED);
}
SendMessage(hControl, BM_SETCHECK, (dwFlags & RSF_LOOKATVALUES) ? TRUE : FALSE, 0);
/* Looking at data is not yet implemented */
hControl = GetDlgItem(hDlg, IDC_LOOKAT_DATA);
if (hControl)
{
lStyle = GetWindowLongPtr(hControl, GWL_STYLE);
SetWindowLongPtr(hControl, GWL_STYLE, lStyle | WS_DISABLED);
}
SendMessage(hControl, BM_SETCHECK, (dwFlags & RSF_LOOKATDATA) ? TRUE : FALSE, 0);
/* Match whole string */
hControl = GetDlgItem(hDlg, IDC_MATCHSTRING);

View file

@ -27,6 +27,7 @@
int Image_String = 0;
int Image_Bin = 0;
INT iListViewSelect = -1;
typedef struct tagLINE_INFO
{
@ -76,6 +77,29 @@ LPCTSTR GetValueName(HWND hwndLV, int iStartAt)
return lineinfo->name;
}
VOID SetValueName(HWND hwndLV, LPCTSTR pszValueName)
{
INT i, c;
LV_FINDINFO fi;
c = ListView_GetItemCount(hwndLV);
for(i = 0; i < c; i++)
{
ListView_SetItemState(hwndLV, i, 0, LVIS_FOCUSED | LVIS_SELECTED);
}
if (pszValueName == NULL)
i = 0;
else
{
fi.flags = LVFI_STRING;
fi.psz = pszValueName;
i = ListView_FindItem(hwndLV, -1, &fi);
}
ListView_SetItemState(hwndLV, i, LVIS_FOCUSED | LVIS_SELECTED,
LVIS_FOCUSED | LVIS_SELECTED);
iListViewSelect = i;
}
BOOL IsDefaultValue(HWND hwndLV, int i)
{
PLINE_INFO lineinfo;
@ -497,6 +521,7 @@ BOOL RefreshListView(HWND hwndLV, HKEY hKey, LPCTSTR keyPath)
DWORD val_count;
HKEY hNewKey;
LONG errCode;
INT i, c;
BOOL AddedDefault = FALSE;
if (!hwndLV) return FALSE;
@ -552,7 +577,15 @@ BOOL RefreshListView(HWND hwndLV, HKEY hKey, LPCTSTR keyPath)
{
AddEntryToList(hwndLV, _T(""), REG_SZ, NULL, 0, 0, FALSE);
}
(void)ListView_SortItems(hwndLV, CompareFunc, (WPARAM)hwndLV);
ListView_SortItems(hwndLV, CompareFunc, (WPARAM)hwndLV);
c = ListView_GetItemCount(hwndLV);
for(i = 0; i < c; i++)
{
ListView_SetItemState(hwndLV, i, 0, LVIS_FOCUSED | LVIS_SELECTED);
}
ListView_SetItemState(hwndLV, iListViewSelect,
LVIS_FOCUSED | LVIS_SELECTED,
LVIS_FOCUSED | LVIS_SELECTED);
RegCloseKey(hNewKey);
SendMessage(hwndLV, WM_SETREDRAW, TRUE, 0);

View file

@ -1497,147 +1497,6 @@ done:
return lResult;
}
/******************************************************************************
* Searching
*/
static LONG RegNextKey(HKEY hKey, LPTSTR lpSubKey, size_t iSubKeyLength)
{
LONG lResult;
LPTSTR s;
LPCTSTR pszOriginalKey;
TCHAR szKeyName[256];
HKEY hSubKey, hBaseKey;
DWORD dwIndex = 0;
DWORD cbName;
FILETIME ft;
BOOL bFoundKey = FALSE;
/* Try accessing a subkey */
if (RegOpenKeyEx(hKey, lpSubKey, 0, KEY_ALL_ACCESS, &hSubKey) == ERROR_SUCCESS)
{
cbName = (DWORD) iSubKeyLength - _tcslen(lpSubKey) - 1;
lResult = RegEnumKeyEx(hSubKey, 0, lpSubKey + _tcslen(lpSubKey) + 1,
&cbName, NULL, NULL, NULL, &ft);
RegCloseKey(hSubKey);
if (lResult == ERROR_SUCCESS)
{
lpSubKey[_tcslen(lpSubKey)] = '\\';
bFoundKey = TRUE;
}
}
if (!bFoundKey)
{
/* Go up and find the next sibling key */
do
{
s = _tcsrchr(lpSubKey, TEXT('\\'));
if (s)
{
*s = '\0';
pszOriginalKey = s + 1;
hBaseKey = NULL;
RegOpenKeyEx(hKey, lpSubKey, 0, KEY_ALL_ACCESS, &hBaseKey);
}
else
{
pszOriginalKey = lpSubKey;
hBaseKey = hKey;
}
if (hBaseKey)
{
dwIndex = 0;
do
{
lResult = RegEnumKey(hBaseKey, dwIndex++, szKeyName, sizeof(szKeyName) / sizeof(szKeyName[0]));
}
while((lResult == ERROR_SUCCESS) && _tcscmp(szKeyName, pszOriginalKey));
if (lResult == ERROR_SUCCESS)
{
lResult = RegEnumKey(hBaseKey, dwIndex++, szKeyName, sizeof(szKeyName) / sizeof(szKeyName[0]));
if (lResult == ERROR_SUCCESS)
{
bFoundKey = TRUE;
_sntprintf(lpSubKey + _tcslen(lpSubKey), iSubKeyLength - _tcslen(lpSubKey), _T("\\%s"), szKeyName);
}
}
RegCloseKey(hBaseKey);
}
}
while(!bFoundKey);
}
return bFoundKey ? ERROR_SUCCESS : ERROR_NO_MORE_ITEMS;
}
static BOOL RegSearchCompare(LPCTSTR s1, LPCTSTR s2, DWORD dwSearchFlags)
{
BOOL bResult;
if (dwSearchFlags & RSF_WHOLESTRING)
{
if (dwSearchFlags & RSF_MATCHCASE)
bResult = !_tcscmp(s1, s2);
else
bResult = !_tcsicmp(s1, s2);
}
else
{
if (dwSearchFlags & RSF_MATCHCASE)
bResult = (_tcsstr(s1, s2) != NULL);
else
{
/* My kingdom for _tcsistr() */
bResult = FALSE;
while(*s1)
{
if (!_tcsnicmp(s1, s2, _tcslen(s2)))
{
bResult = TRUE;
break;
}
s1++;
}
}
}
return bResult;
}
LONG RegSearch(HKEY hKey, LPTSTR lpSubKey, size_t iSubKeyLength,
LPCTSTR pszSearchString, DWORD dwValueIndex,
DWORD dwSearchFlags, BOOL (*pfnCallback)(LPVOID), LPVOID lpParam)
{
LONG lResult;
LPCTSTR s;
UNREFERENCED_PARAMETER(dwValueIndex);
if (dwSearchFlags & (RSF_LOOKATVALUES | RSF_LOOKATDATA))
return ERROR_CALL_NOT_IMPLEMENTED; /* NYI */
do
{
if (pfnCallback)
{
if (pfnCallback(lpParam))
return ERROR_OPERATION_ABORTED;
}
lResult = RegNextKey(hKey, lpSubKey, iSubKeyLength);
if (lResult != ERROR_SUCCESS)
return lResult;
s = _tcsrchr(lpSubKey, TEXT('\\'));
s = s ? s + 1 : lpSubKey;
}
while(!(dwSearchFlags & RSF_LOOKATKEYS) || !RegSearchCompare(s, pszSearchString, dwSearchFlags));
return ERROR_SUCCESS;
}
/******************************************************************************
* Key naming and parsing
*/

View file

@ -92,10 +92,6 @@ LONG RegQueryStringValue(HKEY hKey, LPCTSTR lpSubKey, LPCTSTR lpValueName, LPTST
#define RSF_LOOKATDATA 0x00000008
#define RSF_MATCHCASE 0x00010000
LONG RegSearch(HKEY hKey, LPTSTR lpSubKey, size_t iSubKeyLength,
LPCTSTR pszSearchString, DWORD dwValueIndex,
DWORD dwSearchFlags, BOOL (*pfnCallback)(LPVOID), LPVOID lpParam);
BOOL RegKeyGetName(LPTSTR pszDest, size_t iDestLength, HKEY hRootKey, LPCTSTR lpSubKey);
/* EOF */