mhammond / pywin32

Python for Windows (pywin32) Extensions
5.08k stars 799 forks source link

Workaround Windows API bug CLSIDFromString #650

Open ghost opened 11 years ago

ghost commented 11 years ago

There are two ways a program could get information about a COM server:

If an activation context is active this information has to be preferred. There is a bug in the CLSIDFromString Windows API method which always looks into the registry if the given string is a malformed GUID (e.g. a ProgID), hence the string has to be checked before the method is called if it is a GUID. I attached a patch which takes this workaround into account.

Reported by: sschukat

Original Ticket: pywin32/bugs/650

Avasam commented 8 months ago

Tagging @sschukat as the original SourceForge issue creator.

Proposed patch with updated formatting and location:

diff --git a/win32/src/PyIID.cpp b/win32/src/PyIID.cpp
index 5f004225..645cea8a 100644
--- a/win32/src/PyIID.cpp
+++ b/win32/src/PyIID.cpp
@@ -7,6 +7,27 @@
 #include "PyWinObjects.h"

 #ifndef NO_PYWINTYPES_IID
+static HRESULT myCLSIDFromString(OLECHAR *str, CLSID *clsid)
+{
+    HRESULT hr = E_FAIL;
+    if (str && str[0] == L'{') {
+        hr = CLSIDFromString(str, clsid);
+#ifdef MS_WINCE
+        return hr;
+#else
+        if (SUCCEEDED(hr))
+            return hr;
+        return CLSIDFromProgID(str, clsid);
+#endif
+    }
+#ifndef MS_WINCE
+    else {
+        return CLSIDFromProgID(str, clsid);
+    }
+#endif
+    return hr;
+}
+
 // @pymethod <o PyIID>|pywintypes|IID|Creates a new IID object
 PyObject *PyWinMethod_NewIID(PyObject *self, PyObject *args)
 {
@@ -37,36 +58,17 @@ PyObject *PyWinMethod_NewIID(PyObject *self, PyObject *args)
     if (!PyWinObject_AsWCHAR(obIID, &bstrIID))
         return NULL;

-    HRESULT hr = CLSIDFromString(bstrIID, &iid);
+    HRESULT hr = myCLSIDFromString(bstrIID, &iid);
     if (FAILED(hr)) {
-#ifndef MS_WINCE
-        hr = CLSIDFromProgID(bstrIID, &iid);
-        if (FAILED(hr)) {
-#endif
-            PyWinObject_FreeWCHAR(bstrIID);
-            PyWin_SetBasicCOMError(hr);
-            return NULL;
-#ifndef MS_WINCE
-        }
-#endif
+        PyWinObject_FreeWCHAR(bstrIID);
+        PyWin_SetBasicCOMError(hr);
+        return NULL;
     }
     PyWinObject_FreeWCHAR(bstrIID);
     /* iid -> PyObject */
     return PyWinObject_FromIID(iid);
 }

-static HRESULT myCLSIDFromString(OLECHAR *str, CLSID *clsid)
-{
-    HRESULT hr = CLSIDFromString(str, clsid);
-#ifdef MS_WINCE
-    return hr;
-#else
-    if (SUCCEEDED(hr))
-        return hr;
-    return CLSIDFromProgID(str, clsid);
-#endif
-}
-
 BOOL PyWinObject_AsIID(PyObject *obCLSID, CLSID *clsid)
 {
     BSTR bstrCLSID;