diff options
author | Bevan Weiss <bevan.weiss@gmail.com> | 2024-07-06 21:03:57 +1000 |
---|---|---|
committer | Rob Mensching <rob@firegiant.com> | 2025-02-11 23:14:49 -0800 |
commit | 644276562dcadd65fcb0e9a7c06c704cdda36423 (patch) | |
tree | f42af115bf5354d1c1691c44d517388f6c369b16 /src/ext/Util/ca/scaexec.cpp | |
parent | 7b1bb025dea1d1e9e144cce0dcbba2d86f053b8f (diff) | |
download | wix-644276562dcadd65fcb0e9a7c06c704cdda36423.tar.gz wix-644276562dcadd65fcb0e9a7c06c704cdda36423.tar.bz2 wix-644276562dcadd65fcb0e9a7c06c704cdda36423.zip |
Group Add/Remove working.
Local group membership Add/Remove working, however with
BUILTIN local system groups .NET doesn't appear to locate them as either
groups nor basic security Principals. Still needs work to fix the test
for nested groups. Ideally with some way to test for domain groups.
Signed-off-by: Bevan Weiss <bevan.weiss@gmail.com>
Diffstat (limited to 'src/ext/Util/ca/scaexec.cpp')
-rw-r--r-- | src/ext/Util/ca/scaexec.cpp | 454 |
1 files changed, 254 insertions, 200 deletions
diff --git a/src/ext/Util/ca/scaexec.cpp b/src/ext/Util/ca/scaexec.cpp index 5a750c6b..64f4c823 100644 --- a/src/ext/Util/ca/scaexec.cpp +++ b/src/ext/Util/ca/scaexec.cpp | |||
@@ -291,146 +291,6 @@ LExit: | |||
291 | return hr; | 291 | return hr; |
292 | } | 292 | } |
293 | 293 | ||
294 | static HRESULT AddGroupToGroup( | ||
295 | __in LPWSTR wzMember, | ||
296 | __in LPCWSTR wzMemberDomain, | ||
297 | __in LPCWSTR wzGroup, | ||
298 | __in LPCWSTR wzGroupDomain | ||
299 | ) | ||
300 | { | ||
301 | Assert(wzMember && *wzMember && wzMemberDomain && wzGroup && *wzGroup && wzGroupDomain); | ||
302 | |||
303 | HRESULT hr = S_OK; | ||
304 | IADsGroup* pGroup = NULL; | ||
305 | BSTR bstrMember = NULL; | ||
306 | BSTR bstrGroup = NULL; | ||
307 | LPWSTR pwzMember = NULL; | ||
308 | LPWSTR pwzServerName = NULL; | ||
309 | LOCALGROUP_MEMBERS_INFO_3 lgmi {}; | ||
310 | |||
311 | GetDomainServerName(wzGroupDomain, &pwzServerName); | ||
312 | |||
313 | // Try adding it to the local group | ||
314 | if (wzMemberDomain) | ||
315 | { | ||
316 | hr = StrAllocFormatted(&pwzMember, L"%s\\%s", wzMemberDomain, wzMember); | ||
317 | ExitOnFailure(hr, "failed to allocate group domain string"); | ||
318 | } | ||
319 | |||
320 | lgmi.lgrmi3_domainandname = (NULL == pwzMember ? wzMember : pwzMember); | ||
321 | NET_API_STATUS ui = ::NetLocalGroupAddMembers(pwzServerName, wzGroup, 3, reinterpret_cast<LPBYTE>(&lgmi), 1); | ||
322 | hr = HRESULT_FROM_WIN32(ui); | ||
323 | if (HRESULT_FROM_WIN32(ERROR_MEMBER_IN_ALIAS) == hr) // if they're already a member of the group don't report an error | ||
324 | { | ||
325 | hr = S_OK; | ||
326 | } | ||
327 | |||
328 | // | ||
329 | // If we failed, try active directory | ||
330 | // | ||
331 | if (FAILED(hr)) | ||
332 | { | ||
333 | WcaLog(LOGMSG_VERBOSE, "Failed to add group: %ls, domain %ls to group: %ls, domain: %ls with error 0x%x. Attempting to use Active Directory", wzMember, wzMemberDomain, wzGroup, wzGroupDomain, hr); | ||
334 | |||
335 | hr = UserCreateADsPath(wzMemberDomain, wzMember, &bstrMember); | ||
336 | ExitOnFailure(hr, "failed to create group ADsPath for group: %ls domain: %ls", wzMember, wzMemberDomain); | ||
337 | |||
338 | hr = UserCreateADsPath(wzGroupDomain, wzGroup, &bstrGroup); | ||
339 | ExitOnFailure(hr, "failed to create group ADsPath for group: %ls domain: %ls", wzGroup, wzGroupDomain); | ||
340 | |||
341 | hr = ::ADsGetObject(bstrGroup, IID_IADsGroup, reinterpret_cast<void**>(&pGroup)); | ||
342 | ExitOnFailure(hr, "Failed to get group '%ls'.", reinterpret_cast<WCHAR*>(bstrGroup)); | ||
343 | |||
344 | hr = pGroup->Add(bstrMember); | ||
345 | if ((HRESULT_FROM_WIN32(ERROR_OBJECT_ALREADY_EXISTS) == hr) || (HRESULT_FROM_WIN32(ERROR_MEMBER_IN_ALIAS) == hr)) | ||
346 | hr = S_OK; | ||
347 | |||
348 | ExitOnFailure(hr, "Failed to add group %ls to group '%ls'.", reinterpret_cast<WCHAR*>(bstrMember), reinterpret_cast<WCHAR*>(bstrGroup)); | ||
349 | } | ||
350 | |||
351 | LExit: | ||
352 | ReleaseStr(pwzServerName); | ||
353 | ReleaseStr(pwzMember); | ||
354 | ReleaseBSTR(bstrMember); | ||
355 | ReleaseBSTR(bstrGroup); | ||
356 | ReleaseObject(pGroup); | ||
357 | |||
358 | return hr; | ||
359 | } | ||
360 | |||
361 | static HRESULT RemoveGroupFromGroup( | ||
362 | __in LPWSTR wzMember, | ||
363 | __in LPCWSTR wzMemberDomain, | ||
364 | __in LPCWSTR wzGroup, | ||
365 | __in LPCWSTR wzGroupDomain | ||
366 | ) | ||
367 | { | ||
368 | Assert(wzMember && *wzMember && wzMemberDomain && wzGroup && *wzGroup && wzGroupDomain); | ||
369 | |||
370 | HRESULT hr = S_OK; | ||
371 | IADsGroup* pGroup = NULL; | ||
372 | BSTR bstrMember = NULL; | ||
373 | BSTR bstrGroup = NULL; | ||
374 | LPWSTR pwzMember = NULL; | ||
375 | LPWSTR pwzServerName = NULL; | ||
376 | LOCALGROUP_MEMBERS_INFO_3 lgmi {}; | ||
377 | |||
378 | GetDomainServerName(wzGroupDomain, &pwzServerName, DS_WRITABLE_REQUIRED); | ||
379 | |||
380 | // Try removing it from the local group | ||
381 | if (wzMemberDomain) | ||
382 | { | ||
383 | hr = StrAllocFormatted(&pwzMember, L"%s\\%s", wzMemberDomain, wzMember); | ||
384 | ExitOnFailure(hr, "failed to allocate group domain string"); | ||
385 | } | ||
386 | |||
387 | lgmi.lgrmi3_domainandname = (NULL == pwzMember ? wzMember : pwzMember); | ||
388 | NET_API_STATUS ui = ::NetLocalGroupDelMembers(pwzServerName, wzGroup, 3, reinterpret_cast<LPBYTE>(&lgmi), 1); | ||
389 | hr = HRESULT_FROM_WIN32(ui); | ||
390 | if (HRESULT_FROM_WIN32(ERROR_MEMBER_NOT_IN_ALIAS) == hr | ||
391 | || HRESULT_FROM_WIN32(NERR_GroupNotFound) == hr | ||
392 | || HRESULT_FROM_WIN32(ERROR_NO_SUCH_MEMBER) == hr) // if they're already not a member of the group, or the group doesn't exist, don't report an error | ||
393 | { | ||
394 | hr = S_OK; | ||
395 | } | ||
396 | |||
397 | // | ||
398 | // If we failed, try active directory | ||
399 | // | ||
400 | if (FAILED(hr)) | ||
401 | { | ||
402 | WcaLog(LOGMSG_VERBOSE, "Failed to remove group: %ls, domain %ls from group: %ls, domain: %ls with error 0x%x. Attempting to use Active Directory", wzMember, wzMemberDomain, wzGroup, wzGroupDomain, hr); | ||
403 | |||
404 | hr = UserCreateADsPath(wzMemberDomain, wzMember, &bstrMember); | ||
405 | ExitOnFailure(hr, "failed to create group ADsPath in order to remove group: %ls domain: %ls from a group", wzMember, wzMemberDomain); | ||
406 | |||
407 | hr = UserCreateADsPath(wzGroupDomain, wzGroup, &bstrGroup); | ||
408 | ExitOnFailure(hr, "failed to create group ADsPath in order to remove group from group: %ls domain: %ls", wzGroup, wzGroupDomain); | ||
409 | |||
410 | hr = ::ADsGetObject(bstrGroup, IID_IADsGroup, reinterpret_cast<void**>(&pGroup)); | ||
411 | if ((HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) == hr)) // if parent group not found, no need to remove membership from group | ||
412 | { | ||
413 | hr = S_OK; | ||
414 | ExitFunction(); | ||
415 | } | ||
416 | ExitOnFailure(hr, "Failed to get group '%ls'.", reinterpret_cast<WCHAR*>(bstrGroup)); | ||
417 | |||
418 | hr = pGroup->Remove(bstrMember); | ||
419 | if ((HRESULT_FROM_WIN32(ERROR_MEMBER_NOT_IN_ALIAS) == hr)) // if already not a member, no need to worry about error | ||
420 | hr = S_OK; | ||
421 | ExitOnFailure(hr, "Failed to remove group %ls from group '%ls'.", reinterpret_cast<WCHAR*>(bstrMember), reinterpret_cast<WCHAR*>(bstrGroup)); | ||
422 | } | ||
423 | |||
424 | LExit: | ||
425 | ReleaseStr(pwzServerName); | ||
426 | ReleaseStr(pwzMember); | ||
427 | ReleaseBSTR(bstrMember); | ||
428 | ReleaseBSTR(bstrGroup); | ||
429 | ReleaseObject(pGroup); | ||
430 | |||
431 | return hr; | ||
432 | } | ||
433 | |||
434 | static HRESULT GetUserHasRight( | 294 | static HRESULT GetUserHasRight( |
435 | __in LSA_HANDLE hPolicy, | 295 | __in LSA_HANDLE hPolicy, |
436 | __in PSID pUserSid, | 296 | __in PSID pUserSid, |
@@ -842,7 +702,6 @@ LExit: | |||
842 | } | 702 | } |
843 | 703 | ||
844 | static HRESULT RemoveGroupInternal( | 704 | static HRESULT RemoveGroupInternal( |
845 | LPWSTR wzGroupCaData, | ||
846 | LPWSTR wzDomain, | 705 | LPWSTR wzDomain, |
847 | LPWSTR wzName, | 706 | LPWSTR wzName, |
848 | int iAttributes | 707 | int iAttributes |
@@ -850,9 +709,6 @@ static HRESULT RemoveGroupInternal( | |||
850 | { | 709 | { |
851 | HRESULT hr = S_OK; | 710 | HRESULT hr = S_OK; |
852 | 711 | ||
853 | LPWSTR pwz = NULL; | ||
854 | LPWSTR pwzGroup = NULL; | ||
855 | LPWSTR pwzGroupDomain = NULL; | ||
856 | LPWSTR pwzServerName = NULL; | 712 | LPWSTR pwzServerName = NULL; |
857 | 713 | ||
858 | // | 714 | // |
@@ -871,41 +727,9 @@ static HRESULT RemoveGroupInternal( | |||
871 | } | 727 | } |
872 | ExitOnFailure(hr, "failed to delete group: %ls", wzName); | 728 | ExitOnFailure(hr, "failed to delete group: %ls", wzName); |
873 | } | 729 | } |
874 | else | ||
875 | { | ||
876 | // | ||
877 | // Remove the group from other groups | ||
878 | // | ||
879 | pwz = wzGroupCaData; | ||
880 | while (S_OK == (hr = WcaReadStringFromCaData(&pwz, &pwzGroup))) | ||
881 | { | ||
882 | hr = WcaReadStringFromCaData(&pwz, &pwzGroupDomain); | ||
883 | 730 | ||
884 | if (FAILED(hr)) | ||
885 | { | ||
886 | WcaLogError(hr, "failed to get domain for group: %ls, continuing anyway.", pwzGroup); | ||
887 | } | ||
888 | else | ||
889 | { | ||
890 | hr = RemoveGroupFromGroup(wzName, wzDomain, pwzGroup, pwzGroupDomain); | ||
891 | if (FAILED(hr)) | ||
892 | { | ||
893 | WcaLogError(hr, "failed to remove group: %ls from group %ls, continuing anyway.", wzName, pwzGroup); | ||
894 | } | ||
895 | } | ||
896 | } | ||
897 | |||
898 | if (E_NOMOREITEMS == hr) // if there are no more items, all is well | ||
899 | { | ||
900 | hr = S_OK; | ||
901 | } | ||
902 | |||
903 | ExitOnFailure(hr, "failed to get next group from which to remove group:%ls", wzName); | ||
904 | } | ||
905 | LExit: | 731 | LExit: |
906 | ReleaseStr(pwzServerName); | 732 | ReleaseStr(pwzServerName); |
907 | ReleaseStr(pwzGroup); | ||
908 | ReleaseStr(pwzGroupDomain); | ||
909 | 733 | ||
910 | return hr; | 734 | return hr; |
911 | } | 735 | } |
@@ -1392,6 +1216,7 @@ LExit: | |||
1392 | return WcaFinalize(er); | 1216 | return WcaFinalize(er); |
1393 | } | 1217 | } |
1394 | 1218 | ||
1219 | |||
1395 | /******************************************************************** | 1220 | /******************************************************************** |
1396 | CreateGroup - CUSTOM ACTION ENTRY POINT for creating groups | 1221 | CreateGroup - CUSTOM ACTION ENTRY POINT for creating groups |
1397 | 1222 | ||
@@ -1412,8 +1237,6 @@ extern "C" UINT __stdcall CreateGroup( | |||
1412 | LPWSTR pwzDomain = NULL; | 1237 | LPWSTR pwzDomain = NULL; |
1413 | LPWSTR pwzComment = NULL; | 1238 | LPWSTR pwzComment = NULL; |
1414 | LPWSTR pwzScriptKey = NULL; | 1239 | LPWSTR pwzScriptKey = NULL; |
1415 | LPWSTR pwzGroup = NULL; | ||
1416 | LPWSTR pwzGroupDomain = NULL; | ||
1417 | int iAttributes = 0; | 1240 | int iAttributes = 0; |
1418 | BOOL fInitializedCom = FALSE; | 1241 | BOOL fInitializedCom = FALSE; |
1419 | 1242 | ||
@@ -1553,24 +1376,6 @@ extern "C" UINT __stdcall CreateGroup( | |||
1553 | } | 1376 | } |
1554 | } | 1377 | } |
1555 | MessageExitOnFailure(hr, msierrGRPFailedGroupCreate, "failed to create group: %ls", pwzName); | 1378 | MessageExitOnFailure(hr, msierrGRPFailedGroupCreate, "failed to create group: %ls", pwzName); |
1556 | |||
1557 | // | ||
1558 | // Add the groups to groups | ||
1559 | // | ||
1560 | while (S_OK == (hr = WcaReadStringFromCaData(&pwz, &pwzGroup))) | ||
1561 | { | ||
1562 | hr = WcaReadStringFromCaData(&pwz, &pwzGroupDomain); | ||
1563 | ExitOnFailure(hr, "failed to get domain for group: %ls", pwzGroup); | ||
1564 | |||
1565 | WcaLog(LOGMSG_STANDARD, "Adding group %ls\\%ls to group %ls\\%ls", pwzDomain, pwzName, pwzGroupDomain, pwzGroup); | ||
1566 | hr = AddGroupToGroup(pwzName, pwzDomain, pwzGroup, pwzGroupDomain); | ||
1567 | MessageExitOnFailure(hr, msierrUSRFailedUserGroupAdd, "failed to add group: %ls to group %ls", pwzName, pwzGroup); | ||
1568 | } | ||
1569 | if (E_NOMOREITEMS == hr) // if there are no more items, all is well | ||
1570 | { | ||
1571 | hr = S_OK; | ||
1572 | } | ||
1573 | ExitOnFailure(hr, "failed to get next group in which to include group: %ls", pwzName); | ||
1574 | } | 1379 | } |
1575 | 1380 | ||
1576 | LExit: | 1381 | LExit: |
@@ -1586,8 +1391,6 @@ LExit: | |||
1586 | ReleaseStr(pwzDomain); | 1391 | ReleaseStr(pwzDomain); |
1587 | ReleaseStr(pwzComment); | 1392 | ReleaseStr(pwzComment); |
1588 | ReleaseStr(pwzScriptKey); | 1393 | ReleaseStr(pwzScriptKey); |
1589 | ReleaseStr(pwzGroup); | ||
1590 | ReleaseStr(pwzGroupDomain); | ||
1591 | 1394 | ||
1592 | if (fInitializedCom) | 1395 | if (fInitializedCom) |
1593 | { | 1396 | { |
@@ -1704,7 +1507,7 @@ extern "C" UINT __stdcall CreateGroupRollback( | |||
1704 | } | 1507 | } |
1705 | } | 1508 | } |
1706 | 1509 | ||
1707 | hr = RemoveGroupInternal(pwz, pwzDomain, pwzName, iAttributes); | 1510 | hr = RemoveGroupInternal(pwzDomain, pwzName, iAttributes); |
1708 | 1511 | ||
1709 | LExit: | 1512 | LExit: |
1710 | WcaCaScriptClose(hRollbackScript, WCA_CASCRIPT_CLOSE_DELETE); | 1513 | WcaCaScriptClose(hRollbackScript, WCA_CASCRIPT_CLOSE_DELETE); |
@@ -1781,7 +1584,7 @@ extern "C" UINT __stdcall RemoveGroup( | |||
1781 | hr = WcaReadIntegerFromCaData(&pwz, &iAttributes); | 1584 | hr = WcaReadIntegerFromCaData(&pwz, &iAttributes); |
1782 | ExitOnFailure(hr, "failed to read attributes from custom action data"); | 1585 | ExitOnFailure(hr, "failed to read attributes from custom action data"); |
1783 | 1586 | ||
1784 | hr = RemoveGroupInternal(pwz, pwzDomain, pwzName, iAttributes); | 1587 | hr = RemoveGroupInternal(pwzDomain, pwzName, iAttributes); |
1785 | 1588 | ||
1786 | LExit: | 1589 | LExit: |
1787 | ReleaseStr(pwzData); | 1590 | ReleaseStr(pwzData); |
@@ -1801,3 +1604,254 @@ LExit: | |||
1801 | 1604 | ||
1802 | return WcaFinalize(er); | 1605 | return WcaFinalize(er); |
1803 | } | 1606 | } |
1607 | |||
1608 | HRESULT AlterGroupMembership(bool remove, bool isRollback = false) | ||
1609 | { | ||
1610 | HRESULT hr = S_OK; | ||
1611 | NET_API_STATUS er = ERROR_SUCCESS; | ||
1612 | |||
1613 | LPWSTR pwzData = NULL; | ||
1614 | LPWSTR pwz = NULL; | ||
1615 | LPWSTR pwzParentName = NULL; | ||
1616 | LPWSTR pwzParentDomain = NULL; | ||
1617 | LPWSTR pwzChildName = NULL; | ||
1618 | LPWSTR pwzChildDomain = NULL; | ||
1619 | int iAttributes = 0; | ||
1620 | LPWSTR pwzChildFullName = NULL; | ||
1621 | LPWSTR pwzServerName = NULL; | ||
1622 | LOCALGROUP_MEMBERS_INFO_3 memberInfo3 = {}; | ||
1623 | WCA_CASCRIPT_HANDLE phRollbackScript = NULL; | ||
1624 | |||
1625 | if (isRollback) | ||
1626 | { | ||
1627 | // Get a CaScript key | ||
1628 | hr = WcaCaScriptOpen(WCA_ACTION_NONE, WCA_CASCRIPT_ROLLBACK, FALSE, remove ? L"AddGroupMembershipRollback" : L"RemoveGroupMembershipRollback", &phRollbackScript); | ||
1629 | hr = WcaCaScriptReadAsCustomActionData(phRollbackScript, &pwzData); | ||
1630 | } | ||
1631 | else | ||
1632 | { | ||
1633 | hr = WcaCaScriptCreate(WCA_ACTION_NONE, WCA_CASCRIPT_ROLLBACK, FALSE, remove ? L"RemoveGroupMembershipRollback" : L"AddGroupMembershipRollback", TRUE, &phRollbackScript); | ||
1634 | hr = WcaGetProperty(L"CustomActionData", &pwzData); | ||
1635 | } | ||
1636 | ExitOnFailure(hr, "failed to get CustomActionData"); | ||
1637 | |||
1638 | WcaLog(LOGMSG_TRACEONLY, "CustomActionData: %ls", pwzData); | ||
1639 | |||
1640 | // | ||
1641 | // Read in the CustomActionData | ||
1642 | // | ||
1643 | pwz = pwzData; | ||
1644 | hr = WcaReadStringFromCaData(&pwz, &pwzParentName); | ||
1645 | ExitOnFailure(hr, "failed to read group name from custom action data"); | ||
1646 | |||
1647 | hr = WcaReadStringFromCaData(&pwz, &pwzParentDomain); | ||
1648 | ExitOnFailure(hr, "failed to read domain from custom action data"); | ||
1649 | |||
1650 | hr = WcaReadStringFromCaData(&pwz, &pwzChildName); | ||
1651 | ExitOnFailure(hr, "failed to read group comment from custom action data"); | ||
1652 | |||
1653 | hr = WcaReadStringFromCaData(&pwz, &pwzChildDomain); | ||
1654 | ExitOnFailure(hr, "failed to read group comment from custom action data"); | ||
1655 | |||
1656 | hr = WcaReadIntegerFromCaData(&pwz, &iAttributes); | ||
1657 | ExitOnFailure(hr, "failed to read attributes from custom action data"); | ||
1658 | |||
1659 | hr = GetDomainServerName(pwzParentDomain, &pwzServerName, DS_WRITABLE_REQUIRED); | ||
1660 | ExitOnFailure(hr, "failed to contact domain server %ls", pwzParentDomain); | ||
1661 | |||
1662 | if (*pwzChildDomain) | ||
1663 | { | ||
1664 | StrAllocFormatted(&pwzChildFullName, L"%ls\\%ls", pwzChildDomain, pwzChildName); | ||
1665 | } | ||
1666 | else | ||
1667 | { | ||
1668 | StrAllocFormatted(&pwzChildFullName, L"%ls", pwzChildName); | ||
1669 | } | ||
1670 | memberInfo3.lgrmi3_domainandname = pwzChildFullName; | ||
1671 | |||
1672 | if (remove) | ||
1673 | { | ||
1674 | er = ::NetLocalGroupDelMembers(pwzServerName, pwzParentName, 3, (LPBYTE)&memberInfo3, 1); | ||
1675 | } | ||
1676 | else | ||
1677 | { | ||
1678 | er = ::NetLocalGroupAddMembers(pwzServerName, pwzParentName, 3, (LPBYTE)&memberInfo3, 1); | ||
1679 | } | ||
1680 | hr = HRESULT_FROM_WIN32(er); | ||
1681 | |||
1682 | if (S_OK == hr && !isRollback) | ||
1683 | { | ||
1684 | // we need to log rollback data, we can just use exactly the same data we used to do the initial action though | ||
1685 | WcaCaScriptWriteString(phRollbackScript, pwzParentName); | ||
1686 | WcaCaScriptWriteString(phRollbackScript, pwzParentDomain); | ||
1687 | WcaCaScriptWriteString(phRollbackScript, pwzChildName); | ||
1688 | WcaCaScriptWriteString(phRollbackScript, pwzChildDomain); | ||
1689 | WcaCaScriptWriteNumber(phRollbackScript, iAttributes); | ||
1690 | WcaCaScriptFlush(phRollbackScript); | ||
1691 | WcaCaScriptClose(phRollbackScript, WCA_CASCRIPT_CLOSE_PRESERVE); | ||
1692 | } | ||
1693 | |||
1694 | if (remove) | ||
1695 | { | ||
1696 | if (HRESULT_FROM_WIN32(NERR_GroupNotFound) == hr | ||
1697 | || HRESULT_FROM_WIN32(ERROR_NO_SUCH_MEMBER) == hr | ||
1698 | || HRESULT_FROM_WIN32(ERROR_MEMBER_NOT_IN_ALIAS) == hr) | ||
1699 | { | ||
1700 | hr = S_OK; | ||
1701 | } | ||
1702 | } | ||
1703 | else | ||
1704 | { | ||
1705 | if (HRESULT_FROM_WIN32(ERROR_MEMBER_IN_ALIAS) == hr) | ||
1706 | { | ||
1707 | hr = S_OK; | ||
1708 | } | ||
1709 | } | ||
1710 | |||
1711 | LExit: | ||
1712 | ReleaseStr(pwzData); | ||
1713 | ReleaseStr(pwzParentName); | ||
1714 | ReleaseStr(pwzParentDomain); | ||
1715 | ReleaseStr(pwzChildName); | ||
1716 | ReleaseStr(pwzChildDomain); | ||
1717 | ReleaseStr(pwzChildFullName); | ||
1718 | ReleaseStr(pwzServerName); | ||
1719 | |||
1720 | if (SCAG_NON_VITAL & iAttributes) | ||
1721 | { | ||
1722 | return S_OK; | ||
1723 | } | ||
1724 | return hr; | ||
1725 | } | ||
1726 | |||
1727 | /******************************************************************** | ||
1728 | AddGroupmembership - CUSTOM ACTION ENTRY POINT for creating groups | ||
1729 | |||
1730 | Input: deferred CustomActionData - | ||
1731 | ParentGroupName\tParentGroupDomain\tChildGroupName\tChildGroupDomain\tAttributes | ||
1732 | * *****************************************************************/ | ||
1733 | extern "C" UINT __stdcall AddGroupMembership( | ||
1734 | __in MSIHANDLE hInstall | ||
1735 | ) | ||
1736 | { | ||
1737 | //AssertSz(0, "Debug AddGroupMembership"); | ||
1738 | |||
1739 | HRESULT hr = S_OK; | ||
1740 | |||
1741 | BOOL fInitializedCom = FALSE; | ||
1742 | |||
1743 | hr = WcaInitialize(hInstall, "AddGroupMembership"); | ||
1744 | ExitOnFailure(hr, "failed to initialize"); | ||
1745 | |||
1746 | hr = ::CoInitialize(NULL); | ||
1747 | ExitOnFailure(hr, "failed to initialize COM"); | ||
1748 | fInitializedCom = TRUE; | ||
1749 | |||
1750 | hr = AlterGroupMembership(false, false); | ||
1751 | |||
1752 | LExit: | ||
1753 | if (fInitializedCom) | ||
1754 | { | ||
1755 | ::CoUninitialize(); | ||
1756 | } | ||
1757 | return WcaFinalize(FAILED(hr) ? ERROR_INSTALL_FAILED : ERROR_SUCCESS); | ||
1758 | } | ||
1759 | |||
1760 | /******************************************************************** | ||
1761 | AddGroupmembership - CUSTOM ACTION ENTRY POINT for creating groups | ||
1762 | |||
1763 | Input: deferred CustomActionData - | ||
1764 | ParentGroupName\tParentGroupDomain\tChildGroupName\tChildGroupDomain\tAttributes | ||
1765 | * *****************************************************************/ | ||
1766 | extern "C" UINT __stdcall AddGroupMembershipRollback( | ||
1767 | __in MSIHANDLE hInstall | ||
1768 | ) | ||
1769 | { | ||
1770 | //AssertSz(0, "Debug AddGroupMembershipRollback"); | ||
1771 | |||
1772 | HRESULT hr = S_OK; | ||
1773 | |||
1774 | BOOL fInitializedCom = FALSE; | ||
1775 | |||
1776 | hr = WcaInitialize(hInstall, "AddGroupMembershipRollback"); | ||
1777 | ExitOnFailure(hr, "failed to initialize"); | ||
1778 | |||
1779 | hr = ::CoInitialize(NULL); | ||
1780 | ExitOnFailure(hr, "failed to initialize COM"); | ||
1781 | fInitializedCom = TRUE; | ||
1782 | |||
1783 | hr = AlterGroupMembership(true, true); | ||
1784 | |||
1785 | LExit: | ||
1786 | if (fInitializedCom) | ||
1787 | { | ||
1788 | ::CoUninitialize(); | ||
1789 | } | ||
1790 | return WcaFinalize(FAILED(hr) ? ERROR_INSTALL_FAILED : ERROR_SUCCESS); | ||
1791 | } | ||
1792 | |||
1793 | /******************************************************************** | ||
1794 | RemoveGroupMembership - CUSTOM ACTION ENTRY POINT for creating groups | ||
1795 | |||
1796 | Input: deferred CustomActionData - | ||
1797 | ParentGroupName\tParentGroupDomain\tChildGroupName\tChildGroupDomain\tAttributes | ||
1798 | * *****************************************************************/ | ||
1799 | extern "C" UINT __stdcall RemoveGroupMembership( | ||
1800 | __in MSIHANDLE hInstall | ||
1801 | ) | ||
1802 | { | ||
1803 | //AssertSz(0, "Debug RemoveGroupMembership"); | ||
1804 | |||
1805 | HRESULT hr = S_OK; | ||
1806 | |||
1807 | BOOL fInitializedCom = FALSE; | ||
1808 | |||
1809 | hr = WcaInitialize(hInstall, "RemoveGroupMembership"); | ||
1810 | ExitOnFailure(hr, "failed to initialize"); | ||
1811 | |||
1812 | hr = ::CoInitialize(NULL); | ||
1813 | ExitOnFailure(hr, "failed to initialize COM"); | ||
1814 | fInitializedCom = TRUE; | ||
1815 | |||
1816 | hr = AlterGroupMembership(true, false); | ||
1817 | |||
1818 | LExit: | ||
1819 | if (fInitializedCom) | ||
1820 | { | ||
1821 | ::CoUninitialize(); | ||
1822 | } | ||
1823 | return WcaFinalize(FAILED(hr) ? ERROR_INSTALL_FAILED : ERROR_SUCCESS); | ||
1824 | } | ||
1825 | |||
1826 | /******************************************************************** | ||
1827 | RemoveGroupMembershipRollback - CUSTOM ACTION ENTRY POINT for creating groups | ||
1828 | |||
1829 | Input: deferred CustomActionData - | ||
1830 | ParentGroupName\tParentGroupDomain\tChildGroupName\tChildGroupDomain\tAttributes | ||
1831 | * *****************************************************************/ | ||
1832 | extern "C" UINT __stdcall RemoveGroupMembershipRollback( | ||
1833 | __in MSIHANDLE hInstall | ||
1834 | ) | ||
1835 | { | ||
1836 | //AssertSz(0, "Debug RemoveGroupMembershipRollback"); | ||
1837 | |||
1838 | HRESULT hr = S_OK; | ||
1839 | |||
1840 | BOOL fInitializedCom = FALSE; | ||
1841 | |||
1842 | hr = WcaInitialize(hInstall, "RemoveGroupMembershipRollback"); | ||
1843 | ExitOnFailure(hr, "failed to initialize"); | ||
1844 | |||
1845 | hr = ::CoInitialize(NULL); | ||
1846 | ExitOnFailure(hr, "failed to initialize COM"); | ||
1847 | fInitializedCom = TRUE; | ||
1848 | |||
1849 | hr = AlterGroupMembership(false, true); | ||
1850 | |||
1851 | LExit: | ||
1852 | if (fInitializedCom) | ||
1853 | { | ||
1854 | ::CoUninitialize(); | ||
1855 | } | ||
1856 | return WcaFinalize(FAILED(hr) ? ERROR_INSTALL_FAILED : ERROR_SUCCESS); | ||
1857 | } | ||