From 667ba16dbcfe7af610df0fddcc581522788b39dc Mon Sep 17 00:00:00 2001 From: Hans Leidekker Date: Fri, 10 Jun 2011 10:13:47 +0200 Subject: [PATCH] msi: Implement and test MsiSetFeatureAttributes. --- dlls/msi/install.c | 70 +++++++++++++++++++++++++++++++-- dlls/msi/msi.spec | 4 +- dlls/msi/tests/install.c | 83 ++++++++++++++++++++++++++++++++++++++++ include/msiquery.h | 4 ++ 4 files changed, 155 insertions(+), 6 deletions(-) diff --git a/dlls/msi/install.c b/dlls/msi/install.c index 62252817413..2be4c6c67d5 100644 --- a/dlls/msi/install.c +++ b/dlls/msi/install.c @@ -1027,6 +1027,70 @@ UINT WINAPI MsiSetFeatureStateW(MSIHANDLE hInstall, LPCWSTR szFeature, return rc; } +/*********************************************************************** +* MsiSetFeatureAttributesA (MSI.@) +*/ +UINT WINAPI MsiSetFeatureAttributesA( MSIHANDLE handle, LPCSTR feature, DWORD attrs ) +{ + UINT r; + WCHAR *featureW = NULL; + + TRACE("%u, %s, 0x%08x\n", handle, debugstr_a(feature), attrs); + + if (feature && !(featureW = strdupAtoW( feature ))) return ERROR_OUTOFMEMORY; + + r = MsiSetFeatureAttributesW( handle, featureW, attrs ); + msi_free( featureW ); + return r; +} + +static DWORD unmap_feature_attributes( DWORD attrs ) +{ + DWORD ret = 0; + + if (attrs & INSTALLFEATUREATTRIBUTE_FAVORLOCAL) ret = msidbFeatureAttributesFavorLocal; + if (attrs & INSTALLFEATUREATTRIBUTE_FAVORSOURCE) ret |= msidbFeatureAttributesFavorSource; + if (attrs & INSTALLFEATUREATTRIBUTE_FOLLOWPARENT) ret |= msidbFeatureAttributesFollowParent; + if (attrs & INSTALLFEATUREATTRIBUTE_FAVORADVERTISE) ret |= msidbFeatureAttributesFavorAdvertise; + if (attrs & INSTALLFEATUREATTRIBUTE_DISALLOWADVERTISE) ret |= msidbFeatureAttributesDisallowAdvertise; + if (attrs & INSTALLFEATUREATTRIBUTE_NOUNSUPPORTEDADVERTISE) ret |= msidbFeatureAttributesNoUnsupportedAdvertise; + return ret; +} + +/*********************************************************************** +* MsiSetFeatureAttributesW (MSI.@) +*/ +UINT WINAPI MsiSetFeatureAttributesW( MSIHANDLE handle, LPCWSTR name, DWORD attrs ) +{ + MSIPACKAGE *package; + MSIFEATURE *feature; + WCHAR *costing; + + TRACE("%u, %s, 0x%08x\n", handle, debugstr_w(name), attrs); + + if (!name || !name[0]) return ERROR_UNKNOWN_FEATURE; + + if (!(package = msihandle2msiinfo( handle, MSIHANDLETYPE_PACKAGE ))) + return ERROR_INVALID_HANDLE; + + costing = msi_dup_property( package->db, szCostingComplete ); + if (!costing || !strcmpW( costing, szOne )) + { + msi_free( costing ); + msiobj_release( &package->hdr ); + return ERROR_FUNCTION_FAILED; + } + msi_free( costing ); + if (!(feature = msi_get_loaded_feature( package, name ))) + { + msiobj_release( &package->hdr ); + return ERROR_UNKNOWN_FEATURE; + } + feature->Attributes = unmap_feature_attributes( attrs ); + msiobj_release( &package->hdr ); + return ERROR_SUCCESS; +} + /*********************************************************************** * MsiGetFeatureStateA (MSI.@) */ @@ -1036,12 +1100,10 @@ UINT WINAPI MsiGetFeatureStateA(MSIHANDLE hInstall, LPCSTR szFeature, LPWSTR szwFeature = NULL; UINT rc; - szwFeature = strdupAtoW(szFeature); - - rc = MsiGetFeatureStateW(hInstall,szwFeature,piInstalled, piAction); + if (szFeature && !(szwFeature = strdupAtoW(szFeature))) return ERROR_OUTOFMEMORY; + rc = MsiGetFeatureStateW(hInstall, szwFeature, piInstalled, piAction); msi_free( szwFeature); - return rc; } diff --git a/dlls/msi/msi.spec b/dlls/msi/msi.spec index 10088135641..5f4a51f3900 100644 --- a/dlls/msi/msi.spec +++ b/dlls/msi/msi.spec @@ -199,8 +199,8 @@ 203 stdcall MsiProvideQualifiedComponentExW(wstr wstr long wstr long long ptr ptr) 204 stdcall MsiEnumRelatedProductsA(str long long ptr) 205 stdcall MsiEnumRelatedProductsW(wstr long long ptr) -206 stub MsiSetFeatureAttributesA -207 stub MsiSetFeatureAttributesW +206 stdcall MsiSetFeatureAttributesA(long str long) +207 stdcall MsiSetFeatureAttributesW(long wstr long) 208 stdcall MsiSourceListClearAllA(str str long) 209 stdcall MsiSourceListClearAllW(wstr wstr long) 210 stdcall MsiSourceListAddSourceA(str str long str) diff --git a/dlls/msi/tests/install.c b/dlls/msi/tests/install.c index 267b2bd9537..f93cc487c97 100644 --- a/dlls/msi/tests/install.c +++ b/dlls/msi/tests/install.c @@ -6469,6 +6469,88 @@ static void test_MsiGetFeatureInfo(void) DeleteFileA( msifile ); } +static void test_MsiSetFeatureAttributes(void) +{ + UINT r; + DWORD attrs; + char path[MAX_PATH]; + MSIHANDLE package; + + if (is_process_limited()) + { + skip("process is limited\n"); + return; + } + create_database( msifile, tables, sizeof(tables) / sizeof(tables[0]) ); + + strcpy( path, CURR_DIR ); + strcat( path, "\\" ); + strcat( path, msifile ); + + r = MsiOpenPackage( path, &package ); + if (r == ERROR_INSTALL_PACKAGE_REJECTED) + { + skip("Not enough rights to perform tests\n"); + DeleteFileA( msifile ); + return; + } + ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r); + + r = MsiSetFeatureAttributesA( package, "One", INSTALLFEATUREATTRIBUTE_FAVORLOCAL ); + ok(r == ERROR_FUNCTION_FAILED, "Expected ERROR_FUNCTION_FAILED, got %u\n", r); + + r = MsiDoAction( package, "CostInitialize" ); + ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r); + + r = MsiSetFeatureAttributesA( 0, "One", INSTALLFEATUREATTRIBUTE_FAVORLOCAL ); + ok(r == ERROR_INVALID_HANDLE, "expected ERROR_INVALID_HANDLE, got %u\n", r); + + r = MsiSetFeatureAttributesA( package, "", INSTALLFEATUREATTRIBUTE_FAVORLOCAL ); + ok(r == ERROR_UNKNOWN_FEATURE, "expected ERROR_UNKNOWN_FEATURE, got %u\n", r); + + r = MsiSetFeatureAttributesA( package, NULL, INSTALLFEATUREATTRIBUTE_FAVORLOCAL ); + ok(r == ERROR_UNKNOWN_FEATURE, "expected ERROR_UNKNOWN_FEATURE, got %u\n", r); + + r = MsiSetFeatureAttributesA( package, "One", 0 ); + ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r); + + attrs = 0xdeadbeef; + r = MsiGetFeatureInfoA( package, "One", &attrs, NULL, NULL, NULL, NULL ); + ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r); + ok(attrs == INSTALLFEATUREATTRIBUTE_FAVORLOCAL, + "expected INSTALLFEATUREATTRIBUTE_FAVORLOCAL, got 0x%08x\n", attrs); + + r = MsiSetFeatureAttributesA( package, "One", INSTALLFEATUREATTRIBUTE_FAVORLOCAL ); + ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r); + + attrs = 0; + r = MsiGetFeatureInfoA( package, "One", &attrs, NULL, NULL, NULL, NULL ); + ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r); + ok(attrs == INSTALLFEATUREATTRIBUTE_FAVORLOCAL, + "expected INSTALLFEATUREATTRIBUTE_FAVORLOCAL, got 0x%08x\n", attrs); + + r = MsiDoAction( package, "FileCost" ); + ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r); + + r = MsiSetFeatureAttributesA( package, "One", INSTALLFEATUREATTRIBUTE_FAVORSOURCE ); + ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r); + + attrs = 0; + r = MsiGetFeatureInfoA( package, "One", &attrs, NULL, NULL, NULL, NULL ); + ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r); + ok(attrs == INSTALLFEATUREATTRIBUTE_FAVORSOURCE, + "expected INSTALLFEATUREATTRIBUTE_FAVORSOURCE, got 0x%08x\n", attrs); + + r = MsiDoAction( package, "CostFinalize" ); + ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r); + + r = MsiSetFeatureAttributesA( package, "One", INSTALLFEATUREATTRIBUTE_FAVORLOCAL ); + ok(r == ERROR_FUNCTION_FAILED, "expected ERROR_FUNCTION_FAILED, got %u\n", r); + + MsiCloseHandle( package ); + DeleteFileA( msifile ); +} + START_TEST(install) { DWORD len; @@ -6559,6 +6641,7 @@ START_TEST(install) test_command_line_parsing(); test_upgrade_code(); test_MsiGetFeatureInfo(); + test_MsiSetFeatureAttributes(); DeleteFileA(log_file); diff --git a/include/msiquery.h b/include/msiquery.h index 2ea8320c04d..fbd46515cf3 100644 --- a/include/msiquery.h +++ b/include/msiquery.h @@ -248,6 +248,10 @@ MSIHANDLE WINAPI MsiGetActiveDatabase(MSIHANDLE); UINT WINAPI MsiViewGetColumnInfo(MSIHANDLE, MSICOLINFO, MSIHANDLE*); INT WINAPI MsiProcessMessage(MSIHANDLE, INSTALLMESSAGE, MSIHANDLE); +UINT WINAPI MsiSetFeatureAttributesA(MSIHANDLE, LPCSTR, DWORD); +UINT WINAPI MsiSetFeatureAttributesW(MSIHANDLE, LPCWSTR, DWORD); +#define MsiSetFeatureAttributes WINELIB_NAME_AW(MsiSetFeatureAttributes) + UINT WINAPI MsiSetFeatureStateA(MSIHANDLE, LPCSTR, INSTALLSTATE); UINT WINAPI MsiSetFeatureStateW(MSIHANDLE, LPCWSTR, INSTALLSTATE); #define MsiSetFeatureState WINELIB_NAME_AW(MsiSetFeatureState)