msi: Implement MsiGetComponentPathExA/W.

Signed-off-by: Hans Leidekker <hans@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Hans Leidekker 2017-03-03 11:52:36 +01:00 committed by Alexandre Julliard
parent 6bcf4d6037
commit 64c0625f25
4 changed files with 404 additions and 50 deletions

View File

@ -2778,8 +2778,28 @@ UINT WINAPI MsiVerifyPackageW( LPCWSTR szPackage )
return r;
}
static INSTALLSTATE MSI_GetComponentPath(LPCWSTR szProduct, LPCWSTR szComponent,
awstring* lpPathBuf, LPDWORD pcchBuf)
static BOOL open_userdata_comp_key( const WCHAR *comp, const WCHAR *usersid, MSIINSTALLCONTEXT ctx,
HKEY *hkey )
{
if (ctx & MSIINSTALLCONTEXT_MACHINE)
{
if (!MSIREG_OpenUserDataComponentKey( comp, szLocalSid, hkey, FALSE )) return TRUE;
}
if (ctx & (MSIINSTALLCONTEXT_USERMANAGED|MSIINSTALLCONTEXT_USERUNMANAGED))
{
if (usersid && !strcmpiW( usersid, szAllSid ))
{
FIXME( "only looking at the current user\n" );
usersid = NULL;
}
if (!MSIREG_OpenUserDataComponentKey( comp, usersid, hkey, FALSE )) return TRUE;
}
return FALSE;
}
static INSTALLSTATE MSI_GetComponentPath( const WCHAR *szProduct, const WCHAR *szComponent,
const WCHAR *szUserSid, MSIINSTALLCONTEXT ctx,
awstring *lpPathBuf, DWORD *pcchBuf )
{
static const WCHAR wininstaller[] =
{'W','i','n','d','o','w','s','I','n','s','t','a','l','l','e','r',0};
@ -2797,20 +2817,20 @@ static INSTALLSTATE MSI_GetComponentPath(LPCWSTR szProduct, LPCWSTR szComponent,
if (!squash_guid( szProduct, squashed_pc ) || !squash_guid( szComponent, squashed_comp ))
return INSTALLSTATE_INVALIDARG;
if (szUserSid && ctx == MSIINSTALLCONTEXT_MACHINE)
return INSTALLSTATE_INVALIDARG;
state = INSTALLSTATE_UNKNOWN;
if (MSIREG_OpenUserDataComponentKey(szComponent, szLocalSid, &hkey, FALSE) == ERROR_SUCCESS ||
MSIREG_OpenUserDataComponentKey(szComponent, NULL, &hkey, FALSE) == ERROR_SUCCESS)
if (open_userdata_comp_key( szComponent, szUserSid, ctx, &hkey ))
{
path = msi_reg_get_val_str( hkey, squashed_pc );
RegCloseKey(hkey);
state = INSTALLSTATE_ABSENT;
if ((MSIREG_OpenInstallProps(szProduct, MSIINSTALLCONTEXT_MACHINE, NULL,
&hkey, FALSE) == ERROR_SUCCESS ||
MSIREG_OpenUserDataProductKey(szProduct, MSIINSTALLCONTEXT_USERUNMANAGED,
NULL, &hkey, FALSE) == ERROR_SUCCESS) &&
if ((!MSIREG_OpenInstallProps(szProduct, MSIINSTALLCONTEXT_MACHINE, NULL, &hkey, FALSE) ||
!MSIREG_OpenUserDataProductKey(szProduct, MSIINSTALLCONTEXT_USERUNMANAGED, NULL, &hkey, FALSE)) &&
msi_reg_get_val_dword(hkey, wininstaller, &version) &&
GetFileAttributesW(path) != INVALID_FILE_ATTRIBUTES)
{
@ -2820,16 +2840,12 @@ static INSTALLSTATE MSI_GetComponentPath(LPCWSTR szProduct, LPCWSTR szComponent,
}
if (state != INSTALLSTATE_LOCAL &&
(MSIREG_OpenProductKey(szProduct, NULL,
MSIINSTALLCONTEXT_USERUNMANAGED,
&hkey, FALSE) == ERROR_SUCCESS ||
MSIREG_OpenProductKey(szProduct, NULL, MSIINSTALLCONTEXT_MACHINE,
&hkey, FALSE) == ERROR_SUCCESS))
(!MSIREG_OpenProductKey(szProduct, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, &hkey, FALSE) ||
!MSIREG_OpenProductKey(szProduct, NULL, MSIINSTALLCONTEXT_MACHINE, &hkey, FALSE)))
{
RegCloseKey(hkey);
if (MSIREG_OpenUserDataComponentKey(szComponent, szLocalSid, &hkey, FALSE) == ERROR_SUCCESS ||
MSIREG_OpenUserDataComponentKey(szComponent, NULL, &hkey, FALSE) == ERROR_SUCCESS)
if (open_userdata_comp_key( szComponent, szUserSid, ctx, &hkey ))
{
msi_free(path);
path = msi_reg_get_val_str( hkey, squashed_pc );
@ -2856,51 +2872,63 @@ static INSTALLSTATE MSI_GetComponentPath(LPCWSTR szProduct, LPCWSTR szComponent,
}
/******************************************************************
* MsiGetComponentPathW [MSI.@]
* MsiGetComponentPathExW [MSI.@]
*/
INSTALLSTATE WINAPI MsiGetComponentPathW(LPCWSTR szProduct, LPCWSTR szComponent,
LPWSTR lpPathBuf, LPDWORD pcchBuf)
INSTALLSTATE WINAPI MsiGetComponentPathExW( LPCWSTR product, LPCWSTR comp, LPCWSTR usersid,
MSIINSTALLCONTEXT ctx, LPWSTR buf, LPDWORD buflen )
{
awstring path;
TRACE("%s %s %p %p\n", debugstr_w(szProduct), debugstr_w(szComponent), lpPathBuf, pcchBuf);
TRACE( "%s %s %s 0x%x %p %p\n", debugstr_w(product), debugstr_w(comp), debugstr_w(usersid),
ctx, buf, buflen );
path.unicode = TRUE;
path.str.w = lpPathBuf;
path.str.w = buf;
return MSI_GetComponentPath( szProduct, szComponent, &path, pcchBuf );
return MSI_GetComponentPath( product, comp, usersid, ctx, &path, buflen );
}
INSTALLSTATE WINAPI MsiGetComponentPathExA( LPCSTR product, LPCSTR comp, LPCSTR usersid,
MSIINSTALLCONTEXT ctx, LPSTR buf, LPDWORD buflen )
{
WCHAR *productW = NULL, *compW = NULL, *usersidW = NULL;
INSTALLSTATE r = INSTALLSTATE_UNKNOWN;
awstring path;
TRACE( "%s %s %s 0x%x %p %p\n", debugstr_a(product), debugstr_a(comp), debugstr_a(usersid),
ctx, buf, buflen );
if (product && !(productW = strdupAtoW( product ))) return INSTALLSTATE_UNKNOWN;
if (comp && !(compW = strdupAtoW( comp ))) goto end;
if (usersid && !(usersidW = strdupAtoW( usersid ))) goto end;
path.unicode = FALSE;
path.str.a = buf;
r = MSI_GetComponentPath( productW, compW, usersidW, ctx, &path, buflen );
end:
msi_free( productW );
msi_free( compW );
msi_free( usersidW );
return r;
}
/******************************************************************
* MsiGetComponentPathW [MSI.@]
*/
INSTALLSTATE WINAPI MsiGetComponentPathW( LPCWSTR product, LPCWSTR comp, LPWSTR buf, LPDWORD buflen )
{
return MsiGetComponentPathExW( product, comp, szAllSid, MSIINSTALLCONTEXT_ALL, buf, buflen );
}
/******************************************************************
* MsiGetComponentPathA [MSI.@]
*/
INSTALLSTATE WINAPI MsiGetComponentPathA(LPCSTR szProduct, LPCSTR szComponent,
LPSTR lpPathBuf, LPDWORD pcchBuf)
INSTALLSTATE WINAPI MsiGetComponentPathA( LPCSTR product, LPCSTR comp, LPSTR buf, LPDWORD buflen )
{
LPWSTR szwProduct, szwComponent = NULL;
INSTALLSTATE r = INSTALLSTATE_UNKNOWN;
awstring path;
TRACE("%s %s %p %p\n", debugstr_a(szProduct), debugstr_a(szComponent), lpPathBuf, pcchBuf);
szwProduct = strdupAtoW( szProduct );
if( szProduct && !szwProduct)
goto end;
szwComponent = strdupAtoW( szComponent );
if( szComponent && !szwComponent )
goto end;
path.unicode = FALSE;
path.str.a = lpPathBuf;
r = MSI_GetComponentPath( szwProduct, szwComponent, &path, pcchBuf );
end:
msi_free( szwProduct );
msi_free( szwComponent );
return r;
return MsiGetComponentPathExA( product, comp, "s-1-1-0", MSIINSTALLCONTEXT_ALL, buf, buflen );
}
static UINT query_feature_state( const WCHAR *product, const WCHAR *squashed, const WCHAR *usersid,
@ -3422,7 +3450,7 @@ static UINT MSI_ProvideQualifiedComponentEx(LPCWSTR szComponent,
StringFromGUID2( &guid, comp, sizeof(comp)/sizeof(comp[0]) );
}
state = MSI_GetComponentPath( szProduct, comp, lpPathBuf, pcchPathBuf );
state = MSI_GetComponentPath( szProduct, comp, szAllSid, MSIINSTALLCONTEXT_ALL, lpPathBuf, pcchPathBuf );
if (state == INSTALLSTATE_MOREDATA) return ERROR_MORE_DATA;
if (state != INSTALLSTATE_LOCAL) return ERROR_FILE_NOT_FOUND;

View File

@ -286,8 +286,8 @@
290 stdcall MsiEnumComponentsExW(wstr long long ptr ptr ptr ptr)
291 stdcall MsiEnumClientsExA(str str long long ptr ptr ptr ptr)
292 stdcall MsiEnumClientsExW(wstr wstr long long ptr ptr ptr ptr)
293 stub MsiGetComponentPathExA
294 stub MsiGetComponentPathExW
293 stdcall MsiGetComponentPathExA(str str str long ptr ptr)
294 stdcall MsiGetComponentPathExW(wstr wstr wstr long ptr ptr)
295 stub QueryInstanceCount
@ stdcall -private DllCanUnloadNow()

View File

@ -3429,6 +3429,327 @@ static void test_MsiGetComponentPath(void)
LocalFree(usersid);
}
static void test_MsiGetComponentPathEx(void)
{
HKEY key_comp, key_installprop, key_prod;
char prod[MAX_PATH], prod_squashed[MAX_PATH];
char comp[MAX_PATH], comp_base85[MAX_PATH], comp_squashed[MAX_PATH];
char path[MAX_PATH], path_key[MAX_PATH], *usersid;
INSTALLSTATE state;
DWORD size, val;
REGSAM access = KEY_ALL_ACCESS;
LONG res;
if (!pMsiGetComponentPathExA)
{
win_skip( "MsiGetComponentPathExA not present\n" );
return;
}
if (is_wow64) access |= KEY_WOW64_64KEY;
create_test_guid( prod, prod_squashed );
compose_base85_guid( comp, comp_base85, comp_squashed );
usersid = get_user_sid();
/* NULL product */
size = MAX_PATH;
state = pMsiGetComponentPathExA( NULL, comp, NULL, MSIINSTALLCONTEXT_USERMANAGED, path, &size );
ok( state == INSTALLSTATE_INVALIDARG, "got %d\n", state );
todo_wine ok( !size, "got %u\n", size );
/* NULL component */
size = MAX_PATH;
state = pMsiGetComponentPathExA( prod, NULL, NULL, MSIINSTALLCONTEXT_USERMANAGED, path, &size );
ok( state == INSTALLSTATE_INVALIDARG, "got %d\n", state );
todo_wine ok( !size, "got %u\n", size );
/* non-NULL usersid, MSIINSTALLCONTEXT_MACHINE */
size = MAX_PATH;
state = pMsiGetComponentPathExA( prod, comp, usersid, MSIINSTALLCONTEXT_MACHINE, path, &size);
ok( state == INSTALLSTATE_INVALIDARG, "got %d\n", state );
todo_wine ok( !size, "got %u\n", size );
/* NULL buf */
size = MAX_PATH;
state = pMsiGetComponentPathExA( prod, comp, NULL, MSIINSTALLCONTEXT_MACHINE, NULL, &size );
ok( state == INSTALLSTATE_UNKNOWN, "got %d\n", state );
todo_wine ok( size == MAX_PATH * 2, "got %u\n", size );
/* NULL buflen */
size = MAX_PATH;
state = pMsiGetComponentPathExA( prod, comp, NULL, MSIINSTALLCONTEXT_MACHINE, path, NULL );
ok( state == INSTALLSTATE_INVALIDARG, "got %d\n", state );
ok( size == MAX_PATH, "got %u\n", size );
/* all params valid */
size = MAX_PATH;
state = pMsiGetComponentPathExA( prod, comp, NULL, MSIINSTALLCONTEXT_MACHINE, path, &size );
ok( state == INSTALLSTATE_UNKNOWN, "got %d\n", state );
todo_wine ok( !size, "got %u\n", size );
lstrcpyA( path_key, "Software\\Microsoft\\Windows\\CurrentVersion\\" );
lstrcatA( path_key, "Installer\\UserData\\S-1-5-18\\Components\\" );
lstrcatA( path_key, comp_squashed );
res = RegCreateKeyExA( HKEY_LOCAL_MACHINE, path_key, 0, NULL, 0, access, NULL, &key_comp, NULL );
if (res == ERROR_ACCESS_DENIED)
{
skip( "insufficient rights\n" );
LocalFree( usersid );
return;
}
ok( res == ERROR_SUCCESS, "got %d\n", res );
/* local system component key exists */
size = MAX_PATH;
state = pMsiGetComponentPathExA( prod, comp, NULL, MSIINSTALLCONTEXT_MACHINE, path, &size );
ok( state == INSTALLSTATE_UNKNOWN, "got %d\n", state );
res = RegSetValueExA( key_comp, prod_squashed, 0, REG_SZ, (const BYTE *)"c:\\testcomponentpath", 20 );
ok( res == ERROR_SUCCESS, "got %d\n", res );
/* product value exists */
path[0] = 0;
size = MAX_PATH;
state = pMsiGetComponentPathExA( prod, comp, NULL, MSIINSTALLCONTEXT_MACHINE, path, &size );
ok( state == INSTALLSTATE_ABSENT, "got %d\n", state );
ok( !lstrcmpA( path, "c:\\testcomponentpath" ), "got %s\n", path );
ok( size == 20, "got %u\n", size );
lstrcpyA( path_key, "Software\\Microsoft\\Windows\\CurrentVersion\\" );
lstrcatA( path_key, "Installer\\UserData\\S-1-5-18\\Products\\" );
lstrcatA( path_key, prod_squashed );
lstrcatA( path_key, "\\InstallProperties" );
res = RegCreateKeyExA( HKEY_LOCAL_MACHINE, path_key, 0, NULL, 0, access, NULL, &key_installprop, NULL );
ok( res == ERROR_SUCCESS, "got %d\n", res );
val = 1;
res = RegSetValueExA( key_installprop, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&val, sizeof(val) );
ok( res == ERROR_SUCCESS, "got %d\n", res );
/* install properties key exists */
path[0] = 0;
size = MAX_PATH;
state = pMsiGetComponentPathExA( prod, comp, NULL, MSIINSTALLCONTEXT_MACHINE, path, &size );
ok( state == INSTALLSTATE_ABSENT, "got %d\n", state );
ok( !lstrcmpA( path, "c:\\testcomponentpath"), "got %s\n", path );
ok( size == 20, "got %u\n", size );
create_file( "c:\\testcomponentpath", "c:\\testcomponentpath", 21 );
/* file exists */
path[0] = 0;
size = 0;
state = pMsiGetComponentPathExA( prod, comp, NULL, MSIINSTALLCONTEXT_MACHINE, path, &size );
ok( state == INSTALLSTATE_MOREDATA, "got %d\n", state );
ok( !path[0], "got %s\n", path );
todo_wine ok( size == 40, "got %u\n", size );
path[0] = 0;
size = MAX_PATH;
state = pMsiGetComponentPathExA( prod, comp, NULL, MSIINSTALLCONTEXT_MACHINE, path, &size );
ok( state == INSTALLSTATE_LOCAL, "got %d\n", state );
ok( !lstrcmpA( path, "c:\\testcomponentpath" ), "got %s\n", path );
ok( size == 20, "got %d\n", size );
RegDeleteValueA( key_comp, prod_squashed );
delete_key( key_comp, "", access & KEY_WOW64_64KEY );
RegDeleteValueA( key_installprop, "WindowsInstaller" );
delete_key( key_installprop, "", access & KEY_WOW64_64KEY );
RegCloseKey( key_comp );
RegCloseKey( key_installprop );
DeleteFileA( "c:\\testcomponentpath" );
lstrcpyA( path_key, "Software\\Microsoft\\Installer\\Products\\" );
lstrcatA( path_key, prod_squashed );
res = RegCreateKeyA( HKEY_CURRENT_USER, path_key, &key_prod );
ok( res == ERROR_SUCCESS, "got %d\n", res );
/* user unmanaged product key exists */
size = MAX_PATH;
state = pMsiGetComponentPathExA( prod, comp, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, path, &size );
ok( state == INSTALLSTATE_UNKNOWN, "got %d\n", state );
todo_wine ok(!size, "got %u\n", size);
lstrcpyA( path_key, "Software\\Microsoft\\Windows\\CurrentVersion\\" );
lstrcatA( path_key, "Installer\\UserData\\" );
lstrcatA( path_key, usersid );
lstrcatA( path_key, "\\Components\\" );
lstrcatA( path_key, comp_squashed );
res = RegCreateKeyExA( HKEY_LOCAL_MACHINE, path_key, 0, NULL, 0, access, NULL, &key_comp, NULL );
ok( res == ERROR_SUCCESS, "got %d\n", res );
/* user unmanaged component key exists */
size = MAX_PATH;
state = pMsiGetComponentPathExA( prod, comp, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, path, &size );
ok( state == INSTALLSTATE_UNKNOWN, "got %d\n", state );
todo_wine ok(!size, "got %u\n", size);
res = RegSetValueExA( key_comp, prod_squashed, 0, REG_SZ, (const BYTE *)"c:\\testcomponentpath", 20 );
ok( res == ERROR_SUCCESS, "got %d\n", res );
/* product value exists */
path[0] = 0;
size = MAX_PATH;
state = pMsiGetComponentPathExA( prod, comp, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, path, &size );
ok( state == INSTALLSTATE_ABSENT, "got %d\n", state );
ok( !lstrcmpA( path, "c:\\testcomponentpath"), "got %s\n", path );
ok( size == 20, "got %u\n", size );
create_file( "c:\\testcomponentpath", "c:\\testcomponentpath", 21 );
/* file exists */
path[0] = 0;
size = MAX_PATH;
state = pMsiGetComponentPathExA( prod, comp, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, path, &size );
ok( state == INSTALLSTATE_LOCAL, "got %d\n", state );
ok( !lstrcmpA( path, "c:\\testcomponentpath"), "got %s\n", path );
ok( size == 20, "got %u\n", size );
RegDeleteValueA( key_comp, prod_squashed );
RegDeleteKeyA( key_prod, "" );
delete_key( key_comp, "", access & KEY_WOW64_64KEY );
RegCloseKey( key_prod );
RegCloseKey( key_comp );
DeleteFileA( "c:\\testcomponentpath" );
lstrcpyA( path_key, "Software\\Microsoft\\Windows\\CurrentVersion\\" );
lstrcatA( path_key, "Installer\\Managed\\" );
lstrcatA( path_key, usersid );
lstrcatA( path_key, "\\Installer\\Products\\" );
lstrcatA( path_key, prod_squashed );
res = RegCreateKeyExA( HKEY_LOCAL_MACHINE, path_key, 0, NULL, 0, access, NULL, &key_prod, NULL );
ok( res == ERROR_SUCCESS, "got %d\n", res );
/* user managed product key exists */
size = MAX_PATH;
state = pMsiGetComponentPathExA( prod, comp, NULL, MSIINSTALLCONTEXT_USERMANAGED, path, &size );
ok( state == INSTALLSTATE_UNKNOWN, "got %d\n", state );
lstrcpyA( path_key, "Software\\Microsoft\\Windows\\CurrentVersion\\" );
lstrcatA( path_key, "Installer\\UserData\\" );
lstrcatA( path_key, usersid );
lstrcatA( path_key, "\\Components\\" );
lstrcatA( path_key, comp_squashed );
res = RegCreateKeyExA( HKEY_LOCAL_MACHINE, path_key, 0, NULL, 0, access, NULL, &key_comp, NULL );
ok( res == ERROR_SUCCESS, "got %d\n", res );
/* user managed component key exists */
size = MAX_PATH;
state = pMsiGetComponentPathExA( prod, comp, NULL, MSIINSTALLCONTEXT_USERMANAGED, path, &size );
ok( state == INSTALLSTATE_UNKNOWN, "got %d\n", state );
res = RegSetValueExA( key_comp, prod_squashed, 0, REG_SZ, (const BYTE *)"c:\\testcomponentpath", 20 );
ok( res == ERROR_SUCCESS, "got %d\n", res );
/* product value exists */
path[0] = 0;
size = MAX_PATH;
state = pMsiGetComponentPathExA( prod, comp, NULL, MSIINSTALLCONTEXT_USERMANAGED, path, &size );
ok( state == INSTALLSTATE_ABSENT, "got %d\n", state );
ok( !lstrcmpA( path, "c:\\testcomponentpath" ), "got %s\n", path );
ok( size == 20, "got %u\n", size );
lstrcpyA( path_key, "Software\\Microsoft\\Windows\\CurrentVersion\\" );
lstrcatA( path_key, "Installer\\UserData\\S-1-5-18\\Products\\" );
lstrcatA( path_key, prod_squashed );
lstrcatA( path_key, "\\InstallProperties" );
res = RegCreateKeyExA( HKEY_LOCAL_MACHINE, path_key, 0, NULL, 0, access, NULL, &key_installprop, NULL );
ok( res == ERROR_SUCCESS, "got %d\n", res );
val = 1;
res = RegSetValueExA( key_installprop, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&val, sizeof(val) );
ok( res == ERROR_SUCCESS, "got %d\n", res );
/* install properties key exists */
path[0] = 0;
size = MAX_PATH;
state = pMsiGetComponentPathExA( prod, comp, NULL, MSIINSTALLCONTEXT_USERMANAGED, path, &size );
ok( state == INSTALLSTATE_ABSENT, "got %d\n", state );
ok( !lstrcmpA( path, "c:\\testcomponentpath" ), "got %s\n", path );
ok( size == 20, "got %u\n", size );
create_file( "c:\\testcomponentpath", "C:\\testcomponentpath", 21 );
/* file exists */
path[0] = 0;
size = MAX_PATH;
state = pMsiGetComponentPathExA( prod, comp, NULL, MSIINSTALLCONTEXT_USERMANAGED, path, &size );
ok( state == INSTALLSTATE_LOCAL, "got %d\n", state );
ok( !lstrcmpA( path, "c:\\testcomponentpath" ), "got %s\n", path );
ok( size == 20, "got %u\n", size );
RegDeleteValueA( key_comp, prod_squashed );
delete_key( key_prod, "", access & KEY_WOW64_64KEY );
delete_key( key_comp, "", access & KEY_WOW64_64KEY );
RegDeleteValueA( key_installprop, "WindowsInstaller" );
delete_key( key_installprop, "", access & KEY_WOW64_64KEY );
RegCloseKey( key_prod );
RegCloseKey( key_comp );
RegCloseKey( key_installprop );
DeleteFileA( "c:\\testcomponentpath" );
lstrcpyA( path_key, "Software\\Classes\\Installer\\Products\\" );
lstrcatA( path_key, prod_squashed );
res = RegCreateKeyExA( HKEY_LOCAL_MACHINE, path_key, 0, NULL, 0, access, NULL, &key_prod, NULL );
ok( res == ERROR_SUCCESS, "got %d\n", res );
/* local classes product key exists */
size = MAX_PATH;
state = pMsiGetComponentPathExA( prod, comp, NULL, MSIINSTALLCONTEXT_MACHINE, path, &size );
ok( state == INSTALLSTATE_UNKNOWN, "got %d\n", state );
todo_wine ok(!size, "got %u\n", size);
lstrcpyA( path_key, "Software\\Microsoft\\Windows\\CurrentVersion\\" );
lstrcatA( path_key, "Installer\\UserData\\S-1-5-18\\Components\\" );
lstrcatA( path_key, comp_squashed );
res = RegCreateKeyExA( HKEY_LOCAL_MACHINE, path_key, 0, NULL, 0, access, NULL, &key_comp, NULL );
ok( res == ERROR_SUCCESS, "got %d\n", res );
/* local user component key exists */
size = MAX_PATH;
state = pMsiGetComponentPathExA( prod, comp, NULL, MSIINSTALLCONTEXT_MACHINE, path, &size );
ok( state == INSTALLSTATE_UNKNOWN, "got %d\n", state );
todo_wine ok(!size, "got %u\n", size);
res = RegSetValueExA( key_comp, prod_squashed, 0, REG_SZ, (const BYTE *)"c:\\testcomponentpath", 20 );
ok( res == ERROR_SUCCESS, "got %d\n", res );
/* product value exists */
path[0] = 0;
size = MAX_PATH;
state = pMsiGetComponentPathExA( prod, comp, NULL, MSIINSTALLCONTEXT_MACHINE, path, &size );
ok( state == INSTALLSTATE_ABSENT, "got %d\n", state );
ok( !lstrcmpA( path, "c:\\testcomponentpath" ), "got %s\n", path );
ok( size == 20, "got %u\n", size );
create_file( "c:\\testcomponentpath", "c:\\testcomponentpath", 21 );
/* file exists */
path[0] = 0;
size = MAX_PATH;
state = pMsiGetComponentPathExA( prod, comp, NULL, MSIINSTALLCONTEXT_MACHINE, path, &size );
ok( state == INSTALLSTATE_LOCAL, "got %d\n", state );
ok( !lstrcmpA( path, "c:\\testcomponentpath" ), "got %s\n", path );
ok( size == 20, "got %u\n", size );
RegDeleteValueA( key_comp, prod_squashed );
delete_key( key_prod, "", access & KEY_WOW64_64KEY );
delete_key( key_comp, "", access & KEY_WOW64_64KEY );
RegCloseKey( key_prod );
RegCloseKey( key_comp );
DeleteFileA( "c:\\testcomponentpath" );
LocalFree( usersid );
}
static void test_MsiProvideComponent(void)
{
static const WCHAR sourcedirW[] =
@ -14559,6 +14880,7 @@ START_TEST(msi)
test_MsiQueryFeatureState();
test_MsiQueryComponentState();
test_MsiGetComponentPath();
test_MsiGetComponentPathEx();
test_MsiProvideComponent();
test_MsiGetProductCode();
test_MsiEnumClients();

View File

@ -539,6 +539,10 @@ INSTALLSTATE WINAPI MsiGetComponentPathA(LPCSTR, LPCSTR, LPSTR, LPDWORD);
INSTALLSTATE WINAPI MsiGetComponentPathW(LPCWSTR, LPCWSTR, LPWSTR, LPDWORD);
#define MsiGetComponentPath WINELIB_NAME_AW(MsiGetComponentPath)
INSTALLSTATE WINAPI MsiGetComponentPathExA(LPCSTR, LPCSTR, LPCSTR, MSIINSTALLCONTEXT, LPSTR, LPDWORD);
INSTALLSTATE WINAPI MsiGetComponentPathExW(LPCWSTR, LPCWSTR, LPCWSTR, MSIINSTALLCONTEXT, LPWSTR, LPDWORD);
#define MsiGetComponentPathEx WINELIB_NAME_AW(MsiGetComponentPathEx)
INSTALLSTATE WINAPI MsiQueryFeatureStateA(LPCSTR, LPCSTR);
INSTALLSTATE WINAPI MsiQueryFeatureStateW(LPCWSTR, LPCWSTR);
#define MsiQueryFeatureState WINELIB_NAME_AW(MsiQueryFeatureState)