[4/8] msi: Add a stub implementation of MsiDeterminePatchSequence.
Hans Leidekker
hans at codeweavers.com
Thu Jul 7 02:22:34 CDT 2011
The first service pack for Office 2010 calls this function.
---
dlls/msi/msi.c | 214 +++++++++++++++++++++++++++++++++++---------------------
include/msi.h | 4 +
2 files changed, 137 insertions(+), 81 deletions(-)
diff --git a/dlls/msi/msi.c b/dlls/msi/msi.c
index aaa1d84..f42704b 100644
--- a/dlls/msi/msi.c
+++ b/dlls/msi/msi.c
@@ -492,6 +492,33 @@ UINT WINAPI MsiApplyMultiplePatchesW(LPCWSTR szPatchPackages,
return r;
}
+static void free_patchinfo( DWORD count, MSIPATCHSEQUENCEINFOW *info )
+{
+ DWORD i;
+ for (i = 0; i < count; i++) msi_free( (WCHAR *)info[i].szPatchData );
+ msi_free( info );
+}
+
+static MSIPATCHSEQUENCEINFOW *patchinfoAtoW( DWORD count, const MSIPATCHSEQUENCEINFOA *info )
+{
+ DWORD i;
+ MSIPATCHSEQUENCEINFOW *ret;
+
+ if (!(ret = msi_alloc( count * sizeof(MSIPATCHSEQUENCEINFOW) ))) return NULL;
+ for (i = 0; i < count; i++)
+ {
+ if (info[i].szPatchData && !(ret[i].szPatchData = strdupAtoW( info[i].szPatchData )))
+ {
+ free_patchinfo( i, ret );
+ return NULL;
+ }
+ ret[i].ePatchDataType = info[i].ePatchDataType;
+ ret[i].dwOrder = info[i].dwOrder;
+ ret[i].uStatus = info[i].uStatus;
+ }
+ return ret;
+}
+
UINT WINAPI MsiDetermineApplicablePatchesA(LPCSTR szProductPackagePath,
DWORD cPatchInfo, PMSIPATCHSEQUENCEINFOA pPatchInfo)
{
@@ -499,24 +526,16 @@ UINT WINAPI MsiDetermineApplicablePatchesA(LPCSTR szProductPackagePath,
WCHAR *package_path = NULL;
MSIPATCHSEQUENCEINFOW *psi;
- TRACE("(%s, %d, %p)\n", debugstr_a(szProductPackagePath), cPatchInfo, pPatchInfo);
+ TRACE("%s, %u, %p\n", debugstr_a(szProductPackagePath), cPatchInfo, pPatchInfo);
if (szProductPackagePath && !(package_path = strdupAtoW( szProductPackagePath )))
return ERROR_OUTOFMEMORY;
- psi = msi_alloc( cPatchInfo * sizeof(*psi) );
- if (!psi)
+ if (!(psi = patchinfoAtoW( cPatchInfo, pPatchInfo )))
{
msi_free( package_path );
return ERROR_OUTOFMEMORY;
}
-
- for (i = 0; i < cPatchInfo; i++)
- {
- psi[i].szPatchData = strdupAtoW( pPatchInfo[i].szPatchData );
- psi[i].ePatchDataType = pPatchInfo[i].ePatchDataType;
- }
-
r = MsiDetermineApplicablePatchesW( package_path, cPatchInfo, psi );
if (r == ERROR_SUCCESS)
{
@@ -526,11 +545,8 @@ UINT WINAPI MsiDetermineApplicablePatchesA(LPCSTR szProductPackagePath,
pPatchInfo[i].uStatus = psi[i].uStatus;
}
}
-
msi_free( package_path );
- for (i = 0; i < cPatchInfo; i++)
- msi_free( (WCHAR *)psi[i].szPatchData );
- msi_free( psi );
+ free_patchinfo( cPatchInfo, psi );
return r;
}
@@ -563,114 +579,150 @@ static UINT MSI_ApplicablePatchW( MSIPACKAGE *package, LPCWSTR patch )
return r;
}
-UINT WINAPI MsiDetermineApplicablePatchesW(LPCWSTR szProductPackagePath,
- DWORD cPatchInfo, PMSIPATCHSEQUENCEINFOW pPatchInfo)
+static UINT determine_patch_sequence( MSIPACKAGE *package, DWORD count, MSIPATCHSEQUENCEINFOW *info )
{
- UINT i, r, ret = ERROR_FUNCTION_FAILED;
- MSIPACKAGE *package;
+ DWORD i;
- 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++)
+ for (i = 0; i < count; i++)
{
- switch (pPatchInfo[i].ePatchDataType)
+ switch (info[i].ePatchDataType)
{
case MSIPATCH_DATATYPE_PATCHFILE:
{
FIXME("patch ordering not supported\n");
- r = MSI_ApplicablePatchW( package, pPatchInfo[i].szPatchData );
- if (r != ERROR_SUCCESS)
+ if (MSI_ApplicablePatchW( package, info[i].szPatchData ) != ERROR_SUCCESS)
{
- pPatchInfo[i].dwOrder = ~0u;
- pPatchInfo[i].uStatus = ERROR_PATCH_TARGET_NOT_FOUND;
+ info[i].dwOrder = ~0u;
+ info[i].uStatus = ERROR_PATCH_TARGET_NOT_FOUND;
}
else
{
- pPatchInfo[i].dwOrder = i;
- pPatchInfo[i].uStatus = ret = ERROR_SUCCESS;
+ info[i].dwOrder = i;
+ info[i].uStatus = 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;
+ FIXME("patch data type %u not supported\n", info[i].ePatchDataType);
+ info[i].dwOrder = i;
+ info[i].uStatus = ERROR_SUCCESS;
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);
+ TRACE("szPatchData: %s\n", debugstr_w(info[i].szPatchData));
+ TRACE("ePatchDataType: %u\n", info[i].ePatchDataType);
+ TRACE("dwOrder: %u\n", info[i].dwOrder);
+ TRACE("uStatus: %u\n", info[i].uStatus);
}
- return ret;
+ return ERROR_SUCCESS;
}
-UINT WINAPI MsiDeterminePatchSequenceA(LPCSTR szProductCode, LPCSTR szUserSid,
- MSIINSTALLCONTEXT dwContext, DWORD cPatchInfo, PMSIPATCHSEQUENCEINFOA pPatchInfo)
+UINT WINAPI MsiDetermineApplicablePatchesW(LPCWSTR szProductPackagePath,
+ DWORD cPatchInfo, PMSIPATCHSEQUENCEINFOW pPatchInfo)
{
- FIXME("(%s, %s, %d, %d, %p): stub!\n", debugstr_a(szProductCode),
- debugstr_a(szUserSid), dwContext, cPatchInfo, pPatchInfo);
+ UINT r;
+ MSIPACKAGE *package;
- return ERROR_CALL_NOT_IMPLEMENTED;
+ TRACE("%s, %u, %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;
+ }
+ r = determine_patch_sequence( package, cPatchInfo, pPatchInfo );
+ msiobj_release( &package->hdr );
+ return r;
}
-UINT WINAPI MsiDeterminePatchSequenceW(LPCWSTR szProductCode, LPCWSTR szUserSid,
- MSIINSTALLCONTEXT dwContext, DWORD cPatchInfo, PMSIPATCHSEQUENCEINFOW pPatchInfo)
+UINT WINAPI MsiDeterminePatchSequenceA( LPCSTR product, LPCSTR usersid,
+ MSIINSTALLCONTEXT context, DWORD count, PMSIPATCHSEQUENCEINFOA patchinfo )
{
- FIXME("(%s, %s, %d, %d, %p): stub!\n", debugstr_w(szProductCode),
- debugstr_w(szUserSid), dwContext, cPatchInfo, pPatchInfo);
+ UINT i, r;
+ WCHAR *productW, *usersidW = NULL;
+ MSIPATCHSEQUENCEINFOW *patchinfoW;
- return ERROR_CALL_NOT_IMPLEMENTED;
+ TRACE("%s, %s, %d, %d, %p\n", debugstr_a(product), debugstr_a(usersid),
+ context, count, patchinfo);
+
+ if (!product) return ERROR_INVALID_PARAMETER;
+ if (!(productW = strdupAtoW( product ))) return ERROR_OUTOFMEMORY;
+ if (usersid && !(usersidW = strdupAtoW( usersid )))
+ {
+ msi_free( productW );
+ return ERROR_OUTOFMEMORY;
+ }
+ if (!(patchinfoW = patchinfoAtoW( count, patchinfo )))
+ {
+ msi_free( productW );
+ msi_free( usersidW );
+ return ERROR_OUTOFMEMORY;
+ }
+ r = MsiDeterminePatchSequenceW( productW, usersidW, context, count, patchinfoW );
+ if (r == ERROR_SUCCESS)
+ {
+ for (i = 0; i < count; i++)
+ {
+ patchinfo[i].dwOrder = patchinfoW[i].dwOrder;
+ patchinfo[i].uStatus = patchinfoW[i].uStatus;
+ }
+ }
+ msi_free( productW );
+ msi_free( usersidW );
+ free_patchinfo( count, patchinfoW );
+ return r;
}
-static UINT msi_open_package(LPCWSTR product, MSIINSTALLCONTEXT context,
- MSIPACKAGE **package)
+static UINT open_package( const WCHAR *product, const WCHAR *usersid,
+ MSIINSTALLCONTEXT context, MSIPACKAGE **package )
{
UINT r;
- DWORD sz;
HKEY props;
- LPWSTR localpack;
- WCHAR sourcepath[MAX_PATH];
- WCHAR filename[MAX_PATH];
+ WCHAR *localpath, sourcepath[MAX_PATH], filename[MAX_PATH];
- r = MSIREG_OpenInstallProps(product, context, NULL, &props, FALSE);
- if (r != ERROR_SUCCESS)
- return ERROR_BAD_CONFIGURATION;
+ r = MSIREG_OpenInstallProps( product, context, usersid, &props, FALSE );
+ if (r != ERROR_SUCCESS) return ERROR_BAD_CONFIGURATION;
- localpack = msi_reg_get_val_str(props, szLocalPackage);
- if (localpack)
+ if ((localpath = msi_reg_get_val_str( props, szLocalPackage )))
{
- lstrcpyW(sourcepath, localpack);
- msi_free(localpack);
+ strcpyW( sourcepath, localpath );
+ msi_free( localpath );
}
-
- if (!localpack || GetFileAttributesW(sourcepath) == INVALID_FILE_ATTRIBUTES)
+ RegCloseKey( props );
+ if (!localpath || GetFileAttributesW( sourcepath ) == INVALID_FILE_ATTRIBUTES)
{
- sz = sizeof(sourcepath);
- MsiSourceListGetInfoW(product, NULL, context, MSICODE_PRODUCT,
- INSTALLPROPERTY_LASTUSEDSOURCEW, sourcepath, &sz);
-
+ DWORD sz = sizeof(sourcepath);
+ MsiSourceListGetInfoW( product, usersid, context, MSICODE_PRODUCT,
+ INSTALLPROPERTY_LASTUSEDSOURCEW, sourcepath, &sz );
sz = sizeof(filename);
- MsiSourceListGetInfoW(product, NULL, context, MSICODE_PRODUCT,
- INSTALLPROPERTY_PACKAGENAMEW, filename, &sz);
-
- lstrcatW(sourcepath, filename);
+ MsiSourceListGetInfoW( product, usersid, context, MSICODE_PRODUCT,
+ INSTALLPROPERTY_PACKAGENAMEW, filename, &sz );
+ strcatW( sourcepath, filename );
}
-
- if (GetFileAttributesW(sourcepath) == INVALID_FILE_ATTRIBUTES)
+ if (GetFileAttributesW( sourcepath ) == INVALID_FILE_ATTRIBUTES)
return ERROR_INSTALL_SOURCE_ABSENT;
- return MSI_OpenPackageW(sourcepath, package);
+ return MSI_OpenPackageW( sourcepath, package );
+}
+
+UINT WINAPI MsiDeterminePatchSequenceW( LPCWSTR product, LPCWSTR usersid,
+ MSIINSTALLCONTEXT context, DWORD count, PMSIPATCHSEQUENCEINFOW patchinfo )
+{
+ UINT r;
+ MSIPACKAGE *package;
+
+ TRACE("%s, %s, %d, %d, %p\n", debugstr_w(product), debugstr_w(usersid),
+ context, count, patchinfo);
+
+ if (!product) return ERROR_INVALID_PARAMETER;
+ r = open_package( product, usersid, context, &package );
+ if (r != ERROR_SUCCESS) return r;
+
+ r = determine_patch_sequence( package, count, patchinfo );
+ msiobj_release( &package->hdr );
+ return r;
}
UINT WINAPI MsiConfigureProductExW(LPCWSTR szProduct, int iInstallLevel,
@@ -709,7 +761,7 @@ UINT WINAPI MsiConfigureProductExW(LPCWSTR szProduct, int iInstallLevel,
if (r != ERROR_SUCCESS)
return r;
- r = msi_open_package(szProduct, context, &package);
+ r = open_package(szProduct, NULL, context, &package);
if (r != ERROR_SUCCESS)
return r;
diff --git a/include/msi.h b/include/msi.h
index 5b7eff2..0ec0c96 100644
--- a/include/msi.h
+++ b/include/msi.h
@@ -673,6 +673,10 @@ UINT WINAPI MsiDetermineApplicablePatchesA(LPCSTR, DWORD, PMSIPATCHSEQUENCEINFOA
UINT WINAPI MsiDetermineApplicablePatchesW(LPCWSTR, DWORD, PMSIPATCHSEQUENCEINFOW);
#define MsiDetermineApplicablePatches WINELIB_NAME_AW(MsiDetermineApplicablePatches)
+UINT WINAPI MsiDeterminePatchSequenceA(LPCSTR, LPCSTR, MSIINSTALLCONTEXT, DWORD, PMSIPATCHSEQUENCEINFOA);
+UINT WINAPI MsiDeterminePatchSequenceW(LPCWSTR, LPCWSTR, MSIINSTALLCONTEXT, DWORD, PMSIPATCHSEQUENCEINFOW);
+#define MsiDeterminePatchSequence WINELIB_NAME_AW(MsiDeterminePatchSequence)
+
UINT WINAPI MsiApplyMultiplePatchesA(LPCSTR, LPCSTR, LPCSTR);
UINT WINAPI MsiApplyMultiplePatchesW(LPCWSTR, LPCWSTR, LPCWSTR);
#define MsiApplyMultiplePatches WINELIB_NAME_AW(MsiApplyMultiplePatches)
--
1.7.4.1
More information about the wine-patches
mailing list