Subject: msi: automation: Implement Installer::ProductInfo.

From: Misha Koshelev <[email-masked]>
Date: Wed, 16 May 2007 10:19:12 -0500

---
 dlls/msi/automation.c        |   36 +++++++++++++++++++-
 dlls/msi/msiserver.idl       |    4 ++
 dlls/msi/msiserver_dispids.h |    1 +
 dlls/msi/tests/automation.c  |   74 ++++++++++++++++++++----------------------
 4 files changed, 74 insertions(+), 41 deletions(-)

diff --git a/dlls/msi/automation.c b/dlls/msi/automation.c
index 762f20c..897d2d3 100644
--- a/dlls/msi/automation.c
+++ b/dlls/msi/automation.c
@@ -1167,6 +1167,8 @@ static HRESULT WINAPI InstallerImpl_Invoke(
     UINT ret;
     VARIANTARG varg0, varg1, varg2;
     HRESULT hr;
+    LPWSTR szString = NULL;
+    DWORD dwSize = 0;
 
     VariantInit(&varg0);
     VariantInit(&varg1);
@@ -1256,8 +1258,7 @@ static HRESULT WINAPI InstallerImpl_Invoke(
         case DISPID_INSTALLER_REGISTRYVALUE:
             if (wFlags & DISPATCH_METHOD) {
                 HKEY hkey;
-                LPWSTR szString = NULL;
-                DWORD dwSize = 0, dwType;
+                DWORD dwType;
                 UINT posValue = 2;    /* Save valuePos so we can save puArgErr if we are unable to do our type conversions */
 
                 hr = DispGetParam(pDispParams, 0, VT_I4, &varg0, puArgErr);
@@ -1353,6 +1354,37 @@ static HRESULT WINAPI InstallerImpl_Invoke(
             else return DISP_E_MEMBERNOTFOUND;
             break;
 
+        case DISPID_INSTALLER_PRODUCTINFO:
+            if (wFlags & DISPATCH_PROPERTYGET) {
+                hr = DispGetParam(pDispParams, 0, VT_BSTR, &varg0, puArgErr);
+                if (FAILED(hr)) return hr;
+                hr = DispGetParam(pDispParams, 1, VT_BSTR, &varg1, puArgErr);
+                if (FAILED(hr)) 
+                {
+                    VariantClear(&varg0);
+                    return hr;
+                }
+                V_VT(pVarResult) = VT_BSTR;
+                V_BSTR(pVarResult) = NULL;
+                if ((ret = MsiGetProductInfoW(V_BSTR(&varg0), V_BSTR(&varg1), NULL, &dwSize)) == ERROR_SUCCESS)
+                {
+                    if (!(szString = msi_alloc((++dwSize)*sizeof(WCHAR))))
+                        ERR("Out of memory\n");
+                    else if ((ret = MsiGetProductInfoW(V_BSTR(&varg0), V_BSTR(&varg1), szString, &dwSize)) == ERROR_SUCCESS)
+                        V_BSTR(pVarResult) = SysAllocString(szString);
+                    msi_free(szString);
+                }
+                if (ret != ERROR_SUCCESS)
+                { 
+                    ERR("MsiGetProductInfo returned %d\n", ret);
+                    VariantClear(&varg1);
+                    VariantClear(&varg0);
+                    return DISP_E_EXCEPTION;
+                } 
+            }
+            else return DISP_E_MEMBERNOTFOUND;
+            break;            
+ 
         case DISPID_INSTALLER_PRODUCTS:
             if (wFlags & DISPATCH_PROPERTYGET)
             {
diff --git a/dlls/msi/msiserver.idl b/dlls/msi/msiserver.idl
index 5721319..33b6bf8 100644
--- a/dlls/msi/msiserver.idl
+++ b/dlls/msi/msiserver.idl
@@ -77,6 +77,10 @@ library WindowsInstaller
         [id(DISPID_INSTALLER_PRODUCTSTATE), propget]
             MsiInstallState ProductState(
                 [in] BSTR Product);
+        [id(DISPID_INSTALLER_PRODUCTINFO), propget]
+            BSTR ProductInfo(
+                [in] BSTR Product,
+                [in] BSTR Attribute);
         [id(DISPID_INSTALLER_PRODUCTS), propget]
             StringList *Products();
         [id(DISPID_INSTALLER_RELATEDPRODUCTS), propget]
diff --git a/dlls/msi/msiserver_dispids.h b/dlls/msi/msiserver_dispids.h
index 92c3429..065b874 100644
--- a/dlls/msi/msiserver_dispids.h
+++ b/dlls/msi/msiserver_dispids.h
@@ -21,6 +21,7 @@
 #define DISPID_INSTALLER_INSTALLPRODUCT 8
 #define DISPID_INSTALLER_REGISTRYVALUE 11
 #define DISPID_INSTALLER_PRODUCTSTATE 17
+#define DISPID_INSTALLER_PRODUCTINFO 18
 #define DISPID_INSTALLER_PRODUCTS 35
 #define DISPID_INSTALLER_RELATEDPRODUCTS 40
 
diff --git a/dlls/msi/tests/automation.c b/dlls/msi/tests/automation.c
index c9ff1f8..1c6a2bd 100644
--- a/dlls/msi/tests/automation.c
+++ b/dlls/msi/tests/automation.c
@@ -443,8 +443,8 @@ static void test_dispid(void)
     ok( get_dispid( pInstaller, "FileVersion" ) == 16, "dispid wrong\n");
     }
     ok( get_dispid( pInstaller, "ProductState" ) == 17, "dispid wrong\n");
-    todo_wine {
     ok( get_dispid( pInstaller, "ProductInfo" ) == 18, "dispid wrong\n");
+    todo_wine {
     ok( get_dispid( pInstaller, "ConfigureProduct" ) == 19, "dispid wrong\n");
     ok( get_dispid( pInstaller, "ReinstallProduct" ) == 20 , "dispid wrong\n");
     ok( get_dispid( pInstaller, "CollectUserInfo" ) == 21, "dispid wrong\n");
@@ -1686,32 +1686,30 @@ static void test_Installer_InstallProduct(LPCWSTR szPath)
     ok(iValue == INSTALLSTATE_DEFAULT, "Installer_ProductState returned %d, expected %d\n", iValue, INSTALLSTATE_DEFAULT);
 
     /* Installer::ProductInfo for our product code */
-    todo_wine
-    {
-        /* NULL attribute */
-        memset(szString, 0, sizeof(szString));
-        hr = Installer_ProductInfo(szProductCode, NULL, szString);
-        ok(hr == DISP_E_EXCEPTION, "Installer_ProductInfo failed, hresult 0x%08x\n", hr);
-        ok_exception(hr, szProductInfoException);
 
-        /* Non-existent attribute */
-        memset(szString, 0, sizeof(szString));
-        hr = Installer_ProductInfo(szProductCode, szMsifile, szString);
-        ok(hr == DISP_E_EXCEPTION, "Installer_ProductInfo failed, hresult 0x%08x\n", hr);
-        ok_exception(hr, szProductInfoException);
-
-        /* Package name */
-        memset(szString, 0, sizeof(szString));
-        hr = Installer_ProductInfo(szProductCode, INSTALLPROPERTY_PACKAGENAMEW, szString);
-        ok(SUCCEEDED(hr), "Installer_ProductInfo failed, hresult 0x%08x\n", hr);
-        ok_w2("StringList_Item returned %s but expected %s\n", szString, szMsifile);
-
-        /* Product name */
-        memset(szString, 0, sizeof(szString));
-        hr = Installer_ProductInfo(szProductCode, INSTALLPROPERTY_PRODUCTNAMEW, szString);
-        ok(SUCCEEDED(hr), "Installer_ProductInfo failed, hresult 0x%08x\n", hr);
-        ok_w2("StringList_Item returned %s but expected %s\n", szString, szMSITEST);
-    }
+    /* NULL attribute */
+    memset(szString, 0, sizeof(szString));
+    hr = Installer_ProductInfo(szProductCode, NULL, szString);
+    ok(hr == DISP_E_EXCEPTION, "Installer_ProductInfo failed, hresult 0x%08x\n", hr);
+    ok_exception(hr, szProductInfoException);
+    
+    /* Non-existent attribute */
+    memset(szString, 0, sizeof(szString));
+    hr = Installer_ProductInfo(szProductCode, szMsifile, szString);
+    ok(hr == DISP_E_EXCEPTION, "Installer_ProductInfo failed, hresult 0x%08x\n", hr);
+    ok_exception(hr, szProductInfoException);
+    
+    /* Package name */
+    memset(szString, 0, sizeof(szString));
+    hr = Installer_ProductInfo(szProductCode, INSTALLPROPERTY_PACKAGENAMEW, szString);
+    todo_wine ok(SUCCEEDED(hr), "Installer_ProductInfo failed, hresult 0x%08x\n", hr);
+    todo_wine ok_w2("StringList_Item returned %s but expected %s\n", szString, szMsifile);
+    
+    /* Product name */
+    memset(szString, 0, sizeof(szString));
+    hr = Installer_ProductInfo(szProductCode, INSTALLPROPERTY_PRODUCTNAMEW, szString);
+    ok(SUCCEEDED(hr), "Installer_ProductInfo failed, hresult 0x%08x\n", hr);
+    ok_w2("StringList_Item returned %s but expected %s\n", szString, szMSITEST);
 
     /* Installer::RelatedProducts for our upgrade code */
     hr = Installer_RelatedProducts(szUpgradeCode, &pStringList);
@@ -1933,20 +1931,18 @@ static void test_Installer(void)
     ok(iValue == INSTALLSTATE_UNKNOWN, "Installer_ProductState returned %d, expected %d\n", iValue, INSTALLSTATE_UNKNOWN);
 
     /* Installer::ProductInfo for our product code, which should not be installed */
-    todo_wine
-    {
-        /* Package name */
-        memset(szPath, 0, sizeof(szPath));
-        hr = Installer_ProductInfo(szProductCode, INSTALLPROPERTY_PACKAGENAMEW, szPath);
-        ok(hr == DISP_E_EXCEPTION, "Installer_ProductInfo failed, hresult 0x%08x\n", hr);
-        ok_exception(hr, szProductInfoException);
 
-        /* NULL attribute and NULL product code */
-        memset(szPath, 0, sizeof(szPath));
-        hr = Installer_ProductInfo(NULL, NULL, szPath);
-        ok(hr == DISP_E_EXCEPTION, "Installer_ProductInfo failed, hresult 0x%08x\n", hr);
-        ok_exception(hr, szProductInfoException);
-    }
+    /* Package name */
+    memset(szPath, 0, sizeof(szPath));
+    hr = Installer_ProductInfo(szProductCode, INSTALLPROPERTY_PACKAGENAMEW, szPath);
+    ok(hr == DISP_E_EXCEPTION, "Installer_ProductInfo failed, hresult 0x%08x\n", hr);
+    ok_exception(hr, szProductInfoException);
+    
+    /* NULL attribute and NULL product code */
+    memset(szPath, 0, sizeof(szPath));
+    hr = Installer_ProductInfo(NULL, NULL, szPath);
+    ok(hr == DISP_E_EXCEPTION, "Installer_ProductInfo failed, hresult 0x%08x\n", hr);
+    ok_exception(hr, szProductInfoException);
 
     /* Installer::RelatedProducts for our upgrade code, should not find anything */
     hr = Installer_RelatedProducts(szUpgradeCode, &pStringList);
-- 
1.4.4.2