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)
if (rc != ERROR_SUCCESS)
goto end;
rc = MSIREG_OpenInstallPropertiesKey(package->ProductCode,&props,TRUE);
rc = MSIREG_OpenCurrentUserInstallProps(package->ProductCode, &props, TRUE);
if (rc != ERROR_SUCCESS)
goto end;
......@@ -3905,7 +3905,7 @@ static UINT msi_make_package_local( MSIPACKAGE *package, HKEY hkey )
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)
return r;
......@@ -3995,7 +3995,7 @@ static UINT ACTION_RegisterProduct(MSIPACKAGE *package)
if (rc != ERROR_SUCCESS)
return rc;
rc = MSIREG_OpenInstallPropertiesKey(package->ProductCode, &props, TRUE);
rc = MSIREG_OpenCurrentUserInstallProps(package->ProductCode, &props, TRUE);
if (rc != ERROR_SUCCESS)
return rc;
......@@ -4295,7 +4295,7 @@ static UINT ACTION_RegisterUser(MSIPACKAGE *package)
if (!productid)
return ERROR_SUCCESS;
rc = MSIREG_OpenInstallPropertiesKey(package->ProductCode, &hkey, TRUE);
rc = MSIREG_OpenCurrentUserInstallProps(package->ProductCode, &hkey, TRUE);
if (rc != ERROR_SUCCESS)
goto end;
......
......@@ -630,7 +630,7 @@ static UINT WINAPI MSI_GetProductInfo(LPCWSTR szProduct, LPCWSTR szAttribute,
if (classes)
MSIREG_OpenLocalSystemProductKey(szProduct, &userdata, FALSE);
else
MSIREG_OpenInstallPropertiesKey(szProduct, &userdata, FALSE);
MSIREG_OpenCurrentUserInstallProps(szProduct, &userdata, FALSE);
if (!lstrcmpW(szAttribute, INSTALLPROPERTY_HELPLINKW) ||
!lstrcmpW(szAttribute, INSTALLPROPERTY_HELPTELEPHONEW) ||
......@@ -939,7 +939,7 @@ UINT WINAPI MsiGetProductInfoExW(LPCWSTR szProductCode, LPCWSTR szUserSid,
if (dwContext == MSIINSTALLCONTEXT_USERUNMANAGED)
{
package = INSTALLPROPERTY_LOCALPACKAGEW;
MSIREG_OpenInstallPropertiesKey(szProductCode, &props, FALSE);
MSIREG_OpenCurrentUserInstallProps(szProductCode, &props, FALSE);
if (!props && !prod)
goto done;
......@@ -947,7 +947,7 @@ UINT WINAPI MsiGetProductInfoExW(LPCWSTR szProductCode, LPCWSTR szUserSid,
else if (dwContext == MSIINSTALLCONTEXT_USERMANAGED)
{
package = managed_local_package;
MSIREG_OpenInstallPropertiesKey(szProductCode, &props, FALSE);
MSIREG_OpenCurrentUserInstallProps(szProductCode, &props, FALSE);
if (!props && !managed)
goto done;
......@@ -1197,7 +1197,7 @@ static BOOL msi_comp_find_package(LPCWSTR prodcode, MSIINSTALLCONTEXT context)
if (context == MSIINSTALLCONTEXT_MACHINE)
r = MSIREG_OpenLocalSystemProductKey(prodcode, &hkey, FALSE);
else
r = MSIREG_OpenInstallPropertiesKey(prodcode, &hkey, FALSE);
r = MSIREG_OpenCurrentUserInstallProps(prodcode, &hkey, FALSE);
if (r != ERROR_SUCCESS)
return FALSE;
......@@ -1303,57 +1303,67 @@ INSTALLSTATE WINAPI MsiQueryProductStateA(LPCSTR szProduct)
INSTALLSTATE WINAPI MsiQueryProductStateW(LPCWSTR szProduct)
{
UINT rc;
INSTALLSTATE state = INSTALLSTATE_UNKNOWN;
HKEY hkey = 0, props = 0;
DWORD sz;
BOOL userkey_exists = FALSE;
INSTALLSTATE state = INSTALLSTATE_ADVERTISED;
HKEY prodkey = 0, userdata = 0;
BOOL user = TRUE;
DWORD val;
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[] = {
'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));
if (!szProduct || !*szProduct || lstrlenW(szProduct) != GUID_LEN)
if (!szProduct || !*szProduct)
return INSTALLSTATE_INVALIDARG;
rc = MSIREG_OpenUserProductsKey(szProduct,&hkey,FALSE);
if (rc == ERROR_SUCCESS)
if (lstrlenW(szProduct) != GUID_SIZE - 1)
return INSTALLSTATE_INVALIDARG;
r = MSIREG_OpenLocalManagedProductKey(szProduct, &prodkey, FALSE);
if (r != ERROR_SUCCESS)
{
userkey_exists = TRUE;
state = INSTALLSTATE_ADVERTISED;
RegCloseKey(hkey);
r = MSIREG_OpenUserProductsKey(szProduct, &prodkey, FALSE);
if (r != ERROR_SUCCESS)
{
r = MSIREG_OpenLocalClassesProductKey(szProduct, &prodkey, FALSE);
if (r == ERROR_SUCCESS)
user = FALSE;
}
}
rc = MSIREG_OpenUserDataProductKey(szProduct,&hkey,FALSE);
if (rc != ERROR_SUCCESS)
goto end;
rc = RegOpenKeyW(hkey, szInstallProperties, &props);
if (rc != ERROR_SUCCESS)
goto end;
if (user)
{
r = MSIREG_OpenCurrentUserInstallProps(szProduct, &userdata, FALSE);
if (r != ERROR_SUCCESS)
goto done;
}
else
{
r = MSIREG_OpenLocalSystemInstallProps(szProduct, &userdata, FALSE);
if (r != ERROR_SUCCESS)
goto done;
}
sz = sizeof(state);
rc = RegQueryValueExW(props,szWindowsInstaller,NULL,NULL,(LPVOID)&state, &sz);
if (rc != ERROR_SUCCESS)
goto end;
if (!msi_reg_get_val_dword(userdata, szWindowsInstaller, &val))
goto done;
if (state)
if (val)
state = INSTALLSTATE_DEFAULT;
else
state = INSTALLSTATE_UNKNOWN;
if (state == INSTALLSTATE_DEFAULT && !userkey_exists)
state = INSTALLSTATE_ABSENT;
done:
if (!prodkey)
{
state = INSTALLSTATE_UNKNOWN;
end:
RegCloseKey(props);
RegCloseKey(hkey);
if (userdata)
state = INSTALLSTATE_ABSENT;
}
RegCloseKey(prodkey);
RegCloseKey(userdata);
return state;
}
......
......@@ -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_OpenPatchesKey(LPCWSTR szPatch, 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_OpenUserComponentsKey(LPCWSTR szComponent, 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)
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;
WCHAR squished_pc[GUID_SIZE];
WCHAR keypath[0x200];
LPWSTR usersid;
TRACE("%s\n", debugstr_w(szProduct));
if (!squash_guid(szProduct, squished_pc))
return ERROR_FUNCTION_FAILED;
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);
if (rc != ERROR_SUCCESS || !usersid)
{
......@@ -772,17 +788,20 @@ UINT MSIREG_OpenInstallPropertiesKey(LPCWSTR szProduct, HKEY *key, BOOL create)
return rc;
}
sprintfW(keypath, szInstallProperties_fmt, usersid, squished_pc);
if (create)
rc = RegCreateKeyW(HKEY_LOCAL_MACHINE, keypath, key);
else
rc = RegOpenKeyW(HKEY_LOCAL_MACHINE, keypath, key);
rc = MSIREG_OpenInstallProps(szProduct, usersid, key, create);
LocalFree(usersid);
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 rc;
......
......@@ -2552,7 +2552,10 @@ static void test_publish_registeruser(void)
ok(pf_exists("msitest"), "File not installed\n");
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");
ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
......
......@@ -414,6 +414,7 @@ static void test_MsiQueryProductState(void)
INSTALLSTATE state;
LONG res;
HKEY userkey, localkey, props;
HKEY prodkey;
DWORD data;
create_test_guid(prodcode, prod_squashed);
......@@ -443,7 +444,8 @@ static void test_MsiQueryProductState(void)
state = MsiQueryProductStateA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93");
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);
ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
......@@ -519,13 +521,109 @@ static void test_MsiQueryProductState(void)
state = MsiQueryProductStateA(prodcode);
ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
LocalFree(usersid);
RegDeleteValueA(props, "WindowsInstaller");
RegDeleteKeyA(props, "");
RegCloseKey(props);
RegDeleteKeyA(localkey, "");
RegCloseKey(localkey);
RegDeleteKeyA(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);
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);
RegDeleteKeyA(localkey, "");
RegCloseKey(localkey);
RegDeleteKeyA(prodkey, "");
RegCloseKey(prodkey);
LocalFree(usersid);
}
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