Commit 1f3d6a97 authored by James Hawkins's avatar James Hawkins Committed by Alexandre Julliard

msi: Reimplement MsiGetProductInfo.

parent 48236639
......@@ -564,115 +564,162 @@ done:
static UINT WINAPI MSI_GetProductInfo(LPCWSTR szProduct, LPCWSTR szAttribute,
awstring *szValue, LPDWORD pcchValueBuf)
{
UINT r;
HKEY hkey;
UINT r = ERROR_UNKNOWN_PROPERTY;
HKEY prodkey, userdata, source;
LPWSTR val = NULL;
WCHAR squished_pc[GUID_SIZE];
WCHAR packagecode[GUID_SIZE];
BOOL classes = FALSE;
BOOL badconfig = FALSE;
LONG res;
DWORD save;
static WCHAR empty[] = {0};
static const WCHAR sourcelist[] = {
'S','o','u','r','c','e','L','i','s','t',0};
static const WCHAR display_name[] = {
'D','i','s','p','l','a','y','N','a','m','e',0};
static const WCHAR display_version[] = {
'D','i','s','p','l','a','y','V','e','r','s','i','o','n',0};
static const WCHAR assignment[] = {
'A','s','s','i','g','n','m','e','n','t',0};
TRACE("%s %s %p %p\n", debugstr_w(szProduct),
debugstr_w(szAttribute), szValue, pcchValueBuf);
/*
* FIXME: Values seem scattered/duplicated in the registry. Is there a system?
*/
if ((szValue->str.w && !pcchValueBuf) || !szProduct || !szAttribute)
return ERROR_INVALID_PARAMETER;
if (!squash_guid(szProduct, squished_pc))
return ERROR_INVALID_PARAMETER;
/* check for special properties */
if (!lstrcmpW(szAttribute, INSTALLPROPERTY_PACKAGECODEW))
r = MSIREG_OpenLocalManagedProductKey(szProduct, &prodkey, FALSE);
if (r != ERROR_SUCCESS)
{
LPWSTR regval;
WCHAR packagecode[35];
r = MSIREG_OpenUserProductsKey(szProduct, &hkey, FALSE);
r = MSIREG_OpenUserProductsKey(szProduct, &prodkey, FALSE);
if (r != ERROR_SUCCESS)
return ERROR_UNKNOWN_PRODUCT;
regval = msi_reg_get_val_str( hkey, szAttribute );
if (regval)
{
if (unsquash_guid(regval, packagecode))
val = strdupW(packagecode);
msi_free(regval);
r = MSIREG_OpenLocalClassesProductKey(szProduct, &prodkey, FALSE);
if (r == ERROR_SUCCESS)
classes = TRUE;
}
RegCloseKey(hkey);
}
else if (!lstrcmpW(szAttribute, INSTALLPROPERTY_ASSIGNMENTTYPEW))
if (classes)
MSIREG_OpenLocalSystemProductKey(szProduct, &userdata, FALSE);
else
MSIREG_OpenInstallPropertiesKey(szProduct, &userdata, FALSE);
if (!lstrcmpW(szAttribute, INSTALLPROPERTY_HELPLINKW) ||
!lstrcmpW(szAttribute, INSTALLPROPERTY_HELPTELEPHONEW) ||
!lstrcmpW(szAttribute, INSTALLPROPERTY_INSTALLDATEW) ||
!lstrcmpW(szAttribute, INSTALLPROPERTY_INSTALLEDPRODUCTNAMEW) ||
!lstrcmpW(szAttribute, INSTALLPROPERTY_INSTALLLOCATIONW) ||
!lstrcmpW(szAttribute, INSTALLPROPERTY_INSTALLSOURCEW) ||
!lstrcmpW(szAttribute, INSTALLPROPERTY_LOCALPACKAGEW) ||
!lstrcmpW(szAttribute, INSTALLPROPERTY_PUBLISHERW) ||
!lstrcmpW(szAttribute, INSTALLPROPERTY_URLINFOABOUTW) ||
!lstrcmpW(szAttribute, INSTALLPROPERTY_URLUPDATEINFOW) ||
!lstrcmpW(szAttribute, INSTALLPROPERTY_VERSIONMINORW) ||
!lstrcmpW(szAttribute, INSTALLPROPERTY_VERSIONMAJORW) ||
!lstrcmpW(szAttribute, INSTALLPROPERTY_VERSIONSTRINGW) ||
!lstrcmpW(szAttribute, INSTALLPROPERTY_PRODUCTIDW) ||
!lstrcmpW(szAttribute, INSTALLPROPERTY_REGCOMPANYW) ||
!lstrcmpW(szAttribute, INSTALLPROPERTY_REGOWNERW))
{
if (!prodkey)
{
static const WCHAR one[] = { '1',0 };
/*
* FIXME: should be in the Product key (user or system?)
* but isn't written yet...
*/
val = strdupW( one );
r = ERROR_UNKNOWN_PRODUCT;
goto done;
}
else if (!lstrcmpW(szAttribute, INSTALLPROPERTY_LANGUAGEW) ||
!lstrcmpW(szAttribute, INSTALLPROPERTY_VERSIONW))
{
static const WCHAR fmt[] = { '%','u',0 };
WCHAR szVal[16];
DWORD regval;
r = MSIREG_OpenUninstallKey(szProduct, &hkey, FALSE);
if (r != ERROR_SUCCESS)
return ERROR_UNKNOWN_PRODUCT;
if (!userdata)
return ERROR_UNKNOWN_PROPERTY;
if (msi_reg_get_val_dword( hkey, szAttribute, &regval))
{
sprintfW(szVal, fmt, regval);
val = strdupW( szVal );
}
if (!lstrcmpW(szAttribute, INSTALLPROPERTY_INSTALLEDPRODUCTNAMEW))
szAttribute = display_name;
else if (!lstrcmpW(szAttribute, INSTALLPROPERTY_VERSIONSTRINGW))
szAttribute = display_version;
RegCloseKey(hkey);
val = msi_reg_get_val_str(userdata, szAttribute);
if (!val)
val = empty;
}
else if (!lstrcmpW(szAttribute, INSTALLPROPERTY_PRODUCTNAMEW))
else if (!lstrcmpW(szAttribute, INSTALLPROPERTY_INSTANCETYPEW) ||
!lstrcmpW(szAttribute, INSTALLPROPERTY_TRANSFORMSW) ||
!lstrcmpW(szAttribute, INSTALLPROPERTY_LANGUAGEW) ||
!lstrcmpW(szAttribute, INSTALLPROPERTY_PRODUCTNAMEW) ||
!lstrcmpW(szAttribute, INSTALLPROPERTY_ASSIGNMENTTYPEW) ||
!lstrcmpW(szAttribute, INSTALLPROPERTY_PACKAGECODEW) ||
!lstrcmpW(szAttribute, INSTALLPROPERTY_VERSIONW) ||
!lstrcmpW(szAttribute, INSTALLPROPERTY_PRODUCTICONW) ||
!lstrcmpW(szAttribute, INSTALLPROPERTY_PACKAGENAMEW) ||
!lstrcmpW(szAttribute, INSTALLPROPERTY_AUTHORIZED_LUA_APPW))
{
r = MSIREG_OpenUserProductsKey(szProduct, &hkey, FALSE);
if (r != ERROR_SUCCESS)
return ERROR_UNKNOWN_PRODUCT;
if (!prodkey)
{
r = ERROR_UNKNOWN_PRODUCT;
goto done;
}
val = msi_reg_get_val_str( hkey, szAttribute );
if (!lstrcmpW(szAttribute, INSTALLPROPERTY_ASSIGNMENTTYPEW))
szAttribute = assignment;
RegCloseKey(hkey);
}
else if (!szAttribute[0])
if (!lstrcmpW(szAttribute, INSTALLPROPERTY_PACKAGENAMEW))
{
return ERROR_UNKNOWN_PROPERTY;
res = RegOpenKeyW(prodkey, sourcelist, &source);
if (res == ERROR_SUCCESS)
val = msi_reg_get_val_str(source, szAttribute);
RegCloseKey(source);
}
else
{
static const WCHAR szDisplayVersion[] = {
'D','i','s','p','l','a','y','V','e','r','s','i','o','n',0 };
FIXME("%s\n", debugstr_w(szAttribute));
/* FIXME: some attribute values not tested... */
if (!lstrcmpW( szAttribute, INSTALLPROPERTY_VERSIONSTRINGW ))
szAttribute = szDisplayVersion;
r = MSIREG_OpenUninstallKey( szProduct, &hkey, FALSE );
if (r != ERROR_SUCCESS)
return ERROR_UNKNOWN_PRODUCT;
val = msi_reg_get_val_str(prodkey, szAttribute);
if (!val)
val = empty;
}
val = msi_reg_get_val_str( hkey, szAttribute );
if (val != empty && !lstrcmpW(szAttribute, INSTALLPROPERTY_PACKAGECODEW))
{
if (lstrlenW(val) != SQUISH_GUID_SIZE - 1)
badconfig = TRUE;
else
{
unsquash_guid(val, packagecode);
msi_free(val);
val = strdupW(packagecode);
}
}
}
RegCloseKey(hkey);
if (!val)
{
r = ERROR_UNKNOWN_PROPERTY;
goto done;
}
TRACE("returning %s\n", debugstr_w(val));
save = *pcchValueBuf;
if (!val)
return ERROR_UNKNOWN_PROPERTY;
if (lstrlenW(val) < *pcchValueBuf)
r = msi_strcpy_to_awstring(val, szValue, pcchValueBuf);
else if (szValue->str.a || szValue->str.w)
r = ERROR_MORE_DATA;
r = msi_strcpy_to_awstring( val, szValue, pcchValueBuf );
if (!badconfig)
*pcchValueBuf = lstrlenW(val);
else if (r == ERROR_SUCCESS)
{
*pcchValueBuf = save;
r = ERROR_BAD_CONFIGURATION;
}
if (val != empty)
msi_free(val);
done:
RegCloseKey(prodkey);
RegCloseKey(userdata);
return r;
}
......
......@@ -568,6 +568,7 @@ typedef struct tagMSISCRIPT
#define MSI_BUILDNUMBER 4000
#define GUID_SIZE 39
#define SQUISH_GUID_SIZE 33
#define MSIHANDLE_MAGIC 0x4d434923
......
......@@ -231,8 +231,6 @@ static const WCHAR szInstaller_LocalManagedProd_fmt[] = {
'I','n','s','t','a','l','l','e','r','\\',
'P','r','o','d','u','c','t','s','\\','%','s',0};
#define SQUISH_GUID_SIZE 33
BOOL unsquash_guid(LPCWSTR in, LPWSTR out)
{
DWORD i,n=0;
......
......@@ -2140,14 +2140,14 @@ static void test_Installer_InstallProduct(void)
/* Package name */
memset(szString, 0, sizeof(szString));
hr = Installer_ProductInfo(szProductCode, WINE_INSTALLPROPERTY_PACKAGENAMEW, szString);
todo_wine ok(hr == S_OK, "Installer_ProductInfo failed, hresult 0x%08x\n", hr);
ok(hr == S_OK, "Installer_ProductInfo failed, hresult 0x%08x\n", hr);
todo_wine ok_w2("Installer_ProductInfo returned %s but expected %s\n", szString, szMsifile);
/* Product name */
memset(szString, 0, sizeof(szString));
hr = Installer_ProductInfo(szProductCode, WINE_INSTALLPROPERTY_PRODUCTNAMEW, szString);
ok(hr == S_OK, "Installer_ProductInfo failed, hresult 0x%08x\n", hr);
ok_w2("Installer_ProductInfo returned %s but expected %s\n", szString, szMSITEST);
todo_wine ok_w2("Installer_ProductInfo returned %s but expected %s\n", szString, szMSITEST);
/* Installer::Products */
test_Installer_Products(TRUE);
......@@ -2249,6 +2249,11 @@ static void test_Installer_InstallProduct(void)
res = RegDeleteKeyA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Installer\\Products\\05FA3C1F65B896A40AC00077F34EF203");
todo_wine ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_SUCCESS, got %d\n", res);
res = delete_registry_key(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows\\"
"CurrentVersion\\Installer\\Managed\\S-1-5-4\\"
"Installer\\Products\\05FA3C1F65B896A40AC00077F34EF203");
ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
/* Delete installation files we installed */
delete_test_files();
}
......
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