msi: Use the correct registry key when detecting a published product.
This commit is contained in:
parent
15823e1acf
commit
7da89f48fd
|
@ -763,10 +763,13 @@ INSTALLSTATE WINAPI MsiQueryProductStateW(LPCWSTR szProduct)
|
|||
{
|
||||
UINT rc;
|
||||
INSTALLSTATE state = INSTALLSTATE_UNKNOWN;
|
||||
HKEY hkey = 0;
|
||||
HKEY hkey = 0, props = 0;
|
||||
DWORD sz;
|
||||
|
||||
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
|
||||
};
|
||||
|
@ -783,12 +786,16 @@ INSTALLSTATE WINAPI MsiQueryProductStateW(LPCWSTR szProduct)
|
|||
state = INSTALLSTATE_ADVERTISED;
|
||||
RegCloseKey(hkey);
|
||||
|
||||
rc = MSIREG_OpenUninstallKey(szProduct,&hkey,FALSE);
|
||||
rc = MSIREG_OpenUserDataProductKey(szProduct,&hkey,FALSE);
|
||||
if (rc != ERROR_SUCCESS)
|
||||
goto end;
|
||||
|
||||
rc = RegOpenKeyW(hkey, szInstallProperties, &props);
|
||||
if (rc != ERROR_SUCCESS)
|
||||
goto end;
|
||||
|
||||
sz = sizeof(state);
|
||||
rc = RegQueryValueExW(hkey,szWindowsInstaller,NULL,NULL,(LPVOID)&state, &sz);
|
||||
rc = RegQueryValueExW(props,szWindowsInstaller,NULL,NULL,(LPVOID)&state, &sz);
|
||||
if (rc != ERROR_SUCCESS)
|
||||
goto end;
|
||||
|
||||
|
@ -804,6 +811,7 @@ INSTALLSTATE WINAPI MsiQueryProductStateW(LPCWSTR szProduct)
|
|||
break;
|
||||
}
|
||||
end:
|
||||
RegCloseKey(props);
|
||||
RegCloseKey(hkey);
|
||||
return state;
|
||||
}
|
||||
|
|
|
@ -675,6 +675,7 @@ extern UINT MSIREG_OpenComponents(HKEY* key);
|
|||
extern UINT MSIREG_OpenUserComponentsKey(LPCWSTR szComponent, HKEY* key, BOOL create);
|
||||
extern UINT MSIREG_OpenComponentsKey(LPCWSTR szComponent, HKEY* key, BOOL create);
|
||||
extern UINT MSIREG_OpenProductsKey(LPCWSTR szProduct, HKEY* key, BOOL create);
|
||||
extern UINT MSIREG_OpenUserDataProductKey(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);
|
||||
|
|
|
@ -36,6 +36,7 @@
|
|||
#include "wine/unicode.h"
|
||||
#include "winver.h"
|
||||
#include "winuser.h"
|
||||
#include "sddl.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(msi);
|
||||
|
||||
|
@ -140,6 +141,15 @@ static const WCHAR szInstaller_UserUpgradeCodes_fmt[] = {
|
|||
'U','p','g','r','a','d','e','C','o','d','e','s','\\',
|
||||
'%','s',0};
|
||||
|
||||
static const WCHAR szUserDataProd_fmt[] = {
|
||||
'S','o','f','t','w','a','r','e','\\',
|
||||
'M','i','c','r','o','s','o','f','t','\\',
|
||||
'W','i','n','d','o','w','s','\\',
|
||||
'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
|
||||
'I','n','s','t','a','l','l','e','r','\\',
|
||||
'U','s','e','r','D','a','t','a','\\',
|
||||
'%','s','\\','P','r','o','d','u','c','t','s','\\','%','s',0};
|
||||
|
||||
|
||||
#define SQUISH_GUID_SIZE 33
|
||||
|
||||
|
@ -501,6 +511,55 @@ UINT MSIREG_OpenUserComponentsKey(LPCWSTR szComponent, HKEY* key, BOOL create)
|
|||
return rc;
|
||||
}
|
||||
|
||||
static UINT get_user_sid(LPWSTR *usersid)
|
||||
{
|
||||
HANDLE token;
|
||||
BYTE buf[1024];
|
||||
DWORD size;
|
||||
PTOKEN_USER user;
|
||||
|
||||
if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &token))
|
||||
return ERROR_FUNCTION_FAILED;
|
||||
|
||||
size = sizeof(buf);
|
||||
if (!GetTokenInformation(token, TokenUser, (void *)buf, size, &size))
|
||||
return ERROR_FUNCTION_FAILED;
|
||||
|
||||
user = (PTOKEN_USER)buf;
|
||||
if (!ConvertSidToStringSidW(user->User.Sid, usersid))
|
||||
return ERROR_FUNCTION_FAILED;
|
||||
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
UINT MSIREG_OpenUserDataProductKey(LPCWSTR szProduct, HKEY *key, BOOL create)
|
||||
{
|
||||
UINT rc;
|
||||
WCHAR squished_pc[GUID_SIZE];
|
||||
WCHAR keypath[0x200];
|
||||
LPWSTR usersid;
|
||||
|
||||
TRACE("%s\n", debugstr_w(szProduct));
|
||||
squash_guid(szProduct, squished_pc);
|
||||
TRACE("squished (%s)\n", debugstr_w(squished_pc));
|
||||
|
||||
rc = get_user_sid(&usersid);
|
||||
if (rc != ERROR_SUCCESS || !usersid)
|
||||
{
|
||||
ERR("Failed to retrieve user SID: %d\n", rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
sprintfW(keypath, szUserDataProd_fmt, usersid, squished_pc);
|
||||
|
||||
if (create)
|
||||
rc = RegCreateKeyW(HKEY_LOCAL_MACHINE, keypath, key);
|
||||
else
|
||||
rc = RegOpenKeyW(HKEY_LOCAL_MACHINE, keypath, key);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
UINT MSIREG_OpenProducts(HKEY* key)
|
||||
{
|
||||
return RegCreateKeyW(HKEY_LOCAL_MACHINE,szInstaller_Products,key);
|
||||
|
|
|
@ -2110,7 +2110,10 @@ static void test_Installer_InstallProduct(LPCWSTR szPath)
|
|||
/* Installer::ProductState for our product code, which has been installed */
|
||||
hr = Installer_ProductState(szProductCode, &iValue);
|
||||
ok(hr == S_OK, "Installer_ProductState failed, hresult 0x%08x\n", hr);
|
||||
ok(iValue == INSTALLSTATE_DEFAULT, "Installer_ProductState returned %d, expected %d\n", iValue, INSTALLSTATE_DEFAULT);
|
||||
todo_wine
|
||||
{
|
||||
ok(iValue == INSTALLSTATE_DEFAULT, "Installer_ProductState returned %d, expected %d\n", iValue, INSTALLSTATE_DEFAULT);
|
||||
}
|
||||
|
||||
/* Installer::ProductInfo for our product code */
|
||||
|
||||
|
|
|
@ -379,6 +379,27 @@ static void test_MsiQueryProductState(void)
|
|||
state = MsiQueryProductStateA(prodcode);
|
||||
ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
|
||||
|
||||
lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\");
|
||||
lstrcatA(keypath, prodcode);
|
||||
|
||||
res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &localkey);
|
||||
ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
|
||||
|
||||
/* local uninstall key exists */
|
||||
state = MsiQueryProductStateA(prodcode);
|
||||
ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
|
||||
|
||||
data = 1;
|
||||
res = RegSetValueExA(localkey, "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_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
|
||||
|
||||
RegDeleteValueA(localkey, "WindowsInstaller");
|
||||
RegDeleteKeyA(localkey, "");
|
||||
|
||||
lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
|
||||
lstrcatA(keypath, usersid);
|
||||
lstrcatA(keypath, "\\Products\\");
|
||||
|
@ -404,10 +425,7 @@ static void test_MsiQueryProductState(void)
|
|||
|
||||
/* WindowsInstaller value exists */
|
||||
state = MsiQueryProductStateA(prodcode);
|
||||
todo_wine
|
||||
{
|
||||
ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
|
||||
}
|
||||
ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
|
||||
|
||||
RegDeleteKeyA(userkey, "");
|
||||
|
||||
|
|
Loading…
Reference in New Issue