shell32: Fix search for a command string to cover more cases (like protocol associations).
This commit is contained in:
parent
0816f85b6b
commit
4f6230d5c4
|
@ -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)
|
|
||||||
return HRESULT_FROM_WIN32(ret);
|
|
||||||
|
|
||||||
ret = RegOpenKeyExW(hkeyFile, shellW, 0, KEY_READ, &hkeyShell);
|
|
||||||
RegCloseKey(hkeyFile);
|
|
||||||
if (ret != ERROR_SUCCESS)
|
|
||||||
return HRESULT_FROM_WIN32(ret);
|
|
||||||
|
|
||||||
if (!pszExtra)
|
|
||||||
{
|
{
|
||||||
hr = ASSOC_GetValue(hkeyShell, NULL, (void**)&pszExtraFromReg, NULL);
|
HKEY hkeyFile;
|
||||||
/* if no default action */
|
|
||||||
if (hr == E_FAIL || hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND))
|
ret = RegOpenKeyExW(HKEY_CLASSES_ROOT, filetype, 0, KEY_READ, &hkeyFile);
|
||||||
{
|
HeapFree(GetProcessHeap(), 0, filetype);
|
||||||
DWORD rlen;
|
if (ret) return HRESULT_FROM_WIN32(ret);
|
||||||
ret = RegQueryInfoKeyW(hkeyShell, 0, 0, 0, 0, &rlen, 0, 0, 0, 0, 0, 0);
|
|
||||||
if (ret != ERROR_SUCCESS)
|
ret = RegOpenKeyExW(hkeyFile, shellW, 0, KEY_READ, &hkeyShell);
|
||||||
{
|
RegCloseKey(hkeyFile);
|
||||||
RegCloseKey(hkeyShell);
|
if (ret) return HRESULT_FROM_WIN32(ret);
|
||||||
return HRESULT_FROM_WIN32(ret);
|
}
|
||||||
}
|
else
|
||||||
rlen++;
|
{
|
||||||
pszExtraFromReg = HeapAlloc(GetProcessHeap(), 0, rlen * sizeof(WCHAR));
|
ret = RegOpenKeyExW(This->hkeySource, shellW, 0, KEY_READ, &hkeyShell);
|
||||||
if (!pszExtraFromReg)
|
if (ret) return HRESULT_FROM_WIN32(ret);
|
||||||
{
|
|
||||||
RegCloseKey(hkeyShell);
|
|
||||||
return E_OUTOFMEMORY;
|
|
||||||
}
|
|
||||||
ret = RegEnumKeyExW(hkeyShell, 0, pszExtraFromReg, &rlen, 0, NULL, NULL, NULL);
|
|
||||||
if (ret != ERROR_SUCCESS)
|
|
||||||
{
|
|
||||||
RegCloseKey(hkeyShell);
|
|
||||||
return HRESULT_FROM_WIN32(ret);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (FAILED(hr))
|
|
||||||
{
|
|
||||||
RegCloseKey(hkeyShell);
|
|
||||||
return hr;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = RegOpenKeyExW(hkeyShell, pszExtra ? pszExtra : pszExtraFromReg, 0,
|
if (!extra)
|
||||||
KEY_READ, &hkeyVerb);
|
{
|
||||||
HeapFree(GetProcessHeap(), 0, pszExtraFromReg);
|
/* check for default verb */
|
||||||
RegCloseKey(hkeyShell);
|
hr = ASSOC_GetValue(hkeyShell, NULL, (void**)&extra_from_reg, NULL);
|
||||||
if (ret != ERROR_SUCCESS)
|
if (FAILED(hr))
|
||||||
return HRESULT_FROM_WIN32(ret);
|
{
|
||||||
|
/* no default verb, try first subkey */
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* open verb subkey */
|
||||||
|
ret = RegOpenKeyExW(hkeyShell, extra, 0, KEY_READ, &hkeyVerb);
|
||||||
|
HeapFree(GetProcessHeap(), 0, extra_from_reg);
|
||||||
|
RegCloseKey(hkeyShell);
|
||||||
|
if (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;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue