msi: Add a stub implementation of MsiDeterminePatchSequence.
This commit is contained in:
parent
9299319b88
commit
537a5932b0
240
dlls/msi/msi.c
240
dlls/msi/msi.c
|
@ -492,6 +492,33 @@ UINT WINAPI MsiApplyMultiplePatchesW(LPCWSTR szPatchPackages,
|
||||||
return r;
|
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,
|
UINT WINAPI MsiDetermineApplicablePatchesA(LPCSTR szProductPackagePath,
|
||||||
DWORD cPatchInfo, PMSIPATCHSEQUENCEINFOA pPatchInfo)
|
DWORD cPatchInfo, PMSIPATCHSEQUENCEINFOA pPatchInfo)
|
||||||
{
|
{
|
||||||
|
@ -499,24 +526,16 @@ UINT WINAPI MsiDetermineApplicablePatchesA(LPCSTR szProductPackagePath,
|
||||||
WCHAR *package_path = NULL;
|
WCHAR *package_path = NULL;
|
||||||
MSIPATCHSEQUENCEINFOW *psi;
|
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 )))
|
if (szProductPackagePath && !(package_path = strdupAtoW( szProductPackagePath )))
|
||||||
return ERROR_OUTOFMEMORY;
|
return ERROR_OUTOFMEMORY;
|
||||||
|
|
||||||
psi = msi_alloc( cPatchInfo * sizeof(*psi) );
|
if (!(psi = patchinfoAtoW( cPatchInfo, pPatchInfo )))
|
||||||
if (!psi)
|
|
||||||
{
|
{
|
||||||
msi_free( package_path );
|
msi_free( package_path );
|
||||||
return ERROR_OUTOFMEMORY;
|
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 );
|
r = MsiDetermineApplicablePatchesW( package_path, cPatchInfo, psi );
|
||||||
if (r == ERROR_SUCCESS)
|
if (r == ERROR_SUCCESS)
|
||||||
{
|
{
|
||||||
|
@ -526,11 +545,8 @@ UINT WINAPI MsiDetermineApplicablePatchesA(LPCSTR szProductPackagePath,
|
||||||
pPatchInfo[i].uStatus = psi[i].uStatus;
|
pPatchInfo[i].uStatus = psi[i].uStatus;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
msi_free( package_path );
|
msi_free( package_path );
|
||||||
for (i = 0; i < cPatchInfo; i++)
|
free_patchinfo( cPatchInfo, psi );
|
||||||
msi_free( (WCHAR *)psi[i].szPatchData );
|
|
||||||
msi_free( psi );
|
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -563,13 +579,52 @@ static UINT MSI_ApplicablePatchW( MSIPACKAGE *package, LPCWSTR patch )
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static UINT determine_patch_sequence( MSIPACKAGE *package, DWORD count, MSIPATCHSEQUENCEINFOW *info )
|
||||||
|
{
|
||||||
|
DWORD i;
|
||||||
|
|
||||||
|
for (i = 0; i < count; i++)
|
||||||
|
{
|
||||||
|
switch (info[i].ePatchDataType)
|
||||||
|
{
|
||||||
|
case MSIPATCH_DATATYPE_PATCHFILE:
|
||||||
|
{
|
||||||
|
FIXME("patch ordering not supported\n");
|
||||||
|
if (MSI_ApplicablePatchW( package, info[i].szPatchData ) != ERROR_SUCCESS)
|
||||||
|
{
|
||||||
|
info[i].dwOrder = ~0u;
|
||||||
|
info[i].uStatus = ERROR_PATCH_TARGET_NOT_FOUND;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
info[i].dwOrder = i;
|
||||||
|
info[i].uStatus = ERROR_SUCCESS;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
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(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 ERROR_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
UINT WINAPI MsiDetermineApplicablePatchesW(LPCWSTR szProductPackagePath,
|
UINT WINAPI MsiDetermineApplicablePatchesW(LPCWSTR szProductPackagePath,
|
||||||
DWORD cPatchInfo, PMSIPATCHSEQUENCEINFOW pPatchInfo)
|
DWORD cPatchInfo, PMSIPATCHSEQUENCEINFOW pPatchInfo)
|
||||||
{
|
{
|
||||||
UINT i, r, ret = ERROR_FUNCTION_FAILED;
|
UINT r;
|
||||||
MSIPACKAGE *package;
|
MSIPACKAGE *package;
|
||||||
|
|
||||||
TRACE("(%s, %d, %p)\n", debugstr_w(szProductPackagePath), cPatchInfo, pPatchInfo);
|
TRACE("%s, %u, %p\n", debugstr_w(szProductPackagePath), cPatchInfo, pPatchInfo);
|
||||||
|
|
||||||
r = MSI_OpenPackageW( szProductPackagePath, &package );
|
r = MSI_OpenPackageW( szProductPackagePath, &package );
|
||||||
if (r != ERROR_SUCCESS)
|
if (r != ERROR_SUCCESS)
|
||||||
|
@ -577,100 +632,97 @@ UINT WINAPI MsiDetermineApplicablePatchesW(LPCWSTR szProductPackagePath,
|
||||||
ERR("failed to open package %u\n", r);
|
ERR("failed to open package %u\n", r);
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
r = determine_patch_sequence( package, cPatchInfo, pPatchInfo );
|
||||||
|
msiobj_release( &package->hdr );
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
for (i = 0; i < cPatchInfo; i++)
|
UINT WINAPI MsiDeterminePatchSequenceA( LPCSTR product, LPCSTR usersid,
|
||||||
|
MSIINSTALLCONTEXT context, DWORD count, PMSIPATCHSEQUENCEINFOA patchinfo )
|
||||||
|
{
|
||||||
|
UINT i, r;
|
||||||
|
WCHAR *productW, *usersidW = NULL;
|
||||||
|
MSIPATCHSEQUENCEINFOW *patchinfoW;
|
||||||
|
|
||||||
|
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 )))
|
||||||
{
|
{
|
||||||
switch (pPatchInfo[i].ePatchDataType)
|
msi_free( productW );
|
||||||
{
|
return ERROR_OUTOFMEMORY;
|
||||||
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;
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
UINT WINAPI MsiDeterminePatchSequenceA(LPCSTR szProductCode, LPCSTR szUserSid,
|
static UINT open_package( const WCHAR *product, const WCHAR *usersid,
|
||||||
MSIINSTALLCONTEXT dwContext, DWORD cPatchInfo, PMSIPATCHSEQUENCEINFOA pPatchInfo)
|
MSIINSTALLCONTEXT context, MSIPACKAGE **package )
|
||||||
{
|
|
||||||
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;
|
UINT r;
|
||||||
DWORD sz;
|
|
||||||
HKEY props;
|
HKEY props;
|
||||||
LPWSTR localpack;
|
WCHAR *localpath, sourcepath[MAX_PATH], filename[MAX_PATH];
|
||||||
WCHAR sourcepath[MAX_PATH];
|
|
||||||
WCHAR filename[MAX_PATH];
|
|
||||||
|
|
||||||
r = MSIREG_OpenInstallProps(product, context, NULL, &props, FALSE);
|
r = MSIREG_OpenInstallProps( product, context, usersid, &props, FALSE );
|
||||||
if (r != ERROR_SUCCESS)
|
if (r != ERROR_SUCCESS) return ERROR_BAD_CONFIGURATION;
|
||||||
return ERROR_BAD_CONFIGURATION;
|
|
||||||
|
|
||||||
localpack = msi_reg_get_val_str(props, szLocalPackage);
|
if ((localpath = msi_reg_get_val_str( props, szLocalPackage )))
|
||||||
if (localpack)
|
|
||||||
{
|
{
|
||||||
lstrcpyW(sourcepath, localpack);
|
strcpyW( sourcepath, localpath );
|
||||||
msi_free(localpack);
|
msi_free( localpath );
|
||||||
}
|
}
|
||||||
|
RegCloseKey( props );
|
||||||
if (!localpack || GetFileAttributesW(sourcepath) == INVALID_FILE_ATTRIBUTES)
|
if (!localpath || GetFileAttributesW( sourcepath ) == INVALID_FILE_ATTRIBUTES)
|
||||||
{
|
{
|
||||||
sz = sizeof(sourcepath);
|
DWORD sz = sizeof(sourcepath);
|
||||||
MsiSourceListGetInfoW(product, NULL, context, MSICODE_PRODUCT,
|
MsiSourceListGetInfoW( product, usersid, context, MSICODE_PRODUCT,
|
||||||
INSTALLPROPERTY_LASTUSEDSOURCEW, sourcepath, &sz);
|
INSTALLPROPERTY_LASTUSEDSOURCEW, sourcepath, &sz );
|
||||||
|
|
||||||
sz = sizeof(filename);
|
sz = sizeof(filename);
|
||||||
MsiSourceListGetInfoW(product, NULL, context, MSICODE_PRODUCT,
|
MsiSourceListGetInfoW( product, usersid, context, MSICODE_PRODUCT,
|
||||||
INSTALLPROPERTY_PACKAGENAMEW, filename, &sz);
|
INSTALLPROPERTY_PACKAGENAMEW, filename, &sz );
|
||||||
|
strcatW( sourcepath, filename );
|
||||||
lstrcatW(sourcepath, filename);
|
|
||||||
}
|
}
|
||||||
|
if (GetFileAttributesW( sourcepath ) == INVALID_FILE_ATTRIBUTES)
|
||||||
if (GetFileAttributesW(sourcepath) == INVALID_FILE_ATTRIBUTES)
|
|
||||||
return ERROR_INSTALL_SOURCE_ABSENT;
|
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,
|
UINT WINAPI MsiConfigureProductExW(LPCWSTR szProduct, int iInstallLevel,
|
||||||
|
@ -709,7 +761,7 @@ UINT WINAPI MsiConfigureProductExW(LPCWSTR szProduct, int iInstallLevel,
|
||||||
if (r != ERROR_SUCCESS)
|
if (r != ERROR_SUCCESS)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
r = msi_open_package(szProduct, context, &package);
|
r = open_package(szProduct, NULL, context, &package);
|
||||||
if (r != ERROR_SUCCESS)
|
if (r != ERROR_SUCCESS)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
|
|
|
@ -673,6 +673,10 @@ UINT WINAPI MsiDetermineApplicablePatchesA(LPCSTR, DWORD, PMSIPATCHSEQUENCEINFOA
|
||||||
UINT WINAPI MsiDetermineApplicablePatchesW(LPCWSTR, DWORD, PMSIPATCHSEQUENCEINFOW);
|
UINT WINAPI MsiDetermineApplicablePatchesW(LPCWSTR, DWORD, PMSIPATCHSEQUENCEINFOW);
|
||||||
#define MsiDetermineApplicablePatches WINELIB_NAME_AW(MsiDetermineApplicablePatches)
|
#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 MsiApplyMultiplePatchesA(LPCSTR, LPCSTR, LPCSTR);
|
||||||
UINT WINAPI MsiApplyMultiplePatchesW(LPCWSTR, LPCWSTR, LPCWSTR);
|
UINT WINAPI MsiApplyMultiplePatchesW(LPCWSTR, LPCWSTR, LPCWSTR);
|
||||||
#define MsiApplyMultiplePatches WINELIB_NAME_AW(MsiApplyMultiplePatches)
|
#define MsiApplyMultiplePatches WINELIB_NAME_AW(MsiApplyMultiplePatches)
|
||||||
|
|
Loading…
Reference in New Issue