|
|
#include "stdinc.h"
#include "macros.h"
#include "common.h"
#include "idp.h"
#include "sxsutil.h"
#include "fusionbuffer.h"
#include "fusionheap.h"
#define CA_MIGRATE_ASM_CACHE_DIR L"%windir%\\asmcache\\"
HRESULT CA_Migrate_RemoveAssemblyFromAsmCache(CStringBuffer & fullpath) { HRESULT hr = S_OK;
IFFAILED_EXIT(ca_SxspDeleteDirectory(fullpath)); Exit: return hr; }
HRESULT CA_Migrate_CopyFileToAsmCache(CA_ENM_ASSEMBLY_FILES_CALLBACK_INFO * pInfo) { HRESULT hr = S_OK; CStringBuffer sbFileName; CStringBuffer sbDestFileName; PWSTR p = NULL;
PARAMETER_CHECK_NTC(dwFlags == 0); PARAMETER_CHECK_NTC(pInfo != NULL);
IFFAILED_EXIT(MSI_GetSourceFileFullPathName(CA_FILEFULLPATHNAME_FILENAME_IN_FILE_TABLE, pInfo->hInstall, pInfo->pszComponentSourceDirectory, pszFileNameInFileTable, sbFileName, NULL));
IFFALSE_EXIT(sbDestFileName.Win32Assign(pInfo->pszAssemblyInAsmCache, wcslen(pInfo->pszAssemblyInAsmCache))); // no trailing slash
p = wcsrchr(sbFileName, L'\\'); INTERNAL_ERROR_CHECK_NTC(p != NULL); IFFALSE_EXIT(sbDestFileName.Win32Append(p, wcslen(p))); IFFALSE_EXIT(CopyFileW(sbFileName, sbDestFileName, FALSE));
Exit: return hr; }
HRESULT CA_Migrate_AddAssemblyIntoAsmCache(DWORD dwFlags, const CA_ENM_ASSEMBLY_FILES_CALLBACK_INFO * info) { HRESULT hr = S_OK;
IFFAILED_EXIT(MSI_EnumComponentFiles(info, CA_Migrate_CopyFileToAsmCache));
Exit: return hr; }
HRESULT GetXPInstalledDirectory(MSIHANDLE hInstall, PCWSTR pszComponentID, PWSTR pszAsmDir, DWORD cchbuf) { PMSIHANDLE hdb = NULL; HRESULT hr = S_OK; WCHAR sqlbuf[CA_MAX_BUF]; PMSIHANDLE hView = NULL; MSIHANDLE hRecord = NULL; WCHAR bufName[CA_MAX_BUF]; DWORD cchName; WCHAR bufValue[CA_MAX_BUF]; DWORD cchValue; BOOL fWin32, fWin32Policy; CStringBuffer sbPathBuffer;
UINT iRet;
ASSEMBLY_IDENTITY_ATTRIBUTE Attribute; PASSEMBLY_IDENTITY AssemblyIdentity = NULL;
PARAMETER_CHECK_NTC(hInstall != NULL); PARAMETER_CHECK_NTC((pszComponentID != NULL) && (pszAsmDir != NULL));
hdb = MsiGetActiveDatabase(hInstall);
INTERNAL_ERROR_CHECK_NTC( hdb != NULL); IFFALSE_EXIT(::SxsCreateAssemblyIdentity(0, ASSEMBLY_IDENTITY_TYPE_DEFINITION, &AssemblyIdentity, 0, NULL)); swprintf(sqlbuf, L"SELECT Name, Value FROM MsiAssemblyName WHERE Component_='%s'", pszComponentID);
IF_NOTSUCCESS_SET_HRERR_EXIT(::MsiDatabaseOpenViewW(hdb, sqlbuf, &hView)); IF_NOTSUCCESS_SET_HRERR_EXIT(::MsiViewExecute(hView, 0));
for (;;) { //
// for each entry in MsiAssembly Table
//
iRet = MsiViewFetch(hView, &hRecord); if (iRet == ERROR_NO_MORE_ITEMS) break; if (iRet != ERROR_SUCCESS ) SET_HRERR_AND_EXIT(iRet);
cchName = NUMBER_OF(bufName); cchValue = NUMBER_OF(bufValue);
IF_NOTSUCCESS_SET_HRERR_EXIT(MsiRecordGetStringW(hRecord, 1, bufName, &cchName)); IF_NOTSUCCESS_SET_HRERR_EXIT(MsiRecordGetStringW(hRecord, 2, bufValue, &cchValue));
Attribute.Flags = 0; Attribute.NamespaceCch = 0; Attribute.Namespace = NULL; Attribute.NameCch = cchName; Attribute.Name = bufName; Attribute.ValueCch = cchValue; Attribute.Value = bufValue;
IFFALSE_EXIT(::SxsInsertAssemblyIdentityAttribute(0, AssemblyIdentity, &Attribute)); } IFFALSE_EXIT(SxsHashAssemblyIdentity(0, AssemblyIdentity, NULL));
//
// generate the path, something like x86_ms-sxstest-sfp_75e377300ab7b886_1.0.0.0_en_04f354da
//
IFFAILED_EXIT(ca_SxspDetermineAssemblyType(AssemblyIdentity, fWin32, fWin32Policy));
IFFAILED_EXIT(ca_SxspGenerateSxsPath( SXSP_GENERATE_SXS_PATH_FLAG_OMIT_ROOT | (fWin32Policy ? SXSP_GENERATE_SXS_PATH_FLAG_OMIT_VERSION : 0), SXSP_GENERATE_SXS_PATH_PATHTYPE_ASSEMBLY, NULL, 0, AssemblyIdentity, sbPathBuffer));
if (sbPathBuffer.Cch() > cchbuf) { SET_HRERR_AND_EXIT(ERROR_INSUFFICIENT_BUFFER); }
wcscpy(pszAsmDir, sbPathBuffer);
Exit: SxsDestroyAssemblyIdentity(AssemblyIdentity); return hr; }
//
// CA for Fusion Win32 Assembly installation on downlevel(only) :
// copy files into %windir%\asmcache\textual-identity-of-this-assembly\ //
// In order to generate textual-assembly-name,
// be sure to put this CustomAction after MsiAssemblyName table is filled
//
HRESULT __stdcall CA_MigrateDll_Callback(DWORD dwFlags, MSIHANDLE hInstall, PCWSTR pszComponentID, PCWSTR pszManifetFileID) { HRESULT hr = S_OK; WCHAR buf[MAX_PATH]; DWORD cchbuf = NUMBER_OF(buf); CStringBuffer fullpath; DWORD dwAttrib; enum CA_MIGRATION_MSI_INSTALL_MODE fMode; PMSIHANDLE hdb = NULL;
PARAMETER_CHECK_NTC(dwFlags == 0); PARAMETER_CHECK_NTC(hInstall != NULL); PARAMETER_CHECK_NTC(pszComponentID != NULL); PARAMETER_CHECK_NTC(pszManifetFileID != NULL);
hdb = MsiGetActiveDatabase(hInstall); INTERNAL_ERROR_CHECK_NTC(hdb != NULL); UINT iret = ExpandEnvironmentStringsW(CA_MIGRATE_ASM_CACHE_DIR, buf, NUMBER_OF(buf)); if (( iret == 0 ) || (iret > NUMBER_OF(buf))) { SET_HRERR_AND_EXIT(::GetLastError()); }
IFFALSE_EXIT(fullpath.Win32Assign(buf, wcslen(buf))); dwAttrib = GetFileAttributesW(fullpath); if ( dwAttrib == DWORD(-1) ) { IFFALSE_EXIT(CreateDirectoryW(fullpath, NULL)); }else { ASSERT_NTC(dwAttrib & FILE_ATTRIBUTE_DIRECTORY); INTERNAL_ERROR_CHECK_NTC((dwAttrib & FILE_ATTRIBUTE_DIRECTORY) != 0); } //
// based on Attributes&Value in MsiAssemblyName Table to generate "x86_assemblyName_6595b64144ccf1df_6.0.0.0_x-ww_98a51133"
//
IFFAILED_EXIT(GetXPInstalledDirectory(hInstall, pszComponentID, buf, cchbuf)); IFFALSE_EXIT(fullpath.Win32Append(buf, wcslen(buf)));
DWORD dwAttribs = GetFileAttributesW(fullpath);
IFFAILED_EXIT(MSI_GetInstallerState(hInstall, fMode));
if ( fMode == eRemoveProduct) { ASSERT_NTC((dwAttribs != 0) && (dwAttribs & FILE_ATTRIBUTE_DIRECTORY)); IFFAILED_EXIT(CA_Migrate_RemoveAssemblyFromAsmCache(fullpath)); }else { CA_ENM_ASSEMBLY_FILES_CALLBACK_INFO info ; ZeroMemory(&info, sizeof(info));
hdb = MsiGetActiveDatabase(hInstall); IFFAILED_EXIT(MSI_GetComponentSourceDirectory(hInstall, pszComponentID, buf, cchbuf)); info.pszAssemblyInAsmCache = fullpath; info.pszComponentID = pszComponentID; info.pszComponentSourceDirectory = buf; info.hInstall = hInstall;
IFFALSE_EXIT(CreateDirectoryW(fullpath, NULL)); IFFAILED_EXIT(CA_Migrate_AddAssemblyIntoAsmCache(0, &info)); }
Exit: return hr; }
HRESULT __stdcall CustomAction_CopyFusionWin32AsmIntoAsmCache(MSIHANDLE hInstall) { HRESULT hr = S_OK;
PMSIHANDLE hdb = NULL; PMSIHANDLE hView = NULL; MSIHANDLE hRecord = NULL;
#if DBG
MessageBoxA(NULL, "Enjoy the Debug", "ca_migrate", MB_OK); #endif
hdb = MsiGetActiveDatabase(hInstall); if ( hdb == 0) SETFAIL_AND_EXIT;
IFFAILED_EXIT(MSI_EnumWinFuseAssembly(0, hInstall, CA_MigrateDll_Callback));
Exit: return hr; }
BOOL WINAPI DllMain( HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved ) { if (fdwReason == DLL_PROCESS_ATTACH) { FusionpInitializeHeap(NULL); } return TRUE; }
|