Commit 4c9c50d8 authored by Hans Leidekker's avatar Hans Leidekker Committed by Alexandre Julliard

msi: Implement and test MsiGetFeatureInfo.

parent aec97287
......@@ -999,7 +999,7 @@ static UINT load_component( MSIRECORD *row, LPVOID param )
return ERROR_SUCCESS;
}
static UINT load_all_components( MSIPACKAGE *package )
UINT msi_load_all_components( MSIPACKAGE *package )
{
static const WCHAR query[] = {
'S','E','L','E','C','T',' ','*',' ','F','R', 'O','M',' ',
......@@ -1161,7 +1161,7 @@ static UINT find_feature_children(MSIRECORD * row, LPVOID param)
return ERROR_SUCCESS;
}
static UINT load_all_features( MSIPACKAGE *package )
UINT msi_load_all_features( MSIPACKAGE *package )
{
static const WCHAR query[] = {
'S','E','L','E','C','T',' ','*',' ', 'F','R','O','M',' ',
......@@ -1550,8 +1550,8 @@ static UINT ACTION_CostInitialize(MSIPACKAGE *package)
msi_set_property( package->db, szRootDrive, szCRoot );
load_all_folders( package );
load_all_components( package );
load_all_features( package );
msi_load_all_components( package );
msi_load_all_features( package );
load_all_files( package );
load_all_patches( package );
load_all_media( package );
......
......@@ -1255,6 +1255,126 @@ UINT WINAPI MsiGetFeatureCostW(MSIHANDLE hInstall, LPCWSTR szFeature,
}
/***********************************************************************
* MsiGetFeatureInfoA (MSI.@)
*/
UINT WINAPI MsiGetFeatureInfoA( MSIHANDLE handle, LPCSTR feature, LPDWORD attrs,
LPSTR title, LPDWORD title_len, LPSTR help, LPDWORD help_len )
{
UINT r;
WCHAR *titleW = NULL, *helpW = NULL, *featureW = NULL;
TRACE("%u, %s, %p, %p, %p, %p, %p\n", handle, debugstr_a(feature), attrs, title,
title_len, help, help_len);
if (feature && !(featureW = strdupAtoW( feature ))) return ERROR_OUTOFMEMORY;
if (title && title_len && !(titleW = msi_alloc( *title_len * sizeof(WCHAR) )))
{
msi_free( featureW );
return ERROR_OUTOFMEMORY;
}
if (help && help_len && !(helpW = msi_alloc( *help_len * sizeof(WCHAR) )))
{
msi_free( featureW );
msi_free( titleW );
return ERROR_OUTOFMEMORY;
}
r = MsiGetFeatureInfoW( handle, featureW, attrs, titleW, title_len, helpW, help_len );
if (r == ERROR_SUCCESS)
{
if (titleW) WideCharToMultiByte( CP_ACP, 0, titleW, -1, title, *title_len + 1, NULL, NULL );
if (helpW) WideCharToMultiByte( CP_ACP, 0, helpW, -1, help, *help_len + 1, NULL, NULL );
}
msi_free( titleW );
msi_free( helpW );
msi_free( featureW );
return r;
}
static DWORD map_feature_attributes( DWORD attrs )
{
DWORD ret = 0;
if (attrs == msidbFeatureAttributesFavorLocal) ret |= INSTALLFEATUREATTRIBUTE_FAVORLOCAL;
if (attrs & msidbFeatureAttributesFavorSource) ret |= INSTALLFEATUREATTRIBUTE_FAVORSOURCE;
if (attrs & msidbFeatureAttributesFollowParent) ret |= INSTALLFEATUREATTRIBUTE_FOLLOWPARENT;
if (attrs & msidbFeatureAttributesFavorAdvertise) ret |= INSTALLFEATUREATTRIBUTE_FAVORADVERTISE;
if (attrs & msidbFeatureAttributesDisallowAdvertise) ret |= INSTALLFEATUREATTRIBUTE_DISALLOWADVERTISE;
if (attrs & msidbFeatureAttributesNoUnsupportedAdvertise) ret |= INSTALLFEATUREATTRIBUTE_NOUNSUPPORTEDADVERTISE;
return ret;
}
static UINT MSI_GetFeatureInfo( MSIPACKAGE *package, LPCWSTR name, LPDWORD attrs,
LPWSTR title, LPDWORD title_len, LPWSTR help, LPDWORD help_len )
{
UINT r = ERROR_SUCCESS;
MSIFEATURE *feature = msi_get_loaded_feature( package, name );
int len;
if (!feature) return ERROR_UNKNOWN_FEATURE;
if (attrs) *attrs = map_feature_attributes( feature->Attributes );
if (title_len)
{
if (feature->Title) len = strlenW( feature->Title );
else len = 0;
if (*title_len <= len)
{
*title_len = len;
if (title) r = ERROR_MORE_DATA;
}
else if (title)
{
if (feature->Title) strcpyW( title, feature->Title );
else *title = 0;
*title_len = len;
}
}
if (help_len)
{
if (feature->Description) len = strlenW( feature->Description );
else len = 0;
if (*help_len <= len)
{
*help_len = len;
if (help) r = ERROR_MORE_DATA;
}
else if (help)
{
if (feature->Description) strcpyW( help, feature->Description );
else *help = 0;
*help_len = len;
}
}
return r;
}
/***********************************************************************
* MsiGetFeatureInfoW (MSI.@)
*/
UINT WINAPI MsiGetFeatureInfoW( MSIHANDLE handle, LPCWSTR feature, LPDWORD attrs,
LPWSTR title, LPDWORD title_len, LPWSTR help, LPDWORD help_len )
{
UINT r;
MSIPACKAGE *package;
TRACE("%u, %s, %p, %p, %p, %p, %p\n", handle, debugstr_w(feature), attrs, title,
title_len, help, help_len);
if (!feature) return ERROR_INVALID_PARAMETER;
if (!(package = msihandle2msiinfo( handle, MSIHANDLETYPE_PACKAGE )))
return ERROR_INVALID_HANDLE;
/* features may not have been loaded yet */
msi_load_all_components( package );
msi_load_all_features( package );
r = MSI_GetFeatureInfo( package, feature, attrs, title, title_len, help, help_len );
msiobj_release( &package->hdr );
return r;
}
/***********************************************************************
* MsiSetComponentStateA (MSI.@)
*/
UINT WINAPI MsiSetComponentStateA(MSIHANDLE hInstall, LPCSTR szComponent,
......
......@@ -48,8 +48,8 @@
52 stdcall MsiGetDatabaseState(long)
53 stdcall MsiGetFeatureCostA(long str long long ptr)
54 stdcall MsiGetFeatureCostW(long wstr long long ptr)
55 stub MsiGetFeatureInfoA
56 stub MsiGetFeatureInfoW
55 stdcall MsiGetFeatureInfoA(long str ptr ptr ptr ptr ptr)
56 stdcall MsiGetFeatureInfoW(long wstr ptr ptr ptr ptr ptr)
57 stdcall MsiGetFeatureStateA(long str ptr ptr)
58 stdcall MsiGetFeatureStateW(long wstr ptr ptr)
59 stdcall MsiGetFeatureUsageA(str str ptr ptr)
......
......@@ -776,6 +776,8 @@ extern UINT msi_parse_command_line( MSIPACKAGE *package, LPCWSTR szCommandLine,
extern UINT msi_schedule_action( MSIPACKAGE *package, UINT script, const WCHAR *action ) DECLSPEC_HIDDEN;
extern INSTALLSTATE msi_get_component_action( MSIPACKAGE *package, MSICOMPONENT *comp ) DECLSPEC_HIDDEN;
extern INSTALLSTATE msi_get_feature_action( MSIPACKAGE *package, MSIFEATURE *feature ) DECLSPEC_HIDDEN;
extern UINT msi_load_all_components( MSIPACKAGE *package ) DECLSPEC_HIDDEN;
extern UINT msi_load_all_features( MSIPACKAGE *package ) DECLSPEC_HIDDEN;
/* record internals */
extern void MSI_CloseRecord( MSIOBJECTHDR * ) DECLSPEC_HIDDEN;
......
......@@ -6386,6 +6386,89 @@ static void test_upgrade_code(void)
DeleteFile(msifile);
}
static void test_MsiGetFeatureInfo(void)
{
UINT r;
MSIHANDLE package;
char title[32], help[32], path[MAX_PATH];
DWORD attrs, title_len, help_len;
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 = MsiGetFeatureInfoA( 0, NULL, NULL, NULL, NULL, NULL, NULL );
ok(r == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", r);
r = MsiGetFeatureInfoA( package, NULL, NULL, NULL, NULL, NULL, NULL );
ok(r == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", r);
r = MsiGetFeatureInfoA( package, "", NULL, NULL, NULL, NULL, NULL );
ok(r == ERROR_UNKNOWN_FEATURE, "expected ERROR_UNKNOWN_FEATURE, got %u\n", r);
r = MsiGetFeatureInfoA( package, "One", NULL, NULL, NULL, NULL, NULL );
ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r);
r = MsiGetFeatureInfoA( 0, "One", NULL, NULL, NULL, NULL, NULL );
ok(r == ERROR_INVALID_HANDLE, "expected ERROR_INVALID_HANDLE, got %u\n", r);
title_len = help_len = 0;
r = MsiGetFeatureInfoA( package, "One", NULL, NULL, &title_len, NULL, &help_len );
ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r);
ok(title_len == 3, "expected 3, got %u\n", title_len);
ok(help_len == 15, "expected 15, got %u\n", help_len);
title[0] = help[0] = 0;
title_len = help_len = 0;
r = MsiGetFeatureInfoA( package, "One", NULL, title, &title_len, help, &help_len );
ok(r == ERROR_MORE_DATA, "expected ERROR_MORE_DATA, got %u\n", r);
ok(title_len == 3, "expected 3, got %u\n", title_len);
ok(help_len == 15, "expected 15, got %u\n", help_len);
attrs = 0;
title[0] = help[0] = 0;
title_len = sizeof(title);
help_len = sizeof(help);
r = MsiGetFeatureInfoA( package, "One", &attrs, title, &title_len, help, &help_len );
ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r);
ok(attrs == INSTALLFEATUREATTRIBUTE_FAVORLOCAL, "expected INSTALLFEATUREATTRIBUTE_FAVORLOCAL, got %u\n", attrs);
ok(title_len == 3, "expected 3, got %u\n", title_len);
ok(help_len == 15, "expected 15, got %u\n", help_len);
ok(!strcmp(title, "One"), "expected \"One\", got \"%s\"\n", title);
ok(!strcmp(help, "The One Feature"), "expected \"The One Feature\", got \"%s\"\n", help);
attrs = 0;
title[0] = help[0] = 0;
title_len = sizeof(title);
help_len = sizeof(help);
r = MsiGetFeatureInfoA( package, "feature", &attrs, title, &title_len, help, &help_len );
ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r);
ok(attrs == INSTALLFEATUREATTRIBUTE_FAVORLOCAL, "expected INSTALLFEATUREATTRIBUTE_FAVORLOCAL, got %u\n", attrs);
ok(!title_len, "expected 0, got %u\n", title_len);
ok(!help_len, "expected 0, got %u\n", help_len);
ok(!title[0], "expected \"\", got \"%s\"\n", title);
ok(!help[0], "expected \"\", got \"%s\"\n", help);
MsiCloseHandle( package );
DeleteFileA( msifile );
}
START_TEST(install)
{
DWORD len;
......@@ -6475,6 +6558,7 @@ START_TEST(install)
test_package_validation();
test_command_line_parsing();
test_upgrade_code();
test_MsiGetFeatureInfo();
DeleteFileA(log_file);
......
......@@ -207,6 +207,16 @@ typedef enum tagMSICODE
MSICODE_PATCH = 0x40000000L
} MSICODE;
typedef enum tagINSTALLFEATUREATTRIBUTE
{
INSTALLFEATUREATTRIBUTE_FAVORLOCAL = 1 << 0,
INSTALLFEATUREATTRIBUTE_FAVORSOURCE = 1 << 1,
INSTALLFEATUREATTRIBUTE_FOLLOWPARENT = 1 << 2,
INSTALLFEATUREATTRIBUTE_FAVORADVERTISE = 1 << 3,
INSTALLFEATUREATTRIBUTE_DISALLOWADVERTISE = 1 << 4,
INSTALLFEATUREATTRIBUTE_NOUNSUPPORTEDADVERTISE = 1 << 5
} INSTALLFEATUREATTRIBUTE;
typedef struct _MSIFILEHASHINFO {
ULONG dwFileHashInfoSize;
ULONG dwData[4];
......@@ -523,6 +533,10 @@ INSTALLSTATE WINAPI MsiQueryFeatureStateA(LPCSTR, LPCSTR);
INSTALLSTATE WINAPI MsiQueryFeatureStateW(LPCWSTR, LPCWSTR);
#define MsiQueryFeatureState WINELIB_NAME_AW(MsiQueryFeatureState)
UINT WINAPI MsiGetFeatureInfoA(MSIHANDLE, LPCSTR, LPDWORD, LPSTR, LPDWORD, LPSTR, LPDWORD);
UINT WINAPI MsiGetFeatureInfoW(MSIHANDLE, LPCWSTR, LPDWORD, LPWSTR, LPDWORD, LPWSTR, LPDWORD);
#define MsiGetFeatureInfo WINELIB_NAME_AW(MsiGetFeatureInfo)
UINT WINAPI MsiGetFeatureUsageA(LPCSTR, LPCSTR, LPDWORD, LPWORD);
UINT WINAPI MsiGetFeatureUsageW(LPCWSTR, LPCWSTR, LPDWORD, LPWORD);
#define MsiGetFeatureUsage WINELIB_NAME_AW(MsiGetFeatureUsage)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment