| 1 | // 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. |
| 2 | |
| 3 | #include "precomp.h" |
| 4 | |
| 5 | |
| 6 | #define CP_COMPLUSROLLBACKINSTALLPREPARE CUSTOM_ACTION_DECORATION(L"ComPlusRollbackInstallPrepare") |
| 7 | #define CP_COMPLUSINSTALLPREPARE CUSTOM_ACTION_DECORATION(L"ComPlusInstallPrepare") |
| 8 | #define CP_COMPLUSROLLBACKINSTALLEXECUTE CUSTOM_ACTION_DECORATION(L"ComPlusRollbackInstallExecute") |
| 9 | #define CP_COMPLUSINSTALLEXECUTE CUSTOM_ACTION_DECORATION(L"ComPlusInstallExecute") |
| 10 | #define CP_COMPLUSINSTALLEXECUTECOMMIT CUSTOM_ACTION_DECORATION(L"ComPlusInstallExecuteCommit") |
| 11 | #define CP_COMPLUSINSTALLCOMMIT CUSTOM_ACTION_DECORATION(L"ComPlusInstallCommit") |
| 12 | #define CP_COMPLUSROLLBACKINSTALLPREPARE CUSTOM_ACTION_DECORATION(L"ComPlusRollbackInstallPrepare") |
| 13 | #define CP_COMPLUSINSTALLPREPARE CUSTOM_ACTION_DECORATION(L"ComPlusInstallPrepare") |
| 14 | #define CP_COMPLUSROLLBACKUNINSTALLEXECUTE CUSTOM_ACTION_DECORATION(L"ComPlusRollbackUninstallExecute") |
| 15 | #define CP_COMPLUSUNINSTALLEXECUTE CUSTOM_ACTION_DECORATION(L"ComPlusUninstallExecute") |
| 16 | #define CP_COMPLUSINSTALLCOMMIT CUSTOM_ACTION_DECORATION(L"ComPlusInstallCommit") |
| 17 | |
| 18 | /******************************************************************** |
| 19 | ConfigureComPlusInstall - CUSTOM ACTION ENTRY POINT for installing COM+ components |
| 20 | |
| 21 | ********************************************************************/ |
| 22 | extern "C" UINT __stdcall ConfigureComPlusInstall(MSIHANDLE hInstall) |
| 23 | { |
| 24 | HRESULT hr = S_OK; |
| 25 | UINT er = ERROR_SUCCESS; |
| 26 | |
| 27 | BOOL fInitializedCom = FALSE; |
| 28 | |
| 29 | ICOMAdminCatalog* piCatalog = NULL; |
| 30 | |
| 31 | CPI_PARTITION_LIST partList; |
| 32 | CPI_PARTITION_ROLE_LIST partRoleList; |
| 33 | CPI_USER_IN_PARTITION_ROLE_LIST usrInPartRoleList; |
| 34 | CPI_PARTITION_USER_LIST partUsrList; |
| 35 | CPI_APPLICATION_LIST appList; |
| 36 | CPI_APPLICATION_ROLE_LIST appRoleList; |
| 37 | CPI_USER_IN_APPLICATION_ROLE_LIST usrInAppRoleList; |
| 38 | CPI_ASSEMBLY_LIST asmList; |
| 39 | CPI_SUBSCRIPTION_LIST subList; |
| 40 | |
| 41 | LPWSTR pwzRollbackFileName = NULL; |
| 42 | LPWSTR pwzActionData = NULL; |
| 43 | LPWSTR pwzRollbackActionData = NULL; |
| 44 | LPWSTR pwzCommitActionData = NULL; |
| 45 | |
| 46 | int iVersionNT = 0; |
| 47 | int iProgress = 0; |
| 48 | int iCommitProgress = 0; |
| 49 | |
| 50 | ::ZeroMemory(&partList, sizeof(CPI_PARTITION_LIST)); |
| 51 | ::ZeroMemory(&partRoleList, sizeof(CPI_PARTITION_ROLE_LIST)); |
| 52 | ::ZeroMemory(&usrInPartRoleList, sizeof(CPI_USER_IN_PARTITION_ROLE_LIST)); |
| 53 | ::ZeroMemory(&partUsrList, sizeof(CPI_PARTITION_USER_LIST)); |
| 54 | ::ZeroMemory(&appList, sizeof(CPI_APPLICATION_LIST)); |
| 55 | ::ZeroMemory(&appRoleList, sizeof(CPI_APPLICATION_ROLE_LIST)); |
| 56 | ::ZeroMemory(&usrInAppRoleList, sizeof(CPI_USER_IN_APPLICATION_ROLE_LIST)); |
| 57 | ::ZeroMemory(&asmList, sizeof(CPI_ASSEMBLY_LIST)); |
| 58 | ::ZeroMemory(&subList, sizeof(CPI_SUBSCRIPTION_LIST)); |
| 59 | |
| 60 | // initialize |
| 61 | hr = WcaInitialize(hInstall, "ConfigureComPlusInstall"); |
| 62 | ExitOnFailure(hr, "Failed to initialize"); |
| 63 | |
| 64 | hr = ::CoInitialize(NULL); |
| 65 | ExitOnFailure(hr, "Failed to initialize COM"); |
| 66 | fInitializedCom = TRUE; |
| 67 | |
| 68 | CpiSchedInitialize(); |
| 69 | |
| 70 | // check for the prerequisite tables |
| 71 | if (!CpiTableExists(cptComPlusPartition) && !CpiTableExists(cptComPlusApplication) && !CpiTableExists(cptComPlusAssembly)) |
| 72 | { |
| 73 | WcaLog(LOGMSG_VERBOSE, "skipping install COM+ CustomAction, no ComPlusPartition, ComPlusApplication or ComPlusAssembly table present"); |
| 74 | ExitFunction1(hr = S_FALSE); |
| 75 | } |
| 76 | |
| 77 | // make sure we can access the COM+ admin catalog |
| 78 | do { |
| 79 | hr = CpiSchedGetAdminCatalog(&piCatalog); |
| 80 | if (FAILED(hr)) |
| 81 | { |
| 82 | WcaLog(LOGMSG_STANDARD, "Failed to get COM+ admin catalog"); |
| 83 | er = WcaErrorMessage(msierrComPlusCannotConnect, hr, INSTALLMESSAGE_ERROR | MB_ABORTRETRYIGNORE, 0); |
| 84 | switch (er) |
| 85 | { |
| 86 | case IDABORT: |
| 87 | ExitFunction(); // exit with hr from CpiGetAdminCatalog() to kick off a rollback |
| 88 | case IDRETRY: |
| 89 | hr = S_FALSE; |
| 90 | break; |
| 91 | case IDIGNORE: |
| 92 | default: |
| 93 | ExitFunction1(hr = S_OK); // pretend everything is okay and bail |
| 94 | } |
| 95 | } |
| 96 | } while (S_FALSE == hr); |
| 97 | |
| 98 | // get NT version |
| 99 | hr = WcaGetIntProperty(L"VersionNT", &iVersionNT); |
| 100 | ExitOnFailure(hr, "Failed to get VersionNT property"); |
| 101 | |
| 102 | // read elements |
| 103 | if (502 <= iVersionNT && CpiTableExists(cptComPlusPartition)) |
| 104 | { |
| 105 | hr = CpiPartitionsRead(&partList); |
| 106 | MessageExitOnFailure(hr, msierrComPlusPartitionReadFailed, "Failed to read Wix4ComPlusPartitions table"); |
| 107 | } |
| 108 | |
| 109 | if (502 <= iVersionNT && CpiTableExists(cptComPlusPartitionRole)) |
| 110 | { |
| 111 | hr = CpiPartitionRolesRead(&partList, &partRoleList); |
| 112 | MessageExitOnFailure(hr, msierrComPlusPartitionRoleReadFailed, "Failed to read Wix4ComPlusPartitionRole table"); |
| 113 | } |
| 114 | |
| 115 | if (502 <= iVersionNT && (CpiTableExists(cptComPlusUserInPartitionRole) || CpiTableExists(cptComPlusGroupInPartitionRole))) |
| 116 | { |
| 117 | hr = CpiUsersInPartitionRolesRead(&partRoleList, &usrInPartRoleList); |
| 118 | MessageExitOnFailure(hr, msierrComPlusUserInPartitionRoleReadFailed, "Failed to read Wix4ComPlusUserInPartitionRole table"); |
| 119 | } |
| 120 | |
| 121 | if (502 <= iVersionNT && CpiTableExists(cptComPlusPartitionUser)) |
| 122 | { |
| 123 | hr = CpiPartitionUsersRead(&partList, &partUsrList); |
| 124 | MessageExitOnFailure(hr, msierrComPlusPartitionUserReadFailed, "Failed to read Wix4ComPlusPartitionUser table"); |
| 125 | } |
| 126 | |
| 127 | if (CpiTableExists(cptComPlusApplication)) |
| 128 | { |
| 129 | hr = CpiApplicationsRead(&partList, &appList); |
| 130 | MessageExitOnFailure(hr, msierrComPlusApplicationReadFailed, "Failed to read Wix4ComPlusApplication table"); |
| 131 | } |
| 132 | |
| 133 | if (CpiTableExists(cptComPlusApplicationRole)) |
| 134 | { |
| 135 | hr = CpiApplicationRolesRead(&appList, &appRoleList); |
| 136 | MessageExitOnFailure(hr, msierrComPlusApplicationRoleReadFailed, "Failed to read Wix4ComPlusApplicationRole table"); |
| 137 | } |
| 138 | |
| 139 | if (CpiTableExists(cptComPlusUserInApplicationRole) || CpiTableExists(cptComPlusGroupInApplicationRole)) |
| 140 | { |
| 141 | hr = CpiUsersInApplicationRolesRead(&appRoleList, &usrInAppRoleList); |
| 142 | MessageExitOnFailure(hr, msierrComPlusUserInApplicationRoleReadFailed, "Failed to read Wix4ComPlusUserInApplicationRole table"); |
| 143 | } |
| 144 | |
| 145 | if (CpiTableExists(cptComPlusAssembly)) |
| 146 | { |
| 147 | hr = CpiAssembliesRead(&appList, &appRoleList, &asmList); |
| 148 | MessageExitOnFailure(hr, msierrComPlusAssembliesReadFailed, "Failed to read Wix4ComPlusAssembly table"); |
| 149 | } |
| 150 | |
| 151 | if (CpiTableExists(cptComPlusSubscription)) |
| 152 | { |
| 153 | hr = CpiSubscriptionsRead(&asmList, &subList); |
| 154 | MessageExitOnFailure(hr, msierrComPlusSubscriptionReadFailed, "Failed to read Wix4ComPlusSubscription table"); |
| 155 | } |
| 156 | |
| 157 | // verify elements |
| 158 | hr = CpiPartitionsVerifyInstall(&partList); |
| 159 | ExitOnFailure(hr, "Failed to verify partitions"); |
| 160 | |
| 161 | hr = CpiApplicationsVerifyInstall(&appList); |
| 162 | ExitOnFailure(hr, "Failed to verify applications"); |
| 163 | |
| 164 | hr = CpiApplicationRolesVerifyInstall(&appRoleList); |
| 165 | ExitOnFailure(hr, "Failed to verify application roles"); |
| 166 | |
| 167 | hr = CpiAssembliesVerifyInstall(&asmList); |
| 168 | ExitOnFailure(hr, "Failed to verify assemblies"); |
| 169 | |
| 170 | if (subList.iInstallCount) |
| 171 | { |
| 172 | hr = CpiSubscriptionsVerifyInstall(&subList); |
| 173 | ExitOnFailure(hr, "Failed to verify subscriptions"); |
| 174 | } |
| 175 | |
| 176 | // schedule |
| 177 | if (partList.iInstallCount || appList.iInstallCount || usrInAppRoleList.iInstallCount || |
| 178 | appRoleList.iInstallCount || asmList.iInstallCount || asmList.iRoleInstallCount || subList.iInstallCount) |
| 179 | { |
| 180 | // create rollback file name |
| 181 | hr = CpiGetTempFileName(&pwzRollbackFileName); |
| 182 | ExitOnFailure(hr, "Failed to get rollback file name"); |
| 183 | |
| 184 | // schedule rollback prepare custom action |
| 185 | hr = WcaDoDeferredAction(CP_COMPLUSROLLBACKINSTALLPREPARE, pwzRollbackFileName, 0); |
| 186 | ExitOnFailure(hr, "Failed to schedule ComPlusRollbackInstallPrepare"); |
| 187 | |
| 188 | // schedule prepare custom action |
| 189 | hr = WcaDoDeferredAction(CP_COMPLUSINSTALLPREPARE, pwzRollbackFileName, 0); |
| 190 | ExitOnFailure(hr, "Failed to schedule ComPlusInstallPrepare"); |
| 191 | |
| 192 | // schedule rollback custom action |
| 193 | hr = WcaWriteStringToCaData(pwzRollbackFileName, &pwzRollbackActionData); |
| 194 | ExitOnFailure(hr, "Failed to add rollback file name to rollback custom action data"); |
| 195 | |
| 196 | hr = CpiSubscriptionsInstall(&subList, rmRollback, &pwzRollbackActionData, NULL); |
| 197 | ExitOnFailure(hr, "Failed to install subscriptions"); |
| 198 | hr = CpiRoleAssignmentsInstall(&asmList, rmRollback, &pwzRollbackActionData, NULL); |
| 199 | ExitOnFailure(hr, "Failed to install assemblies"); |
| 200 | hr = CpiAssembliesInstall(&asmList, rmRollback, &pwzRollbackActionData, NULL); |
| 201 | ExitOnFailure(hr, "Failed to install assemblies"); |
| 202 | hr = CpiUsersInApplicationRolesInstall(&usrInAppRoleList, rmRollback, &pwzRollbackActionData, NULL); |
| 203 | ExitOnFailure(hr, "Failed to install users in application roles"); |
| 204 | hr = CpiApplicationRolesInstall(&appRoleList, rmRollback, &pwzRollbackActionData, NULL); |
| 205 | ExitOnFailure(hr, "Failed to install application roles"); |
| 206 | hr = CpiApplicationsInstall(&appList, rmRollback, &pwzRollbackActionData, NULL); |
| 207 | ExitOnFailure(hr, "Failed to install applications"); |
| 208 | hr = CpiPartitionUsersInstall(&partUsrList, rmRollback, &pwzRollbackActionData, NULL); |
| 209 | ExitOnFailure(hr, "Failed to install partition users"); |
| 210 | hr = CpiUsersInPartitionRolesInstall(&usrInPartRoleList, rmRollback, &pwzRollbackActionData, NULL); |
| 211 | ExitOnFailure(hr, "Failed to install users in partition roles"); |
| 212 | hr = CpiPartitionsInstall(&partList, rmRollback, &pwzRollbackActionData, NULL); |
| 213 | ExitOnFailure(hr, "Failed to install partitions"); |
| 214 | |
| 215 | hr = WcaDoDeferredAction(CP_COMPLUSROLLBACKINSTALLEXECUTE, pwzRollbackActionData, 0); |
| 216 | ExitOnFailure(hr, "Failed to schedule ComPlusRollbackInstallExecute"); |
| 217 | |
| 218 | // schedule install custom action |
| 219 | hr = WcaWriteStringToCaData(pwzRollbackFileName, &pwzActionData); |
| 220 | ExitOnFailure(hr, "Failed to add rollback file name to custom action data"); |
| 221 | |
| 222 | hr = CpiPartitionsInstall(&partList, rmDeferred, &pwzActionData, &iProgress); |
| 223 | ExitOnFailure(hr, "Failed to install partitions"); |
| 224 | hr = CpiUsersInPartitionRolesInstall(&usrInPartRoleList, rmDeferred, &pwzActionData, &iProgress); |
| 225 | ExitOnFailure(hr, "Failed to install users in partition roles"); |
| 226 | hr = CpiPartitionUsersInstall(&partUsrList, rmDeferred, &pwzActionData, &iProgress); |
| 227 | ExitOnFailure(hr, "Failed to install partition users"); |
| 228 | hr = CpiApplicationsInstall(&appList, rmDeferred, &pwzActionData, &iProgress); |
| 229 | ExitOnFailure(hr, "Failed to install applications"); |
| 230 | hr = CpiApplicationRolesInstall(&appRoleList, rmDeferred, &pwzActionData, &iProgress); |
| 231 | ExitOnFailure(hr, "Failed to install application roles"); |
| 232 | hr = CpiUsersInApplicationRolesInstall(&usrInAppRoleList, rmDeferred, &pwzActionData, &iProgress); |
| 233 | ExitOnFailure(hr, "Failed to install users in application roles"); |
| 234 | hr = CpiAssembliesInstall(&asmList, rmDeferred, &pwzActionData, &iProgress); |
| 235 | ExitOnFailure(hr, "Failed to install assemblies"); |
| 236 | hr = CpiRoleAssignmentsInstall(&asmList, rmDeferred, &pwzActionData, &iProgress); |
| 237 | ExitOnFailure(hr, "Failed to install assemblies"); |
| 238 | hr = CpiSubscriptionsInstall(&subList, rmDeferred, &pwzActionData, &iProgress); |
| 239 | ExitOnFailure(hr, "Failed to install subscriptions"); |
| 240 | |
| 241 | hr = WcaDoDeferredAction(CP_COMPLUSINSTALLEXECUTE, pwzActionData, iProgress); |
| 242 | ExitOnFailure(hr, "Failed to schedule ComPlusInstallExecute"); |
| 243 | |
| 244 | // schedule install commit custom action |
| 245 | hr = WcaWriteStringToCaData(pwzRollbackFileName, &pwzCommitActionData); |
| 246 | ExitOnFailure(hr, "Failed to add rollback file name to commit custom action data"); |
| 247 | |
| 248 | hr = CpiAssembliesInstall(&asmList, rmCommit, &pwzCommitActionData, &iCommitProgress); |
| 249 | ExitOnFailure(hr, "Failed to install assemblies"); |
| 250 | hr = CpiRoleAssignmentsInstall(&asmList, rmCommit, &pwzCommitActionData, &iCommitProgress); |
| 251 | ExitOnFailure(hr, "Failed to install assemblies"); |
| 252 | hr = CpiSubscriptionsInstall(&subList, rmCommit, &pwzCommitActionData, &iCommitProgress); |
| 253 | ExitOnFailure(hr, "Failed to install subscriptions"); |
| 254 | |
| 255 | hr = WcaDoDeferredAction(CP_COMPLUSINSTALLEXECUTECOMMIT, pwzCommitActionData, iCommitProgress); |
| 256 | ExitOnFailure(hr, "Failed to schedule ComPlusInstallExecuteCommit"); |
| 257 | |
| 258 | // schedule commit custom action |
| 259 | hr = WcaDoDeferredAction(CP_COMPLUSINSTALLCOMMIT, pwzRollbackFileName, 0); |
| 260 | ExitOnFailure(hr, "Failed to schedule ComPlusInstallCommit"); |
| 261 | } |
| 262 | |
| 263 | hr = S_OK; |
| 264 | |
| 265 | LExit: |
| 266 | // clean up |
| 267 | ReleaseObject(piCatalog); |
| 268 | |
| 269 | ReleaseStr(pwzRollbackFileName); |
| 270 | ReleaseStr(pwzActionData); |
| 271 | ReleaseStr(pwzRollbackActionData); |
| 272 | ReleaseStr(pwzCommitActionData); |
| 273 | |
| 274 | CpiPartitionListFree(&partList); |
| 275 | CpiPartitionRoleListFree(&partRoleList); |
| 276 | CpiUserInPartitionRoleListFree(&usrInPartRoleList); |
| 277 | CpiPartitionUserListFree(&partUsrList); |
| 278 | CpiApplicationListFree(&appList); |
| 279 | CpiApplicationRoleListFree(&appRoleList); |
| 280 | CpiUserInApplicationRoleListFree(&usrInAppRoleList); |
| 281 | CpiAssemblyListFree(&asmList); |
| 282 | CpiSubscriptionListFree(&subList); |
| 283 | |
| 284 | // uninitialize |
| 285 | CpiSchedFinalize(); |
| 286 | |
| 287 | if (fInitializedCom) |
| 288 | ::CoUninitialize(); |
| 289 | |
| 290 | er = SUCCEEDED(hr) ? ERROR_SUCCESS : ERROR_INSTALL_FAILURE; |
| 291 | return WcaFinalize(er); |
| 292 | } |
| 293 | |
| 294 | |
| 295 | /******************************************************************** |
| 296 | ConfigureComPlusUninstall - CUSTOM ACTION ENTRY POINT for uninstalling COM+ components |
| 297 | |
| 298 | ********************************************************************/ |
| 299 | extern "C" UINT __stdcall ConfigureComPlusUninstall(MSIHANDLE hInstall) |
| 300 | { |
| 301 | HRESULT hr = S_OK; |
| 302 | UINT er = ERROR_SUCCESS; |
| 303 | |
| 304 | BOOL fInitializedCom = FALSE; |
| 305 | |
| 306 | ICOMAdminCatalog* piCatalog = NULL; |
| 307 | |
| 308 | CPI_PARTITION_LIST partList; |
| 309 | CPI_PARTITION_ROLE_LIST partRoleList; |
| 310 | CPI_USER_IN_PARTITION_ROLE_LIST usrInPartRoleList; |
| 311 | CPI_PARTITION_USER_LIST partUsrList; |
| 312 | CPI_APPLICATION_LIST appList; |
| 313 | CPI_APPLICATION_ROLE_LIST appRoleList; |
| 314 | CPI_USER_IN_APPLICATION_ROLE_LIST usrInAppRoleList; |
| 315 | CPI_ASSEMBLY_LIST asmList; |
| 316 | CPI_SUBSCRIPTION_LIST subList; |
| 317 | |
| 318 | LPWSTR pwzRollbackFileName = NULL; |
| 319 | LPWSTR pwzActionData = NULL; |
| 320 | LPWSTR pwzRollbackActionData = NULL; |
| 321 | |
| 322 | int iVersionNT = 0; |
| 323 | int iProgress = 0; |
| 324 | |
| 325 | ::ZeroMemory(&partList, sizeof(CPI_PARTITION_LIST)); |
| 326 | ::ZeroMemory(&partRoleList, sizeof(CPI_PARTITION_ROLE_LIST)); |
| 327 | ::ZeroMemory(&usrInPartRoleList, sizeof(CPI_USER_IN_PARTITION_ROLE_LIST)); |
| 328 | ::ZeroMemory(&partUsrList, sizeof(CPI_PARTITION_USER_LIST)); |
| 329 | ::ZeroMemory(&appList, sizeof(CPI_APPLICATION_LIST)); |
| 330 | ::ZeroMemory(&appRoleList, sizeof(CPI_APPLICATION_ROLE_LIST)); |
| 331 | ::ZeroMemory(&usrInAppRoleList, sizeof(CPI_USER_IN_APPLICATION_ROLE_LIST)); |
| 332 | ::ZeroMemory(&asmList, sizeof(CPI_ASSEMBLY_LIST)); |
| 333 | ::ZeroMemory(&subList, sizeof(CPI_SUBSCRIPTION_LIST)); |
| 334 | |
| 335 | // initialize |
| 336 | hr = WcaInitialize(hInstall, "ConfigureComPlusUninstall"); |
| 337 | ExitOnFailure(hr, "Failed to initialize"); |
| 338 | |
| 339 | hr = ::CoInitialize(NULL); |
| 340 | ExitOnFailure(hr, "Failed to initialize COM"); |
| 341 | fInitializedCom = TRUE; |
| 342 | |
| 343 | CpiSchedInitialize(); |
| 344 | |
| 345 | // check for the prerequsite tables |
| 346 | if (!CpiTableExists(cptComPlusPartition) && !CpiTableExists(cptComPlusApplication) && !CpiTableExists(cptComPlusAssembly)) |
| 347 | { |
| 348 | WcaLog(LOGMSG_VERBOSE, "skipping uninstall COM+ CustomAction, no Wix4ComPlusPartition, Wix4ComPlusApplication or Wix4ComPlusAssembly table present"); |
| 349 | ExitFunction1(hr = S_FALSE); |
| 350 | } |
| 351 | |
| 352 | // make sure we can access the COM+ admin catalog |
| 353 | do { |
| 354 | hr = CpiSchedGetAdminCatalog(&piCatalog); |
| 355 | if (FAILED(hr)) |
| 356 | { |
| 357 | WcaLog(LOGMSG_STANDARD, "Failed to get COM+ admin catalog"); |
| 358 | er = WcaErrorMessage(msierrComPlusCannotConnect, hr, INSTALLMESSAGE_ERROR | MB_ABORTRETRYIGNORE, 0); |
| 359 | switch (er) |
| 360 | { |
| 361 | case IDABORT: |
| 362 | ExitFunction(); // exit with hr from CpiGetAdminCatalog() to kick off a rollback |
| 363 | case IDRETRY: |
| 364 | hr = S_FALSE; |
| 365 | break; |
| 366 | case IDIGNORE: |
| 367 | default: |
| 368 | ExitFunction1(hr = S_OK); // pretend everything is okay and bail |
| 369 | } |
| 370 | } |
| 371 | } while (S_FALSE == hr); |
| 372 | |
| 373 | // get NT version |
| 374 | hr = WcaGetIntProperty(L"VersionNT", &iVersionNT); |
| 375 | ExitOnFailure(hr, "Failed to get VersionNT property"); |
| 376 | |
| 377 | // read elements |
| 378 | if (502 <= iVersionNT && CpiTableExists(cptComPlusPartition)) |
| 379 | { |
| 380 | hr = CpiPartitionsRead(&partList); |
| 381 | MessageExitOnFailure(hr, msierrComPlusPartitionReadFailed, "Failed to read Wix4ComPlusPartitions table"); |
| 382 | } |
| 383 | |
| 384 | if (502 <= iVersionNT && CpiTableExists(cptComPlusPartitionRole)) |
| 385 | { |
| 386 | hr = CpiPartitionRolesRead(&partList, &partRoleList); |
| 387 | MessageExitOnFailure(hr, msierrComPlusPartitionRoleReadFailed, "Failed to read Wix4ComPlusPartitionRole table"); |
| 388 | } |
| 389 | |
| 390 | if (502 <= iVersionNT && (CpiTableExists(cptComPlusUserInPartitionRole) || CpiTableExists(cptComPlusGroupInPartitionRole))) |
| 391 | { |
| 392 | hr = CpiUsersInPartitionRolesRead(&partRoleList, &usrInPartRoleList); |
| 393 | MessageExitOnFailure(hr, msierrComPlusUserInPartitionRoleReadFailed, "Failed to read Wix4ComPlusUserInPartitionRole table"); |
| 394 | } |
| 395 | |
| 396 | if (502 <= iVersionNT && CpiTableExists(cptComPlusPartitionUser)) |
| 397 | { |
| 398 | hr = CpiPartitionUsersRead(&partList, &partUsrList); |
| 399 | MessageExitOnFailure(hr, msierrComPlusPartitionUserReadFailed, "Failed to read Wix4ComPlusPartitionUser table"); |
| 400 | } |
| 401 | |
| 402 | if (CpiTableExists(cptComPlusApplication)) |
| 403 | { |
| 404 | hr = CpiApplicationsRead(&partList, &appList); |
| 405 | MessageExitOnFailure(hr, msierrComPlusApplicationReadFailed, "Failed to read Wix4ComPlusApplication table"); |
| 406 | } |
| 407 | |
| 408 | if (CpiTableExists(cptComPlusApplicationRole)) |
| 409 | { |
| 410 | hr = CpiApplicationRolesRead(&appList, &appRoleList); |
| 411 | MessageExitOnFailure(hr, msierrComPlusApplicationRoleReadFailed, "Failed to read Wix4ComPlusApplicationRole table"); |
| 412 | } |
| 413 | |
| 414 | if (CpiTableExists(cptComPlusUserInApplicationRole) || CpiTableExists(cptComPlusGroupInApplicationRole)) |
| 415 | { |
| 416 | hr = CpiUsersInApplicationRolesRead(&appRoleList, &usrInAppRoleList); |
| 417 | MessageExitOnFailure(hr, msierrComPlusUserInApplicationRoleReadFailed, "Failed to read Wix4ComPlusUserInApplicationRole table"); |
| 418 | } |
| 419 | |
| 420 | if (CpiTableExists(cptComPlusAssembly)) |
| 421 | { |
| 422 | hr = CpiAssembliesRead(&appList, &appRoleList, &asmList); |
| 423 | MessageExitOnFailure(hr, msierrComPlusAssembliesReadFailed, "Failed to read Wix4ComPlusAssembly table"); |
| 424 | } |
| 425 | |
| 426 | if (CpiTableExists(cptComPlusSubscription)) |
| 427 | { |
| 428 | hr = CpiSubscriptionsRead(&asmList, &subList); |
| 429 | MessageExitOnFailure(hr, msierrComPlusSubscriptionReadFailed, "Failed to read Wix4ComPlusSubscription table"); |
| 430 | } |
| 431 | |
| 432 | // verify elements |
| 433 | hr = CpiPartitionsVerifyUninstall(&partList); |
| 434 | ExitOnFailure(hr, "Failed to verify partitions"); |
| 435 | |
| 436 | hr = CpiApplicationsVerifyUninstall(&appList); |
| 437 | ExitOnFailure(hr, "Failed to verify applications"); |
| 438 | |
| 439 | hr = CpiApplicationRolesVerifyUninstall(&appRoleList); |
| 440 | ExitOnFailure(hr, "Failed to verify application roles"); |
| 441 | |
| 442 | hr = CpiAssembliesVerifyUninstall(&asmList); |
| 443 | ExitOnFailure(hr, "Failed to verify assemblies"); |
| 444 | |
| 445 | if (subList.iUninstallCount) |
| 446 | { |
| 447 | hr = CpiSubscriptionsVerifyUninstall(&subList); |
| 448 | ExitOnFailure(hr, "Failed to verify subscriptions"); |
| 449 | } |
| 450 | |
| 451 | // schedule |
| 452 | if (partList.iUninstallCount || appList.iUninstallCount || appRoleList.iUninstallCount || |
| 453 | usrInAppRoleList.iUninstallCount || asmList.iUninstallCount || asmList.iRoleUninstallCount || subList.iUninstallCount) |
| 454 | { |
| 455 | // create rollback file name |
| 456 | hr = CpiGetTempFileName(&pwzRollbackFileName); |
| 457 | ExitOnFailure(hr, "Failed to get rollback file name"); |
| 458 | |
| 459 | // schedule rollback prepare custom action |
| 460 | hr = WcaDoDeferredAction(CP_COMPLUSROLLBACKINSTALLPREPARE, pwzRollbackFileName, 0); |
| 461 | ExitOnFailure(hr, "Failed to schedule ComPlusRollbackInstallPrepare"); |
| 462 | |
| 463 | // schedule prepare custom action |
| 464 | hr = WcaDoDeferredAction(CP_COMPLUSINSTALLPREPARE, pwzRollbackFileName, 0); |
| 465 | ExitOnFailure(hr, "Failed to schedule ComPlusInstallPrepare"); |
| 466 | |
| 467 | // schedule rollback custom action |
| 468 | hr = WcaWriteStringToCaData(pwzRollbackFileName, &pwzRollbackActionData); |
| 469 | ExitOnFailure(hr, "Failed to add rollback file name to rollback custom action data"); |
| 470 | |
| 471 | hr = CpiPartitionsUninstall(&partList, rmRollback, &pwzRollbackActionData, NULL); |
| 472 | ExitOnFailure(hr, "Failed to uninstall partitions"); |
| 473 | hr = CpiUsersInPartitionRolesUninstall(&usrInPartRoleList, rmRollback, &pwzRollbackActionData, NULL); |
| 474 | ExitOnFailure(hr, "Failed to uninstall users in partition roles"); |
| 475 | hr = CpiPartitionUsersUninstall(&partUsrList, rmRollback, &pwzRollbackActionData, NULL); |
| 476 | ExitOnFailure(hr, "Failed to uninstall partition users"); |
| 477 | hr = CpiApplicationsUninstall(&appList, rmRollback, &pwzRollbackActionData, NULL); |
| 478 | ExitOnFailure(hr, "Failed to uninstall applications"); |
| 479 | hr = CpiApplicationRolesUninstall(&appRoleList, rmRollback, &pwzRollbackActionData, NULL); |
| 480 | ExitOnFailure(hr, "Failed to uninstall application roles"); |
| 481 | hr = CpiUsersInApplicationRolesUninstall(&usrInAppRoleList, rmRollback, &pwzRollbackActionData, NULL); |
| 482 | ExitOnFailure(hr, "Failed to uninstall users in application roles"); |
| 483 | hr = CpiAssembliesUninstall(&asmList, rmRollback, &pwzRollbackActionData, NULL); |
| 484 | ExitOnFailure(hr, "Failed to uninstall assemblies"); |
| 485 | hr = CpiRoleAssignmentsUninstall(&asmList, rmRollback, &pwzRollbackActionData, NULL); |
| 486 | ExitOnFailure(hr, "Failed to uninstall assemblies"); |
| 487 | hr = CpiSubscriptionsUninstall(&subList, rmRollback, &pwzRollbackActionData, NULL); |
| 488 | ExitOnFailure(hr, "Failed to uninstall subscriptions"); |
| 489 | |
| 490 | hr = WcaDoDeferredAction(CP_COMPLUSROLLBACKUNINSTALLEXECUTE, pwzRollbackActionData, 0); |
| 491 | ExitOnFailure(hr, "Failed to schedule ComPlusRollbackUninstallExecute"); |
| 492 | |
| 493 | // schedule install custom action |
| 494 | hr = WcaWriteStringToCaData(pwzRollbackFileName, &pwzActionData); |
| 495 | ExitOnFailure(hr, "Failed to add rollback file name to custom action data"); |
| 496 | |
| 497 | hr = CpiSubscriptionsUninstall(&subList, rmDeferred, &pwzActionData, &iProgress); |
| 498 | ExitOnFailure(hr, "Failed to uninstall subscriptions"); |
| 499 | hr = CpiRoleAssignmentsUninstall(&asmList, rmDeferred, &pwzActionData, &iProgress); |
| 500 | ExitOnFailure(hr, "Failed to uninstall assemblies"); |
| 501 | hr = CpiAssembliesUninstall(&asmList, rmDeferred, &pwzActionData, &iProgress); |
| 502 | ExitOnFailure(hr, "Failed to uninstall assemblies"); |
| 503 | hr = CpiUsersInApplicationRolesUninstall(&usrInAppRoleList, rmDeferred, &pwzActionData, &iProgress); |
| 504 | ExitOnFailure(hr, "Failed to uninstall users in application roles"); |
| 505 | hr = CpiApplicationRolesUninstall(&appRoleList, rmDeferred, &pwzActionData, &iProgress); |
| 506 | ExitOnFailure(hr, "Failed to uninstall application roles"); |
| 507 | hr = CpiApplicationsUninstall(&appList, rmDeferred, &pwzActionData, &iProgress); |
| 508 | ExitOnFailure(hr, "Failed to uninstall applications"); |
| 509 | hr = CpiPartitionUsersUninstall(&partUsrList, rmDeferred, &pwzActionData, &iProgress); |
| 510 | ExitOnFailure(hr, "Failed to uninstall partition users"); |
| 511 | hr = CpiUsersInPartitionRolesUninstall(&usrInPartRoleList, rmDeferred, &pwzActionData, &iProgress); |
| 512 | ExitOnFailure(hr, "Failed to uninstall users in partition roles"); |
| 513 | hr = CpiPartitionsUninstall(&partList, rmDeferred, &pwzActionData, &iProgress); |
| 514 | ExitOnFailure(hr, "Failed to uninstall partitions"); |
| 515 | |
| 516 | hr = WcaDoDeferredAction(CP_COMPLUSUNINSTALLEXECUTE, pwzActionData, iProgress); |
| 517 | ExitOnFailure(hr, "Failed to schedule ComPlusUninstallExecute"); |
| 518 | |
| 519 | // schedule commit custom action |
| 520 | hr = WcaDoDeferredAction(CP_COMPLUSINSTALLCOMMIT, pwzRollbackFileName, 0); |
| 521 | ExitOnFailure(hr, "Failed to schedule ComPlusInstallCommit"); |
| 522 | } |
| 523 | |
| 524 | hr = S_OK; |
| 525 | |
| 526 | LExit: |
| 527 | // clean up |
| 528 | ReleaseObject(piCatalog); |
| 529 | |
| 530 | ReleaseStr(pwzRollbackFileName); |
| 531 | ReleaseStr(pwzActionData); |
| 532 | ReleaseStr(pwzRollbackActionData); |
| 533 | |
| 534 | CpiPartitionListFree(&partList); |
| 535 | CpiPartitionRoleListFree(&partRoleList); |
| 536 | CpiUserInPartitionRoleListFree(&usrInPartRoleList); |
| 537 | CpiPartitionUserListFree(&partUsrList); |
| 538 | CpiApplicationListFree(&appList); |
| 539 | CpiApplicationRoleListFree(&appRoleList); |
| 540 | CpiUserInApplicationRoleListFree(&usrInAppRoleList); |
| 541 | CpiAssemblyListFree(&asmList); |
| 542 | CpiSubscriptionListFree(&subList); |
| 543 | |
| 544 | // uninitialize |
| 545 | CpiSchedFinalize(); |
| 546 | |
| 547 | if (fInitializedCom) |
| 548 | ::CoUninitialize(); |
| 549 | |
| 550 | er = SUCCEEDED(hr) ? ERROR_SUCCESS : ERROR_INSTALL_FAILURE; |
| 551 | return WcaFinalize(er); |
| 552 | } |