*context = MSIINSTALLCONTEXT_NONE;
- if (MSIREG_OpenProductKey(szProduct, MSIINSTALLCONTEXT_USERMANAGED,
+ if (MSIREG_OpenProductKey(szProduct, NULL, MSIINSTALLCONTEXT_USERMANAGED,
&hkey, FALSE) == ERROR_SUCCESS)
*context = MSIINSTALLCONTEXT_USERMANAGED;
- else if (MSIREG_OpenProductKey(szProduct, MSIINSTALLCONTEXT_MACHINE,
+ else if (MSIREG_OpenProductKey(szProduct, NULL, MSIINSTALLCONTEXT_MACHINE,
&hkey, FALSE) == ERROR_SUCCESS)
*context = MSIINSTALLCONTEXT_MACHINE;
- else if (MSIREG_OpenProductKey(szProduct, MSIINSTALLCONTEXT_USERUNMANAGED,
+ else if (MSIREG_OpenProductKey(szProduct, NULL,
+ MSIINSTALLCONTEXT_USERUNMANAGED,
&hkey, FALSE) == ERROR_SUCCESS)
*context = MSIINSTALLCONTEXT_USERUNMANAGED;
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)
{
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)
{
- FIXME("(%s, %d, %p): stub!\n", debugstr_w(szProductPackagePath),
- cPatchInfo, 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;
}
MSIINSTALLCONTEXT context;
UINT r;
DWORD sz;
- WCHAR sourcepath[MAX_PATH];
+ WCHAR sourcepath[MAX_PATH], filename[MAX_PATH];
LPWSTR commandline;
static const WCHAR szInstalled[] = {
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 );
msi_free(commandline);
sz = GUID_SIZE;
unsquash_guid(squished_prod, szBuffer);
- if (MSIREG_OpenProductKey(szBuffer, MSIINSTALLCONTEXT_USERMANAGED,
+ if (MSIREG_OpenProductKey(szBuffer, NULL,
+ MSIINSTALLCONTEXT_USERMANAGED,
&prodkey, FALSE) == ERROR_SUCCESS ||
- MSIREG_OpenProductKey(szBuffer, MSIINSTALLCONTEXT_USERUNMANAGED,
+ MSIREG_OpenProductKey(szBuffer, NULL,
+ MSIINSTALLCONTEXT_USERUNMANAGED,
&prodkey, FALSE) == ERROR_SUCCESS ||
- MSIREG_OpenProductKey(szBuffer, MSIINSTALLCONTEXT_MACHINE,
+ MSIREG_OpenProductKey(szBuffer, NULL,
+ MSIINSTALLCONTEXT_MACHINE,
&prodkey, FALSE) == ERROR_SUCCESS)
{
RegCloseKey(prodkey);
if (!squash_guid(szProduct, squished_pc))
return ERROR_INVALID_PARAMETER;
- if ((r = MSIREG_OpenProductKey(szProduct, MSIINSTALLCONTEXT_USERMANAGED,
+ if ((r = MSIREG_OpenProductKey(szProduct, NULL,
+ MSIINSTALLCONTEXT_USERMANAGED,
&prodkey, FALSE)) != ERROR_SUCCESS &&
- (r = MSIREG_OpenProductKey(szProduct, MSIINSTALLCONTEXT_USERUNMANAGED,
+ (r = MSIREG_OpenProductKey(szProduct, NULL,
+ MSIINSTALLCONTEXT_USERUNMANAGED,
&prodkey, FALSE)) != ERROR_SUCCESS &&
- (r = MSIREG_OpenProductKey(szProduct, MSIINSTALLCONTEXT_MACHINE,
- &prodkey, FALSE)) == ERROR_SUCCESS)
+ (r = MSIREG_OpenProductKey(szProduct, NULL,
+ MSIINSTALLCONTEXT_MACHINE,
+ &prodkey, FALSE)) == ERROR_SUCCESS)
{
context = MSIINSTALLCONTEXT_MACHINE;
}
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);
}
return ERROR_INVALID_PARAMETER;
/* FIXME: dwContext is provided, no need to search for it */
- MSIREG_OpenProductKey(szProductCode, MSIINSTALLCONTEXT_USERMANAGED,
+ MSIREG_OpenProductKey(szProductCode, NULL,MSIINSTALLCONTEXT_USERMANAGED,
&managed, FALSE);
- MSIREG_OpenProductKey(szProductCode, MSIINSTALLCONTEXT_USERUNMANAGED,
+ MSIREG_OpenProductKey(szProductCode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
&prod, FALSE);
MSIREG_OpenInstallProps(szProductCode, dwContext, NULL, &props, FALSE);
else if (dwContext == MSIINSTALLCONTEXT_MACHINE)
{
package = INSTALLPROPERTY_LOCALPACKAGEW;
- MSIREG_OpenProductKey(szProductCode, dwContext, &classes, FALSE);
+ MSIREG_OpenProductKey(szProductCode, NULL, dwContext, &classes, FALSE);
if (!props && !classes)
goto done;
if (!lstrcmpW(szProperty, INSTALLPROPERTY_TRANSFORMSW))
{
- if (MSIREG_OpenProductKey(szProductCode, dwContext,
+ if (MSIREG_OpenProductKey(szProductCode, NULL, dwContext,
&prod, FALSE) != ERROR_SUCCESS)
goto done;
UINT r;
HKEY hkey;
- r = MSIREG_OpenProductKey(prodcode, context, &hkey, FALSE);
+ r = MSIREG_OpenProductKey(prodcode, NULL, context, &hkey, FALSE);
RegCloseKey(hkey);
return (r == ERROR_SUCCESS);
}
if (lstrlenW(szProduct) != GUID_SIZE - 1)
return INSTALLSTATE_INVALIDARG;
- if (MSIREG_OpenProductKey(szProduct, MSIINSTALLCONTEXT_USERMANAGED,
+ if (MSIREG_OpenProductKey(szProduct, NULL, MSIINSTALLCONTEXT_USERMANAGED,
&prodkey, FALSE) != ERROR_SUCCESS &&
- MSIREG_OpenProductKey(szProduct, MSIINSTALLCONTEXT_USERUNMANAGED,
+ MSIREG_OpenProductKey(szProduct, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
&prodkey, FALSE) != ERROR_SUCCESS &&
- MSIREG_OpenProductKey(szProduct, MSIINSTALLCONTEXT_MACHINE,
+ MSIREG_OpenProductKey(szProduct, NULL, MSIINSTALLCONTEXT_MACHINE,
&prodkey, FALSE) == ERROR_SUCCESS)
{
context = MSIINSTALLCONTEXT_MACHINE;
}
if (state != INSTALLSTATE_LOCAL &&
- (MSIREG_OpenProductKey(szProduct, MSIINSTALLCONTEXT_USERUNMANAGED,
+ (MSIREG_OpenProductKey(szProduct, NULL,
+ MSIINSTALLCONTEXT_USERUNMANAGED,
&hkey, FALSE) == ERROR_SUCCESS ||
- MSIREG_OpenProductKey(szProduct, MSIINSTALLCONTEXT_MACHINE,
+ MSIREG_OpenProductKey(szProduct, NULL, MSIINSTALLCONTEXT_MACHINE,
&hkey, FALSE) == ERROR_SUCCESS))
{
RegCloseKey(hkey);
if (!szProduct || !squash_guid(szProduct, squished_pc))
return USERINFOSTATE_INVALIDARG;
- if (MSIREG_OpenProductKey(szProduct, MSIINSTALLCONTEXT_USERMANAGED,
+ if (MSIREG_OpenProductKey(szProduct, NULL, MSIINSTALLCONTEXT_USERMANAGED,
&hkey, FALSE) != ERROR_SUCCESS &&
- MSIREG_OpenProductKey(szProduct, MSIINSTALLCONTEXT_USERUNMANAGED,
+ MSIREG_OpenProductKey(szProduct, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
&hkey, FALSE) != ERROR_SUCCESS &&
- MSIREG_OpenProductKey(szProduct, MSIINSTALLCONTEXT_MACHINE,
+ MSIREG_OpenProductKey(szProduct, NULL, MSIINSTALLCONTEXT_MACHINE,
&hkey, FALSE) != ERROR_SUCCESS)
{
return USERINFOSTATE_UNKNOWN;
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 );