Rob Shearman : msi: Improve stub for MsiGetFeatureCost{A, W} and hook the stub into the VolumeCostList dialog control.

Alexandre Julliard julliard at winehq.org
Mon Nov 9 15:14:15 CST 2009


Module: wine
Branch: master
Commit: b960b967c997915cb4f3a415b8b2dfbd09c4cdc5
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=b960b967c997915cb4f3a415b8b2dfbd09c4cdc5

Author: Rob Shearman <robertshearman at gmail.com>
Date:   Sun Nov  8 13:34:43 2009 +0100

msi: Improve stub for MsiGetFeatureCost{A, W} and hook the stub into the VolumeCostList dialog control.

---

 dlls/msi/dialog.c      |   41 +++++++++++++++++++++++++++
 dlls/msi/install.c     |   73 ++++++++++++++++++++++++++++++++++++++++++++---
 dlls/msi/msipriv.h     |    1 +
 dlls/msi/msiserver.idl |    1 +
 dlls/msi/package.c     |    9 ++++++
 5 files changed, 120 insertions(+), 5 deletions(-)

diff --git a/dlls/msi/dialog.c b/dlls/msi/dialog.c
index 59ef8c3..a22091f 100644
--- a/dlls/msi/dialog.c
+++ b/dlls/msi/dialog.c
@@ -2614,15 +2614,44 @@ static void msi_dialog_vcl_add_columns( msi_dialog *dialog, msi_control *control
     }
 }
 
+static LONGLONG msi_vcl_get_cost( msi_dialog *dialog )
+{
+    MSIFEATURE *feature;
+    INT each_cost;
+    LONGLONG total_cost = 0;
+
+    LIST_FOR_EACH_ENTRY( feature, &dialog->package->features, MSIFEATURE, entry )
+    {
+        if (ERROR_SUCCESS == (MSI_GetFeatureCost(dialog->package, feature,
+                MSICOSTTREE_SELFONLY, INSTALLSTATE_LOCAL, &each_cost)))
+        {
+            /* each_cost is in 512-byte units */
+            total_cost += each_cost * 512;
+        }
+        if (ERROR_SUCCESS == (MSI_GetFeatureCost(dialog->package, feature,
+                MSICOSTTREE_SELFONLY, INSTALLSTATE_ABSENT, &each_cost)))
+        {
+            /* each_cost is in 512-byte units */
+            total_cost -= each_cost * 512;
+        }
+    }
+    return total_cost;
+}
+
 static void msi_dialog_vcl_add_drives( msi_dialog *dialog, msi_control *control )
 {
     ULARGE_INTEGER total, free;
+    LONGLONG difference, cost;
     WCHAR size_text[MAX_PATH];
+    WCHAR cost_text[MAX_PATH];
     LPWSTR drives, ptr;
     LVITEMW lvitem;
     DWORD size;
     int i = 0;
 
+    cost = msi_vcl_get_cost(dialog);
+    StrFormatByteSizeW(cost, cost_text, MAX_PATH);
+
     size = GetLogicalDriveStringsW( 0, NULL );
     if ( !size ) return;
 
@@ -2642,6 +2671,7 @@ static void msi_dialog_vcl_add_drives( msi_dialog *dialog, msi_control *control
         SendMessageW( control->hwnd, LVM_INSERTITEMW, 0, (LPARAM)&lvitem );
 
         GetDiskFreeSpaceExW(ptr, &free, &total, NULL);
+        difference = free.QuadPart - cost;
 
         StrFormatByteSizeW(total.QuadPart, size_text, MAX_PATH);
         lvitem.iSubItem = 1;
@@ -2655,6 +2685,17 @@ static void msi_dialog_vcl_add_drives( msi_dialog *dialog, msi_control *control
         lvitem.cchTextMax = lstrlenW(size_text) + 1;
         SendMessageW( control->hwnd, LVM_SETITEMW, 0, (LPARAM)&lvitem );
 
+        lvitem.iSubItem = 3;
+        lvitem.pszText = cost_text;
+        lvitem.cchTextMax = lstrlenW(cost_text) + 1;
+        SendMessageW( control->hwnd, LVM_SETITEMW, 0, (LPARAM)&lvitem );
+
+        StrFormatByteSizeW(difference, size_text, MAX_PATH);
+        lvitem.iSubItem = 4;
+        lvitem.pszText = size_text;
+        lvitem.cchTextMax = lstrlenW(size_text) + 1;
+        SendMessageW( control->hwnd, LVM_SETITEMW, 0, (LPARAM)&lvitem );
+
         ptr += lstrlenW(ptr) + 1;
         i++;
     }
diff --git a/dlls/msi/install.c b/dlls/msi/install.c
index 606caba..1a535eb 100644
--- a/dlls/msi/install.c
+++ b/dlls/msi/install.c
@@ -934,8 +934,24 @@ UINT WINAPI MsiGetFeatureStateW(MSIHANDLE hInstall, LPCWSTR szFeature,
 UINT WINAPI MsiGetFeatureCostA(MSIHANDLE hInstall, LPCSTR szFeature,
                   MSICOSTTREE iCostTree, INSTALLSTATE iState, LPINT piCost)
 {
-    FIXME("(%d %s %i %i %p): stub\n", hInstall, debugstr_a(szFeature),
-          iCostTree, iState, piCost);
+    LPWSTR szwFeature = NULL;
+    UINT rc;
+
+    szwFeature = strdupAtoW(szFeature);
+
+    rc = MsiGetFeatureCostW(hInstall, szwFeature, iCostTree, iState, piCost);
+
+    msi_free(szwFeature);
+
+    return rc;
+}
+
+UINT MSI_GetFeatureCost(MSIPACKAGE *package, MSIFEATURE *feature,
+                        MSICOSTTREE iCostTree, INSTALLSTATE iState,
+                        LPINT piCost)
+{
+    FIXME("(%s %i %i %p): not implemented yet\n",
+        debugstr_w(feature->Feature), iCostTree, iState, piCost);
     if (piCost) *piCost = 0;
     return ERROR_SUCCESS;
 }
@@ -946,10 +962,57 @@ UINT WINAPI MsiGetFeatureCostA(MSIHANDLE hInstall, LPCSTR szFeature,
 UINT WINAPI MsiGetFeatureCostW(MSIHANDLE hInstall, LPCWSTR szFeature,
                   MSICOSTTREE iCostTree, INSTALLSTATE iState, LPINT piCost)
 {
-    FIXME("(%d %s %i %i %p): stub\n", hInstall, debugstr_w(szFeature),
+    MSIPACKAGE *package;
+    MSIFEATURE *feature;
+    UINT ret;
+
+    TRACE("(%d %s %i %i %p)\n", hInstall, debugstr_w(szFeature),
           iCostTree, iState, piCost);
-    if (piCost) *piCost = 0;
-    return ERROR_SUCCESS;
+
+    package = msihandle2msiinfo(hInstall, MSIHANDLETYPE_PACKAGE);
+    if (!package)
+    {
+        HRESULT hr;
+        BSTR feature;
+        IWineMsiRemotePackage *remote_package;
+
+        remote_package = (IWineMsiRemotePackage *)msi_get_remote(hInstall);
+        if (!remote_package)
+            return ERROR_INVALID_HANDLE;
+
+        feature = SysAllocString(szFeature);
+        if (!feature)
+        {
+            IWineMsiRemotePackage_Release(remote_package);
+            return ERROR_OUTOFMEMORY;
+        }
+
+        hr = IWineMsiRemotePackage_GetFeatureCost(remote_package, feature,
+                                                  iCostTree, iState, piCost);
+
+        SysFreeString(feature);
+        IWineMsiRemotePackage_Release(remote_package);
+
+        if (FAILED(hr))
+        {
+            if (HRESULT_FACILITY(hr) == FACILITY_WIN32)
+                return HRESULT_CODE(hr);
+
+            return ERROR_FUNCTION_FAILED;
+        }
+
+        return ERROR_SUCCESS;
+    }
+
+    feature = get_loaded_feature(package, szFeature);
+
+    if (feature)
+        ret = MSI_GetFeatureCost(package, feature, iCostTree, iState, piCost);
+    else
+        ret = ERROR_UNKNOWN_FEATURE;
+
+    msiobj_release( &package->hdr );
+    return ret;
 }
 
 /***********************************************************************
diff --git a/dlls/msi/msipriv.h b/dlls/msi/msipriv.h
index 38103d8..5b23f55 100644
--- a/dlls/msi/msipriv.h
+++ b/dlls/msi/msipriv.h
@@ -759,6 +759,7 @@ extern LPCWSTR msi_download_file( LPCWSTR szUrl, LPWSTR filename );
 extern UINT msi_package_add_info(MSIPACKAGE *, DWORD, DWORD, LPCWSTR, LPWSTR);
 extern UINT msi_package_add_media_disk(MSIPACKAGE *, DWORD, DWORD, DWORD, LPWSTR, LPWSTR);
 extern UINT msi_clone_properties(MSIPACKAGE *);
+extern UINT MSI_GetFeatureCost(MSIPACKAGE *, MSIFEATURE *, MSICOSTTREE, INSTALLSTATE, LPINT);
 
 /* for deformating */
 extern UINT MSI_FormatRecordW( MSIPACKAGE *, MSIRECORD *, LPWSTR, LPDWORD );
diff --git a/dlls/msi/msiserver.idl b/dlls/msi/msiserver.idl
index 2189fc4..753cbb0 100644
--- a/dlls/msi/msiserver.idl
+++ b/dlls/msi/msiserver.idl
@@ -71,6 +71,7 @@ interface IWineMsiRemotePackage : IUnknown
     HRESULT SetInstallLevel( [in] int level );
     HRESULT FormatRecord( [in] MSIHANDLE record, [out] BSTR *value );
     HRESULT EvaluateCondition( [in] BSTR condition );
+    HRESULT GetFeatureCost( [in] BSTR feature, [in] INT cost_tree, [in] INSTALLSTATE state, [out] INT *cost);
 }
 
 [
diff --git a/dlls/msi/package.c b/dlls/msi/package.c
index 7f13633..87f1092 100644
--- a/dlls/msi/package.c
+++ b/dlls/msi/package.c
@@ -1898,6 +1898,14 @@ static HRESULT WINAPI mrp_EvaluateCondition( IWineMsiRemotePackage *iface, BSTR
     return HRESULT_FROM_WIN32(r);
 }
 
+static HRESULT WINAPI mrp_GetFeatureCost( IWineMsiRemotePackage *iface, BSTR feature,
+                                          INT cost_tree, INSTALLSTATE state, INT *cost )
+{
+    msi_remote_package_impl* This = mrp_from_IWineMsiRemotePackage( iface );
+    UINT r = MsiGetFeatureCostW(This->package, feature, cost_tree, state, cost);
+    return HRESULT_FROM_WIN32(r);
+}
+
 static const IWineMsiRemotePackageVtbl msi_remote_package_vtbl =
 {
     mrp_QueryInterface,
@@ -1922,6 +1930,7 @@ static const IWineMsiRemotePackageVtbl msi_remote_package_vtbl =
     mrp_SetInstallLevel,
     mrp_FormatRecord,
     mrp_EvaluateCondition,
+    mrp_GetFeatureCost,
 };
 
 HRESULT create_msi_remote_package( IUnknown *pOuter, LPVOID *ppObj )




More information about the wine-cvs mailing list