private LSAPR_SID_ENUM_BUFFER Marshal_LSAPR_SID_ENUM_BUFFER(SecurityIdentifier[] SidEnumBuffer, List <GCHandle> HandleToFree) { LSAPR_SID_ENUM_BUFFER output = new LSAPR_SID_ENUM_BUFFER(); output.Entries = (UInt32)SidEnumBuffer.Length; IntPtr[] sidPtr = new IntPtr[SidEnumBuffer.Length]; for (int i = 0; i < SidEnumBuffer.Length; i++) { byte[] sid = new byte[SidEnumBuffer[i].BinaryLength]; SidEnumBuffer[i].GetBinaryForm(sid, 0); GCHandle handlesid = GCHandle.Alloc(sid, GCHandleType.Pinned); HandleToFree.Add(handlesid); sidPtr[i] = handlesid.AddrOfPinnedObject(); } GCHandle handle = GCHandle.Alloc(sidPtr, GCHandleType.Pinned); HandleToFree.Add(handle); output.SidInfo = handle.AddrOfPinnedObject(); return(output); }
public Int32 LsarLookupSids(IntPtr PolicyHandle, SecurityIdentifier[] SidEnumBuffer, out LSA_LOOKUP_RESULT[] LookupResult, UInt32 LookupLevel, out UInt32 MappedCount) { List <GCHandle> HandleToFree = new List <GCHandle>(); IntPtr result = IntPtr.Zero; LookupResult = null; MappedCount = 0; try { IntPtr IntPtrReferencedDomains = IntPtr.Zero; LSAPR_TRANSLATED_NAMES TranslatedNames = new LSAPR_TRANSLATED_NAMES(); GCHandle handleTranslatedNames = GCHandle.Alloc(TranslatedNames, GCHandleType.Pinned); // translatedNamesValuePointer points to a copy of TranslatedNames IntPtr IntPtrTranslatedNames = handleTranslatedNames.AddrOfPinnedObject(); HandleToFree.Add(handleTranslatedNames); LSAPR_SID_ENUM_BUFFER enumBuffer = Marshal_LSAPR_SID_ENUM_BUFFER(SidEnumBuffer, HandleToFree); if (IntPtr.Size == 8) { result = NativeMethods.NdrClientCall2x64(GetStubHandle(), GetProcStringHandle(522), PolicyHandle, enumBuffer, out IntPtrReferencedDomains, IntPtrTranslatedNames, LookupLevel, out MappedCount); } else { GCHandle handle1 = GCHandle.Alloc(enumBuffer, GCHandleType.Pinned); IntPtr tempValuePointer1 = handle1.AddrOfPinnedObject(); IntPtr tempValue2 = IntPtr.Zero; GCHandle handle2 = GCHandle.Alloc(tempValue2, GCHandleType.Pinned); IntPtr tempValuePointer2 = handle2.AddrOfPinnedObject(); IntPtr tempValue4 = IntPtr.Zero; GCHandle handle4 = GCHandle.Alloc(tempValue4, GCHandleType.Pinned); IntPtr tempValuePointer4 = handle4.AddrOfPinnedObject(); try { result = CallNdrClientCall2x86(492, PolicyHandle, tempValuePointer1, tempValuePointer2, IntPtrTranslatedNames, new IntPtr(LookupLevel), tempValuePointer4); // each pinvoke work on a copy of the arguments (without an out specifier) // get back the data IntPtrReferencedDomains = Marshal.ReadIntPtr(tempValuePointer2); MappedCount = (UInt32)Marshal.ReadInt32(tempValuePointer4); } finally { handle1.Free(); handle2.Free(); handle4.Free(); } } if (result == IntPtr.Zero || result == new IntPtr(0x00000107)) { LookupResult = Marshal_LsarLookupSids_Output(IntPtrReferencedDomains, IntPtrTranslatedNames); } } catch (SEHException) { Trace.WriteLine("LsarLookupSids failed 0x" + Marshal.GetExceptionCode().ToString("x")); return(Marshal.GetExceptionCode()); } finally { foreach (GCHandle handle in HandleToFree) { handle.Free(); } } return((int)result.ToInt64()); }