diff options
author | Bevan Weiss <bevan.weiss@gmail.com> | 2024-08-04 21:13:44 +1000 |
---|---|---|
committer | Rob Mensching <rob@firegiant.com> | 2025-02-11 23:14:49 -0800 |
commit | 5b4a6538ee06988c75b717bd905197fb670e6142 (patch) | |
tree | eb078854f258ebdabaf206282d56cbdcf87759ef /src/ext/Util/ca/scagroup.cpp | |
parent | 2c5bb89424b12de812498d568bc1aae2d4098e60 (diff) | |
download | wix-5b4a6538ee06988c75b717bd905197fb670e6142.tar.gz wix-5b4a6538ee06988c75b717bd905197fb670e6142.tar.bz2 wix-5b4a6538ee06988c75b717bd905197fb670e6142.zip |
Add/Remove Group Membership rollback handled.
Fixups to a few test cases.
Signed-off-by: Bevan Weiss <bevan.weiss@gmail.com>
Diffstat (limited to 'src/ext/Util/ca/scagroup.cpp')
-rw-r--r-- | src/ext/Util/ca/scagroup.cpp | 159 |
1 files changed, 130 insertions, 29 deletions
diff --git a/src/ext/Util/ca/scagroup.cpp b/src/ext/Util/ca/scagroup.cpp index 699d9db7..bab438ea 100644 --- a/src/ext/Util/ca/scagroup.cpp +++ b/src/ext/Util/ca/scagroup.cpp | |||
@@ -220,13 +220,13 @@ HRESULT ScaGroupGetParents( | |||
220 | ExitOnFailure(hr, "failed to get Component state for Wix4Group"); | 220 | ExitOnFailure(hr, "failed to get Component state for Wix4Group"); |
221 | } | 221 | } |
222 | 222 | ||
223 | hr = WcaGetRecordString(hRec, vgpqParentName, &pwzTempStr); | 223 | hr = WcaGetRecordFormattedString(hRec, vgpqParentName, &pwzTempStr); |
224 | ExitOnFailure(hr, "failed to get Wix4Group.Name"); | 224 | ExitOnFailure(hr, "failed to get Wix4Group.Name"); |
225 | wcsncpy_s(psgParent->wzName, pwzTempStr, MAX_DARWIN_COLUMN); | 225 | wcsncpy_s(psgParent->wzName, pwzTempStr, MAX_DARWIN_COLUMN); |
226 | ReleaseNullStr(pwzTempStr); | 226 | ReleaseNullStr(pwzTempStr); |
227 | 227 | ||
228 | 228 | ||
229 | hr = WcaGetRecordString(hRec, vgpqParentDomain, &pwzTempStr); | 229 | hr = WcaGetRecordFormattedString(hRec, vgpqParentDomain, &pwzTempStr); |
230 | ExitOnFailure(hr, "failed to get Wix4Group.Domain"); | 230 | ExitOnFailure(hr, "failed to get Wix4Group.Domain"); |
231 | wcsncpy_s(psgParent->wzDomain, pwzTempStr, MAX_DARWIN_COLUMN); | 231 | wcsncpy_s(psgParent->wzDomain, pwzTempStr, MAX_DARWIN_COLUMN); |
232 | ReleaseNullStr(pwzTempStr); | 232 | ReleaseNullStr(pwzTempStr); |
@@ -288,13 +288,13 @@ HRESULT ScaGroupGetChildren( | |||
288 | ExitOnFailure(hr, "failed to get Component state for Wix4Group"); | 288 | ExitOnFailure(hr, "failed to get Component state for Wix4Group"); |
289 | } | 289 | } |
290 | 290 | ||
291 | hr = WcaGetRecordString(hRec, vgcqChildName, &pwzTempStr); | 291 | hr = WcaGetRecordFormattedString(hRec, vgcqChildName, &pwzTempStr); |
292 | ExitOnFailure(hr, "failed to get Wix4Group.Name"); | 292 | ExitOnFailure(hr, "failed to get Wix4Group.Name"); |
293 | wcsncpy_s(psgChild->wzName, pwzTempStr, MAX_DARWIN_COLUMN); | 293 | wcsncpy_s(psgChild->wzName, pwzTempStr, MAX_DARWIN_COLUMN); |
294 | ReleaseNullStr(pwzTempStr); | 294 | ReleaseNullStr(pwzTempStr); |
295 | 295 | ||
296 | 296 | ||
297 | hr = WcaGetRecordString(hRec, vgcqChildDomain, &pwzTempStr); | 297 | hr = WcaGetRecordFormattedString(hRec, vgcqChildDomain, &pwzTempStr); |
298 | ExitOnFailure(hr, "failed to get Wix4Group.Domain"); | 298 | ExitOnFailure(hr, "failed to get Wix4Group.Domain"); |
299 | wcsncpy_s(psgChild->wzDomain, pwzTempStr, MAX_DARWIN_COLUMN); | 299 | wcsncpy_s(psgChild->wzDomain, pwzTempStr, MAX_DARWIN_COLUMN); |
300 | ReleaseNullStr(pwzTempStr); | 300 | ReleaseNullStr(pwzTempStr); |
@@ -412,8 +412,11 @@ LExit: | |||
412 | } | 412 | } |
413 | 413 | ||
414 | /* **************************************************************** | 414 | /* **************************************************************** |
415 | ScaGroupExecute - Schedules group account creation or removal based on | 415 | ScaGroupExecute - Schedules group account creation or removal based on component state. |
416 | component state. | 416 | |
417 | Output: CustomData for CreateGroup - Name\tDomain\tComment\tAttributes\tScriptKey | ||
418 | CustomData for RollbackCreateGroup - ScriptKey\tName\tDomain\tComment\tRollbackAttributes | ||
419 | CustomData for RemoveGroup - Name\tDomain\tComment\tAttributes | ||
417 | ******************************************************************/ | 420 | ******************************************************************/ |
418 | HRESULT ScaGroupExecute( | 421 | HRESULT ScaGroupExecute( |
419 | __in SCA_GROUP *psgList | 422 | __in SCA_GROUP *psgList |
@@ -455,8 +458,7 @@ HRESULT ScaGroupExecute( | |||
455 | // and removing groups. Note: MSDN says that it is safe to call these APIs from any | 458 | // and removing groups. Note: MSDN says that it is safe to call these APIs from any |
456 | // user, so we should be safe calling it during immediate mode. | 459 | // user, so we should be safe calling it during immediate mode. |
457 | 460 | ||
458 | LPCWSTR wzDomain = psg->wzDomain; | 461 | hr = GetDomainServerName(psg->wzDomain, &pwzServerName); |
459 | hr = GetDomainServerName(wzDomain, &pwzServerName); | ||
460 | 462 | ||
461 | er = ::NetLocalGroupGetInfo(pwzServerName, psg->wzName, 0, reinterpret_cast<LPBYTE*>(&pGroupInfo)); | 463 | er = ::NetLocalGroupGetInfo(pwzServerName, psg->wzName, 0, reinterpret_cast<LPBYTE*>(&pGroupInfo)); |
462 | if (NERR_Success == er) | 464 | if (NERR_Success == er) |
@@ -471,7 +473,7 @@ HRESULT ScaGroupExecute( | |||
471 | { | 473 | { |
472 | geGroupExists = GROUP_EXISTS_INDETERMINATE; | 474 | geGroupExists = GROUP_EXISTS_INDETERMINATE; |
473 | hr = HRESULT_FROM_WIN32(er); | 475 | hr = HRESULT_FROM_WIN32(er); |
474 | WcaLog(LOGMSG_VERBOSE, "Failed to check existence of domain: %ls, group: %ls (error code 0x%x) - continuing", wzDomain, psg->wzName, hr); | 476 | WcaLog(LOGMSG_VERBOSE, "Failed to check existence of group: %ls\\%ls (error code 0x%x) - continuing", psg->wzDomain, psg->wzName, hr); |
475 | hr = S_OK; | 477 | hr = S_OK; |
476 | er = ERROR_SUCCESS; | 478 | er = ERROR_SUCCESS; |
477 | } | 479 | } |
@@ -498,7 +500,7 @@ HRESULT ScaGroupExecute( | |||
498 | && !(SCAG_UPDATE_IF_EXISTS & psg->iAttributes)) | 500 | && !(SCAG_UPDATE_IF_EXISTS & psg->iAttributes)) |
499 | { | 501 | { |
500 | hr = HRESULT_FROM_WIN32(NERR_GroupExists); | 502 | hr = HRESULT_FROM_WIN32(NERR_GroupExists); |
501 | MessageExitOnFailure(hr, msierrGRPFailedGroupCreateExists, "Failed to create group: %ls because group already exists.", psg->wzName); | 503 | MessageExitOnFailure(hr, msierrGRPFailedGroupCreateExists, "Failed to create group: %ls\\%ls because group already exists.", psg->wzDomain, psg->wzName); |
502 | } | 504 | } |
503 | } | 505 | } |
504 | 506 | ||
@@ -537,10 +539,19 @@ HRESULT ScaGroupExecute( | |||
537 | ExitOnFailure(hr, "Failed to add group name to rollback custom action data: %ls", psg->wzName); | 539 | ExitOnFailure(hr, "Failed to add group name to rollback custom action data: %ls", psg->wzName); |
538 | hr = WcaWriteStringToCaData(psg->wzDomain, &pwzRollbackData); | 540 | hr = WcaWriteStringToCaData(psg->wzDomain, &pwzRollbackData); |
539 | ExitOnFailure(hr, "Failed to add group domain to rollback custom action data: %ls", psg->wzDomain); | 541 | ExitOnFailure(hr, "Failed to add group domain to rollback custom action data: %ls", psg->wzDomain); |
542 | hr = WcaWriteStringToCaData(psg->wzComment, &pwzRollbackData); | ||
543 | ExitOnFailure(hr, "Failed to add group comment to rollback custom action data: %ls", psg->wzComment); | ||
540 | hr = WcaWriteIntegerToCaData(iRollbackUserAttributes, &pwzRollbackData); | 544 | hr = WcaWriteIntegerToCaData(iRollbackUserAttributes, &pwzRollbackData); |
541 | ExitOnFailure(hr, "failed to add group attributes to rollback custom action data for group: %ls", psg->wzKey); | 545 | ExitOnFailure(hr, "failed to add group rollback attributes to rollback custom action data: %i", iRollbackUserAttributes); |
542 | 546 | ||
543 | hr = WcaDoDeferredAction(CUSTOM_ACTION_DECORATION6(L"CreateGroupRollback"), pwzRollbackData, COST_GROUP_DELETE); | 547 | if (*psg->wzDomain) |
548 | { | ||
549 | hr = WcaDoDeferredAction(CUSTOM_ACTION_DECORATION6(L"CreateDomainGroupRollback"), pwzRollbackData, COST_GROUP_DELETE); | ||
550 | } | ||
551 | else | ||
552 | { | ||
553 | hr = WcaDoDeferredAction(CUSTOM_ACTION_DECORATION6(L"CreateGroupRollback"), pwzRollbackData, COST_GROUP_DELETE); | ||
554 | } | ||
544 | ExitOnFailure(hr, "failed to schedule CreateGroupRollback"); | 555 | ExitOnFailure(hr, "failed to schedule CreateGroupRollback"); |
545 | } | 556 | } |
546 | else | 557 | else |
@@ -571,11 +582,10 @@ HRESULT ScaGroupExecute( | |||
571 | hr = WcaWriteIntegerToCaData(psg->iAttributes, &pwzActionData); | 582 | hr = WcaWriteIntegerToCaData(psg->iAttributes, &pwzActionData); |
572 | ExitOnFailure(hr, "failed to add group attributes to custom action data for group: %ls", psg->wzKey); | 583 | ExitOnFailure(hr, "failed to add group attributes to custom action data for group: %ls", psg->wzKey); |
573 | 584 | ||
574 | // Schedule the removal because the group exists and we don't have any flags set | 585 | // Schedule the removal because the group exists and we don't have any flags set that say not to remove the group |
575 | // that say not to remove the group on uninstall. | 586 | // on uninstall. |
576 | // | 587 | // |
577 | // Note: We can't rollback the removal of a group which is why RemoveGroup is a commit | 588 | // Note: We can't rollback the removal of a group which is why RemoveGroup is a commit CustomAction. |
578 | // CustomAction. | ||
579 | if (psg->wzDomain && *psg->wzDomain) | 589 | if (psg->wzDomain && *psg->wzDomain) |
580 | { | 590 | { |
581 | hr = WcaDoDeferredAction(CUSTOM_ACTION_DECORATION6(L"RemoveDomainGroup"), pwzActionData, COST_GROUP_DELETE); | 591 | hr = WcaDoDeferredAction(CUSTOM_ACTION_DECORATION6(L"RemoveDomainGroup"), pwzActionData, COST_GROUP_DELETE); |
@@ -631,15 +641,31 @@ LExit: | |||
631 | /* **************************************************************** | 641 | /* **************************************************************** |
632 | ScaGroupMembershipRemoveParentsExecute - Schedules group membership removal | 642 | ScaGroupMembershipRemoveParentsExecute - Schedules group membership removal |
633 | based on parent/child component state | 643 | based on parent/child component state |
644 | |||
645 | Output: deferred CustomActionData - | ||
646 | ParentGroupName\tParentGroupDomain\tChildGroupName\tChildGroupDomain\tAttributes\tScriptkey | ||
647 | rollback CustomActionData - | ||
648 | ParentGroupName\tParentGroupDomain\tChildGroupName\tChildGroupDomain\tAttributes\tScriptkey | ||
634 | ******************************************************************/ | 649 | ******************************************************************/ |
635 | HRESULT ScaGroupMembershipRemoveParentsExecute( | 650 | HRESULT ScaGroupMembershipRemoveParentsExecute( |
636 | __in SCA_GROUP* psg | 651 | __in SCA_GROUP* psg, |
652 | __inout DWORD &cScriptIndex | ||
637 | ) | 653 | ) |
638 | { | 654 | { |
639 | HRESULT hr = S_OK; | 655 | HRESULT hr = S_OK; |
640 | LPWSTR pwzActionData = NULL; | 656 | LPWSTR pwzActionData = NULL; |
657 | LPWSTR pwzBaseScriptKey = NULL; | ||
658 | LPWSTR pwzScriptKey = NULL; | ||
659 | SCA_GROUP* psgp = NULL; | ||
641 | 660 | ||
642 | for (SCA_GROUP* psgp = psg->psgParents; psgp; psgp = psgp->psgNext) | 661 | ++cScriptIndex; |
662 | // Get the base script key for this CustomAction. | ||
663 | hr = WcaCaScriptCreateKey(&pwzBaseScriptKey); | ||
664 | ExitOnFailure(hr, "Failed to get encoding key."); | ||
665 | hr = StrAllocFormatted(&pwzScriptKey, L"%ls_removemember_%u", pwzBaseScriptKey, cScriptIndex); | ||
666 | ExitOnFailure(hr, "Failed to create script key"); | ||
667 | |||
668 | for (psgp = psg->psgParents; psgp; psgp = psgp->psgNext) | ||
643 | { | 669 | { |
644 | Assert(psgp->wzName); | 670 | Assert(psgp->wzName); |
645 | if (WcaIsUninstalling(psg->isInstalled, psg->isAction) | 671 | if (WcaIsUninstalling(psg->isInstalled, psg->isAction) |
@@ -655,18 +681,24 @@ HRESULT ScaGroupMembershipRemoveParentsExecute( | |||
655 | ExitOnFailure(hr, "Failed to add child group domain to custom action data: %ls", psg->wzDomain); | 681 | ExitOnFailure(hr, "Failed to add child group domain to custom action data: %ls", psg->wzDomain); |
656 | hr = WcaWriteIntegerToCaData(psg->iAttributes, &pwzActionData); | 682 | hr = WcaWriteIntegerToCaData(psg->iAttributes, &pwzActionData); |
657 | ExitOnFailure(hr, "Failed to add group attributes to custom action data: %i", psg->iAttributes); | 683 | ExitOnFailure(hr, "Failed to add group attributes to custom action data: %i", psg->iAttributes); |
684 | hr = WcaWriteStringToCaData(pwzScriptKey, &pwzActionData); | ||
685 | ExitOnFailure(hr, "Failed to add script key to custom action data: %i", pwzScriptKey); | ||
658 | 686 | ||
659 | if (psgp->wzDomain && *psgp->wzDomain) | 687 | if (psgp->wzDomain && *psgp->wzDomain) |
660 | { | 688 | { |
661 | hr = WcaDoDeferredAction(CUSTOM_ACTION_DECORATION6(L"RemoveDomainGroupMembership"), pwzActionData, COST_GROUPMEMBERSHIP_DELETE); | 689 | hr = WcaDoDeferredAction(CUSTOM_ACTION_DECORATION6(L"RemoveDomainGroupMembership"), pwzActionData, COST_GROUPMEMBERSHIP_DELETE); |
690 | hr = WcaDoDeferredAction(CUSTOM_ACTION_DECORATION6(L"RemoveDomainGroupMembershipRollback"), pwzActionData, COST_GROUPMEMBERSHIP_ADD); | ||
662 | } | 691 | } |
663 | else | 692 | else |
664 | { | 693 | { |
665 | hr = WcaDoDeferredAction(CUSTOM_ACTION_DECORATION6(L"RemoveGroupMembership"), pwzActionData, COST_GROUPMEMBERSHIP_DELETE); | 694 | hr = WcaDoDeferredAction(CUSTOM_ACTION_DECORATION6(L"RemoveGroupMembership"), pwzActionData, COST_GROUPMEMBERSHIP_DELETE); |
695 | hr = WcaDoDeferredAction(CUSTOM_ACTION_DECORATION6(L"RemoveGroupMembershipRollback"), pwzActionData, COST_GROUPMEMBERSHIP_ADD); | ||
666 | } | 696 | } |
667 | 697 | ||
668 | LExit: | 698 | LExit: |
669 | ReleaseNullStr(pwzActionData); | 699 | ReleaseNullStr(pwzActionData); |
700 | ReleaseNullStr(pwzBaseScriptKey); | ||
701 | ReleaseNullStr(pwzScriptKey); | ||
670 | if (hr != S_OK && !(psg->iAttributes & SCAG_NON_VITAL)) | 702 | if (hr != S_OK && !(psg->iAttributes & SCAG_NON_VITAL)) |
671 | { | 703 | { |
672 | return hr; | 704 | return hr; |
@@ -677,16 +709,32 @@ HRESULT ScaGroupMembershipRemoveParentsExecute( | |||
677 | } | 709 | } |
678 | 710 | ||
679 | /* **************************************************************** | 711 | /* **************************************************************** |
680 | ScaGroupMembershipRemoveChildrenExecute - | 712 | ScaGroupMembershipRemoveChildrenExecute - |
713 | |||
714 | Output: deferred CustomActionData - | ||
715 | ParentGroupName\tParentGroupDomain\tChildGroupName\tChildGroupDomain\tAttributes\tScriptkey | ||
716 | rollback CustomActionData - | ||
717 | ParentGroupName\tParentGroupDomain\tChildGroupName\tChildGroupDomain\tAttributes\tScriptkey | ||
681 | ******************************************************************/ | 718 | ******************************************************************/ |
682 | HRESULT ScaGroupMembershipRemoveChildrenExecute( | 719 | HRESULT ScaGroupMembershipRemoveChildrenExecute( |
683 | __in SCA_GROUP* psg | 720 | __in SCA_GROUP* psg, |
721 | __inout DWORD &cScriptIndex | ||
684 | ) | 722 | ) |
685 | { | 723 | { |
686 | HRESULT hr = S_OK; | 724 | HRESULT hr = S_OK; |
687 | LPWSTR pwzActionData = NULL; | 725 | LPWSTR pwzActionData = NULL; |
726 | LPWSTR pwzBaseScriptKey = NULL; | ||
727 | LPWSTR pwzScriptKey = NULL; | ||
728 | SCA_GROUP* psgc = NULL; | ||
688 | 729 | ||
689 | for (SCA_GROUP* psgc = psg->psgChildren; psgc; psgc = psgc->psgNext) | 730 | ++cScriptIndex; |
731 | // Get the base script key for this CustomAction. | ||
732 | hr = WcaCaScriptCreateKey(&pwzBaseScriptKey); | ||
733 | ExitOnFailure(hr, "Failed to get encoding key."); | ||
734 | hr = StrAllocFormatted(&pwzScriptKey, L"%ls_removemember_%u", pwzBaseScriptKey, cScriptIndex); | ||
735 | ExitOnFailure(hr, "Failed to create script key"); | ||
736 | |||
737 | for (psgc = psg->psgChildren; psgc; psgc = psgc->psgNext) | ||
690 | { | 738 | { |
691 | Assert(psgc->wzName); | 739 | Assert(psgc->wzName); |
692 | if (WcaIsUninstalling(psg->isInstalled, psg->isAction) | 740 | if (WcaIsUninstalling(psg->isInstalled, psg->isAction) |
@@ -702,17 +750,23 @@ HRESULT ScaGroupMembershipRemoveChildrenExecute( | |||
702 | ExitOnFailure(hr, "Failed to add child group domain to custom action data: %ls", psgc->wzDomain); | 750 | ExitOnFailure(hr, "Failed to add child group domain to custom action data: %ls", psgc->wzDomain); |
703 | hr = WcaWriteIntegerToCaData(psg->iAttributes, &pwzActionData); | 751 | hr = WcaWriteIntegerToCaData(psg->iAttributes, &pwzActionData); |
704 | ExitOnFailure(hr, "Failed to add group attributes to custom action data: %i", psg->iAttributes); | 752 | ExitOnFailure(hr, "Failed to add group attributes to custom action data: %i", psg->iAttributes); |
753 | hr = WcaWriteStringToCaData(pwzScriptKey, &pwzActionData); | ||
754 | ExitOnFailure(hr, "Failed to add script key to custom action data: %i", pwzScriptKey); | ||
705 | if (psg->wzDomain && *psg->wzDomain) | 755 | if (psg->wzDomain && *psg->wzDomain) |
706 | { | 756 | { |
707 | hr = WcaDoDeferredAction(CUSTOM_ACTION_DECORATION6(L"RemoveDomainGroupMembership"), pwzActionData, COST_GROUPMEMBERSHIP_DELETE); | 757 | hr = WcaDoDeferredAction(CUSTOM_ACTION_DECORATION6(L"RemoveDomainGroupMembership"), pwzActionData, COST_GROUPMEMBERSHIP_DELETE); |
758 | hr = WcaDoDeferredAction(CUSTOM_ACTION_DECORATION6(L"RemoveDomainGroupMembershipRollback"), pwzActionData, COST_GROUPMEMBERSHIP_ADD); | ||
708 | } | 759 | } |
709 | else | 760 | else |
710 | { | 761 | { |
711 | hr = WcaDoDeferredAction(CUSTOM_ACTION_DECORATION6(L"RemoveGroupMembership"), pwzActionData, COST_GROUPMEMBERSHIP_DELETE); | 762 | hr = WcaDoDeferredAction(CUSTOM_ACTION_DECORATION6(L"RemoveGroupMembership"), pwzActionData, COST_GROUPMEMBERSHIP_DELETE); |
763 | hr = WcaDoDeferredAction(CUSTOM_ACTION_DECORATION6(L"RemoveGroupMembershipRollback"), pwzActionData, COST_GROUPMEMBERSHIP_ADD); | ||
712 | } | 764 | } |
713 | 765 | ||
714 | LExit: | 766 | LExit: |
715 | ReleaseNullStr(pwzActionData); | 767 | ReleaseNullStr(pwzActionData); |
768 | ReleaseNullStr(pwzBaseScriptKey); | ||
769 | ReleaseNullStr(pwzScriptKey); | ||
716 | 770 | ||
717 | if (hr != S_OK && !(psg->iAttributes & SCAG_NON_VITAL)) | 771 | if (hr != S_OK && !(psg->iAttributes & SCAG_NON_VITAL)) |
718 | { | 772 | { |
@@ -726,23 +780,29 @@ HRESULT ScaGroupMembershipRemoveChildrenExecute( | |||
726 | /* **************************************************************** | 780 | /* **************************************************************** |
727 | ScaGroupMembershipRemoveExecute - Schedules group membership removal | 781 | ScaGroupMembershipRemoveExecute - Schedules group membership removal |
728 | based on parent/child component state | 782 | based on parent/child component state |
783 | |||
784 | Output: deferred CustomActionData - | ||
785 | ParentGroupName\tParentGroupDomain\tChildGroupName\tChildGroupDomain\tAttributes\tScriptkey | ||
786 | rollback CustomActionData - | ||
787 | ParentGroupName\tParentGroupDomain\tChildGroupName\tChildGroupDomain\tAttributes\tScriptkey | ||
729 | ******************************************************************/ | 788 | ******************************************************************/ |
730 | HRESULT ScaGroupMembershipRemoveExecute( | 789 | HRESULT ScaGroupMembershipRemoveExecute( |
731 | __in SCA_GROUP* psgList | 790 | __in SCA_GROUP* psgList |
732 | ) | 791 | ) |
733 | { | 792 | { |
734 | HRESULT hr = S_OK; | 793 | HRESULT hr = S_OK; |
794 | static DWORD iScriptIndex = 0; | ||
735 | 795 | ||
736 | // Loop through all the users to be configured. | 796 | // Loop through all the users to be configured. |
737 | for (SCA_GROUP* psg = psgList; psg; psg = psg->psgNext) | 797 | for (SCA_GROUP* psg = psgList; psg; psg = psg->psgNext) |
738 | { | 798 | { |
739 | Assert(psg->wzName); | 799 | Assert(psg->wzName); |
740 | // first we loop through the Parents | 800 | // first we loop through the Parents |
741 | hr = ScaGroupMembershipRemoveParentsExecute(psg); | 801 | hr = ScaGroupMembershipRemoveParentsExecute(psg, iScriptIndex); |
742 | ExitOnFailure(hr, "Failed to remove parent membership for vital group: %ls", psg->wzKey); | 802 | ExitOnFailure(hr, "Failed to remove parent membership for vital group: %ls", psg->wzKey); |
743 | 803 | ||
744 | // then through the Children | 804 | // then through the Children |
745 | hr = ScaGroupMembershipRemoveChildrenExecute(psg); | 805 | hr = ScaGroupMembershipRemoveChildrenExecute(psg, iScriptIndex); |
746 | ExitOnFailure(hr, "Failed to remove child membership for vital group: %ls", psg->wzKey); | 806 | ExitOnFailure(hr, "Failed to remove child membership for vital group: %ls", psg->wzKey); |
747 | } | 807 | } |
748 | 808 | ||
@@ -755,13 +815,24 @@ ScaGroupMembershipAddParentsExecute - Schedules group membership removal | |||
755 | based on parent/child component state | 815 | based on parent/child component state |
756 | ******************************************************************/ | 816 | ******************************************************************/ |
757 | HRESULT ScaGroupMembershipAddParentsExecute( | 817 | HRESULT ScaGroupMembershipAddParentsExecute( |
758 | __in SCA_GROUP* psg | 818 | __in SCA_GROUP* psg, |
819 | __inout DWORD &cScriptIndex | ||
759 | ) | 820 | ) |
760 | { | 821 | { |
761 | HRESULT hr = S_OK; | 822 | HRESULT hr = S_OK; |
762 | LPWSTR pwzActionData = NULL; | 823 | LPWSTR pwzActionData = NULL; |
824 | LPWSTR pwzBaseScriptKey = NULL; | ||
825 | LPWSTR pwzScriptKey = NULL; | ||
826 | SCA_GROUP* psgp = NULL; | ||
827 | |||
828 | ++cScriptIndex; | ||
829 | // Get the base script key for this CustomAction. | ||
830 | hr = WcaCaScriptCreateKey(&pwzBaseScriptKey); | ||
831 | ExitOnFailure(hr, "Failed to get encoding key."); | ||
832 | hr = StrAllocFormatted(&pwzScriptKey, L"%ls_addmember_%u", pwzBaseScriptKey, cScriptIndex); | ||
833 | ExitOnFailure(hr, "Failed to create script key"); | ||
763 | 834 | ||
764 | for (SCA_GROUP* psgp = psg->psgParents; psgp; psgp = psgp->psgNext) | 835 | for (psgp = psg->psgParents; psgp; psgp = psgp->psgNext) |
765 | { | 836 | { |
766 | Assert(psgp->wzName); | 837 | Assert(psgp->wzName); |
767 | if (WcaIsInstalling(psg->isInstalled, psg->isAction) | 838 | if (WcaIsInstalling(psg->isInstalled, psg->isAction) |
@@ -777,17 +848,23 @@ HRESULT ScaGroupMembershipAddParentsExecute( | |||
777 | ExitOnFailure(hr, "Failed to add child group domain to custom action data: %ls", psg->wzDomain); | 848 | ExitOnFailure(hr, "Failed to add child group domain to custom action data: %ls", psg->wzDomain); |
778 | hr = WcaWriteIntegerToCaData(psg->iAttributes, &pwzActionData); | 849 | hr = WcaWriteIntegerToCaData(psg->iAttributes, &pwzActionData); |
779 | ExitOnFailure(hr, "Failed to add group attributes to custom action data: %i", psg->iAttributes); | 850 | ExitOnFailure(hr, "Failed to add group attributes to custom action data: %i", psg->iAttributes); |
851 | hr = WcaWriteStringToCaData(pwzScriptKey, &pwzActionData); | ||
852 | ExitOnFailure(hr, "Failed to add script key to custom action data: %i", pwzScriptKey); | ||
780 | if (psgp->wzDomain&&* psgp->wzDomain) | 853 | if (psgp->wzDomain&&* psgp->wzDomain) |
781 | { | 854 | { |
782 | hr = WcaDoDeferredAction(CUSTOM_ACTION_DECORATION6(L"AddDomainGroupMembership"), pwzActionData, COST_GROUPMEMBERSHIP_ADD); | 855 | hr = WcaDoDeferredAction(CUSTOM_ACTION_DECORATION6(L"AddDomainGroupMembership"), pwzActionData, COST_GROUPMEMBERSHIP_ADD); |
856 | hr = WcaDoDeferredAction(CUSTOM_ACTION_DECORATION6(L"AddDomainGroupMembershipRollback"), pwzActionData, COST_GROUPMEMBERSHIP_ADD); | ||
783 | } | 857 | } |
784 | else | 858 | else |
785 | { | 859 | { |
786 | hr = WcaDoDeferredAction(CUSTOM_ACTION_DECORATION6(L"AddGroupMembership"), pwzActionData, COST_GROUPMEMBERSHIP_ADD); | 860 | hr = WcaDoDeferredAction(CUSTOM_ACTION_DECORATION6(L"AddGroupMembership"), pwzActionData, COST_GROUPMEMBERSHIP_ADD); |
861 | hr = WcaDoDeferredAction(CUSTOM_ACTION_DECORATION6(L"AddGroupMembershipRollback"), pwzActionData, COST_GROUPMEMBERSHIP_ADD); | ||
787 | } | 862 | } |
788 | 863 | ||
789 | LExit: | 864 | LExit: |
790 | ReleaseNullStr(pwzActionData); | 865 | ReleaseNullStr(pwzActionData); |
866 | ReleaseNullStr(pwzBaseScriptKey); | ||
867 | ReleaseNullStr(pwzScriptKey); | ||
791 | 868 | ||
792 | if (hr != S_OK && !(psg->iAttributes & SCAG_NON_VITAL)) | 869 | if (hr != S_OK && !(psg->iAttributes & SCAG_NON_VITAL)) |
793 | { | 870 | { |
@@ -801,16 +878,32 @@ HRESULT ScaGroupMembershipAddParentsExecute( | |||
801 | /* **************************************************************** | 878 | /* **************************************************************** |
802 | ScaGroupMembershipAddChildrenExecute - Schedules group membership removal | 879 | ScaGroupMembershipAddChildrenExecute - Schedules group membership removal |
803 | based on parent/child component state | 880 | based on parent/child component state |
881 | |||
882 | Output: deferred CustomActionData - | ||
883 | ParentGroupName\tParentGroupDomain\tChildGroupName\tChildGroupDomain\tAttributes\tScriptkey | ||
884 | rollback CustomActionData - | ||
885 | ParentGroupName\tParentGroupDomain\tChildGroupName\tChildGroupDomain\tAttributes\tScriptkey | ||
804 | ******************************************************************/ | 886 | ******************************************************************/ |
805 | HRESULT ScaGroupMembershipAddChildrenExecute( | 887 | HRESULT ScaGroupMembershipAddChildrenExecute( |
806 | __in SCA_GROUP* psg | 888 | __in SCA_GROUP* psg, |
889 | __inout DWORD &cScriptIndex | ||
807 | ) | 890 | ) |
808 | { | 891 | { |
809 | HRESULT hr = S_OK; | 892 | HRESULT hr = S_OK; |
810 | LPWSTR pwzActionData = NULL; | 893 | LPWSTR pwzActionData = NULL; |
894 | LPWSTR pwzBaseScriptKey = NULL; | ||
895 | LPWSTR pwzScriptKey = NULL; | ||
896 | SCA_GROUP* psgc = NULL; | ||
897 | |||
898 | ++cScriptIndex; | ||
899 | // Get the base script key for this CustomAction. | ||
900 | hr = WcaCaScriptCreateKey(&pwzBaseScriptKey); | ||
901 | ExitOnFailure(hr, "Failed to get encoding key."); | ||
902 | hr = StrAllocFormatted(&pwzScriptKey, L"%ls_addmember_%u", pwzBaseScriptKey, cScriptIndex); | ||
903 | ExitOnFailure(hr, "Failed to create script key"); | ||
811 | 904 | ||
812 | // then through the Children | 905 | // then through the Children |
813 | for (SCA_GROUP* psgc = psg->psgChildren; psgc; psgc = psgc->psgNext) | 906 | for (psgc = psg->psgChildren; psgc; psgc = psgc->psgNext) |
814 | { | 907 | { |
815 | Assert(psgc->wzName); | 908 | Assert(psgc->wzName); |
816 | if (WcaIsInstalling(psg->isInstalled, psg->isAction) | 909 | if (WcaIsInstalling(psg->isInstalled, psg->isAction) |
@@ -826,17 +919,24 @@ HRESULT ScaGroupMembershipAddChildrenExecute( | |||
826 | ExitOnFailure(hr, "Failed to add parent group domain to custom action data: %ls", psgc->wzDomain); | 919 | ExitOnFailure(hr, "Failed to add parent group domain to custom action data: %ls", psgc->wzDomain); |
827 | hr = WcaWriteIntegerToCaData(psg->iAttributes, &pwzActionData); | 920 | hr = WcaWriteIntegerToCaData(psg->iAttributes, &pwzActionData); |
828 | ExitOnFailure(hr, "Failed to add group attributes to custom action data: %i", psg->iAttributes); | 921 | ExitOnFailure(hr, "Failed to add group attributes to custom action data: %i", psg->iAttributes); |
922 | hr = WcaWriteStringToCaData(pwzScriptKey, &pwzActionData); | ||
923 | ExitOnFailure(hr, "Failed to add script key to custom action data: %i", pwzScriptKey); | ||
829 | if (psg->wzDomain && *psg->wzDomain) | 924 | if (psg->wzDomain && *psg->wzDomain) |
830 | { | 925 | { |
831 | hr = WcaDoDeferredAction(CUSTOM_ACTION_DECORATION6(L"AddDomainGroupMembership"), pwzActionData, COST_GROUPMEMBERSHIP_ADD); | 926 | hr = WcaDoDeferredAction(CUSTOM_ACTION_DECORATION6(L"AddDomainGroupMembership"), pwzActionData, COST_GROUPMEMBERSHIP_ADD); |
927 | hr = WcaDoDeferredAction(CUSTOM_ACTION_DECORATION6(L"AddDomainGroupMembershipRollback"), pwzActionData, COST_GROUPMEMBERSHIP_ADD); | ||
832 | } | 928 | } |
833 | else | 929 | else |
834 | { | 930 | { |
835 | hr = WcaDoDeferredAction(CUSTOM_ACTION_DECORATION6(L"AddGroupMembership"), pwzActionData, COST_GROUPMEMBERSHIP_ADD); | 931 | hr = WcaDoDeferredAction(CUSTOM_ACTION_DECORATION6(L"AddGroupMembership"), pwzActionData, COST_GROUPMEMBERSHIP_ADD); |
932 | hr = WcaDoDeferredAction(CUSTOM_ACTION_DECORATION6(L"AddGroupMembershipRollback"), pwzActionData, COST_GROUPMEMBERSHIP_ADD); | ||
836 | } | 933 | } |
837 | 934 | ||
838 | LExit: | 935 | LExit: |
839 | ReleaseNullStr(pwzActionData); | 936 | ReleaseNullStr(pwzActionData); |
937 | ReleaseNullStr(pwzBaseScriptKey); | ||
938 | ReleaseNullStr(pwzScriptKey); | ||
939 | |||
840 | if (hr != S_OK && !(psg->iAttributes & SCAG_NON_VITAL)) | 940 | if (hr != S_OK && !(psg->iAttributes & SCAG_NON_VITAL)) |
841 | { | 941 | { |
842 | return hr; | 942 | return hr; |
@@ -855,17 +955,18 @@ HRESULT ScaGroupMembershipAddExecute( | |||
855 | ) | 955 | ) |
856 | { | 956 | { |
857 | HRESULT hr = S_OK; | 957 | HRESULT hr = S_OK; |
958 | static DWORD iScriptIndex = 0; | ||
858 | 959 | ||
859 | // Loop through all the users to be configured. | 960 | // Loop through all the users to be configured. |
860 | for (SCA_GROUP* psg = psgList; psg; psg = psg->psgNext) | 961 | for (SCA_GROUP* psg = psgList; psg; psg = psg->psgNext) |
861 | { | 962 | { |
862 | Assert(psg->wzName); | 963 | Assert(psg->wzName); |
863 | // first we loop through the Parents | 964 | // first we loop through the Parents |
864 | hr = ScaGroupMembershipAddParentsExecute(psg); | 965 | hr = ScaGroupMembershipAddParentsExecute(psg, iScriptIndex); |
865 | ExitOnFailure(hr, "Failed to add parent membership for vital group: %ls", psg->wzKey); | 966 | ExitOnFailure(hr, "Failed to add parent membership for vital group: %ls", psg->wzKey); |
866 | 967 | ||
867 | // then through the Children | 968 | // then through the Children |
868 | hr = ScaGroupMembershipAddChildrenExecute(psg); | 969 | hr = ScaGroupMembershipAddChildrenExecute(psg, iScriptIndex); |
869 | ExitOnFailure(hr, "Failed to add child membership for vital group: %ls", psg->wzKey); | 970 | ExitOnFailure(hr, "Failed to add child membership for vital group: %ls", psg->wzKey); |
870 | } | 971 | } |
871 | 972 | ||