/******************************************************************** ComPlusInstallExecuteCommit - CUSTOM ACTION ENTRY POINT Input: deferred CustomActionData - ComPlusInstallExecuteCommit ********************************************************************/ extern "C" UINT __stdcall ComPlusInstallExecuteCommit(MSIHANDLE hInstall) { HRESULT hr = S_OK; UINT er = ERROR_SUCCESS; LPWSTR pwzData = NULL; LPWSTR pwzRollbackFileName = NULL; HANDLE hRollbackFile = INVALID_HANDLE_VALUE; BOOL fInitializedCom = FALSE; // initialize hr = WcaInitialize(hInstall, "ComPlusInstallExecuteCommit"); ExitOnFailure(hr, "Failed to initialize ComPlusInstallExecuteCommit"); hr = ::CoInitialize(NULL); ExitOnFailure(hr, "Failed to initialize COM"); fInitializedCom = TRUE; CpiInitialize(); // get custom action data hr = WcaGetProperty(L"CustomActionData", &pwzData); ExitOnFailure(hr, "Failed to get CustomActionData"); // open rollback file hr = WcaReadStringFromCaData(&pwzData, &pwzRollbackFileName); ExitOnFailure(hr, "Failed to read rollback file name"); hRollbackFile = ::CreateFileW(pwzRollbackFileName, GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_TEMPORARY, NULL); if (INVALID_HANDLE_VALUE == hRollbackFile) ExitOnFailure1(hr = HRESULT_FROM_WIN32(::GetLastError()), "Failed to open rollback file, name: %S", pwzRollbackFileName); if (INVALID_SET_FILE_POINTER == ::SetFilePointer(hRollbackFile, 0, NULL, FILE_END)) ExitOnFailure(hr = HRESULT_FROM_WIN32(::GetLastError()), "Failed to set file pointer"); // register assemblies hr = CpiConfigureAssemblies(&pwzData, hRollbackFile); ExitOnFailure(hr, "Failed to register assemblies"); if (S_FALSE == hr) ExitFunction(); // create role assignments hr = CpiConfigureRoleAssignments(&pwzData, hRollbackFile); ExitOnFailure(hr, "Failed to create role assignments"); if (S_FALSE == hr) ExitFunction(); // create subscriptions hr = CpiConfigureSubscriptions(&pwzData, hRollbackFile); ExitOnFailure(hr, "Failed to create subscriptions"); if (S_FALSE == hr) ExitFunction(); hr = S_OK; LExit: // clean up ReleaseStr(pwzData); if (INVALID_HANDLE_VALUE != hRollbackFile) ::CloseHandle(hRollbackFile); // unitialize CpiFinalize(); if (fInitializedCom) ::CoUninitialize(); er = SUCCEEDED(hr) ? ERROR_SUCCESS : ERROR_INSTALL_FAILURE; return WcaFinalize(er); }
/******************************************************************** ComPlusRollbackUninstallExecute - CUSTOM ACTION ENTRY POINT Input: deferred CustomActionData - ComPlusRollbackUninstallExecute ********************************************************************/ extern "C" UINT __stdcall ComPlusRollbackUninstallExecute(MSIHANDLE hInstall) { HRESULT hr = S_OK; UINT er = ERROR_SUCCESS; LPWSTR pwzData = NULL; LPWSTR pwzRollbackFileName = NULL; HANDLE hRollbackFile = INVALID_HANDLE_VALUE; CPI_ROLLBACK_DATA* prdPartitions = NULL; CPI_ROLLBACK_DATA* prdUsersInPartitionRoles = NULL; CPI_ROLLBACK_DATA* prdPartitionUsers = NULL; CPI_ROLLBACK_DATA* prdApplications = NULL; CPI_ROLLBACK_DATA* prdApplicationRoles = NULL; CPI_ROLLBACK_DATA* prdUsersApplicationRoles = NULL; CPI_ROLLBACK_DATA* prdAssemblies = NULL; CPI_ROLLBACK_DATA* prdRoleAssignments = NULL; CPI_ROLLBACK_DATA* prdSubscriptions = NULL; BOOL fInitializedCom = FALSE; // initialize hr = WcaInitialize(hInstall, "ComPlusRollbackUninstallExecute"); ExitOnFailure(hr, "Failed to initialize ComPlusRollbackUninstallExecute"); hr = ::CoInitialize(NULL); ExitOnFailure(hr, "Failed to initialize COM"); fInitializedCom = TRUE; CpiInitialize(); // get custom action data hr = WcaGetProperty(L"CustomActionData", &pwzData); ExitOnFailure(hr, "Failed to get CustomActionData"); // open rollback file hr = WcaReadStringFromCaData(&pwzData, &pwzRollbackFileName); ExitOnFailure(hr, "Failed to read rollback file name"); hRollbackFile = ::CreateFileW(pwzRollbackFileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_TEMPORARY, NULL); if (INVALID_HANDLE_VALUE == hRollbackFile) ExitOnFailure1(hr = HRESULT_FROM_WIN32(::GetLastError()), "Failed to open rollback file, name: %S", pwzRollbackFileName); // read rollback data hr = CpiReadRollbackDataList(hRollbackFile, &prdSubscriptions); ExitOnFailure(hr, "Failed to read subscription rollback data"); hr = CpiReadRollbackDataList(hRollbackFile, &prdRoleAssignments); ExitOnFailure(hr, "Failed to read role assignments rollback data"); hr = CpiReadRollbackDataList(hRollbackFile, &prdAssemblies); ExitOnFailure(hr, "Failed to read assemblies rollback data"); hr = CpiReadRollbackDataList(hRollbackFile, &prdUsersApplicationRoles); ExitOnFailure(hr, "Failed to read users in application roles rollback data"); hr = CpiReadRollbackDataList(hRollbackFile, &prdApplicationRoles); ExitOnFailure(hr, "Failed to read application roles rollback data"); hr = CpiReadRollbackDataList(hRollbackFile, &prdApplications); ExitOnFailure(hr, "Failed to read applications rollback data"); hr = CpiReadRollbackDataList(hRollbackFile, &prdPartitionUsers); ExitOnFailure(hr, "Failed to read partition users rollback data"); hr = CpiReadRollbackDataList(hRollbackFile, &prdUsersInPartitionRoles); ExitOnFailure(hr, "Failed to read users in partition roles rollback data"); hr = CpiReadRollbackDataList(hRollbackFile, &prdPartitions); ExitOnFailure(hr, "Failed to read partitions rollback data"); ::CloseHandle(hRollbackFile); hRollbackFile = INVALID_HANDLE_VALUE; // rollback remove partitions hr = CpiRollbackConfigurePartitions(&pwzData, prdPartitions); ExitOnFailure(hr, "Failed to rollback delete partitions"); // rollback remove users in partition roles hr = CpiRollbackConfigureUsersInPartitionRoles(&pwzData, prdUsersInPartitionRoles); ExitOnFailure(hr, "Failed to rollback delete users in partition roles"); // rollback remove partition users hr = CpiRollbackConfigurePartitionUsers(&pwzData, prdPartitionUsers); ExitOnFailure(hr, "Failed to rollback delete partition users"); // rollback remove applications hr = CpiRollbackConfigureApplications(&pwzData, prdApplications); ExitOnFailure(hr, "Failed to rollback delete applications"); // rollback remove application roles hr = CpiRollbackConfigureApplicationRoles(&pwzData, prdApplicationRoles); ExitOnFailure(hr, "Failed to rollback delete application roles"); // rollback remove users in application roles hr = CpiRollbackConfigureUsersInApplicationRoles(&pwzData, prdUsersApplicationRoles); ExitOnFailure(hr, "Failed to rollback delete users in application roles"); // rollback unregister assemblies hr = CpiRollbackConfigureAssemblies(&pwzData, prdAssemblies); ExitOnFailure(hr, "Failed to rollback unregister assemblies"); // rollback delete role assignments hr = CpiRollbackConfigureRoleAssignments(&pwzData, prdAssemblies); ExitOnFailure(hr, "Failed to rollback delete role assignments"); // rollback delete subscriptions hr = CpiRollbackConfigureSubscriptions(&pwzData, prdSubscriptions); ExitOnFailure(hr, "Failed to rollback delete subscriptions"); hr = S_OK; LExit: // clean up ReleaseStr(pwzData); ReleaseStr(pwzRollbackFileName); if (INVALID_HANDLE_VALUE != hRollbackFile) ::CloseHandle(hRollbackFile); if (prdPartitions) CpiFreeRollbackDataList(prdPartitions); if (prdUsersInPartitionRoles) CpiFreeRollbackDataList(prdUsersInPartitionRoles); if (prdPartitionUsers) CpiFreeRollbackDataList(prdPartitionUsers); if (prdApplications) CpiFreeRollbackDataList(prdApplications); if (prdApplicationRoles) CpiFreeRollbackDataList(prdApplicationRoles); if (prdUsersApplicationRoles) CpiFreeRollbackDataList(prdUsersApplicationRoles); if (prdAssemblies) CpiFreeRollbackDataList(prdAssemblies); if (prdRoleAssignments) CpiFreeRollbackDataList(prdRoleAssignments); if (prdSubscriptions) CpiFreeRollbackDataList(prdSubscriptions); // unitialize CpiFinalize(); if (fInitializedCom) ::CoUninitialize(); er = SUCCEEDED(hr) ? ERROR_SUCCESS : ERROR_INSTALL_FAILURE; return WcaFinalize(er); }
/******************************************************************** ConfigureComPlusInstall - CUSTOM ACTION ENTRY POINT for installing COM+ components ********************************************************************/ extern "C" UINT __stdcall ConfigureComPlusInstall(MSIHANDLE hInstall) { HRESULT hr = S_OK; UINT er = ERROR_SUCCESS; BOOL fInitializedCom = FALSE; ICOMAdminCatalog* piCatalog = NULL; CPI_PARTITION_LIST partList; CPI_PARTITION_ROLE_LIST partRoleList; CPI_USER_IN_PARTITION_ROLE_LIST usrInPartRoleList; CPI_PARTITION_USER_LIST partUsrList; CPI_APPLICATION_LIST appList; CPI_APPLICATION_ROLE_LIST appRoleList; CPI_USER_IN_APPLICATION_ROLE_LIST usrInAppRoleList; CPI_ASSEMBLY_LIST asmList; CPI_SUBSCRIPTION_LIST subList; LPWSTR pwzRollbackFileName = NULL; LPWSTR pwzActionData = NULL; LPWSTR pwzRollbackActionData = NULL; LPWSTR pwzCommitActionData = NULL; int iVersionNT = 0; int iProgress = 0; int iCommitProgress = 0; ::ZeroMemory(&partList, sizeof(CPI_PARTITION_LIST)); ::ZeroMemory(&partRoleList, sizeof(CPI_PARTITION_ROLE_LIST)); ::ZeroMemory(&usrInPartRoleList, sizeof(CPI_USER_IN_PARTITION_ROLE_LIST)); ::ZeroMemory(&partUsrList, sizeof(CPI_PARTITION_USER_LIST)); ::ZeroMemory(&appList, sizeof(CPI_APPLICATION_LIST)); ::ZeroMemory(&appRoleList, sizeof(CPI_APPLICATION_ROLE_LIST)); ::ZeroMemory(&usrInAppRoleList, sizeof(CPI_USER_IN_APPLICATION_ROLE_LIST)); ::ZeroMemory(&asmList, sizeof(CPI_ASSEMBLY_LIST)); ::ZeroMemory(&subList, sizeof(CPI_SUBSCRIPTION_LIST)); // initialize hr = WcaInitialize(hInstall, "ConfigureComPlusInstall"); ExitOnFailure(hr, "Failed to initialize"); hr = ::CoInitialize(NULL); ExitOnFailure(hr, "Failed to initialize COM"); fInitializedCom = TRUE; CpiInitialize(); // check for the prerequsite tables if (!CpiTableExists(cptComPlusPartition) && !CpiTableExists(cptComPlusApplication) && !CpiTableExists(cptComPlusAssembly)) { WcaLog(LOGMSG_VERBOSE, "skipping install COM+ CustomAction, no ComPlusPartition, ComPlusApplication or ComPlusAssembly table present"); ExitFunction1(hr = S_FALSE); } // make sure we can access the COM+ admin catalog do { hr = CpiGetAdminCatalog(&piCatalog); if (FAILED(hr)) { WcaLog(LOGMSG_STANDARD, "Failed to get COM+ admin catalog"); er = WcaErrorMessage(msierrComPlusCannotConnect, hr, INSTALLMESSAGE_ERROR | MB_ABORTRETRYIGNORE, 0); switch (er) { case IDABORT: ExitFunction(); // exit with hr from CpiGetAdminCatalog() to kick off a rollback case IDRETRY: hr = S_FALSE; break; case IDIGNORE: default: ExitFunction1(hr = S_OK); // pretend everything is okay and bail } } } while (S_FALSE == hr); // get NT version hr = WcaGetIntProperty(L"VersionNT", &iVersionNT); ExitOnFailure(hr, "Failed to get VersionNT property"); // read elements if (502 <= iVersionNT && CpiTableExists(cptComPlusPartition)) { hr = CpiPartitionsRead(&partList); MessageExitOnFailure(hr, msierrComPlusPartitionReadFailed, "Failed to read ComPlusPartitions table"); } if (502 <= iVersionNT && CpiTableExists(cptComPlusPartitionRole)) { hr = CpiPartitionRolesRead(&partList, &partRoleList); MessageExitOnFailure(hr, msierrComPlusPartitionRoleReadFailed, "Failed to read ComPlusPartitionRole table"); } if (502 <= iVersionNT && (CpiTableExists(cptComPlusUserInPartitionRole) || CpiTableExists(cptComPlusGroupInPartitionRole))) { hr = CpiUsersInPartitionRolesRead(&partRoleList, &usrInPartRoleList); MessageExitOnFailure(hr, msierrComPlusUserInPartitionRoleReadFailed, "Failed to read ComPlusUserInPartitionRole table"); } if (502 <= iVersionNT && CpiTableExists(cptComPlusPartitionUser)) { hr = CpiPartitionUsersRead(&partList, &partUsrList); MessageExitOnFailure(hr, msierrComPlusPartitionUserReadFailed, "Failed to read ComPlusPartitionUser table"); } if (CpiTableExists(cptComPlusApplication)) { hr = CpiApplicationsRead(&partList, &appList); MessageExitOnFailure(hr, msierrComPlusApplicationReadFailed, "Failed to read ComPlusApplication table"); } if (CpiTableExists(cptComPlusApplicationRole)) { hr = CpiApplicationRolesRead(&appList, &appRoleList); MessageExitOnFailure(hr, msierrComPlusApplicationRoleReadFailed, "Failed to read ComPlusApplicationRole table"); } if (CpiTableExists(cptComPlusUserInApplicationRole) || CpiTableExists(cptComPlusGroupInApplicationRole)) { hr = CpiUsersInApplicationRolesRead(&appRoleList, &usrInAppRoleList); MessageExitOnFailure(hr, msierrComPlusUserInApplicationRoleReadFailed, "Failed to read ComPlusUserInApplicationRole table"); } if (CpiTableExists(cptComPlusAssembly)) { hr = CpiAssembliesRead(&appList, &appRoleList, &asmList); MessageExitOnFailure(hr, msierrComPlusAssembliesReadFailed, "Failed to read ComPlusAssembly table"); } if (CpiTableExists(cptComPlusSubscription)) { hr = CpiSubscriptionsRead(&asmList, &subList); MessageExitOnFailure(hr, msierrComPlusSubscriptionReadFailed, "Failed to read ComPlusSubscription table"); } // verify elements hr = CpiPartitionsVerifyInstall(&partList); ExitOnFailure(hr, "Failed to verify partitions"); hr = CpiApplicationsVerifyInstall(&appList); ExitOnFailure(hr, "Failed to verify applications"); hr = CpiApplicationRolesVerifyInstall(&appRoleList); ExitOnFailure(hr, "Failed to verify application roles"); hr = CpiAssembliesVerifyInstall(&asmList); ExitOnFailure(hr, "Failed to verify assemblies"); if (subList.iInstallCount) { hr = CpiSubscriptionsVerifyInstall(&subList); ExitOnFailure(hr, "Failed to verify subscriptions"); } // schedule if (partList.iInstallCount || appList.iInstallCount || usrInAppRoleList.iInstallCount || appRoleList.iInstallCount || asmList.iInstallCount || asmList.iRoleInstallCount || subList.iInstallCount) { // create rollback file name hr = CpiGetTempFileName(&pwzRollbackFileName); ExitOnFailure(hr, "Failed to get rollback file name"); // schedule rollback prepare custom action hr = WcaDoDeferredAction(CP_COMPLUSROLLBACKINSTALLPREPARE, pwzRollbackFileName, 0); ExitOnFailure(hr, "Failed to schedule ComPlusRollbackInstallPrepare"); // schedule prepare custom action hr = WcaDoDeferredAction(CP_COMPLUSINSTALLPREPARE, pwzRollbackFileName, 0); ExitOnFailure(hr, "Failed to schedule ComPlusInstallPrepare"); // schedule rollback custom action hr = WcaWriteStringToCaData(pwzRollbackFileName, &pwzRollbackActionData); ExitOnFailure(hr, "Failed to add rollback file name to rollback custom action data"); hr = CpiSubscriptionsInstall(&subList, rmRollback, &pwzRollbackActionData, NULL); ExitOnFailure(hr, "Failed to install subscriptions"); hr = CpiRoleAssignmentsInstall(&asmList, rmRollback, &pwzRollbackActionData, NULL); ExitOnFailure(hr, "Failed to install assemblies"); hr = CpiAssembliesInstall(&asmList, rmRollback, &pwzRollbackActionData, NULL); ExitOnFailure(hr, "Failed to install assemblies"); hr = CpiUsersInApplicationRolesInstall(&usrInAppRoleList, rmRollback, &pwzRollbackActionData, NULL); ExitOnFailure(hr, "Failed to install users in application roles"); hr = CpiApplicationRolesInstall(&appRoleList, rmRollback, &pwzRollbackActionData, NULL); ExitOnFailure(hr, "Failed to install application roles"); hr = CpiApplicationsInstall(&appList, rmRollback, &pwzRollbackActionData, NULL); ExitOnFailure(hr, "Failed to install applications"); hr = CpiPartitionUsersInstall(&partUsrList, rmRollback, &pwzRollbackActionData, NULL); ExitOnFailure(hr, "Failed to install partition users"); hr = CpiUsersInPartitionRolesInstall(&usrInPartRoleList, rmRollback, &pwzRollbackActionData, NULL); ExitOnFailure(hr, "Failed to install users in partition roles"); hr = CpiPartitionsInstall(&partList, rmRollback, &pwzRollbackActionData, NULL); ExitOnFailure(hr, "Failed to install partitions"); hr = WcaDoDeferredAction(CP_COMPLUSROLLBACKINSTALLEXECUTE, pwzRollbackActionData, 0); ExitOnFailure(hr, "Failed to schedule ComPlusRollbackInstallExecute"); // schedule install custom action hr = WcaWriteStringToCaData(pwzRollbackFileName, &pwzActionData); ExitOnFailure(hr, "Failed to add rollback file name to custom action data"); hr = CpiPartitionsInstall(&partList, rmDeferred, &pwzActionData, &iProgress); ExitOnFailure(hr, "Failed to install partitions"); hr = CpiUsersInPartitionRolesInstall(&usrInPartRoleList, rmDeferred, &pwzActionData, &iProgress); ExitOnFailure(hr, "Failed to install users in partition roles"); hr = CpiPartitionUsersInstall(&partUsrList, rmDeferred, &pwzActionData, &iProgress); ExitOnFailure(hr, "Failed to install partition users"); hr = CpiApplicationsInstall(&appList, rmDeferred, &pwzActionData, &iProgress); ExitOnFailure(hr, "Failed to install applications"); hr = CpiApplicationRolesInstall(&appRoleList, rmDeferred, &pwzActionData, &iProgress); ExitOnFailure(hr, "Failed to install application roles"); hr = CpiUsersInApplicationRolesInstall(&usrInAppRoleList, rmDeferred, &pwzActionData, &iProgress); ExitOnFailure(hr, "Failed to install users in application roles"); hr = CpiAssembliesInstall(&asmList, rmDeferred, &pwzActionData, &iProgress); ExitOnFailure(hr, "Failed to install assemblies"); hr = CpiRoleAssignmentsInstall(&asmList, rmDeferred, &pwzActionData, &iProgress); ExitOnFailure(hr, "Failed to install assemblies"); hr = CpiSubscriptionsInstall(&subList, rmDeferred, &pwzActionData, &iProgress); ExitOnFailure(hr, "Failed to install subscriptions"); hr = WcaDoDeferredAction(CP_COMPLUSINSTALLEXECUTE, pwzActionData, iProgress); ExitOnFailure(hr, "Failed to schedule ComPlusInstallExecute"); // schedule install commit custom action hr = WcaWriteStringToCaData(pwzRollbackFileName, &pwzCommitActionData); ExitOnFailure(hr, "Failed to add rollback file name to commit custom action data"); hr = CpiAssembliesInstall(&asmList, rmCommit, &pwzCommitActionData, &iCommitProgress); ExitOnFailure(hr, "Failed to install assemblies"); hr = CpiRoleAssignmentsInstall(&asmList, rmCommit, &pwzCommitActionData, &iCommitProgress); ExitOnFailure(hr, "Failed to install assemblies"); hr = CpiSubscriptionsInstall(&subList, rmCommit, &pwzCommitActionData, &iCommitProgress); ExitOnFailure(hr, "Failed to install subscriptions"); hr = WcaDoDeferredAction(CP_COMPLUSINSTALLEXECUTECOMMIT, pwzCommitActionData, iCommitProgress); ExitOnFailure(hr, "Failed to schedule ComPlusInstallExecuteCommit"); // schedule commit custom action hr = WcaDoDeferredAction(CP_COMPLUSINSTALLCOMMIT, pwzRollbackFileName, 0); ExitOnFailure(hr, "Failed to schedule ComPlusInstallCommit"); } hr = S_OK; LExit: // clean up ReleaseObject(piCatalog); ReleaseStr(pwzRollbackFileName); ReleaseStr(pwzActionData); ReleaseStr(pwzRollbackActionData); ReleaseStr(pwzCommitActionData); CpiPartitionListFree(&partList); CpiPartitionRoleListFree(&partRoleList); CpiUserInPartitionRoleListFree(&usrInPartRoleList); CpiPartitionUserListFree(&partUsrList); CpiApplicationListFree(&appList); CpiApplicationRoleListFree(&appRoleList); CpiUserInApplicationRoleListFree(&usrInAppRoleList); CpiAssemblyListFree(&asmList); CpiSubscriptionListFree(&subList); // unitialize CpiFinalize(); if (fInitializedCom) ::CoUninitialize(); er = SUCCEEDED(hr) ? ERROR_SUCCESS : ERROR_INSTALL_FAILURE; return WcaFinalize(er); }