Commit 4f6230d5 authored by Nikolay Sivov's avatar Nikolay Sivov Committed by Alexandre Julliard

shell32: Fix search for a command string to cover more cases (like protocol associations).

parent 0816f85b
...@@ -240,79 +240,86 @@ static HRESULT ASSOC_GetValue(HKEY hkey, const WCHAR *name, void **data, DWORD * ...@@ -240,79 +240,86 @@ static HRESULT ASSOC_GetValue(HKEY hkey, const WCHAR *name, void **data, DWORD *
return S_OK; return S_OK;
} }
static HRESULT ASSOC_GetCommand(IQueryAssociationsImpl *This, static HRESULT ASSOC_GetCommand(IQueryAssociationsImpl *This, const WCHAR *extra, WCHAR **command)
LPCWSTR pszExtra, WCHAR **ppszCommand)
{ {
HKEY hkeyCommand; HKEY hkeyCommand;
HKEY hkeyFile;
HKEY hkeyShell; HKEY hkeyShell;
HKEY hkeyVerb; HKEY hkeyVerb;
HRESULT hr; HRESULT hr;
LONG ret; LONG ret;
WCHAR * pszExtraFromReg = NULL; WCHAR *extra_from_reg = NULL;
WCHAR * pszFileType; WCHAR *filetype;
static const WCHAR commandW[] = { 'c','o','m','m','a','n','d',0 }; static const WCHAR commandW[] = { 'c','o','m','m','a','n','d',0 };
static const WCHAR shellW[] = { 's','h','e','l','l',0 }; static const WCHAR shellW[] = { 's','h','e','l','l',0 };
hr = ASSOC_GetValue(This->hkeySource, NULL, (void**)&pszFileType, NULL); /* When looking for file extension it's possible to have a default value
if (FAILED(hr)) that points to another key that contains 'shell/<verb>/command' subtree. */
return hr; hr = ASSOC_GetValue(This->hkeySource, NULL, (void**)&filetype, NULL);
ret = RegOpenKeyExW(HKEY_CLASSES_ROOT, pszFileType, 0, KEY_READ, &hkeyFile); if (hr == S_OK)
HeapFree(GetProcessHeap(), 0, pszFileType); {
if (ret != ERROR_SUCCESS) HKEY hkeyFile;
return HRESULT_FROM_WIN32(ret);
ret = RegOpenKeyExW(hkeyFile, shellW, 0, KEY_READ, &hkeyShell); ret = RegOpenKeyExW(HKEY_CLASSES_ROOT, filetype, 0, KEY_READ, &hkeyFile);
RegCloseKey(hkeyFile); HeapFree(GetProcessHeap(), 0, filetype);
if (ret != ERROR_SUCCESS) if (ret) return HRESULT_FROM_WIN32(ret);
return HRESULT_FROM_WIN32(ret);
if (!pszExtra) ret = RegOpenKeyExW(hkeyFile, shellW, 0, KEY_READ, &hkeyShell);
RegCloseKey(hkeyFile);
if (ret) return HRESULT_FROM_WIN32(ret);
}
else
{ {
hr = ASSOC_GetValue(hkeyShell, NULL, (void**)&pszExtraFromReg, NULL); ret = RegOpenKeyExW(This->hkeySource, shellW, 0, KEY_READ, &hkeyShell);
/* if no default action */ if (ret) return HRESULT_FROM_WIN32(ret);
if (hr == E_FAIL || hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND)) }
{
DWORD rlen; if (!extra)
ret = RegQueryInfoKeyW(hkeyShell, 0, 0, 0, 0, &rlen, 0, 0, 0, 0, 0, 0); {
if (ret != ERROR_SUCCESS) /* check for default verb */
{ hr = ASSOC_GetValue(hkeyShell, NULL, (void**)&extra_from_reg, NULL);
RegCloseKey(hkeyShell); if (FAILED(hr))
return HRESULT_FROM_WIN32(ret);
}
rlen++;
pszExtraFromReg = HeapAlloc(GetProcessHeap(), 0, rlen * sizeof(WCHAR));
if (!pszExtraFromReg)
{
RegCloseKey(hkeyShell);
return E_OUTOFMEMORY;
}
ret = RegEnumKeyExW(hkeyShell, 0, pszExtraFromReg, &rlen, 0, NULL, NULL, NULL);
if (ret != ERROR_SUCCESS)
{ {
RegCloseKey(hkeyShell); /* no default verb, try first subkey */
return HRESULT_FROM_WIN32(ret); DWORD max_subkey_len;
ret = RegQueryInfoKeyW(hkeyShell, NULL, NULL, NULL, NULL, &max_subkey_len, NULL, NULL, NULL, NULL, NULL, NULL);
if (ret)
{
RegCloseKey(hkeyShell);
return HRESULT_FROM_WIN32(ret);
}
max_subkey_len++;
extra_from_reg = HeapAlloc(GetProcessHeap(), 0, max_subkey_len * sizeof(WCHAR));
if (!extra_from_reg)
{
RegCloseKey(hkeyShell);
return E_OUTOFMEMORY;
}
ret = RegEnumKeyExW(hkeyShell, 0, extra_from_reg, &max_subkey_len, NULL, NULL, NULL, NULL);
if (ret)
{
HeapFree(GetProcessHeap(), 0, extra_from_reg);
RegCloseKey(hkeyShell);
return HRESULT_FROM_WIN32(ret);
}
} }
} extra = extra_from_reg;
else if (FAILED(hr))
{
RegCloseKey(hkeyShell);
return hr;
}
} }
ret = RegOpenKeyExW(hkeyShell, pszExtra ? pszExtra : pszExtraFromReg, 0, /* open verb subkey */
KEY_READ, &hkeyVerb); ret = RegOpenKeyExW(hkeyShell, extra, 0, KEY_READ, &hkeyVerb);
HeapFree(GetProcessHeap(), 0, pszExtraFromReg); HeapFree(GetProcessHeap(), 0, extra_from_reg);
RegCloseKey(hkeyShell); RegCloseKey(hkeyShell);
if (ret != ERROR_SUCCESS) if (ret) return HRESULT_FROM_WIN32(ret);
return HRESULT_FROM_WIN32(ret);
/* open command subkey */
ret = RegOpenKeyExW(hkeyVerb, commandW, 0, KEY_READ, &hkeyCommand); ret = RegOpenKeyExW(hkeyVerb, commandW, 0, KEY_READ, &hkeyCommand);
RegCloseKey(hkeyVerb); RegCloseKey(hkeyVerb);
if (ret != ERROR_SUCCESS) if (ret) return HRESULT_FROM_WIN32(ret);
return HRESULT_FROM_WIN32(ret);
hr = ASSOC_GetValue(hkeyCommand, NULL, (void**)ppszCommand, NULL); hr = ASSOC_GetValue(hkeyCommand, NULL, (void**)command, NULL);
RegCloseKey(hkeyCommand); RegCloseKey(hkeyCommand);
return hr; return hr;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment