shell32/autocomplete: Revamp pwzsRegKeyPath handling so it can deal with arbitrary sizes and make it more robust.

Handle heap_alloc failure, reg strings without a \ character at all,
try harder to find the reg path (if only value fails the lookup), and
read the registry value with any size.

Signed-off-by: Gabriel Ivăncescu <gabrielopcode@gmail.com>
Signed-off-by: Huw Davies <huw@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Gabriel Ivăncescu 2018-09-06 21:26:11 +03:00 committed by Alexandre Julliard
parent c5bb108484
commit 2964b975ac

View File

@ -486,40 +486,57 @@ static HRESULT WINAPI IAutoComplete2_fnInit(
if (This->options & ACO_AUTOSUGGEST) if (This->options & ACO_AUTOSUGGEST)
create_listbox(This); create_listbox(This);
if (pwzsRegKeyPath) { if (pwzsRegKeyPath)
WCHAR *key; {
WCHAR result[MAX_PATH]; static const HKEY roots[] = { HKEY_CURRENT_USER, HKEY_LOCAL_MACHINE };
WCHAR *value; WCHAR *key, *value;
HKEY hKey = 0; DWORD type, sz;
LONG res; BYTE *qc;
LONG len; HKEY hKey;
LSTATUS res;
size_t len;
UINT i;
/* pwszRegKeyPath contains the key as well as the value, so we split */ /* pwszRegKeyPath contains the key as well as the value, so split it */
key = heap_alloc((lstrlenW(pwzsRegKeyPath)+1)*sizeof(WCHAR)); value = strrchrW(pwzsRegKeyPath, '\\');
strcpyW(key, pwzsRegKeyPath); len = value - pwzsRegKeyPath;
value = strrchrW(key, '\\');
*value = 0; if (value && (key = heap_alloc((len+1) * sizeof(*key))) != NULL)
value++; {
/* Now value contains the value and buffer the key */ memcpy(key, pwzsRegKeyPath, len * sizeof(*key));
res = RegOpenKeyExW(HKEY_CURRENT_USER, key, 0, KEY_READ, &hKey); key[len] = '\0';
if (res != ERROR_SUCCESS) { value++;
/* if the key is not found, MSDN states we must seek in HKEY_LOCAL_MACHINE */
res = RegOpenKeyExW(HKEY_LOCAL_MACHINE, key, 0, KEY_READ, &hKey); for (i = 0; i < ARRAY_SIZE(roots); i++)
} {
if (res == ERROR_SUCCESS) { if (RegOpenKeyExW(roots[i], key, 0, KEY_READ, &hKey) != ERROR_SUCCESS)
res = RegQueryValueW(hKey, value, result, &len); continue;
if (res == ERROR_SUCCESS) { sz = MAX_PATH * sizeof(WCHAR);
This->quickComplete = heap_alloc(len*sizeof(WCHAR));
strcpyW(This->quickComplete, result); while ((qc = heap_alloc(sz)) != NULL)
} {
RegCloseKey(hKey); res = RegQueryValueExW(hKey, value, NULL, &type, qc, &sz);
} if (res == ERROR_SUCCESS && type == REG_SZ)
heap_free(key); {
This->quickComplete = heap_realloc(qc, sz);
i = ARRAY_SIZE(roots);
break;
}
heap_free(qc);
if (res != ERROR_MORE_DATA || type != REG_SZ)
break;
}
RegCloseKey(hKey);
}
heap_free(key);
}
} }
if ((pwszQuickComplete) && (!This->quickComplete)) { if (!This->quickComplete && pwszQuickComplete)
This->quickComplete = heap_alloc((lstrlenW(pwszQuickComplete)+1)*sizeof(WCHAR)); {
lstrcpyW(This->quickComplete, pwszQuickComplete); size_t len = strlenW(pwszQuickComplete)+1;
if ((This->quickComplete = heap_alloc(len * sizeof(WCHAR))) != NULL)
memcpy(This->quickComplete, pwszQuickComplete, len * sizeof(WCHAR));
} }
return S_OK; return S_OK;