private LSA_LOOKUP_RESULT[] Marshal_LsarLookupSids_Output(IntPtr IntPtrReferencedDomains, IntPtr IntPtrTranslatedNames) { if (IntPtrReferencedDomains == IntPtr.Zero || IntPtrTranslatedNames == IntPtr.Zero) { return(null); } LSAPR_REFERENCED_DOMAIN_LIST ReferencedDomains = (LSAPR_REFERENCED_DOMAIN_LIST)Marshal.PtrToStructure(IntPtrReferencedDomains, typeof(LSAPR_REFERENCED_DOMAIN_LIST)); LSAPR_TRANSLATED_NAMES TranslatedNames = (LSAPR_TRANSLATED_NAMES)Marshal.PtrToStructure(IntPtrTranslatedNames, typeof(LSAPR_TRANSLATED_NAMES)); int SizeTranslatedName = Marshal.SizeOf(typeof(LSAPR_TRANSLATED_NAME)); int SizeTrustInformation = Marshal.SizeOf(typeof(LSAPR_TRUST_INFORMATION)); string[] referencedDomainsString = new string[ReferencedDomains.Entries]; SecurityIdentifier[] referencedDomainsSid = new SecurityIdentifier[ReferencedDomains.Entries]; for (UInt32 i = 0; i < ReferencedDomains.Entries; i++) { LSAPR_TRUST_INFORMATION trustInformation = (LSAPR_TRUST_INFORMATION)Marshal.PtrToStructure(new IntPtr(ReferencedDomains.Domains.ToInt64() + SizeTrustInformation * i), typeof(LSAPR_TRUST_INFORMATION)); if (trustInformation.buffer != IntPtr.Zero) { referencedDomainsString[i] = Marshal.PtrToStringUni(trustInformation.buffer, trustInformation.Length / 2); } if (trustInformation.Sid != null) { referencedDomainsSid[i] = new SecurityIdentifier(trustInformation.Sid); } if (trustInformation.buffer != IntPtr.Zero && trustInformation.MaximumLength > 0) { FreeMemory(trustInformation.buffer); } if (trustInformation.Sid != IntPtr.Zero) { FreeMemory(trustInformation.Sid); } } LSA_LOOKUP_RESULT[] output = new LSA_LOOKUP_RESULT[TranslatedNames.Entries]; for (UInt32 i = 0; i < TranslatedNames.Entries; i++) { LSAPR_TRANSLATED_NAME translatedName = (LSAPR_TRANSLATED_NAME)Marshal.PtrToStructure(new IntPtr(TranslatedNames.Names.ToInt64() + SizeTranslatedName * i), typeof(LSAPR_TRANSLATED_NAME)); output[i] = new LSA_LOOKUP_RESULT(); if (translatedName.buffer != IntPtr.Zero) { output[i].TranslatedName = Marshal.PtrToStringUni(translatedName.buffer, translatedName.Length / 2); } output[i].Use = (SID_NAME_USE)translatedName.Use; output[i].DomainName = referencedDomainsString[translatedName.DomainIndex]; output[i].DomainSid = referencedDomainsSid[translatedName.DomainIndex]; if (translatedName.buffer != IntPtr.Zero && translatedName.MaximumLength > 0) { FreeMemory(translatedName.buffer); } } FreeMemory(ReferencedDomains.Domains); FreeMemory(TranslatedNames.Names); FreeMemory(IntPtrReferencedDomains); 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()); }