Module: wine Branch: master Commit: 9163b0d0a388c2aa2b1e7cf835e01616ba66fb4c URL: http://source.winehq.org/git/wine.git/?a=commit;h=9163b0d0a388c2aa2b1e7cf835...
Author: Hans Leidekker hans@codeweavers.com Date: Fri Mar 27 13:40:16 2009 +0100
msi: Enumerate products from all contexts.
Fix for office 2007 proofing tools installer.
---
dlls/msi/registry.c | 121 ++++++++++++++++++++++++++++++++++++++++--- dlls/msi/tests/automation.c | 2 +- 2 files changed, 114 insertions(+), 9 deletions(-)
diff --git a/dlls/msi/registry.c b/dlls/msi/registry.c index 3205079..3ba34d1 100644 --- a/dlls/msi/registry.c +++ b/dlls/msi/registry.c @@ -103,6 +103,12 @@ static const WCHAR szUninstall_fmt[] = { 'U','n','i','n','s','t','a','l','l','\', '%','s',0 };
+static const WCHAR szUserProduct[] = { +'S','o','f','t','w','a','r','e','\', +'M','i','c','r','o','s','o','f','t','\', +'I','n','s','t','a','l','l','e','r','\', +'P','r','o','d','u','c','t','s',0}; + static const WCHAR szUserProduct_fmt[] = { 'S','o','f','t','w','a','r','e','\', 'M','i','c','r','o','s','o','f','t','\', @@ -187,6 +193,12 @@ static const WCHAR szInstallProperties_fmt[] = { '%','s','\','P','r','o','d','u','c','t','s','\','%','s','\', 'I','n','s','t','a','l','l','P','r','o','p','e','r','t','i','e','s',0};
+static const WCHAR szInstaller_LocalClassesProd[] = { +'S','o','f','t','w','a','r','e','\', +'C','l','a','s','s','e','s','\', +'I','n','s','t','a','l','l','e','r','\', +'P','r','o','d','u','c','t','s',0}; + static const WCHAR szInstaller_LocalClassesProd_fmt[] = { 'S','o','f','t','w','a','r','e','\', 'C','l','a','s','s','e','s','\', @@ -199,6 +211,16 @@ static const WCHAR szInstaller_LocalClassesFeat_fmt[] = { 'I','n','s','t','a','l','l','e','r','\', 'F','e','a','t','u','r','e','s','\','%','s',0};
+static const WCHAR szInstaller_LocalManaged_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','\', +'M','a','n','a','g','e','d','\','%','s','\', +'I','n','s','t','a','l','l','e','r','\', +'P','r','o','d','u','c','t','s',0}; + static const WCHAR szInstaller_LocalManagedProd_fmt[] = { 'S','o','f','t','w','a','r','e','\', 'M','i','c','r','o','s','o','f','t','\', @@ -1198,25 +1220,108 @@ UINT WINAPI MsiEnumProductsA(DWORD index, LPSTR lpguid)
UINT WINAPI MsiEnumProductsW(DWORD index, LPWSTR lpguid) { - HKEY hkeyProducts = 0; - DWORD r; + UINT r; WCHAR szKeyName[SQUISH_GUID_SIZE]; + HKEY key; + DWORD machine_count, managed_count, unmanaged_count; + WCHAR keypath[MAX_PATH]; + LPWSTR usersid = NULL; + + static DWORD last_index;
TRACE("%d %p\n", index, lpguid);
if (NULL == lpguid) return ERROR_INVALID_PARAMETER;
- r = RegCreateKeyW(HKEY_LOCAL_MACHINE, szInstaller_Products, &hkeyProducts); + if (index && index - last_index != 1) + return ERROR_INVALID_PARAMETER; + + r = RegCreateKeyW(HKEY_LOCAL_MACHINE, szInstaller_LocalClassesProd, &key); if( r != ERROR_SUCCESS ) return ERROR_NO_MORE_ITEMS;
- r = RegEnumKeyW(hkeyProducts, index, szKeyName, SQUISH_GUID_SIZE); - if( r == ERROR_SUCCESS ) - unsquash_guid(szKeyName, lpguid); - RegCloseKey(hkeyProducts); + r = RegQueryInfoKeyW(key, NULL, NULL, NULL, &machine_count, NULL, NULL, + NULL, NULL, NULL, NULL, NULL); + if( r != ERROR_SUCCESS ) + { + RegCloseKey(key); + return ERROR_NO_MORE_ITEMS; + }
- return r; + if (machine_count && index <= machine_count) + { + r = RegEnumKeyW(key, index, szKeyName, SQUISH_GUID_SIZE); + if( r == ERROR_SUCCESS ) + { + unsquash_guid(szKeyName, lpguid); + last_index = index; + RegCloseKey(key); + return ERROR_SUCCESS; + } + } + RegCloseKey(key); + + r = get_user_sid(&usersid); + if (r != ERROR_SUCCESS || !usersid) + { + ERR("Failed to retrieve user SID: %d\n", r); + return r; + } + sprintfW(keypath, szInstaller_LocalManaged_fmt, usersid); + LocalFree(usersid); + + r = RegCreateKeyW(HKEY_LOCAL_MACHINE, keypath, &key); + if( r != ERROR_SUCCESS ) + return ERROR_NO_MORE_ITEMS; + + r = RegQueryInfoKeyW(key, NULL, NULL, NULL, &managed_count, NULL, NULL, + NULL, NULL, NULL, NULL, NULL); + if( r != ERROR_SUCCESS ) + { + RegCloseKey(key); + return ERROR_NO_MORE_ITEMS; + } + + if (managed_count && index <= machine_count + managed_count) + { + r = RegEnumKeyW(key, index - machine_count, szKeyName, SQUISH_GUID_SIZE); + if( r == ERROR_SUCCESS ) + { + unsquash_guid(szKeyName, lpguid); + last_index = index; + RegCloseKey(key); + return ERROR_SUCCESS; + } + } + RegCloseKey(key); + + r = RegCreateKeyW(HKEY_CURRENT_USER, szUserProduct, &key); + if( r != ERROR_SUCCESS ) + return ERROR_NO_MORE_ITEMS; + + r = RegQueryInfoKeyW(key, NULL, NULL, NULL, &unmanaged_count, NULL, NULL, + NULL, NULL, NULL, NULL, NULL); + if( r != ERROR_SUCCESS ) + { + RegCloseKey(key); + return ERROR_NO_MORE_ITEMS; + } + + if (unmanaged_count && index <= machine_count + managed_count + unmanaged_count) + { + r = RegEnumKeyW(key, index - machine_count - managed_count, szKeyName, SQUISH_GUID_SIZE); + if( r == ERROR_SUCCESS ) + { + unsquash_guid(szKeyName, lpguid); + last_index = index; + RegCloseKey(key); + return ERROR_SUCCESS; + } + } + RegCloseKey(key); + + return ERROR_NO_MORE_ITEMS; }
UINT WINAPI MsiEnumFeaturesA(LPCSTR szProduct, DWORD index, diff --git a/dlls/msi/tests/automation.c b/dlls/msi/tests/automation.c index ca40f09..f9ab254 100644 --- a/dlls/msi/tests/automation.c +++ b/dlls/msi/tests/automation.c @@ -2022,7 +2022,7 @@ static void test_Installer_Products(BOOL bProductInstalled) } }
- if (bProductInstalled) todo_wine + if (bProductInstalled) { ok(bProductInstalled == bProductFound, "Product expected to %s installed but product code was %s\n", bProductInstalled ? "be" : "not be",