aboutsummaryrefslogtreecommitdiff
path: root/src/ext/Util/ca/scagroup.cpp
diff options
context:
space:
mode:
authorBevan Weiss <bevan.weiss@gmail.com>2024-08-04 21:13:44 +1000
committerRob Mensching <rob@firegiant.com>2025-02-11 23:14:49 -0800
commit5b4a6538ee06988c75b717bd905197fb670e6142 (patch)
treeeb078854f258ebdabaf206282d56cbdcf87759ef /src/ext/Util/ca/scagroup.cpp
parent2c5bb89424b12de812498d568bc1aae2d4098e60 (diff)
downloadwix-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.cpp159
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/* ****************************************************************
415ScaGroupExecute - Schedules group account creation or removal based on 415ScaGroupExecute - Schedules group account creation or removal based on component state.
416component 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******************************************************************/
418HRESULT ScaGroupExecute( 421HRESULT 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/* ****************************************************************
632ScaGroupMembershipRemoveParentsExecute - Schedules group membership removal 642ScaGroupMembershipRemoveParentsExecute - Schedules group membership removal
633based on parent/child component state 643based 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******************************************************************/
635HRESULT ScaGroupMembershipRemoveParentsExecute( 650HRESULT 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/* ****************************************************************
680ScaGroupMembershipRemoveChildrenExecute - 712ScaGroupMembershipRemoveChildrenExecute -
713
714 Output: deferred CustomActionData -
715 ParentGroupName\tParentGroupDomain\tChildGroupName\tChildGroupDomain\tAttributes\tScriptkey
716 rollback CustomActionData -
717 ParentGroupName\tParentGroupDomain\tChildGroupName\tChildGroupDomain\tAttributes\tScriptkey
681******************************************************************/ 718******************************************************************/
682HRESULT ScaGroupMembershipRemoveChildrenExecute( 719HRESULT 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/* ****************************************************************
727ScaGroupMembershipRemoveExecute - Schedules group membership removal 781ScaGroupMembershipRemoveExecute - Schedules group membership removal
728based on parent/child component state 782based 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******************************************************************/
730HRESULT ScaGroupMembershipRemoveExecute( 789HRESULT 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
755based on parent/child component state 815based on parent/child component state
756******************************************************************/ 816******************************************************************/
757HRESULT ScaGroupMembershipAddParentsExecute( 817HRESULT 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/* ****************************************************************
802ScaGroupMembershipAddChildrenExecute - Schedules group membership removal 879ScaGroupMembershipAddChildrenExecute - Schedules group membership removal
803based on parent/child component state 880based 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******************************************************************/
805HRESULT ScaGroupMembershipAddChildrenExecute( 887HRESULT 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