Lei Zhang : shlwapi: Handle ASSOCSTR_EXECUTABLE in IQueryAssociations_GetString.
Alexandre Julliard
julliard at winehq.org
Mon Oct 13 06:38:55 CDT 2008
Module: wine
Branch: master
Commit: 3684009b6e2cd8d4fc287e195b52581fc6857e46
URL: http://source.winehq.org/git/wine.git/?a=commit;h=3684009b6e2cd8d4fc287e195b52581fc6857e46
Author: Lei Zhang <thestig at google.com>
Date: Fri Oct 10 23:34:04 2008 -0700
shlwapi: Handle ASSOCSTR_EXECUTABLE in IQueryAssociations_GetString.
---
dlls/shlwapi/assoc.c | 141 +++++++++++++++++++++++++++++++++++++++++++-
dlls/shlwapi/tests/assoc.c | 6 +-
2 files changed, 141 insertions(+), 6 deletions(-)
diff --git a/dlls/shlwapi/assoc.c b/dlls/shlwapi/assoc.c
index 23ece70..8ef6da2 100644
--- a/dlls/shlwapi/assoc.c
+++ b/dlls/shlwapi/assoc.c
@@ -18,6 +18,7 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <stdarg.h>
+#include <assert.h>
#include "windef.h"
#include "winbase.h"
@@ -26,6 +27,7 @@
#include "objbase.h"
#include "shlguid.h"
#include "shlwapi.h"
+#include "wine/unicode.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(shell);
@@ -562,6 +564,30 @@ static HRESULT WINAPI IQueryAssociations_fnInit(
return E_INVALIDARG;
}
+static HRESULT ASSOC_GetValue(HKEY hkey, WCHAR ** pszText)
+{
+ DWORD len;
+ LONG ret;
+
+ assert(pszText);
+ ret = RegQueryValueExW(hkey, NULL, 0, NULL, NULL, &len);
+ if (ret != ERROR_SUCCESS)
+ return HRESULT_FROM_WIN32(ret);
+ if (!len)
+ return E_FAIL;
+ *pszText = HeapAlloc(GetProcessHeap(), 0, len);
+ if (!*pszText)
+ return E_OUTOFMEMORY;
+ ret = RegQueryValueExW(hkey, NULL, 0, NULL, (LPBYTE)*pszText,
+ &len);
+ if (ret != ERROR_SUCCESS)
+ {
+ HeapFree(GetProcessHeap(), 0, *pszText);
+ return HRESULT_FROM_WIN32(ret);
+ }
+ return S_OK;
+}
+
/**************************************************************************
* IQueryAssociations_GetString {SHLWAPI}
*
@@ -588,10 +614,119 @@ static HRESULT WINAPI IQueryAssociations_fnGetString(
DWORD *pcchOut)
{
IQueryAssociationsImpl *This = (IQueryAssociationsImpl *)iface;
-
- FIXME("(%p,0x%8x,0x%8x,%s,%p,%p)-stub!\n", This, cfFlags, str,
+ const ASSOCF cfUnimplemented = ~(0);
+ DWORD len;
+ HKEY hkeyCommand;
+ HKEY hkeyFile;
+ HKEY hkeyShell;
+ HKEY hkeyVerb;
+ HRESULT hr;
+ LONG ret;
+ WCHAR path[MAX_PATH];
+ WCHAR * pszCommand;
+ WCHAR * pszEnd;
+ WCHAR * pszExtraFromReg;
+ WCHAR * pszFileType;
+ WCHAR * pszStart;
+ static const WCHAR commandW[] = { 'c','o','m','m','a','n','d',0 };
+ static const WCHAR shellW[] = { 's','h','e','l','l',0 };
+
+ TRACE("(%p,0x%8x,0x%8x,%s,%p,%p)\n", This, cfFlags, str,
debugstr_w(pszExtra), pszOut, pcchOut);
- return E_NOTIMPL;
+
+ if (cfFlags & cfUnimplemented)
+ FIXME("%08x: unimplemented flags!\n", cfFlags & cfUnimplemented);
+
+ if (!pcchOut)
+ return E_UNEXPECTED;
+
+ switch (str)
+ {
+ case ASSOCSTR_EXECUTABLE:
+ {
+ hr = ASSOC_GetValue(This->hkeySource, &pszFileType);
+ if (FAILED(hr))
+ return hr;
+ ret = RegOpenKeyExW(HKEY_CLASSES_ROOT, pszFileType, 0, KEY_READ,
+ &hkeyFile);
+ 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, &pszExtraFromReg);
+ if (FAILED(hr))
+ {
+ RegCloseKey(hkeyShell);
+ return hr;
+ }
+ }
+
+ ret = RegOpenKeyExW(hkeyShell, pszExtra ? pszExtra : pszExtraFromReg,
+ 0, KEY_READ, &hkeyVerb);
+ HeapFree(GetProcessHeap(), 0, pszExtraFromReg);
+ RegCloseKey(hkeyShell);
+ if (ret != ERROR_SUCCESS)
+ return HRESULT_FROM_WIN32(ret);
+
+ ret = RegOpenKeyExW(hkeyVerb, commandW, 0, KEY_READ, &hkeyCommand);
+ RegCloseKey(hkeyVerb);
+ if (ret != ERROR_SUCCESS)
+ return HRESULT_FROM_WIN32(ret);
+ hr = ASSOC_GetValue(hkeyCommand, &pszCommand);
+ RegCloseKey(hkeyCommand);
+ if (FAILED(hr))
+ return hr;
+
+ /* cleanup pszCommand */
+ if (pszCommand[0] == '"')
+ {
+ pszStart = pszCommand + 1;
+ pszEnd = strchrW(pszStart, '"');
+ }
+ else
+ {
+ pszStart = pszCommand;
+ pszEnd = strchrW(pszStart, ' ');
+ }
+ if (pszEnd)
+ *pszEnd = 0;
+
+ len = SearchPathW(NULL, pszStart, NULL, MAX_PATH, path, NULL);
+ HeapFree(GetProcessHeap(), 0, pszCommand);
+ if (!len)
+ return HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);
+
+ len++;
+ if (pszOut)
+ {
+ if (*pcchOut < len)
+ {
+ *pcchOut = len;
+ return E_POINTER;
+ }
+ *pcchOut = len;
+ lstrcpynW(pszOut, path, len);
+ return S_OK;
+ }
+ else
+ {
+ *pcchOut = len;
+ return S_FALSE;
+ }
+ break;
+ }
+
+ default:
+ FIXME("assocstr %d unimplemented!\n", str);
+ return E_NOTIMPL;
+ }
}
/**************************************************************************
diff --git a/dlls/shlwapi/tests/assoc.c b/dlls/shlwapi/tests/assoc.c
index 4d5c87c..bb1c4d6 100644
--- a/dlls/shlwapi/tests/assoc.c
+++ b/dlls/shlwapi/tests/assoc.c
@@ -45,7 +45,7 @@ static void test_getstring_bad(void)
expect_hr(E_FAIL, hr);
hr = AssocQueryStringW(0, ASSOCSTR_EXECUTABLE, dotHtml, invalid, NULL,
&len);
- todo_wine expect_hr(0x80070002, hr); /* NOT FOUND */
+ expect_hr(0x80070002, hr); /* NOT FOUND */
hr = AssocQueryStringW(0, ASSOCSTR_EXECUTABLE, dotHtml, open, NULL, NULL);
expect_hr(E_UNEXPECTED, hr);
@@ -73,7 +73,7 @@ static void test_getstring_basic(void)
DWORD len, len2, slen;
hr = AssocQueryStringW(0, ASSOCSTR_EXECUTABLE, dotHtml, open, NULL, &len);
- todo_wine expect_hr(S_FALSE, hr);
+ expect_hr(S_FALSE, hr);
if (hr != S_FALSE)
{
skip("failed to get initial len\n");
@@ -98,7 +98,7 @@ static void test_getstring_basic(void)
hr = AssocQueryStringW(0, ASSOCSTR_FRIENDLYAPPNAME, dotHtml, open, NULL,
&len);
- expect_hr(S_FALSE, hr);
+ todo_wine expect_hr(S_FALSE, hr);
if (hr != S_FALSE)
{
HeapFree(GetProcessHeap(), 0, executableName);
More information about the wine-cvs
mailing list