Skip to content

Commit

Permalink
Fix up COM+ to be back in working order under Wix4+
Browse files Browse the repository at this point in the history
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 (however issues still exist).
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 <[email protected]>
  • Loading branch information
bevanweiss committed Jul 27, 2024
1 parent ce73352 commit d361c56
Show file tree
Hide file tree
Showing 29 changed files with 413 additions and 114 deletions.
4 changes: 2 additions & 2 deletions src/ext/ComPlus/ca/cpapproleexec.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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");
Expand Down Expand Up @@ -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");
Expand Down
20 changes: 10 additions & 10 deletions src/ext/ComPlus/ca/cpapprolesched.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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)))
{
Expand Down Expand Up @@ -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);

Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion src/ext/ComPlus/ca/cpappsched.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down
11 changes: 6 additions & 5 deletions src/ext/ComPlus/ca/cpasmexec.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -64,10 +64,6 @@ typedef HRESULT (__stdcall *CreateAssemblyCacheFunc)(IAssemblyCache **ppAsmCache


// 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,
Expand Down Expand Up @@ -729,7 +725,12 @@ static HRESULT GetRegistrationHelper(

if (!gpiRegHlp)
{
CLSID CLSID_RegistrationHelper{};
hr = ::CLSIDFromProgID(OLESTR("System.EnterpriseServices.RegistrationHelper"), &CLSID_RegistrationHelper);
ExitOnFailure(hr, "Failed to identify CLSID for 'System.EnterpriseServices.RegistrationHelper'");
// create registration helper object
// This will fail with Class not registered if only .NET Framework 4.5 is installed, it appears to require
// .NET 3 to get registered into the system correctly.
hr = ::CoCreateInstance(CLSID_RegistrationHelper, NULL, CLSCTX_ALL, IID_IDispatch, (void**)&gpiRegHlp);
ExitOnFailure(hr, "Failed to create registration helper object");
}
Expand Down Expand Up @@ -979,7 +980,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);
Expand Down
2 changes: 1 addition & 1 deletion src/ext/ComPlus/ca/cpasmsched.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
Expand Down
10 changes: 5 additions & 5 deletions src/ext/ComPlus/ca/cpexec.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,7 @@ extern "C" UINT __stdcall ComPlusInstallExecute(MSIHANDLE hInstall)
if (INVALID_HANDLE_VALUE != hRollbackFile)
::CloseHandle(hRollbackFile);

// unitialize
// uninitialize
CpiExecFinalize();

if (fInitializedCom)
Expand Down Expand Up @@ -258,7 +258,7 @@ extern "C" UINT __stdcall ComPlusInstallExecuteCommit(MSIHANDLE hInstall)
if (INVALID_HANDLE_VALUE != hRollbackFile)
::CloseHandle(hRollbackFile);

// unitialize
// uninitialize
CpiExecFinalize();

if (fInitializedCom)
Expand Down Expand Up @@ -415,7 +415,7 @@ extern "C" UINT __stdcall ComPlusRollbackInstallExecute(MSIHANDLE hInstall)
if (prdSubscriptions)
CpiFreeRollbackDataList(prdSubscriptions);

// unitialize
// uninitialize
CpiExecFinalize();

if (fInitializedCom)
Expand Down Expand Up @@ -521,7 +521,7 @@ extern "C" UINT __stdcall ComPlusUninstallExecute(MSIHANDLE hInstall)
if (INVALID_HANDLE_VALUE != hRollbackFile)
::CloseHandle(hRollbackFile);

// unitialize
// uninitialize
CpiExecFinalize();

if (fInitializedCom)
Expand Down Expand Up @@ -670,7 +670,7 @@ extern "C" UINT __stdcall ComPlusRollbackUninstallExecute(MSIHANDLE hInstall)
if (prdSubscriptions)
CpiFreeRollbackDataList(prdSubscriptions);

// unitialize
// uninitialize
CpiExecFinalize();

if (fInitializedCom)
Expand Down
71 changes: 69 additions & 2 deletions src/ext/ComPlus/ca/cppartexec.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ static HRESULT ReadPartitionAttributes(
static void FreePartitionAttributes(
CPI_PARTITION_ATTRIBUTES* pAttrs
);
static HRESULT CpiEnsurePartitionsEnabled();
static HRESULT CreatePartition(
CPI_PARTITION_ATTRIBUTES* pAttrs
);
Expand Down Expand Up @@ -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");
Expand Down Expand Up @@ -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");
Expand Down Expand Up @@ -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
)
Expand All @@ -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");
Expand Down
2 changes: 1 addition & 1 deletion src/ext/ComPlus/ca/cppartroleexec.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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");
Expand Down
4 changes: 2 additions & 2 deletions src/ext/ComPlus/ca/cppartrolesched.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 };


Expand Down
14 changes: 7 additions & 7 deletions src/ext/ComPlus/ca/cppartsched.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 };


Expand Down Expand Up @@ -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);

Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
Loading

0 comments on commit d361c56

Please sign in to comment.