/// <summary> /// Update a local group with new property values. This method provides /// the actual implementation. /// </summary> /// <param name="group"> /// A <see cref="LocalGroup"/> object representing the group to be updated. /// </param> /// <param name="changed"> /// A LocalGroup object containing the desired changes. /// </param> /// <remarks> /// Currently, a group's description is the only changeable property. /// </remarks> private void UpdateGroup(LocalGroup group, LocalGroup changed) { // Only description may be changed if (group.Description == changed.Description) return; IntPtr aliasHandle = IntPtr.Zero; IntPtr buffer = IntPtr.Zero; if (group.SID == null) group = GetLocalGroup(group.Name); var sre = GetGroupSre(group.SID); UInt32 status; try { status = SamApi.SamOpenAlias(sre.domainHandle, Win32.MAXIMUM_ALLOWED, sre.RelativeId, out aliasHandle); ThrowOnFailure(status); ALIAS_ADM_COMMENT_INFORMATION info = new ALIAS_ADM_COMMENT_INFORMATION(); info.AdminComment = new UNICODE_STRING(changed.Description); buffer = Marshal.AllocHGlobal(Marshal.SizeOf(info)); Marshal.StructureToPtr(info, buffer, false); status = SamApi.SamSetInformationAlias(aliasHandle, ALIAS_INFORMATION_CLASS.AliasAdminCommentInformation, buffer); ThrowOnFailure(status); } finally { if (buffer != IntPtr.Zero) { ClrFacade.DestroyStructure<ALIAS_ADM_COMMENT_INFORMATION>(buffer); Marshal.FreeHGlobal(buffer); } if (aliasHandle != IntPtr.Zero) status = SamApi.SamCloseHandle(aliasHandle); } }
/// <summary> /// Create a new group in the specified domain. /// </summary> /// <param name="groupInfo"> /// A <see cref="LocalGroup"/> object containing information about the new group. /// </param> /// <param name="domainHandle">Handle to the domain in which to create the new group.</param> /// <returns> /// A LocalGroup object that represents the newly-created group. /// </returns> private LocalGroup CreateGroup(LocalGroup groupInfo, IntPtr domainHandle) { IntPtr aliasHandle = IntPtr.Zero; IntPtr buffer = IntPtr.Zero; UNICODE_STRING str = new UNICODE_STRING(); UInt32 status; try { UInt32 relativeId; str = new UNICODE_STRING(groupInfo.Name); buffer = Marshal.AllocHGlobal(Marshal.SizeOf(str)); Marshal.StructureToPtr(str, buffer, false); status = SamApi.SamCreateAliasInDomain(domainHandle, buffer, Win32.MAXIMUM_ALLOWED, out aliasHandle, out relativeId); ClrFacade.DestroyStructure<UNICODE_STRING>(buffer); Marshal.FreeHGlobal(buffer); buffer = IntPtr.Zero; ThrowOnFailure(status); if (!string.IsNullOrEmpty(groupInfo.Description)) { ALIAS_ADM_COMMENT_INFORMATION info = new ALIAS_ADM_COMMENT_INFORMATION(); info.AdminComment = new UNICODE_STRING(groupInfo.Description); buffer = Marshal.AllocHGlobal(Marshal.SizeOf(info)); Marshal.StructureToPtr(info, buffer, false); status = SamApi.SamSetInformationAlias(aliasHandle, ALIAS_INFORMATION_CLASS.AliasAdminCommentInformation, buffer); ClrFacade.DestroyStructure<ALIAS_ADM_COMMENT_INFORMATION>(buffer); Marshal.FreeHGlobal(buffer); buffer = IntPtr.Zero; ThrowOnFailure(status); } return MakeLocalGroupObject(new SamRidEnumeration { domainHandle = domainHandle, Name = groupInfo.Name, RelativeId = relativeId }, aliasHandle); } finally { if (buffer != IntPtr.Zero) Marshal.FreeHGlobal(buffer); if (aliasHandle != IntPtr.Zero) status = SamApi.SamCloseHandle(aliasHandle); } }