[BROWSEUI] SHExplorerParseCmdLine: Fix parsing of /root (#6752)
[reactos.git] / base / applications / regedit / find.c
index 4b9e4cd..919ae0c 100644 (file)
@@ -32,7 +32,7 @@ static BOOL s_bAbort;
 
 static DWORD s_dwFlags;
 static WCHAR s_szName[MAX_PATH];
-static DWORD s_cbName;
+static DWORD s_cchName;
 static const WCHAR s_empty[] = L"";
 static const WCHAR s_backslash[] = L"\\";
 
@@ -87,41 +87,32 @@ static BOOL CompareName(LPCWSTR pszName1, LPCWSTR pszName2)
     }
 }
 
-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) ? 0 : NORM_IGNORECASE);
 
-        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;
 }
 
@@ -143,23 +134,23 @@ BOOL RegFindRecurse(
     LONG lResult;
     WCHAR szSubKey[MAX_PATH];
     DWORD i, c, cb, type;
-    BOOL fPast = FALSE;
+    BOOL fPast;
     LPWSTR *ppszNames = NULL;
     LPBYTE pb = NULL;
 
     if (DoEvents())
         return FALSE;
 
-    wcscpy(szSubKey, pszSubKey);
+    if(wcslen(pszSubKey) >= _countof(szSubKey))
+        return FALSE;
+
+    StringCbCopyW(szSubKey, sizeof(szSubKey), pszSubKey);
     hSubKey = NULL;
 
     lResult = RegOpenKeyExW(hKey, szSubKey, 0, KEY_ALL_ACCESS, &hSubKey);
     if (lResult != ERROR_SUCCESS)
         return FALSE;
 
-    if (pszValueName == NULL)
-        pszValueName = s_empty;
-
     lResult = RegQueryInfoKeyW(hSubKey, NULL, NULL, NULL, NULL, NULL, NULL,
                               &c, NULL, NULL, NULL, NULL);
     if (lResult != ERROR_SUCCESS)
@@ -169,13 +160,14 @@ BOOL RegFindRecurse(
         goto err;
     ZeroMemory(ppszNames, c * sizeof(LPWSTR));
 
+    /* Retrieve the value names associated with the current key */
     for(i = 0; i < c; i++)
     {
         if (DoEvents())
             goto err;
 
-        s_cbName = MAX_PATH * sizeof(WCHAR);
-        lResult = RegEnumValueW(hSubKey, i, s_szName, &s_cbName, NULL, NULL,
+        s_cchName = _countof(s_szName);
+        lResult = RegEnumValueW(hSubKey, i, s_szName, &s_cchName, NULL, NULL,
                                NULL, &cb);
         if (lResult == ERROR_NO_MORE_ITEMS)
         {
@@ -184,7 +176,7 @@ BOOL RegFindRecurse(
         }
         if (lResult != ERROR_SUCCESS)
             goto err;
-        if (s_cbName >= MAX_PATH * sizeof(WCHAR))
+        if (s_cchName >= _countof(s_szName))
             continue;
 
         ppszNames[i] = _wcsdup(s_szName);
@@ -192,7 +184,11 @@ BOOL RegFindRecurse(
 
     qsort(ppszNames, c, sizeof(LPWSTR), compare);
 
-    for(i = 0; i < c; i++)
+    /* If pszValueName is NULL, the function will search for all values within the key */
+    fPast = (pszValueName == NULL);
+
+    /* Search within the values */
+    for (i = 0; i < c; i++)
     {
         if (DoEvents())
             goto err;
@@ -209,10 +205,7 @@ BOOL RegFindRecurse(
                 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;
         }
 
@@ -228,14 +221,10 @@ BOOL RegFindRecurse(
         if (lResult != ERROR_SUCCESS)
             goto err;
 
-        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);
@@ -250,6 +239,7 @@ BOOL RegFindRecurse(
     }
     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)
@@ -259,13 +249,14 @@ BOOL RegFindRecurse(
         goto err;
     ZeroMemory(ppszNames, c * sizeof(LPWSTR));
 
+    /* Retrieve the names of the sub-keys */
     for(i = 0; i < c; i++)
     {
         if (DoEvents())
             goto err;
 
-        s_cbName = MAX_PATH * sizeof(WCHAR);
-        lResult = RegEnumKeyExW(hSubKey, i, s_szName, &s_cbName, NULL, NULL,
+        s_cchName = _countof(s_szName);
+        lResult = RegEnumKeyExW(hSubKey, i, s_szName, &s_cchName, NULL, NULL,
                                NULL, NULL);
         if (lResult == ERROR_NO_MORE_ITEMS)
         {
@@ -274,7 +265,7 @@ BOOL RegFindRecurse(
         }
         if (lResult != ERROR_SUCCESS)
             goto err;
-        if (s_cbName >= MAX_PATH * sizeof(WCHAR))
+        if (s_cchName >= _countof(s_szName))
             continue;
 
         ppszNames[i] = _wcsdup(s_szName);
@@ -282,6 +273,7 @@ BOOL RegFindRecurse(
 
     qsort(ppszNames, c, sizeof(LPWSTR), compare);
 
+    /* Search within the sub-keys */
     for(i = 0; i < c; i++)
     {
         if (DoEvents())
@@ -307,18 +299,19 @@ BOOL RegFindRecurse(
             goto success;
         }
 
+        /* Search within the value entries of the sub-key */
         if (RegFindRecurse(hSubKey, ppszNames[i], NULL, ppszFoundSubKey,
                            ppszFoundValueName))
         {
             LPWSTR psz = *ppszFoundSubKey;
-            *ppszFoundSubKey = malloc(
-                                   (wcslen(szSubKey) + wcslen(psz) + 2) * sizeof(WCHAR));
+            SIZE_T cbFoundSubKey = (wcslen(szSubKey) + wcslen(psz) + 2) * sizeof(WCHAR);
+            *ppszFoundSubKey = malloc(cbFoundSubKey);
             if (*ppszFoundSubKey == NULL)
                 goto err;
             if (szSubKey[0])
             {
-                wcscpy(*ppszFoundSubKey, szSubKey);
-                wcscat(*ppszFoundSubKey, s_backslash);
+                StringCbCopyW(*ppszFoundSubKey, cbFoundSubKey, szSubKey);
+                StringCbCatW(*ppszFoundSubKey, cbFoundSubKey, s_backslash);
             }
             else
                 **ppszFoundSubKey = 0;
@@ -363,18 +356,19 @@ BOOL RegFindWalk(
     WCHAR szKeyName[MAX_PATH];
     WCHAR szSubKey[MAX_PATH];
     LPWSTR pch;
-    BOOL fPast;
+    BOOL fPast, fKeyMatched;
     LPWSTR *ppszNames = NULL;
 
     hBaseKey = *phKey;
+
+    if (wcslen(pszSubKey) >= _countof(szSubKey))
+        return FALSE;
+
     if (RegFindRecurse(hBaseKey, pszSubKey, pszValueName, ppszFoundSubKey,
                        ppszFoundValueName))
         return TRUE;
 
-    if (wcslen(pszSubKey) >= MAX_PATH)
-        return FALSE;
-
-    wcscpy(szSubKey, pszSubKey);
+    StringCbCopyW(szSubKey, sizeof(szSubKey), pszSubKey);
     while(szSubKey[0] != 0)
     {
         if (DoEvents())
@@ -412,8 +406,8 @@ BOOL RegFindWalk(
             if (DoEvents())
                 goto err;
 
-            s_cbName = MAX_PATH * sizeof(WCHAR);
-            lResult = RegEnumKeyExW(hSubKey, i, s_szName, &s_cbName,
+            s_cchName = _countof(s_szName);
+            lResult = RegEnumKeyExW(hSubKey, i, s_szName, &s_cchName,
                                     NULL, NULL, NULL, NULL);
             if (lResult == ERROR_NO_MORE_ITEMS)
             {
@@ -461,19 +455,19 @@ BOOL RegFindWalk(
                 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;
-                *ppszFoundSubKey = malloc(
-                                       (wcslen(szSubKey) + wcslen(psz) + 2) *
-                                       sizeof(WCHAR));
+                SIZE_T cbFoundSubKey = (wcslen(szSubKey) + wcslen(psz) + 2) * sizeof(WCHAR);
+                *ppszFoundSubKey = malloc(cbFoundSubKey);
                 if (*ppszFoundSubKey == NULL)
                     goto err;
                 if (szSubKey[0])
                 {
-                    wcscpy(*ppszFoundSubKey, szSubKey);
-                    wcscat(*ppszFoundSubKey, s_backslash);
+                    StringCbCopyW(*ppszFoundSubKey, cbFoundSubKey, szSubKey);
+                    StringCbCatW(*ppszFoundSubKey, cbFoundSubKey, s_backslash);
                 }
                 else
                     **ppszFoundSubKey = 0;
@@ -682,12 +676,20 @@ BOOL FindNext(HWND hWnd)
 
     if (fSuccess)
     {
-        GetKeyName(szFullKey, COUNT_OF(szFullKey), hKeyRoot, pszFoundSubKey);
+        GetKeyName(szFullKey, ARRAY_SIZE(szFullKey), hKeyRoot, pszFoundSubKey);
         SelectNode(g_pChildWnd->hTreeWnd, szFullKey);
-        SetValueName(g_pChildWnd->hListWnd, pszFoundValueName);
         free(pszFoundSubKey);
-        free(pszFoundValueName);
-        SetFocus(g_pChildWnd->hListWnd);
+
+        if (pszFoundValueName != NULL)
+        {
+            SetValueName(g_pChildWnd->hListWnd, pszFoundValueName);
+            free(pszFoundValueName);
+            SetFocus(g_pChildWnd->hListWnd);
+        }
+        else
+        {
+            SetFocus(g_pChildWnd->hTreeWnd);
+        }
     }
     return fSuccess || s_bAbort;
 }
@@ -773,7 +775,7 @@ static INT_PTR CALLBACK FindDialogProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPAR
 
                 hControl = GetDlgItem(hDlg, IDC_FINDWHAT);
                 if (hControl)
-                    GetWindowTextW(hControl, s_szFindWhat, COUNT_OF(s_szFindWhat));
+                    GetWindowTextW(hControl, s_szFindWhat, ARRAY_SIZE(s_szFindWhat));
                 EndDialog(hDlg, 1);
                 break;
 
@@ -787,7 +789,7 @@ static INT_PTR CALLBACK FindDialogProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPAR
             switch(LOWORD(wParam))
             {
             case IDC_FINDWHAT:
-                GetWindowTextW((HWND) lParam, s_szSavedFindValue, COUNT_OF(s_szSavedFindValue));
+                GetWindowTextW((HWND) lParam, s_szSavedFindValue, ARRAY_SIZE(s_szSavedFindValue));
                 hControl = GetDlgItem(hDlg, IDOK);
                 if (hControl)
                 {
@@ -807,18 +809,23 @@ static INT_PTR CALLBACK FindDialogProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPAR
     return iResult;
 }
 
+void FindNextMessageBox(HWND hWnd)
+{
+    if (!FindNext(hWnd))
+    {
+        WCHAR msg[128], caption[128];
+
+        LoadStringW(hInst, IDS_FINISHEDFIND, msg, ARRAY_SIZE(msg));
+        LoadStringW(hInst, IDS_APP_TITLE, caption, ARRAY_SIZE(caption));
+        MessageBoxW(hWnd, msg, caption, MB_ICONINFORMATION);
+    }
+}
+
 void FindDialog(HWND hWnd)
 {
     if (DialogBoxParamW(GetModuleHandle(NULL), MAKEINTRESOURCEW(IDD_FIND),
                        hWnd, FindDialogProc, 0) != 0)
     {
-        if (!FindNext(hWnd))
-        {
-            WCHAR msg[128], caption[128];
-
-            LoadStringW(hInst, IDS_FINISHEDFIND, msg, COUNT_OF(msg));
-            LoadStringW(hInst, IDS_APP_TITLE, caption, COUNT_OF(caption));
-            MessageBoxW(0, msg, caption, MB_ICONINFORMATION);
-        }
+        FindNextMessageBox(hWnd);
     }
 }