[ATL] Improve the order of operations in CComPtr and CComQIIDPtr
authorMark Jansen <mark.jansen@reactos.org>
Sun, 5 Aug 2018 09:48:31 +0000 (11:48 +0200)
committerMark Jansen <mark.jansen@reactos.org>
Sun, 19 Aug 2018 15:35:18 +0000 (17:35 +0200)
sdk/lib/atl/atlcomcli.h

index 229c585..ad1582a 100644 (file)
@@ -87,23 +87,49 @@ public:
 
     T *operator = (T *lp)
     {
-        if (p != NULL)
-            p->Release();
+        T* pOld = p;
+
         p = lp;
         if (p != NULL)
             p->AddRef();
+
+        if (pOld != NULL)
+            pOld->Release();
+
         return *this;
     }
 
     T *operator = (const CComPtr<T> &lp)
     {
-        if (p != NULL)
-            p->Release();
+        T* pOld = p;
+
         p = lp.p;
         if (p != NULL)
             p->AddRef();
+
+        if (pOld != NULL)
+            pOld->Release();
+
+        return *this;
+    }
+
+    // We cannot enable this until gcc starts supporting __uuidof
+    // See CORE-12710
+#if 0
+    template <typename Q>
+    T* operator=(const CComPtr<Q>& lp)
+    {
+        T* pOld = p;
+
+        if (!lp.p || FAILED(lp.p->QueryInterface(__uuidof(T), (void**)(IUnknown**)&p)))
+            p = NULL;
+
+        if (pOld != NULL)
+            pOld->Release();
+
         return *this;
     }
+#endif
 
     void Release()
     {
@@ -175,38 +201,48 @@ public:
     {
         if (lp != NULL)
         {
-            if (FAILED(lp->QueryInterface(*piid, reinterpret_cast<void **>(&p))))
+            if (FAILED(lp->QueryInterface(*piid, (void**)(IUnknown**)&p)))
                 p = NULL;
         }
     }
     T *operator = (T *lp)
     {
-        if (p != NULL)
-            p->Release();
+        T* pOld = p;
+
         p = lp;
         if (p != NULL)
             p->AddRef();
+
+        if (pOld != NULL)
+            pOld->Release();
+
         return *this;
     }
 
     T *operator = (const CComQIIDPtr<T,piid> &lp)
     {
-        if (p != NULL)
-            p->Release();
+        T* pOld = p;
+
         p = lp.p;
         if (p != NULL)
             p->AddRef();
+
+        if (pOld != NULL)
+            pOld->Release();
+
         return *this;
     }
 
     T * operator=(IUnknown* lp)
     {
-        if (p != NULL)
-            p->Release();
+        T* pOld = p;
 
-        if (FAILED(lp->QueryInterface(*piid, reinterpret_cast<void **>(&p))))
+        if (!lp || FAILED(lp->QueryInterface(*piid, (void**)(IUnknown**)&p)))
             p = NULL;
 
+        if (pOld != NULL)
+            pOld->Release();
+
         return *this;
     }
 };