[SHELL32] IQueryAssociations: Fix path and length (#6656)
authorKatayama Hirofumi MZ <katayama.hirofumi.mz@gmail.com>
Sun, 24 Mar 2024 22:35:15 +0000 (07:35 +0900)
committerGitHub <noreply@github.com>
Sun, 24 Mar 2024 22:35:15 +0000 (07:35 +0900)
Implementing correct FindExecutable...
JIRA issue: CORE-19493
- If there were filename extension, then skip to the extension
  by using PathFindExtensionW.
- Use "open" verb if there is no default action if possible.
- Set outlen at CQueryAssociations::ReturnString.

dll/win32/shell32/CQueryAssociations.cpp

index 093a536..974ea5d 100644 (file)
@@ -96,6 +96,11 @@ HRESULT STDMETHODCALLTYPE CQueryAssociations::Init(
     {
         WCHAR *progId;
         HRESULT hr;
+        LPCWSTR pchDotExt;
+
+        pchDotExt = PathFindExtensionW(pszAssoc);
+        if (pchDotExt && *pchDotExt)
+            pszAssoc = pchDotExt;
 
         LONG ret = RegOpenKeyExW(HKEY_CLASSES_ROOT,
                             pszAssoc,
@@ -216,7 +221,7 @@ HRESULT STDMETHODCALLTYPE CQueryAssociations::GetString(
         case ASSOCSTR_EXECUTABLE:
         {
             hr = this->GetExecutable(pszExtra, path, MAX_PATH, &len);
-            if (FAILED(hr))
+            if (FAILED_UNEXPECTEDLY(hr))
             {
                 return hr;
             }
@@ -535,28 +540,25 @@ HRESULT CQueryAssociations::GetValue(HKEY hkey, const WCHAR *name, void **data,
 
     ret = RegQueryValueExW(hkey, name, 0, NULL, NULL, &size);
     if (ret != ERROR_SUCCESS)
-    {
         return HRESULT_FROM_WIN32(ret);
-    }
+
     if (!size)
-    {
         return E_FAIL;
-    }
+
     *data = HeapAlloc(GetProcessHeap(), 0, size);
     if (!*data)
-    {
         return E_OUTOFMEMORY;
-    }
+
     ret = RegQueryValueExW(hkey, name, 0, NULL, (LPBYTE)*data, &size);
     if (ret != ERROR_SUCCESS)
     {
         HeapFree(GetProcessHeap(), 0, *data);
         return HRESULT_FROM_WIN32(ret);
     }
-    if(data_size)
-    {
+
+    if (data_size)
         *data_size = size;
-    }
+
     return S_OK;
 }
 
@@ -604,6 +606,8 @@ HRESULT CQueryAssociations::GetCommand(const WCHAR *extra, WCHAR **command)
     {
         /* check for default verb */
         hr = this->GetValue(hkeyShell, NULL, (void**)&extra_from_reg, NULL);
+        if (FAILED(hr))
+            hr = this->GetValue(hkeyShell, L"open", (void**)&extra_from_reg, NULL);
         if (FAILED(hr))
         {
             /* no default verb, try first subkey */
@@ -662,7 +666,7 @@ HRESULT CQueryAssociations::GetExecutable(LPCWSTR pszExtra, LPWSTR path, DWORD p
     WCHAR *pszEnd;
 
     HRESULT hr = this->GetCommand(pszExtra, &pszCommand);
-    if (FAILED(hr))
+    if (FAILED_UNEXPECTEDLY(hr))
     {
         return hr;
     }
@@ -765,7 +769,7 @@ HRESULT CQueryAssociations::ReturnString(ASSOCF flags, LPWSTR out, DWORD *outlen
     }
     else
     {
-        len = datalen;
+        *outlen = len = datalen;
     }
 
     if (len)