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
1 changed files with 48 additions and 31 deletions

View File

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