msi ole automation update

Misha Koshelev mk144210 at bcm.tmc.edu
Sat Mar 3 17:46:22 CST 2007


On Sat, 2007-03-03 at 17:03 -0600, Misha Koshelev wrote:
> Hi everbody,
> 
> I have been working on some more stuff for the MSI OLE automation, and I
> now have a moderately comprehensive conformance test (1000 or so lines,
> tests each function implemented at least for basic functionality, tests
> things like return codes, if you set a property and then get it do you
> get what you set it to, etc.). A few small patches are needed to then
> make my OLE automation code (which is still hanging out in wine-patches,
> not in git yet) pass this test. 
> 
> I am going to wait to send all these new patches to wine-patches until
> my other patches get reviewed/committed by Alexandre. However, I thought
> I would post them here for any comments. I am going to be _quite_ busy
> starting Monday for a month though, so I may likely not be able to make
> any serious modifications to them if people see large problems until
> April. However, if anyone has any comments about these or my patches
> already sitting in wine-patches, please do let me know.
> 
> Thanks
> Misha

Whoops, one small typo. Updated file attached.

Misha
-------------- next part --------------
From 9edf7480405e5aa133e834fc09711e54e3c18e19 Mon Sep 17 00:00:00 2001
From: Misha Koshelev <mk144210 at bcm.tmc.edu>
Date: Sat, 3 Mar 2007 17:33:10 -0600
Subject: msi: automation: Return exceptions like native.
---
 dlls/msi/automation.c |  102 +++++++++++++++++++++++++++++++++++++++++--------
 1 files changed, 86 insertions(+), 16 deletions(-)

diff --git a/dlls/msi/automation.c b/dlls/msi/automation.c
index a504734..9825496 100644
--- a/dlls/msi/automation.c
+++ b/dlls/msi/automation.c
@@ -279,6 +279,9 @@ static HRESULT WINAPI AutomationObject_G
     return ITypeInfo_GetIDsOfNames(This->iTypeInfo, rgszNames, cNames, rgDispId);
 }
 
+/* Maximum number of allowed function parameters+1 */
+#define MAX_FUNC_PARAMS 20
+
 /* Some error checking is done here to simplify individual object function invocation */
 static HRESULT WINAPI AutomationObject_Invoke(
         IDispatch* iface,
@@ -337,6 +340,41 @@ static HRESULT WINAPI AutomationObject_I
 	if (bstrName == NULL) ITypeInfo_GetDocumentation(This->iTypeInfo, dispIdMember, &bstrName, NULL, NULL, NULL);
 	FIXME("Method %d, %s wflags %d not implemented, clsid %s\n", dispIdMember, debugstr_w(bstrName), wFlags, debugstr_guid(This->clsid));
     }
+    else if (pExcepInfo && 
+             (hr == DISP_E_PARAMNOTFOUND ||
+              hr == DISP_E_EXCEPTION)) {
+        static WCHAR szComma[] = { ',',0 };
+        static WCHAR szExceptionSource[] = {'M','s','i',' ','A','P','I',' ','E','r','r','o','r',0};
+        WCHAR szExceptionDescription[MAX_PATH];
+        BSTR bstrParamNames[MAX_FUNC_PARAMS];
+        unsigned namesNo, i;
+        BOOL bFirst = TRUE;
+
+        if (FAILED(ITypeInfo_GetNames(This->iTypeInfo, dispIdMember, bstrParamNames,
+                                      MAX_FUNC_PARAMS, &namesNo)))
+        {
+            TRACE("Failed to retrieve names for dispIdMember %d\n", dispIdMember);
+        }
+        else 
+        {
+            memset(szExceptionDescription, 0, sizeof(szExceptionDescription));
+            for (i=0; i<namesNo; i++)
+            {
+                if (bFirst) bFirst = FALSE;
+                else {
+                    lstrcpyW(&szExceptionDescription[lstrlenW(szExceptionDescription)], szComma);
+                }
+                lstrcpyW(&szExceptionDescription[lstrlenW(szExceptionDescription)], bstrParamNames[i]);            
+                SysFreeString(bstrParamNames[i]);
+            }
+
+            memset(pExcepInfo, 0, sizeof(EXCEPINFO));
+            pExcepInfo->wCode = 1000;
+            pExcepInfo->bstrSource = szExceptionSource;
+            pExcepInfo->bstrDescription = szExceptionDescription;
+            hr = DISP_E_EXCEPTION;
+        }
+    }
 
     /* Make sure we free the return variant if it is our dummy variant */
     if (pVarResult == &varResultDummy) VariantClear(pVarResult);
