shell32(2/6): Implement IQueryAssociations::Init()

Juan Lang juan.lang at gmail.com
Wed Aug 26 17:01:05 CDT 2009


--Juan
-------------- next part --------------
From 4fa4898a242726210371fd574bd1e5ee7c6da828 Mon Sep 17 00:00:00 2001
From: Juan Lang <juan.lang at gmail.com>
Date: Wed, 26 Aug 2009 14:27:58 -0700
Subject: [PATCH 4/8] Implement IQueryAssociations::Init()

---
 dlls/shell32/assoc.c |  113 +++++++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 111 insertions(+), 2 deletions(-)

diff --git a/dlls/shell32/assoc.c b/dlls/shell32/assoc.c
index 5ebc78f..66cac55 100644
--- a/dlls/shell32/assoc.c
+++ b/dlls/shell32/assoc.c
@@ -28,12 +28,14 @@
 #include "shlobj.h"
 #include "shlwapi.h"
 #include "wine/debug.h"
+#include "wine/unicode.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(shell);
 
 typedef struct {
     const IQueryAssociationsVtbl *lpVtbl;
     LONG                          ref;
+    HKEY                          key;
 } QueryAssociationsImpl;
 
 static HRESULT WINAPI IQueryAssociations_fnQueryInterface(
@@ -73,16 +75,122 @@ static ULONG WINAPI IQueryAssociations_fnRelease (IQueryAssociations *iface)
     ULONG refCount = InterlockedDecrement(&This->ref);
 
     if (!refCount)
+    {
+        RegCloseKey(This->key);
         SHFree(This);
+    }
     return refCount;
 }
 
+static HRESULT QueryAssociations_InitFromProgID(QueryAssociationsImpl *This,
+        LPCWSTR progID)
+{
+    LONG l;
+
+    l = RegOpenKeyExW(HKEY_CLASSES_ROOT, progID, 0, KEY_READ, &This->key);
+    return HRESULT_FROM_WIN32(l);
+}
+
+static HRESULT QueryAssociations_InitFromCLSID(QueryAssociationsImpl *This,
+        LPCWSTR clsid)
+{
+    static const WCHAR progIDFmt[] = { 'C','L','S','I','D','\\','%','s','\\',
+        'P','r','o','g','I','D',0 };
+    WCHAR temp[MAX_PATH], progID[MAX_PATH];
+    DWORD size = sizeof(progID);
+    LONG l;
+    HRESULT hr;
+
+    sprintfW(temp, progIDFmt, clsid);
+    l = RegGetValueW(HKEY_CLASSES_ROOT, temp, NULL, RRF_RT_REG_SZ, NULL,
+            progID, &size);
+    if (!l)
+        hr = QueryAssociations_InitFromProgID(This, progID);
+    else
+        hr = HRESULT_FROM_WIN32(l);
+    return hr;
+}
+
+static HRESULT QueryAssociations_InitFromExt(QueryAssociationsImpl *This,
+        LPCWSTR ext)
+{
+    WCHAR temp[MAX_PATH];
+    DWORD size = sizeof(temp);
+    LONG l;
+    HRESULT hr;
+
+    l = RegGetValueW(HKEY_CLASSES_ROOT, ext, NULL, RRF_RT_REG_SZ, NULL, temp,
+            &size);
+    if (!l)
+    {
+        /* The default value is the ProgID */
+        hr = QueryAssociations_InitFromProgID(This, temp);
+    }
+    else
+    {
+        static const WCHAR contentType[] = { 'C','o','n','t','e','n','t',' ',
+            'T','y','p','e',0 };
+
+        size = sizeof(temp);
+        l = RegGetValueW(HKEY_CLASSES_ROOT, ext, contentType, RRF_RT_REG_SZ,
+                NULL, temp, &size);
+        if (!l)
+        {
+            static const WCHAR mimeContentType[] = { 'M','I','M','E','\\',
+                'D','a','t','a','b','a','s','e','\\',
+                'C','o','n','t','e','n','t',' ','T','y','p','e',0 };
+            static const WCHAR clsid[] = { 'C','L','S','I','D',0 };
+
+            size = sizeof(temp);
+            l = RegGetValueW(HKEY_CLASSES_ROOT, mimeContentType, clsid,
+                    RRF_RT_REG_SZ, NULL, temp, &size);
+            if (!l)
+                hr = QueryAssociations_InitFromCLSID(This, temp);
+            else
+                hr = HRESULT_FROM_WIN32(l);
+        }
+        else
+            hr = HRESULT_FROM_WIN32(l);
+    }
+    return hr;
+}
+
 static HRESULT WINAPI IQueryAssociations_fnInit(IQueryAssociations *iface,
         ASSOCF flags, LPCWSTR pszAssoc, HKEY hkProgid, HWND hwnd)
 {
-    FIXME("(%p, %08x, %s, %p, %p): stub\n", iface, flags,
+    QueryAssociationsImpl *This = (QueryAssociationsImpl *)iface;
+    HRESULT hr;
+
+    TRACE("(%p, %08x, %s, %p, %p)\n", iface, flags,
             debugstr_w(pszAssoc), hkProgid, hwnd);
-    return E_NOTIMPL;
+
+    if (flags)
+    {
+        FIXME("unimplemented flags: %08x\n", flags);
+        return E_NOTIMPL;
+    }
+
+    if (This->key)
+    {
+        RegCloseKey(This->key);
+        This->key = NULL;
+    }
+    if (hkProgid)
+    {
+        LONG l = RegOpenKeyExW(hkProgid, NULL, 0, KEY_READ, &This->key);
+
+        hr = HRESULT_FROM_WIN32(l);
+    }
+    else
+    {
+        if (pszAssoc[0] == '{')
+            hr = QueryAssociations_InitFromCLSID(This, pszAssoc);
+        else if (pszAssoc[0] == '.')
+            hr = QueryAssociations_InitFromExt(This, pszAssoc);
+        else
+            hr = QueryAssociations_InitFromProgID(This, pszAssoc);
+    }
+    return hr;
 }
 
 static HRESULT WINAPI IQueryAssociations_fnGetString(IQueryAssociations *iface,
@@ -146,6 +254,7 @@ HRESULT WINAPI QueryAssociations_Constructor(IUnknown *pUnkOuter, REFIID riid, L
         return E_OUTOFMEMORY;
     obj->lpVtbl = &queryAssociationsVtbl;
     obj->ref = 1;
+    obj->key = NULL;
     if (FAILED(ret = IUnknown_QueryInterface((IUnknown *)obj, riid, ppOutput)))
         return ret;
     return S_OK;
-- 
1.6.3.2


More information about the wine-patches mailing list