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