Commit e21a26e4 authored by James Hawkins's avatar James Hawkins Committed by Alexandre Julliard

msi: Test and reimplement MsiQueryProductState.

parent 85866317
...@@ -3372,7 +3372,7 @@ static UINT ACTION_PublishProduct(MSIPACKAGE *package) ...@@ -3372,7 +3372,7 @@ static UINT ACTION_PublishProduct(MSIPACKAGE *package)
if (rc != ERROR_SUCCESS) if (rc != ERROR_SUCCESS)
goto end; goto end;
rc = MSIREG_OpenInstallPropertiesKey(package->ProductCode,&props,TRUE); rc = MSIREG_OpenCurrentUserInstallProps(package->ProductCode, &props, TRUE);
if (rc != ERROR_SUCCESS) if (rc != ERROR_SUCCESS)
goto end; goto end;
...@@ -3905,7 +3905,7 @@ static UINT msi_make_package_local( MSIPACKAGE *package, HKEY hkey ) ...@@ -3905,7 +3905,7 @@ static UINT msi_make_package_local( MSIPACKAGE *package, HKEY hkey )
msi_reg_set_val_str( hkey, INSTALLPROPERTY_LOCALPACKAGEW, packagefile ); msi_reg_set_val_str( hkey, INSTALLPROPERTY_LOCALPACKAGEW, packagefile );
r = MSIREG_OpenInstallPropertiesKey(package->ProductCode, &props, TRUE); r = MSIREG_OpenCurrentUserInstallProps(package->ProductCode, &props, TRUE);
if (r != ERROR_SUCCESS) if (r != ERROR_SUCCESS)
return r; return r;
...@@ -3995,7 +3995,7 @@ static UINT ACTION_RegisterProduct(MSIPACKAGE *package) ...@@ -3995,7 +3995,7 @@ static UINT ACTION_RegisterProduct(MSIPACKAGE *package)
if (rc != ERROR_SUCCESS) if (rc != ERROR_SUCCESS)
return rc; return rc;
rc = MSIREG_OpenInstallPropertiesKey(package->ProductCode, &props, TRUE); rc = MSIREG_OpenCurrentUserInstallProps(package->ProductCode, &props, TRUE);
if (rc != ERROR_SUCCESS) if (rc != ERROR_SUCCESS)
return rc; return rc;
...@@ -4295,7 +4295,7 @@ static UINT ACTION_RegisterUser(MSIPACKAGE *package) ...@@ -4295,7 +4295,7 @@ static UINT ACTION_RegisterUser(MSIPACKAGE *package)
if (!productid) if (!productid)
return ERROR_SUCCESS; return ERROR_SUCCESS;
rc = MSIREG_OpenInstallPropertiesKey(package->ProductCode, &hkey, TRUE); rc = MSIREG_OpenCurrentUserInstallProps(package->ProductCode, &hkey, TRUE);
if (rc != ERROR_SUCCESS) if (rc != ERROR_SUCCESS)
goto end; goto end;
......
...@@ -630,7 +630,7 @@ static UINT WINAPI MSI_GetProductInfo(LPCWSTR szProduct, LPCWSTR szAttribute, ...@@ -630,7 +630,7 @@ static UINT WINAPI MSI_GetProductInfo(LPCWSTR szProduct, LPCWSTR szAttribute,
if (classes) if (classes)
MSIREG_OpenLocalSystemProductKey(szProduct, &userdata, FALSE); MSIREG_OpenLocalSystemProductKey(szProduct, &userdata, FALSE);
else else
MSIREG_OpenInstallPropertiesKey(szProduct, &userdata, FALSE); MSIREG_OpenCurrentUserInstallProps(szProduct, &userdata, FALSE);
if (!lstrcmpW(szAttribute, INSTALLPROPERTY_HELPLINKW) || if (!lstrcmpW(szAttribute, INSTALLPROPERTY_HELPLINKW) ||
!lstrcmpW(szAttribute, INSTALLPROPERTY_HELPTELEPHONEW) || !lstrcmpW(szAttribute, INSTALLPROPERTY_HELPTELEPHONEW) ||
...@@ -939,7 +939,7 @@ UINT WINAPI MsiGetProductInfoExW(LPCWSTR szProductCode, LPCWSTR szUserSid, ...@@ -939,7 +939,7 @@ UINT WINAPI MsiGetProductInfoExW(LPCWSTR szProductCode, LPCWSTR szUserSid,
if (dwContext == MSIINSTALLCONTEXT_USERUNMANAGED) if (dwContext == MSIINSTALLCONTEXT_USERUNMANAGED)
{ {
package = INSTALLPROPERTY_LOCALPACKAGEW; package = INSTALLPROPERTY_LOCALPACKAGEW;
MSIREG_OpenInstallPropertiesKey(szProductCode, &props, FALSE); MSIREG_OpenCurrentUserInstallProps(szProductCode, &props, FALSE);
if (!props && !prod) if (!props && !prod)
goto done; goto done;
...@@ -947,7 +947,7 @@ UINT WINAPI MsiGetProductInfoExW(LPCWSTR szProductCode, LPCWSTR szUserSid, ...@@ -947,7 +947,7 @@ UINT WINAPI MsiGetProductInfoExW(LPCWSTR szProductCode, LPCWSTR szUserSid,
else if (dwContext == MSIINSTALLCONTEXT_USERMANAGED) else if (dwContext == MSIINSTALLCONTEXT_USERMANAGED)
{ {
package = managed_local_package; package = managed_local_package;
MSIREG_OpenInstallPropertiesKey(szProductCode, &props, FALSE); MSIREG_OpenCurrentUserInstallProps(szProductCode, &props, FALSE);
if (!props && !managed) if (!props && !managed)
goto done; goto done;
...@@ -1197,7 +1197,7 @@ static BOOL msi_comp_find_package(LPCWSTR prodcode, MSIINSTALLCONTEXT context) ...@@ -1197,7 +1197,7 @@ static BOOL msi_comp_find_package(LPCWSTR prodcode, MSIINSTALLCONTEXT context)
if (context == MSIINSTALLCONTEXT_MACHINE) if (context == MSIINSTALLCONTEXT_MACHINE)
r = MSIREG_OpenLocalSystemProductKey(prodcode, &hkey, FALSE); r = MSIREG_OpenLocalSystemProductKey(prodcode, &hkey, FALSE);
else else
r = MSIREG_OpenInstallPropertiesKey(prodcode, &hkey, FALSE); r = MSIREG_OpenCurrentUserInstallProps(prodcode, &hkey, FALSE);
if (r != ERROR_SUCCESS) if (r != ERROR_SUCCESS)
return FALSE; return FALSE;
...@@ -1303,57 +1303,67 @@ INSTALLSTATE WINAPI MsiQueryProductStateA(LPCSTR szProduct) ...@@ -1303,57 +1303,67 @@ INSTALLSTATE WINAPI MsiQueryProductStateA(LPCSTR szProduct)
INSTALLSTATE WINAPI MsiQueryProductStateW(LPCWSTR szProduct) INSTALLSTATE WINAPI MsiQueryProductStateW(LPCWSTR szProduct)
{ {
UINT rc; INSTALLSTATE state = INSTALLSTATE_ADVERTISED;
INSTALLSTATE state = INSTALLSTATE_UNKNOWN; HKEY prodkey = 0, userdata = 0;
HKEY hkey = 0, props = 0; BOOL user = TRUE;
DWORD sz; DWORD val;
BOOL userkey_exists = FALSE; UINT r;
static const int GUID_LEN = 38;
static const WCHAR szInstallProperties[] = {
'I','n','s','t','a','l','l','P','r','o','p','e','r','t','i','e','s',0
};
static const WCHAR szWindowsInstaller[] = { static const WCHAR szWindowsInstaller[] = {
'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};
};
TRACE("%s\n", debugstr_w(szProduct)); TRACE("%s\n", debugstr_w(szProduct));
if (!szProduct || !*szProduct || lstrlenW(szProduct) != GUID_LEN) if (!szProduct || !*szProduct)
return INSTALLSTATE_INVALIDARG; return INSTALLSTATE_INVALIDARG;
rc = MSIREG_OpenUserProductsKey(szProduct,&hkey,FALSE); if (lstrlenW(szProduct) != GUID_SIZE - 1)
if (rc == ERROR_SUCCESS) return INSTALLSTATE_INVALIDARG;
r = MSIREG_OpenLocalManagedProductKey(szProduct, &prodkey, FALSE);
if (r != ERROR_SUCCESS)
{ {
userkey_exists = TRUE; r = MSIREG_OpenUserProductsKey(szProduct, &prodkey, FALSE);
state = INSTALLSTATE_ADVERTISED; if (r != ERROR_SUCCESS)
RegCloseKey(hkey); {
r = MSIREG_OpenLocalClassesProductKey(szProduct, &prodkey, FALSE);
if (r == ERROR_SUCCESS)
user = FALSE;
}
} }
rc = MSIREG_OpenUserDataProductKey(szProduct,&hkey,FALSE); if (user)
if (rc != ERROR_SUCCESS) {
goto end; r = MSIREG_OpenCurrentUserInstallProps(szProduct, &userdata, FALSE);
if (r != ERROR_SUCCESS)
rc = RegOpenKeyW(hkey, szInstallProperties, &props); goto done;
if (rc != ERROR_SUCCESS) }
goto end; else
{
r = MSIREG_OpenLocalSystemInstallProps(szProduct, &userdata, FALSE);
if (r != ERROR_SUCCESS)
goto done;
}
sz = sizeof(state); if (!msi_reg_get_val_dword(userdata, szWindowsInstaller, &val))
rc = RegQueryValueExW(props,szWindowsInstaller,NULL,NULL,(LPVOID)&state, &sz); goto done;
if (rc != ERROR_SUCCESS)
goto end;
if (state) if (val)
state = INSTALLSTATE_DEFAULT; state = INSTALLSTATE_DEFAULT;
else else
state = INSTALLSTATE_UNKNOWN; state = INSTALLSTATE_UNKNOWN;
if (state == INSTALLSTATE_DEFAULT && !userkey_exists) done:
state = INSTALLSTATE_ABSENT; if (!prodkey)
{
state = INSTALLSTATE_UNKNOWN;
end: if (userdata)
RegCloseKey(props); state = INSTALLSTATE_ABSENT;
RegCloseKey(hkey); }
RegCloseKey(prodkey);
RegCloseKey(userdata);
return state; return state;
} }
......
...@@ -758,7 +758,8 @@ extern UINT MSIREG_OpenUserDataComponentKey(LPCWSTR szComponent, HKEY *key, BOOL ...@@ -758,7 +758,8 @@ extern UINT MSIREG_OpenUserDataComponentKey(LPCWSTR szComponent, HKEY *key, BOOL
extern UINT MSIREG_OpenProductsKey(LPCWSTR szProduct, HKEY* key, BOOL create); extern UINT MSIREG_OpenProductsKey(LPCWSTR szProduct, HKEY* key, BOOL create);
extern UINT MSIREG_OpenPatchesKey(LPCWSTR szPatch, HKEY* key, BOOL create); extern UINT MSIREG_OpenPatchesKey(LPCWSTR szPatch, HKEY* key, BOOL create);
extern UINT MSIREG_OpenUserDataProductKey(LPCWSTR szProduct, HKEY* key, BOOL create); extern UINT MSIREG_OpenUserDataProductKey(LPCWSTR szProduct, HKEY* key, BOOL create);
extern UINT MSIREG_OpenInstallPropertiesKey(LPCWSTR szProduct, HKEY* key, BOOL create); extern UINT MSIREG_OpenCurrentUserInstallProps(LPCWSTR szProduct, HKEY* key, BOOL create);
extern UINT MSIREG_OpenLocalSystemInstallProps(LPCWSTR szProduct, HKEY* key, BOOL create);
extern UINT MSIREG_OpenUserFeaturesKey(LPCWSTR szProduct, HKEY* key, BOOL create); extern UINT MSIREG_OpenUserFeaturesKey(LPCWSTR szProduct, HKEY* key, BOOL create);
extern UINT MSIREG_OpenUserComponentsKey(LPCWSTR szComponent, HKEY* key, BOOL create); extern UINT MSIREG_OpenUserComponentsKey(LPCWSTR szComponent, HKEY* key, BOOL create);
extern UINT MSIREG_OpenUpgradeCodesKey(LPCWSTR szProduct, HKEY* key, BOOL create); extern UINT MSIREG_OpenUpgradeCodesKey(LPCWSTR szProduct, HKEY* key, BOOL create);
......
...@@ -753,18 +753,34 @@ UINT MSIREG_OpenUserDataProductKey(LPCWSTR szProduct, HKEY *key, BOOL create) ...@@ -753,18 +753,34 @@ UINT MSIREG_OpenUserDataProductKey(LPCWSTR szProduct, HKEY *key, BOOL create)
return rc; return rc;
} }
UINT MSIREG_OpenInstallPropertiesKey(LPCWSTR szProduct, HKEY *key, BOOL create) static UINT MSIREG_OpenInstallProps(LPCWSTR szProduct, LPCWSTR szUserSID,
HKEY *key, BOOL create)
{ {
UINT rc; UINT rc;
WCHAR squished_pc[GUID_SIZE]; WCHAR squished_pc[GUID_SIZE];
WCHAR keypath[0x200]; WCHAR keypath[0x200];
LPWSTR usersid;
TRACE("%s\n", debugstr_w(szProduct)); TRACE("%s\n", debugstr_w(szProduct));
if (!squash_guid(szProduct, squished_pc)) if (!squash_guid(szProduct, squished_pc))
return ERROR_FUNCTION_FAILED; return ERROR_FUNCTION_FAILED;
TRACE("squished (%s)\n", debugstr_w(squished_pc)); TRACE("squished (%s)\n", debugstr_w(squished_pc));
sprintfW(keypath, szInstallProperties_fmt, szUserSID, squished_pc);
if (create)
rc = RegCreateKeyW(HKEY_LOCAL_MACHINE, keypath, key);
else
rc = RegOpenKeyW(HKEY_LOCAL_MACHINE, keypath, key);
return rc;
}
UINT MSIREG_OpenCurrentUserInstallProps(LPCWSTR szProduct, HKEY *key,
BOOL create)
{
UINT rc;
LPWSTR usersid;
rc = get_user_sid(&usersid); rc = get_user_sid(&usersid);
if (rc != ERROR_SUCCESS || !usersid) if (rc != ERROR_SUCCESS || !usersid)
{ {
...@@ -772,17 +788,20 @@ UINT MSIREG_OpenInstallPropertiesKey(LPCWSTR szProduct, HKEY *key, BOOL create) ...@@ -772,17 +788,20 @@ UINT MSIREG_OpenInstallPropertiesKey(LPCWSTR szProduct, HKEY *key, BOOL create)
return rc; return rc;
} }
sprintfW(keypath, szInstallProperties_fmt, usersid, squished_pc); rc = MSIREG_OpenInstallProps(szProduct, usersid, key, create);
if (create)
rc = RegCreateKeyW(HKEY_LOCAL_MACHINE, keypath, key);
else
rc = RegOpenKeyW(HKEY_LOCAL_MACHINE, keypath, key);
LocalFree(usersid); LocalFree(usersid);
return rc; return rc;
} }
UINT MSIREG_OpenLocalSystemInstallProps(LPCWSTR szProduct, HKEY *key,
BOOL create)
{
static const WCHAR localsid[] = {'S','-','1','-','5','-','1','8',0};
return MSIREG_OpenInstallProps(szProduct, localsid, key, create);
}
UINT MSIREG_DeleteUserDataProductKey(LPCWSTR szProduct) UINT MSIREG_DeleteUserDataProductKey(LPCWSTR szProduct)
{ {
UINT rc; UINT rc;
......
...@@ -2552,7 +2552,10 @@ static void test_publish_registeruser(void) ...@@ -2552,7 +2552,10 @@ static void test_publish_registeruser(void)
ok(pf_exists("msitest"), "File not installed\n"); ok(pf_exists("msitest"), "File not installed\n");
state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}"); state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state); todo_wine
{
ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
}
state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature"); state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state); ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
......
...@@ -414,6 +414,7 @@ static void test_MsiQueryProductState(void) ...@@ -414,6 +414,7 @@ static void test_MsiQueryProductState(void)
INSTALLSTATE state; INSTALLSTATE state;
LONG res; LONG res;
HKEY userkey, localkey, props; HKEY userkey, localkey, props;
HKEY prodkey;
DWORD data; DWORD data;
create_test_guid(prodcode, prod_squashed); create_test_guid(prodcode, prod_squashed);
...@@ -443,7 +444,8 @@ static void test_MsiQueryProductState(void) ...@@ -443,7 +444,8 @@ static void test_MsiQueryProductState(void)
state = MsiQueryProductStateA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93"); state = MsiQueryProductStateA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93");
ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state); ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
/* created guid cannot possibly be an installed product code */ /* MSIINSTALLCONTEXT_USERUNMANAGED */
state = MsiQueryProductStateA(prodcode); state = MsiQueryProductStateA(prodcode);
ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state); ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
...@@ -519,13 +521,109 @@ static void test_MsiQueryProductState(void) ...@@ -519,13 +521,109 @@ static void test_MsiQueryProductState(void)
state = MsiQueryProductStateA(prodcode); state = MsiQueryProductStateA(prodcode);
ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state); ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
LocalFree(usersid);
RegDeleteValueA(props, "WindowsInstaller"); RegDeleteValueA(props, "WindowsInstaller");
RegDeleteKeyA(props, ""); RegDeleteKeyA(props, "");
RegCloseKey(props);
RegDeleteKeyA(localkey, ""); RegDeleteKeyA(localkey, "");
RegCloseKey(localkey);
RegDeleteKeyA(userkey, "");
RegCloseKey(userkey); RegCloseKey(userkey);
/* MSIINSTALLCONTEXT_USERMANAGED */
lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
lstrcatA(keypath, usersid);
lstrcatA(keypath, "\\Installer\\Products\\");
lstrcatA(keypath, prod_squashed);
res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
state = MsiQueryProductStateA(prodcode);
ok(state == INSTALLSTATE_ADVERTISED,
"Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
lstrcatA(keypath, usersid);
lstrcatA(keypath, "\\Products\\");
lstrcatA(keypath, prod_squashed);
res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &localkey);
ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
state = MsiQueryProductStateA(prodcode);
ok(state == INSTALLSTATE_ADVERTISED,
"Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
res = RegCreateKeyA(localkey, "InstallProperties", &props);
ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
state = MsiQueryProductStateA(prodcode);
ok(state == INSTALLSTATE_ADVERTISED,
"Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
data = 1;
res = RegSetValueExA(props, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&data, sizeof(DWORD));
ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
/* WindowsInstaller value exists */
state = MsiQueryProductStateA(prodcode);
ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
RegDeleteValueA(props, "WindowsInstaller");
RegDeleteKeyA(props, "");
RegCloseKey(props);
RegDeleteKeyA(localkey, "");
RegCloseKey(localkey); RegCloseKey(localkey);
RegDeleteKeyA(prodkey, "");
RegCloseKey(prodkey);
/* MSIINSTALLCONTEXT_MACHINE */
lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
lstrcatA(keypath, prod_squashed);
res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
state = MsiQueryProductStateA(prodcode);
ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
lstrcatA(keypath, "S-1-5-18\\Products\\");
lstrcatA(keypath, prod_squashed);
res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &localkey);
ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
state = MsiQueryProductStateA(prodcode);
ok(state == INSTALLSTATE_ADVERTISED,
"Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
res = RegCreateKeyA(localkey, "InstallProperties", &props);
ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
state = MsiQueryProductStateA(prodcode);
ok(state == INSTALLSTATE_ADVERTISED,
"Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
data = 1;
res = RegSetValueExA(props, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&data, sizeof(DWORD));
ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
/* WindowsInstaller value exists */
state = MsiQueryProductStateA(prodcode);
ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
RegDeleteValueA(props, "WindowsInstaller");
RegDeleteKeyA(props, "");
RegCloseKey(props); RegCloseKey(props);
RegDeleteKeyA(localkey, "");
RegCloseKey(localkey);
RegDeleteKeyA(prodkey, "");
RegCloseKey(prodkey);
LocalFree(usersid);
} }
static const char table_enc85[] = static const char table_enc85[] =
......
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