public static DsNameResultItem CrackNames(DsNameFormat formatOffered, DsNameFormat formatDesired, string name, string dnsDomainName = null, int referralLevel = 0) { IntPtr hds = IntPtr.Zero; try { int result = NativeMethods.DsBind(null, dnsDomainName, out hds); if (result != 0) { throw new DirectoryException("DsBind failed", new Win32Exception(result)); } DsNameResultItem nameResult = NativeMethods.CrackNames(hds, DsNameFlags.DS_NAME_FLAG_TRUST_REFERRAL, formatOffered, formatDesired, name); switch (nameResult.Status) { case DsNameError.None: return(nameResult); case DsNameError.NoMapping: throw new NameMappingException($"The object name {name} was found in the global catalog, but could not be mapped to a DN. DsCrackNames returned NO_MAPPING"); case DsNameError.TrustReferral: case DsNameError.DomainOnly: if (!string.IsNullOrWhiteSpace(nameResult.Domain)) { if (referralLevel < NativeMethods.DirectoryReferralLimit) { return(NativeMethods.CrackNames(formatOffered, formatDesired, name, nameResult.Domain, ++referralLevel)); } throw new ReferralLimitExceededException("The referral limit exceeded the maximum configured value"); } throw new ReferralFailedException($"A referral to the object name {name} was received from the global catalog, but no referral information was provided. DsNameError: {nameResult.Status}"); case DsNameError.NotFound: throw new ObjectNotFoundException($"The object name {name} was not found in the global catalog"); case DsNameError.NotUnique: throw new AmbiguousNameException($"There was more than one object with the name {name} in the global catalog"); case DsNameError.Resolving: throw new NameMappingException($"The object name {name} was not able to be resolved in the global catalog. DsCrackNames returned RESOLVING"); case DsNameError.NoSyntacticalMapping: throw new NameMappingException($"DsCrackNames unexpectedly returned DS_NAME_ERROR_NO_SYNTACTICAL_MAPPING for name {name}"); default: throw new NameMappingException($"An unexpected status was returned from DsCrackNames {nameResult.Status}"); } } finally { if (hds != IntPtr.Zero) { NativeMethods.DsUnBind(hds); } } }
private static DsNameResultItem[] CrackNames(IntPtr hds, DsNameFlags flags, DsNameFormat formatOffered, DsNameFormat formatDesired, string[] namesToCrack) { IntPtr pDsNameResult = IntPtr.Zero; DsNameResultItem[] resultItems; try { uint namesToCrackCount = (uint)namesToCrack.Length; int result = NativeMethods.DsCrackNames(hds, flags, formatOffered, formatDesired, namesToCrackCount, namesToCrack, out pDsNameResult); if (result != 0) { throw new DirectoryException("DsCrackNames failed", new Win32Exception(result)); } DsNameResult dsNameResult = (DsNameResult)Marshal.PtrToStructure(pDsNameResult, typeof(DsNameResult)); if (dsNameResult.cItems == 0) { throw new DirectoryException("DsCrackNames returned an unexpected result"); } resultItems = new DsNameResultItem[dsNameResult.cItems]; IntPtr pItem = dsNameResult.rItems; for (int idx = 0; idx < dsNameResult.cItems; idx++) { resultItems[idx] = (DsNameResultItem)Marshal.PtrToStructure(pItem, typeof(DsNameResultItem)); pItem = IntPtr.Add(pItem, Marshal.SizeOf(resultItems[idx])); } } finally { if (pDsNameResult != IntPtr.Zero) { NativeMethods.DsFreeNameResult(pDsNameResult); } } return(resultItems); }