Nikolay Sivov : combase: Move CLSIDFromProgID().

Alexandre Julliard julliard at winehq.org
Mon Aug 10 16:16:29 CDT 2020


Module: wine
Branch: master
Commit: d271b9ff73e8c9fe18a513517e144a799b65e171
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=d271b9ff73e8c9fe18a513517e144a799b65e171

Author: Nikolay Sivov <nsivov at codeweavers.com>
Date:   Mon Aug 10 11:12:51 2020 +0300

combase: Move CLSIDFromProgID().

Signed-off-by: Nikolay Sivov <nsivov at codeweavers.com>
Signed-off-by: Huw Davies <huw at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/combase/combase.c    | 138 ++++++++++++++++++++++++++++++++++++++++++++++
 dlls/combase/combase.spec |   2 +-
 dlls/ole32/compobj.c      |  33 -----------
 dlls/ole32/ole32.spec     |   2 +-
 4 files changed, 140 insertions(+), 35 deletions(-)

diff --git a/dlls/combase/combase.c b/dlls/combase/combase.c
index 6b8eb4ee7a..2d202c796d 100644
--- a/dlls/combase/combase.c
+++ b/dlls/combase/combase.c
@@ -28,6 +28,7 @@
 #include "winternl.h"
 
 #include "wine/debug.h"
+#include "wine/heap.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(ole);
 
@@ -55,6 +56,13 @@ struct comclassredirect_data
     DWORD miscstatusdocprint;
 };
 
