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

msi: Reimplement MsiGetProductInfo.

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