Module: wine Branch: master Commit: 7da89f48fd44c54e8b963e94b5f69d88b6334c57 URL: http://source.winehq.org/git/wine.git/?a=commit;h=7da89f48fd44c54e8b963e94b5...
Author: James Hawkins truiken@gmail.com Date: Tue Jun 26 19:01:03 2007 -0700
msi: Use the correct registry key when detecting a published product.
---
dlls/msi/msi.c | 14 ++++++++-- dlls/msi/msipriv.h | 1 + dlls/msi/registry.c | 59 +++++++++++++++++++++++++++++++++++++++++++ dlls/msi/tests/automation.c | 5 +++- dlls/msi/tests/msi.c | 26 ++++++++++++++++--- 5 files changed, 97 insertions(+), 8 deletions(-)
diff --git a/dlls/msi/msi.c b/dlls/msi/msi.c index 7240ea4..fce1bc5 100644 --- a/dlls/msi/msi.c +++ b/dlls/msi/msi.c @@ -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; } diff --git a/dlls/msi/msipriv.h b/dlls/msi/msipriv.h index d9c7615..be5f2b1 100644 --- a/dlls/msi/msipriv.h +++ b/dlls/msi/msipriv.h @@ -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); diff --git a/dlls/msi/registry.c b/dlls/msi/registry.c index 14a4754..21e0804 100644 --- a/dlls/msi/registry.c +++ b/dlls/msi/registry.c @@ -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); diff --git a/dlls/msi/tests/automation.c b/dlls/msi/tests/automation.c index 7308671..84c3627 100644 --- a/dlls/msi/tests/automation.c +++ b/dlls/msi/tests/automation.c @@ -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 */
diff --git a/dlls/msi/tests/msi.c b/dlls/msi/tests/msi.c index 9afa576..4e42fea 100644 --- a/dlls/msi/tests/msi.c +++ b/dlls/msi/tests/msi.c @@ -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, "");