+struct progidredirect_data
+{
+    ULONG size;
+    DWORD reserved;
+    ULONG clsid_offset;
+};
+
 static NTSTATUS create_key(HKEY *retkey, ACCESS_MASK access, OBJECT_ATTRIBUTES *attr)
 {
     NTSTATUS status = NtCreateKey((HANDLE *)retkey, access, attr, 0, NULL, 0, NULL);
@@ -915,6 +923,136 @@ HRESULT WINAPI DECLSPEC_HOTPATCH ProgIDFromCLSID(REFCLSID clsid, LPOLESTR *progi
     return hr;
 }
 
+static inline BOOL is_valid_hex(WCHAR c)
+{
+    if (!(((c >= '0') && (c <= '9'))  ||
+          ((c >= 'a') && (c <= 'f'))  ||
+          ((c >= 'A') && (c <= 'F'))))
+        return FALSE;
+    return TRUE;
+}
+
+static const BYTE guid_conv_table[256] =
+{
+    0,   0,   0,   0,   0,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x00 */
+    0,   0,   0,   0,   0,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x10 */
+    0,   0,   0,   0,   0,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x20 */
+    0,   1,   2,   3,   4,   5,   6, 7, 8, 9, 0, 0, 0, 0, 0, 0, /* 0x30 */
+    0, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x40 */
+    0,   0,   0,   0,   0,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x50 */
+    0, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf                             /* 0x60 */
+};
+
+static BOOL guid_from_string(LPCWSTR s, GUID *id)
+{
+    int i;
+
+    if (!s || s[0] != '{')
+    {
+        memset(id, 0, sizeof(*id));
+        if (!s) return TRUE;
+        return FALSE;
+    }
+
+    TRACE("%s -> %p\n", debugstr_w(s), id);
+
+    /* In form {XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX} */
+
+    id->Data1 = 0;
+    for (i = 1; i < 9; ++i)
+    {
+        if (!is_valid_hex(s[i])) return FALSE;
+        id->Data1 = (id->Data1 << 4) | guid_conv_table[s[i]];
+    }
+    if (s[9] != '-') return FALSE;
+
+    id->Data2 = 0;
+    for (i = 10; i < 14; ++i)
+    {
+        if (!is_valid_hex(s[i])) return FALSE;
+        id->Data2 = (id->Data2 << 4) | guid_conv_table[s[i]];
+    }
+    if (s[14] != '-') return FALSE;
+
+    id->Data3 = 0;
+    for (i = 15; i < 19; ++i)
+    {
+        if (!is_valid_hex(s[i])) return FALSE;
+        id->Data3 = (id->Data3 << 4) | guid_conv_table[s[i]];
+    }
+    if (s[19] != '-') return FALSE;
+
+    for (i = 20; i < 37; i += 2)
+    {
+        if (i == 24)
+        {
+            if (s[i] != '-') return FALSE;
+            i++;
+        }
+        if (!is_valid_hex(s[i]) || !is_valid_hex(s[i + 1])) return FALSE;
+        id->Data4[(i - 20) / 2] = guid_conv_table[s[i]] << 4 | guid_conv_table[s[i + 1]];
+    }
+
+    if (s[37] == '}' && s[38] == '\0')
+        return TRUE;
+
+    return FALSE;
+}
+
+static HRESULT clsid_from_string_reg(LPCOLESTR progid, CLSID *clsid)
+{
+    WCHAR buf2[CHARS_IN_GUID];
+    LONG buf2len = sizeof(buf2);
+    HKEY xhkey;
+    WCHAR *buf;
+
+    memset(clsid, 0, sizeof(*clsid));
+    buf = heap_alloc((lstrlenW(progid) + 8) * sizeof(WCHAR));
+    if (!buf) return E_OUTOFMEMORY;
+
+    lstrcpyW(buf, progid);
+    lstrcatW(buf, L"\\CLSID");
+    if (open_classes_key(HKEY_CLASSES_ROOT, buf, MAXIMUM_ALLOWED, &xhkey))
+    {
+        heap_free(buf);
+        WARN("couldn't open key for ProgID %s\n", debugstr_w(progid));
+        return CO_E_CLASSSTRING;
+    }
+    heap_free(buf);
+
+    if (RegQueryValueW(xhkey, NULL, buf2, &buf2len))
+    {
+        RegCloseKey(xhkey);
+        WARN("couldn't query clsid value for ProgID %s\n", debugstr_w(progid));
+        return CO_E_CLASSSTRING;
+    }
+    RegCloseKey(xhkey);
+    return guid_from_string(buf2, clsid) ? S_OK : CO_E_CLASSSTRING;
+}
+
+/******************************************************************************
+ *                CLSIDFromProgID        (combase.@)
+ */
+HRESULT WINAPI DECLSPEC_HOTPATCH CLSIDFromProgID(LPCOLESTR progid, CLSID *clsid)
+{
+    ACTCTX_SECTION_KEYED_DATA data;
+
+    if (!progid || !clsid)
+        return E_INVALIDARG;
+
+    data.cbSize = sizeof(data);
+    if (FindActCtxSectionStringW(0, NULL, ACTIVATION_CONTEXT_SECTION_COM_PROGID_REDIRECTION,
+            progid, &data))
+    {
+        struct progidredirect_data *progiddata = (struct progidredirect_data *)data.lpData;
+        CLSID *alias = (CLSID *)((BYTE *)data.lpSectionBase + progiddata->clsid_offset);
+        *clsid = *alias;
+        return S_OK;
+    }
+
+    return clsid_from_string_reg(progid, clsid);
+}
+
 static void init_multi_qi(DWORD count, MULTI_QI *mqi, HRESULT hr)
 {
     ULONG i;
diff --git a/dlls/combase/combase.spec b/dlls/combase/combase.spec
index a90a418764..4e5c5a9dc9 100644
--- a/dlls/combase/combase.spec
+++ b/dlls/combase/combase.spec
@@ -67,7 +67,7 @@
 @ stdcall CLIPFORMAT_UserSize(ptr long ptr)
 @ stdcall CLIPFORMAT_UserUnmarshal(ptr ptr ptr)
 @ stub CLSIDFromOle1Class
-@ stdcall CLSIDFromProgID(wstr ptr) ole32.CLSIDFromProgID
+@ stdcall CLSIDFromProgID(wstr ptr)
 @ stdcall CLSIDFromString(wstr ptr) ole32.CLSIDFromString
 @ stub CleanupOleStateInAllTls
 @ stdcall CleanupTlsOleState(ptr)
diff --git a/dlls/ole32/compobj.c b/dlls/ole32/compobj.c
index 47b815b752..91ff812428 100644
--- a/dlls/ole32/compobj.c
+++ b/dlls/ole32/compobj.c
@@ -2485,39 +2485,6 @@ HRESULT COM_OpenKeyForAppIdFromCLSID(REFCLSID clsid, REGSAM access, HKEY *subkey
     return S_OK;
 }
 
-/******************************************************************************
- *		CLSIDFromProgID	[OLE32.@]
- *
- * Converts a program id into the respective GUID.
- *
- * PARAMS
- *  progid [I] Unicode program ID, as found in registry.
- *  clsid  [O] Associated CLSID.
- *
- * RETURNS
- *	Success: S_OK
- *  Failure: CO_E_CLASSSTRING - the given ProgID cannot be found.
- */
-HRESULT WINAPI DECLSPEC_HOTPATCH CLSIDFromProgID(LPCOLESTR progid, LPCLSID clsid)
-{
-    ACTCTX_SECTION_KEYED_DATA data;
-
-    if (!progid || !clsid)
-        return E_INVALIDARG;
-
-    data.cbSize = sizeof(data);
-    if (FindActCtxSectionStringW(0, NULL, ACTIVATION_CONTEXT_SECTION_COM_PROGID_REDIRECTION,
-                                 progid, &data))
-    {
-        struct progidredirect_data *progiddata = (struct progidredirect_data*)data.lpData;
-        CLSID *alias = (CLSID*)((BYTE*)data.lpSectionBase + progiddata->clsid_offset);
-        *clsid = *alias;
-        return S_OK;
-    }
-
-    return clsid_from_string_reg(progid, clsid);
-}
-
 /******************************************************************************
  *              CLSIDFromProgIDEx [OLE32.@]
  */
diff --git a/dlls/ole32/ole32.spec b/dlls/ole32/ole32.spec
index 74eb6f0106..ce5d7987d9 100644
--- a/dlls/ole32/ole32.spec
+++ b/dlls/ole32/ole32.spec
@@ -3,7 +3,7 @@
 @ stdcall CLIPFORMAT_UserMarshal(ptr ptr ptr) combase.CLIPFORMAT_UserMarshal
 @ stdcall CLIPFORMAT_UserSize(ptr long ptr) combase.CLIPFORMAT_UserSize
 @ stdcall CLIPFORMAT_UserUnmarshal(ptr ptr ptr) combase.CLIPFORMAT_UserUnmarshal
-@ stdcall CLSIDFromProgID(wstr ptr)
+@ stdcall CLSIDFromProgID(wstr ptr) combase.CLSIDFromProgID
 @ stdcall CLSIDFromProgIDEx(wstr ptr)
 @ stdcall CLSIDFromString(wstr ptr)
 @ stdcall CoAddRefServerProcess()




More information about the wine-cvs mailing list