mirror of
https://github.com/reactos/reactos.git
synced 2024-11-11 01:04:11 +00:00
1fb94b1cb5
sync with trunk (r49230) svn path=/branches/cmake-bringup/; revision=49246
826 lines
24 KiB
C
826 lines
24 KiB
C
/*
|
|
* Regedit find dialog
|
|
*
|
|
* This library is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
* License as published by the Free Software Foundation; either
|
|
* version 2.1 of the License, or (at your option) any later version.
|
|
*
|
|
* This library is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
* Lesser General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
* License along with this library; if not, write to the Free Software
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
*/
|
|
|
|
|
|
#include <regedit.h>
|
|
|
|
#define RSF_WHOLESTRING 0x00000001
|
|
#define RSF_LOOKATKEYS 0x00000002
|
|
#define RSF_LOOKATVALUES 0x00000004
|
|
#define RSF_LOOKATDATA 0x00000008
|
|
#define RSF_MATCHCASE 0x00010000
|
|
|
|
static TCHAR s_szFindWhat[256];
|
|
static const TCHAR s_szFindFlags[] = _T("FindFlags");
|
|
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 dwType, dwValue, cbData;
|
|
DWORD dwFlags = RSF_LOOKATKEYS | RSF_LOOKATVALUES | RSF_LOOKATDATA;
|
|
|
|
if (RegOpenKey(HKEY_CURRENT_USER, g_szGeneralRegKey, &hKey) == ERROR_SUCCESS)
|
|
{
|
|
/* Retrieve flags from registry key */
|
|
cbData = sizeof(dwValue);
|
|
if (RegQueryValueEx(hKey, s_szFindFlags, NULL, &dwType, (LPBYTE) &dwValue, &cbData) == ERROR_SUCCESS)
|
|
{
|
|
if (dwType == REG_DWORD)
|
|
dwFlags = (dwFlags & ~0x0000FFFF) | ((dwValue & 0x0000FFFF) << 0);
|
|
}
|
|
|
|
/* Retrieve ReactOS Regedit specific flags from registry key */
|
|
cbData = sizeof(dwValue);
|
|
if (RegQueryValueEx(hKey, s_szFindFlagsR, NULL, &dwType, (LPBYTE) &dwValue, &cbData) == ERROR_SUCCESS)
|
|
{
|
|
if (dwType == REG_DWORD)
|
|
dwFlags = (dwFlags & ~0xFFFF0000) | ((dwValue & 0x0000FFFF) << 16);
|
|
}
|
|
|
|
RegCloseKey(hKey);
|
|
}
|
|
return dwFlags;
|
|
}
|
|
|
|
static void SetFindFlags(DWORD dwFlags)
|
|
{
|
|
HKEY hKey;
|
|
DWORD dwDisposition;
|
|
DWORD dwData;
|
|
|
|
if (RegCreateKeyEx(HKEY_CURRENT_USER, g_szGeneralRegKey, 0, NULL, 0, KEY_ALL_ACCESS, NULL, &hKey, &dwDisposition) == ERROR_SUCCESS)
|
|
{
|
|
dwData = (dwFlags >> 0) & 0x0000FFFF;
|
|
RegSetValueEx(hKey, s_szFindFlags, 0, REG_DWORD, (const BYTE *) &dwData, sizeof(dwData));
|
|
|
|
dwData = (dwFlags >> 16) & 0x0000FFFF;
|
|
RegSetValueEx(hKey, s_szFindFlagsR, 0, REG_DWORD, (const BYTE *) &dwData, sizeof(dwData));
|
|
|
|
RegCloseKey(hKey);
|
|
}
|
|
}
|
|
|
|
static INT_PTR CALLBACK AbortFindDialogProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
UNREFERENCED_PARAMETER(lParam);
|
|
UNREFERENCED_PARAMETER(hDlg);
|
|
|
|
switch(uMsg)
|
|
{
|
|
case WM_CLOSE:
|
|
s_bAbort = TRUE;
|
|
break;
|
|
|
|
case WM_COMMAND:
|
|
switch(HIWORD(wParam))
|
|
{
|
|
case BN_CLICKED:
|
|
switch(LOWORD(wParam))
|
|
{
|
|
case IDCANCEL:
|
|
s_bAbort = TRUE;
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
BOOL FindNext(HWND hWnd)
|
|
{
|
|
HKEY hKeyRoot;
|
|
LPCTSTR pszKeyPath;
|
|
BOOL fSuccess;
|
|
TCHAR szFullKey[512];
|
|
LPCTSTR pszValueName;
|
|
LPTSTR pszFoundSubKey, pszFoundValueName;
|
|
|
|
if (_tcslen(s_szFindWhat) == 0)
|
|
{
|
|
FindDialog(hWnd);
|
|
return TRUE;
|
|
}
|
|
|
|
s_dwFlags = GetFindFlags();
|
|
|
|
pszKeyPath = GetItemPath(g_pChildWnd->hTreeWnd, 0, &hKeyRoot);
|
|
if (pszKeyPath == NULL)
|
|
{
|
|
hKeyRoot = HKEY_CLASSES_ROOT;
|
|
pszKeyPath = s_empty;
|
|
}
|
|
|
|
/* Create abort find dialog */
|
|
s_hwndAbortDialog = CreateDialog(GetModuleHandle(NULL),
|
|
MAKEINTRESOURCE(IDD_FINDING), hWnd, AbortFindDialogProc);
|
|
if (s_hwndAbortDialog)
|
|
{
|
|
ShowWindow(s_hwndAbortDialog, SW_SHOW);
|
|
UpdateWindow(s_hwndAbortDialog);
|
|
}
|
|
s_bAbort = FALSE;
|
|
|
|
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)
|
|
{
|
|
DestroyWindow(s_hwndAbortDialog);
|
|
s_hwndAbortDialog = NULL;
|
|
}
|
|
|
|
if (fSuccess)
|
|
{
|
|
GetKeyName(szFullKey, COUNT_OF(szFullKey), hKeyRoot, pszFoundSubKey);
|
|
SelectNode(g_pChildWnd->hTreeWnd, szFullKey);
|
|
SetValueName(g_pChildWnd->hListWnd, pszFoundValueName);
|
|
free(pszFoundSubKey);
|
|
free(pszFoundValueName);
|
|
SetFocus(g_pChildWnd->hListWnd);
|
|
}
|
|
return fSuccess || s_bAbort;
|
|
}
|
|
|
|
static INT_PTR CALLBACK FindDialogProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
INT_PTR iResult = 0;
|
|
HWND hControl;
|
|
LONG lStyle;
|
|
DWORD dwFlags;
|
|
static TCHAR s_szSavedFindValue[256];
|
|
|
|
switch(uMsg)
|
|
{
|
|
case WM_INITDIALOG:
|
|
dwFlags = GetFindFlags();
|
|
|
|
hControl = GetDlgItem(hDlg, IDC_LOOKAT_KEYS);
|
|
if (hControl)
|
|
SendMessage(hControl, BM_SETCHECK, (dwFlags & RSF_LOOKATKEYS) ? TRUE : FALSE, 0);
|
|
|
|
hControl = GetDlgItem(hDlg, IDC_LOOKAT_VALUES);
|
|
if (hControl)
|
|
SendMessage(hControl, BM_SETCHECK, (dwFlags & RSF_LOOKATVALUES) ? TRUE : FALSE, 0);
|
|
|
|
hControl = GetDlgItem(hDlg, IDC_LOOKAT_DATA);
|
|
if (hControl)
|
|
SendMessage(hControl, BM_SETCHECK, (dwFlags & RSF_LOOKATDATA) ? TRUE : FALSE, 0);
|
|
|
|
/* Match whole string */
|
|
hControl = GetDlgItem(hDlg, IDC_MATCHSTRING);
|
|
if (hControl)
|
|
SendMessage(hControl, BM_SETCHECK, (dwFlags & RSF_WHOLESTRING) ? TRUE : FALSE, 0);
|
|
|
|
/* Case sensitivity */
|
|
hControl = GetDlgItem(hDlg, IDC_MATCHCASE);
|
|
if (hControl)
|
|
SendMessage(hControl, BM_SETCHECK, (dwFlags & RSF_MATCHCASE) ? TRUE : FALSE, 0);
|
|
|
|
hControl = GetDlgItem(hDlg, IDC_FINDWHAT);
|
|
if (hControl)
|
|
{
|
|
SetWindowText(hControl, s_szSavedFindValue);
|
|
SetFocus(hControl);
|
|
SendMessage(hControl, EM_SETSEL, 0, -1);
|
|
}
|
|
break;
|
|
|
|
case WM_CLOSE:
|
|
EndDialog(hDlg, 0);
|
|
break;
|
|
|
|
case WM_COMMAND:
|
|
switch(HIWORD(wParam))
|
|
{
|
|
case BN_CLICKED:
|
|
switch(LOWORD(wParam))
|
|
{
|
|
case IDOK:
|
|
dwFlags = 0;
|
|
|
|
hControl = GetDlgItem(hDlg, IDC_LOOKAT_KEYS);
|
|
if (hControl && (SendMessage(hControl, BM_GETCHECK, 0, 0) == BST_CHECKED))
|
|
dwFlags |= RSF_LOOKATKEYS;
|
|
|
|
hControl = GetDlgItem(hDlg, IDC_LOOKAT_VALUES);
|
|
if (hControl && (SendMessage(hControl, BM_GETCHECK, 0, 0) == BST_CHECKED))
|
|
dwFlags |= RSF_LOOKATVALUES;
|
|
|
|
hControl = GetDlgItem(hDlg, IDC_LOOKAT_DATA);
|
|
if (hControl && (SendMessage(hControl, BM_GETCHECK, 0, 0) == BST_CHECKED))
|
|
dwFlags |= RSF_LOOKATDATA;
|
|
|
|
hControl = GetDlgItem(hDlg, IDC_MATCHSTRING);
|
|
if (hControl && (SendMessage(hControl, BM_GETCHECK, 0, 0) == BST_CHECKED))
|
|
dwFlags |= RSF_WHOLESTRING;
|
|
|
|
hControl = GetDlgItem(hDlg, IDC_MATCHCASE);
|
|
if (hControl && (SendMessage(hControl, BM_GETCHECK, 0, 0) == BST_CHECKED))
|
|
dwFlags |= RSF_MATCHCASE;
|
|
|
|
SetFindFlags(dwFlags);
|
|
|
|
hControl = GetDlgItem(hDlg, IDC_FINDWHAT);
|
|
if (hControl)
|
|
GetWindowText(hControl, s_szFindWhat, sizeof(s_szFindWhat) / sizeof(s_szFindWhat[0]));
|
|
EndDialog(hDlg, 1);
|
|
break;
|
|
|
|
case IDCANCEL:
|
|
EndDialog(hDlg, 0);
|
|
break;
|
|
}
|
|
break;
|
|
|
|
case EN_CHANGE:
|
|
switch(LOWORD(wParam))
|
|
{
|
|
case IDC_FINDWHAT:
|
|
GetWindowText((HWND) lParam, s_szSavedFindValue, sizeof(s_szSavedFindValue) / sizeof(s_szSavedFindValue[0]));
|
|
hControl = GetDlgItem(hDlg, IDOK);
|
|
if (hControl)
|
|
{
|
|
lStyle = GetWindowLongPtr(hControl, GWL_STYLE);
|
|
if (s_szSavedFindValue[0])
|
|
lStyle &= ~WS_DISABLED;
|
|
else
|
|
lStyle |= WS_DISABLED;
|
|
SetWindowLongPtr(hControl, GWL_STYLE, lStyle);
|
|
RedrawWindow(hControl, NULL, NULL, RDW_INVALIDATE);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
return iResult;
|
|
}
|
|
|
|
void FindDialog(HWND hWnd)
|
|
{
|
|
if (DialogBoxParam(GetModuleHandle(NULL), MAKEINTRESOURCE(IDD_FIND),
|
|
hWnd, FindDialogProc, 0) != 0)
|
|
{
|
|
if (!FindNext(hWnd))
|
|
{
|
|
TCHAR msg[128], caption[128];
|
|
|
|
LoadString(hInst, IDS_FINISHEDFIND, msg, sizeof(msg)/sizeof(TCHAR));
|
|
LoadString(hInst, IDS_APP_TITLE, caption, sizeof(caption)/sizeof(TCHAR));
|
|
MessageBox(0, msg, caption, MB_ICONINFORMATION);
|
|
}
|
|
}
|
|
}
|
|
|