We will check the data size correctly, instead of 3 NUL byte appending hack. Add bSelectNone parameter to UpdateAddress and RefreshListView functions. If bSelectNone is TRUE, then select nothing of ListView. Fix item selection of ListView. Rename CompareData helper function as MatchData and improve it. Improve the search algorithm. If the item selection of ListView changed, scroll down to the item. Follow up to #5146. CORE-15986, CORE-18230
}
VOID
-UpdateAddress(HTREEITEM hItem, HKEY hRootKey, LPCWSTR pszPath)
+UpdateAddress(HTREEITEM hItem, HKEY hRootKey, LPCWSTR pszPath, BOOL bSelectNone)
{
LPCWSTR keyPath, rootName;
LPWSTR fullPath;
if (keyPath)
{
- RefreshListView(g_pChildWnd->hListWnd, hRootKey, keyPath);
+ RefreshListView(g_pChildWnd->hListWnd, hRootKey, keyPath, bSelectNone);
rootName = get_root_key_name(hRootKey);
cbFullPath = (wcslen(rootName) + 1 + wcslen(keyPath) + 1) * sizeof(WCHAR);
fullPath = malloc(cbFullPath);
}
}
-static BOOL
-CompareData(
- DWORD dwType,
- LPCWSTR psz1,
- LPCWSTR psz2)
+/* Do not assume that pch1 is terminated with UNICODE_NULL */
+static BOOL MatchString(LPCWCH pch1, INT cch1, LPCWCH pch2, INT cch2)
{
- INT i, cch1 = wcslen(psz1), cch2 = wcslen(psz2);
- if (dwType == REG_SZ || dwType == REG_EXPAND_SZ)
- {
- if (s_dwFlags & RSF_WHOLESTRING)
- {
- if (s_dwFlags & RSF_MATCHCASE)
- return 2 == CompareStringW(LOCALE_SYSTEM_DEFAULT, 0,
- psz1, cch1, psz2, cch2);
- else
- return 2 == CompareStringW(LOCALE_SYSTEM_DEFAULT,
- NORM_IGNORECASE, psz1, cch1, psz2, cch2);
- }
+ INT i;
+ DWORD dwNorm = ((s_dwFlags & RSF_MATCHCASE) ? NORM_IGNORECASE : 0);
- for(i = 0; i <= cch1 - cch2; i++)
- {
- if (s_dwFlags & RSF_MATCHCASE)
- {
- if (2 == CompareStringW(LOCALE_SYSTEM_DEFAULT, 0,
- psz1 + i, cch2, psz2, cch2))
- return TRUE;
- }
- else
- {
- if (2 == CompareStringW(LOCALE_SYSTEM_DEFAULT,
- NORM_IGNORECASE, psz1 + i, cch2, psz2, cch2))
- return TRUE;
- }
- }
+ if (s_dwFlags & RSF_WHOLESTRING)
+ return 2 == CompareStringW(LOCALE_SYSTEM_DEFAULT, dwNorm, pch1, cch1, pch2, cch2);
+
+ if (cch1 < cch2)
+ return FALSE;
+
+ for (i = 0; i <= cch1 - cch2; i++)
+ {
+ if (2 == CompareStringW(LOCALE_SYSTEM_DEFAULT, dwNorm, pch1 + i, cch2, pch2, cch2))
+ return TRUE;
}
+
+ return FALSE;
+}
+
+static BOOL MatchData(DWORD dwType, LPCVOID pv1, DWORD cb1)
+{
+ if (dwType == REG_SZ || dwType == REG_EXPAND_SZ || dwType == REG_MULTI_SZ)
+ return MatchString(pv1, (INT)(cb1 / sizeof(WCHAR)), s_szFindWhat, lstrlenW(s_szFindWhat));
+
return FALSE;
}
LONG lResult;
WCHAR szSubKey[MAX_PATH];
DWORD i, c, cb, type;
- BOOL fPast = FALSE;
+ BOOL fPast;
LPWSTR *ppszNames = NULL;
LPBYTE pb = NULL;
goto err;
ZeroMemory(ppszNames, c * sizeof(LPWSTR));
+ /* Retrieve the value names associated with the current key */
for(i = 0; i < c; i++)
{
if (DoEvents())
qsort(ppszNames, c, sizeof(LPWSTR), compare);
- if (pszValueName == NULL)
- pszValueName = ppszNames[0];
+ /* If pszValueName is NULL, the function will search for all values within the key */
+ fPast = (pszValueName == NULL);
- for(i = 0; i < c; i++)
+ /* Search within the values */
+ for (i = 0; i < c; i++)
{
if (DoEvents())
goto err;
CompareName(ppszNames[i], s_szFindWhat))
{
*ppszFoundSubKey = _wcsdup(szSubKey);
- if (ppszNames[i][0] == 0)
- *ppszFoundValueName = NULL;
- else
- *ppszFoundValueName = _wcsdup(ppszNames[i]);
+ *ppszFoundValueName = _wcsdup(ppszNames[i]);
goto success;
}
NULL, &cb);
if (lResult != ERROR_SUCCESS)
goto err;
- pb = malloc(cb + 3); /* To avoid buffer overrun, append 3 NULs */
+ pb = malloc(cb);
if (pb == NULL)
goto err;
lResult = RegQueryValueExW(hSubKey, ppszNames[i], NULL, &type,
if (lResult != ERROR_SUCCESS)
goto err;
- /* To avoid buffer overrun, append 3 NUL bytes.
- NOTE: cb can be an odd number although UNICODE_NULL is two bytes.
- Two bytes at odd position is not enough to avoid buffer overrun. */
- pb[cb] = pb[cb + 1] = pb[cb + 2] = 0;
-
- if ((s_dwFlags & RSF_LOOKATDATA) &&
- CompareData(type, (LPWSTR) pb, s_szFindWhat))
+ if ((s_dwFlags & RSF_LOOKATDATA) && MatchData(type, pb, cb))
{
*ppszFoundSubKey = _wcsdup(szSubKey);
- if (ppszNames[i][0] == 0)
- *ppszFoundValueName = NULL;
- else
- *ppszFoundValueName = _wcsdup(ppszNames[i]);
+ *ppszFoundValueName = _wcsdup(ppszNames[i]);
goto success;
}
free(pb);
}
ppszNames = NULL;
+ /* Retrieve the number of sub-keys */
lResult = RegQueryInfoKeyW(hSubKey, NULL, NULL, NULL, &c, NULL, NULL,
NULL, NULL, NULL, NULL, NULL);
if (lResult != ERROR_SUCCESS)
goto err;
ZeroMemory(ppszNames, c * sizeof(LPWSTR));
+ /* Retrieve the names of the sub-keys */
for(i = 0; i < c; i++)
{
if (DoEvents())
qsort(ppszNames, c, sizeof(LPWSTR), compare);
+ /* Search within the sub-keys */
for(i = 0; i < c; i++)
{
if (DoEvents())
goto success;
}
+ /* Search within the value entries of the sub-key */
if (RegFindRecurse(hSubKey, ppszNames[i], NULL, ppszFoundSubKey,
ppszFoundValueName))
{
WCHAR szKeyName[MAX_PATH];
WCHAR szSubKey[MAX_PATH];
LPWSTR pch;
- BOOL fPast;
+ BOOL fPast, fKeyMatched;
LPWSTR *ppszNames = NULL;
hBaseKey = *phKey;
goto success;
}
- if (RegFindRecurse(hSubKey, ppszNames[i], NULL,
+ fKeyMatched = (_wcsicmp(ppszNames[i], szKeyName) == 0);
+ if (RegFindRecurse(hSubKey, ppszNames[i], (fKeyMatched ? pszValueName : NULL),
ppszFoundSubKey, ppszFoundValueName))
{
LPWSTR psz = *ppszFoundSubKey;
/* refresh tree and list views */
RefreshTreeView(g_pChildWnd->hTreeWnd);
pszKeyPath = GetItemPath(g_pChildWnd->hTreeWnd, 0, &hRootKey);
- RefreshListView(g_pChildWnd->hListWnd, hRootKey, pszKeyPath);
+ RefreshListView(g_pChildWnd->hListWnd, hRootKey, pszKeyPath, TRUE);
}
else
{
/* refresh tree and list views */
RefreshTreeView(g_pChildWnd->hTreeWnd);
pszKeyPath = GetItemPath(g_pChildWnd->hTreeWnd, 0, &hRootKey);
- RefreshListView(g_pChildWnd->hListWnd, hRootKey, pszKeyPath);
+ RefreshListView(g_pChildWnd->hListWnd, hRootKey, pszKeyPath, TRUE);
}
else
{
/* refresh tree and list views */
RefreshTreeView(g_pChildWnd->hTreeWnd);
pszKeyPath = GetItemPath(g_pChildWnd->hTreeWnd, 0, &hKeyRoot);
- RefreshListView(g_pChildWnd->hListWnd, hKeyRoot, pszKeyPath);
+ RefreshListView(g_pChildWnd->hListWnd, hKeyRoot, pszKeyPath, TRUE);
return bRet;
}
return FALSE;
}
- RefreshListView(g_pChildWnd->hListWnd, hRootKey, pszKeyPath);
+ RefreshListView(g_pChildWnd->hListWnd, hRootKey, pszKeyPath, TRUE);
/* locate the newly added value, and get ready to rename it */
memset(&lvfi, 0, sizeof(lvfi));
lvfi.psz = szNewValue;
iIndex = ListView_FindItem(g_pChildWnd->hListWnd, -1, &lvfi);
if (iIndex >= 0)
+ {
+ ListView_SetItemState(g_pChildWnd->hListWnd, iIndex,
+ LVIS_SELECTED | LVIS_FOCUSED, LVIS_SELECTED | LVIS_FOCUSED);
+ ListView_EnsureVisible(g_pChildWnd->hListWnd, iIndex, FALSE);
(void)ListView_EditLabel(g_pChildWnd->hListWnd, iIndex);
+ }
return TRUE;
}
{
case ID_EDIT_MODIFY:
if (valueName && ModifyValue(hWnd, hKey, valueName, FALSE))
- RefreshListView(g_pChildWnd->hListWnd, hKeyRoot, keyPath);
+ RefreshListView(g_pChildWnd->hListWnd, hKeyRoot, keyPath, FALSE);
break;
case ID_EDIT_MODIFY_BIN:
if (valueName && ModifyValue(hWnd, hKey, valueName, TRUE))
- RefreshListView(g_pChildWnd->hListWnd, hKeyRoot, keyPath);
+ RefreshListView(g_pChildWnd->hListWnd, hKeyRoot, keyPath, FALSE);
break;
case ID_EDIT_RENAME:
if (GetFocus() == g_pChildWnd->hListWnd)
item = ni;
}
- RefreshListView(g_pChildWnd->hListWnd, hKeyRoot, keyPath);
+ RefreshListView(g_pChildWnd->hListWnd, hKeyRoot, keyPath, FALSE);
if(errs > 0)
{
LoadStringW(hInst, IDS_ERR_DELVAL_CAPTION, caption, ARRAY_SIZE(caption));
case ID_VIEW_REFRESH:
RefreshTreeView(g_pChildWnd->hTreeWnd);
keyPath = GetItemPath(g_pChildWnd->hTreeWnd, 0, &hKeyRoot);
- RefreshListView(g_pChildWnd->hListWnd, hKeyRoot, keyPath);
+ RefreshListView(g_pChildWnd->hListWnd, hKeyRoot, keyPath, TRUE);
break;
/*case ID_OPTIONS_TOOLBAR:*/
/* toggle_child(hWnd, LOWORD(wParam), hToolBar);*/
{
ListView_SetItemState(hwndLV, i, 0, LVIS_FOCUSED | LVIS_SELECTED);
}
- if (pszValueName == NULL)
+ if (pszValueName == NULL || pszValueName[0] == 0)
i = 0;
else
{
}
ListView_SetItemState(hwndLV, i, LVIS_FOCUSED | LVIS_SELECTED,
LVIS_FOCUSED | LVIS_SELECTED);
+ ListView_EnsureVisible(hwndLV, i, FALSE);
iListViewSelect = i;
}
}
-BOOL RefreshListView(HWND hwndLV, HKEY hKey, LPCWSTR keyPath)
+BOOL RefreshListView(HWND hwndLV, HKEY hKey, LPCWSTR keyPath, BOOL bSelectNone)
{
DWORD max_sub_key_len;
DWORD max_val_name_len;
{
ListView_SetItemState(hwndLV, i, 0, LVIS_FOCUSED | LVIS_SELECTED);
}
+
+ if (bSelectNone)
+ iListViewSelect = -1;
ListView_SetItemState(hwndLV, iListViewSelect,
LVIS_FOCUSED | LVIS_SELECTED,
LVIS_FOCUSED | LVIS_SELECTED);
LRESULT CALLBACK ChildWndProc(HWND, UINT, WPARAM, LPARAM);
void ResizeWnd(int cx, int cy);
LPCWSTR get_root_key_name(HKEY hRootKey);
-VOID UpdateAddress(HTREEITEM hItem, HKEY hRootKey, LPCWSTR pszPath);
+VOID UpdateAddress(HTREEITEM hItem, HKEY hRootKey, LPCWSTR pszPath, BOOL bSelectNone);
/* edit.c */
BOOL ModifyValue(HWND hwnd, HKEY hKey, LPCWSTR valueName, BOOL EditBin);
/* listview.c */
HWND CreateListView(HWND hwndParent, HMENU id, INT cx);
-BOOL RefreshListView(HWND hwndLV, HKEY hKey, LPCWSTR keyPath);
+BOOL RefreshListView(HWND hwndLV, HKEY hKey, LPCWSTR keyPath, BOOL bSelectNone);
WCHAR *GetValueName(HWND hwndLV, int iStartAt);
BOOL ListWndNotifyProc(HWND hWnd, WPARAM wParam, LPARAM lParam, BOOL *Result);
BOOL TreeWndNotifyProc(HWND hWnd, WPARAM wParam, LPARAM lParam, BOOL *Result);
/* Get the parent of the current item */
HTREEITEM hParentItem = TreeView_GetParent(g_pChildWnd->hTreeWnd, pnmtv->itemNew.hItem);
- UpdateAddress(pnmtv->itemNew.hItem, NULL, NULL);
+ UpdateAddress(pnmtv->itemNew.hItem, NULL, NULL, TRUE);
/* Disable the Permissions menu item for 'My Computer' */
EnableMenuItem(hMenuFrame, ID_EDIT_PERMISSIONS, MF_BYCOMMAND | (hParentItem ? MF_ENABLED : MF_GRAYED));
lResult = FALSE;
}
else
- UpdateAddress(ptvdi->item.hItem, hRootKey, szBuffer);
+ UpdateAddress(ptvdi->item.hItem, hRootKey, szBuffer, FALSE);
}
*Result = lResult;
}