using System;
using System.Runtime.InteropServices;
using System.Linq;
using Vanara.InteropServices;
using static Vanara.PInvoke.AdvApi32;
using static Vanara.PInvoke.Ws2_32;
namespace Vanara.PInvoke
{
public static partial class NetApi32
{
/// Enumeration supporting .
[PInvokeData("DsGetDC.h", MSDNShortId = "ms675912")]
public enum DomainControllerAddressType
{
/// The address is a string IP address (for example, "\\157.55.94.74") of the domain controller.
DS_INET_ADDRESS = 1,
/// The address is a NetBIOS name, for example, "\\phoenix", of the domain controller.
DS_NETBIOS_ADDRESS = 2
}
/// Enumeration supporting .
[Flags]
[PInvokeData("DsGetDC.h", MSDNShortId = "ms675912")]
public enum DomainControllerType : uint
{
/// The domain controller is PDC of Domain.
DS_PDC_FLAG = 0x00000001,
/// The domain controller is a GC of forest.
DS_GC_FLAG = 0x00000004,
/// Server supports an LDAP server.
DS_LDAP_FLAG = 0x00000008,
/// The domain controller supports a DS and is a Domain Controller.
DS_DS_FLAG = 0x00000010,
/// The domain controller is running KDC service.
DS_KDC_FLAG = 0x00000020,
/// The domain controller is running time service.
DS_TIMESERV_FLAG = 0x00000040,
/// The domain controller is in closest site to client.
DS_CLOSEST_FLAG = 0x00000080,
/// The domain controller has a writable DS.
DS_WRITABLE_FLAG = 0x00000100,
/// The domain controller is running time service (and has clock hardware).
DS_GOOD_TIMESERV_FLAG = 0x00000200,
/// DomainName is non-domain NC serviced by the LDAP server.
DS_NDNC_FLAG = 0x00000400,
/// The domain controller has some secrets.
DS_SELECT_SECRET_DOMAIN_6_FLAG = 0x00000800,
/// The domain controller has all secrets.
DS_FULL_SECRET_DOMAIN_6_FLAG = 0x00001000,
/// The domain controller is running web service.
DS_WS_FLAG = 0x00002000,
/// The domain controller is running Win8 or later.
DS_DS_8_FLAG = 0x00004000,
/// The domain controller is running Win8.1 or later.
DS_DS_9_FLAG = 0x00008000,
/// The domain controller is running WinThreshold or later.
DS_DS_10_FLAG = 0x00010000,
/// Flags returned on ping.
DS_PING_FLAGS = 0x000FFFFF,
/// The DomainControllerName is a DNS name.
DS_DNS_CONTROLLER_FLAG = 0x20000000,
/// The DomainName is a DNS name.
DS_DNS_DOMAIN_FLAG = 0x40000000,
/// The DnsForestName is a DNS name.
DS_DNS_FOREST_FLAG = 0x80000000,
}
///
/// A set of flags that specify more data about the domain trust. This can be zero or a combination of one or more of the following values.
///
[PInvokeData("dsgetdc.h", MSDNShortId = "cd260fd1-dc38-4405-95ba-097a23faf668")]
public enum DomainTrustFlag
{
///
/// The domain represented by this structure is a member of the same forest as the server specified in the ServerName parameter
/// of the DsEnumerateDomainTrusts function.
///
DS_DOMAIN_IN_FOREST = 0x0001,
///
/// The domain represented by this structure is directly trusted by the domain that the server specified in the ServerName
/// parameter of the DsEnumerateDomainTrusts function is a member of.
///
DS_DOMAIN_DIRECT_OUTBOUND = 0x0002,
///
/// The domain represented by this structure is the root of a tree and a member of the same forest as the server specified in the
/// ServerName parameter of the DsEnumerateDomainTrusts function.
///
DS_DOMAIN_TREE_ROOT = 0x0004,
///
/// The domain represented by this structure is the primary domain of the server specified in the ServerName parameter of the
/// DsEnumerateDomainTrusts function.
///
DS_DOMAIN_PRIMARY = 0x0008,
/// The domain represented by this structure is running in the Windows 2000 native mode.
DS_DOMAIN_NATIVE_MODE = 0x0010,
///
/// The domain represented by this structure directly trusts the domain that the server specified in the ServerName parameter of
/// the DsEnumerateDomainTrusts function is a member of.
///
DS_DOMAIN_DIRECT_INBOUND = 0x0020,
}
/// Flags supporting behavior of .
[Flags]
[PInvokeData("DsGetDC.h", MSDNShortId = "ms675983")]
public enum DsGetDcNameFlags : uint
{
///
/// Forces cached domain controller data to be ignored. When the DS_FORCE_REDISCOVERY flag is not specified, DsGetDcName may
/// return cached domain controller data. If this flag is specified, DsGetDcName will not use cached information (if any exists)
/// but will instead perform a fresh domain controller discovery.
///
/// This flag should not be used under normal conditions, as using the cached domain controller information has better
/// performance characteristics and helps to ensure that the same domain controller is used consistently by all applications.
/// This flag should be used only after the application determines that the domain controller returned by DsGetDcName (when
/// called without this flag) is not accessible. In that case, the application should repeat the DsGetDcName call with this flag
/// to ensure that the unuseful cached information (if any) is ignored and a reachable domain controller is discovered.
///
///
DS_FORCE_REDISCOVERY = 0x1,
/// Requires that the returned domain controller support directory services.
DS_DIRECTORY_SERVICE_REQUIRED = 0x10,
///
/// DsGetDcName attempts to find a domain controller that supports directory service functions. If a domain controller that
/// supports directory services is not available, DsGetDcName returns the name of a non-directory service domain controller.
/// However, DsGetDcName only returns a non-directory service domain controller after the attempt to find a directory service
/// domain controller times out.
///
DS_DIRECTORY_SERVICE_PREFERRED = 0x20,
///
/// Requires that the returned domain controller be a global catalog server for the forest of domains with this domain as the
/// root. If this flag is set and the DomainName parameter is not NULL, DomainName must specify a forest name. This flag cannot
/// be combined with the DS_PDC_REQUIRED or DS_KDC_REQUIRED flags.
///
DS_GC_SERVER_REQUIRED = 0x40,
///
/// Requires that the returned domain controller be the primary domain controller for the domain. This flag cannot be combined
/// with the DS_KDC_REQUIRED or DS_GC_SERVER_REQUIRED flags.
///
DS_PDC_REQUIRED = 0x80,
///
/// If the DS_FORCE_REDISCOVERY flag is not specified, this function uses cached domain controller data. If the cached data is
/// more than 15 minutes old, the cache is refreshed by pinging the domain controller. If this flag is specified, this refresh is
/// avoided even if the cached data is expired. This flag should be used if the DsGetDcName function is called periodically.
///
DS_BACKGROUND_ONLY = 0x100,
///
/// This parameter indicates that the domain controller must have an IP address. In that case, DsGetDcName will place the
/// Internet protocol address of the domain controller in the DomainControllerAddress member of DomainControllerInfo.
///
DS_IP_REQUIRED = 0x200,
///
/// Requires that the returned domain controller be currently running the Kerberos Key Distribution Center service. This flag
/// cannot be combined with the DS_PDC_REQUIRED or DS_GC_SERVER_REQUIRED flags.
///
DS_KDC_REQUIRED = 0x400,
/// Requires that the returned domain controller be currently running the Windows Time Service.
DS_TIMESERV_REQUIRED = 0x800,
/// Requires that the returned domain controller be writable; that is, host a writable copy of the directory service.
DS_WRITABLE_REQUIRED = 0x1000,
///
/// DsGetDcName attempts to find a domain controller that is a reliable time server. The Windows Time Service can be configured
/// to declare one or more domain controllers as a reliable time server. For more information, see the Windows Time Service
/// documentation. This flag is intended to be used only by the Windows Time Service.
///
DS_GOOD_TIMESERV_PREFERRED = 0x2000,
///
/// When called from a domain controller, specifies that the returned domain controller name should not be the current computer.
/// If the current computer is not a domain controller, this flag is ignored. This flag can be used to obtain the name of another
/// domain controller in the domain.
///
DS_AVOID_SELF = 0x4000,
///
/// Specifies that the server returned is an LDAP server. The server returned is not necessarily a domain controller. No other
/// services are implied to be present at the server. The server returned does not necessarily have a writable config container
/// nor a writable schema container. The server returned may not necessarily be used to create or modify security principles.
/// This flag may be used with the DS_GC_SERVER_REQUIRED flag to return an LDAP server that also hosts a global catalog server.
/// The returned global catalog server is not necessarily a domain controller. No other services are implied to be present at the
/// server. If this flag is specified, the DS_PDC_REQUIRED, DS_TIMESERV_REQUIRED, DS_GOOD_TIMESERV_PREFERRED,
/// DS_DIRECTORY_SERVICES_PREFERED, DS_DIRECTORY_SERVICES_REQUIRED, and DS_KDC_REQUIRED flags are ignored.
///
DS_ONLY_LDAP_NEEDED = 0x8000,
///
/// Specifies that the DomainName parameter is a flat name. This flag cannot be combined with the DS_IS_DNS_NAME flag.
///
DS_IS_FLAT_NAME = 0x10000,
///
/// Specifies that the DomainName parameter is a DNS name. This flag cannot be combined with the DS_IS_FLAT_NAME flag.
///
/// Specify either DS_IS_DNS_NAME or DS_IS_FLAT_NAME. If neither flag is specified, DsGetDcName may take longer to find a domain
/// controller because it may have to search for both the DNS-style and flat name.
///
///
DS_IS_DNS_NAME = 0x20000,
///
/// When this flag is specified, DsGetDcName attempts to find a domain controller in the same site as the caller. If no such
/// domain controller is found, it will find a domain controller that can provide topology information and call DsBindToISTG to
/// obtain a bind handle, then call DsQuerySitesByCost over UDP to determine the "next closest site," and finally cache the name
/// of the site found. If no domain controller is found in that site, then DsGetDcName falls back on the default method of
/// locating a domain controller.
///
/// If this flag is used in conjunction with a non-NULL value in the input parameter SiteName, then ERROR_INVALID_FLAGS is thrown.
///
///
/// Also, the kind of search employed with DS_TRY_NEXT_CLOSEST_SITE is site-specific, so this flag is ignored if it is used in
/// conjunction with DS_PDC_REQUIRED. Finally, DS_TRY_NEXTCLOSEST_SITE is ignored when used in conjunction with
/// DS_RETURN_FLAT_NAME because that uses NetBIOS to resolve the name, but the domain of the domain controller found won't
/// necessarily match the domain to which the client is joined.
///
/// Note This flag is Group Policy enabled. If you enable the "Next Closest Site" policy setting, Next Closest Site DC
/// Location will be turned on for the machine across all available but un-configured network adapters. If you disable the policy
/// setting, Next Closest Site DC Location will not be used by default for the machine across all available but un-configured
/// network adapters. However, if a DC Locator call is made using the DS_TRY_NEXTCLOSEST_SITE flag explicitly, DsGetDcName honors
/// the Next Closest Site behavior. If you do not configure this policy setting, Next Closest Site DC Location will be not be
/// used by default for the machine across all available but un-configured network adapters. If the DS_TRY_NEXTCLOSEST_SITE flag
/// is used explicitly, the Next Closest Site behavior will be used.
///
DS_TRY_NEXTCLOSEST_SITE = 0x40000,
/// Requires that the returned domain controller be running Windows Server 2008 or later.
DS_DIRECTORY_SERVICE_6_REQUIRED = 0x80000,
/// Requires that the returned domain controller be currently running the Active Directory web service.
DS_WEB_SERVICE_REQUIRED = 0x100000,
/// Requires that the returned domain controller be running Windows Server 2012 or later.
DS_DIRECTORY_SERVICE_8_REQUIRED = 0x200000,
/// Requires that the returned domain controller be running Windows Server 2012 R2 or later.
DS_DIRECTORY_SERVICE_9_REQUIRED = 0x400000,
/// Requires that the returned domain controller be running Windows Server 2016 or later.
DS_DIRECTORY_SERVICE_10_REQUIRED = 0x800000,
///
/// Specifies that the names returned in the DomainControllerName and DomainName members of DomainControllerInfo should be DNS
/// names. If a DNS name is not available, an error is returned. This flag cannot be specified with the DS_RETURN_FLAT_NAME flag.
/// This flag implies the DS_IP_REQUIRED flag.
///
DS_RETURN_DNS_NAME = 0x40000000,
///
/// Specifies that the names returned in the DomainControllerName and DomainName members of DomainControllerInfo should be flat
/// names. If a flat name is not available, an error is returned. This flag cannot be specified with the DS_RETURN_DNS_NAME flag.
///
DS_RETURN_FLAT_NAME = 0x80000000,
}
/// Flags used by DsGetDcOpen.
[PInvokeData("dsgetdc.h", MSDNShortId = "2811cc30-f367-4f1a-8f0c-ed0a77dad24c")]
[Flags]
public enum DsGetDcOpenOptions
{
/// Only site-specific domain controllers are enumerated.
DS_ONLY_DO_SITE_NAME = 0x01,
///
/// The DsGetDcNext function will return the ERROR_FILEMARK_DETECTED value after all of the site-specific domain controllers are
/// retrieved. DsGetDcNext will then enumerate the second group, which contains all domain controllers in the domain, including
/// the site-specific domain controllers contained in the first group.
///
DS_NOTIFY_AFTER_SITE_RECORDS = 0x02,
}
/// Flags used by DsGetForestTrustInformationW.
[PInvokeData("dsgetdc.h", MSDNShortId = "c94fdc5b-920b-4807-9cbf-3172ec1c7386")]
[Flags]
public enum DsGetForestTrustInformationFlags
{
///
/// If this flag is set, DsGetForestTrustInformationW will update the forest trust data of the trusted domain identified by the
/// TrustedDomainNameparameter. In this case, the TrustedDomainName parameter cannot be NULL. The caller must have access to
/// modify the trust data or ERROR_ACCESS_DENIED is returned.
/// This flag is only valid if ServerName specifies the primary domain controller of the domain.
///
DS_GFTI_UPDATE_TDO = 1
}
/// The DsAddressToSiteNames function obtains the site names corresponding to the specified addresses.
///
/// Pointer to a null-terminated string that specifies the name of the remote server to process this function. This parameter must be
/// the name of a domain controller. A non-domain controller can call this function by calling DsGetDcName to find the domain controller.
///
/// Contains the number of elements in the SocketAddresses array.
///
/// Contains an array of SOCKET_ADDRESS structures that contain the addresses to convert. Each address in this array must be of the
/// type AF_INET. EntryCount contains the number of elements in this array.
///
///
/// Receives an array of null-terminated string pointers that contain the site names for the addresses. Each element in this array
/// corresponds to the same element in the SocketAddresses array. An element is NULL if the corresponding address does not map
/// to any known site or if the address entry is not of the proper form. The caller must free this array when it is no longer
/// required by calling NetApiBufferFree.
///
///
/// Returns NO_ERROR if successful or a Win32 or RPC error otherwise. The following list lists possible error codes.
///
// https://docs.microsoft.com/en-us/windows/desktop/api/dsgetdc/nf-dsgetdc-dsaddresstositenamesa DSGETDCAPI DWORD
// DsAddressToSiteNamesA( IN LPCSTR ComputerName, IN DWORD EntryCount, IN PSOCKET_ADDRESS SocketAddresses, OUT LPSTR **SiteNames );
[DllImport(Lib.NetApi32, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("dsgetdc.h", MSDNShortId = "4d70dbee-be33-4d2a-a200-3696443fa853")]
public static extern Win32Error DsAddressToSiteNames(string ComputerName, uint EntryCount, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] SOCKET_ADDRESS[] SocketAddresses, out SafeNetApiBuffer SiteNames);
/// The DsAddressToSiteNamesEx function obtains the site and subnet names corresponding to the addresses specified.
///
/// Pointer to a null-terminated string that specifies the name of the remote server to process this function. This parameter must be
/// the name of a domain controller. A non-domain controller can call this function by calling DsGetDcName to find the domain controller.
///
/// Contains the number of elements in the SocketAddresses array.
///
/// Contains an array of SOCKET_ADDRESS structures that contain the addresses to convert. Each address in this array must be of the
/// type AF_INET. EntryCount contains the number of elements in this array.
///
///
/// Receives an array of null-terminated string pointers that contain the site names for the addresses. Each element in this array
/// corresponds to the same element in the SocketAddresses array. An element is NULL if the corresponding address does not map
/// to any known site or if the address entry is not of the proper form. The caller must free this array when it is no longer
/// required by calling NetApiBufferFree.
///
///
/// Receives an array of null-terminated string pointers that contain the subnet names used to perform the address to site name
/// mappings. Each element in this array corresponds to the same element in the SocketAddresses array. An element is NULL if
/// the corresponding address to site name mapping was not determined or if no subnet was used to perform the corresponding address
/// to site mapping. The latter will be the case when there is exactly one site in the enterprise with no subnet objects mapped to
/// it. The caller must free this array when it is no longer required by calling NetApiBufferFree.
///
/// Returns NO_ERROR if successful or a Win32 or RPC error otherwise. The following are possible error codes.
// https://docs.microsoft.com/en-us/windows/desktop/api/dsgetdc/nf-dsgetdc-dsaddresstositenamesexw
// DSGETDCAPI DWORD DsAddressToSiteNamesExW( IN LPCWSTR ComputerName, IN DWORD EntryCount, IN PSOCKET_ADDRESS SocketAddresses, OUT LPWSTR **SiteNames, OUT LPWSTR **SubnetNames );
[DllImport(Lib.NetApi32, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("dsgetdc.h", MSDNShortId = "60ac6195-6e43-46da-a1e6-74ec989cd0c4")]
public static extern Win32Error DsAddressToSiteNamesEx(string ComputerName, uint EntryCount, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] SOCKET_ADDRESS[] SocketAddresses, out SafeNetApiBuffer SiteNames, out SafeNetApiBuffer SubnetNames);
///
///
/// The DsDeregisterDnsHostRecords function deletes DNS entries, except for type A records registered by a domain controller.
/// Only an administrator, account operator, or server operator may call this function.
///
///
///
///
/// The null-terminated string that specifies the name of the remote domain controller. Can be set to NULL if the calling
/// application is running on the domain controller being updated.
///
///
///
///
/// The null-terminated string that specifies the DNS domain name of the domain occupied by the domain controller. It is unnecessary
/// for this to be a domain hosted by this domain controller. If NULL, the DnsHostName with the leftmost label removed is specified.
///
///
///
/// Pointer to the Domain GUID of the domain. If NULL, GUID specific names are not removed.
///
///
///
/// Pointer to the GUID of the NTDS-DSA object to be deleted. If NULL, NTDS-DSA specific names are not removed.
///
///
///
///
/// Pointer to the null-terminated string that specifies the DNS host name of the domain controller whose DNS records are being deleted.
///
///
///
/// This function returns DSGETDCAPI DWORD.
///
///
///
/// This function deregisters SRV and CNAME records only. It leaves type A records intact. Deletion of site specific records, for
/// example, _ldap.tcp.<SiteName>._sites.dc._msdcs.<DnsDomainName>, is attempted for every site (<SiteName> in this
/// example) in the enterprise of the domain controller on which the function is executed. Therefore, this function call could create
/// a time-consuming run and may generate significant network traffic for enterprises with many sites.
///
///
// https://docs.microsoft.com/en-us/windows/desktop/api/dsgetdc/nf-dsgetdc-dsderegisterdnshostrecordsa DSGETDCAPI DWORD
// DsDeregisterDnsHostRecordsA( LPSTR ServerName, LPSTR DnsDomainName, GUID *DomainGuid, GUID *DsaGuid, LPSTR DnsHostName );
[DllImport(Lib.NetApi32, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("dsgetdc.h", MSDNShortId = "18ab6455-dab2-42d9-b68e-a8f0ad2d8091")]
public static extern Win32Error DsDeregisterDnsHostRecords([Optional] string ServerName, string DnsDomainName, in Guid DomainGuid, in Guid DsaGuid, string DnsHostName);
///
///
/// The DsDeregisterDnsHostRecords function deletes DNS entries, except for type A records registered by a domain controller.
/// Only an administrator, account operator, or server operator may call this function.
///
///
///
///
/// The null-terminated string that specifies the name of the remote domain controller. Can be set to NULL if the calling
/// application is running on the domain controller being updated.
///
///
///
///
/// The null-terminated string that specifies the DNS domain name of the domain occupied by the domain controller. It is unnecessary
/// for this to be a domain hosted by this domain controller. If NULL, the DnsHostName with the leftmost label removed is specified.
///
///
///
/// Pointer to the Domain GUID of the domain. If NULL, GUID specific names are not removed.
///
///
///
/// Pointer to the GUID of the NTDS-DSA object to be deleted. If NULL, NTDS-DSA specific names are not removed.
///
///
///
///
/// Pointer to the null-terminated string that specifies the DNS host name of the domain controller whose DNS records are being deleted.
///
///
///
/// This function returns DSGETDCAPI DWORD.
///
///
///
/// This function deregisters SRV and CNAME records only. It leaves type A records intact. Deletion of site specific records, for
/// example, _ldap.tcp.<SiteName>._sites.dc._msdcs.<DnsDomainName>, is attempted for every site (<SiteName> in this
/// example) in the enterprise of the domain controller on which the function is executed. Therefore, this function call could create
/// a time-consuming run and may generate significant network traffic for enterprises with many sites.
///
///
// https://docs.microsoft.com/en-us/windows/desktop/api/dsgetdc/nf-dsgetdc-dsderegisterdnshostrecordsa DSGETDCAPI DWORD
// DsDeregisterDnsHostRecordsA( LPSTR ServerName, LPSTR DnsDomainName, GUID *DomainGuid, GUID *DsaGuid, LPSTR DnsHostName );
[DllImport(Lib.NetApi32, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("dsgetdc.h", MSDNShortId = "18ab6455-dab2-42d9-b68e-a8f0ad2d8091")]
public static extern Win32Error DsDeregisterDnsHostRecords([Optional] string ServerName, string DnsDomainName, IntPtr DomainGuid, IntPtr DsaGuid, string DnsHostName);
/// The DsEnumerateDomainTrusts function obtains domain trust data for a specified domain.
///
/// Pointer to a null-terminated string that specifies the name of a computer in the domain to obtain the trust information for. If
/// this parameter is NULL, the name of the local computer is used. The caller must be an authenticated user in this domain.
///
///
/// If this computer is a domain controller, this function returns the trust data immediately. If this computer is not a domain
/// controller, this function obtains the trust data from cached data if the cached data is not expired. If the cached data is
/// expired, this function obtains the trust data from a domain controller in the domain that this computer is a member of and
/// updates the cache. The cached data automatically expires after five minutes.
///
///
/// Contains a set of flags that determines which domain trusts to enumerate. This can be zero or a combination of one or more of the
/// following values.
///
/// DS_DOMAIN_DIRECT_INBOUND
/// Enumerate domains that directly trust the domain which has ServerName as a member.
/// DS_DOMAIN_DIRECT_OUTBOUND
/// Enumerate domains directly trusted by the domain which has ServerName as a member.
/// DS_DOMAIN_IN_FOREST
/// Enumerate domains that are a member of the same forest which has ServerName as a member.
/// DS_DOMAIN_NATIVE_MODE
/// Enumerate domains where the primary domain is running in Windows 2000 native mode.
/// DS_DOMAIN_PRIMARY
/// Enumerate domains that are the primary domain of the domain which has ServerName as a member.
/// DS_DOMAIN_TREE_ROOT
/// Enumerate domains that are at the root of the forest which has ServerName as a member.
/// Pointer to a PDS_DOMAIN_TRUSTS value that receives an array of DS_DOMAIN_TRUSTS structures. Each structure in this array
/// contains trust data about a domain. The caller must free this memory when it is no longer required by calling NetApiBufferFree.
/// Pointer to a ULONG value that receives the number of elements returned in the Domains array.
///
/// Returns ERROR_SUCCESS if successful or a Win32 error code otherwise. Possible error codes include those listed in the
/// following list.
///
// https://docs.microsoft.com/en-us/windows/desktop/api/dsgetdc/nf-dsgetdc-dsenumeratedomaintrustsa DSGETDCAPI DWORD
// DsEnumerateDomainTrustsA( LPSTR ServerName, ULONG Flags, PDS_DOMAIN_TRUSTSA *Domains, PULONG DomainCount );
[DllImport(Lib.NetApi32, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("dsgetdc.h", MSDNShortId = "6c3b788f-ee53-4637-acdb-04316e8464fe")]
public static extern Win32Error DsEnumerateDomainTrusts([Optional] string ServerName, [Optional] DomainTrustFlag Flags, out SafeNetApiBuffer Domains, out uint DomainCount);
///
/// The DsGetDcClose function closes a domain controller enumeration operation.
///
///
/// Contains the domain controller enumeration context handle provided by the DsGetDcOpen function.
///
///
/// This function does not return a value.
///
///
/// When this function is called, GetDcContextHandle is invalid and cannot be used.
///
// https://docs.microsoft.com/en-us/windows/desktop/api/dsgetdc/nf-dsgetdc-dsgetdcclosew DSGETDCAPI VOID DsGetDcCloseW( IN HANDLE
// GetDcContextHandle );
[DllImport(Lib.NetApi32, SetLastError = false, EntryPoint = "DsGetDcCloseW")]
[PInvokeData("dsgetdc.h", MSDNShortId = "d193e4cd-ad66-4d93-b912-348f17e93a6f")]
public static extern void DsGetDcClose(HANDLE GetDcContextHandle);
///
/// The DsGetDcName function returns the name of a domain controller in a specified domain. This function accepts additional
/// domain controller selection criteria to indicate preference for a domain controller with particular characteristics.
///
///
/// Pointer to a null-terminated string that specifies the name of the server to process this function. Typically, this parameter is
/// NULL, which indicates that the local computer is used.
///
///
///
/// Pointer to a null-terminated string that specifies the name of the domain or application partition to query. This name can either
/// be a DNS style name, for example, fabrikam.com, or a flat-style name, for example, Fabrikam. If a DNS style name is specified,
/// the name may be specified with or without a trailing period.
///
///
/// If the Flags parameter contains the DS_GC_SERVER_REQUIRED flag, DomainName must be the name of the forest. In this case,
/// DsGetDcName fails if DomainName specifies a name that is not the forest root.
///
///
/// If the Flags parameter contains the DS_GC_SERVER_REQUIRED flag and DomainName is NULL, DsGetDcName attempts
/// to find a global catalog in the forest of the computer identified by ComputerName, which is the local computer if ComputerName is NULL.
///
///
/// If DomainName is NULL and the Flags parameter does not contain the DS_GC_SERVER_REQUIRED flag, ComputerName is set
/// to the default domain name of the primary domain of the computer identified by ComputerName.
///
///
///
/// Pointer to a GUID structure that specifies the GUID of the domain queried. If DomainGuid is not NULL and the domain
/// specified by DomainName or ComputerName cannot be found, DsGetDcName attempts to locate a domain controller in the domain
/// having the GUID specified by DomainGuid.
///
///
/// Pointer to a null-terminated string that specifies the name of the site where the returned domain controller should physically
/// exist. If this parameter is NULL, DsGetDcName attempts to return a domain controller in the site closest to the
/// site of the computer specified by ComputerName. This parameter should be NULL, by default.
///
///
///
/// Contains a set of flags that provide additional data used to process the request. This parameter can be a combination of the
/// following values.
///
/// DS_AVOID_SELF
///
/// When called from a domain controller, specifies that the returned domain controller name should not be the current computer. If
/// the current computer is not a domain controller, this flag is ignored. This flag can be used to obtain the name of another domain
/// controller in the domain.
///
/// DS_BACKGROUND_ONLY
///
/// If the DS_FORCE_REDISCOVERY flag is not specified, this function uses cached domain controller data. If the cached data is
/// more than 15 minutes old, the cache is refreshed by pinging the domain controller. If this flag is specified, this refresh is
/// avoided even if the cached data is expired. This flag should be used if the DsGetDcName function is called periodically.
///
/// DS_DIRECTORY_SERVICE_PREFERRED
///
/// DsGetDcName attempts to find a domain controller that supports directory service functions. If a domain controller that
/// supports directory services is not available, DsGetDcName returns the name of a non-directory service domain controller.
/// However, DsGetDcName only returns a non-directory service domain controller after the attempt to find a directory service
/// domain controller times out.
///
/// DS_DIRECTORY_SERVICE_REQUIRED
/// Requires that the returned domain controller support directory services.
/// DS_DIRECTORY_SERVICE_6_REQUIRED
/// Requires that the returned domain controller be running Windows Server 2008 or later.
/// DS_DIRECTORY_SERVICE_8_REQUIRED
/// Requires that the returned domain controller be running Windows Server 2012 or later.
/// DS_FORCE_REDISCOVERY
///
/// Forces cached domain controller data to be ignored. When the DS_FORCE_REDISCOVERY flag is not specified,
/// DsGetDcName may return cached domain controller data. If this flag is specified, DsGetDcName will not use cached
/// information (if any exists) but will instead perform a fresh domain controller discovery.
///
///
/// This flag should not be used under normal conditions, as using the cached domain controller information has better performance
/// characteristics and helps to ensure that the same domain controller is used consistently by all applications. This flag should be
/// used only after the application determines that the domain controller returned by DsGetDcName (when called without this
/// flag) is not accessible. In that case, the application should repeat the DsGetDcName call with this flag to ensure that
/// the unuseful cached information (if any) is ignored and a reachable domain controller is discovered.
///
/// DS_GC_SERVER_REQUIRED
///
/// Requires that the returned domain controller be a global catalog server for the forest of domains with this domain as the root.
/// If this flag is set and the DomainName parameter is not NULL, DomainName must specify a forest name. This flag cannot be
/// combined with the DS_PDC_REQUIRED or DS_KDC_REQUIRED flags.
///
/// DS_GOOD_TIMESERV_PREFERRED
///
/// DsGetDcName attempts to find a domain controller that is a reliable time server. The Windows Time Service can be
/// configured to declare one or more domain controllers as a reliable time server. For more information, see the Windows Time
/// Service documentation. This flag is intended to be used only by the Windows Time Service.
///
/// DS_IP_REQUIRED
///
/// This parameter indicates that the domain controller must have an IP address. In that case, DsGetDcName will place the
/// Internet protocol address of the domain controller in the DomainControllerAddress member of DomainControllerInfo.
///
/// DS_IS_DNS_NAME
/// Specifies that the DomainName parameter is a DNS name. This flag cannot be combined with the DS_IS_FLAT_NAME flag.
///
/// Specify either DS_IS_DNS_NAME or DS_IS_FLAT_NAME. If neither flag is specified, DsGetDcName may take longer
/// to find a domain controller because it may have to search for both the DNS-style and flat name.
///
/// DS_IS_FLAT_NAME
/// Specifies that the DomainName parameter is a flat name. This flag cannot be combined with the DS_IS_DNS_NAME flag.
/// DS_KDC_REQUIRED
///
/// Requires that the returned domain controller be currently running the Kerberos Key Distribution Center service. This flag cannot
/// be combined with the DS_PDC_REQUIRED or DS_GC_SERVER_REQUIRED flags.
///
/// DS_ONLY_LDAP_NEEDED
///
/// Specifies that the server returned is an LDAP server. The server returned is not necessarily a domain controller. No other
/// services are implied to be present at the server. The server returned does not necessarily have a writable config
/// container nor a writable schema container. The server returned may not necessarily be used to create or modify security
/// principles. This flag may be used with the DS_GC_SERVER_REQUIRED flag to return an LDAP server that also hosts a global
/// catalog server. The returned global catalog server is not necessarily a domain controller. No other services are implied to be
/// present at the server. If this flag is specified, the DS_PDC_REQUIRED, DS_TIMESERV_REQUIRED,
/// DS_GOOD_TIMESERV_PREFERRED, DS_DIRECTORY_SERVICES_PREFERED, DS_DIRECTORY_SERVICES_REQUIRED, and
/// DS_KDC_REQUIRED flags are ignored.
///
/// DS_PDC_REQUIRED
///
/// Requires that the returned domain controller be the primary domain controller for the domain. This flag cannot be combined with
/// the DS_KDC_REQUIRED or DS_GC_SERVER_REQUIRED flags.
///
/// DS_RETURN_DNS_NAME
///
/// Specifies that the names returned in the DomainControllerName and DomainName members of DomainControllerInfo should
/// be DNS names. If a DNS name is not available, an error is returned. This flag cannot be specified with the
/// DS_RETURN_FLAT_NAME flag. This flag implies the DS_IP_REQUIRED flag.
///
/// DS_RETURN_FLAT_NAME
///
/// Specifies that the names returned in the DomainControllerName and DomainName members of DomainControllerInfo should
/// be flat names. If a flat name is not available, an error is returned. This flag cannot be specified with the
/// DS_RETURN_DNS_NAME flag.
///
/// DS_TIMESERV_REQUIRED
/// Requires that the returned domain controller be currently running the Windows Time Service.
/// DS_TRY_NEXTCLOSEST_SITE
///
/// When this flag is specified, DsGetDcName attempts to find a domain controller in the same site as the caller. If no such
/// domain controller is found, it will find a domain controller that can provide topology information and call DsBindToISTG to
/// obtain a bind handle, then call DsQuerySitesByCost over UDP to determine the "next closest site," and finally cache the name of
/// the site found. If no domain controller is found in that site, then DsGetDcName falls back on the default method of
/// locating a domain controller.
///
///
/// If this flag is used in conjunction with a non-NULL value in the input parameter SiteName, then ERROR_INVALID_FLAGS is thrown.
///
///
/// Also, the kind of search employed with DS_TRY_NEXT_CLOSEST_SITE is site-specific, so this flag is ignored if it is used in
/// conjunction with DS_PDC_REQUIRED. Finally, DS_TRY_NEXTCLOSEST_SITE is ignored when used in conjunction with
/// DS_RETURN_FLAT_NAME because that uses NetBIOS to resolve the name, but the domain of the domain controller found won't
/// necessarily match the domain to which the client is joined.
///
///
/// Note This flag is Group Policy enabled. If you enable the "Next Closest Site" policy setting, Next Closest Site DC
/// Location will be turned on for the machine across all available but un-configured network adapters. If you disable the policy
/// setting, Next Closest Site DC Location will not be used by default for the machine across all available but un-configured network
/// adapters. However, if a DC Locator call is made using the DS_TRY_NEXTCLOSEST_SITE flag explicitly, DsGetDcName
/// honors the Next Closest Site behavior. If you do not configure this policy setting, Next Closest Site DC Location will be not be
/// used by default for the machine across all available but un-configured network adapters. If the DS_TRY_NEXTCLOSEST_SITE
/// flag is used explicitly, the Next Closest Site behavior will be used.
///
/// DS_WRITABLE_REQUIRED
/// Requires that the returned domain controller be writable; that is, host a writable copy of the directory service.
/// DS_WEB_SERVICE_REQUIRED
/// Requires that the returned domain controller be currently running the Active Directory web service.
///
///
/// Pointer to a PDOMAIN_CONTROLLER_INFO value that receives a pointer to a DOMAIN_CONTROLLER_INFO structure that contains
/// data about the domain controller selected. This structure is allocated by DsGetDcName. The caller must free the structure
/// using the NetApiBufferFree function when it is no longer required.
///
///
/// If the function returns domain controller data, the return value is ERROR_SUCCESS.
/// If the function fails, the return value can be one of the following error codes.
///
///
///
/// The DsGetDcName function is sent to the Netlogon service on the remote computer specified by ComputerName. If ComputerName
/// is NULL, the function is processed on the local computer.
///
///
/// DsGetDcName does not verify that the domain controller name returned is the name of an actual domain controller or global
/// catalog. If mutual authentication is required, the caller must perform the authentication.
///
///
/// DsGetDcName does not require any particular access to the specified domain. By default, this function does not ensure that
/// the returned domain controller is currently available. Instead, the caller should attempt to use the returned domain controller.
/// If the domain controller is not available, the caller should call the DsGetDcName function again, specifying the
/// DS_FORCE_REDISCOVERY flag.
///
/// Response Time
/// When using DsGetDcName be aware of the following timing details:
///
/// -
///
/// DsGetDcName makes network calls and can take from a few seconds up to one minute, depending on network traffic, topology,
/// DC load, and so on.
///
///
/// -
/// It is NOT recommended to call DsGetDcName from a UI or other timing critical thread.
///
/// -
///
/// The DC Locator does use optimized logic to provide the DC information as quickly as possible. It also uses cached information at
/// the site to contact the closest DC.
///
///
///
/// Notes on Domain Controller Stickiness
///
/// In Active Directory Domain Services, the domain controller locator function is designed so that once a client finds a preferred
/// domain controller, the client will not look for another unless that domain controller stops responding or the client is
/// restarted. This is referred to as "Domain Controller Stickiness." Because workstations typically operate for months without a
/// problem or restart, one unintended consequence of this behavior is that if a particular domain controller goes down for
/// maintenance, all of the clients that were connected to it shift their connections to another domain controller. But when the
/// domain controller comes back up, no clients ever reconnect to it because the clients do not restart very often. This can cause
/// load-balancing problems.
///
///
/// Previously, the most common solution to this problem was to deploy a script on each client machine that periodically called
/// DsGetDcName using the flag. This was a somewhat cumbersome solution, so Windows Server 2008 and Windows Vista introduced a
/// new mechanism that caused issues with domain controller stickiness.
///
///
/// Whenever DsGetDcName retrieves a domain controller name from its cache, it checks to see if this cached entry is expired,
/// and if so, discards that domain controller name and tries to rediscover a domain controller name. The life span of a cached entry
/// is controlled by the value in the following registry keys
///
/// HKEY_LOCAL_MACHINE<b>SYSTEM<b>CurrentControlSet<b>Services<b>Netlogon<b>Parameters<b>ForceRediscoveryInterval
/// and
/// HKEY_LOCAL_MACHINE<b>Software<b>Policies<b>Microsoft<b>Netlogon<b>Parameters<b>ForceRediscoveryInterval
///
/// The values in these registry keys are of type REG_DWORD. They specify the length in seconds before DsGetDcName
/// should try to rediscover the domain controller name. The default value is 43200 seconds (12 hours). If the value of the
/// ForceRediscoveryInterval registry entry is set to 0, the client always performs rediscovery. If the value is set to
/// 4294967295, the cache never expires, and the cached domain controller continues to be used. We recommend that you do not set the
/// ForceRediscoveryInterval registry entry to a value that is less than 3600 seconds (60 minutes).
///
///
/// Note The registry settings of ForceRediscoveryInterval are group policy enabled. If you disable the policy setting,
/// Force Rediscovery will used by default for the machine at every 12 hour interval. If you do not configure this policy setting,
/// Force Rediscovery will used by default for the machine at every 12 hour interval, unless the local machine setting in the
/// registry is a different value.
///
///
/// Note that if the DS_BACKGROUND_ONLY flag is specified, DsGetDcName will never try to rediscover the domain
/// controller name, since the point of that flag is to force DsGetDcName to use the cached domain controller name even if it
/// is expired.
///
/// ETW Tracing in DsGetDcName
/// To turn on ETW Tracing for DsGetDcName, create the following registry key:
/// HKEY_LOCAL_MACHINE<b>System<b>CurrentControlSet<b>Services<b>DCLocator<b>Tracing
/// The key will have a structure as follows:
///
/// ProcessName must be the full name including extension of the process that you want to get trace information for. PID is only
/// required when multiple processes with the same name exist. If it is defined, then only the process with that PID will be enabled
/// for tracing. It is not possible to trace only 2 out of 3 (or more) processes with the same name. You can enable one instance or
/// all instances (when multiple instances with the same process name exist and PID is not specified, all instances will be enabled
/// for tracing).
///
///
/// For example, this would trace all instances of App1.exe and App2.exe, but only the instance of App3.exe that has a PID of 999:
///
/// Run the following command to start the tracing session:
/// tracelog.exe -start <sessionname> -guid #cfaa5446-c6c4-4f5c-866f-31c9b55b962d -f <filename> -flag <traceFlags>
///
/// sessionname is the name given for the trace session. The guid for the DCLocator tracing provider is
/// "cfaa5446-c6c4-4f5c-866f-31c9b55b962d". filename is the name of the log file to which the events are written. traceFlags is one
/// or more of the following flags which signify which areas to trace:
///
///
///
/// Flag
/// Hex Value
/// Description
///
/// -
/// DCLOCATOR_MISC
/// 0x00000002
/// Miscellaneous debugging
///
/// -
/// DCLOCATOR_MAILSLOT
/// 0x00000010
/// Mailslot messages
///
/// -
/// DCLOCATOR_SITE
/// 0x00000020
/// Sites
///
/// -
/// DCLOCATOR_CRITICAL
/// 0x00000100
/// Important errors
///
/// -
/// DCLOCATOR_SESSION_SETUP
/// 0x00000200
/// Trusted Domain Maintenance
///
/// -
/// DCLOCATOR_DNS
/// 0x00004000
/// Name Registration
///
/// -
/// DCLOCATOR_DNS_MORE
/// 0x00020000
/// Verbose Name Registration
///
/// -
/// DCLOCATOR_MAILBOX_TEXT
/// 0x02000000
/// Verbose Mailbox Messages
///
/// -
/// DCLOCATOR_SITE_MORE
/// 0x08000000
/// Verbose sites
///
///
/// Run the following command to stop the trace session:
/// tracelog.exe -stop <sessionname>
/// sessionname is the same name as the name you used when starting the session.
///
/// Note The registry key for the process being traced must be present in the registry at the time the trace session is
/// started. When the session starts, the process will verify whether or not it should be generating trace messages (based on the
/// presence or absence of a registry key for that process name and optional PID). The process checks the registry only at the start
/// of the session. Any changes in the registry occurring after that will not have any effect on tracing.
///
///
// https://docs.microsoft.com/en-us/windows/desktop/api/dsgetdc/nf-dsgetdc-dsgetdcnamea
// DSGETDCAPI DWORD DsGetDcNameA( IN LPCSTR ComputerName, IN LPCSTR DomainName, IN GUID *DomainGuid, IN LPCSTR SiteName, IN ULONG Flags, OUT PDOMAIN_CONTROLLER_INFOA *DomainControllerInfo );
[DllImport(Lib.NetApi32, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("dsgetdc.h", MSDNShortId = "da8b2983-5e45-40b0-b552-c9b3a1d8ae94")]
public static extern Win32Error DsGetDcName([Optional] string ComputerName, [Optional] string DomainName, in Guid DomainGuid, [Optional] string SiteName, DsGetDcNameFlags Flags, out SafeNetApiBuffer DomainControllerInfo);
///
/// The DsGetDcName function returns the name of a domain controller in a specified domain. This function accepts additional domain
/// controller selection criteria to indicate preference for a domain controller with particular characteristics.
///
///
/// Pointer to a null-terminated string that specifies the name of the server to process this function. Typically, this parameter is
/// NULL, which indicates that the local computer is used.
///
///
/// Pointer to a null-terminated string that specifies the name of the domain or application partition to query. This name can either
/// be a DNS style name, for example, fabrikam.com, or a flat-style name, for example, Fabrikam. If a DNS style name is specified,
/// the name may be specified with or without a trailing period.
///
/// If the Flags parameter contains the DS_GC_SERVER_REQUIRED flag, DomainName must be the name of the forest. In this case,
/// DsGetDcName fails if DomainName specifies a name that is not the forest root.
///
///
/// If the Flags parameter contains the DS_GC_SERVER_REQUIRED flag and DomainName is NULL, DsGetDcName attempts to find a global
/// catalog in the forest of the computer identified by ComputerName, which is the local computer if ComputerName is NULL.
///
///
/// If DomainName is NULL and the Flags parameter does not contain the DS_GC_SERVER_REQUIRED flag, ComputerName is set to the default
/// domain name of the primary domain of the computer identified by ComputerName.
///
///
///
/// Pointer to a GUID structure that specifies the GUID of the domain queried. If DomainGuid is not NULL and the domain specified by
/// DomainName or ComputerName cannot be found, DsGetDcName attempts to locate a domain controller in the domain having the GUID
/// specified by DomainGuid.
///
///
/// Pointer to a null-terminated string that specifies the name of the site where the returned domain controller should physically
/// exist. If this parameter is NULL, DsGetDcName attempts to return a domain controller in the site closest to the site of the
/// computer specified by ComputerName. This parameter should be NULL, by default.
///
///
/// Contains a set of flags that provide additional data used to process the request. This parameter can be a combination of the
/// following values.
///
///
/// Pointer to a PDOMAIN_CONTROLLER_INFO value that receives a pointer to a DOMAIN_CONTROLLER_INFO structure that contains data about
/// the domain controller selected. This structure is allocated by DsGetDcName. The caller must free the structure using the
/// NetApiBufferFree function when it is no longer required.
///
///
/// If the function returns domain controller data, the return value is ERROR_SUCCESS.
/// If the function fails, the return value can be one of the following error codes.
///
[DllImport(Lib.NetApi32, CharSet = CharSet.Auto)]
[PInvokeData("DsGetDC.h", MSDNShortId = "ms675983")]
public static extern Win32Error DsGetDcName([Optional] string ComputerName, [Optional] string DomainName, [Optional] IntPtr DomainGuid, [Optional] string SiteName, DsGetDcNameFlags Flags, out SafeNetApiBuffer DomainControllerInfo);
///
/// The DsGetDcNext function retrieves the next domain controller in a domain controller enumeration operation.
///
///
/// Contains the domain controller enumeration context handle provided by the DsGetDcOpen function.
///
///
///
/// Pointer to a ULONG value that receives the number of elements in the SockAddresses array. If this parameter is
/// NULL, socket addresses are not retrieved.
///
///
///
///
/// Pointer to an array of SOCKET_ADDRESS structures that receives the socket address data for the domain controller.
/// SockAddressCount receives the number of elements in this array.
///
///
/// All returned addresses will be of type AF_INET or AF_INET6. The sin_port member contains the port from the
/// server record. A port of 0 indicates no port is available from DNS.
///
/// The caller must free this memory when it is no longer required by calling LocalFree.
/// This parameter is ignored if SockAddressCount is NULL.
///
///
///
/// Pointer to a string pointer that receives the DNS name of the domain controller. This parameter receives NULL if no host
/// name is known. The caller must free this memory when it is no longer required by calling NetApiBufferFree.
///
///
///
/// Returns ERROR_SUCCESS if successful or a Win32 or RPC error otherwise. Possible error values include the following.
///
///
///
/// To reset the enumeration, close the current enumeration by calling DsGetDcClose and then reopen the enumeration by calling
/// DsGetDcOpen again.
///
///
/// The DC returned by DsGetDcNext will not be a Read-only DC (RODC) because those DCs only register site-specific and CName
/// records, and both DsGetDcNext and DsGetDcOpen look for DNS SRV records.
///
/// The following procedure shows how to get a complete DC list from a computer running Windows Server 2008.
/// To obtain a complete list of domain controllers
///
/// -
/// Use DsGetDcName to get a domain controller name.
///
/// -
/// Use DsBind to connect to that domain controller.
///
/// -
///
/// Call DsGetDomainControllerInfo with InfoLevel 3 ( DS_DOMAIN_CONTROLLER_INFO_3) to get the complete list, including RODCs.
///
///
///
///
// https://docs.microsoft.com/en-us/windows/desktop/api/Dsgetdc/nf-dsgetdc-dsgetdcnexta DSGETDCAPI DWORD DsGetDcNextA( IN HANDLE
// GetDcContextHandle, OUT PULONG SockAddressCount, OUT LPSOCKET_ADDRESS *SockAddresses, OUT LPSTR *DnsHostName );
[DllImport(Lib.NetApi32, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("dsgetdc.h", MSDNShortId = "2906772f-4391-411b-b0a9-5a20ebb6c0ee")]
public static extern Win32Error DsGetDcNext(SafeDCEnumHandle GetDcContextHandle, out uint SockAddressCount, out SafeLocalHandle SockAddresses, out SafeNetApiBuffer DnsHostName);
///
/// The DsGetDcOpen function opens a new domain controller enumeration operation.
///
///
///
/// Pointer to a null-terminated string that contains the domain naming system (DNS) name of the domain to enumerate the domain
/// controllers for. This parameter cannot be NULL.
///
///
///
///
/// Contains a set of flags that modify the behavior of the function. This can be zero or a combination of one or more of the
/// following values.
///
/// DS_ONLY_DO_SITE_NAME
/// Only site-specific domain controllers are enumerated.
/// DS_NOTIFY_AFTER_SITE_RECORDS
///
/// The DsGetDcNext function will return the ERROR_FILEMARK_DETECTED value after all of the site-specific domain controllers
/// are retrieved. DsGetDcNext will then enumerate the second group, which contains all domain controllers in the domain,
/// including the site-specific domain controllers contained in the first group.
///
///
///
///
/// Pointer to a null-terminated string that contains the name of site the client is in. This parameter is optional and may be NULL.
///
///
///
///
/// Pointer to a GUID value that contains the identifier of the domain specified by DnsName. This identifier is used to handle
/// the case of a renamed domain. If this value is specified and the domain specified in DnsName is renamed, this function attempts
/// to enumerate domain controllers in the domain that contains the specified identifier. This parameter is optional and may be NULL.
///
///
///
///
/// Pointer to a null-terminated string that contains the name of the forest that contains the DnsName domain. This value is used in
/// conjunction with DomainGuidto enumerate the domain controllers if the domain has been renamed. This parameter is optional and may
/// be NULL.
///
///
///
///
/// Contains a set of flags that identify the type of domain controllers to enumerate. This can be zero or a combination of one or
/// more of the following values.
///
/// DS_FORCE_REDISCOVERY
///
/// Forces cached domain controller data to be ignored. When this flag is not specified, DsGetDcOpen obtains the domain
/// controller enumeration from cached domain controller data.
///
/// DS_GC_SERVER_REQUIRED
///
/// Requires that the enumerated domain controllers be global catalog servers for the forest of domains with this domain as the root.
/// This flag cannot be combined with the DS_PDC_REQUIRED flag.
///
/// DS_KDC_REQUIRED
///
/// Requires that the enumerated domain controllers currently be running the Kerberos Key Distribution Center service. This flag
/// cannot be combined with the DS_PDC_REQUIRED or DS_GC_SERVER_REQUIRED flags.
///
/// DS_ONLY_LDAP_NEEDED
///
/// Specifies that the enumerated servers are LDAP servers. The servers are not necessarily domain controllers. No other services are
/// implied to be present at each enumerated server. The servers do not necessarily have a writable config container nor a
/// writable schema container. The servers may not necessarily be used to create or modify security principles. This flag may
/// be used with the DS_GC_SERVER_REQUIRED flag to enumerate LDAP servers that also host a global catalog server. In that
/// case, the enumerated global catalog servers are not necessarily domain controllers and other services are implied to be present
/// at each server. If this flag is specified, the DS_PDC_REQUIRED, DS_TIMESERV_REQUIRED,
/// DS_GOOD_TIMESERV_PREFERRED, DS_DIRECTORY_SERVICES_PREFERED, DS_DIRECTORY_SERVICES_REQUIRED, and
/// DS_KDC_REQUIRED flags are ignored.
///
/// DS_PDC_REQUIRED
///
/// Requires that the enumerated domain controllers be the primary domain controllers for the domain. This flag cannot be combined
/// with the DS_GC_SERVER_REQUIRED flag.
///
///
///
///
/// Pointer to a HANDLE value that receives the domain controller enumeration context handle. This handle is used with the
/// DsGetDcNext function to identify the domain controller enumeration operation. This handle is passed to DsGetDcClose to close the
/// domain controller enumeration operation.
///
///
///
/// Returns ERROR_SUCCESS if successful or a Win32 or RPC error otherwise. Possible error values include the following.
///
// https://docs.microsoft.com/en-us/windows/desktop/api/dsgetdc/nf-dsgetdc-dsgetdcopena DSGETDCAPI DWORD DsGetDcOpenA( IN LPCSTR
// DnsName, IN ULONG OptionFlags, IN LPCSTR SiteName, IN GUID *DomainGuid, IN LPCSTR DnsForestName, IN ULONG DcFlags, OUT PHANDLE
// RetGetDcContext );
[DllImport(Lib.NetApi32, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("dsgetdc.h", MSDNShortId = "2811cc30-f367-4f1a-8f0c-ed0a77dad24c")]
public static extern Win32Error DsGetDcOpen(string DnsName, DsGetDcOpenOptions OptionFlags, [Optional] string SiteName, in Guid DomainGuid, [Optional] string DnsForestName, DsGetDcNameFlags DcFlags, out SafeDCEnumHandle RetGetDcContext);
///
/// The DsGetDcOpen function opens a new domain controller enumeration operation.
///
///
///
/// Pointer to a null-terminated string that contains the domain naming system (DNS) name of the domain to enumerate the domain
/// controllers for. This parameter cannot be NULL.
///
///
///
///
/// Contains a set of flags that modify the behavior of the function. This can be zero or a combination of one or more of the
/// following values.
///
/// DS_ONLY_DO_SITE_NAME
/// Only site-specific domain controllers are enumerated.
/// DS_NOTIFY_AFTER_SITE_RECORDS
///
/// The DsGetDcNext function will return the ERROR_FILEMARK_DETECTED value after all of the site-specific domain controllers
/// are retrieved. DsGetDcNext will then enumerate the second group, which contains all domain controllers in the domain,
/// including the site-specific domain controllers contained in the first group.
///
///
///
///
/// Pointer to a null-terminated string that contains the name of site the client is in. This parameter is optional and may be NULL.
///
///
///
///
/// Pointer to a GUID value that contains the identifier of the domain specified by DnsName. This identifier is used to handle
/// the case of a renamed domain. If this value is specified and the domain specified in DnsName is renamed, this function attempts
/// to enumerate domain controllers in the domain that contains the specified identifier. This parameter is optional and may be NULL.
///
///
///
///
/// Pointer to a null-terminated string that contains the name of the forest that contains the DnsName domain. This value is used in
/// conjunction with DomainGuidto enumerate the domain controllers if the domain has been renamed. This parameter is optional and may
/// be NULL.
///
///
///
///
/// Contains a set of flags that identify the type of domain controllers to enumerate. This can be zero or a combination of one or
/// more of the following values.
///
/// DS_FORCE_REDISCOVERY
///
/// Forces cached domain controller data to be ignored. When this flag is not specified, DsGetDcOpen obtains the domain
/// controller enumeration from cached domain controller data.
///
/// DS_GC_SERVER_REQUIRED
///
/// Requires that the enumerated domain controllers be global catalog servers for the forest of domains with this domain as the root.
/// This flag cannot be combined with the DS_PDC_REQUIRED flag.
///
/// DS_KDC_REQUIRED
///
/// Requires that the enumerated domain controllers currently be running the Kerberos Key Distribution Center service. This flag
/// cannot be combined with the DS_PDC_REQUIRED or DS_GC_SERVER_REQUIRED flags.
///
/// DS_ONLY_LDAP_NEEDED
///
/// Specifies that the enumerated servers are LDAP servers. The servers are not necessarily domain controllers. No other services are
/// implied to be present at each enumerated server. The servers do not necessarily have a writable config container nor a
/// writable schema container. The servers may not necessarily be used to create or modify security principles. This flag may
/// be used with the DS_GC_SERVER_REQUIRED flag to enumerate LDAP servers that also host a global catalog server. In that
/// case, the enumerated global catalog servers are not necessarily domain controllers and other services are implied to be present
/// at each server. If this flag is specified, the DS_PDC_REQUIRED, DS_TIMESERV_REQUIRED,
/// DS_GOOD_TIMESERV_PREFERRED, DS_DIRECTORY_SERVICES_PREFERED, DS_DIRECTORY_SERVICES_REQUIRED, and
/// DS_KDC_REQUIRED flags are ignored.
///
/// DS_PDC_REQUIRED
///
/// Requires that the enumerated domain controllers be the primary domain controllers for the domain. This flag cannot be combined
/// with the DS_GC_SERVER_REQUIRED flag.
///
///
///
///
/// Pointer to a HANDLE value that receives the domain controller enumeration context handle. This handle is used with the
/// DsGetDcNext function to identify the domain controller enumeration operation. This handle is passed to DsGetDcClose to close the
/// domain controller enumeration operation.
///
///
///
/// Returns ERROR_SUCCESS if successful or a Win32 or RPC error otherwise. Possible error values include the following.
///
// https://docs.microsoft.com/en-us/windows/desktop/api/dsgetdc/nf-dsgetdc-dsgetdcopena DSGETDCAPI DWORD DsGetDcOpenA( IN LPCSTR
// DnsName, IN ULONG OptionFlags, IN LPCSTR SiteName, IN GUID *DomainGuid, IN LPCSTR DnsForestName, IN ULONG DcFlags, OUT PHANDLE
// RetGetDcContext );
[DllImport(Lib.NetApi32, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("dsgetdc.h", MSDNShortId = "2811cc30-f367-4f1a-8f0c-ed0a77dad24c")]
public static extern Win32Error DsGetDcOpen(string DnsName, DsGetDcOpenOptions OptionFlags, [Optional] string SiteName, [Optional] IntPtr DomainGuid, [Optional] string DnsForestName, DsGetDcNameFlags DcFlags, out SafeDCEnumHandle RetGetDcContext);
///
/// The DsGetDcSiteCoverage function returns the site names of all sites covered by a domain controller.
///
///
/// The null-terminated string value that specifies the name of the remote domain controller.
///
///
/// Pointer to a ULONG value that receives the number of sites covered by the domain controller.
///
///
///
/// Pointer to an array of pointers to null-terminated strings that receives the site names. To free the returned buffer, call the
/// NetApiBufferFree function.
///
///
///
/// This function returns DSGETDCAPI DWORD.
///
// https://docs.microsoft.com/en-us/windows/desktop/api/dsgetdc/nf-dsgetdc-dsgetdcsitecoveragew DSGETDCAPI DWORD
// DsGetDcSiteCoverageW( IN LPCWSTR ServerName, OUT PULONG EntryCount, OUT LPWSTR **SiteNames );
[DllImport(Lib.NetApi32, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("dsgetdc.h", MSDNShortId = "e0f757d9-36b6-40f8-a1db-fb5b9862b46a")]
public static extern Win32Error DsGetDcSiteCoverage([Optional] string ServerName, out uint EntryCount, out SafeNetApiBuffer SiteNames);
///
/// The DsGetForestTrustInformationW function obtains forest trust data for a specified domain.
///
///
///
/// Contains the name of the domain controller that DsGetForestTrustInformationW is connected to remotely. The caller must be
/// an authenticated user on this server. If this parameter is NULL, the local server is used.
///
///
///
///
/// Contains the NETBIOS or DNS name of the trusted domain that the forest trust data is to be retrieved for. This domain must have
/// the TRUST_ATTRIBUTE_FOREST_TRANSITIVE trust attribute. For more information, see TRUSTED_DOMAIN_INFORMATION_EX.
///
/// If this parameter is NULL, the forest trust data for the domain hosted by ServerName is retrieved.
///
///
/// Contains a set of flags that modify the behavior of this function. This can be zero or the following value.
/// DS_GFTI_UPDATE_TDO
///
/// If this flag is set, DsGetForestTrustInformationW will update the forest trust data of the trusted domain identified by
/// the TrustedDomainNameparameter. In this case, the TrustedDomainName parameter cannot be NULL. The caller must have access
/// to modify the trust data or ERROR_ACCESS_DENIED is returned.
///
/// This flag is only valid if ServerName specifies the primary domain controller of the domain.
///
///
///
/// Pointer to an LSA_FOREST_TRUST_INFORMATION structure pointer that receives the forest trust data that describes the namespaces
/// claimed by the domain specified by TrustedDomainName. The Time member of all returned records will be zero.
///
/// The caller must free this structure when it is no longer required by calling NetApiBufferFree.
///
///
/// Returns NO_ERROR if successful or a Win32 error code otherwise. Possible error codes include the following.
///
// https://docs.microsoft.com/en-us/windows/desktop/api/dsgetdc/nf-dsgetdc-dsgetforesttrustinformationw DSGETDCAPI DWORD
// DsGetForestTrustInformationW( IN LPCWSTR ServerName, IN LPCWSTR TrustedDomainName, IN DWORD Flags, OUT
// PLSA_FOREST_TRUST_INFORMATION *ForestTrustInfo );
[DllImport(Lib.NetApi32, SetLastError = false, ExactSpelling = true, CharSet = CharSet.Unicode)]
[PInvokeData("dsgetdc.h", MSDNShortId = "c94fdc5b-920b-4807-9cbf-3172ec1c7386")]
public static extern Win32Error DsGetForestTrustInformationW([Optional] string ServerName, [Optional] string TrustedDomainName, DsGetForestTrustInformationFlags Flags, out SafeNetApiBuffer ForestTrustInfo);
///
///
/// The DsGetSiteName function returns the name of the site where a computer resides. For a domain controller (DC), the name
/// of the site is the location of the configured DC. For a member workstation or member server, the name specifies the workstation
/// site as configured in the domain of the computer.
///
///
///
///
/// Pointer to a null-terminated string that specifies the name of the server to send this function. A NULL implies the local computer.
///
///
///
///
/// Pointer to a variable that receives a pointer to a null-terminated string specifying the site location of this computer.
///
///
///
/// If the function returns account information, the return value is NO_ERROR.
/// If the function fails, the return value can be one of the following error codes.
///
///
///
/// The DsGetSiteName function does not require any particular access to the specified domain. The function is sent to the
/// "NetLogon" service on the computer specified by ComputerName.
///
///
// https://docs.microsoft.com/en-us/windows/desktop/api/dsgetdc/nf-dsgetdc-dsgetsitenamea DSGETDCAPI DWORD DsGetSiteNameA( IN LPCSTR
// ComputerName, OUT LPSTR *SiteName );
[DllImport(Lib.NetApi32, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("dsgetdc.h", MSDNShortId = "2dfffd9a-af4f-4a93-8b3c-966e4f7c455f")]
public static extern Win32Error DsGetSiteName([Optional] string ComputerName, [MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(NetApiBufferUnicodeStringMarshaler))] out string SiteName);
///
///
/// The DsMergeForestTrustInformationW function merges the changes from a new forest trust data structure with an old forest
/// trust data structure.
///
///
///
/// Pointer to a null-terminated Unicode string that specifies the trusted domain to update.
///
///
///
/// Pointer to an LSA_FOREST_TRUST_INFORMATION structure that contains the new forest trust data to be merged. The
/// Flags and Time members of the entries are ignored.
///
///
///
///
/// Pointer to an LSA_FOREST_TRUST_INFORMATION structure that contains the old forest trust data to be merged. This parameter
/// may be NULL if no records exist.
///
///
///
/// Pointer to an LSA_FOREST_TRUST_INFORMATION structure pointer that receives the merged forest trust data.
/// The caller must free this structure when it is no longer required by calling NetApiBufferFree.
///
///
/// Returns NO_ERROR if successful or a Windows error code otherwise.
///
// https://docs.microsoft.com/en-us/windows/desktop/api/dsgetdc/nf-dsgetdc-dsmergeforesttrustinformationw DSGETDCAPI DWORD
// DsMergeForestTrustInformationW( IN LPCWSTR DomainName, IN PLSA_FOREST_TRUST_INFORMATION NewForestTrustInfo, IN
// PLSA_FOREST_TRUST_INFORMATION OldForestTrustInfo, OUT PLSA_FOREST_TRUST_INFORMATION *MergedForestTrustInfo );
[DllImport(Lib.NetApi32, SetLastError = false, ExactSpelling = true, CharSet = CharSet.Unicode)]
[PInvokeData("dsgetdc.h", MSDNShortId = "f42e16d0-62b2-49c4-b182-d1e744afe58c")]
public static extern Win32Error DsMergeForestTrustInformationW(string DomainName, in LSA_FOREST_TRUST_INFORMATION NewForestTrustInfo, in LSA_FOREST_TRUST_INFORMATION OldForestTrustInfo, out SafeNetApiBuffer MergedForestTrustInfo);
///
///
/// The DsMergeForestTrustInformationW function merges the changes from a new forest trust data structure with an old forest
/// trust data structure.
///
///
///
/// Pointer to a null-terminated Unicode string that specifies the trusted domain to update.
///
///
///
/// Pointer to an LSA_FOREST_TRUST_INFORMATION structure that contains the new forest trust data to be merged. The
/// Flags and Time members of the entries are ignored.
///
///
///
///
/// Pointer to an LSA_FOREST_TRUST_INFORMATION structure that contains the old forest trust data to be merged. This parameter
/// may be NULL if no records exist.
///
///
///
/// Pointer to an LSA_FOREST_TRUST_INFORMATION structure pointer that receives the merged forest trust data.
/// The caller must free this structure when it is no longer required by calling NetApiBufferFree.
///
///
/// Returns NO_ERROR if successful or a Windows error code otherwise.
///
// https://docs.microsoft.com/en-us/windows/desktop/api/dsgetdc/nf-dsgetdc-dsmergeforesttrustinformationw DSGETDCAPI DWORD
// DsMergeForestTrustInformationW( IN LPCWSTR DomainName, IN PLSA_FOREST_TRUST_INFORMATION NewForestTrustInfo, IN
// PLSA_FOREST_TRUST_INFORMATION OldForestTrustInfo, OUT PLSA_FOREST_TRUST_INFORMATION *MergedForestTrustInfo );
[DllImport(Lib.NetApi32, SetLastError = false, ExactSpelling = true, CharSet = CharSet.Unicode)]
[PInvokeData("dsgetdc.h", MSDNShortId = "f42e16d0-62b2-49c4-b182-d1e744afe58c")]
public static extern Win32Error DsMergeForestTrustInformationW(string DomainName, in LSA_FOREST_TRUST_INFORMATION NewForestTrustInfo, [Optional] IntPtr OldForestTrustInfo, out SafeNetApiBuffer MergedForestTrustInfo);
///
///
/// The DsValidateSubnetName function validates a subnet name in the form xxx.xxx.xxx.xxx/YY. The Xxx.xxx.xxx.xxx portion must
/// be a valid IP address. Yy must be the number of leftmost significant bits included in the mask. All bits of the IP address that
/// are not covered by the mask must be specified as zero.
///
///
///
/// Pointer to a null-terminated string that specifies the name of the subnet to validate.
///
///
/// If the function returns account information, the return value is NO_ERROR.
/// If the function fails, the return value is the following error code.
///
// https://docs.microsoft.com/en-us/windows/desktop/api/dsgetdc/nf-dsgetdc-dsvalidatesubnetnamew DSGETDCAPI DWORD
// DsValidateSubnetNameW( IN LPCWSTR SubnetName );
[DllImport(Lib.NetApi32, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("dsgetdc.h", MSDNShortId = "bed49e08-4cb7-439c-bfb7-815263ec7568")]
public static extern Win32Error DsValidateSubnetName(string SubnetName);
/// The DOMAIN_CONTROLLER_INFO structure is used with the DsGetDcName function to receive data about a domain controller.
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
[PInvokeData("DsGetDC.h", MSDNShortId = "ms675912")]
public struct DOMAIN_CONTROLLER_INFO
{
///
/// Pointer to a null-terminated string that specifies the computer name of the discovered domain controller. The returned
/// computer name is prefixed with "\\". The DNS-style name, for example, "\\phoenix.fabrikam.com", is returned, if available. If
/// the DNS-style name is not available, the flat-style name (for example, "\\phoenix") is returned. This example would apply if
/// the domain is a Windows NT 4.0 domain or if the domain does not support the IP family of protocols.
///
public string DomainControllerName;
///
/// Pointer to a null-terminated string that specifies the address of the discovered domain controller. The address is prefixed
/// with "\\". This string is one of the types defined by the DomainControllerAddressType member.
///
public string DomainControllerAddress;
/// Indicates the type of string that is contained in the DomainControllerAddress member.
public DomainControllerAddressType DomainControllerAddressType;
///
/// The GUID of the domain. This member is zero if the domain controller does not have a Domain GUID; for example, the domain
/// controller is not a Windows 2000 domain controller.
///
public Guid DomainGuid;
///
/// Pointer to a null-terminated string that specifies the name of the domain. The DNS-style name, for example, "fabrikam.com",
/// is returned if available. Otherwise, the flat-style name, for example, "fabrikam", is returned. This name may be different
/// than the requested domain name if the domain has been renamed.
///
public string DomainName;
///
/// Pointer to a null-terminated string that specifies the name of the domain at the root of the DS tree. The DNS-style name, for
/// example, "fabrikam.com", is returned if available. Otherwise, the flat-style name, for example, "fabrikam" is returned.
///
public string DnsForestName;
///
/// Contains a set of flags that describe the domain controller. This can be zero or a combination of one or more of the
/// following values.
///
public DomainControllerType Flags;
///
/// Pointer to a null-terminated string that specifies the name of the site where the domain controller is located. This member
/// may be NULL if the domain controller is not in a site; for example, the domain controller is a Windows NT 4.0 domain controller.
///
public string DcSiteName;
///
/// Pointer to a null-terminated string that specifies the name of the site that the computer belongs to. The computer is
/// specified in the ComputerName parameter passed to DsGetDcName. This member may be NULL if the site that contains the computer
/// cannot be found; for example, if the DS administrator has not associated the subnet that the computer is in with a valid site.
///
public string ClientSiteName;
}
///
/// The DS_DOMAIN_TRUSTS structure is used with the DsEnumerateDomainTrusts function to contain trust data for a domain.
///
// https://docs.microsoft.com/en-us/windows/desktop/api/dsgetdc/ns-dsgetdc-_ds_domain_trustsa typedef struct _DS_DOMAIN_TRUSTSA {
// LPSTR NetbiosDomainName; LPSTR DnsDomainName; ULONG Flags; ULONG ParentIndex; ULONG TrustType; ULONG TrustAttributes; PSID
// DomainSid; GUID DomainGuid; } DS_DOMAIN_TRUSTSA, *PDS_DOMAIN_TRUSTSA;
[PInvokeData("dsgetdc.h", MSDNShortId = "cd260fd1-dc38-4405-95ba-097a23faf668")]
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public struct DS_DOMAIN_TRUSTS
{
///
/// Pointer to a null-terminated string that contains the NetBIOS name of the domain.
///
public string NetbiosDomainName;
///
/// Pointer to a null-terminated string that contains the DNS name of the domain. This member may be NULL.
///
public string DnsDomainName;
///
///
/// Contains a set of flags that specify more data about the domain trust. This can be zero or a combination of one or more of
/// the following values.
///
/// DS_DOMAIN_IN_FOREST (1 (0x1))
///
/// The domain represented by this structure is a member of the same forest as the server specified in the ServerName parameter
/// of the DsEnumerateDomainTrusts function.
///
/// DS_DOMAIN_DIRECT_OUTBOUND (2 (0x2))
///
/// The domain represented by this structure is directly trusted by the domain that the server specified in the ServerName
/// parameter of the DsEnumerateDomainTrusts function is a member of.
///
/// DS_DOMAIN_TREE_ROOT (4 (0x4))
///
/// The domain represented by this structure is the root of a tree and a member of the same forest as the server specified in the
/// ServerName parameter of the DsEnumerateDomainTrusts function.
///
/// DS_DOMAIN_PRIMARY (8 (0x8))
///
/// The domain represented by this structure is the primary domain of the server specified in the ServerName parameter of the
/// DsEnumerateDomainTrusts function.
///
/// DS_DOMAIN_NATIVE_MODE (16 (0x10))
/// The domain represented by this structure is running in the Windows 2000 native mode.
/// DS_DOMAIN_DIRECT_INBOUND (32 (0x20))
///
/// The domain represented by this structure directly trusts the domain that the server specified in the ServerName parameter of
/// the DsEnumerateDomainTrusts function is a member of.
///
///
public DomainTrustFlag Flags;
///
///
/// Contains the index in the Domains array returned by the DsEnumerateDomainTrusts function that corresponds to the parent
/// domain of the domain represented by this structure. This member is only valid if the all of the following conditions are met:
///
///
/// -
/// The DS_DOMAIN_IN_FOREST flag was specified in the Flags parameter of the DsEnumerateDomainTrusts function.
///
/// -
/// The Flags member of this structure does not contain the DS_DOMAIN_TREE_ROOT flag.
///
///
///
public uint ParentIndex;
///
///
/// Contains a value that indicates the type of trust represented by this structure. Possible values for this member are
/// documented in the TrustType member of the TRUSTED_DOMAIN_INFORMATION_EX structure.
///
///
public TrustType TrustType;
///
///
/// Contains a value that indicates the attributes of the trust represented by this structure. Possible values for this member
/// are documented in the TrustAttribute member of the TRUSTED_DOMAIN_INFORMATION_EX structure.
///
///
public TrustAttributes TrustAttributes;
///
/// Contains the security identifier of the domain represented by this structure.
///
public IntPtr DomainSid;
///
/// Contains the GUID of the domain represented by this structure.
///
public Guid DomainGuid;
}
///
/// Provides a to a domain controller enumeration handle that is released at disposal using DsGetDcClose.
///
public class SafeDCEnumHandle : SafeHANDLE
{
/// Initializes a new instance of the class and assigns an existing handle.
/// An object that represents the pre-existing handle to use.
///
/// to reliably release the handle during the finalization phase; otherwise, (not recommended).
///
public SafeDCEnumHandle(IntPtr preexistingHandle, bool ownsHandle = true) : base(preexistingHandle, ownsHandle) { }
/// Initializes a new instance of the class.
private SafeDCEnumHandle() : base() { }
///
protected override bool InternalReleaseHandle() { DsGetDcClose(handle); return true; }
}
}
}