@@ -582,7 +620,7 @@ HRESULT WINAPI RecordImpl_Invoke(
                     V_BSTR(pVarResult) = SysAllocString(szString);
 		else
 		{
-		    TRACE("MsiRecordGetString returned %d\n", ret);
+		    ERR("MsiRecordGetString returned %d\n", ret);
                     V_BSTR(pVarResult) = NULL;
 		}
 	    } else if (wFlags & DISPATCH_PROPERTYPUT) {
@@ -591,7 +629,10 @@ HRESULT WINAPI RecordImpl_Invoke(
                 hr = DispGetParam(pDispParams, DISPID_PROPERTYPUT, VT_BSTR, &varg1, puArgErr);
                 if (FAILED(hr)) return hr;
 		if ((ret = MsiRecordSetStringW(This->msiHandle, V_I4(&varg0), V_BSTR(&varg1))) != ERROR_SUCCESS)
-                    TRACE("MsiRecordSetString returned %d\n", ret);
+                {
+                    ERR("MsiRecordSetString returned %d\n", ret);
+                    return DISP_E_EXCEPTION;
+                }
 	    }
 	    break;
             
@@ -628,7 +669,7 @@ HRESULT WINAPI ViewImpl_Invoke(
 	    if (wFlags & DISPATCH_METHOD)
 	    {
                 hr = DispGetParam(pDispParams, 0, VT_DISPATCH, &varg0, puArgErr); 
-                if (SUCCEEDED(hr))
+                if (SUCCEEDED(hr) && V_DISPATCH(&varg0) != NULL)
                     MsiViewExecute(This->msiHandle, ((AutomationObject *)V_DISPATCH(&varg0))->msiHandle);
                 else
                     MsiViewExecute(This->msiHandle, 0);
@@ -639,13 +680,21 @@ HRESULT WINAPI ViewImpl_Invoke(
 	    if (wFlags & DISPATCH_METHOD)
 	    { 
                 V_VT(pVarResult) = VT_DISPATCH;
-		if ((ret = MsiViewFetch(This->msiHandle, &msiHandle)) == ERROR_SUCCESS) 
+                if ((ret = MsiViewFetch(This->msiHandle, &msiHandle)) == ERROR_SUCCESS) 
                 {
 		    if (SUCCEEDED(create_automation_object(msiHandle, NULL, (LPVOID)&pDispatch, &DIID_Record, RecordImpl_Invoke)))
+                    {
                         IDispatch_AddRef(pDispatch);
+                        V_DISPATCH(pVarResult) = pDispatch;
+                    }
+                }
+		else if (ret == ERROR_NO_MORE_ITEMS)
+                    V_DISPATCH(pVarResult) = NULL;
+                else
+                {
+                    ERR("MsiViewFetch returned %d\n", ret);
+                    return DISP_E_EXCEPTION;
                 }
-		else TRACE("MsiViewFetch returned %d\n", ret);
-                V_DISPATCH(pVarResult) = pDispatch;
 	    }
 	    break;
 
@@ -691,13 +740,19 @@ HRESULT WINAPI DatabaseImpl_Invoke(
                 hr = DispGetParam(pDispParams, 0, VT_BSTR, &varg0, puArgErr);
                 if (FAILED(hr)) return hr;
                 V_VT(pVarResult) = VT_DISPATCH;
-		if ((ret = MsiDatabaseOpenViewW(This->msiHandle, V_BSTR(&varg0), &msiHandle)) == ERROR_SUCCESS) 
+                if ((ret = MsiDatabaseOpenViewW(This->msiHandle, V_BSTR(&varg0), &msiHandle)) == ERROR_SUCCESS)
                 {
 		    if (SUCCEEDED(create_automation_object(msiHandle, NULL, (LPVOID)&pDispatch, &DIID_View, ViewImpl_Invoke)))
+                    {
                         IDispatch_AddRef(pDispatch);
+                        V_DISPATCH(pVarResult) = pDispatch;
+                    }
+                }
+		else 
+                {
+                    ERR("MsiDatabaseOpenView returned %d\n", ret);
+                    return DISP_E_EXCEPTION;
                 }
-		else TRACE("MsiDatabaseOpenView returned %d\n", ret);
-	        V_DISPATCH(pVarResult) = pDispatch;
 	    }
 	    break;
             
@@ -752,7 +807,10 @@ HRESULT WINAPI SessionImpl_Invoke(
                     return hr;
                 }
 		if ((ret = MsiSetPropertyW(This->msiHandle, V_BSTR(&varg0), V_BSTR(&varg1))) != ERROR_SUCCESS) 
-                    TRACE("MsiSetProperty returned %d\n", ret);
+                {
+                    ERR("MsiSetProperty returned %d\n", ret);
+                    return DISP_E_EXCEPTION;
+                }
 	    }
 	    break;
 
@@ -776,7 +834,10 @@ HRESULT WINAPI SessionImpl_Invoke(
                 hr = DispGetParam(pDispParams, DISPID_PROPERTYPUT, VT_BOOL, &varg1, puArgErr);
                 if (FAILED(hr)) return hr;
 		if ((ret = MsiSetMode(This->msiHandle, V_I4(&varg0), V_BOOL(&varg1))) != ERROR_SUCCESS)
-                    TRACE("MsiSetMode returned %d\n", ret);
+                {
+                    ERR("MsiSetMode returned %d\n", ret);
+                    return DISP_E_EXCEPTION;
+                }
 	    }
 	    break;
 
@@ -786,10 +847,16 @@ HRESULT WINAPI SessionImpl_Invoke(
 		if ((msiHandle = MsiGetActiveDatabase(This->msiHandle))) 
                 {
 		    if (SUCCEEDED(create_automation_object(msiHandle, NULL, (LPVOID)&pDispatch, &DIID_Database, DatabaseImpl_Invoke)))
+                    {
                         IDispatch_AddRef(pDispatch);
+                        V_DISPATCH(pVarResult) = pDispatch;
+                    }
+                }
+		else 
+                {
+                    ERR("MsiGetActiveDatabase failed\n");
+                    return DISP_E_EXCEPTION;
                 }
-		else TRACE("MsiGetActiveDatabase failed\n");
-                V_DISPATCH(pVarResult) = pDispatch;
 	    }
 	    break;
 
@@ -802,7 +869,7 @@ HRESULT WINAPI SessionImpl_Invoke(
 		    V_I4(pVarResult) = iInstalled;
 		else 
 		{
-		    TRACE("MsiGetFeatureState returned %d\n", ret);
+		    ERR("MsiGetFeatureState returned %d\n", ret);
                     V_I4(pVarResult) = msiInstallStateUnknown;
 		}
 	    } 
@@ -817,7 +884,7 @@ HRESULT WINAPI SessionImpl_Invoke(
 		    V_I4(pVarResult) = iAction;
 		else 
 		{
-		    TRACE("MsiGetFeatureState returned %d\n", ret);
+		    ERR("MsiGetFeatureState returned %d\n", ret);
                     V_I4(pVarResult) = msiInstallStateUnknown;
 		}
 	    } else if (wFlags & DISPATCH_PROPERTYPUT) {
@@ -829,7 +896,10 @@ HRESULT WINAPI SessionImpl_Invoke(
                     return hr;
                 }
 		if ((ret = MsiSetFeatureStateW(This->msiHandle, V_BSTR(&varg0), V_I4(&varg1))) != ERROR_SUCCESS)
-                    TRACE("MsiSetFeatureState returned %d\n", ret);
+                {
+                    ERR("MsiSetFeatureState returned %d\n", ret);
+                    return DISP_E_EXCEPTION;
+                }
 	    }
 	    break;
 
-- 
1.4.1



More information about the wine-devel mailing list