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