shell32: Fix return value for ASSOCSTR_FRIENDLYDOCNAME and ASSOCSTR_DEFAULTICON when passed a ProgID.
Signed-off-by: Theodore Dubois <tblodt@icloud.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
446ee50b90
commit
04a339e770
|
@ -88,6 +88,8 @@ static inline struct enumassochandlers *impl_from_IEnumAssocHandlers(IEnumAssocH
|
||||||
return CONTAINING_RECORD(iface, struct enumassochandlers, IEnumAssocHandlers_iface);
|
return CONTAINING_RECORD(iface, struct enumassochandlers, IEnumAssocHandlers_iface);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static HRESULT ASSOC_GetValue(HKEY hkey, const WCHAR *name, void **data, DWORD *data_size);
|
||||||
|
|
||||||
/**************************************************************************
|
/**************************************************************************
|
||||||
* IQueryAssociations_QueryInterface
|
* IQueryAssociations_QueryInterface
|
||||||
*
|
*
|
||||||
|
@ -196,10 +198,16 @@ static HRESULT WINAPI IQueryAssociations_fnInit(
|
||||||
FIXME("unsupported flags: %x\n", cfFlags);
|
FIXME("unsupported flags: %x\n", cfFlags);
|
||||||
|
|
||||||
RegCloseKey(This->hkeySource);
|
RegCloseKey(This->hkeySource);
|
||||||
RegCloseKey(This->hkeyProgID);
|
if (This->hkeySource != This->hkeyProgID)
|
||||||
|
RegCloseKey(This->hkeyProgID);
|
||||||
This->hkeySource = This->hkeyProgID = NULL;
|
This->hkeySource = This->hkeyProgID = NULL;
|
||||||
|
|
||||||
|
/* If the process of initializing hkeyProgID fails, just return S_OK. That's what Windows does. */
|
||||||
if (pszAssoc != NULL)
|
if (pszAssoc != NULL)
|
||||||
{
|
{
|
||||||
|
WCHAR *progId;
|
||||||
|
HRESULT hr;
|
||||||
|
|
||||||
ret = RegOpenKeyExW(HKEY_CLASSES_ROOT,
|
ret = RegOpenKeyExW(HKEY_CLASSES_ROOT,
|
||||||
pszAssoc,
|
pszAssoc,
|
||||||
0,
|
0,
|
||||||
|
@ -207,22 +215,51 @@ static HRESULT WINAPI IQueryAssociations_fnInit(
|
||||||
&This->hkeySource);
|
&This->hkeySource);
|
||||||
if (ret)
|
if (ret)
|
||||||
return S_OK;
|
return S_OK;
|
||||||
/* if this is not a prog id */
|
/* if this is a progid */
|
||||||
if ((*pszAssoc == '.') || (*pszAssoc == '{'))
|
if (*pszAssoc != '.' && *pszAssoc != '{')
|
||||||
{
|
{
|
||||||
RegOpenKeyExW(This->hkeySource,
|
|
||||||
szProgID,
|
|
||||||
0,
|
|
||||||
KEY_READ,
|
|
||||||
&This->hkeyProgID);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
This->hkeyProgID = This->hkeySource;
|
This->hkeyProgID = This->hkeySource;
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* if it's not a progid, it's a file extension or clsid */
|
||||||
|
if (*pszAssoc == '.')
|
||||||
|
{
|
||||||
|
/* for a file extension, the progid is the default value */
|
||||||
|
hr = ASSOC_GetValue(This->hkeySource, NULL, (void**)&progId, NULL);
|
||||||
|
if (FAILED(hr))
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
else /* if (*pszAssoc == '{') */
|
||||||
|
{
|
||||||
|
HKEY progIdKey;
|
||||||
|
/* for a clsid, the progid is the default value of the ProgID subkey */
|
||||||
|
ret = RegOpenKeyExW(This->hkeySource,
|
||||||
|
szProgID,
|
||||||
|
0,
|
||||||
|
KEY_READ,
|
||||||
|
&progIdKey);
|
||||||
|
if (ret != ERROR_SUCCESS)
|
||||||
|
return S_OK;
|
||||||
|
hr = ASSOC_GetValue(progIdKey, NULL, (void**)&progId, NULL);
|
||||||
|
if (FAILED(hr))
|
||||||
|
return S_OK;
|
||||||
|
RegCloseKey(progIdKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* open the actual progid key, the one with the shell subkey */
|
||||||
|
ret = RegOpenKeyExW(HKEY_CLASSES_ROOT,
|
||||||
|
progId,
|
||||||
|
0,
|
||||||
|
KEY_READ,
|
||||||
|
&This->hkeyProgID);
|
||||||
|
HeapFree(GetProcessHeap(), 0, progId);
|
||||||
|
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
else if (hkeyProgid != NULL)
|
else if (hkeyProgid != NULL)
|
||||||
{
|
{
|
||||||
This->hkeyProgID = hkeyProgid;
|
This->hkeySource = This->hkeyProgID = hkeyProgid;
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -507,33 +544,15 @@ static HRESULT WINAPI IQueryAssociations_fnGetString(
|
||||||
|
|
||||||
case ASSOCSTR_FRIENDLYDOCNAME:
|
case ASSOCSTR_FRIENDLYDOCNAME:
|
||||||
{
|
{
|
||||||
WCHAR *pszFileType;
|
WCHAR *docName;
|
||||||
DWORD ret;
|
|
||||||
DWORD size;
|
|
||||||
|
|
||||||
hr = ASSOC_GetValue(This->hkeySource, NULL, (void**)&pszFileType, NULL);
|
hr = ASSOC_GetValue(This->hkeyProgID, NULL, (void**)&docName, NULL);
|
||||||
if (FAILED(hr))
|
if (FAILED(hr)) {
|
||||||
return hr;
|
/* hKeyProgID is NULL or there is no default value, so fail */
|
||||||
size = 0;
|
return HRESULT_FROM_WIN32(ERROR_NO_ASSOCIATION);
|
||||||
ret = RegGetValueW(HKEY_CLASSES_ROOT, pszFileType, NULL, RRF_RT_REG_SZ, NULL, NULL, &size);
|
|
||||||
if (ret == ERROR_SUCCESS)
|
|
||||||
{
|
|
||||||
WCHAR *docName = HeapAlloc(GetProcessHeap(), 0, size);
|
|
||||||
if (docName)
|
|
||||||
{
|
|
||||||
ret = RegGetValueW(HKEY_CLASSES_ROOT, pszFileType, NULL, RRF_RT_REG_SZ, NULL, docName, &size);
|
|
||||||
if (ret == ERROR_SUCCESS)
|
|
||||||
hr = ASSOC_ReturnString(flags, pszOut, pcchOut, docName, strlenW(docName) + 1);
|
|
||||||
else
|
|
||||||
hr = HRESULT_FROM_WIN32(ret);
|
|
||||||
HeapFree(GetProcessHeap(), 0, docName);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
hr = E_OUTOFMEMORY;
|
|
||||||
}
|
}
|
||||||
else
|
hr = ASSOC_ReturnString(flags, pszOut, pcchOut, docName, strlenW(docName) + 1);
|
||||||
hr = HRESULT_FROM_WIN32(ret);
|
HeapFree(GetProcessHeap(), 0, docName);
|
||||||
HeapFree(GetProcessHeap(), 0, pszFileType);
|
|
||||||
return hr;
|
return hr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -623,41 +642,33 @@ get_friendly_name_fail:
|
||||||
case ASSOCSTR_DEFAULTICON:
|
case ASSOCSTR_DEFAULTICON:
|
||||||
{
|
{
|
||||||
static const WCHAR DefaultIconW[] = {'D','e','f','a','u','l','t','I','c','o','n',0};
|
static const WCHAR DefaultIconW[] = {'D','e','f','a','u','l','t','I','c','o','n',0};
|
||||||
WCHAR *pszFileType;
|
static const WCHAR documentIcon[] = {'s','h','e','l','l','3','2','.','d','l','l',',','0',0};
|
||||||
DWORD ret;
|
DWORD ret;
|
||||||
DWORD size;
|
DWORD size;
|
||||||
HKEY hkeyFile;
|
|
||||||
|
|
||||||
hr = ASSOC_GetValue(This->hkeySource, NULL, (void**)&pszFileType, NULL);
|
size = 0;
|
||||||
if (FAILED(hr))
|
ret = RegGetValueW(This->hkeyProgID, DefaultIconW, NULL, RRF_RT_REG_SZ, NULL, NULL, &size);
|
||||||
return hr;
|
|
||||||
ret = RegOpenKeyExW(HKEY_CLASSES_ROOT, pszFileType, 0, KEY_READ, &hkeyFile);
|
|
||||||
if (ret == ERROR_SUCCESS)
|
if (ret == ERROR_SUCCESS)
|
||||||
{
|
{
|
||||||
size = 0;
|
WCHAR *icon = HeapAlloc(GetProcessHeap(), 0, size);
|
||||||
ret = RegGetValueW(hkeyFile, DefaultIconW, NULL, RRF_RT_REG_SZ, NULL, NULL, &size);
|
if (icon)
|
||||||
if (ret == ERROR_SUCCESS)
|
|
||||||
{
|
{
|
||||||
WCHAR *icon = HeapAlloc(GetProcessHeap(), 0, size);
|
ret = RegGetValueW(This->hkeyProgID, DefaultIconW, NULL, RRF_RT_REG_SZ, NULL, icon, &size);
|
||||||
if (icon)
|
if (ret == ERROR_SUCCESS)
|
||||||
{
|
hr = ASSOC_ReturnString(flags, pszOut, pcchOut, icon, strlenW(icon) + 1);
|
||||||
ret = RegGetValueW(hkeyFile, DefaultIconW, NULL, RRF_RT_REG_SZ, NULL, icon, &size);
|
|
||||||
if (ret == ERROR_SUCCESS)
|
|
||||||
hr = ASSOC_ReturnString(flags, pszOut, pcchOut, icon, strlenW(icon) + 1);
|
|
||||||
else
|
|
||||||
hr = HRESULT_FROM_WIN32(ret);
|
|
||||||
HeapFree(GetProcessHeap(), 0, icon);
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
hr = E_OUTOFMEMORY;
|
hr = HRESULT_FROM_WIN32(ret);
|
||||||
|
HeapFree(GetProcessHeap(), 0, icon);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
hr = HRESULT_FROM_WIN32(ret);
|
hr = E_OUTOFMEMORY;
|
||||||
RegCloseKey(hkeyFile);
|
} else {
|
||||||
|
/* there is no DefaultIcon subkey or hkeyProgID is NULL, so return the default document icon */
|
||||||
|
if (This->hkeyProgID == NULL)
|
||||||
|
hr = ASSOC_ReturnString(flags, pszOut, pcchOut, documentIcon, strlenW(documentIcon) + 1);
|
||||||
|
else
|
||||||
|
return HRESULT_FROM_WIN32(ERROR_NO_ASSOCIATION);
|
||||||
}
|
}
|
||||||
else
|
|
||||||
hr = HRESULT_FROM_WIN32(ret);
|
|
||||||
HeapFree(GetProcessHeap(), 0, pszFileType);
|
|
||||||
return hr;
|
return hr;
|
||||||
}
|
}
|
||||||
case ASSOCSTR_SHELLEXTENSION:
|
case ASSOCSTR_SHELLEXTENSION:
|
||||||
|
|
Loading…
Reference in New Issue