static const WCHAR installerW[] = {'\\','I','n','s','t','a','l','l','e','r',0};
+static UINT msi_locate_product(LPCWSTR szProduct, MSIINSTALLCONTEXT *context)
+{
+ HKEY hkey = NULL;
+
+ *context = MSIINSTALLCONTEXT_NONE;
+
+ if (MSIREG_OpenProductKey(szProduct, NULL, MSIINSTALLCONTEXT_USERMANAGED,
+ &hkey, FALSE) == ERROR_SUCCESS)
+ *context = MSIINSTALLCONTEXT_USERMANAGED;
+ else if (MSIREG_OpenProductKey(szProduct, NULL, MSIINSTALLCONTEXT_MACHINE,
+ &hkey, FALSE) == ERROR_SUCCESS)
+ *context = MSIINSTALLCONTEXT_MACHINE;
+ else if (MSIREG_OpenProductKey(szProduct, NULL,
+ MSIINSTALLCONTEXT_USERUNMANAGED,
+ &hkey, FALSE) == ERROR_SUCCESS)
+ *context = MSIINSTALLCONTEXT_USERUNMANAGED;
+
+ RegCloseKey(hkey);
+
+ if (*context == MSIINSTALLCONTEXT_NONE)
+ return ERROR_UNKNOWN_PRODUCT;
+
+ return ERROR_SUCCESS;
+}
+
UINT WINAPI MsiOpenProductA(LPCSTR szProduct, MSIHANDLE *phProduct)
{
UINT r;
return r;
}
-static UINT MSI_OpenProductW( LPCWSTR szProduct, MSIPACKAGE **ppackage )
+static UINT MSI_OpenProductW(LPCWSTR szProduct, MSIPACKAGE **package)
{
- LPWSTR path = NULL;
UINT r;
- HKEY hKeyProduct = NULL;
- DWORD count, type;
+ HKEY props;
+ LPWSTR path;
+ MSIINSTALLCONTEXT context;
- TRACE("%s %p\n", debugstr_w(szProduct), ppackage );
+ static const WCHAR managed[] = {
+ 'M','a','n','a','g','e','d','L','o','c','a','l','P','a','c','k','a','g','e',0};
+ static const WCHAR local[] = {'L','o','c','a','l','P','a','c','k','a','g','e',0};
- r = MSIREG_OpenUninstallKey(szProduct,&hKeyProduct,FALSE);
- if( r != ERROR_SUCCESS )
- {
- r = ERROR_UNKNOWN_PRODUCT;
- goto end;
- }
+ TRACE("%s %p\n", debugstr_w(szProduct), package);
- /* find the size of the path */
- type = count = 0;
- r = RegQueryValueExW( hKeyProduct, INSTALLPROPERTY_LOCALPACKAGEW,
- NULL, &type, NULL, &count );
- if( r != ERROR_SUCCESS )
- {
- r = ERROR_UNKNOWN_PRODUCT;
- goto end;
- }
+ r = msi_locate_product(szProduct, &context);
+ if (r != ERROR_SUCCESS)
+ return r;
- /* now alloc and fetch the path of the database to open */
- path = msi_alloc( count );
- if( !path )
- goto end;
+ r = MSIREG_OpenInstallProps(szProduct, context, NULL, &props, FALSE);
+ if (r != ERROR_SUCCESS)
+ return ERROR_UNKNOWN_PRODUCT;
+
+ if (context == MSIINSTALLCONTEXT_USERMANAGED)
+ path = msi_reg_get_val_str(props, managed);
+ else
+ path = msi_reg_get_val_str(props, local);
- r = RegQueryValueExW( hKeyProduct, INSTALLPROPERTY_LOCALPACKAGEW,
- NULL, &type, (LPBYTE) path, &count );
- if( r != ERROR_SUCCESS )
+ r = ERROR_UNKNOWN_PRODUCT;
+
+ if (!path || GetFileAttributesW(path) == INVALID_FILE_ATTRIBUTES)
+ goto done;
+
+ if (PathIsRelativeW(path))
{
- r = ERROR_UNKNOWN_PRODUCT;
- goto end;
+ r = ERROR_INSTALL_PACKAGE_OPEN_FAILED;
+ goto done;
}
- r = MSI_OpenPackageW( path, ppackage );
-
-end:
- msi_free( path );
- if( hKeyProduct )
- RegCloseKey( hKeyProduct );
+ r = MSI_OpenPackageW(path, package);
+done:
+ RegCloseKey(props);
+ msi_free(path);
return r;
}
-UINT WINAPI MsiOpenProductW( LPCWSTR szProduct, MSIHANDLE *phProduct )
+UINT WINAPI MsiOpenProductW(LPCWSTR szProduct, MSIHANDLE *phProduct)
{
- MSIPACKAGE *package = NULL;
- UINT r;
+ MSIPACKAGE *package = NULL;
+ WCHAR squished_pc[GUID_SIZE];
+ UINT r;
- r = MSI_OpenProductW( szProduct, &package );
- if( r == ERROR_SUCCESS )
- {
- *phProduct = alloc_msihandle( &package->hdr );
- if (! *phProduct)
- r = ERROR_NOT_ENOUGH_MEMORY;
- msiobj_release( &package->hdr );
- }
- return r;
+ if (!szProduct || !squash_guid(szProduct, squished_pc))
+ return ERROR_INVALID_PARAMETER;
+
+ if (!phProduct)
+ return ERROR_INVALID_PARAMETER;
+
+ r = MSI_OpenProductW(szProduct, &package);
+ if (r != ERROR_SUCCESS)
+ return r;
+
+ *phProduct = alloc_msihandle(&package->hdr);
+ if (!*phProduct)
+ r = ERROR_NOT_ENOUGH_MEMORY;
+
+ msiobj_release(&package->hdr);
+ return r;
}
UINT WINAPI MsiAdvertiseProductA(LPCSTR szPackagePath, LPCSTR szScriptfilePath,
TRACE("%s %s\n",debugstr_w(szPackagePath), debugstr_w(szCommandLine));
+ if (!szPackagePath)
+ return ERROR_INVALID_PARAMETER;
+
+ if (!*szPackagePath)
+ return ERROR_PATH_NOT_FOUND;
+
r = MSI_OpenPackageW( szPackagePath, &package );
if (r == ERROR_SUCCESS)
{
UINT WINAPI MsiReinstallProductA(LPCSTR szProduct, DWORD dwReinstallMode)
{
- FIXME("%s %08x\n", debugstr_a(szProduct), dwReinstallMode);
- return ERROR_CALL_NOT_IMPLEMENTED;
+ LPWSTR wszProduct;
+ UINT rc;
+
+ TRACE("%s %08x\n", debugstr_a(szProduct), dwReinstallMode);
+
+ wszProduct = strdupAtoW(szProduct);
+
+ rc = MsiReinstallProductW(wszProduct, dwReinstallMode);
+
+ msi_free(wszProduct);
+ return rc;
}
UINT WINAPI MsiReinstallProductW(LPCWSTR szProduct, DWORD dwReinstallMode)
{
- FIXME("%s %08x\n", debugstr_w(szProduct), dwReinstallMode);
- return ERROR_CALL_NOT_IMPLEMENTED;
+ static const WCHAR szAll[] = {'A','L','L',0};
+
+ TRACE("%s %08x\n", debugstr_w(szProduct), dwReinstallMode);
+
+ return MsiReinstallFeatureW(szProduct, szAll, dwReinstallMode);
}
UINT WINAPI MsiApplyPatchA(LPCSTR szPatchPackage, LPCSTR szInstallPackage,
return r;
}
-UINT WINAPI MsiApplyPatchW(LPCWSTR szPatchPackage, LPCWSTR szInstallPackage,
- INSTALLTYPE eInstallType, LPCWSTR szCommandLine)
+static UINT MSI_ApplyPatchW(LPCWSTR szPatchPackage, LPCWSTR szProductCode, LPCWSTR szCommandLine)
{
- MSIHANDLE patch, info;
- UINT r, type;
+ MSIHANDLE patch = 0, info = 0;
+ UINT r = ERROR_SUCCESS, type;
DWORD size = 0;
LPCWSTR cmd_ptr = szCommandLine;
+ LPCWSTR product_code = szProductCode;
LPWSTR beg, end;
LPWSTR cmd = NULL, codes = NULL;
static const WCHAR patcheq[] = {'P','A','T','C','H','=',0};
static WCHAR empty[] = {0};
- TRACE("%s %s %d %s\n", debugstr_w(szPatchPackage), debugstr_w(szInstallPackage),
- eInstallType, debugstr_w(szCommandLine));
+ if (!szPatchPackage || !szPatchPackage[0])
+ return ERROR_INVALID_PARAMETER;
- if (szInstallPackage || eInstallType == INSTALLTYPE_NETWORK_IMAGE ||
- eInstallType == INSTALLTYPE_SINGLE_INSTANCE)
+ if (!szProductCode)
{
- FIXME("Only reading target products from patch\n");
- return ERROR_CALL_NOT_IMPLEMENTED;
- }
+ r = MsiOpenDatabaseW(szPatchPackage, MSIDBOPEN_READONLY, &patch);
+ if (r != ERROR_SUCCESS)
+ return r;
- r = MsiOpenDatabaseW(szPatchPackage, MSIDBOPEN_READONLY, &patch);
- if (r != ERROR_SUCCESS)
- return r;
+ r = MsiGetSummaryInformationW(patch, NULL, 0, &info);
+ if (r != ERROR_SUCCESS)
+ goto done;
- r = MsiGetSummaryInformationW(patch, NULL, 0, &info);
- if (r != ERROR_SUCCESS)
- goto done;
+ r = MsiSummaryInfoGetPropertyW(info, PID_TEMPLATE, &type, NULL, NULL, empty, &size);
+ if (r != ERROR_MORE_DATA || !size || type != VT_LPSTR)
+ {
+ ERR("Failed to read product codes from patch\n");
+ goto done;
+ }
- r = MsiSummaryInfoGetPropertyW(info, PID_TEMPLATE, &type, NULL, NULL, empty, &size);
- if (r != ERROR_MORE_DATA || !size || type != VT_LPSTR)
- {
- ERR("Failed to read product codes from patch\n");
- goto done;
- }
+ codes = msi_alloc(++size * sizeof(WCHAR));
+ if (!codes)
+ {
+ r = ERROR_OUTOFMEMORY;
+ goto done;
+ }
- codes = msi_alloc(++size * sizeof(WCHAR));
- if (!codes)
- {
- r = ERROR_OUTOFMEMORY;
- goto done;
- }
+ r = MsiSummaryInfoGetPropertyW(info, PID_TEMPLATE, &type, NULL, NULL, codes, &size);
+ if (r != ERROR_SUCCESS)
+ goto done;
- r = MsiSummaryInfoGetPropertyW(info, PID_TEMPLATE, &type, NULL, NULL, codes, &size);
- if (r != ERROR_SUCCESS)
- goto done;
+ product_code = codes;
+ }
if (!szCommandLine)
cmd_ptr = empty;
return r;
}
+UINT WINAPI MsiApplyPatchW(LPCWSTR szPatchPackage, LPCWSTR szInstallPackage,
+ INSTALLTYPE eInstallType, LPCWSTR szCommandLine)
+{
+ TRACE("%s %s %d %s\n", debugstr_w(szPatchPackage), debugstr_w(szInstallPackage),
+ eInstallType, debugstr_w(szCommandLine));
+
+ if (szInstallPackage || eInstallType == INSTALLTYPE_NETWORK_IMAGE ||
+ eInstallType == INSTALLTYPE_SINGLE_INSTANCE)
+ {
+ FIXME("Only reading target products from patch\n");
+ return ERROR_CALL_NOT_IMPLEMENTED;
+ }
+
+ return MSI_ApplyPatchW(szPatchPackage, NULL, szCommandLine);
+}
+
+UINT WINAPI MsiApplyMultiplePatchesA(LPCSTR szPatchPackages,
+ LPCSTR szProductCode, LPCSTR szPropertiesList)
+{
+ LPWSTR patch_packages = NULL;
+ LPWSTR product_code = NULL;
+ LPWSTR properties_list = NULL;
+ UINT r = ERROR_OUTOFMEMORY;
+
+ TRACE("%s %s %s\n", debugstr_a(szPatchPackages), debugstr_a(szProductCode),
+ debugstr_a(szPropertiesList));
+
+ if (!szPatchPackages || !szPatchPackages[0])
+ return ERROR_INVALID_PARAMETER;
+
+ if (!(patch_packages = strdupAtoW(szPatchPackages)))
+ return ERROR_OUTOFMEMORY;
+
+ if (szProductCode && !(product_code = strdupAtoW(szProductCode)))
+ goto done;
+
+ if (szPropertiesList && !(properties_list = strdupAtoW(szPropertiesList)))
+ goto done;
+
+ r = MsiApplyMultiplePatchesW(patch_packages, product_code, properties_list);
+
+done:
+ msi_free(patch_packages);
+ msi_free(product_code);
+ msi_free(properties_list);
+
+ return r;
+}
+
+UINT WINAPI MsiApplyMultiplePatchesW(LPCWSTR szPatchPackages,
+ LPCWSTR szProductCode, LPCWSTR szPropertiesList)
+{
+ UINT r = ERROR_SUCCESS;
+ LPCWSTR beg, end;
+
+ TRACE("%s %s %s\n", debugstr_w(szPatchPackages), debugstr_w(szProductCode),
+ debugstr_w(szPropertiesList));
+
+ if (!szPatchPackages || !szPatchPackages[0])
+ return ERROR_INVALID_PARAMETER;
+
+ beg = end = szPatchPackages;
+ while (*beg)
+ {
+ DWORD len;
+ LPWSTR patch;
+
+ while (*beg == ' ') beg++;
+ while (*end && *end != ';') end++;
+
+ len = end - beg;
+ while (len && beg[len - 1] == ' ') len--;
+
+ if (!len) return ERROR_INVALID_NAME;
+
+ patch = msi_alloc((len + 1) * sizeof(WCHAR));
+ if (!patch)
+ return ERROR_OUTOFMEMORY;
+
+ memcpy(patch, beg, len * sizeof(WCHAR));
+ patch[len] = '\0';
+
+ r = MSI_ApplyPatchW(patch, szProductCode, szPropertiesList);
+ msi_free(patch);
+
+ if (r != ERROR_SUCCESS)
+ break;
+
+ beg = ++end;
+ }
+ return r;
+}
+
+UINT WINAPI MsiDetermineApplicablePatchesA(LPCSTR szProductPackagePath,
+ DWORD cPatchInfo, PMSIPATCHSEQUENCEINFOA pPatchInfo)
+{
+ FIXME("(%s, %d, %p): stub!\n", debugstr_a(szProductPackagePath),
+ cPatchInfo, pPatchInfo);
+
+ return ERROR_CALL_NOT_IMPLEMENTED;
+}
+
+static UINT MSI_ApplicablePatchW( MSIPACKAGE *package, LPCWSTR patch )
+{
+ MSISUMMARYINFO *si;
+ MSIDATABASE *patch_db;
+ UINT r = ERROR_SUCCESS;
+
+ r = MSI_OpenDatabaseW( patch, MSIDBOPEN_READONLY, &patch_db );
+ if (r != ERROR_SUCCESS)
+ {
+ WARN("failed to open patch file %s\n", debugstr_w(patch));
+ return r;
+ }
+
+ si = MSI_GetSummaryInformationW( patch_db->storage, 0 );
+ if (!si)
+ {
+ r = ERROR_FUNCTION_FAILED;
+ goto done;
+ }
+
+ r = msi_check_patch_applicable( package, si );
+ if (r != ERROR_SUCCESS)
+ TRACE("patch not applicable\n");
+
+done:
+ msiobj_release( &patch_db->hdr );
+ msiobj_release( &si->hdr );
+ return r;
+}
+
+UINT WINAPI MsiDetermineApplicablePatchesW(LPCWSTR szProductPackagePath,
+ DWORD cPatchInfo, PMSIPATCHSEQUENCEINFOW pPatchInfo)
+{
+ UINT i, r, ret = ERROR_FUNCTION_FAILED;
+ MSIPACKAGE *package;
+
+ TRACE("(%s, %d, %p)\n", debugstr_w(szProductPackagePath), cPatchInfo, pPatchInfo);
+
+ r = MSI_OpenPackageW( szProductPackagePath, &package );
+ if (r != ERROR_SUCCESS)
+ {
+ ERR("failed to open package %u\n", r);
+ return r;
+ }
+
+ for (i = 0; i < cPatchInfo; i++)
+ {
+ switch (pPatchInfo[i].ePatchDataType)
+ {
+ case MSIPATCH_DATATYPE_PATCHFILE:
+ {
+ FIXME("patch ordering not supported\n");
+ r = MSI_ApplicablePatchW( package, pPatchInfo[i].szPatchData );
+ if (r != ERROR_SUCCESS)
+ {
+ pPatchInfo[i].dwOrder = ~0u;
+ pPatchInfo[i].uStatus = ERROR_PATCH_TARGET_NOT_FOUND;
+ }
+ else
+ {
+ pPatchInfo[i].dwOrder = i;
+ pPatchInfo[i].uStatus = ret = ERROR_SUCCESS;
+ }
+ break;
+ }
+ default:
+ {
+ FIXME("patch data type %u not supported\n", pPatchInfo[i].ePatchDataType);
+ pPatchInfo[i].dwOrder = ~0u;
+ pPatchInfo[i].uStatus = ERROR_PATCH_TARGET_NOT_FOUND;
+ break;
+ }
+ }
+
+ TRACE(" szPatchData: %s\n", debugstr_w(pPatchInfo[i].szPatchData));
+ TRACE("ePatchDataType: %u\n", pPatchInfo[i].ePatchDataType);
+ TRACE(" dwOrder: %u\n", pPatchInfo[i].dwOrder);
+ TRACE(" uStatus: %u\n", pPatchInfo[i].uStatus);
+ }
+ return ret;
+}
+
+UINT WINAPI MsiDeterminePatchSequenceA(LPCSTR szProductCode, LPCSTR szUserSid,
+ MSIINSTALLCONTEXT dwContext, DWORD cPatchInfo, PMSIPATCHSEQUENCEINFOA pPatchInfo)
+{
+ FIXME("(%s, %s, %d, %d, %p): stub!\n", debugstr_a(szProductCode),
+ debugstr_a(szUserSid), dwContext, cPatchInfo, pPatchInfo);
+
+ return ERROR_CALL_NOT_IMPLEMENTED;
+}
+
+UINT WINAPI MsiDeterminePatchSequenceW(LPCWSTR szProductCode, LPCWSTR szUserSid,
+ MSIINSTALLCONTEXT dwContext, DWORD cPatchInfo, PMSIPATCHSEQUENCEINFOW pPatchInfo)
+{
+ FIXME("(%s, %s, %d, %d, %p): stub!\n", debugstr_w(szProductCode),
+ debugstr_w(szUserSid), dwContext, cPatchInfo, pPatchInfo);
+
+ return ERROR_CALL_NOT_IMPLEMENTED;
+}
+
+static UINT msi_open_package(LPCWSTR product, MSIINSTALLCONTEXT context,
+ MSIPACKAGE **package)
+{
+ UINT r;
+ DWORD sz;
+ HKEY props;
+ LPWSTR localpack;
+ WCHAR sourcepath[MAX_PATH];
+ WCHAR filename[MAX_PATH];
+
+ static const WCHAR szLocalPackage[] = {
+ 'L','o','c','a','l','P','a','c','k','a','g','e',0};
+
+
+ r = MSIREG_OpenInstallProps(product, context, NULL, &props, FALSE);
+ if (r != ERROR_SUCCESS)
+ return ERROR_BAD_CONFIGURATION;
+
+ localpack = msi_reg_get_val_str(props, szLocalPackage);
+ if (localpack)
+ {
+ lstrcpyW(sourcepath, localpack);
+ msi_free(localpack);
+ }
+
+ if (!localpack || GetFileAttributesW(sourcepath) == INVALID_FILE_ATTRIBUTES)
+ {
+ sz = sizeof(sourcepath);
+ MsiSourceListGetInfoW(product, NULL, context, MSICODE_PRODUCT,
+ INSTALLPROPERTY_LASTUSEDSOURCEW, sourcepath, &sz);
+
+ sz = sizeof(filename);
+ MsiSourceListGetInfoW(product, NULL, context, MSICODE_PRODUCT,
+ INSTALLPROPERTY_PACKAGENAMEW, filename, &sz);
+
+ lstrcatW(sourcepath, filename);
+ }
+
+ if (GetFileAttributesW(sourcepath) == INVALID_FILE_ATTRIBUTES)
+ return ERROR_INSTALL_SOURCE_ABSENT;
+
+ return MSI_OpenPackageW(sourcepath, package);
+}
+
UINT WINAPI MsiConfigureProductExW(LPCWSTR szProduct, int iInstallLevel,
INSTALLSTATE eInstallState, LPCWSTR szCommandLine)
{
MSIPACKAGE* package = NULL;
+ MSIINSTALLCONTEXT context;
UINT r;
DWORD sz;
- WCHAR sourcepath[MAX_PATH];
- WCHAR filename[MAX_PATH];
+ WCHAR sourcepath[MAX_PATH], filename[MAX_PATH];
+ LPWSTR commandline;
+
static const WCHAR szInstalled[] = {
' ','I','n','s','t','a','l','l','e','d','=','1',0};
- LPWSTR commandline;
+ static const WCHAR szRemoveAll[] = {
+ ' ','R','E','M','O','V','E','=','A','L','L',0};
+ static const WCHAR szMachine[] = {
+ ' ','A','L','L','U','S','E','R','S','=','1',0};
TRACE("%s %d %d %s\n",debugstr_w(szProduct), iInstallLevel, eInstallState,
debugstr_w(szCommandLine));
- if (eInstallState != INSTALLSTATE_LOCAL &&
- eInstallState != INSTALLSTATE_DEFAULT)
+ if (!szProduct || lstrlenW(szProduct) != GUID_SIZE - 1)
+ return ERROR_INVALID_PARAMETER;
+
+ if (eInstallState == INSTALLSTATE_ADVERTISED ||
+ eInstallState == INSTALLSTATE_SOURCE)
{
- FIXME("Not implemented for anything other than local installs\n");
+ FIXME("State %d not implemented\n", eInstallState);
return ERROR_CALL_NOT_IMPLEMENTED;
}
- sz = sizeof(sourcepath);
- MsiSourceListGetInfoW(szProduct, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
- MSICODE_PRODUCT, INSTALLPROPERTY_LASTUSEDSOURCEW, sourcepath,
- &sz);
-
- sz = sizeof(filename);
- MsiSourceListGetInfoW(szProduct, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
- MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAMEW, filename, &sz);
-
- lstrcatW(sourcepath,filename);
-
- /*
- * ok 1, we need to find the msi file for this product.
- * 2, find the source dir for the files
- * 3, do the configure/install.
- * 4, cleanupany runonce entry.
- */
+ r = msi_locate_product(szProduct, &context);
+ if (r != ERROR_SUCCESS)
+ return r;
- r = MSI_OpenProductW( szProduct, &package );
+ r = msi_open_package(szProduct, context, &package);
if (r != ERROR_SUCCESS)
return r;
if (szCommandLine)
sz += lstrlenW(szCommandLine);
+ if (eInstallState == INSTALLSTATE_ABSENT)
+ sz += lstrlenW(szRemoveAll);
+
+ if (context == MSIINSTALLCONTEXT_MACHINE)
+ sz += lstrlenW(szMachine);
+
commandline = msi_alloc(sz * sizeof(WCHAR));
- if (!commandline )
+ if (!commandline)
{
r = ERROR_OUTOFMEMORY;
goto end;
if (szCommandLine)
lstrcpyW(commandline,szCommandLine);
- if (MsiQueryProductStateW(szProduct) != INSTALLSTATE_UNKNOWN)
- lstrcatW(commandline,szInstalled);
+ if (eInstallState == INSTALLSTATE_ABSENT)
+ lstrcatW(commandline, szRemoveAll);
+
+ if (context == MSIINSTALLCONTEXT_MACHINE)
+ lstrcatW(commandline, szMachine);
+
+ sz = sizeof(sourcepath);
+ MsiSourceListGetInfoW(szProduct, NULL, context, MSICODE_PRODUCT,
+ INSTALLPROPERTY_LASTUSEDSOURCEW, sourcepath, &sz);
+
+ sz = sizeof(filename);
+ MsiSourceListGetInfoW(szProduct, NULL, context, MSICODE_PRODUCT,
+ INSTALLPROPERTY_PACKAGENAMEW, filename, &sz);
+
+ strcatW(sourcepath, filename);
r = MSI_InstallPackage( package, sourcepath, commandline );
if (!squash_guid(szComponent, squished_comp))
return ERROR_INVALID_PARAMETER;
- if (MSIREG_OpenUserDataComponentKey(szComponent, &compkey, FALSE) != ERROR_SUCCESS &&
- MSIREG_OpenLocalSystemComponentKey(szComponent, &compkey, FALSE) != ERROR_SUCCESS)
+ if (MSIREG_OpenUserDataComponentKey(szComponent, NULL, &compkey, FALSE) != ERROR_SUCCESS &&
+ MSIREG_OpenUserDataComponentKey(szComponent, szLocalSid, &compkey, FALSE) != ERROR_SUCCESS)
{
return ERROR_UNKNOWN_COMPONENT;
}
sz = GUID_SIZE;
unsquash_guid(squished_prod, szBuffer);
- if (MSIREG_OpenLocalManagedProductKey(szBuffer, &prodkey, FALSE) == ERROR_SUCCESS ||
- MSIREG_OpenUserProductsKey(szBuffer, &prodkey, FALSE) == ERROR_SUCCESS ||
- MSIREG_OpenLocalClassesProductKey(szBuffer, &prodkey, FALSE) == ERROR_SUCCESS)
+ if (MSIREG_OpenProductKey(szBuffer, NULL,
+ MSIINSTALLCONTEXT_USERMANAGED,
+ &prodkey, FALSE) == ERROR_SUCCESS ||
+ MSIREG_OpenProductKey(szBuffer, NULL,
+ MSIINSTALLCONTEXT_USERUNMANAGED,
+ &prodkey, FALSE) == ERROR_SUCCESS ||
+ MSIREG_OpenProductKey(szBuffer, NULL,
+ MSIINSTALLCONTEXT_MACHINE,
+ &prodkey, FALSE) == ERROR_SUCCESS)
{
RegCloseKey(prodkey);
rc = ERROR_SUCCESS;
return strdupW(temp);
}
-static UINT WINAPI MSI_GetProductInfo(LPCWSTR szProduct, LPCWSTR szAttribute,
- awstring *szValue, LPDWORD pcchValueBuf)
+static UINT MSI_GetProductInfo(LPCWSTR szProduct, LPCWSTR szAttribute,
+ awstring *szValue, LPDWORD pcchValueBuf)
{
+ MSIINSTALLCONTEXT context = MSIINSTALLCONTEXT_USERUNMANAGED;
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, type = REG_NONE;
if (!squash_guid(szProduct, squished_pc))
return ERROR_INVALID_PARAMETER;
- r = MSIREG_OpenLocalManagedProductKey(szProduct, &prodkey, FALSE);
- if (r != ERROR_SUCCESS)
+ if ((r = MSIREG_OpenProductKey(szProduct, NULL,
+ MSIINSTALLCONTEXT_USERMANAGED,
+ &prodkey, FALSE)) != ERROR_SUCCESS &&
+ (r = MSIREG_OpenProductKey(szProduct, NULL,
+ MSIINSTALLCONTEXT_USERUNMANAGED,
+ &prodkey, FALSE)) != ERROR_SUCCESS &&
+ (r = MSIREG_OpenProductKey(szProduct, NULL,
+ MSIINSTALLCONTEXT_MACHINE,
+ &prodkey, FALSE)) == ERROR_SUCCESS)
{
- r = MSIREG_OpenUserProductsKey(szProduct, &prodkey, FALSE);
- if (r != ERROR_SUCCESS)
- {
- r = MSIREG_OpenLocalClassesProductKey(szProduct, &prodkey, FALSE);
- if (r == ERROR_SUCCESS)
- classes = TRUE;
- }
+ context = MSIINSTALLCONTEXT_MACHINE;
}
- if (classes)
- MSIREG_OpenLocalSystemProductKey(szProduct, &userdata, FALSE);
- else
- MSIREG_OpenCurrentUserInstallProps(szProduct, &userdata, FALSE);
+ MSIREG_OpenInstallProps(szProduct, context, NULL, &userdata, FALSE);
if (!lstrcmpW(szAttribute, INSTALLPROPERTY_HELPLINKW) ||
!lstrcmpW(szAttribute, INSTALLPROPERTY_HELPTELEPHONEW) ||
if (!lstrcmpW(szAttribute, INSTALLPROPERTY_PACKAGENAMEW))
{
res = RegOpenKeyW(prodkey, sourcelist, &source);
- if (res == ERROR_SUCCESS)
- val = msi_reg_get_value(source, szAttribute, &type);
+ if (res != ERROR_SUCCESS)
+ {
+ r = ERROR_UNKNOWN_PRODUCT;
+ goto done;
+ }
+
+ val = msi_reg_get_value(source, szAttribute, &type);
+ if (!val)
+ val = empty;
RegCloseKey(source);
}
{
save = *pcchValueBuf;
- if (lstrlenW(val) < *pcchValueBuf)
+ if (strlenW(val) < *pcchValueBuf)
r = msi_strcpy_to_awstring(val, szValue, pcchValueBuf);
else if (szValue->str.a || szValue->str.w)
r = ERROR_MORE_DATA;
if (out)
{
- if (lstrlenW(val) >= *size)
+ if (strlenW(val) >= *size)
{
r = ERROR_MORE_DATA;
if (*size > 0)
if (dwContext == MSIINSTALLCONTEXT_MACHINE && szUserSid)
return ERROR_INVALID_PARAMETER;
- MSIREG_OpenLocalManagedProductKey(szProductCode, &managed, FALSE);
- MSIREG_OpenUserProductsKey(szProductCode, &prod, FALSE);
+ /* FIXME: dwContext is provided, no need to search for it */
+ MSIREG_OpenProductKey(szProductCode, NULL,MSIINSTALLCONTEXT_USERMANAGED,
+ &managed, FALSE);
+ MSIREG_OpenProductKey(szProductCode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
+ &prod, FALSE);
+
+ MSIREG_OpenInstallProps(szProductCode, dwContext, NULL, &props, FALSE);
if (dwContext == MSIINSTALLCONTEXT_USERUNMANAGED)
{
package = INSTALLPROPERTY_LOCALPACKAGEW;
- MSIREG_OpenCurrentUserInstallProps(szProductCode, &props, FALSE);
if (!props && !prod)
goto done;
else if (dwContext == MSIINSTALLCONTEXT_USERMANAGED)
{
package = managed_local_package;
- MSIREG_OpenCurrentUserInstallProps(szProductCode, &props, FALSE);
if (!props && !managed)
goto done;
else if (dwContext == MSIINSTALLCONTEXT_MACHINE)
{
package = INSTALLPROPERTY_LOCALPACKAGEW;
- MSIREG_OpenLocalSystemProductKey(szProductCode, &props, FALSE);
- MSIREG_OpenLocalClassesProductKey(szProductCode, &classes, FALSE);
+ MSIREG_OpenProductKey(szProductCode, NULL, dwContext, &classes, FALSE);
if (!props && !classes)
goto done;
if (!val)
val = strdupW(empty);
- r = msi_copy_outval(val, szValue, pcchValue);
- }
- else if (!lstrcmpW(szProperty, INSTALLPROPERTY_TRANSFORMSW) ||
- !lstrcmpW(szProperty, INSTALLPROPERTY_LANGUAGEW) ||
- !lstrcmpW(szProperty, INSTALLPROPERTY_PRODUCTNAMEW) ||
- !lstrcmpW(szProperty, INSTALLPROPERTY_PACKAGECODEW) ||
- !lstrcmpW(szProperty, INSTALLPROPERTY_VERSIONW) ||
- !lstrcmpW(szProperty, INSTALLPROPERTY_PRODUCTICONW) ||
- !lstrcmpW(szProperty, INSTALLPROPERTY_PACKAGENAMEW) ||
- !lstrcmpW(szProperty, INSTALLPROPERTY_AUTHORIZED_LUA_APPW))
+ r = msi_copy_outval(val, szValue, pcchValue);
+ }
+ else if (!lstrcmpW(szProperty, INSTALLPROPERTY_TRANSFORMSW) ||
+ !lstrcmpW(szProperty, INSTALLPROPERTY_LANGUAGEW) ||
+ !lstrcmpW(szProperty, INSTALLPROPERTY_PRODUCTNAMEW) ||
+ !lstrcmpW(szProperty, INSTALLPROPERTY_PACKAGECODEW) ||
+ !lstrcmpW(szProperty, INSTALLPROPERTY_VERSIONW) ||
+ !lstrcmpW(szProperty, INSTALLPROPERTY_PRODUCTICONW) ||
+ !lstrcmpW(szProperty, INSTALLPROPERTY_PACKAGENAMEW) ||
+ !lstrcmpW(szProperty, INSTALLPROPERTY_AUTHORIZED_LUA_APPW))
+ {
+ if (!prod && !classes)
+ goto done;
+
+ if (dwContext == MSIINSTALLCONTEXT_USERUNMANAGED)
+ hkey = prod;
+ else if (dwContext == MSIINSTALLCONTEXT_USERMANAGED)
+ hkey = managed;
+ else if (dwContext == MSIINSTALLCONTEXT_MACHINE)
+ hkey = classes;
+
+ val = msi_reg_get_value(hkey, szProperty, &type);
+ if (!val)
+ val = strdupW(empty);
+
+ r = msi_copy_outval(val, szValue, pcchValue);
+ }
+ else if (!lstrcmpW(szProperty, INSTALLPROPERTY_PRODUCTSTATEW))
+ {
+ if (dwContext == MSIINSTALLCONTEXT_MACHINE)
+ {
+ if (props)
+ {
+ val = msi_reg_get_value(props, package, &type);
+ if (!val)
+ goto done;
+
+ msi_free(val);
+ val = strdupW(five);
+ }
+ else
+ val = strdupW(one);
+
+ r = msi_copy_outval(val, szValue, pcchValue);
+ goto done;
+ }
+ else if (props && (val = msi_reg_get_value(props, package, &type)))
+ {
+ msi_free(val);
+ val = strdupW(five);
+ r = msi_copy_outval(val, szValue, pcchValue);
+ goto done;
+ }
+
+ if (prod || managed)
+ val = strdupW(one);
+ else
+ goto done;
+
+ r = msi_copy_outval(val, szValue, pcchValue);
+ }
+ else if (!lstrcmpW(szProperty, INSTALLPROPERTY_ASSIGNMENTTYPEW))
+ {
+ if (!prod && !classes)
+ goto done;
+
+ /* FIXME */
+ val = strdupW(empty);
+ r = msi_copy_outval(val, szValue, pcchValue);
+ }
+ else
+ r = ERROR_UNKNOWN_PROPERTY;
+
+done:
+ RegCloseKey(props);
+ RegCloseKey(prod);
+ RegCloseKey(managed);
+ RegCloseKey(classes);
+ msi_free(val);
+
+ return r;
+}
+
+UINT WINAPI MsiGetPatchInfoExA(LPCSTR szPatchCode, LPCSTR szProductCode,
+ LPCSTR szUserSid, MSIINSTALLCONTEXT dwContext,
+ LPCSTR szProperty, LPSTR lpValue, DWORD *pcchValue)
+{
+ LPWSTR patch = NULL, product = NULL, usersid = NULL;
+ LPWSTR property = NULL, val = NULL;
+ DWORD len;
+ UINT r;
+
+ TRACE("(%s, %s, %s, %d, %s, %p, %p)\n", debugstr_a(szPatchCode),
+ debugstr_a(szProductCode), debugstr_a(szUserSid), dwContext,
+ debugstr_a(szProperty), lpValue, pcchValue);
+
+ if (lpValue && !pcchValue)
+ return ERROR_INVALID_PARAMETER;
+
+ if (szPatchCode) patch = strdupAtoW(szPatchCode);
+ if (szProductCode) product = strdupAtoW(szProductCode);
+ if (szUserSid) usersid = strdupAtoW(szUserSid);
+ if (szProperty) property = strdupAtoW(szProperty);
+
+ len = 0;
+ r = MsiGetPatchInfoExW(patch, product, usersid, dwContext, property,
+ NULL, &len);
+ if (r != ERROR_SUCCESS)
+ goto done;
+
+ val = msi_alloc(++len * sizeof(WCHAR));
+ if (!val)
+ {
+ r = ERROR_OUTOFMEMORY;
+ goto done;
+ }
+
+ r = MsiGetPatchInfoExW(patch, product, usersid, dwContext, property,
+ val, &len);
+ if (r != ERROR_SUCCESS || !pcchValue)
+ goto done;
+
+ if (lpValue)
+ WideCharToMultiByte(CP_ACP, 0, val, -1, lpValue,
+ *pcchValue - 1, NULL, NULL);
+
+ len = lstrlenW(val);
+ if ((*val && *pcchValue < len + 1) || !lpValue)
+ {
+ if (lpValue)
+ {
+ r = ERROR_MORE_DATA;
+ lpValue[*pcchValue - 1] = '\0';
+ }
+
+ *pcchValue = len * sizeof(WCHAR);
+ }
+ else
+ *pcchValue = len;
+
+done:
+ msi_free(val);
+ msi_free(patch);
+ msi_free(product);
+ msi_free(usersid);
+ msi_free(property);
+
+ return r;
+}
+
+UINT WINAPI MsiGetPatchInfoExW(LPCWSTR szPatchCode, LPCWSTR szProductCode,
+ LPCWSTR szUserSid, MSIINSTALLCONTEXT dwContext,
+ LPCWSTR szProperty, LPWSTR lpValue, DWORD *pcchValue)
+{
+ WCHAR squished_pc[GUID_SIZE];
+ WCHAR squished_patch[GUID_SIZE];
+ HKEY udprod = 0, prod = 0, props = 0;
+ HKEY patch = 0, patches = 0;
+ HKEY udpatch = 0, datakey = 0;
+ HKEY prodpatches = 0;
+ LPWSTR val = NULL;
+ UINT r = ERROR_UNKNOWN_PRODUCT;
+ DWORD len;
+ LONG res;
+
+ static const WCHAR szEmpty[] = {0};
+ static const WCHAR szPatches[] = {'P','a','t','c','h','e','s',0};
+ static const WCHAR szInstalled[] = {'I','n','s','t','a','l','l','e','d',0};
+ static const WCHAR szManagedPackage[] = {'M','a','n','a','g','e','d',
+ 'L','o','c','a','l','P','a','c','k','a','g','e',0};
+
+ TRACE("(%s, %s, %s, %d, %s, %p, %p)\n", debugstr_w(szPatchCode),
+ debugstr_w(szProductCode), debugstr_w(szUserSid), dwContext,
+ debugstr_w(szProperty), lpValue, pcchValue);
+
+ if (!szProductCode || !squash_guid(szProductCode, squished_pc))
+ return ERROR_INVALID_PARAMETER;
+
+ if (!szPatchCode || !squash_guid(szPatchCode, squished_patch))
+ return ERROR_INVALID_PARAMETER;
+
+ if (!szProperty)
+ return ERROR_INVALID_PARAMETER;
+
+ if (lpValue && !pcchValue)
+ return ERROR_INVALID_PARAMETER;
+
+ if (dwContext != MSIINSTALLCONTEXT_USERMANAGED &&
+ dwContext != MSIINSTALLCONTEXT_USERUNMANAGED &&
+ dwContext != MSIINSTALLCONTEXT_MACHINE)
+ return ERROR_INVALID_PARAMETER;
+
+ if (dwContext == MSIINSTALLCONTEXT_MACHINE && szUserSid)
+ return ERROR_INVALID_PARAMETER;
+
+ if (!lstrcmpW(szUserSid, szLocalSid))
+ return ERROR_INVALID_PARAMETER;
+
+ if (MSIREG_OpenUserDataProductKey(szProductCode, dwContext, NULL,
+ &udprod, FALSE) != ERROR_SUCCESS)
+ goto done;
+
+ if (MSIREG_OpenInstallProps(szProductCode, dwContext, NULL,
+ &props, FALSE) != ERROR_SUCCESS)
+ goto done;
+
+ r = ERROR_UNKNOWN_PATCH;
+
+ res = RegOpenKeyExW(udprod, szPatches, 0, KEY_READ, &patches);
+ if (res != ERROR_SUCCESS)
+ goto done;
+
+ res = RegOpenKeyExW(patches, squished_patch, 0, KEY_READ, &patch);
+ if (res != ERROR_SUCCESS)
+ goto done;
+
+ if (!lstrcmpW(szProperty, INSTALLPROPERTY_TRANSFORMSW))
{
- if (!prod && !classes)
+ if (MSIREG_OpenProductKey(szProductCode, NULL, dwContext,
+ &prod, FALSE) != ERROR_SUCCESS)
goto done;
- if (dwContext == MSIINSTALLCONTEXT_USERUNMANAGED)
- hkey = prod;
- else if (dwContext == MSIINSTALLCONTEXT_USERMANAGED)
- hkey = managed;
- else if (dwContext == MSIINSTALLCONTEXT_MACHINE)
- hkey = classes;
-
- val = msi_reg_get_value(hkey, szProperty, &type);
- if (!val)
- val = strdupW(empty);
+ res = RegOpenKeyExW(prod, szPatches, 0, KEY_ALL_ACCESS, &prodpatches);
+ if (res != ERROR_SUCCESS)
+ goto done;
- r = msi_copy_outval(val, szValue, pcchValue);
+ datakey = prodpatches;
+ szProperty = squished_patch;
}
- else if (!lstrcmpW(szProperty, INSTALLPROPERTY_PRODUCTSTATEW))
+ else
{
- if (dwContext == MSIINSTALLCONTEXT_MACHINE)
- {
- if (props)
- {
- val = msi_reg_get_value(props, package, &type);
- if (!val)
- goto done;
-
- msi_free(val);
- val = strdupW(five);
- }
- else
- val = strdupW(one);
-
- r = msi_copy_outval(val, szValue, pcchValue);
+ if (MSIREG_OpenUserDataPatchKey(szPatchCode, dwContext,
+ &udpatch, FALSE) != ERROR_SUCCESS)
goto done;
+
+ if (!lstrcmpW(szProperty, INSTALLPROPERTY_LOCALPACKAGEW))
+ {
+ if (dwContext == MSIINSTALLCONTEXT_USERMANAGED)
+ szProperty = szManagedPackage;
+ datakey = udpatch;
}
- else if (props && (val = msi_reg_get_value(props, package, &type)))
+ else if (!lstrcmpW(szProperty, INSTALLPROPERTY_INSTALLDATEW))
{
- msi_free(val);
- val = strdupW(five);
- r = msi_copy_outval(val, szValue, pcchValue);
- goto done;
+ datakey = patch;
+ szProperty = szInstalled;
+ }
+ else if (!lstrcmpW(szProperty, INSTALLPROPERTY_LOCALPACKAGEW))
+ {
+ datakey = udpatch;
+ }
+ else if (!lstrcmpW(szProperty, INSTALLPROPERTY_UNINSTALLABLEW) ||
+ !lstrcmpW(szProperty, INSTALLPROPERTY_PATCHSTATEW) ||
+ !lstrcmpW(szProperty, INSTALLPROPERTY_DISPLAYNAMEW) ||
+ !lstrcmpW(szProperty, INSTALLPROPERTY_MOREINFOURLW))
+ {
+ datakey = patch;
}
-
- if (prod || managed)
- val = strdupW(one);
else
+ {
+ r = ERROR_UNKNOWN_PROPERTY;
goto done;
-
- r = msi_copy_outval(val, szValue, pcchValue);
+ }
}
- else if (!lstrcmpW(szProperty, INSTALLPROPERTY_ASSIGNMENTTYPEW))
+
+ val = msi_reg_get_val_str(datakey, szProperty);
+ if (!val)
+ val = strdupW(szEmpty);
+
+ r = ERROR_SUCCESS;
+
+ if (!pcchValue)
+ goto done;
+
+ if (lpValue)
+ lstrcpynW(lpValue, val, *pcchValue);
+
+ len = lstrlenW(val);
+ if ((*val && *pcchValue < len + 1) || !lpValue)
{
- if (!prod && !classes)
- goto done;
+ if (lpValue)
+ r = ERROR_MORE_DATA;
- /* FIXME */
- val = strdupW(empty);
- r = msi_copy_outval(val, szValue, pcchValue);
+ *pcchValue = len * sizeof(WCHAR);
}
- else
- r = ERROR_UNKNOWN_PROPERTY;
+
+ *pcchValue = len;
done:
- RegCloseKey(props);
- RegCloseKey(prod);
- RegCloseKey(managed);
- RegCloseKey(classes);
msi_free(val);
+ RegCloseKey(prodpatches);
+ RegCloseKey(prod);
+ RegCloseKey(patch);
+ RegCloseKey(patches);
+ RegCloseKey(udpatch);
+ RegCloseKey(props);
+ RegCloseKey(udprod);
return r;
}
LPWSTR lpDriveBuf, DWORD *pcchDriveBuf,
int *piCost, int *pTempCost)
{
- FIXME("(%ld, %s, %d, %d, %p, %p, %p %p): stub!\n", hInstall,
+ FIXME("(%d, %s, %d, %d, %p, %p, %p %p): stub!\n", hInstall,
debugstr_w(szComponent), dwIndex, iState, lpDriveBuf,
pcchDriveBuf, piCost, pTempCost);
UINT r;
HKEY hkey;
- if (context == MSIINSTALLCONTEXT_MACHINE)
- r = MSIREG_OpenLocalClassesProductKey(prodcode, &hkey, FALSE);
- else if (context == MSIINSTALLCONTEXT_USERUNMANAGED)
- r = MSIREG_OpenUserProductsKey(prodcode, &hkey, FALSE);
- else
- r = MSIREG_OpenLocalManagedProductKey(prodcode, &hkey, FALSE);
-
+ r = MSIREG_OpenProductKey(prodcode, NULL, context, &hkey, FALSE);
RegCloseKey(hkey);
return (r == ERROR_SUCCESS);
}
'M','a','n','a','g','e','d','L','o','c','a','l','P','a','c','k','a','g','e',0
};
- if (context == MSIINSTALLCONTEXT_MACHINE)
- r = MSIREG_OpenLocalSystemProductKey(prodcode, &hkey, FALSE);
- else
- r = MSIREG_OpenCurrentUserInstallProps(prodcode, &hkey, FALSE);
-
+ r = MSIREG_OpenInstallProps(prodcode, context, NULL, &hkey, FALSE);
if (r != ERROR_SUCCESS)
return FALSE;
static BOOL msi_comp_find_prodcode(LPWSTR squished_pc,
MSIINSTALLCONTEXT context,
- LPCWSTR comp, DWORD *sz)
+ LPCWSTR comp, LPWSTR val, DWORD *sz)
{
HKEY hkey;
LONG res;
UINT r;
if (context == MSIINSTALLCONTEXT_MACHINE)
- r = MSIREG_OpenLocalSystemComponentKey(comp, &hkey, FALSE);
+ r = MSIREG_OpenUserDataComponentKey(comp, szLocalSid, &hkey, FALSE);
else
- r = MSIREG_OpenUserDataComponentKey(comp, &hkey, FALSE);
+ r = MSIREG_OpenUserDataComponentKey(comp, NULL, &hkey, FALSE);
if (r != ERROR_SUCCESS)
return FALSE;
- *sz = 0;
- res = RegQueryValueExW(hkey, squished_pc, NULL, NULL, NULL, sz);
+ res = RegQueryValueExW(hkey, squished_pc, NULL, NULL, (BYTE *)val, sz);
if (res != ERROR_SUCCESS)
return FALSE;
LPCWSTR szComponent, INSTALLSTATE *pdwState)
{
WCHAR squished_pc[GUID_SIZE];
+ WCHAR val[MAX_PATH];
BOOL found;
DWORD sz;
TRACE("(%s, %s, %d, %s, %p)\n", debugstr_w(szProductCode),
debugstr_w(szUserSid), dwContext, debugstr_w(szComponent), pdwState);
- if (!pdwState)
+ if (!pdwState || !szComponent)
return ERROR_INVALID_PARAMETER;
if (!szProductCode || !*szProductCode || lstrlenW(szProductCode) != GUID_SIZE - 1)
*pdwState = INSTALLSTATE_UNKNOWN;
- if (!msi_comp_find_prodcode(squished_pc, dwContext, szComponent, &sz))
+ sz = MAX_PATH;
+ if (!msi_comp_find_prodcode(squished_pc, dwContext, szComponent, val, &sz))
return ERROR_UNKNOWN_COMPONENT;
if (sz == 0)
*pdwState = INSTALLSTATE_NOTUSED;
else
- *pdwState = INSTALLSTATE_LOCAL;
+ {
+ if (lstrlenW(val) > 2 &&
+ val[0] >= '0' && val[0] <= '9' && val[1] >= '0' && val[1] <= '9')
+ {
+ *pdwState = INSTALLSTATE_SOURCE;
+ }
+ else
+ *pdwState = INSTALLSTATE_LOCAL;
+ }
return ERROR_SUCCESS;
}
INSTALLSTATE WINAPI MsiQueryProductStateW(LPCWSTR szProduct)
{
+ MSIINSTALLCONTEXT context = MSIINSTALLCONTEXT_USERUNMANAGED;
INSTALLSTATE state = INSTALLSTATE_ADVERTISED;
HKEY prodkey = 0, userdata = 0;
- BOOL user = TRUE;
DWORD val;
UINT r;
if (lstrlenW(szProduct) != GUID_SIZE - 1)
return INSTALLSTATE_INVALIDARG;
- r = MSIREG_OpenLocalManagedProductKey(szProduct, &prodkey, FALSE);
- if (r != ERROR_SUCCESS)
+ if (MSIREG_OpenProductKey(szProduct, NULL, MSIINSTALLCONTEXT_USERMANAGED,
+ &prodkey, FALSE) != ERROR_SUCCESS &&
+ MSIREG_OpenProductKey(szProduct, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
+ &prodkey, FALSE) != ERROR_SUCCESS &&
+ MSIREG_OpenProductKey(szProduct, NULL, MSIINSTALLCONTEXT_MACHINE,
+ &prodkey, FALSE) == ERROR_SUCCESS)
{
- r = MSIREG_OpenUserProductsKey(szProduct, &prodkey, FALSE);
- if (r != ERROR_SUCCESS)
- {
- r = MSIREG_OpenLocalClassesProductKey(szProduct, &prodkey, FALSE);
- if (r == ERROR_SUCCESS)
- user = FALSE;
- }
+ context = MSIINSTALLCONTEXT_MACHINE;
}
- if (user)
- {
- r = MSIREG_OpenCurrentUserInstallProps(szProduct, &userdata, FALSE);
- if (r != ERROR_SUCCESS)
- goto done;
- }
- else
- {
- r = MSIREG_OpenLocalSystemInstallProps(szProduct, &userdata, FALSE);
- if (r != ERROR_SUCCESS)
- goto done;
- }
+ r = MSIREG_OpenInstallProps(szProduct, context, NULL, &userdata, FALSE);
+ if (r != ERROR_SUCCESS)
+ goto done;
if (!msi_reg_get_val_dword(userdata, szWindowsInstaller, &val))
goto done;
LPWSTR p;
DWORD i, len;
- TRACE("%ld %u %p %d %d\n", handle, id, lpBuffer, nBufferMax, lang);
+ TRACE("%d %u %p %d %d\n", handle, id, lpBuffer, nBufferMax, lang);
if( handle != -1 )
- FIXME("don't know how to deal with handle = %08lx\n", handle);
+ FIXME("don't know how to deal with handle = %08x\n", handle);
if( !lang )
lang = GetUserDefaultLangID();
{
LPWSTR bufW;
LANGID r;
- DWORD len;
+ INT len;
bufW = msi_alloc(nBufferMax*sizeof(WCHAR));
r = MsiLoadStringW(handle, id, bufW, nBufferMax, lang);
return ERROR_CALL_NOT_IMPLEMENTED;
}
-UINT WINAPI MsiGetProductPropertyA( MSIHANDLE hProduct, LPCSTR szProperty,
- LPSTR szValue, LPDWORD pccbValue )
+/******************************************************************
+ * MsiGetProductPropertyA [MSI.@]
+ */
+UINT WINAPI MsiGetProductPropertyA(MSIHANDLE hProduct, LPCSTR szProperty,
+ LPSTR szValue, LPDWORD pccbValue)
{
- FIXME("%ld %s %p %p\n", hProduct, debugstr_a(szProperty), szValue, pccbValue);
- return ERROR_CALL_NOT_IMPLEMENTED;
+ LPWSTR prop = NULL, val = NULL;
+ DWORD len;
+ UINT r;
+
+ TRACE("(%d, %s, %p, %p)\n", hProduct, debugstr_a(szProperty),
+ szValue, pccbValue);
+
+ if (szValue && !pccbValue)
+ return ERROR_INVALID_PARAMETER;
+
+ if (szProperty) prop = strdupAtoW(szProperty);
+
+ len = 0;
+ r = MsiGetProductPropertyW(hProduct, prop, NULL, &len);
+ if (r != ERROR_SUCCESS && r != ERROR_MORE_DATA)
+ goto done;
+
+ if (r == ERROR_SUCCESS)
+ {
+ if (szValue) *szValue = '\0';
+ if (pccbValue) *pccbValue = 0;
+ goto done;
+ }
+
+ val = msi_alloc(++len * sizeof(WCHAR));
+ if (!val)
+ {
+ r = ERROR_OUTOFMEMORY;
+ goto done;
+ }
+
+ r = MsiGetProductPropertyW(hProduct, prop, val, &len);
+ if (r != ERROR_SUCCESS)
+ goto done;
+
+ len = WideCharToMultiByte(CP_ACP, 0, val, -1, NULL, 0, NULL, NULL);
+
+ if (szValue)
+ WideCharToMultiByte(CP_ACP, 0, val, -1, szValue,
+ *pccbValue, NULL, NULL);
+
+ if (pccbValue)
+ {
+ if (len > *pccbValue)
+ r = ERROR_MORE_DATA;
+
+ *pccbValue = len - 1;
+ }
+
+done:
+ msi_free(prop);
+ msi_free(val);
+
+ return r;
}
-UINT WINAPI MsiGetProductPropertyW( MSIHANDLE hProduct, LPCWSTR szProperty,
- LPWSTR szValue, LPDWORD pccbValue )
+/******************************************************************
+ * MsiGetProductPropertyW [MSI.@]
+ */
+UINT WINAPI MsiGetProductPropertyW(MSIHANDLE hProduct, LPCWSTR szProperty,
+ LPWSTR szValue, LPDWORD pccbValue)
{
- FIXME("%ld %s %p %p\n", hProduct, debugstr_w(szProperty), szValue, pccbValue);
- return ERROR_CALL_NOT_IMPLEMENTED;
+ MSIPACKAGE *package;
+ MSIQUERY *view = NULL;
+ MSIRECORD *rec = NULL;
+ LPCWSTR val;
+ UINT r;
+
+ static const WCHAR query[] = {
+ 'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
+ '`','P','r','o','p','e','r','t','y','`',' ','W','H','E','R','E',' ',
+ '`','P','r','o','p','e','r','t','y','`','=','\'','%','s','\'',0};
+
+ TRACE("(%d, %s, %p, %p)\n", hProduct, debugstr_w(szProperty),
+ szValue, pccbValue);
+
+ if (!szProperty)
+ return ERROR_INVALID_PARAMETER;
+
+ if (szValue && !pccbValue)
+ return ERROR_INVALID_PARAMETER;
+
+ package = msihandle2msiinfo(hProduct, MSIHANDLETYPE_PACKAGE);
+ if (!package)
+ return ERROR_INVALID_HANDLE;
+
+ r = MSI_OpenQuery(package->db, &view, query, szProperty);
+ if (r != ERROR_SUCCESS)
+ goto done;
+
+ r = MSI_ViewExecute(view, 0);
+ if (r != ERROR_SUCCESS)
+ goto done;
+
+ r = MSI_ViewFetch(view, &rec);
+ if (r != ERROR_SUCCESS)
+ goto done;
+
+ val = MSI_RecordGetString(rec, 2);
+ if (!val)
+ goto done;
+
+ if (lstrlenW(val) >= *pccbValue)
+ {
+ lstrcpynW(szValue, val, *pccbValue);
+ *pccbValue = lstrlenW(val);
+ r = ERROR_MORE_DATA;
+ }
+ else
+ {
+ lstrcpyW(szValue, val);
+ *pccbValue = lstrlenW(val);
+ r = ERROR_SUCCESS;
+ }
+
+done:
+ if (view)
+ {
+ MSI_ViewClose(view);
+ msiobj_release(&view->hdr);
+ if (rec) msiobj_release(&rec->hdr);
+ }
+
+ if (!rec)
+ {
+ if (szValue) *szValue = '\0';
+ if (pccbValue) *pccbValue = 0;
+ r = ERROR_SUCCESS;
+ }
+
+ return r;
}
UINT WINAPI MsiVerifyPackageA( LPCSTR szPackage )
return r;
}
-static INSTALLSTATE WINAPI MSI_GetComponentPath(LPCWSTR szProduct, LPCWSTR szComponent,
- awstring* lpPathBuf, LPDWORD pcchBuf)
+static INSTALLSTATE MSI_GetComponentPath(LPCWSTR szProduct, LPCWSTR szComponent,
+ awstring* lpPathBuf, LPDWORD pcchBuf)
{
WCHAR squished_pc[GUID_SIZE];
WCHAR squished_comp[GUID_SIZE];
state = INSTALLSTATE_UNKNOWN;
- if (MSIREG_OpenLocalSystemComponentKey(szComponent, &hkey, FALSE) == ERROR_SUCCESS ||
- MSIREG_OpenUserDataComponentKey(szComponent, &hkey, FALSE) == ERROR_SUCCESS)
+ if (MSIREG_OpenUserDataComponentKey(szComponent, szLocalSid, &hkey, FALSE) == ERROR_SUCCESS ||
+ MSIREG_OpenUserDataComponentKey(szComponent, NULL, &hkey, FALSE) == ERROR_SUCCESS)
{
path = msi_reg_get_val_str(hkey, squished_pc);
RegCloseKey(hkey);
state = INSTALLSTATE_ABSENT;
- if ((MSIREG_OpenLocalSystemProductKey(szProduct, &hkey, FALSE) == ERROR_SUCCESS ||
- MSIREG_OpenUserDataProductKey(szProduct, &hkey, FALSE) == ERROR_SUCCESS) &&
+ if ((MSIREG_OpenInstallProps(szProduct, MSIINSTALLCONTEXT_MACHINE, NULL,
+ &hkey, FALSE) == ERROR_SUCCESS ||
+ MSIREG_OpenUserDataProductKey(szProduct, MSIINSTALLCONTEXT_USERUNMANAGED,
+ NULL, &hkey, FALSE) == ERROR_SUCCESS) &&
msi_reg_get_val_dword(hkey, wininstaller, &version) &&
GetFileAttributesW(path) != INVALID_FILE_ATTRIBUTES)
{
}
if (state != INSTALLSTATE_LOCAL &&
- (MSIREG_OpenUserProductsKey(szProduct, &hkey, FALSE) == ERROR_SUCCESS ||
- MSIREG_OpenLocalClassesProductKey(szProduct, &hkey, FALSE) == ERROR_SUCCESS))
+ (MSIREG_OpenProductKey(szProduct, NULL,
+ MSIINSTALLCONTEXT_USERUNMANAGED,
+ &hkey, FALSE) == ERROR_SUCCESS ||
+ MSIREG_OpenProductKey(szProduct, NULL, MSIINSTALLCONTEXT_MACHINE,
+ &hkey, FALSE) == ERROR_SUCCESS))
{
RegCloseKey(hkey);
- if (MSIREG_OpenLocalSystemComponentKey(szComponent, &hkey, FALSE) == ERROR_SUCCESS ||
- MSIREG_OpenUserDataComponentKey(szComponent, &hkey, FALSE) == ERROR_SUCCESS)
+ if (MSIREG_OpenUserDataComponentKey(szComponent, szLocalSid, &hkey, FALSE) == ERROR_SUCCESS ||
+ MSIREG_OpenUserDataComponentKey(szComponent, NULL, &hkey, FALSE) == ERROR_SUCCESS)
{
msi_free(path);
path = msi_reg_get_val_str(hkey, squished_pc);
HKEY hkey;
INSTALLSTATE r;
BOOL missing = FALSE;
+ BOOL machine = FALSE;
+ BOOL source = FALSE;
TRACE("%s %s\n", debugstr_w(szProduct), debugstr_w(szFeature));
if (!squash_guid( szProduct, squishProduct ))
return INSTALLSTATE_INVALIDARG;
- /* check that it's installed at all */
- rc = MSIREG_OpenUserFeaturesKey(szProduct, &hkey, FALSE);
- if (rc != ERROR_SUCCESS)
- return INSTALLSTATE_UNKNOWN;
+ if (MSIREG_OpenFeaturesKey(szProduct, MSIINSTALLCONTEXT_USERMANAGED,
+ &hkey, FALSE) != ERROR_SUCCESS &&
+ MSIREG_OpenFeaturesKey(szProduct, MSIINSTALLCONTEXT_USERUNMANAGED,
+ &hkey, FALSE) != ERROR_SUCCESS)
+ {
+ rc = MSIREG_OpenFeaturesKey(szProduct, MSIINSTALLCONTEXT_MACHINE,
+ &hkey, FALSE);
+ if (rc != ERROR_SUCCESS)
+ return INSTALLSTATE_UNKNOWN;
+
+ machine = TRUE;
+ }
parent_feature = msi_reg_get_val_str( hkey, szFeature );
RegCloseKey(hkey);
if (r == INSTALLSTATE_ABSENT)
return r;
- /* now check if it's complete or advertised */
- rc = MSIREG_OpenUserDataFeaturesKey(szProduct, &hkey, FALSE);
+ if (machine)
+ rc = MSIREG_OpenUserDataFeaturesKey(szProduct,
+ MSIINSTALLCONTEXT_MACHINE,
+ &hkey, FALSE);
+ else
+ rc = MSIREG_OpenUserDataFeaturesKey(szProduct,
+ MSIINSTALLCONTEXT_USERUNMANAGED,
+ &hkey, FALSE);
+
if (rc != ERROR_SUCCESS)
return INSTALLSTATE_ADVERTISED;
}
StringFromGUID2(&guid, comp, GUID_SIZE);
- rc = MSIREG_OpenUserDataComponentKey(comp, &hkey, FALSE);
+
+ if (machine)
+ rc = MSIREG_OpenUserDataComponentKey(comp, szLocalSid, &hkey, FALSE);
+ else
+ rc = MSIREG_OpenUserDataComponentKey(comp, NULL, &hkey, FALSE);
+
if (rc != ERROR_SUCCESS)
{
msi_free(components);
path = msi_reg_get_val_str(hkey, squishProduct);
if (!path)
missing = TRUE;
+ else if (lstrlenW(path) > 2 &&
+ path[0] >= '0' && path[0] <= '9' &&
+ path[1] >= '0' && path[1] <= '9')
+ {
+ source = TRUE;
+ }
msi_free(path);
}
if (missing)
return INSTALLSTATE_ADVERTISED;
+ if (source)
+ return INSTALLSTATE_SOURCE;
+
return INSTALLSTATE_LOCAL;
}
HIWORD(ffi->dwFileVersionLS), LOWORD(ffi->dwFileVersionLS));
if (lpVersionBuf) lstrcpynW(lpVersionBuf, tmp, *pcchVersionBuf);
- if (lstrlenW(tmp) >= *pcchVersionBuf)
+ if (strlenW(tmp) >= *pcchVersionBuf)
ret = ERROR_MORE_DATA;
*pcchVersionBuf = lstrlenW(tmp);
wsprintfW(tmp, szLangFormat, *lang);
if (lpLangBuf) lstrcpynW(lpLangBuf, tmp, *pcchLangBuf);
- if (lstrlenW(tmp) >= *pcchLangBuf)
+ if (strlenW(tmp) >= *pcchLangBuf)
ret = ERROR_MORE_DATA;
*pcchLangBuf = lstrlenW(tmp);
/***********************************************************************
* MSI_ProvideQualifiedComponentEx [internal]
*/
-static UINT WINAPI MSI_ProvideQualifiedComponentEx(LPCWSTR szComponent,
+static UINT MSI_ProvideQualifiedComponentEx(LPCWSTR szComponent,
LPCWSTR szQualifier, DWORD dwInstallMode, LPCWSTR szProduct,
DWORD Unused1, DWORD Unused2, awstring *lpPathBuf,
LPDWORD pcchPathBuf)
/***********************************************************************
* MSI_GetUserInfo [internal]
*/
-static USERINFOSTATE WINAPI MSI_GetUserInfo(LPCWSTR szProduct,
+static USERINFOSTATE MSI_GetUserInfo(LPCWSTR szProduct,
awstring *lpUserNameBuf, LPDWORD pcchUserNameBuf,
awstring *lpOrgNameBuf, LPDWORD pcchOrgNameBuf,
awstring *lpSerialBuf, LPDWORD pcchSerialBuf)
{
- HKEY hkey;
+ WCHAR squished_pc[SQUISH_GUID_SIZE];
LPWSTR user, org, serial;
- UINT r;
USERINFOSTATE state;
+ HKEY hkey, props;
+ LPCWSTR orgptr;
+ UINT r;
- TRACE("%s %p %p %p %p %p %p\n",debugstr_w(szProduct), lpUserNameBuf,
+ static const WCHAR szEmpty[] = {0};
+
+ TRACE("%s %p %p %p %p %p %p\n", debugstr_w(szProduct), lpUserNameBuf,
pcchUserNameBuf, lpOrgNameBuf, pcchOrgNameBuf, lpSerialBuf,
pcchSerialBuf);
- if (!szProduct)
+ if (!szProduct || !squash_guid(szProduct, squished_pc))
return USERINFOSTATE_INVALIDARG;
- r = MSIREG_OpenUninstallKey(szProduct, &hkey, FALSE);
- if (r != ERROR_SUCCESS)
+ if (MSIREG_OpenProductKey(szProduct, NULL, MSIINSTALLCONTEXT_USERMANAGED,
+ &hkey, FALSE) != ERROR_SUCCESS &&
+ MSIREG_OpenProductKey(szProduct, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
+ &hkey, FALSE) != ERROR_SUCCESS &&
+ MSIREG_OpenProductKey(szProduct, NULL, MSIINSTALLCONTEXT_MACHINE,
+ &hkey, FALSE) != ERROR_SUCCESS)
+ {
return USERINFOSTATE_UNKNOWN;
+ }
+
+ if (MSIREG_OpenInstallProps(szProduct, MSIINSTALLCONTEXT_USERUNMANAGED,
+ NULL, &props, FALSE) != ERROR_SUCCESS &&
+ MSIREG_OpenInstallProps(szProduct, MSIINSTALLCONTEXT_MACHINE,
+ NULL, &props, FALSE) != ERROR_SUCCESS)
+ {
+ RegCloseKey(hkey);
+ return USERINFOSTATE_ABSENT;
+ }
- user = msi_reg_get_val_str( hkey, INSTALLPROPERTY_REGOWNERW );
- org = msi_reg_get_val_str( hkey, INSTALLPROPERTY_REGCOMPANYW );
- serial = msi_reg_get_val_str( hkey, INSTALLPROPERTY_PRODUCTIDW );
+ user = msi_reg_get_val_str(props, INSTALLPROPERTY_REGOWNERW);
+ org = msi_reg_get_val_str(props, INSTALLPROPERTY_REGCOMPANYW);
+ serial = msi_reg_get_val_str(props, INSTALLPROPERTY_PRODUCTIDW);
+ state = USERINFOSTATE_ABSENT;
RegCloseKey(hkey);
+ RegCloseKey(props);
- state = USERINFOSTATE_PRESENT;
+ if (user && serial)
+ state = USERINFOSTATE_PRESENT;
- if (user)
+ if (pcchUserNameBuf)
{
- r = msi_strcpy_to_awstring( user, lpUserNameBuf, pcchUserNameBuf );
+ if (lpUserNameBuf && !user)
+ {
+ (*pcchUserNameBuf)--;
+ goto done;
+ }
+
+ r = msi_strcpy_to_awstring(user, lpUserNameBuf, pcchUserNameBuf);
if (r == ERROR_MORE_DATA)
+ {
state = USERINFOSTATE_MOREDATA;
+ goto done;
+ }
}
- else
- state = USERINFOSTATE_ABSENT;
- if (org)
+
+ if (pcchOrgNameBuf)
{
- r = msi_strcpy_to_awstring( org, lpOrgNameBuf, pcchOrgNameBuf );
- if (r == ERROR_MORE_DATA && state == USERINFOSTATE_PRESENT)
+ orgptr = org;
+ if (!orgptr) orgptr = szEmpty;
+
+ r = msi_strcpy_to_awstring(orgptr, lpOrgNameBuf, pcchOrgNameBuf);
+ if (r == ERROR_MORE_DATA)
+ {
state = USERINFOSTATE_MOREDATA;
+ goto done;
+ }
}
- /* msdn states: The user information is considered to be present even in the absence of a company name. */
- if (serial)
+
+ if (pcchSerialBuf)
{
- r = msi_strcpy_to_awstring( serial, lpSerialBuf, pcchSerialBuf );
- if (r == ERROR_MORE_DATA && state == USERINFOSTATE_PRESENT)
+ if (!serial)
+ {
+ (*pcchSerialBuf)--;
+ goto done;
+ }
+
+ r = msi_strcpy_to_awstring(serial, lpSerialBuf, pcchSerialBuf);
+ if (r == ERROR_MORE_DATA)
state = USERINFOSTATE_MOREDATA;
}
- else
- state = USERINFOSTATE_ABSENT;
- msi_free( user );
- msi_free( org );
- msi_free( serial );
+done:
+ msi_free(user);
+ msi_free(org);
+ msi_free(serial);
return state;
}
{
awstring user, org, serial;
+ if ((lpUserNameBuf && !pcchUserNameBuf) ||
+ (lpOrgNameBuf && !pcchOrgNameBuf) ||
+ (lpSerialBuf && !pcchSerialBuf))
+ return USERINFOSTATE_INVALIDARG;
+
user.unicode = TRUE;
user.str.w = lpUserNameBuf;
org.unicode = TRUE;
LPWSTR prod;
UINT r;
+ if ((lpUserNameBuf && !pcchUserNameBuf) ||
+ (lpOrgNameBuf && !pcchOrgNameBuf) ||
+ (lpSerialBuf && !pcchSerialBuf))
+ return USERINFOSTATE_INVALIDARG;
+
prod = strdupAtoW( szProduct );
if (szProduct && !prod)
return ERROR_OUTOFMEMORY;
if (rc != ERROR_SUCCESS)
return ERROR_INVALID_PARAMETER;
+ /* MsiCollectUserInfo cannot be called from a custom action. */
package = msihandle2msiinfo(handle, MSIHANDLETYPE_PACKAGE);
+ if (!package)
+ return ERROR_CALL_NOT_IMPLEMENTED;
+
rc = ACTION_PerformUIAction(package, szFirstRun, -1);
msiobj_release( &package->hdr );
if (rc != ERROR_SUCCESS)
return ERROR_INVALID_PARAMETER;
+ /* MsiCollectUserInfo cannot be called from a custom action. */
package = msihandle2msiinfo(handle, MSIHANDLETYPE_PACKAGE);
+ if (!package)
+ return ERROR_CALL_NOT_IMPLEMENTED;
+
rc = ACTION_PerformUIAction(package, szFirstRun, -1);
msiobj_release( &package->hdr );
MD5Final( &ctx );
UnmapViewOfFile( p );
- memcpy( pHash->dwData, &ctx.digest, sizeof pHash->dwData );
+ memcpy( pHash->dwData, ctx.digest, sizeof pHash->dwData );
r = ERROR_SUCCESS;
}
CloseHandle( mapping );
*pfElevated = TRUE;
return ERROR_SUCCESS;
}
+
+/***********************************************************************
+ * MsiSetExternalUIRecord [MSI.@]
+ */
+UINT WINAPI MsiSetExternalUIRecord( INSTALLUI_HANDLER_RECORD puiHandler,
+ DWORD dwMessageFilter, LPVOID pvContext,
+ PINSTALLUI_HANDLER_RECORD ppuiPrevHandler)
+{
+ FIXME("%p %08x %p %p\n", puiHandler, dwMessageFilter ,pvContext,
+ ppuiPrevHandler);
+ return ERROR_CALL_NOT_IMPLEMENTED;
+}
+
+/***********************************************************************
+ * MsiInstallMissingComponentW [MSI.@]
+ */
+UINT WINAPI MsiInstallMissingComponentW(LPCWSTR szProduct, LPCWSTR szComponent, INSTALLSTATE eInstallState)
+{
+ FIXME("(%s %s %d\n", debugstr_w(szProduct), debugstr_w(szComponent), eInstallState);
+ return ERROR_SUCCESS;
+}