msi: Implement and test MsiEnumComponentCostsA/W.

This commit is contained in:
Hans Leidekker 2011-04-01 14:54:12 +02:00 committed by Alexandre Julliard
parent f2231f8419
commit 68d6158875
5 changed files with 316 additions and 16 deletions

View File

@ -2007,10 +2007,7 @@ static UINT load_all_folders( MSIPACKAGE *package )
*/
static UINT ACTION_CostInitialize(MSIPACKAGE *package)
{
static const WCHAR szCosting[] =
{'C','o','s','t','i','n','g','C','o','m','p','l','e','t','e',0 };
msi_set_property( package->db, szCosting, szZero );
msi_set_property( package->db, szCostingComplete, szZero );
msi_set_property( package->db, cszRootDrive, c_colon );
load_all_folders( package );
@ -2639,8 +2636,6 @@ static UINT ACTION_CostFinalize(MSIPACKAGE *package)
static const WCHAR ConditionQuery[] =
{'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
'`','C','o','n','d','i','t','i','o','n','`',0};
static const WCHAR szCosting[] =
{'C','o','s','t','i','n','g','C','o','m','p','l','e','t','e',0 };
static const WCHAR szlevel[] =
{'I','N','S','T','A','L','L','L','E','V','E','L',0};
static const WCHAR szOutOfDiskSpace[] =
@ -2691,7 +2686,7 @@ static UINT ACTION_CostFinalize(MSIPACKAGE *package)
TRACE("Calculating file cost\n");
calculate_file_cost( package );
msi_set_property( package->db, szCosting, szOne );
msi_set_property( package->db, szCostingComplete, szOne );
/* set default run level if not set */
level = msi_dup_property( package->db, szlevel );
if (!level)

View File

@ -1794,16 +1794,101 @@ UINT WINAPI MsiEnableLogW(DWORD dwLogMode, LPCWSTR szLogFile, DWORD attributes)
return ERROR_SUCCESS;
}
UINT WINAPI MsiEnumComponentCostsW(MSIHANDLE hInstall, LPCWSTR szComponent,
DWORD dwIndex, INSTALLSTATE iState,
LPWSTR lpDriveBuf, DWORD *pcchDriveBuf,
int *piCost, int *pTempCost)
UINT WINAPI MsiEnumComponentCostsA( MSIHANDLE handle, LPCSTR component, DWORD index,
INSTALLSTATE state, LPSTR drive, DWORD *buflen,
int *cost, int *temp )
{
FIXME("(%d, %s, %d, %d, %p, %p, %p %p): stub!\n", hInstall,
debugstr_w(szComponent), dwIndex, iState, lpDriveBuf,
pcchDriveBuf, piCost, pTempCost);
UINT r;
DWORD len;
WCHAR *driveW, *componentW = NULL;
return ERROR_NO_MORE_ITEMS;
TRACE("%d, %s, %u, %d, %p, %p, %p %p\n", handle, debugstr_a(component), index,
state, drive, buflen, cost, temp);
if (!drive || !buflen) return ERROR_INVALID_PARAMETER;
if (component && !(componentW = strdupAtoW( component ))) return ERROR_OUTOFMEMORY;
len = *buflen;
if (!(driveW = msi_alloc( len * sizeof(WCHAR) )))
{
msi_free( componentW );
return ERROR_OUTOFMEMORY;
}
r = MsiEnumComponentCostsW( handle, componentW, index, state, driveW, buflen, cost, temp );
if (!r)
{
WideCharToMultiByte( CP_ACP, 0, driveW, -1, drive, len, NULL, NULL );
}
msi_free( componentW );
msi_free( driveW );
return r;
}
UINT WINAPI MsiEnumComponentCostsW( MSIHANDLE handle, LPCWSTR component, DWORD index,
INSTALLSTATE state, LPWSTR drive, DWORD *buflen,
int *cost, int *temp )
{
UINT r = ERROR_NO_MORE_ITEMS;
MSICOMPONENT *comp = NULL;
MSIPACKAGE *package;
MSIFILE *file;
STATSTG stat = {0};
WCHAR path[MAX_PATH];
TRACE("%d, %s, %u, %d, %p, %p, %p %p\n", handle, debugstr_w(component), index,
state, drive, buflen, cost, temp);
if (!drive || !buflen || !cost || !temp) return ERROR_INVALID_PARAMETER;
if (!(package = msihandle2msiinfo( handle, MSIHANDLETYPE_PACKAGE ))) return ERROR_INVALID_HANDLE;
if (!msi_get_property_int( package->db, szCostingComplete, 0 ))
{
msiobj_release( &package->hdr );
return ERROR_FUNCTION_NOT_CALLED;
}
if (component && component[0] && !(comp = get_loaded_component( package, component )))
{
msiobj_release( &package->hdr );
return ERROR_UNKNOWN_COMPONENT;
}
if (*buflen < 3)
{
*buflen = 2;
msiobj_release( &package->hdr );
return ERROR_MORE_DATA;
}
if (index)
{
msiobj_release( &package->hdr );
return ERROR_NO_MORE_ITEMS;
}
drive[0] = 0;
*cost = *temp = 0;
if (component && component[0])
{
*cost = max( 8, comp->Cost / 512 );
if (comp->assembly && !comp->assembly->application) *temp = comp->Cost;
if ((file = get_loaded_file( package, comp->KeyPath )))
{
drive[0] = file->TargetPath[0];
drive[1] = ':';
drive[2] = 0;
*buflen = 2;
r = ERROR_SUCCESS;
}
}
else if (IStorage_Stat( package->db->storage, &stat, STATFLAG_NONAME ) == S_OK)
{
*temp = max( 8, stat.cbSize.QuadPart / 512 );
GetWindowsDirectoryW( path, MAX_PATH );
drive[0] = path[0];
drive[1] = ':';
drive[2] = 0;
*buflen = 2;
r = ERROR_SUCCESS;
}
msiobj_release( &package->hdr );
return r;
}
UINT WINAPI MsiQueryComponentStateA(LPCSTR szProductCode,

View File

@ -213,7 +213,7 @@
217 stdcall MsiGetShortcutTargetW(wstr ptr ptr ptr)
218 stdcall MsiGetFileHashA(str long ptr)
219 stdcall MsiGetFileHashW(wstr long ptr)
220 stub MsiEnumComponentCostsA
220 stdcall MsiEnumComponentCostsA(long str long long ptr ptr ptr ptr)
221 stdcall MsiEnumComponentCostsW(long wstr long long ptr ptr ptr ptr)
222 stdcall MsiCreateAndVerifyInstallerDirectory(long)
223 stdcall MsiGetFileSignatureInformationA(str long ptr ptr ptr)

View File

@ -1108,6 +1108,7 @@ static const WCHAR szWow6432Node[] = {'W','o','w','6','4','3','2','N','o','d','e
static const WCHAR szStreams[] = {'_','S','t','r','e','a','m','s',0};
static const WCHAR szStorages[] = {'_','S','t','o','r','a','g','e','s',0};
static const WCHAR szMsiPublishAssemblies[] = {'M','s','i','P','u','b','l','i','s','h','A','s','s','e','m','b','l','i','e','s',0};
static const WCHAR szCostingComplete[] = {'C','o','s','t','i','n','g','C','o','m','p','l','e','t','e',0};
/* memory allocation macro functions */
static void *msi_alloc( size_t len ) __WINE_ALLOC_SIZE(1);

View File

@ -12907,6 +12907,224 @@ static void test_MsiApplyPatch(void)
ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r);
}
static void test_MsiEnumComponentCosts(void)
{
MSIHANDLE hdb, hpkg;
char package[12], drive[3];
DWORD len;
UINT r;
int cost, temp;
hdb = create_package_db();
ok( hdb, "failed to create database\n" );
r = create_property_table( hdb );
ok( r == ERROR_SUCCESS, "cannot create Property table %u\n", r );
r = add_property_entry( hdb, "'ProductCode', '{379B1C47-40C1-42FA-A9BB-BEBB6F1B0172}'" );
ok( r == ERROR_SUCCESS, "cannot add property entry %u\n", r );
r = add_property_entry( hdb, "'MSIFASTINSTALL', '1'" );
ok( r == ERROR_SUCCESS, "cannot add property entry %u\n", r );
r = add_directory_entry( hdb, "'TARGETDIR', '', 'SourceDir'" );
ok( r == ERROR_SUCCESS, "failed to add directory entry %u\n" , r );
r = create_media_table( hdb );
ok( r == ERROR_SUCCESS, "cannot create Media table %u\n", r );
r = add_media_entry( hdb, "'1', '2', 'cabinet', '', '', ''");
ok( r == ERROR_SUCCESS, "cannot add media entry %u\n", r );
r = create_file_table( hdb );
ok( r == ERROR_SUCCESS, "cannot create File table %u\n", r );
r = add_file_entry( hdb, "'one.txt', 'one', 'one.txt', 4096, '', '', 8192, 1" );
ok( r == ERROR_SUCCESS, "cannot add file %u\n", r );
r = add_file_entry( hdb, "'two.txt', 'two', 'two.txt', 8192, '', '', 8192, 2" );
ok( r == ERROR_SUCCESS, "cannot add file %u\n", r );
r = create_component_table( hdb );
ok( r == ERROR_SUCCESS, "cannot create Component table %u\n", r );
r = add_component_entry( hdb, "'one', '{B2F86B9D-8447-4BC5-8883-750C45AA31CA}', 'TARGETDIR', 0, '', 'one.txt'" );
ok( r == ERROR_SUCCESS, "cannot add component %u\n", r );
r = add_component_entry( hdb, "'two', '{62A09F6E-0B74-4829-BDB7-CAB66F42CCE8}', 'TARGETDIR', 0, '', 'two.txt'" );
ok( r == ERROR_SUCCESS, "cannot add component %u\n", r );
r = create_feature_table( hdb );
ok( r == ERROR_SUCCESS, "cannot create Feature table %u\n", r );
r = add_feature_entry( hdb, "'one', '', '', '', 0, 1, '', 0" );
ok( r == ERROR_SUCCESS, "cannot add feature %u\n", r );
r = add_feature_entry( hdb, "'two', '', '', '', 0, 1, '', 0" );
ok( r == ERROR_SUCCESS, "cannot add feature %u\n", r );
r = create_feature_components_table( hdb );
ok( r == ERROR_SUCCESS, "cannot create FeatureComponents table %u\n", r );
r = add_feature_components_entry( hdb, "'one', 'one'" );
ok( r == ERROR_SUCCESS, "cannot add feature/component pair %u\n", r );
r = add_feature_components_entry( hdb, "'two', 'two'" );
ok( r == ERROR_SUCCESS, "cannot add feature/component pair %u\n", r );
r = create_install_execute_sequence_table( hdb );
ok( r == ERROR_SUCCESS, "cannot create InstallExecuteSequence table %u\n", r );
r = add_install_execute_sequence_entry( hdb, "'CostInitialize', '', '800'" );
ok( r == ERROR_SUCCESS, "cannot add install execute sequence entry %u\n", r );
r = add_install_execute_sequence_entry( hdb, "'FileCost', '', '900'" );
ok( r == ERROR_SUCCESS, "cannot add install execute sequence entry %u\n", r );
r = add_install_execute_sequence_entry( hdb, "'CostFinalize', '', '1000'" );
ok( r == ERROR_SUCCESS, "cannot add install execute sequence entry %u\n", r );
r = add_install_execute_sequence_entry( hdb, "'InstallValidate', '', '1100'" );
ok( r == ERROR_SUCCESS, "cannot add install execute sequence entry %u\n", r );
MsiDatabaseCommit( hdb );
sprintf( package, "#%u", hdb );
r = MsiOpenPackageA( package, &hpkg );
if (r == ERROR_INSTALL_PACKAGE_REJECTED)
{
skip("Not enough rights to perform tests\n");
goto error;
}
ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r );
r = MsiEnumComponentCostsA( 0, NULL, 0, INSTALLSTATE_UNKNOWN, NULL, NULL, NULL, NULL );
ok( r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r );
r = MsiEnumComponentCostsA( hpkg, NULL, 0, INSTALLSTATE_UNKNOWN, NULL, NULL, NULL, NULL );
ok( r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r );
r = MsiEnumComponentCostsA( hpkg, NULL, 0, INSTALLSTATE_UNKNOWN, NULL, NULL, NULL, NULL );
ok( r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r );
r = MsiEnumComponentCostsA( hpkg, "", 0, INSTALLSTATE_UNKNOWN, NULL, NULL, NULL, NULL );
ok( r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r );
r = MsiEnumComponentCostsA( hpkg, "one", 0, INSTALLSTATE_UNKNOWN, NULL, NULL, NULL, NULL );
ok( r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r );
r = MsiEnumComponentCostsA( hpkg, "one", 0, INSTALLSTATE_LOCAL, NULL, NULL, NULL, NULL );
ok( r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r );
r = MsiEnumComponentCostsA( hpkg, "one", 0, INSTALLSTATE_LOCAL, drive, NULL, NULL, NULL );
ok( r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r );
len = sizeof(drive);
r = MsiEnumComponentCostsA( hpkg, "one", 0, INSTALLSTATE_LOCAL, drive, &len, NULL, NULL );
ok( r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r );
len = sizeof(drive);
r = MsiEnumComponentCostsA( hpkg, "one", 0, INSTALLSTATE_LOCAL, drive, &len, &cost, NULL );
ok( r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r );
len = sizeof(drive);
r = MsiEnumComponentCostsA( hpkg, "one", 0, INSTALLSTATE_LOCAL, drive, &len, &cost, &temp );
todo_wine ok( r == ERROR_INVALID_HANDLE_STATE, "Expected ERROR_INVALID_HANDLE_STATE, got %u\n", r );
len = sizeof(drive);
r = MsiEnumComponentCostsA( hpkg, "one", 0, INSTALLSTATE_LOCAL, NULL, &len, &cost, &temp );
ok( r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r );
MsiSetInternalUI( INSTALLUILEVEL_NONE, NULL );
r = MsiDoAction( hpkg, "CostInitialize" );
ok( r == ERROR_SUCCESS, "CostInitialize failed %u\n", r );
r = MsiDoAction( hpkg, "FileCost" );
ok( r == ERROR_SUCCESS, "FileCost failed %u\n", r );
len = sizeof(drive);
r = MsiEnumComponentCostsA( hpkg, "one", 0, INSTALLSTATE_LOCAL, drive, &len, &cost, &temp );
ok( r == ERROR_FUNCTION_NOT_CALLED, "Expected ERROR_FUNCTION_NOT_CALLED, got %u\n", r );
r = MsiDoAction( hpkg, "CostFinalize" );
ok( r == ERROR_SUCCESS, "CostFinalize failed %u\n", r );
/* contrary to what msdn says InstallValidate must be called too */
len = sizeof(drive);
r = MsiEnumComponentCostsA( hpkg, "one", 0, INSTALLSTATE_LOCAL, drive, &len, &cost, &temp );
todo_wine ok( r == ERROR_FUNCTION_NOT_CALLED, "Expected ERROR_FUNCTION_NOT_CALLED, got %u\n", r );
r = MsiDoAction( hpkg, "InstallValidate" );
ok( r == ERROR_SUCCESS, "InstallValidate failed %u\n", r );
len = 0;
r = MsiEnumComponentCostsA( hpkg, "three", 0, INSTALLSTATE_LOCAL, drive, &len, &cost, &temp );
ok( r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %u\n", r );
len = 0;
r = MsiEnumComponentCostsA( hpkg, "one", 0, INSTALLSTATE_LOCAL, drive, &len, &cost, &temp );
ok( r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %u\n", r );
ok( len == 2, "expected len == 2, got %u\n", len );
len = 2;
r = MsiEnumComponentCostsA( hpkg, "one", 0, INSTALLSTATE_LOCAL, drive, &len, &cost, &temp );
ok( r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %u\n", r );
ok( len == 2, "expected len == 2, got %u\n", len );
len = 2;
r = MsiEnumComponentCostsA( hpkg, "one", 0, INSTALLSTATE_UNKNOWN, drive, &len, &cost, &temp );
ok( r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %u\n", r );
ok( len == 2, "expected len == 2, got %u\n", len );
/* install state doesn't seem to matter */
len = sizeof(drive);
r = MsiEnumComponentCostsA( hpkg, "one", 0, INSTALLSTATE_UNKNOWN, drive, &len, &cost, &temp );
ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r );
len = sizeof(drive);
r = MsiEnumComponentCostsA( hpkg, "one", 0, INSTALLSTATE_ABSENT, drive, &len, &cost, &temp );
ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r );
len = sizeof(drive);
r = MsiEnumComponentCostsA( hpkg, "one", 0, INSTALLSTATE_SOURCE, drive, &len, &cost, &temp );
ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r );
len = sizeof(drive);
drive[0] = 0;
cost = temp = 0xdead;
r = MsiEnumComponentCostsA( hpkg, "one", 0, INSTALLSTATE_LOCAL, drive, &len, &cost, &temp );
ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r );
ok( len == 2, "expected len == 2, got %u\n", len );
ok( drive[0], "expected a drive\n" );
ok( cost && cost != 0xdead, "expected cost > 0, got %d\n", cost );
ok( !temp, "expected temp == 0, got %d\n", temp );
len = sizeof(drive);
drive[0] = 0;
cost = temp = 0xdead;
r = MsiEnumComponentCostsA( hpkg, "", 0, INSTALLSTATE_UNKNOWN, drive, &len, &cost, &temp );
ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r );
ok( len == 2, "expected len == 2, got %u\n", len );
ok( drive[0], "expected a drive\n" );
ok( !cost, "expected cost == 0, got %d\n", cost );
ok( temp && temp != 0xdead, "expected temp > 0, got %d\n", temp );
/* increased index */
len = sizeof(drive);
r = MsiEnumComponentCostsA( hpkg, "one", 1, INSTALLSTATE_LOCAL, drive, &len, &cost, &temp );
ok( r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %u\n", r );
len = sizeof(drive);
r = MsiEnumComponentCostsA( hpkg, "", 1, INSTALLSTATE_UNKNOWN, drive, &len, &cost, &temp );
ok( r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %u\n", r );
MsiCloseHandle( hpkg );
error:
MsiCloseHandle( hdb );
DeleteFileA( msifile );
}
START_TEST(package)
{
STATEMGRSTATUS status;
@ -12962,6 +13180,7 @@ START_TEST(package)
test_MsiSetProperty();
test_MsiApplyMultiplePatches();
test_MsiApplyPatch();
test_MsiEnumComponentCosts();
if (pSRSetRestorePointA && !pMsiGetComponentPathExA && ret)
{