From ee41358bb583619ef4fe6707958dc3c6c62cd13f Mon Sep 17 00:00:00 2001 From: Bevan Weiss Date: Sun, 28 Jul 2024 00:12:25 +1000 Subject: [PATCH] Fix up COM+ to be back in working order under Wix4+ Table names updated for Wix4 prefix. Custom action names similarly updated. Table names Wix4ComPlusUserInApplicationRole, Wix4ComPlusGroupInApplicationRole and Wix4ComPlusApplicationRoleProperty had to be shortened to fit within MSI 31 character table name limit. Migrated from fixed GUID for RegistrationHelper to use CLSIDFromProgID in an attempt to fix behaviour under .NET 4+ DLLs. Added setting of Partition enable if a Partition is configured in authoring, new Windows config has Partitions disabled by default, and they don't work at all under Windows workstation (non-server) versions. Added a new Runtime condition for `RequireWindowsServer` which will skip execution of Runtime test on workstation/desktop OSes, since COM+ Partitions only work correctly under Windows Server. Quite a lot of basic typos fixed also. Signed-off-by: Bevan Weiss --- src/ext/ComPlus/ca/cpapproleexec.cpp | 4 +- src/ext/ComPlus/ca/cpapprolesched.cpp | 20 ++--- src/ext/ComPlus/ca/cpappsched.cpp | 2 +- src/ext/ComPlus/ca/cpasmexec.cpp | 50 ++++++++--- src/ext/ComPlus/ca/cpasmsched.cpp | 2 +- src/ext/ComPlus/ca/cpexec.cpp | 10 +-- src/ext/ComPlus/ca/cppartexec.cpp | 71 +++++++++++++++- src/ext/ComPlus/ca/cppartroleexec.cpp | 2 +- src/ext/ComPlus/ca/cppartrolesched.cpp | 4 +- src/ext/ComPlus/ca/cppartsched.cpp | 14 +-- src/ext/ComPlus/ca/cpsched.cpp | 80 ++++++++---------- src/ext/ComPlus/ca/cpsubsexec.cpp | 4 +- src/ext/ComPlus/ca/cputilsched.cpp | 52 ++++++------ src/ext/ComPlus/ca/precomp.h | 2 + .../ComPlus/wixext/ComPlusTableDefinitions.cs | 6 +- .../Directory.Packages.props.pp | 1 + .../burn/WixTestTools/RuntimeFactAttribute.cs | 30 +++++++ .../Components/TestComponentNET3.dll | Bin 0 -> 16384 bytes .../Components/TestComponentNET3.tlb | Bin 0 -> 2088 bytes .../Components/TestComponentNET4.dll | Bin 0 -> 16384 bytes .../Components/TestComponentNET4.tlb | Bin 0 -> 2088 bytes .../Components/TestComponentNative.dll | Bin 0 -> 56832 bytes ...tallUninstallNET3WithoutPartitions.wixproj | 15 ++++ .../product.wxs | 24 ++++++ ...tallUninstallNET4WithoutPartitions.wixproj | 15 ++++ .../product.wxs | 24 ++++++ ...llUninstallNativeWithoutPartitions.wixproj | 15 ++++ .../product.wxs | 24 ++++++ .../InstallUninstallWithPartitions.wixproj | 15 ++++ .../product.wxs | 30 +++++++ .../ComPlusExtensionTests.cs | 50 +++++++++++ 31 files changed, 446 insertions(+), 120 deletions(-) create mode 100644 src/test/msi/TestData/ComPlusExtensionTests/Components/TestComponentNET3.dll create mode 100644 src/test/msi/TestData/ComPlusExtensionTests/Components/TestComponentNET3.tlb create mode 100644 src/test/msi/TestData/ComPlusExtensionTests/Components/TestComponentNET4.dll create mode 100644 src/test/msi/TestData/ComPlusExtensionTests/Components/TestComponentNET4.tlb create mode 100644 src/test/msi/TestData/ComPlusExtensionTests/Components/TestComponentNative.dll create mode 100644 src/test/msi/TestData/ComPlusExtensionTests/InstallUninstallNET3WithoutPartitions/InstallUninstallNET3WithoutPartitions.wixproj create mode 100644 src/test/msi/TestData/ComPlusExtensionTests/InstallUninstallNET3WithoutPartitions/product.wxs create mode 100644 src/test/msi/TestData/ComPlusExtensionTests/InstallUninstallNET4WithoutPartitions/InstallUninstallNET4WithoutPartitions.wixproj create mode 100644 src/test/msi/TestData/ComPlusExtensionTests/InstallUninstallNET4WithoutPartitions/product.wxs create mode 100644 src/test/msi/TestData/ComPlusExtensionTests/InstallUninstallNativeWithoutPartitions/InstallUninstallNativeWithoutPartitions.wixproj create mode 100644 src/test/msi/TestData/ComPlusExtensionTests/InstallUninstallNativeWithoutPartitions/product.wxs create mode 100644 src/test/msi/TestData/ComPlusExtensionTests/InstallUninstallWithPartitions/InstallUninstallWithPartitions.wixproj create mode 100644 src/test/msi/TestData/ComPlusExtensionTests/InstallUninstallWithPartitions/product.wxs create mode 100644 src/test/msi/WixToolsetTest.MsiE2E/ComPlusExtensionTests.cs diff --git a/src/ext/ComPlus/ca/cpapproleexec.cpp b/src/ext/ComPlus/ca/cpapproleexec.cpp index e3b71e932..4b38b23c5 100644 --- a/src/ext/ComPlus/ca/cpapproleexec.cpp +++ b/src/ext/ComPlus/ca/cpapproleexec.cpp @@ -74,7 +74,7 @@ HRESULT CpiConfigureApplicationRoles( hr = CpiActionStartMessage(ppwzData, FALSE); ExitOnFailure(hr, "Failed to send action start message"); - // ger count + // get count int iCnt = 0; hr = WcaReadIntegerFromCaData(ppwzData, &iCnt); ExitOnFailure(hr, "Failed to read count"); @@ -218,7 +218,7 @@ HRESULT CpiConfigureUsersInApplicationRoles( hr = CpiActionStartMessage(ppwzData, FALSE); ExitOnFailure(hr, "Failed to send action start message"); - // ger count + // get count int iCnt = 0; hr = WcaReadIntegerFromCaData(ppwzData, &iCnt); ExitOnFailure(hr, "Failed to read count"); diff --git a/src/ext/ComPlus/ca/cpapprolesched.cpp b/src/ext/ComPlus/ca/cpapprolesched.cpp index 04de6b65a..a92c340c5 100644 --- a/src/ext/ComPlus/ca/cpapprolesched.cpp +++ b/src/ext/ComPlus/ca/cpapprolesched.cpp @@ -10,13 +10,13 @@ LPCWSTR vcsApplicationRoleQuery = enum eApplicationRoleQuery { arqApplicationRole = 1, arqApplication, arqComponent, arqName }; LPCWSTR vcsUserInApplicationRoleQuery = - L"SELECT `UserInApplicationRole`, `ApplicationRole_`, `ComPlusUserInApplicationRole`.`Component_`, `Domain`, `Name` FROM `Wix4ComPlusUserInApplicationRole`, `Wix4User` WHERE `User_` = `User`"; + L"SELECT `UserInApplicationRole`, `ApplicationRole_`, `Wix4ComPlusUserInAppRole`.`Component_`, `Domain`, `Name` FROM `Wix4ComPlusUserInAppRole`, `Wix4User` WHERE `User_` = `User`"; LPCWSTR vcsGroupInApplicationRoleQuery = - L"SELECT `GroupInApplicationRole`, `ApplicationRole_`, `ComPlusGroupInApplicationRole`.`Component_`, `Domain`, `Name` FROM `Wix4ComPlusGroupInApplicationRole`, `Wix4Group` WHERE `Group_` = `Group`"; + L"SELECT `GroupInApplicationRole`, `ApplicationRole_`, `Wix4ComPlusGroupInAppRole`.`Component_`, `Domain`, `Name` FROM `Wix4ComPlusGroupInAppRole`, `Wix4Group` WHERE `Group_` = `Group`"; enum eTrusteeInApplicationRoleQuery { tiarqUserInApplicationRole = 1, tiarqApplicationRole, tiarqComponent, tiarqDomain, tiarqName }; LPCWSTR vcsApplicationRolePropertyQuery = - L"SELECT `Name`, `Value` FROM `Wix4ComPlusApplicationRoleProperty` WHERE `ApplicationRole_` = ?"; + L"SELECT `Name`, `Value` FROM `Wix4ComPlusAppRoleProperty` WHERE `ApplicationRole_` = ?"; // property definitions @@ -95,7 +95,7 @@ HRESULT CpiApplicationRolesRead( // loop through all application roles hr = WcaOpenExecuteView(vcsApplicationRoleQuery, &hView); - ExitOnFailure(hr, "Failed to execute view on ComPlusApplicationRole table"); + ExitOnFailure(hr, "Failed to execute view on Wix4ComPlusApplicationRole table"); while (S_OK == (hr = WcaFetchRecord(hView, &hRec))) { @@ -205,7 +205,7 @@ HRESULT CpiApplicationRolesVerifyInstall( if (!pItm->fReferencedForInstall && !(pItm->fHasComponent && WcaIsInstalling(pItm->isInstalled, pItm->isAction))) continue; - // if the role is referensed and is not a locater, it must be installed + // if the role is referenced and is not a locater, it must be installed if (pItm->fReferencedForInstall && pItm->fHasComponent && !CpiWillBeInstalled(pItm->isInstalled, pItm->isAction)) MessageExitOnFailure(hr = E_FAIL, msierrComPlusApplicationRoleDependency, "An application role is used by another entity being installed, but is not installed itself, key: %S", pItm->wzKey); @@ -235,7 +235,7 @@ HRESULT CpiApplicationRolesVerifyInstall( switch (er) { case IDABORT: - ExitOnFailure(hr = E_FAIL, "An application with a conflictiong name exists, key: %S", pItm->wzKey); + ExitOnFailure(hr = E_FAIL, "An application with a conflicting name exists, key: %S", pItm->wzKey); break; case IDRETRY: break; @@ -319,7 +319,7 @@ HRESULT CpiApplicationRolesInstall( int iActionType; // add action text - hr = CpiAddActionTextToActionData(L"CreateComPlusApplicationRoles", ppwzActionData); + hr = CpiAddActionTextToActionData(CUSTOM_ACTION_DECORATION(L"CreateComPlusApplicationRoles"), ppwzActionData); ExitOnFailure(hr, "Failed to add action text to custom action data"); // add count to action data @@ -371,7 +371,7 @@ HRESULT CpiApplicationRolesUninstall( int iActionType; // add action text - hr = CpiAddActionTextToActionData(L"RemoveComPlusApplicationRoles", ppwzActionData); + hr = CpiAddActionTextToActionData(CUSTOM_ACTION_DECORATION(L"RemoveComPlusApplicationRoles"), ppwzActionData); ExitOnFailure(hr, "Failed to add action text to custom action data"); // add count to action data @@ -477,7 +477,7 @@ HRESULT CpiUsersInApplicationRolesInstall( int iActionType; // add action text - hr = CpiAddActionTextToActionData(L"AddUsersToComPlusApplicationRoles", ppwzActionData); + hr = CpiAddActionTextToActionData(CUSTOM_ACTION_DECORATION(L"AddUsersToComPlusApplicationRoles"), ppwzActionData); ExitOnFailure(hr, "Failed to add action text to custom action data"); // add count to action data @@ -529,7 +529,7 @@ HRESULT CpiUsersInApplicationRolesUninstall( int iActionType; // add action text - hr = CpiAddActionTextToActionData(L"RemoveUsersFromComPlusAppRoles", ppwzActionData); + hr = CpiAddActionTextToActionData(CUSTOM_ACTION_DECORATION(L"RemoveUsersFromComPlusAppRoles"), ppwzActionData); ExitOnFailure(hr, "Failed to add action text to custom action data"); // add count to action data diff --git a/src/ext/ComPlus/ca/cpappsched.cpp b/src/ext/ComPlus/ca/cpappsched.cpp index 4d867f6bd..bcd3bb75b 100644 --- a/src/ext/ComPlus/ca/cpappsched.cpp +++ b/src/ext/ComPlus/ca/cpappsched.cpp @@ -255,7 +255,7 @@ HRESULT CpiApplicationsVerifyInstall( if (!pItm->fReferencedForInstall && !(pItm->fHasComponent && WcaIsInstalling(pItm->isInstalled, pItm->isAction))) continue; - // if the application is referensed and is not a locater, it must be installed + // if the application is referenced and is not a locater, it must be installed if (pItm->fReferencedForInstall && pItm->fHasComponent && !CpiWillBeInstalled(pItm->isInstalled, pItm->isAction)) MessageExitOnFailure(hr = E_FAIL, msierrComPlusApplicationDependency, "An application is used by another entity being installed, but is not installed itself, key: %S", pItm->wzKey); diff --git a/src/ext/ComPlus/ca/cpasmexec.cpp b/src/ext/ComPlus/ca/cpasmexec.cpp index 3d140027c..af6c7eff2 100644 --- a/src/ext/ComPlus/ca/cpasmexec.cpp +++ b/src/ext/ComPlus/ca/cpasmexec.cpp @@ -1,7 +1,7 @@ // Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. #include "precomp.h" - +#include // GAC related declarations @@ -61,13 +61,11 @@ IAssemblyCache : public IUnknown typedef HRESULT (__stdcall *LoadLibraryShimFunc)(LPCWSTR szDllName, LPCWSTR szVersion, LPVOID pvReserved, HMODULE *phModDll); typedef HRESULT (__stdcall *CreateAssemblyCacheFunc)(IAssemblyCache **ppAsmCache, DWORD dwReserved); +typedef HRESULT (__stdcall *GetFileVersionFnPtr)(LPCWSTR szFilename, _Out_writes_to_opt_(cchBuffer, *dwLength) LPWSTR szBuffer, DWORD cchBuffer, DWORD* dwLength); +typedef HRESULT (__stdcall *CorBindToRuntimeExFnPtr)(LPCWSTR pwszVersion, LPCWSTR pwszBuildFlavor, DWORD startupFlags, REFCLSID rclsid, REFIID riid, LPVOID FAR* ppv); // RegistrationHelper related declarations - -static const GUID CLSID_RegistrationHelper = - { 0x89a86e7b, 0xc229, 0x4008, { 0x9b, 0xaa, 0x2f, 0x5c, 0x84, 0x11, 0xd7, 0xe0 } }; - enum eInstallationFlags { ifConfigureComponentsOnly = 16, ifFindOrCreateTargetApplication = 4, @@ -156,7 +154,8 @@ static HRESULT UnregisterAssembly( static void InitAssemblyExec(); static void UninitAssemblyExec(); static HRESULT GetRegistrationHelper( - IDispatch** ppiRegHlp + IDispatch** ppiRegHlp, + LPCWSTR pwzAssemblyPath ); static HRESULT GetAssemblyCacheObject( IAssemblyCache** ppAssemblyCache @@ -722,15 +721,44 @@ static void UninitAssemblyExec() } static HRESULT GetRegistrationHelper( - IDispatch** ppiRegHlp + IDispatch** ppiRegHlp, + LPCWSTR pwzAssemblyPath ) { HRESULT hr = S_OK; + wchar_t pwzVersion[MAX_PATH]; + DWORD pcchVersionLen = MAX_PATH; + ICLRRuntimeHost* runtimeHost = NULL; + + if (!ghMscoree) + { + ghMscoree = ::LoadLibraryW(L"mscoree.dll"); + ExitOnNull(ghMscoree, hr, E_FAIL, "Failed to load mscoree.dll"); + } + GetFileVersionFnPtr GetFileVersion = (GetFileVersionFnPtr)::GetProcAddress(ghMscoree, "GetFileVersion"); + ExitOnNull(GetFileVersion, hr, E_FAIL, "Failed to GetProcAddress for 'GetFileVersion' from 'mscoree.dll'"); + hr = GetFileVersion(pwzAssemblyPath, pwzVersion, pcchVersionLen, &pcchVersionLen); if (!gpiRegHlp) { + CLSID CLSID_RegistrationHelper{}; + hr = ::CLSIDFromProgID(OLESTR("System.EnterpriseServices.RegistrationHelper"), &CLSID_RegistrationHelper); + ExitOnFailure(hr, "Failed to identify CLSID for 'System.EnterpriseServices.RegistrationHelper'"); + + // NOTE: The 'CoreBindToRuntimeEx' method is DEPRECATED in .NET v4. + // HOWEVER, we might be running in an earlier context at this point so we don't want to rely upon stuff that is particularly v4 dependent. + // Even if we are about to try to fire up a v4 runtime. + // The .NET v4 runtime with STARTUP_LOADER_SAFEMODE flag (to disable version checking of loaded assemblies) is what lets us launch the + // RegistrationHelper. The v4 RegistrationHelper is able to register both v4 and v3 assemblies however, so if we can get it, we most as well + // use it. + CorBindToRuntimeExFnPtr CorBindToRuntimeEx = (CorBindToRuntimeExFnPtr)::GetProcAddress(ghMscoree, "CorBindToRuntimeEx"); + hr = CorBindToRuntimeEx(L"v4.0.30319", L"wks", STARTUP_LOADER_SAFEMODE, CLSID_CLRRuntimeHost, IID_ICLRRuntimeHost, (LPVOID*)&runtimeHost); + // we ignore the HRESULT here. If it worked, great, we'll use it moving forward. If it didn't work, we'll end up trying to resort to legacy .NET FW + // when we just try the COM Create below + // create registration helper object - hr = ::CoCreateInstance(CLSID_RegistrationHelper, NULL, CLSCTX_ALL, IID_IDispatch, (void**)&gpiRegHlp); + // This will be created in the .NET FW 4 version if we managed to launch it above, or in the .NET FW <4 version based on the COM dispatch otherwise + hr = ::CoCreateInstance(CLSID_RegistrationHelper, NULL, CLSCTX_ALL, IID_IDispatch, (void**)&gpiRegHlp); ExitOnFailure(hr, "Failed to create registration helper object"); } @@ -883,7 +911,7 @@ static HRESULT RegisterDotNetAssembly( } // get registration helper object - hr = GetRegistrationHelper(&piRegHlp); + hr = GetRegistrationHelper(&piRegHlp, pAttrs->pwzDllPath); ExitOnFailure(hr, "Failed to get registration helper object"); // get dispatch id of InstallAssembly() method @@ -979,7 +1007,7 @@ static HRESULT RegisterNativeAssembly( ExitOnNull(bstrTlbPath, hr, E_OUTOFMEMORY, "Failed to allocate BSTR for tlb path"); bstrPSDllPath = ::SysAllocString(pAttrs->pwzPSDllPath ? pAttrs->pwzPSDllPath : L""); - ExitOnNull(bstrPSDllPath, hr, E_OUTOFMEMORY, "Failed to allocate BSTR for tlb path"); + ExitOnNull(bstrPSDllPath, hr, E_OUTOFMEMORY, "Failed to allocate BSTR for proxy/stub dll path"); // get catalog hr = CpiExecGetAdminCatalog(&piCatalog); @@ -1089,7 +1117,7 @@ static HRESULT UnregisterDotNetAssembly( ExitOnNull(bstrDllPath, hr, E_OUTOFMEMORY, "Failed to allocate BSTR for dll path"); // get registration helper object - hr = GetRegistrationHelper(&piRegHlp); + hr = GetRegistrationHelper(&piRegHlp, pAttrs->pwzDllPath); ExitOnFailure(hr, "Failed to get registration helper object"); // get dispatch id of UninstallAssembly() method diff --git a/src/ext/ComPlus/ca/cpasmsched.cpp b/src/ext/ComPlus/ca/cpasmsched.cpp index 325808dee..044b2ef89 100644 --- a/src/ext/ComPlus/ca/cpasmsched.cpp +++ b/src/ext/ComPlus/ca/cpasmsched.cpp @@ -408,7 +408,7 @@ HRESULT CpiAssembliesVerifyInstall( if (!pItm->fReferencedForInstall && !pItm->iRoleAssignmentsInstallCount && !WcaIsInstalling(pItm->isInstalled, pItm->isAction)) continue; - // if the assembly is referensed, it must be installed + // if the assembly is referenced, it must be installed if ((pItm->fReferencedForInstall || pItm->iRoleAssignmentsInstallCount) && !CpiWillBeInstalled(pItm->isInstalled, pItm->isAction)) MessageExitOnFailure(hr = E_FAIL, msierrComPlusAssemblyDependency, "An assembly is used by another entity being installed, but is not installed itself, key: %S", pItm->wzKey); } diff --git a/src/ext/ComPlus/ca/cpexec.cpp b/src/ext/ComPlus/ca/cpexec.cpp index 9b1691fc3..a915dd341 100644 --- a/src/ext/ComPlus/ca/cpexec.cpp +++ b/src/ext/ComPlus/ca/cpexec.cpp @@ -180,7 +180,7 @@ extern "C" UINT __stdcall ComPlusInstallExecute(MSIHANDLE hInstall) if (INVALID_HANDLE_VALUE != hRollbackFile) ::CloseHandle(hRollbackFile); - // unitialize + // uninitialize CpiExecFinalize(); if (fInitializedCom) @@ -258,7 +258,7 @@ extern "C" UINT __stdcall ComPlusInstallExecuteCommit(MSIHANDLE hInstall) if (INVALID_HANDLE_VALUE != hRollbackFile) ::CloseHandle(hRollbackFile); - // unitialize + // uninitialize CpiExecFinalize(); if (fInitializedCom) @@ -415,7 +415,7 @@ extern "C" UINT __stdcall ComPlusRollbackInstallExecute(MSIHANDLE hInstall) if (prdSubscriptions) CpiFreeRollbackDataList(prdSubscriptions); - // unitialize + // uninitialize CpiExecFinalize(); if (fInitializedCom) @@ -521,7 +521,7 @@ extern "C" UINT __stdcall ComPlusUninstallExecute(MSIHANDLE hInstall) if (INVALID_HANDLE_VALUE != hRollbackFile) ::CloseHandle(hRollbackFile); - // unitialize + // uninitialize CpiExecFinalize(); if (fInitializedCom) @@ -670,7 +670,7 @@ extern "C" UINT __stdcall ComPlusRollbackUninstallExecute(MSIHANDLE hInstall) if (prdSubscriptions) CpiFreeRollbackDataList(prdSubscriptions); - // unitialize + // uninitialize CpiExecFinalize(); if (fInitializedCom) diff --git a/src/ext/ComPlus/ca/cppartexec.cpp b/src/ext/ComPlus/ca/cppartexec.cpp index 673bdaf9f..06aa16f49 100644 --- a/src/ext/ComPlus/ca/cppartexec.cpp +++ b/src/ext/ComPlus/ca/cppartexec.cpp @@ -34,6 +34,7 @@ static HRESULT ReadPartitionAttributes( static void FreePartitionAttributes( CPI_PARTITION_ATTRIBUTES* pAttrs ); +static HRESULT CpiEnsurePartitionsEnabled(); static HRESULT CreatePartition( CPI_PARTITION_ATTRIBUTES* pAttrs ); @@ -71,7 +72,7 @@ HRESULT CpiConfigurePartitions( hr = CpiActionStartMessage(ppwzData, FALSE); ExitOnFailure(hr, "Failed to send action start message"); - // ger partition count + // get partition count int iCnt = 0; hr = WcaReadIntegerFromCaData(ppwzData, &iCnt); ExitOnFailure(hr, "Failed to read count"); @@ -215,7 +216,7 @@ HRESULT CpiConfigurePartitionUsers( hr = CpiActionStartMessage(ppwzData, FALSE); ExitOnFailure(hr, "Failed to send action start message"); - // ger partition count + // get partition count int iCnt = 0; hr = WcaReadIntegerFromCaData(ppwzData, &iCnt); ExitOnFailure(hr, "Failed to read count"); @@ -384,6 +385,69 @@ static void FreePartitionAttributes( CpiFreePropertyList(pAttrs->pPropList); } +static HRESULT CpiEnsurePartitionsEnabled() +{ + HRESULT hr = S_OK; + + ICatalogCollection* piLocalComputerColl = NULL; + IDispatch* piDisp = NULL; + ICatalogObject* piLocalComputerObj = NULL; + VARIANT vtVal; + BSTR bsPartitionsEnabledName = ::SysAllocString(L"PartitionsEnabled"); + long numChanges = 0; + + ::VariantInit(&vtVal); + + // get collection + hr = CpiExecGetCatalogCollection(L"LocalComputer", &piLocalComputerColl); + ExitOnFailure(hr, "Failed to get catalog collection"); + + // find object, there will be only one in the LocalComputer collection + hr = piLocalComputerColl->get_Item(0, &piDisp); + ExitOnFailure(hr, "Failed to get object from collection"); + + hr = piDisp->QueryInterface(IID_ICatalogObject, (void**)&piLocalComputerObj); + ExitOnFailure(hr, "Failed to get IID_ICatalogObject interface"); + + // and then we get the value of the PartitionsEnabled property + hr = piLocalComputerObj->get_Value(bsPartitionsEnabledName, &vtVal); + if (!vtVal.boolVal) + { + vtVal.boolVal = true; + hr = piLocalComputerObj->put_Value(bsPartitionsEnabledName, vtVal); + ExitOnFailure(hr, "Failed to put value to Enable COM+ PartitionsEnabled property"); + hr = piLocalComputerColl->SaveChanges(&numChanges); + ExitOnFailure(hr, "Failed to save PartitionsEnabled property"); + + // we'll read back the hopefully updated values of the PartitionsEnabled property + // if it's still False, then we're on a Windows Desktop that doesn't allow Partitions + // (as of Windows Server2003 Microsoft limited Partitions to only ServerOS platforms) + hr = piLocalComputerObj->get_Value(bsPartitionsEnabledName, &vtVal); + ExitOnFailure(hr, "Failed to read PartitionsEnabled property"); + } + + if (vtVal.boolVal) + { + // everything went well, we have the Partitioning available + hr = S_OK; + } + else + { + // we're on a Desktop OS, or couldn't otherwise enable partitioning + WcaLog(LOGMSG_STANDARD, "Failed to Enable COM+ PartitionEnabled property. This suggests Partitioning was attempted on a Desktop OS, which is not supported"); + hr = S_FALSE; + } + +LExit: + // clean up + ReleaseObject(piLocalComputerColl); + ReleaseObject(piLocalComputerObj); + ReleaseBSTR(bsPartitionsEnabledName); + ::VariantClear(&vtVal); + + return hr; +} + static HRESULT CreatePartition( CPI_PARTITION_ATTRIBUTES* pAttrs ) @@ -408,6 +472,9 @@ static HRESULT CreatePartition( if (S_FALSE == hr) { + hr = CpiEnsurePartitionsEnabled(); + ExitOnFailure(hr, "Failed to enable partitions"); + // create partition hr = CpiAddCollectionObject(piPartColl, &piPartObj); ExitOnFailure(hr, "Failed to add partition to collection"); diff --git a/src/ext/ComPlus/ca/cppartroleexec.cpp b/src/ext/ComPlus/ca/cppartroleexec.cpp index 4a503c79c..910473e00 100644 --- a/src/ext/ComPlus/ca/cppartroleexec.cpp +++ b/src/ext/ComPlus/ca/cppartroleexec.cpp @@ -49,7 +49,7 @@ HRESULT CpiConfigureUsersInPartitionRoles( hr = CpiActionStartMessage(ppwzData, FALSE); ExitOnFailure(hr, "Failed to send action start message"); - // ger count + // get count int iCnt = 0; hr = WcaReadIntegerFromCaData(ppwzData, &iCnt); ExitOnFailure(hr, "Failed to read count"); diff --git a/src/ext/ComPlus/ca/cppartrolesched.cpp b/src/ext/ComPlus/ca/cppartrolesched.cpp index 0ca4bf0c5..b2fb51186 100644 --- a/src/ext/ComPlus/ca/cppartrolesched.cpp +++ b/src/ext/ComPlus/ca/cppartrolesched.cpp @@ -10,9 +10,9 @@ LPCWSTR vcsPartitionRoleQuery = enum ePartitionRoleQuery { prqPartitionRole = 1, prqPartition, prqComponent, prqName }; LPCWSTR vcsUserInPartitionRoleQuery = - L"SELECT `UserInPartitionRole`, `PartitionRole_`, `ComPlusUserInPartitionRole`.`Component_`, `Domain`, `Name` FROM `Wix4ComPlusUserInPartitionRole`, `Wix4User` WHERE `User_` = `User`"; + L"SELECT `UserInPartitionRole`, `PartitionRole_`, `Wix4ComPlusUserInPartitionRole`.`Component_`, `Domain`, `Name` FROM `Wix4ComPlusUserInPartitionRole`, `Wix4User` WHERE `User_` = `User`"; LPCWSTR vcsGroupInPartitionRoleQuery = - L"SELECT `GroupInPartitionRole`, `PartitionRole_`, `ComPlusGroupInPartitionRole`.`Component_`, `Domain`, `Name` FROM `Wix4ComPlusGroupInPartitionRole`, `Wix4Group` WHERE `Group_` = `Group`"; + L"SELECT `GroupInPartitionRole`, `PartitionRole_`, `Wix4ComPlusGroupInPartitionRole`.`Component_`, `Domain`, `Name` FROM `Wix4ComPlusGroupInPartitionRole`, `Wix4Group` WHERE `Group_` = `Group`"; enum eTrusteeInPartitionRoleQuery { tiprqUserInPartitionRole = 1, tiprqPartitionRole, tiprqComponent, tiprqDomain, tiprqName }; diff --git a/src/ext/ComPlus/ca/cppartsched.cpp b/src/ext/ComPlus/ca/cppartsched.cpp index d4065d34e..b4c1c3141 100644 --- a/src/ext/ComPlus/ca/cppartsched.cpp +++ b/src/ext/ComPlus/ca/cppartsched.cpp @@ -13,7 +13,7 @@ LPCWSTR vcsPartitionPropertyQuery = L"SELECT `Name`, `Value` FROM `Wix4ComPlusPartitionProperty` WHERE `Partition_` = ?"; LPCWSTR vcsPartitionUserQuery = - L"SELECT `PartitionUser`, `Partition_`, `ComPlusPartitionUser`.`Component_`, `Domain`, `Name` FROM `Wix4ComPlusPartitionUser`, `Wix4User` WHERE `User_` = `User`"; + L"SELECT `PartitionUser`, `Partition_`, `Wix4ComPlusPartitionUser`.`Component_`, `Domain`, `Name` FROM `Wix4ComPlusPartitionUser`, `Wix4User` WHERE `User_` = `User`"; enum ePartitionUserQuery { puqPartitionUser = 1, puqPartition, puqComponent, puqDomain, puqName }; @@ -192,7 +192,7 @@ HRESULT CpiPartitionsVerifyInstall( if (!pItm->fReferencedForInstall && !(pItm->fHasComponent && WcaIsInstalling(pItm->isInstalled, pItm->isAction))) continue; - // if the partition is referensed and is not a locater, it must be installed + // if the partition is referenced and is not a locater, it must be installed if (pItm->fReferencedForInstall && pItm->fHasComponent && !CpiWillBeInstalled(pItm->isInstalled, pItm->isAction)) MessageExitOnFailure(hr = E_FAIL, msierrComPlusPartitionDependency, "A partition is used by another entity being installed, but is not installed itself, key: %S", pItm->wzKey); @@ -281,7 +281,7 @@ HRESULT CpiPartitionsVerifyInstall( { case IDCANCEL: case IDABORT: - ExitOnFailure(hr = E_FAIL, "A partition with a conflictiong name or id exists, key: %S", pItm->wzKey); + ExitOnFailure(hr = E_FAIL, "A partition with a conflicting name or id exists, key: %S", pItm->wzKey); break; case IDRETRY: break; @@ -403,7 +403,7 @@ HRESULT CpiPartitionsInstall( int iActionType; // add action text - hr = CpiAddActionTextToActionData(L"CreateComPlusPartitions", ppwzActionData); + hr = CpiAddActionTextToActionData(CUSTOM_ACTION_DECORATION(L"CreateComPlusPartitions"), ppwzActionData); ExitOnFailure(hr, "Failed to add action text to custom action data"); // add partition count to action data @@ -455,7 +455,7 @@ HRESULT CpiPartitionsUninstall( int iActionType; // add action text - hr = CpiAddActionTextToActionData(L"RemoveComPlusPartitions", ppwzActionData); + hr = CpiAddActionTextToActionData(CUSTOM_ACTION_DECORATION(L"RemoveComPlusPartitions"), ppwzActionData); ExitOnFailure(hr, "Failed to add action text to custom action data"); // add partition count to action data @@ -735,7 +735,7 @@ HRESULT CpiPartitionUsersInstall( int iActionType; // add action text - hr = CpiAddActionTextToActionData(L"AddComPlusPartitionUsers", ppwzActionData); + hr = CpiAddActionTextToActionData(CUSTOM_ACTION_DECORATION(L"AddComPlusPartitionUsers"), ppwzActionData); ExitOnFailure(hr, "Failed to add action text to custom action data"); // add partition count to action data @@ -787,7 +787,7 @@ HRESULT CpiPartitionUsersUninstall( int iActionType; // add action text - hr = CpiAddActionTextToActionData(L"RemoveComPlusPartitionUsers", ppwzActionData); + hr = CpiAddActionTextToActionData(CUSTOM_ACTION_DECORATION(L"RemoveComPlusPartitionUsers"), ppwzActionData); ExitOnFailure(hr, "Failed to add action text to custom action data"); // add partition count to action data diff --git a/src/ext/ComPlus/ca/cpsched.cpp b/src/ext/ComPlus/ca/cpsched.cpp index ebc547ae0..acde3cd31 100644 --- a/src/ext/ComPlus/ca/cpsched.cpp +++ b/src/ext/ComPlus/ca/cpsched.cpp @@ -3,31 +3,17 @@ #include "precomp.h" -#ifdef _WIN64 -#define CP_COMPLUSROLLBACKINSTALLPREPARE L"ComPlusRollbackInstallPrepare_64" -#define CP_COMPLUSINSTALLPREPARE L"ComPlusInstallPrepare_64" -#define CP_COMPLUSROLLBACKINSTALLEXECUTE L"ComPlusRollbackInstallExecute_64" -#define CP_COMPLUSINSTALLEXECUTE L"ComPlusInstallExecute_64" -#define CP_COMPLUSINSTALLEXECUTECOMMIT L"ComPlusInstallExecuteCommit_64" -#define CP_COMPLUSINSTALLCOMMIT L"ComPlusInstallCommit_64" -#define CP_COMPLUSROLLBACKINSTALLPREPARE L"ComPlusRollbackInstallPrepare_64" -#define CP_COMPLUSINSTALLPREPARE L"ComPlusInstallPrepare_64" -#define CP_COMPLUSROLLBACKUNINSTALLEXECUTE L"ComPlusRollbackUninstallExecute_64" -#define CP_COMPLUSUNINSTALLEXECUTE L"ComPlusUninstallExecute_64" -#define CP_COMPLUSINSTALLCOMMIT L"ComPlusInstallCommit_64" -#else -#define CP_COMPLUSROLLBACKINSTALLPREPARE L"ComPlusRollbackInstallPrepare" -#define CP_COMPLUSINSTALLPREPARE L"ComPlusInstallPrepare" -#define CP_COMPLUSROLLBACKINSTALLEXECUTE L"ComPlusRollbackInstallExecute" -#define CP_COMPLUSINSTALLEXECUTE L"ComPlusInstallExecute" -#define CP_COMPLUSINSTALLEXECUTECOMMIT L"ComPlusInstallExecuteCommit" -#define CP_COMPLUSINSTALLCOMMIT L"ComPlusInstallCommit" -#define CP_COMPLUSROLLBACKINSTALLPREPARE L"ComPlusRollbackInstallPrepare" -#define CP_COMPLUSINSTALLPREPARE L"ComPlusInstallPrepare" -#define CP_COMPLUSROLLBACKUNINSTALLEXECUTE L"ComPlusRollbackUninstallExecute" -#define CP_COMPLUSUNINSTALLEXECUTE L"ComPlusUninstallExecute" -#define CP_COMPLUSINSTALLCOMMIT L"ComPlusInstallCommit" -#endif +#define CP_COMPLUSROLLBACKINSTALLPREPARE CUSTOM_ACTION_DECORATION(L"ComPlusRollbackInstallPrepare") +#define CP_COMPLUSINSTALLPREPARE CUSTOM_ACTION_DECORATION(L"ComPlusInstallPrepare") +#define CP_COMPLUSROLLBACKINSTALLEXECUTE CUSTOM_ACTION_DECORATION(L"ComPlusRollbackInstallExecute") +#define CP_COMPLUSINSTALLEXECUTE CUSTOM_ACTION_DECORATION(L"ComPlusInstallExecute") +#define CP_COMPLUSINSTALLEXECUTECOMMIT CUSTOM_ACTION_DECORATION(L"ComPlusInstallExecuteCommit") +#define CP_COMPLUSINSTALLCOMMIT CUSTOM_ACTION_DECORATION(L"ComPlusInstallCommit") +#define CP_COMPLUSROLLBACKINSTALLPREPARE CUSTOM_ACTION_DECORATION(L"ComPlusRollbackInstallPrepare") +#define CP_COMPLUSINSTALLPREPARE CUSTOM_ACTION_DECORATION(L"ComPlusInstallPrepare") +#define CP_COMPLUSROLLBACKUNINSTALLEXECUTE CUSTOM_ACTION_DECORATION(L"ComPlusRollbackUninstallExecute") +#define CP_COMPLUSUNINSTALLEXECUTE CUSTOM_ACTION_DECORATION(L"ComPlusUninstallExecute") +#define CP_COMPLUSINSTALLCOMMIT CUSTOM_ACTION_DECORATION(L"ComPlusInstallCommit") /******************************************************************** ConfigureComPlusInstall - CUSTOM ACTION ENTRY POINT for installing COM+ components @@ -81,7 +67,7 @@ extern "C" UINT __stdcall ConfigureComPlusInstall(MSIHANDLE hInstall) CpiSchedInitialize(); - // check for the prerequsite tables + // check for the prerequisite tables if (!CpiTableExists(cptComPlusPartition) && !CpiTableExists(cptComPlusApplication) && !CpiTableExists(cptComPlusAssembly)) { WcaLog(LOGMSG_VERBOSE, "skipping install COM+ CustomAction, no ComPlusPartition, ComPlusApplication or ComPlusAssembly table present"); @@ -117,55 +103,55 @@ extern "C" UINT __stdcall ConfigureComPlusInstall(MSIHANDLE hInstall) if (502 <= iVersionNT && CpiTableExists(cptComPlusPartition)) { hr = CpiPartitionsRead(&partList); - MessageExitOnFailure(hr, msierrComPlusPartitionReadFailed, "Failed to read ComPlusPartitions table"); + MessageExitOnFailure(hr, msierrComPlusPartitionReadFailed, "Failed to read Wix4ComPlusPartitions table"); } if (502 <= iVersionNT && CpiTableExists(cptComPlusPartitionRole)) { hr = CpiPartitionRolesRead(&partList, &partRoleList); - MessageExitOnFailure(hr, msierrComPlusPartitionRoleReadFailed, "Failed to read ComPlusPartitionRole table"); + MessageExitOnFailure(hr, msierrComPlusPartitionRoleReadFailed, "Failed to read Wix4ComPlusPartitionRole table"); } if (502 <= iVersionNT && (CpiTableExists(cptComPlusUserInPartitionRole) || CpiTableExists(cptComPlusGroupInPartitionRole))) { hr = CpiUsersInPartitionRolesRead(&partRoleList, &usrInPartRoleList); - MessageExitOnFailure(hr, msierrComPlusUserInPartitionRoleReadFailed, "Failed to read ComPlusUserInPartitionRole table"); + MessageExitOnFailure(hr, msierrComPlusUserInPartitionRoleReadFailed, "Failed to read Wix4ComPlusUserInPartitionRole table"); } if (502 <= iVersionNT && CpiTableExists(cptComPlusPartitionUser)) { hr = CpiPartitionUsersRead(&partList, &partUsrList); - MessageExitOnFailure(hr, msierrComPlusPartitionUserReadFailed, "Failed to read ComPlusPartitionUser table"); + MessageExitOnFailure(hr, msierrComPlusPartitionUserReadFailed, "Failed to read Wix4ComPlusPartitionUser table"); } if (CpiTableExists(cptComPlusApplication)) { hr = CpiApplicationsRead(&partList, &appList); - MessageExitOnFailure(hr, msierrComPlusApplicationReadFailed, "Failed to read ComPlusApplication table"); + MessageExitOnFailure(hr, msierrComPlusApplicationReadFailed, "Failed to read Wix4ComPlusApplication table"); } if (CpiTableExists(cptComPlusApplicationRole)) { hr = CpiApplicationRolesRead(&appList, &appRoleList); - MessageExitOnFailure(hr, msierrComPlusApplicationRoleReadFailed, "Failed to read ComPlusApplicationRole table"); + MessageExitOnFailure(hr, msierrComPlusApplicationRoleReadFailed, "Failed to read Wix4ComPlusApplicationRole table"); } if (CpiTableExists(cptComPlusUserInApplicationRole) || CpiTableExists(cptComPlusGroupInApplicationRole)) { hr = CpiUsersInApplicationRolesRead(&appRoleList, &usrInAppRoleList); - MessageExitOnFailure(hr, msierrComPlusUserInApplicationRoleReadFailed, "Failed to read ComPlusUserInApplicationRole table"); + MessageExitOnFailure(hr, msierrComPlusUserInApplicationRoleReadFailed, "Failed to read Wix4ComPlusUserInApplicationRole table"); } if (CpiTableExists(cptComPlusAssembly)) { hr = CpiAssembliesRead(&appList, &appRoleList, &asmList); - MessageExitOnFailure(hr, msierrComPlusAssembliesReadFailed, "Failed to read ComPlusAssembly table"); + MessageExitOnFailure(hr, msierrComPlusAssembliesReadFailed, "Failed to read Wix4ComPlusAssembly table"); } if (CpiTableExists(cptComPlusSubscription)) { hr = CpiSubscriptionsRead(&asmList, &subList); - MessageExitOnFailure(hr, msierrComPlusSubscriptionReadFailed, "Failed to read ComPlusSubscription table"); + MessageExitOnFailure(hr, msierrComPlusSubscriptionReadFailed, "Failed to read Wix4ComPlusSubscription table"); } // verify elements @@ -295,7 +281,7 @@ extern "C" UINT __stdcall ConfigureComPlusInstall(MSIHANDLE hInstall) CpiAssemblyListFree(&asmList); CpiSubscriptionListFree(&subList); - // unitialize + // uninitialize CpiSchedFinalize(); if (fInitializedCom) @@ -359,7 +345,7 @@ extern "C" UINT __stdcall ConfigureComPlusUninstall(MSIHANDLE hInstall) // check for the prerequsite tables if (!CpiTableExists(cptComPlusPartition) && !CpiTableExists(cptComPlusApplication) && !CpiTableExists(cptComPlusAssembly)) { - WcaLog(LOGMSG_VERBOSE, "skipping uninstall COM+ CustomAction, no ComPlusPartition, ComPlusApplication or ComPlusAssembly table present"); + WcaLog(LOGMSG_VERBOSE, "skipping uninstall COM+ CustomAction, no Wix4ComPlusPartition, Wix4ComPlusApplication or Wix4ComPlusAssembly table present"); ExitFunction1(hr = S_FALSE); } @@ -392,55 +378,55 @@ extern "C" UINT __stdcall ConfigureComPlusUninstall(MSIHANDLE hInstall) if (502 <= iVersionNT && CpiTableExists(cptComPlusPartition)) { hr = CpiPartitionsRead(&partList); - MessageExitOnFailure(hr, msierrComPlusPartitionReadFailed, "Failed to read ComPlusPartitions table"); + MessageExitOnFailure(hr, msierrComPlusPartitionReadFailed, "Failed to read Wix4ComPlusPartitions table"); } if (502 <= iVersionNT && CpiTableExists(cptComPlusPartitionRole)) { hr = CpiPartitionRolesRead(&partList, &partRoleList); - MessageExitOnFailure(hr, msierrComPlusPartitionRoleReadFailed, "Failed to read ComPlusPartitionRole table"); + MessageExitOnFailure(hr, msierrComPlusPartitionRoleReadFailed, "Failed to read Wix4ComPlusPartitionRole table"); } if (502 <= iVersionNT && (CpiTableExists(cptComPlusUserInPartitionRole) || CpiTableExists(cptComPlusGroupInPartitionRole))) { hr = CpiUsersInPartitionRolesRead(&partRoleList, &usrInPartRoleList); - MessageExitOnFailure(hr, msierrComPlusUserInPartitionRoleReadFailed, "Failed to read ComPlusUserInPartitionRole table"); + MessageExitOnFailure(hr, msierrComPlusUserInPartitionRoleReadFailed, "Failed to read Wix4ComPlusUserInPartitionRole table"); } if (502 <= iVersionNT && CpiTableExists(cptComPlusPartitionUser)) { hr = CpiPartitionUsersRead(&partList, &partUsrList); - MessageExitOnFailure(hr, msierrComPlusPartitionUserReadFailed, "Failed to read ComPlusPartitionUser table"); + MessageExitOnFailure(hr, msierrComPlusPartitionUserReadFailed, "Failed to read Wix4ComPlusPartitionUser table"); } if (CpiTableExists(cptComPlusApplication)) { hr = CpiApplicationsRead(&partList, &appList); - MessageExitOnFailure(hr, msierrComPlusApplicationReadFailed, "Failed to read ComPlusApplication table"); + MessageExitOnFailure(hr, msierrComPlusApplicationReadFailed, "Failed to read Wix4ComPlusApplication table"); } if (CpiTableExists(cptComPlusApplicationRole)) { hr = CpiApplicationRolesRead(&appList, &appRoleList); - MessageExitOnFailure(hr, msierrComPlusApplicationRoleReadFailed, "Failed to read ComPlusApplicationRole table"); + MessageExitOnFailure(hr, msierrComPlusApplicationRoleReadFailed, "Failed to read Wix4ComPlusApplicationRole table"); } if (CpiTableExists(cptComPlusUserInApplicationRole) || CpiTableExists(cptComPlusGroupInApplicationRole)) { hr = CpiUsersInApplicationRolesRead(&appRoleList, &usrInAppRoleList); - MessageExitOnFailure(hr, msierrComPlusUserInApplicationRoleReadFailed, "Failed to read ComPlusUserInApplicationRole table"); + MessageExitOnFailure(hr, msierrComPlusUserInApplicationRoleReadFailed, "Failed to read Wix4ComPlusUserInApplicationRole table"); } if (CpiTableExists(cptComPlusAssembly)) { hr = CpiAssembliesRead(&appList, &appRoleList, &asmList); - MessageExitOnFailure(hr, msierrComPlusAssembliesReadFailed, "Failed to read ComPlusAssembly table"); + MessageExitOnFailure(hr, msierrComPlusAssembliesReadFailed, "Failed to read Wix4ComPlusAssembly table"); } if (CpiTableExists(cptComPlusSubscription)) { hr = CpiSubscriptionsRead(&asmList, &subList); - MessageExitOnFailure(hr, msierrComPlusSubscriptionReadFailed, "Failed to read ComPlusSubscription table"); + MessageExitOnFailure(hr, msierrComPlusSubscriptionReadFailed, "Failed to read Wix4ComPlusSubscription table"); } // verify elements @@ -555,7 +541,7 @@ extern "C" UINT __stdcall ConfigureComPlusUninstall(MSIHANDLE hInstall) CpiAssemblyListFree(&asmList); CpiSubscriptionListFree(&subList); - // unitialize + // uninitialize CpiSchedFinalize(); if (fInitializedCom) diff --git a/src/ext/ComPlus/ca/cpsubsexec.cpp b/src/ext/ComPlus/ca/cpsubsexec.cpp index bbcf98537..ab32b856a 100644 --- a/src/ext/ComPlus/ca/cpsubsexec.cpp +++ b/src/ext/ComPlus/ca/cpsubsexec.cpp @@ -54,7 +54,7 @@ HRESULT CpiConfigureSubscriptions( hr = CpiActionStartMessage(ppwzData, FALSE); ExitOnFailure(hr, "Failed to send action start message"); - // ger count + // get count int iCnt = 0; hr = WcaReadIntegerFromCaData(ppwzData, &iCnt); ExitOnFailure(hr, "Failed to read count"); @@ -127,7 +127,7 @@ HRESULT CpiRollbackConfigureSubscriptions( hr = CpiActionStartMessage(ppwzData, NULL == pRollbackDataList); ExitOnFailure(hr, "Failed to send action start message"); - // ger count + // get count int iCnt = 0; hr = WcaReadIntegerFromCaData(ppwzData, &iCnt); ExitOnFailure(hr, "Failed to read count"); diff --git a/src/ext/ComPlus/ca/cputilsched.cpp b/src/ext/ComPlus/ca/cputilsched.cpp index 4a2fdfc60..760b5ec9c 100644 --- a/src/ext/ComPlus/ca/cputilsched.cpp +++ b/src/ext/ComPlus/ca/cputilsched.cpp @@ -53,31 +53,31 @@ void CpiSchedInitialize() // tables giTables = 0; - if (S_OK == WcaTableExists(L"ComPlusPartition")) giTables |= cptComPlusPartition; - if (S_OK == WcaTableExists(L"ComPlusPartitionProperty")) giTables |= cptComPlusPartitionProperty; - if (S_OK == WcaTableExists(L"ComPlusPartitionRole")) giTables |= cptComPlusPartitionRole; - if (S_OK == WcaTableExists(L"ComPlusUserInPartitionRole")) giTables |= cptComPlusUserInPartitionRole; - if (S_OK == WcaTableExists(L"ComPlusGroupInPartitionRole")) giTables |= cptComPlusGroupInPartitionRole; - if (S_OK == WcaTableExists(L"ComPlusPartitionUser")) giTables |= cptComPlusPartitionUser; - if (S_OK == WcaTableExists(L"ComPlusApplication")) giTables |= cptComPlusApplication; - if (S_OK == WcaTableExists(L"ComPlusApplicationProperty")) giTables |= cptComPlusApplicationProperty; - if (S_OK == WcaTableExists(L"ComPlusApplicationRole")) giTables |= cptComPlusApplicationRole; - if (S_OK == WcaTableExists(L"ComPlusApplicationRoleProperty")) giTables |= cptComPlusApplicationRoleProperty; - if (S_OK == WcaTableExists(L"ComPlusUserInApplicationRole")) giTables |= cptComPlusUserInApplicationRole; - if (S_OK == WcaTableExists(L"ComPlusGroupInApplicationRole")) giTables |= cptComPlusGroupInApplicationRole; - if (S_OK == WcaTableExists(L"ComPlusAssembly")) giTables |= cptComPlusAssembly; - if (S_OK == WcaTableExists(L"ComPlusAssemblyDependency")) giTables |= cptComPlusAssemblyDependency; - if (S_OK == WcaTableExists(L"ComPlusComponent")) giTables |= cptComPlusComponent; - if (S_OK == WcaTableExists(L"ComPlusComponentProperty")) giTables |= cptComPlusComponentProperty; - if (S_OK == WcaTableExists(L"ComPlusRoleForComponent")) giTables |= cptComPlusRoleForComponent; - if (S_OK == WcaTableExists(L"ComPlusInterface")) giTables |= cptComPlusInterface; - if (S_OK == WcaTableExists(L"ComPlusInterfaceProperty")) giTables |= cptComPlusInterfaceProperty; - if (S_OK == WcaTableExists(L"ComPlusRoleForInterface")) giTables |= cptComPlusRoleForInterface; - if (S_OK == WcaTableExists(L"ComPlusMethod")) giTables |= cptComPlusMethod; - if (S_OK == WcaTableExists(L"ComPlusMethodProperty")) giTables |= cptComPlusMethodProperty; - if (S_OK == WcaTableExists(L"ComPlusRoleForMethod")) giTables |= cptComPlusRoleForMethod; - if (S_OK == WcaTableExists(L"ComPlusSubscription")) giTables |= cptComPlusSubscription; - if (S_OK == WcaTableExists(L"ComPlusSubscriptionProperty")) giTables |= cptComPlusSubscriptionProperty; + if (S_OK == WcaTableExists(L"Wix4ComPlusPartition")) giTables |= cptComPlusPartition; + if (S_OK == WcaTableExists(L"Wix4ComPlusPartitionProperty")) giTables |= cptComPlusPartitionProperty; + if (S_OK == WcaTableExists(L"Wix4ComPlusPartitionRole")) giTables |= cptComPlusPartitionRole; + if (S_OK == WcaTableExists(L"Wix4ComPlusUserInPartitionRole")) giTables |= cptComPlusUserInPartitionRole; + if (S_OK == WcaTableExists(L"Wix4ComPlusGroupInPartitionRole")) giTables |= cptComPlusGroupInPartitionRole; + if (S_OK == WcaTableExists(L"Wix4ComPlusPartitionUser")) giTables |= cptComPlusPartitionUser; + if (S_OK == WcaTableExists(L"Wix4ComPlusApplication")) giTables |= cptComPlusApplication; + if (S_OK == WcaTableExists(L"Wix4ComPlusApplicationProperty")) giTables |= cptComPlusApplicationProperty; + if (S_OK == WcaTableExists(L"Wix4ComPlusApplicationRole")) giTables |= cptComPlusApplicationRole; + if (S_OK == WcaTableExists(L"Wix4ComPlusAppRoleProperty")) giTables |= cptComPlusApplicationRoleProperty; + if (S_OK == WcaTableExists(L"Wix4ComPlusUserInAppRole")) giTables |= cptComPlusUserInApplicationRole; + if (S_OK == WcaTableExists(L"Wix4ComPlusGroupInAppRole")) giTables |= cptComPlusGroupInApplicationRole; + if (S_OK == WcaTableExists(L"Wix4ComPlusAssembly")) giTables |= cptComPlusAssembly; + if (S_OK == WcaTableExists(L"Wix4ComPlusAssemblyDependency")) giTables |= cptComPlusAssemblyDependency; + if (S_OK == WcaTableExists(L"Wix4ComPlusComponent")) giTables |= cptComPlusComponent; + if (S_OK == WcaTableExists(L"Wix4ComPlusComponentProperty")) giTables |= cptComPlusComponentProperty; + if (S_OK == WcaTableExists(L"Wix4ComPlusRoleForComponent")) giTables |= cptComPlusRoleForComponent; + if (S_OK == WcaTableExists(L"Wix4ComPlusInterface")) giTables |= cptComPlusInterface; + if (S_OK == WcaTableExists(L"Wix4ComPlusInterfaceProperty")) giTables |= cptComPlusInterfaceProperty; + if (S_OK == WcaTableExists(L"Wix4ComPlusRoleForInterface")) giTables |= cptComPlusRoleForInterface; + if (S_OK == WcaTableExists(L"Wix4ComPlusMethod")) giTables |= cptComPlusMethod; + if (S_OK == WcaTableExists(L"Wix4ComPlusMethodProperty")) giTables |= cptComPlusMethodProperty; + if (S_OK == WcaTableExists(L"Wix4ComPlusRoleForMethod")) giTables |= cptComPlusRoleForMethod; + if (S_OK == WcaTableExists(L"Wix4ComPlusSubscription")) giTables |= cptComPlusSubscription; + if (S_OK == WcaTableExists(L"Wix4ComPlusSubscriptionProperty")) giTables |= cptComPlusSubscriptionProperty; } void CpiSchedFinalize() @@ -137,7 +137,7 @@ HRESULT CpiSchedGetCatalogCollection( hr = CpiSchedGetAdminCatalog(&piCatalog); ExitOnFailure(hr, "Failed to get COM+ admin catalog"); - // get collecton from catalog + // get collection from catalog hr = piCatalog->GetCollection(bstrName, &piDisp); ExitOnFailure(hr, "Failed to get collection"); diff --git a/src/ext/ComPlus/ca/precomp.h b/src/ext/ComPlus/ca/precomp.h index 74c328d2d..97aa8e976 100644 --- a/src/ext/ComPlus/ca/precomp.h +++ b/src/ext/ComPlus/ca/precomp.h @@ -31,3 +31,5 @@ #include "cpapprolesched.h" #include "cpasmsched.h" #include "cpsubssched.h" + +#include "..\..\caDecor.h" diff --git a/src/ext/ComPlus/wixext/ComPlusTableDefinitions.cs b/src/ext/ComPlus/wixext/ComPlusTableDefinitions.cs index 6af5045cd..cffaff0da 100644 --- a/src/ext/ComPlus/wixext/ComPlusTableDefinitions.cs +++ b/src/ext/ComPlus/wixext/ComPlusTableDefinitions.cs @@ -123,7 +123,7 @@ public static class ComPlusTableDefinitions ); public static readonly TableDefinition ComPlusApplicationRoleProperty = new TableDefinition( - "Wix4ComPlusApplicationRoleProperty", + "Wix4ComPlusAppRoleProperty", ComPlusSymbolDefinitions.ComPlusApplicationRoleProperty, new[] { @@ -135,7 +135,7 @@ public static class ComPlusTableDefinitions ); public static readonly TableDefinition ComPlusUserInApplicationRole = new TableDefinition( - "Wix4ComPlusUserInApplicationRole", + "Wix4ComPlusUserInAppRole", ComPlusSymbolDefinitions.ComPlusUserInApplicationRole, new[] { @@ -148,7 +148,7 @@ public static class ComPlusTableDefinitions ); public static readonly TableDefinition ComPlusGroupInApplicationRole = new TableDefinition( - "Wix4ComPlusGroupInApplicationRole", + "Wix4ComPlusGroupInAppRole", ComPlusSymbolDefinitions.ComPlusGroupInApplicationRole, new[] { diff --git a/src/internal/SetBuildNumber/Directory.Packages.props.pp b/src/internal/SetBuildNumber/Directory.Packages.props.pp index 552aab87f..4085568fb 100644 --- a/src/internal/SetBuildNumber/Directory.Packages.props.pp +++ b/src/internal/SetBuildNumber/Directory.Packages.props.pp @@ -33,6 +33,7 @@ + diff --git a/src/test/burn/WixTestTools/RuntimeFactAttribute.cs b/src/test/burn/WixTestTools/RuntimeFactAttribute.cs index f73c87a29..573a9de20 100644 --- a/src/test/burn/WixTestTools/RuntimeFactAttribute.cs +++ b/src/test/burn/WixTestTools/RuntimeFactAttribute.cs @@ -5,6 +5,7 @@ namespace WixTestTools using System; using System.Security.Principal; using WixInternal.TestSupport.XunitExtensions; + using System.Runtime.InteropServices; public class RuntimeFactAttribute : SkippableFactAttribute { @@ -12,6 +13,16 @@ public class RuntimeFactAttribute : SkippableFactAttribute public static bool RuntimeTestsEnabled { get; } public static bool RunningAsAdministrator { get; } + public static bool RunningOnWindowsServer { get; } + + [DllImport("shlwapi.dll", SetLastError = true, EntryPoint = "#437")] + private static extern bool IsOS(int os); + private static bool IsWindowsServer() + { + const int OS_ANYSERVER = 29; + return IsOS(OS_ANYSERVER); + } + static RuntimeFactAttribute() { @@ -21,6 +32,25 @@ static RuntimeFactAttribute() var testsEnabledString = Environment.GetEnvironmentVariable(RequiredEnvironmentVariableName); RuntimeTestsEnabled = Boolean.TryParse(testsEnabledString, out var testsEnabled) && testsEnabled; + + RunningOnWindowsServer = IsWindowsServer(); + } + + private bool _RequireWindowsServer; + public bool RequireWindowsServer + { + get + { + return _RequireWindowsServer; + } + set + { + _RequireWindowsServer = value; + if (_RequireWindowsServer && !RunningOnWindowsServer) + { + this.Skip = $"These tests are only run on Windows Server"; + } + } } public RuntimeFactAttribute() diff --git a/src/test/msi/TestData/ComPlusExtensionTests/Components/TestComponentNET3.dll b/src/test/msi/TestData/ComPlusExtensionTests/Components/TestComponentNET3.dll new file mode 100644 index 0000000000000000000000000000000000000000..b46be64945be47de9181b0a7aa6cd5eb5b98ce40 GIT binary patch literal 16384 zcmeHNYitzP6+W|mVqyo!#Q{>10XxBV;+66G2?e~~wZVyB@oo$zZtZ=H*8{UN%giiz zLsc9|BJw~&0yT;nMI=GAs8s@ODnhDMQQ8U=i&mjY`bvc>MJ=RKP)XXR5QTpC&Kj?6 z(x#Q7{^-5y`R2Utx#xcK*txUr+Pt5#h$tJ|)vH7=W6xR($A1mua2MV7N)f#@@6587 zrOq?Uf}^S>Crl$|hT?K0r0a$)hZWgO>awcK{+@swH=>HWu&|&!ow~P;s8hFt3(}xx(@=Bi~=!F(VBk zZx0h%i1sofX18IY8)n-+k1iACXT;@0-;klZZDq`c{t^pIFbx{rt%0%ONMDv(2qrJNV_6+^A#9LhzUm_}~%B{j;GjMmSL=q2W z>(cGD?izP}O=E2%Gv$y5>~s;8eFN_uu&==SyDVUvsvfgg#AJ@Mt}nYUK<`0jOWLya z_jUNO{|NdMNL|*d8DSQTh7{8Jh3VQaOCBnP0rs06AM^9~1SpV7urVLA5!Je!Ds$-> z>6|N<=DQefrUR}U=_*2U>07i3mIozT;9g< zLEsX4l-r*I%JeMo4mt{4KqtBVI1pUXe7XQEp-aG9s917S87%?c$2T6k$ghNxu~;aqDbqF#)UR6V44c=olz3Q6-J_)1)y&{2M^Lq| zXGT05eLA@}X&Y=Nnqp^Id%|0kh}~-#8ZNbr;Pj|LGZa|omtWCBsel^O=em4` zKBC5wX2@2JOm`xosS(E*vDNLf+!#x@LU7FJlP<)sSP@fA%yhEps2Wexhib;SWX-Lo z*TgZ3*mE5|Bat%I*ywd#@kB^ZP50?b>b4qJ*q9h6tZJ&A;q3}-RoX+UHuLmgCyYC) zIacrV^eK?CY$fjQQ${qtKR^G(1B3mG>n0z~ zKeldYSMl2gtHuveIc`|vL%;3$B`2Qh80bG=_*}^=6NkpeI z?zyL%-gxzeL-qZouYck%-}BeE^5kr(s3_l+FQwn_-pZ;9x=J^ip+vW#w~a*BWcVoVYg9sJ(Z?rF`sr@5ip(}1s5UqfAeYm@Wh_ld9W2;XeyRy?%kA7hPw z-txxgEA2JA>LxDumVMj1G5(u_U1!{@%g=WG_QVfA{P5@JhtDiLacZn+Z}%^{9(($H z?a{9--u0*ZJJrFHu8&u*(grqmzu&#@k(@P?2dlQ|p5%+Aw=KTX{?3>G_NH?3g8ugR zmVNZNZ^`bfzx!sX7Q47Dd+F)t^M3hI`q_e2{tT04Ce3YA&mfLx$Y+>-P3sD&x^sI~ z6n-@^@73Fpqj+uxVG#@n1_T3w0l|P^;J;^ptuu)h%~|U6M-ujP^7zc$&NB;pcd)62 zsLFX_;UQI7b=db)fQEo=)CZ{pzqEHl?*O(tzq-?_*%v=`)@u^oWfqk&neEvcmNh)} z%~+=~n;)BmtRXUyN5y*t1vzyZA%nT`#K?LD;SIrR!5<6c{`sv3iF@Tm!PLaKIDtzqoB8qQJl6s!Zp27p_f0`#vo7f2k1OtKr!GK^uFd!HZ37smI2xM tpYdbPa`B5DOJo-e2nGZLf&syRU_dY+7!V8y1_T3w0l|P^;D5rvKLKu{>Jb0{ literal 0 HcmV?d00001 diff --git a/src/test/msi/TestData/ComPlusExtensionTests/Components/TestComponentNET3.tlb b/src/test/msi/TestData/ComPlusExtensionTests/Components/TestComponentNET3.tlb new file mode 100644 index 0000000000000000000000000000000000000000..87419ee1c06418de83c5942d879d6675dfe70959 GIT binary patch literal 2088 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 U36H#H&f}rTklD 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 literal 0 HcmV?d00001 diff --git a/src/test/msi/TestData/ComPlusExtensionTests/InstallUninstallNET3WithoutPartitions/InstallUninstallNET3WithoutPartitions.wixproj b/src/test/msi/TestData/ComPlusExtensionTests/InstallUninstallNET3WithoutPartitions/InstallUninstallNET3WithoutPartitions.wixproj new file mode 100644 index 000000000..19382c83f --- /dev/null +++ b/src/test/msi/TestData/ComPlusExtensionTests/InstallUninstallNET3WithoutPartitions/InstallUninstallNET3WithoutPartitions.wixproj @@ -0,0 +1,15 @@ + + + + + {A3E0B539-63F9-4B43-9E34-F33AE1C6E06D} + true + + + + + + + + + diff --git a/src/test/msi/TestData/ComPlusExtensionTests/InstallUninstallNET3WithoutPartitions/product.wxs b/src/test/msi/TestData/ComPlusExtensionTests/InstallUninstallNET3WithoutPartitions/product.wxs new file mode 100644 index 000000000..129669cc9 --- /dev/null +++ b/src/test/msi/TestData/ComPlusExtensionTests/InstallUninstallNET3WithoutPartitions/product.wxs @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/test/msi/TestData/ComPlusExtensionTests/InstallUninstallNET4WithoutPartitions/InstallUninstallNET4WithoutPartitions.wixproj b/src/test/msi/TestData/ComPlusExtensionTests/InstallUninstallNET4WithoutPartitions/InstallUninstallNET4WithoutPartitions.wixproj new file mode 100644 index 000000000..19382c83f --- /dev/null +++ b/src/test/msi/TestData/ComPlusExtensionTests/InstallUninstallNET4WithoutPartitions/InstallUninstallNET4WithoutPartitions.wixproj @@ -0,0 +1,15 @@ + + + + + {A3E0B539-63F9-4B43-9E34-F33AE1C6E06D} + true + + + + + + + + + diff --git a/src/test/msi/TestData/ComPlusExtensionTests/InstallUninstallNET4WithoutPartitions/product.wxs b/src/test/msi/TestData/ComPlusExtensionTests/InstallUninstallNET4WithoutPartitions/product.wxs new file mode 100644 index 000000000..eabd77942 --- /dev/null +++ b/src/test/msi/TestData/ComPlusExtensionTests/InstallUninstallNET4WithoutPartitions/product.wxs @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/test/msi/TestData/ComPlusExtensionTests/InstallUninstallNativeWithoutPartitions/InstallUninstallNativeWithoutPartitions.wixproj b/src/test/msi/TestData/ComPlusExtensionTests/InstallUninstallNativeWithoutPartitions/InstallUninstallNativeWithoutPartitions.wixproj new file mode 100644 index 000000000..19382c83f --- /dev/null +++ b/src/test/msi/TestData/ComPlusExtensionTests/InstallUninstallNativeWithoutPartitions/InstallUninstallNativeWithoutPartitions.wixproj @@ -0,0 +1,15 @@ + + + + + {A3E0B539-63F9-4B43-9E34-F33AE1C6E06D} + true + + + + + + + + + diff --git a/src/test/msi/TestData/ComPlusExtensionTests/InstallUninstallNativeWithoutPartitions/product.wxs b/src/test/msi/TestData/ComPlusExtensionTests/InstallUninstallNativeWithoutPartitions/product.wxs new file mode 100644 index 000000000..ee3c4d8fa --- /dev/null +++ b/src/test/msi/TestData/ComPlusExtensionTests/InstallUninstallNativeWithoutPartitions/product.wxs @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/test/msi/TestData/ComPlusExtensionTests/InstallUninstallWithPartitions/InstallUninstallWithPartitions.wixproj b/src/test/msi/TestData/ComPlusExtensionTests/InstallUninstallWithPartitions/InstallUninstallWithPartitions.wixproj new file mode 100644 index 000000000..19382c83f --- /dev/null +++ b/src/test/msi/TestData/ComPlusExtensionTests/InstallUninstallWithPartitions/InstallUninstallWithPartitions.wixproj @@ -0,0 +1,15 @@ + + + + + {A3E0B539-63F9-4B43-9E34-F33AE1C6E06D} + true + + + + + + + + + diff --git a/src/test/msi/TestData/ComPlusExtensionTests/InstallUninstallWithPartitions/product.wxs b/src/test/msi/TestData/ComPlusExtensionTests/InstallUninstallWithPartitions/product.wxs new file mode 100644 index 000000000..92dc892b9 --- /dev/null +++ b/src/test/msi/TestData/ComPlusExtensionTests/InstallUninstallWithPartitions/product.wxs @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/test/msi/WixToolsetTest.MsiE2E/ComPlusExtensionTests.cs b/src/test/msi/WixToolsetTest.MsiE2E/ComPlusExtensionTests.cs new file mode 100644 index 000000000..b143c19d0 --- /dev/null +++ b/src/test/msi/WixToolsetTest.MsiE2E/ComPlusExtensionTests.cs @@ -0,0 +1,50 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. + +namespace WixToolsetTest.MsiE2E +{ + using System; + using WixTestTools; + using Xunit; + using Xunit.Abstractions; + + public class ComPlusExtensionTests : MsiE2ETests + { + public ComPlusExtensionTests(ITestOutputHelper testOutputHelper) : base(testOutputHelper) { } + + [RuntimeFact] + public void CanInstallUninstallNativeWithoutPartitions() + { + var product = this.CreatePackageInstaller("InstallUninstallNativeWithoutPartitions"); + product.InstallProduct(MSIExec.MSIExecReturnCode.SUCCESS); + + product.UninstallProduct(MSIExec.MSIExecReturnCode.SUCCESS); + } + + [RuntimeFact] + public void CanInstallUninstallNET3WithoutPartitions() + { + var product = this.CreatePackageInstaller("InstallUninstallNET3WithoutPartitions"); + product.InstallProduct(MSIExec.MSIExecReturnCode.SUCCESS); + + product.UninstallProduct(MSIExec.MSIExecReturnCode.SUCCESS); + } + + [RuntimeFact] + public void CanInstallUninstallNET4WithoutPartitions() + { + var product = this.CreatePackageInstaller("InstallUninstallNET4WithoutPartitions"); + product.InstallProduct(MSIExec.MSIExecReturnCode.SUCCESS); + + product.UninstallProduct(MSIExec.MSIExecReturnCode.SUCCESS); + } + + [RuntimeFact(RequireWindowsServer = true)] + public void CanInstallAndUninstallWithPartitions() + { + var product = this.CreatePackageInstaller("InstallUninstallWithPartitions"); + product.InstallProduct(MSIExec.MSIExecReturnCode.SUCCESS); + + product.UninstallProduct(MSIExec.MSIExecReturnCode.SUCCESS); + } + } +}