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; return r;
} }
static INSTALLSTATE MSI_GetComponentPath(LPCWSTR szProduct, LPCWSTR szComponent, static BOOL open_userdata_comp_key( const WCHAR *comp, const WCHAR *usersid, MSIINSTALLCONTEXT ctx,
awstring* lpPathBuf, LPDWORD pcchBuf) 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[] = static const WCHAR wininstaller[] =
{'W','i','n','d','o','w','s','I','n','s','t','a','l','l','e','r',0}; {'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 )) if (!squash_guid( szProduct, squashed_pc ) || !squash_guid( szComponent, squashed_comp ))
return INSTALLSTATE_INVALIDARG; return INSTALLSTATE_INVALIDARG;
if (szUserSid && ctx == MSIINSTALLCONTEXT_MACHINE)
return INSTALLSTATE_INVALIDARG;
state = INSTALLSTATE_UNKNOWN; state = INSTALLSTATE_UNKNOWN;
if (MSIREG_OpenUserDataComponentKey(szComponent, szLocalSid, &hkey, FALSE) == ERROR_SUCCESS || if (open_userdata_comp_key( szComponent, szUserSid, ctx, &hkey ))
MSIREG_OpenUserDataComponentKey(szComponent, NULL, &hkey, FALSE) == ERROR_SUCCESS)
{ {
path = msi_reg_get_val_str( hkey, squashed_pc ); path = msi_reg_get_val_str( hkey, squashed_pc );
RegCloseKey(hkey); RegCloseKey(hkey);
state = INSTALLSTATE_ABSENT; state = INSTALLSTATE_ABSENT;
if ((MSIREG_OpenInstallProps(szProduct, MSIINSTALLCONTEXT_MACHINE, NULL, if ((!MSIREG_OpenInstallProps(szProduct, MSIINSTALLCONTEXT_MACHINE, NULL, &hkey, FALSE) ||
&hkey, FALSE) == ERROR_SUCCESS || !MSIREG_OpenUserDataProductKey(szProduct, MSIINSTALLCONTEXT_USERUNMANAGED, NULL, &hkey, FALSE)) &&
MSIREG_OpenUserDataProductKey(szProduct, MSIINSTALLCONTEXT_USERUNMANAGED,
NULL, &hkey, FALSE) == ERROR_SUCCESS) &&
msi_reg_get_val_dword(hkey, wininstaller, &version) && msi_reg_get_val_dword(hkey, wininstaller, &version) &&
GetFileAttributesW(path) != INVALID_FILE_ATTRIBUTES) GetFileAttributesW(path) != INVALID_FILE_ATTRIBUTES)
{ {
@ -2820,16 +2840,12 @@ static INSTALLSTATE MSI_GetComponentPath(LPCWSTR szProduct, LPCWSTR szComponent,
} }
if (state != INSTALLSTATE_LOCAL && if (state != INSTALLSTATE_LOCAL &&
(MSIREG_OpenProductKey(szProduct, NULL, (!MSIREG_OpenProductKey(szProduct, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, &hkey, FALSE) ||
MSIINSTALLCONTEXT_USERUNMANAGED, !MSIREG_OpenProductKey(szProduct, NULL, MSIINSTALLCONTEXT_MACHINE, &hkey, FALSE)))
&hkey, FALSE) == ERROR_SUCCESS ||
MSIREG_OpenProductKey(szProduct, NULL, MSIINSTALLCONTEXT_MACHINE,
&hkey, FALSE) == ERROR_SUCCESS))
{ {
RegCloseKey(hkey); RegCloseKey(hkey);
if (MSIREG_OpenUserDataComponentKey(szComponent, szLocalSid, &hkey, FALSE) == ERROR_SUCCESS || if (open_userdata_comp_key( szComponent, szUserSid, ctx, &hkey ))
MSIREG_OpenUserDataComponentKey(szComponent, NULL, &hkey, FALSE) == ERROR_SUCCESS)
{ {
msi_free(path); msi_free(path);
path = msi_reg_get_val_str( hkey, squashed_pc ); 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, INSTALLSTATE WINAPI MsiGetComponentPathExW( LPCWSTR product, LPCWSTR comp, LPCWSTR usersid,
LPWSTR lpPathBuf, LPDWORD pcchBuf) MSIINSTALLCONTEXT ctx, LPWSTR buf, LPDWORD buflen )
{ {
awstring path; 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.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.@] * MsiGetComponentPathA [MSI.@]
*/ */
INSTALLSTATE WINAPI MsiGetComponentPathA(LPCSTR szProduct, LPCSTR szComponent, INSTALLSTATE WINAPI MsiGetComponentPathA( LPCSTR product, LPCSTR comp, LPSTR buf, LPDWORD buflen )
LPSTR lpPathBuf, LPDWORD pcchBuf)
{ {
LPWSTR szwProduct, szwComponent = NULL; return MsiGetComponentPathExA( product, comp, "s-1-1-0", MSIINSTALLCONTEXT_ALL, buf, buflen );
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;
} }
static UINT query_feature_state( const WCHAR *product, const WCHAR *squashed, const WCHAR *usersid, 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]) ); 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_MOREDATA) return ERROR_MORE_DATA;
if (state != INSTALLSTATE_LOCAL) return ERROR_FILE_NOT_FOUND; 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) 290 stdcall MsiEnumComponentsExW(wstr long long ptr ptr ptr ptr)
291 stdcall MsiEnumClientsExA(str str 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) 292 stdcall MsiEnumClientsExW(wstr wstr long long ptr ptr ptr ptr)
293 stub MsiGetComponentPathExA 293 stdcall MsiGetComponentPathExA(str str str long ptr ptr)
294 stub MsiGetComponentPathExW 294 stdcall MsiGetComponentPathExW(wstr wstr wstr long ptr ptr)
295 stub QueryInstanceCount 295 stub QueryInstanceCount
@ stdcall -private DllCanUnloadNow() @ stdcall -private DllCanUnloadNow()

View File

@ -3429,6 +3429,327 @@ static void test_MsiGetComponentPath(void)
LocalFree(usersid); 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 void test_MsiProvideComponent(void)
{ {
static const WCHAR sourcedirW[] = static const WCHAR sourcedirW[] =
@ -14559,6 +14880,7 @@ START_TEST(msi)
test_MsiQueryFeatureState(); test_MsiQueryFeatureState();
test_MsiQueryComponentState(); test_MsiQueryComponentState();
test_MsiGetComponentPath(); test_MsiGetComponentPath();
test_MsiGetComponentPathEx();
test_MsiProvideComponent(); test_MsiProvideComponent();
test_MsiGetProductCode(); test_MsiGetProductCode();
test_MsiEnumClients(); test_MsiEnumClients();

View File

@ -539,6 +539,10 @@ INSTALLSTATE WINAPI MsiGetComponentPathA(LPCSTR, LPCSTR, LPSTR, LPDWORD);
INSTALLSTATE WINAPI MsiGetComponentPathW(LPCWSTR, LPCWSTR, LPWSTR, LPDWORD); INSTALLSTATE WINAPI MsiGetComponentPathW(LPCWSTR, LPCWSTR, LPWSTR, LPDWORD);
#define MsiGetComponentPath WINELIB_NAME_AW(MsiGetComponentPath) #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 MsiQueryFeatureStateA(LPCSTR, LPCSTR);
INSTALLSTATE WINAPI MsiQueryFeatureStateW(LPCWSTR, LPCWSTR); INSTALLSTATE WINAPI MsiQueryFeatureStateW(LPCWSTR, LPCWSTR);
#define MsiQueryFeatureState WINELIB_NAME_AW(MsiQueryFeatureState) #define MsiQueryFeatureState WINELIB_NAME_AW(MsiQueryFeatureState)