using System; using System.Collections.Generic; using System.Linq; using System.Runtime.InteropServices; using Vanara.Extensions; using Vanara.InteropServices; using static Vanara.PInvoke.Ws2_32; namespace Vanara.PInvoke { public static partial class NetApi32 { /// The DsAddressToSiteNamesEx function obtains the site and subnet names corresponding to the addresses specified. /// /// 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 an array of SOCKET_ADDRESS structures that contain the addresses to convert. Each address in this array must be of the /// type AF_INET. /// /// /// Returns a list that contains the supplied SOCKET_ADDRESS structure with its corresponding site name and subnet name. An /// value is if the corresponding address does not map to any known site or subnet or if the address entry is /// not of the proper form. /// // https://docs.microsoft.com/en-us/windows/desktop/api/dsgetdc/nf-dsgetdc-dsaddresstositenamesexa DSGETDCAPI DWORD // DsAddressToSiteNamesExA( IN LPCSTR ComputerName, IN DWORD EntryCount, IN PSOCKET_ADDRESS SocketAddresses, OUT LPSTR **SiteNames, // OUT LPSTR **SubnetNames ); [PInvokeData("dsgetdc.h", MSDNShortId = "60ac6195-6e43-46da-a1e6-74ec989cd0c4")] public static IEnumerable<(SOCKET_ADDRESS address, string site, string subnet)> DsAddressToSiteNamesEx(string ComputerName, SOCKET_ADDRESS[] SocketAddresses) { DsAddressToSiteNamesEx(ComputerName, (uint)(SocketAddresses?.Length ?? 0), SocketAddresses, out var sites, out var subnets).ThrowIfFailed(); return from addr in SocketAddresses from site in sites.ToStringEnum(SocketAddresses.Length) from sub in subnets.ToStringEnum(SocketAddresses.Length) select (addr, site, sub); } /// The DsEnumerateDomainTrusts function obtains domain trust data for a specified domain. /// /// /// A string that specifies the name of a computer in the domain to obtain the trust information for. If this parameter is /// , 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 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. /// /// An enumeration of DS_DOMAIN_TRUSTS structures. Each structure in this array contains trust data about a domain. // 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 ); [PInvokeData("dsgetdc.h", MSDNShortId = "6c3b788f-ee53-4637-acdb-04316e8464fe")] public static IEnumerable DsEnumerateDomainTrusts(DomainTrustFlag Flags, string ServerName = null) { DsEnumerateDomainTrusts(ServerName, Flags, out var buf, out var cnt).ThrowIfFailed(); return buf.ToIEnum((int)cnt); } /// The DsGetDcOpen function opens a new domain controller enumeration operation. /// /// A string that contains the domain naming system (DNS) name of the domain to enumerate the domain controllers for. This parameter /// cannot be . /// /// /// /// 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. /// /// /// A string that contains the name of site the client is in. This parameter is optional and may be . /// /// An optional 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 . /// /// /// A 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 . /// /// /// /// 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. /// /// /// An enumeration of domain controllers paired with the socket address data for the domain controller. // 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 ); [PInvokeData("dsgetdc.h", MSDNShortId = "2811cc30-f367-4f1a-8f0c-ed0a77dad24c")] public static IEnumerable<(string dnsHostName, SOCKET_ADDRESS[] sockets)> DsGetDcEnum(string DnsName, [Optional] DsGetDcOpenOptions OptionFlags, [Optional] DsGetDcNameFlags DcFlags, [Optional] string SiteName, [Optional] Guid? DomainGuid, [Optional] string DnsForestName) { SafeDCEnumHandle h; if (DomainGuid.HasValue) DsGetDcOpen(DnsName, OptionFlags, SiteName, DomainGuid.Value, DnsForestName, DcFlags, out h).ThrowIfFailed(); else DsGetDcOpen(DnsName, OptionFlags, SiteName, IntPtr.Zero, DnsForestName, DcFlags, out h).ThrowIfFailed(); using (h) { while (true) { var err = DsGetDcNext(h, out var addrCnt, out var addr, out var host); if (err.Succeeded) yield return (host.ToString(), addr.ToArray((int)addrCnt)); else if (err == Win32Error.ERROR_NO_MORE_ITEMS) break; else if (err == Win32Error.ERROR_FILEMARK_DETECTED) continue; else err.ThrowIfFailed(); } } } /// /// 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. /// /// /// /// 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 , 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. /// /// /// A string that specifies the name of the server to process this function. Typically, this parameter is , /// which indicates that the local computer is used. /// /// /// /// A 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 , /// DsGetDcName attempts to find a global catalog in the forest of the computer identified by ComputerName, which is the local /// computer if ComputerName is . /// /// /// If DomainName is 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. /// /// /// /// An optional Guid value that specifies the GUID of the domain queried. If DomainGuid is not 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. /// /// /// A string that specifies the name of the site where the returned domain controller should physically exist. If this parameter is /// , DsGetDcName attempts to return a domain controller in the site closest to the site of the computer /// specified by ComputerName. This parameter should be , by default. /// /// A DOMAIN_CONTROLLER_INFO structure that contains data about the domain controller selected. /// /// /// The DsGetDcName function is sent to the Netlogon service on the remote computer specified by ComputerName. If ComputerName /// is , 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. /// /// [PInvokeData("dsgetdc.h", MSDNShortId = "da8b2983-5e45-40b0-b552-c9b3a1d8ae94")] public static DOMAIN_CONTROLLER_INFO DsGetDcName(DsGetDcNameFlags Flags, [Optional] string ComputerName, [Optional] string DomainName, [Optional] Guid? DomainGuid, [Optional] string SiteName) { SafeNetApiBuffer buf; if (DomainGuid.HasValue) DsGetDcName(ComputerName, DomainName, DomainGuid.Value, SiteName, Flags, out buf).ThrowIfFailed(); else DsGetDcName(ComputerName, DomainName, IntPtr.Zero, SiteName, Flags, out buf).ThrowIfFailed(); return buf.ToStructure(); } /// The DsGetDcSiteCoverage function returns the site names of all sites covered by a domain controller. /// A string value that specifies the name of the remote domain controller. /// An array of strings containing the site names. // https://docs.microsoft.com/en-us/windows/desktop/api/dsgetdc/nf-dsgetdc-dsgetdcsitecoveragea [PInvokeData("dsgetdc.h", MSDNShortId = "e0f757d9-36b6-40f8-a1db-fb5b9862b46a")] public static IEnumerable DsGetDcSiteCoverage(string ServerName = null) { DsGetDcSiteCoverage(ServerName, out var c, out var b).ThrowIfFailed(); return b.ToStringEnum((int)c); } /// The DsGetForestTrustInformationW function obtains forest trust data for a specified domain. /// /// Contains the name of the domain controller that DsGetForestTrustInformation is connected to remotely. The caller must be /// an authenticated user on this server. If this parameter is , 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 , 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 . 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. /// /// /// 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. /// // https://docs.microsoft.com/en-us/windows/desktop/api/dsgetdc/nf-dsgetdc-dsgetforesttrustinformationw [PInvokeData("dsgetdc.h", MSDNShortId = "c94fdc5b-920b-4807-9cbf-3172ec1c7386")] public static AdvApi32.LsaForestTrustInformation DsGetForestTrustInformation([Optional] string ServerName, [Optional] string TrustedDomainName, DsGetForestTrustInformationFlags Flags = 0) { DsGetForestTrustInformationW(ServerName, TrustedDomainName, Flags, out var b).ThrowIfFailed(); return AdvApi32.LsaForestTrustInformation.FromBuffer(b.DangerousGetHandle()); } /// /// The DsMergeForestTrustInformationW function merges the changes from a new forest trust data structure with an old forest /// trust data structure. /// /// A string that specifies the trusted domain to update. /// /// A LsaForestTrustInformation instance that contains the new forest trust data to be merged. The Flags and /// Time members of the entries are ignored. /// /// /// A LsaForestTrustInformation instance that contains the old forest trust data to be merged. This parameter may be /// if no records exist. /// /// Returns NO_ERROR if successful or a Windows error code otherwise. // https://docs.microsoft.com/en-us/windows/desktop/api/dsgetdc/nf-dsgetdc-dsmergeforesttrustinformationw [PInvokeData("dsgetdc.h", MSDNShortId = "f42e16d0-62b2-49c4-b182-d1e744afe58c")] public static AdvApi32.LsaForestTrustInformation DsMergeForestTrustInformation(string DomainName, [In] AdvApi32.LsaForestTrustInformation NewForestTrustInfo, [In, Optional] AdvApi32.LsaForestTrustInformation OldForestTrustInfo) { SafeNetApiBuffer buf; if (OldForestTrustInfo is null) DsMergeForestTrustInformationW(DomainName, NewForestTrustInfo.DangerousGetLSA_FOREST_TRUST_INFORMATION(), IntPtr.Zero, out buf).ThrowIfFailed(); else DsMergeForestTrustInformationW(DomainName, NewForestTrustInfo.DangerousGetLSA_FOREST_TRUST_INFORMATION(), OldForestTrustInfo.DangerousGetLSA_FOREST_TRUST_INFORMATION(), out buf).ThrowIfFailed(); return AdvApi32.LsaForestTrustInformation.FromBuffer(buf.DangerousGetHandle()); } /// /// The DsRoleGetPrimaryDomainInformation function retrieves state data for the computer. This data includes the state of the /// directory service installation and domain data. /// /// /// Pointer to null-terminated Unicode string that contains the name of the computer on which to call the function. If this /// parameter is , the local computer is used. /// /// /// Contains one of the DSROLE_PRIMARY_DOMAIN_INFO_LEVEL values that specify the type of data to retrieve. This parameter also /// determines the format of the data supplied in Buffer. /// /// /// The requested data. The format of this data depends on the value of the InfoLevel parameter. /// // https://docs.microsoft.com/en-us/windows/desktop/api/dsrole/nf-dsrole-dsrolegetprimarydomaininformation DWORD // DsRoleGetPrimaryDomainInformation( IN LPCWSTR lpServer, IN DSROLE_PRIMARY_DOMAIN_INFO_LEVEL InfoLevel, OUT PBYTE *Buffer ); [PInvokeData("dsrole.h", MSDNShortId = "d54876e3-a622-4b44-a597-db0f710f7758")] public static T DsRoleGetPrimaryDomainInformation([Optional] string lpServer, DSROLE_PRIMARY_DOMAIN_INFO_LEVEL InfoLevel) where T : struct { if (!CorrespondingTypeAttribute.CanGet(InfoLevel, typeof(T))) throw new ArgumentException("Type mismatch", nameof(InfoLevel)); DsRoleGetPrimaryDomainInformation(lpServer, InfoLevel, out var buf).ThrowIfFailed(); return buf.ToStructure(); } /// /// Lists all connections made to a shared resource on the server or all connections established from a particular computer. If there /// is more than one user using this connection, then it is possible to get more than one structure for the same connection, but with /// a different user name. /// /// /// /// A string that specifies the DNS or NetBIOS name of the remote server on which the function is to execute. If this parameter is /// , the local computer is used. /// /// This string is Unicode if _WIN32_WINNT or FORCE_UNICODE is defined. /// /// /// /// A string that specifies a share name or computer name for the connections of interest. If it is a share name, then all the /// connections made to that share name are listed. If it is a computer name (for example, it starts with two backslash characters), /// then NetConnectionEnum lists all connections made from that computer to the server specified. /// /// This string is Unicode if _WIN32_WINNT or FORCE_UNICODE is defined. /// /// /// Specifies the information level of the data. This parameter can be one of the following values. /// /// /// Value /// Meaning /// /// /// 0 /// Return connection identifiers. The bufptr parameter is a pointer to an array of CONNECTION_INFO_0 structures. /// /// /// 1 /// /// Return connection identifiers and connection information. The bufptr parameter is a pointer to an array of CONNECTION_INFO_1 structures. /// /// /// /// /// A sequence of the requested type. /// /// /// Administrator, Server or Print Operator, or Power User group membership is required to successfully execute the /// NetConnectionEnum function. /// /// Examples /// /// The following code sample demonstrates how to list the connections made to a shared resource with a call to the /// NetConnectionEnum function. The sample calls NetConnectionEnum, specifying information level 1 (CONNECTION_INFO_1). /// If there are entries to return, it prints the values of the coni1_username and coni1_netname members. If there are /// no entries to return, the sample prints an appropriate message. Finally, the code sample frees the memory allocated for the /// information buffer. /// /// // https://docs.microsoft.com/en-us/windows/desktop/api/lmshare/nf-lmshare-netconnectionenum NET_API_STATUS NET_API_FUNCTION // NetConnectionEnum( LMSTR servername, LMSTR qualifier, DWORD level, LPBYTE *bufptr, DWORD prefmaxlen, LPDWORD entriesread, LPDWORD // totalentries, LPDWORD resume_handle ); [PInvokeData("lmshare.h", MSDNShortId = "935ac6e9-78e0-42ae-a454-0a14b03ddc21")] public static IEnumerable NetConnectionEnum([Optional] string servername, string qualifier, uint level = uint.MaxValue) where T : struct { if (level == uint.MaxValue) level = (uint)GetLevelFromStructure(); var h = 0U; NetConnectionEnum(servername, qualifier, level, out var buf, MAX_PREFERRED_LENGTH, out var cnt, out var _, ref h).ThrowIfFailed(); return buf.ToIEnum((int)cnt); } /// /// Enumerates the Distributed File System (DFS) namespaces hosted on a server or DFS links of a namespace hosted by a server. /// /// /// /// Pointer to a string that specifies the Universal Naming Convention (UNC) path of the DFS root or link. /// /// When you specify information level 200 (DFS_INFO_200), this parameter is the name of a domain. When you specify information level /// 300 (DFS_INFO_300), this parameter is the name of a server. /// /// For all other levels, the string can be in one of the following four forms: /// ServerName<i>DfsName /// or /// ServerName<i>DfsName<i>link_path /// /// where ServerName is the name of the root target server that hosts the stand-alone DFS namespace; Dfsname is the name of the DFS /// namespace; and link_path is a DFS link. /// /// The string can also be of the following forms: /// DomainName<i>DomainName\DomDfsName /// or /// DomainName<i>DomDfsName<i>link_path /// /// where DomainName is the name of the domain that hosts the domain-based DFS root; DomDfsName is the name of the DFS namespace; and /// link_path is a DFS link. /// /// You can precede the string with backslashes (\), but they are not required. This parameter is required. /// /// /// Specifies the information level of the request. This parameter can be one of the following values. /// 1 /// Return the name of the DFS root and all links under the root. The Buffer parameter points to an array of DFS_INFO_1 structures. /// 2 /// /// Return the name, comment, status, and the number of targets for the DFS root and all links under the root. The Buffer parameter /// points to an array of DFS_INFO_2 structures. /// /// 3 /// /// Return the name, comment, status, number of targets, and information about each target for the DFS root and all links under the /// root. The Buffer parameter points to an array of DFS_INFO_3 structures. /// /// 4 /// /// Return the name, comment, status, GUID, time-out, number of targets, and information about each target for the DFS root /// and all links under the root. The Buffer parameter points to an array of DFS_INFO_4 structures. /// /// 5 /// /// Return the name, status, GUID, time-out, property flags, metadata size, and number of targets for a DFS root and all links /// under the root. The Buffer parameter points to an array of DFS_INFO_5 structures. /// /// 6 /// /// Return the name, status, GUID, time-out, property flags, metadata size, DFS target information for a root or link, and a /// list of DFS targets. The Buffer parameter points to an array of DFS_INFO_6 structures. /// /// 8 /// /// Return the name, status, GUID, time-out, property flags, metadata size, number of targets, and link reparse point security /// descriptors for a DFS root and all links under the root. The Buffer parameter points to an array of DFS_INFO_8 structures. /// /// 9 /// /// Return the name, status, GUID, time-out, property flags, metadata size, DFS target information, link reparse point /// security descriptors, and a list of DFS targets for a root or link. The Buffer parameter points to an array of DFS_INFO_9 structures. /// /// 200 /// /// Return the list of domain-based DFS namespaces in the domain. The Buffer parameter points to an array of DFS_INFO_200 structures. /// /// 300 /// /// Return the stand-alone and domain-based DFS namespaces hosted by a server. The Buffer parameter points to an array of /// DFS_INFO_300 structures. /// /// /// /// If the function succeeds, the return value is NERR_Success. /// If no more entries are available to be enumerated, the return value is ERROR_NO_MORE_ITEMS. /// If the function fails, the return value is a system error code. For a list of error codes, see System Error Codes. /// /// /// No special group membership is required for using the NetDfsEnum function. /// /// Call the NetDfsEnum function with the ResumeHandle parameter set to zero to begin the enumeration. To continue the /// enumeration operation, call this function with the ResumeHandle returned by the previous call to NetDfsEnum. If this /// function does not return ERROR_NO_MORE_ITEMS, subsequent calls to this API will return the remaining links. Once /// ERROR_NO_MORE_ITEMS is returned, all available DFS links have been retrieved. /// /// /// The NetDfsEnum function allocates the memory required for the information structure buffer. If you specify an amount in /// the PrefMaxLen parameter, it restricts the memory that the function returns. However, the actual size of the memory that the /// NetDfsEnum function allocates can be greater than the amount you specify. For additional information see Network /// Management Function Buffer Lengths. /// /// /// Due to the possibility of concurrent updates to the DFS namespace, the caller should not assume completeness or uniqueness of the /// results returned when resuming an enumeration operation. /// /// Examples /// /// The following code sample demonstrates how to list the DFS links in a named DFS root with a call to the NetDfsEnum /// function. The sample calls NetDfsEnum, specifying information level 3 ( DFS_INFO_3). The sample code loops through the /// entries and prints the retrieved data and the status of each host server referenced by the DFS link. Finally, the sample frees /// the memory allocated for the information buffer. /// /// [PInvokeData("lmdfs.h", MSDNShortId = "c05a8d78-41f4-4c19-a25e-ef4885869584")] public static IEnumerable NetDfsEnum(string DfsName, uint Level = uint.MaxValue) where T : struct { if (Level == uint.MaxValue) Level = (uint)GetLevelFromStructure(); var h = 0U; NetDfsEnum(DfsName, Level, MAX_PREFERRED_LENGTH, out var buf, out var cnt, ref h).ThrowIfFailed(); return buf.ToIEnum((int)cnt); } /// Retrieves information about a Distributed File System (DFS) root or link from the cache maintained by the DFS client. /// /// /// Pointer to a string that specifies the Universal Naming Convention (UNC) path of a DFS root or link. /// For a link, the string can be in one of two forms. The first form is as follows: /// \ServerName<i>DfsName<i>link_path /// /// where ServerName is the name of the root target server that hosts the stand-alone DFS namespace; DfsName is the name of the DFS /// namespace; and link_path is a DFS link. /// /// The second form is as follows: /// \DomainName<i>DomDfsname<i>link_path /// /// where DomainName is the name of the domain that hosts the domain-based DFS namespace; DomDfsname is the name of the DFS /// namespace; and link_path is a DFS link. /// /// For a root, the string can be in one of two forms: /// \ServerName<i>DfsName /// or /// \DomainName<i>DomDfsname /// where the values of the names are the same as those described previously. /// This parameter is required. /// /// /// Pointer to a string that specifies the name of the DFS root target or link target server. This parameter is optional. /// /// /// Pointer to a string that specifies the name of the share corresponding to the DFS root target or link target. This parameter is optional. /// /// /// Specifies the information level of the request. This parameter can be one of the following values. /// 1 /// Return the DFS root or DFS link name. The Buffer parameter points to a DFS_INFO_1 structure. /// 2 /// /// Return the DFS root or DFS link name, status, and the number of DFS targets. The Buffer parameter points to a DFS_INFO_2 structure. /// /// 3 /// Return the DFS root or DFS link name, status, and target information. The Buffer parameter points to a DFS_INFO_3 structure. /// 4 /// /// Return the DFS root or DFS link name, status, GUID, time-out, and target information. The Buffer parameter points to a /// DFS_INFO_4 structure. /// /// /// The requested information. /// No special group membership is required for using the NetDfsGetClientInfo function. [PInvokeData("lmdfs.h", MSDNShortId = "065ec002-cb90-4d78-a70c-6ac37f71994f")] public static T NetDfsGetClientInfo(string DfsEntryPath, [Optional] string ServerName, [Optional] string ShareName, uint Level = uint.MaxValue) where T : struct { if (Level == uint.MaxValue) Level = (uint)GetLevelFromStructure(); NetDfsGetClientInfo(DfsEntryPath, ServerName, ShareName, Level, out var buf).ThrowIfFailed(); return buf.ToStructure(); } /// /// Retrieves the security descriptor of the container object for the domain-based DFS namespaces in the specified Active Directory domain. /// /// Pointer to a string that specifies the Active Directory domain name. /// /// SECURITY_INFORMATION structure that contains bit flags that indicate the type of security information to retrieve. /// /// SECURITY_DESCRIPTOR that contains the security items requested in the SecurityInformation parameter. /// /// The security descriptor is retrieved from the "CN=DFS-Configuration,CN=System,DC=domain" object in Active Directory from the /// primary domain controller (PDC) of the domain specified in the DomainName parameter, where domain is the distinguished name of /// the domain specified in the DomainName parameter. /// [PInvokeData("lmdfs.h", MSDNShortId = "88e988db-1418-49d5-8cac-1ea6144474a5")] public static AdvApi32.SafePSECURITY_DESCRIPTOR NetDfsGetFtContainerSecurity(string DomainName, SECURITY_INFORMATION SecurityInformation) { NetDfsGetFtContainerSecurity(DomainName, SecurityInformation, out var buf, out var len).ThrowIfFailed(); return new AdvApi32.SafePSECURITY_DESCRIPTOR(buf.ToIEnum((int)len).ToArray()); } /// Retrieves information about a specified Distributed File System (DFS) root or link in a DFS namespace. /// /// /// Pointer to a string that specifies the Universal Naming Convention (UNC) path of a DFS root or link. /// For a link, the string can be in one of two forms. The first form is as follows: /// \ServerName<i>DfsName<i>link_path /// /// where ServerName is the name of the root target server that hosts the stand-alone DFS namespace; DfsName is the name of the DFS /// namespace; and link_path is a DFS link. /// /// The second form is as follows: /// \DomainName<i>DomDfsname<i>link_path /// /// where DomainName is the name of the domain that hosts the domain-based DFS namespace; DomDfsname is the name of the DFS /// namespace; and link_path is a DFS link. /// /// For a root, the string can be in one of two forms: /// \ServerName<i>DfsName /// or /// \DomainName<i>DomDfsname /// where the values of the names are the same as those described previously. /// This parameter is required. /// /// This parameter is currently ignored and should be NULL. /// This parameter is currently ignored and should be NULL. /// /// Specifies the information level of the request. This parameter can be one of the following values. /// 1 /// Return the DFS root or DFS link name. The Buffer parameter points to a DFS_INFO_1 structure. /// 2 /// /// Return the DFS root or DFS link name, status, and the number of DFS targets. The Buffer parameter points to a DFS_INFO_2 structure. /// /// 3 /// Return the DFS root or DFS link name, status, and target information. The Buffer parameter points to a DFS_INFO_3 structure. /// 4 /// /// Return the DFS root or DFS link name, status, GUID, time-out, and target information. The Buffer parameter points to a DFS_INFO_4 structure. /// /// 5 /// /// Return the name, status, GUID, time-out, property flags, metadata size, and number of targets for a DFS root and all links /// under the root. The Buffer parameter points to an array of DFS_INFO_5 structures. /// /// 6 /// /// Return the name, status, GUID, time-out, property flags, metadata size, DFS target information for a root or link, and a /// list of DFS targets. The Buffer parameter points to an array of DFS_INFO_6 structures. /// /// 7 /// Return the version number GUID of the DFS metadata. The Buffer parameter points to an array of DFS_INFO_7 structures. /// 8 /// /// Return the name, status, GUID, time-out, property flags, metadata size, number of targets, and link reparse point security /// descriptors for a DFS root and all links under the root. The Buffer parameter points to an array of DFS_INFO_8 structures. /// /// 9 /// /// Return the name, status, GUID, time-out, property flags, metadata size, DFS target information, link reparse point /// security descriptors, and a list of DFS targets for a root or link. The Buffer parameter points to an array of DFS_INFO_9 structures. /// /// 50 /// /// Return the DFS metadata version and capabilities of an existing DFS namespace. The Buffer parameter points to a DFS_INFO_50 structure. /// /// 100 /// Return a comment about the DFS root or DFS link. The Buffer parameter points to a DFS_INFO_100 structure. /// 150 /// Return the security descriptor for the DFS link's reparse point. The Buffer parameter points to a DFS_INFO_150 structure. /// /// Note This value is natively supported only if the DFS link resides on a server that is running Windows Server 2008 or later. /// /// /// The requested information structures. The format of this data depends on the value of the Level parameter. /// /// No special group membership is required for using the NetDfsGetInfo function. /// /// An application calling the NetDfsGetInfo function may indirectly cause the local DFS Namespace server servicing the /// function call to perform a full synchronization of the related namespace metadata from the PDC emulator master for that domain. /// This full synchronization could happen even when root scalability mode is configured for that namespace. In order to avoid this /// side-effect, if the intent is to only retrieve the physical UNC pathname used by a specific DFSN client machine corresponding a /// given DFS namespace path, then one alternative is to use the WDK API ZwQueryInformationFile, passing /// FileNetworkPhysicalNameInformation as the FileInformationClass parameter and passing the address of a caller-allocated /// FILE_NETWORK_PHYSICAL_NAME_INFORMATION structure as the FileInformation parameter. Please see the WDK for more information on /// calling WDK APIs. /// /// [PInvokeData("lmdfs.h", MSDNShortId = "bbb2f24d-1c49-4016-a16b-60fde4a78193")] public static T NetDfsGetInfo(string DfsEntryPath, [Optional] string ServerName, [Optional] string ShareName, uint Level = uint.MaxValue) where T : struct { if (Level == uint.MaxValue) Level = (uint)GetLevelFromStructure(); NetDfsGetInfo(DfsEntryPath, ServerName, ShareName, Level, out var buf).ThrowIfFailed(); return buf.ToStructure(); } /// Retrieves the security descriptor for the root object of the specified DFS namespace. /// /// Pointer to a string that specifies the Universal Naming Convention (UNC) path of a DFS namespace root. /// The string can be in one of two forms. The first form is as follows: /// \ServerName<i>DfsName /// /// where ServerName is the name of the root target server that hosts the stand-alone DFS namespace and Dfsname is the name of the /// DFS namespace. /// /// The second form is as follows: /// \DomainName<i>DomDfsName /// /// where DomainName is the name of the domain that hosts the domain-based DFS namespace and DomDfsName is the name of the DFS namespace. /// /// /// /// SECURITY_INFORMATION structure that contains bit flags that indicate the type of security information to retrieve from the root object. /// /// A list of SECURITY_DESCRIPTOR structures that contain the security items requested in the SecurityInformation parameter. /// /// /// For domain-based DFS namespaces, the security descriptor is retrieved from the /// "CN=DomDfsName,CN=DFS-Configuration,CN=System,DC=domain" object in Active Directory from the primary domain controller (PDC) of /// the domain that hosts the DFS namespace, where DomDfsName is the name of the domain-based DFS namespace and <domain> is the /// distinguished name of the Active Directory domain that hosts the namespace. /// /// /// For stand-alone roots, the security descriptor is retrieved from the object specified by the /// HKLM<b>Software<b>Microsoft<b>Dfs<b>Standalone<b><root-name> registry entry. /// /// [PInvokeData("lmdfs.h", MSDNShortId = "a6db7c82-c2ec-464a-8c05-2360622880b4")] public static AdvApi32.SafePSECURITY_DESCRIPTOR NetDfsGetSecurity(string DfsEntryPath, SECURITY_INFORMATION SecurityInformation) { NetDfsGetSecurity(DfsEntryPath, SecurityInformation, out var buf, out var len).ThrowIfFailed(); return new AdvApi32.SafePSECURITY_DESCRIPTOR(buf.ToIEnum((int)len).ToArray()); } /// Retrieves the security descriptor for the container object of the specified stand-alone DFS namespace. /// /// Pointer to a string that specifies the name of the server that hosts the stand-alone DFS namespace. /// /// SECURITY_INFORMATION structure that contains bit flags that indicate the type of security information to retrieve. /// /// A list of SECURITY_DESCRIPTOR structures that contain the security items requested in the SecurityInformation parameter. /// /// The security descriptor is retrieved from the object specified by the /// HKLM<b>Software<b>Microsoft<b>Dfs<b>Standalone key in the registry of the server specified in the /// MachineName parameter. /// [PInvokeData("lmdfs.h", MSDNShortId = "63ad610e-c66f-4fad-b3b6-2ee15e90a723")] public static AdvApi32.SafePSECURITY_DESCRIPTOR NetDfsGetStdContainerSecurity(string MachineName, SECURITY_INFORMATION SecurityInformation) { NetDfsGetStdContainerSecurity(MachineName, SecurityInformation, out var buf, out var len).ThrowIfFailed(); return new AdvApi32.SafePSECURITY_DESCRIPTOR(buf.ToIEnum((int)len).ToArray()); } /// Modifies information about a Distributed File System (DFS) root or link in the cache maintained by the DFS client. /// /// /// Pointer to a string that specifies the Universal Naming Convention (UNC) path of a DFS root or link. /// For a link, the string can be in one of two forms. The first form is as follows: /// \ServerName<i>DfsName<i>link_path /// /// where ServerName is the name of the root target server that hosts the stand-alone DFS namespace; DfsName is the name of the DFS /// namespace; and link_path is a DFS link. /// /// The second form is as follows: /// \DomainName<i>DomDfsname<i>link_path /// /// where DomainName is the name of the domain that hosts the domain-based DFS namespace; DomDfsname is the name of the DFS /// namespace; and link_path is a DFS link. /// /// For a root, the string can be in one of two forms: /// \ServerName<i>DfsName /// or /// \DomainName<i>DomDfsname /// where the values of the names are the same as those described previously. /// This parameter is required. /// /// /// Pointer to a string that specifies the DFS link target server name. This parameter is optional. For more information, see the /// Remarks section. /// /// /// Pointer to a string that specifies the DFS link target share name. This parameter is optional. For additional information, see /// the following Remarks section. /// /// /// The information to be set. The format of this information depends on the value of the Level parameter. For more information, see /// Network Management Function Buffers. /// /// /// Specifies the information level of the request. This parameter can be one of the following values. /// 101 /// Set the local DFS link's storage status. The Buffer parameter points to a DFS_INFO_101 structure. /// 102 /// /// Set the local DFS link time-out. The Buffer parameter points to a DFS_INFO_102 structure. For more information, see the following /// Remarks section. /// /// /// /// /// The caller must have Administrator privilege on the DFS server. For more information about calling functions that require /// administrator privileges, see Running with Special Privileges. /// /// /// Setting the time-out to zero may not immediately delete the local cached copy of the DFS link, because threads may be referencing /// the entry. /// /// Because there is only one time-out on a DFS link, the ServerName and ShareName parameters are ignored for level 102. /// /// The DFS_STORAGE_STATE_ONLINE and DFS_STORAGE_STATE_OFFLINE bits will be ignored. The /// DFS_STORAGE_STATE_ACTIVE bit is valid only if no files are open to the active computer. /// /// [PInvokeData("lmdfs.h", MSDNShortId = "4c95dffb-a092-45ad-9a3f-37d3abbf4427")] public static void NetDfsSetClientInfo(string DfsEntryPath, [Optional] string ServerName, string ShareName, in T Buffer, uint Level = uint.MaxValue) where T : struct { var mem = SafeHGlobalHandle.CreateFromStructure(Buffer); if (Level == uint.MaxValue) Level = (uint)GetLevelFromStructure(); NetDfsSetClientInfo(DfsEntryPath, ServerName, ShareName, Level, mem).ThrowIfFailed(); } /// Sets or modifies information about a specific Distributed File System (DFS) root, root target, link, or link target. /// /// /// Pointer to a string that specifies the Universal Naming Convention (UNC) path of a DFS root or link. /// For a link, the string can be in one of two forms. The first form is as follows: /// \ServerName<i>DfsName<i>link_path /// /// where ServerName is the name of the root target server that hosts the stand-alone DFS namespace; DfsName is the name of the DFS /// namespace; and link_path is a DFS link. /// /// The second form is as follows: /// \DomainName<i>DomDfsname<i>link_path /// /// where DomainName is the name of the domain that hosts the domain-based DFS namespace; DomDfsname is the name of the DFS /// namespace; and link_path is a DFS link. /// /// For a root, the string can be in one of two forms: /// \ServerName<i>DfsName /// or /// \DomainName<i>DomDfsname /// where the values of the names are the same as those described previously. /// /// /// Pointer to a string that specifies the DFS link target server name. This parameter is optional. For more information, see the /// Remarks section. /// /// /// Pointer to a string that specifies the DFS link target share name. This may also be a share name with a path relative to the /// share. For example, "share1\mydir1\mydir2". This parameter is optional. For more information, see the Remarks section. /// /// /// The data. The format of this data depends on the value of the Level parameter. For more information, see Network Management /// Function Buffers. /// /// /// Specifies the information level of the data. This parameter can be one of the following values. /// 100 /// /// Set the comment associated with the DFS root or link specified in the DfsEntryPath parameter. The Buffer parameter points to a /// DFS_INFO_100 structure. /// /// 101 /// /// Set the storage state associated with the DFS root or link specified in the DfsEntryPath parameter. The Buffer parameter points /// to a DFS_INFO_101 structure. /// /// 102 /// /// Set the time-out value associated with the DFS root or link specified in the DfsEntryPath parameter. The Buffer parameter points /// to a DFS_INFO_102 structure. /// /// 103 /// /// Set the property flags for the DFS root or link specified in the DfsEntryPath parameter. The Buffer parameter points to a /// DFS_INFO_103 structure. /// /// 104 /// /// Set the target priority rank and class for the root target or link target specified in the DfsEntryPath parameter. The Buffer /// parameter points to a DFS_INFO_104 structure. /// /// 105 /// /// Set the comment, state, and time-out information, as well as property flags, for the DFS root or link specified in the /// DfsEntryPath parameter. The Buffer parameter points to a DFS_INFO_105 structure. /// /// 106 /// /// Set the target state and priority for the root target or link target specified in the DfsEntryPath parameter. This information /// cannot be set for a DFS namespace root or link, only for a root target or link target. The Buffer parameter points to a /// DFS_INFO_106 structure. /// /// 107 /// /// Set the comment, state, time-out information, and property flags for the DFS root or link specified in the DfsEntryPath /// parameter. For DFS links, you can also set the security descriptor for the link's reparse point. The Buffer parameter points to a /// DFS_INFO_107 structure. /// /// 150 /// Set the security descriptor for a DFS link's reparse point. The Buffer parameter points to a DFS_INFO_150 structure. /// /// /// /// The caller must have Administrator privilege on the DFS server. For more information about calling functions that require /// administrator privileges, see Running with Special Privileges. /// /// /// If you specify both the ServerName and ShareName parameters, the NetDfsSetInfo function sets or modifies information /// specific to that root target or link target. If the parameters are NULL, the function sets or modifies information that is /// specific to the DFS namespace root or the DFS link instead of a specific DFS root target or link target. /// /// /// Because only one comment and one time-out can be set for a DFS root or link, the ServerName and ShareName parameters are ignored /// for information levels 100 and 102. These parameters are required for level 101. /// /// /// For information level 101, the DFS_VOLUME_STATE_RESYNCHRONIZE and DFS_VOLUME_STATE_STANDBY state values can be set /// as follows for a specific domain-based DFS root when there is more than one DFS root target for the DFS namespace: /// /// /// The DfsEntryPath parameter specifies the domain-based DFS namespace, and the ServerName and ShareName parameters taken together /// specify the DFS root target on which the set-information operation is to be performed. /// /// [PInvokeData("lmdfs.h", MSDNShortId = "5526afa7-82bc-47c7-99d6-44e41ef772b1")] public static void NetDfsSetInfo(string DfsEntryPath, [Optional] string ServerName, string ShareName, in T Buffer, uint Level = uint.MaxValue) where T : struct { var mem = SafeHGlobalHandle.CreateFromStructure(Buffer); if (Level == uint.MaxValue) Level = (uint)GetLevelFromStructure(); NetDfsSetInfo(DfsEntryPath, ServerName, ShareName, Level, mem).ThrowIfFailed(); } /// The NetEnumerateComputerNames function enumerates names for the specified computer. /// /// A pointer to a constant string that specifies the name of the computer on which to execute this function. If this parameter is /// , the local computer is used. /// /// /// /// The type of the name queried. This member can be one of the following values defined in the NET_COMPUTER_NAME_TYPE /// enumeration defined in the Lmjoin.h header file. /// /// /// /// Value /// Meaning /// /// /// NetPrimaryComputerName /// The primary computer name. /// /// /// NetAlternateComputerNames /// Alternate computer names. /// /// /// NetAllComputerNames /// All computer names. /// /// /// NetComputerNameTypeMax /// Indicates the end of the range that specifies the possible values for the type of name to be queried. /// /// /// /// /// If the function call is successful, this parameter will return the computer names that match the computer type name specified in /// the NameType parameter. /// /// /// The NetEnumerateComputerNames function is supported on Windows Vista and later. /// The NetEnumerateComputerNames function is used to request the names a computer currently has configured. /// /// The NetEnumerateComputerNames function requires that the caller is a member of the Administrators local group on the /// target computer. /// /// // https://docs.microsoft.com/en-us/windows/desktop/api/lmjoin/nf-lmjoin-netenumeratecomputernames NET_API_STATUS NET_API_FUNCTION // NetEnumerateComputerNames( LPCWSTR Server, NET_COMPUTER_NAME_TYPE NameType, ULONG Reserved, PDWORD EntryCount, LPWSTR // **ComputerNames ); [PInvokeData("lmjoin.h", MSDNShortId = "c657ae33-404e-4c36-a956-5fbcfa540be7")] public static IEnumerable NetEnumerateComputerNames([Optional] string Server, NET_COMPUTER_NAME_TYPE NameType = NET_COMPUTER_NAME_TYPE.NetAllComputerNames) { NetEnumerateComputerNames(Server, NameType, 0, out var c, out var buf).ThrowIfFailed(); return buf.ToStringEnum((int)c); } /// Returns information about some or all open files on a server, depending on the parameters specified. /// The expected return type of the enumerated element. /// /// /// A string that specifies the DNS or NetBIOS name of the remote server on which the function is to execute. If this parameter is /// , the local computer is used. /// /// This string is Unicode if _WIN32_WINNT or FORCE_UNICODE is defined. /// /// /// /// A string that specifies a qualifier for the returned information. If this parameter is , all open resources /// are enumerated. If this parameter is not , the function enumerates only resources that have the value of /// the basepath parameter as a prefix. (A prefix is the portion of a path that comes before a backslash.) /// /// This string is Unicode if _WIN32_WINNT or FORCE_UNICODE is defined. /// /// /// /// A string that specifies the name of the user or the name of the connection. If the string begins with two backslashes ("\"), then /// it indicates the name of the connection, for example, "\127.0.0.1" or "\ClientName". The part of the connection name after the /// backslashes is the same as the client name in the session information structure returned by the NetSessionEnum function. If the /// string does not begin with two backslashes, then it indicates the name of the user. If this parameter is not /// , its value serves as a qualifier for the enumeration. The files returned are limited to those that have /// user names or connection names that match the qualifier. If this parameter is , no user-name qualifier is used. /// /// /// Windows Server 2008, Windows Vista, Windows Server 2003 and Windows XP: This parameter is a pointer to a string that /// specifies the name of the user. If this parameter is not , its value serves as a qualifier for the /// enumeration. The files returned are limited to those that have user names matching the qualifier. If this parameter is /// , no user-name qualifier is used. /// /// This string is Unicode if _WIN32_WINNT or FORCE_UNICODE is defined. /// /// /// Specifies the information level of the data. This parameter can be one of the following values. /// /// /// Value /// Meaning /// /// /// 2 /// Return the file identification number. The return value is an array of FILE_INFO_2 structures. /// /// /// 3 /// Return information about the file. The return value is an array of FILE_INFO_3 structures. /// /// /// /// An enumeration of files. The format of this data depends on the value of the level parameter. /// /// Only members of the Administrators or Server Operators local group can successfully execute the NetFileEnum function. /// You can call the NetFileGetInfo function to retrieve information about a particular opening of a server resource. /// /// If you are programming for Active Directory, you may be able to call certain Active Directory Service Interface (ADSI) methods to /// achieve the same functionality you can achieve by calling NetFileEnum. For more information, see IADsResource and IADsFileServiceOperations. /// /// [PInvokeData("lmshare.h", MSDNShortId = "1375b337-efb0-4be1-94f7-473456a825b5")] public static IEnumerable NetFileEnum([Optional] string servername, [Optional] string basepath, [Optional] string username, uint level = uint.MaxValue) where T : struct { if (level == uint.MaxValue) level = (uint)GetLevelFromStructure(); var h = IntPtr.Zero; NetFileEnum(servername, basepath, username, level, out var buf, MAX_PREFERRED_LENGTH, out var cnt, out var _, ref h).ThrowIfFailed(); return buf.ToIEnum((int)cnt); } /// Retrieves information about a particular opening of a server resource. /// The expected return type associated with the . /// /// A string that specifies the DNS or NetBIOS name of the remote server on which the function is to execute. If this parameter is /// , the local computer is used. /// /// /// Specifies the file identifier of the open resource for which to return information. The value of this parameter must have been /// returned in a previous enumeration call. For more information, see the following Remarks section. /// /// /// Specifies the information level of the data. This parameter can be one of the following values. /// /// /// Value /// Meaning /// /// /// 2 /// Return the file identification number. The bufptr parameter is a pointer to a FILE_INFO_2 structure. /// /// /// 3 /// /// Return the file identification number and other information about the file. The bufptr parameter is a pointer to a FILE_INFO_3 structure. /// /// /// /// /// The format of this structure depends on the value of the parameter. /// /// /// Only members of the Administrators or Server Operators local group can successfully execute the NetFileGetInfo function. /// /// You can call the NetFileEnum function to retrieve information about multiple files open on a server. /// /// If you are programming for Active Directory, you may be able to call certain Active Directory Service Interface (ADSI) methods to /// achieve the same functionality you can achieve by calling NetFileGetInfo. For more information, see IADsResource and IADsFileServiceOperations. /// /// [PInvokeData("lmshare.h", MSDNShortId = "d50c05e7-7ddd-4a7d-96f6-51878e52373c")] public static T NetFileGetInfo([Optional] string servername, uint fileid, uint level = uint.MaxValue) where T : struct { if (level == uint.MaxValue) level = (uint)GetLevelFromStructure(); NetFileGetInfo(servername, fileid, level, out var buf).ThrowIfFailed(); return buf.ToStructure(); } /// /// The NetGetJoinableOUs function retrieves a list of organizational units (OUs) in which a computer account can be created. /// /// A string that specifies the name of the domain for which to retrieve the list of OUs that can be joined. /// /// A string that specifies the DNS or NetBIOS name of the computer on which to call the function. If this parameter is /// , the local computer is used. /// /// /// A string that specifies the account name to use when connecting to the domain controller. The string must specify either a domain /// NetBIOS name and user account (for example, "REDMOND\user") or the user principal name (UPN) of the user in the form of an /// Internet-style login name (for example, "someone@example.com"). If this parameter is , the caller's context /// is used. /// /// /// If the lpAccount parameter specifies an account name, this parameter must point to the password to use when connecting to the /// domain controller. Otherwise, this parameter must be . /// /// The list of joinable OUs. /// /// No special group membership is required to successfully execute the NetGetJoinableOUs function. /// For more information about organizational units, see Managing Users in the Active Directory documentation. /// [PInvokeData("lmjoin.h", MSDNShortId = "1faa912b-c56d-431c-95d5-d36790b0d467")] public static IEnumerable NetGetJoinableOUs(string lpDomain, [Optional] string lpServer, [Optional] string lpAccount, [Optional] string lpPassword) { NetGetJoinableOUs(lpServer, lpDomain, lpAccount, lpPassword, out var cnt, out var buf).ThrowIfFailed(); return buf.ToStringEnum((int)cnt); } /// /// The NetGroupAdd function creates a global group in the security database, which is the security accounts manager (SAM) /// database or, in the case of domain controllers, the Active Directory. /// /// /// /// Pointer to a constant string that specifies the DNS or NetBIOS name of the remote server on which the function is to execute. If /// this parameter is NULL, the local computer is used. /// /// /// The data. The format of this data depends on the value of the level parameter. For more information, see Network Management /// Function Buffers. /// /// /// Specifies the information level of the data. This parameter can be one of the following values. /// /// /// Value /// Meaning /// /// /// 0 /// Specifies a global group name. The buf parameter contains a pointer to a GROUP_INFO_0 structure. /// /// /// 1 /// Specifies a global group name and a comment. The buf parameter contains a pointer to a GROUP_INFO_1 structure. /// /// /// 2 /// /// Specifies detailed information about the global group. The buf parameter contains a pointer to a GROUP_INFO_2 structure. Note /// that on Windows XP and later, it is recommended that you use GROUP_INFO_3 instead. /// /// /// /// 3 /// /// Specifies detailed information about the global group. The buf parameter contains a pointer to a GROUP_INFO_3 structure. Windows /// 2000: This level is not supported. /// /// /// /// /// /// /// If you are programming for Active Directory, you may be able to call certain Active Directory Service Interface (ADSI) methods to /// achieve the same functionality you can achieve by calling the network management group functions. For more information, see IADsGroup. /// /// /// If you call this function on a domain controller that is running Active Directory, access is allowed or denied based on the /// access control list (ACL) for the securable object. The default ACL permits only Domain Admins and Account Operators to call this /// function. On a member server or workstation, only Administrators and Power Users can call this function. For more information, /// see Security Requirements for the Network Management Functions. For more information on ACLs, ACEs, and access tokens, see Access /// Control Model. /// /// /// The security descriptor of the user container is used to perform the access check for this function. The caller must be able to /// create child objects of the group class. Typically, callers must also have write access to the entire object for calls to this /// function to succeed. /// /// /// User account names are limited to 20 characters and group names are limited to 256 characters. In addition, account names cannot /// be terminated by a period and they cannot include commas or any of the following printable characters: ", /, , [, ], :, |, <, /// >, +, =, ;, ?, *. Names also cannot include characters in the range 1-31, which are non-printable. /// /// [PInvokeData("lmaccess.h", MSDNShortId = "fbf90758-79fd-4959-b6d0-ad3872e77242")] public static void NetGroupAdd([In, Optional] string servername, in T buf, uint level = uint.MaxValue) where T : struct { if (level == uint.MaxValue) level = (uint)GetLevelFromStructure(); var mem = SafeHGlobalHandle.CreateFromStructure(buf); var err = NetGroupAdd(servername, level, mem, out var perr); if (err.Succeeded) return; if (err != Win32Error.ERROR_INVALID_PARAMETER) err.ThrowIfFailed(); throw err.GetException($"Invalid parameter. Index: {perr}"); } /// /// /// The NetGroupEnum function retrieves information about each global group in the security database, which is the security /// accounts manager (SAM) database or, in the case of domain controllers, the Active Directory. /// /// /// The NetQueryDisplayInformation function provides an efficient mechanism for enumerating global groups. When possible, it is /// recommended that you use NetQueryDisplayInformation instead of the NetGroupEnum function. /// /// /// /// /// Pointer to a constant string that specifies the DNS or NetBIOS name of the remote server on which the function is to execute. If /// this parameter is NULL, the local computer is used. /// /// /// Specifies the information level of the data. This parameter can be one of the following values. /// /// /// Value /// Meaning /// /// /// 0 /// Return the global group name. The bufptr parameter points to an array of GROUP_INFO_0 structures. /// /// /// 1 /// Return the global group name and a comment. The bufptr parameter points to an array of GROUP_INFO_1 structures. /// /// /// 2 /// /// Return detailed information about the global group. The bufptr parameter points to an array of GROUP_INFO_2 structures. Note that /// on Windows XP and later, it is recommended that you use GROUP_INFO_3 instead. /// /// /// /// 3 /// /// Return detailed information about the global group. The bufptr parameter points to an array of GROUP_INFO_3 structures. Windows /// 2000: This level is not supported. /// /// /// /// /// The global group information structure. The format of this data depends on the value of the level parameter. /// /// /// If you are programming for Active Directory, you may be able to call certain Active Directory Service Interface (ADSI) methods to /// achieve the same functionality you can achieve by calling the network management group functions. For more information, see IADsGroup. /// /// /// If you call this function on a domain controller that is running Active Directory, access is allowed or denied based on the /// access control list (ACL) for the securable object. The default ACL permits all authenticated users and members of the /// "Pre-Windows 2000 compatible access" group to view the information. If you call this function on a member server or workstation, /// all authenticated users can view the information. For information about anonymous access and restricting anonymous access on /// these platforms, see Security Requirements for the Network Management Functions. For more information on ACLs, ACEs, and access /// tokens, see Access Control Model. /// /// /// The function only returns information to which the caller has Read access. The caller must have List Contents access to the /// Domain object, and Enumerate Entire SAM Domain access on the SAM Server object located in the System container. /// /// /// To determine the exact total number of groups, you must enumerate the entire tree, which can be a costly operation. To enumerate /// the entire tree, use the resume_handle parameter to continue the enumeration for consecutive calls, and use the entriesread /// parameter to accumulate the total number of groups. If your application is communicating with a domain controller, you should /// consider using the ADSI LDAP Provider to retrieve this type of data more efficiently. The ADSI LDAP Provider implements a set of /// ADSI objects that support various ADSI interfaces. For more information, see ADSI Service Providers. /// /// /// User account names are limited to 20 characters and group names are limited to 256 characters. In addition, account names cannot /// be terminated by a period and they cannot include commas or any of the following printable characters: ", /, , [, ], :, |, <, /// >, +, =, ;, ?, *. Names also cannot include characters in the range 1-31, which are non-printable. /// /// [PInvokeData("lmaccess.h", MSDNShortId = "3f8fabce-94cb-41f5-9af1-04585ac3f16e")] public static IEnumerable NetGroupEnum([Optional] string servername, uint level = uint.MaxValue) where T : struct { if (level == uint.MaxValue) level = (uint)GetLevelFromStructure(); var h = IntPtr.Zero; NetGroupEnum(servername, level, out var buf, MAX_PREFERRED_LENGTH, out var cnt, out var _, ref h).ThrowIfFailed(); return buf.ToIEnum((int)cnt); } /// /// The NetGroupGetInfo function retrieves information about a particular global group in the security database, which is the /// security accounts manager (SAM) database or, in the case of domain controllers, the Active Directory. /// /// /// /// Pointer to a constant string that specifies the DNS or NetBIOS name of the remote server on which the function is to execute. If /// this parameter is NULL, the local computer is used. /// /// /// Pointer to a constant string that specifies the name of the global group for which to retrieve information. For more information, /// see the following Remarks section. /// /// /// Specifies the information level of the data. This parameter can be one of the following values. /// /// /// Value /// Meaning /// /// /// 0 /// Return the global group name. The bufptr parameter points to a GROUP_INFO_0 structure. /// /// /// 1 /// Return the global group name and a comment. The bufptr parameter points to a GROUP_INFO_1 structure. /// /// /// 2 /// /// Return detailed information about the global group. The bufptr parameter points to a GROUP_INFO_2 structure. Note that on Windows /// XP and later, it is recommended that you use GROUP_INFO_3 instead. /// /// /// /// 3 /// /// Return detailed information about the global group. The bufptr parameter points to a GROUP_INFO_3 structure. Windows 2000: This /// level is not supported. /// /// /// /// /// The global group information structure. The format of this data depends on the value of the level parameter. /// /// /// If you are programming for Active Directory, you may be able to call certain Active Directory Service Interface (ADSI) methods to /// achieve the same functionality you can achieve by calling the network management group functions. For more information, see IADsGroup. /// /// /// If you call this function on a domain controller that is running Active Directory, access is allowed or denied based on the /// access control list (ACL) for the securable object. The default ACL permits all authenticated users and members of the /// "Pre-Windows 2000 compatible access" group to view the information. If you call this function on a member server or workstation, /// all authenticated users can view the information. For information about anonymous access and restricting anonymous access on /// these platforms, see Security Requirements for the Network Management Functions. For more information on ACLs, ACEs, and access /// tokens, see Access Control Model. /// /// The security descriptor of the Group object is used to perform the access check for this function. /// /// User account names are limited to 20 characters and group names are limited to 256 characters. In addition, account names cannot /// be terminated by a period and they cannot include commas or any of the following printable characters: ", /, , [, ], :, |, <, /// >, +, =, ;, ?, *. Names also cannot include characters in the range 1-31, which are non-printable. /// /// [PInvokeData("lmaccess.h", MSDNShortId = "f9957c15-9a49-4b53-ae31-efd6a03417a6")] public static T NetGroupGetInfo([Optional] string servername, string groupname, uint level = uint.MaxValue) where T : struct { if (level == uint.MaxValue) level = (uint)GetLevelFromStructure(); NetGroupGetInfo(servername, groupname, level, out var buf).ThrowIfFailed(); return buf.ToStructure(); } /// /// The NetGroupGetUsers function retrieves a list of the members in a particular global group in the security database, which /// is the security accounts manager (SAM) database or, in the case of domain controllers, the Active Directory. /// /// /// /// A pointer to a constant string that specifies the DNS or NetBIOS name of the remote server on which the function is to execute. /// If this parameter is NULL, the local computer is used. /// /// /// A pointer to a constant string that specifies the name of the global group whose members are to be listed. For more information, /// see the following Remarks section. /// /// /// The information level of the data requested. This parameter can be one of the following values. /// /// /// Value /// Meaning /// /// /// 0 /// Return the global group's member names. The bufptr parameter points to an array of GROUP_USERS_INFO_0 structures. /// /// /// 1 /// Return the global group's member names and attributes. The bufptr parameter points to an array of GROUP_USERS_INFO_1 structures. /// /// /// /// The information structure. /// /// /// If you call this function on a domain controller that is running Active Directory, access is allowed or denied based on the /// access control list (ACL) for the securable object. The default ACL permits all authenticated users and members of the /// "Pre-Windows 2000 compatible access" group to view the information. If you call this function on a member server or workstation, /// all authenticated users can view the information. For information about anonymous access and restricting anonymous access on /// these platforms, see Security Requirements for the Network Management Functions. For more information on ACLs, ACEs, and access /// tokens, see Access Control Model. /// /// The security descriptor of the Group object is used to perform the access check for this function. /// /// To grant one user membership in an existing global group, you can call the NetGroupAddUser function. To remove a user from a /// global group, call the NetGroupDelUser function. For information about replacing the membership of a global group, see NetGroupSetUsers. /// /// /// User account names are limited to 20 characters and group names are limited to 256 characters. In addition, account names cannot /// be terminated by a period and they cannot include commas or any of the following printable characters: ", /, , [, ], :, |, <, /// >, +, =, ;, ?, *. Names also cannot include characters in the range 1-31, which are non-printable. /// /// /// If you are programming for Active Directory, you may be able to call certain Active Directory Service Interface (ADSI) methods to /// achieve the same functionality you can achieve by calling the network management group functions. For more information, see IADsGroup. /// /// [PInvokeData("lmaccess.h", MSDNShortId = "a9bcb806-f44c-4db2-9644-06687b31405d")] public static IEnumerable NetGroupGetUsers([Optional] string servername, string groupname, uint level = uint.MaxValue) where T : struct { if (level == uint.MaxValue) level = (uint)GetLevelFromStructure(); var h = IntPtr.Zero; NetGroupGetUsers(servername, groupname, level, out var buf, MAX_PREFERRED_LENGTH, out var cnt, out var _, ref h).ThrowIfFailed(); return buf.ToIEnum((int)cnt); } /// /// The NetGroupSetInfo function sets the parameters of a global group in the security database, which is the security /// accounts manager (SAM) database or, in the case of domain controllers, the Active Directory. /// /// /// /// Pointer to a constant string that specifies the DNS or NetBIOS name of the remote server on which the function is to execute. If /// this parameter is NULL, the local computer is used. /// /// /// Pointer to a constant string that specifies the name of the global group for which to set information. For more information, see /// the following Remarks section. /// /// /// The data. The format of this data depends on the value of the level parameter. For more information, see Network Management /// Function Buffers. /// /// /// Specifies the information level of the data. This parameter can be one of the following values. /// /// /// Value /// Meaning /// /// /// 0 /// Specifies a global group name. The buf parameter points to a GROUP_INFO_0 structure. /// /// /// 1 /// Specifies a global group name and a comment. The buf parameter points to a GROUP_INFO_1 structure. /// /// /// 2 /// /// Specifies detailed information about the global group. The buf parameter points to a GROUP_INFO_2 structure. Note that on Windows /// XP and later, it is recommended that you use GROUP_INFO_3 instead. /// /// /// /// 3 /// /// Specifies detailed information about the global group. The buf parameter points to a GROUP_INFO_3 structure. Windows 2000: This /// level is not supported. /// /// /// /// 1002 /// Specifies a comment only about the global group. The buf parameter points to a GROUP_INFO_1002 structure. /// /// /// 1005 /// Specifies global group attributes. The buf parameter points to a GROUP_INFO_1005 structure. /// /// /// For more information, see the following Remarks section. /// /// /// /// If you are programming for Active Directory, you may be able to call certain Active Directory Service Interface (ADSI) methods to /// achieve the same functionality you can achieve by calling the network management group functions. For more information, see IADsGroup. /// /// /// If you call this function on a domain controller that is running Active Directory, access is allowed or denied based on the /// access control list (ACL) for the securable object. The default ACL permits only Domain Admins and Account Operators to call this /// function. On a member server or workstation, only Administrators and Power Users can call this function. For more information, /// see Security Requirements for the Network Management Functions. For more information on ACLs, ACEs, and access tokens, see Access /// Control Model. /// /// /// The security descriptor of the Group object is used to perform the access check for this function. Typically, callers must have /// write access to the entire object for calls to this function to succeed. /// /// /// The correct way to set the new name of a global group is to call the NetGroupSetInfo function, using a GROUP_INFO_0 /// structure. Specify the new value in the grpi0_name member. If you use a GROUP_INFO_1 structure and specify the value in /// the grpi1_name member, the new name value is ignored. /// /// /// If the NetGroupSetInfo function returns ERROR_INVALID_PARAMETER, you can use the parm_err parameter to indicate the first /// member of the group information structure that is invalid. (A group information structure begins with GROUP_INFO_ and its format /// is specified by the level parameter.) The following table lists the values that can be returned in the parm_err parameter and the /// corresponding structure member that is in error. (The prefix grpi*_ indicates that the member can begin with multiple prefixes, /// for example, grpi1_ or grpi2_.) /// /// /// /// Value /// Member /// /// /// GROUP_NAME_PARMNUM /// grpi*_name /// /// /// GROUP_COMMENT_PARMNUM /// grpi*_comment /// /// /// GROUP_ATTRIBUTES_PARMNUM /// grpi*_attributes /// /// /// /// User account names are limited to 20 characters and group names are limited to 256 characters. In addition, account names cannot /// be terminated by a period and they cannot include commas or any of the following printable characters: ", /, , [, ], :, |, <, /// >, +, =, ;, ?, *. Names also cannot include characters in the range 1-31, which are non-printable. /// /// [PInvokeData("lmaccess.h", MSDNShortId = "8c235f9a-095e-4108-9b93-008ffe9bc776")] public static void NetGroupSetInfo([Optional] string servername, string groupname, in T buf, uint level = uint.MaxValue) where T : struct { if (level == uint.MaxValue) level = (uint)GetLevelFromStructure(); var mem = SafeHGlobalHandle.CreateFromStructure(buf); var err = NetGroupSetInfo(servername, groupname, level, mem, out var perr); if (err.Succeeded) return; if (err != Win32Error.ERROR_INVALID_PARAMETER) err.ThrowIfFailed(); throw err.GetException($"Invalid parameter. Index: {perr}"); } /// /// The NetGroupSetUsers function sets the membership for the specified global group. Each user you specify is enrolled as a /// member of the global group. Users you do not specify, but who are currently members of the global group, will have their /// membership revoked. /// /// /// /// A pointer to a constant string that specifies the DNS or NetBIOS name of the remote server on which the function is to execute. /// If this parameter is NULL, the local computer is used. /// /// /// A pointer to a constant string that specifies the name of the global group of interest. For more information, see the Remarks section. /// /// The data. For more information, see Network Management Function Buffers. /// /// The information level of the data. This parameter can be one of the following values. /// /// /// Value /// Meaning /// /// /// 0 /// The buf parameter points to an array of GROUP_USERS_INFO_0 structures that specify user names. /// /// /// 1 /// /// The buf parameter points to an array of GROUP_USERS_INFO_1 structures that specifies user names and the attributes of the group. /// /// /// /// /// /// /// If you call this function on a domain controller that is running Active Directory, access is allowed or denied based on the /// access control list (ACL) for the securable object. The default ACL permits only Domain Admins and Account Operators to call this /// function. On a member server or workstation, only Administrators and Power Users can call this function. For more information, /// see Security Requirements for the Network Management Functions. For more information on ACLs, ACEs, and access tokens, see Access /// Control Model. /// /// The security descriptor of the Group object is used to perform the access check for this function. /// /// You can replace the global group membership with an entirely new list of members by calling the NetGroupSetUsers function. /// The typical sequence of steps to perform this follows. /// /// To replace the global group membership /// /// /// Call the NetGroupGetUsers function to retrieve the current membership list. /// /// /// Modify the returned membership list to reflect the new membership. /// /// /// Call the NetGroupSetUsers function to replace the old membership list with the new membership list. /// /// /// /// To grant one user membership in an existing global group, you can call the NetGroupAddUser function. To remove a user from a /// global group, call the NetGroupDelUser function. /// /// /// User account names are limited to 20 characters and group names are limited to 256 characters. In addition, account names cannot /// be terminated by a period and they cannot include commas or any of the following printable characters: ", /, , [, ], :, |, <, /// >, +, =, ;, ?, *. Names also cannot include characters in the range 1-31, which are non-printable. /// /// /// If you are programming for Active Directory, you may be able to call certain Active Directory Service Interface (ADSI) methods to /// achieve the same functionality you can achieve by calling the network management group functions. For more information, see IADsGroup. /// /// [PInvokeData("lmaccess.h", MSDNShortId = "4221f5c8-a71c-4368-9be4-9562063b6cfd")] public static void NetGroupSetUsers([Optional] string servername, string groupname, T[] buf, uint level = uint.MaxValue) where T : struct { if (level == uint.MaxValue) level = (uint)GetLevelFromStructure(); using var mem = SafeHGlobalHandle.CreateFromList(buf); NetGroupSetUsers(servername, groupname, level, mem, (uint)buf.Length).ThrowIfFailed(); } /// /// The NetLocalGroupAdd function creates a local group in the security database, which is the security accounts manager (SAM) /// database or, in the case of domain controllers, the Active Directory. /// /// /// /// A pointer to a string that specifies the DNS or NetBIOS name of the remote server on which the function is to execute. If this /// parameter is NULL, the local computer is used. /// /// /// The local group information structure. The format of this data depends on the value of the level parameter. For more information, /// see Network Management Function Buffers. /// /// /// The information level of the data. This parameter can be one of the following values. /// /// /// Value /// Meaning /// /// /// 0 /// A local group name. The buf parameter points to a LOCALGROUP_INFO_0 structure. /// /// /// 1 /// A local group name and a comment to associate with the group. The buf parameter points to a LOCALGROUP_INFO_1 structure. /// /// /// /// /// /// If you call this function on a domain controller that is running Active Directory, access is allowed or denied based on the /// access control list (ACL) for the securable object. The default ACL permits only Domain Admins and Account Operators to call this /// function. On a member server or workstation, only Administrators and Power Users can call this function. For more information, /// see Security Requirements for the Network Management Functions. For more information on ACLs, ACEs, and access tokens, see Access /// Control Model. /// /// /// The security descriptor of the user container is used to perform the access check for this function. The caller must be able to /// create child objects of the group class. /// /// /// User account names are limited to 20 characters and group names are limited to 256 characters. In addition, account names cannot /// be terminated by a period and they cannot include commas or any of the following printable characters: ", /, , [, ], :, |, <, /// >, +, =, ;, ?, *. Names also cannot include characters in the range 1-31, which are non-printable. /// /// /// If the NetLocalGroupAdd function returns ERROR_INVALID_PARAMETER and a NULL pointer was not passed in /// parm_err parameter, on return the parm_err parameter indicates the first member of the local group information structure that is /// invalid. The format of the local group information structure is specified in the level parameter. A pointer to the local group /// information structure is passed in buf parameter. The following table lists the values that can be returned in the parm_err /// parameter and the corresponding structure member that is in error. /// /// /// /// Value /// Member /// /// /// LOCALGROUP_NAME_PARMNUM /// /// If the level parameter was 0, the lgrpi0_name member of the LOCALGROUP_INFO_0 structure was invalid. If the level parameter was /// 1, the lgrpi1_name member of the LOCALGROUP_INFO_1 structure was invalid. /// /// /// /// LOCALGROUP_COMMENT_PARMNUM /// If the level parameter was 1, the lgrpi1_comment member of the LOCALGROUP_INFO_1 structure was invalid. /// /// /// /// When making requests to a domain controller and Active Directory, you may be able to call certain Active Directory Service /// Interface (ADSI) methods to achieve the same results as the network management local group functions. For more information, see IADsGroup. /// /// [PInvokeData("lmaccess.h", MSDNShortId = "5028c1bc-8fed-4f02-8e69-d0d122b08d9f")] public static void NetLocalGroupAdd([Optional] string servername, in T buf, uint level = uint.MaxValue) where T : struct { if (level == uint.MaxValue) level = (uint)GetLevelFromStructure(); var mem = SafeHGlobalHandle.CreateFromStructure(buf); var err = NetLocalGroupAdd(servername, level, mem, out var perr); if (err.Succeeded) return; if (err != Win32Error.ERROR_INVALID_PARAMETER) err.ThrowIfFailed(); throw err.GetException($"Invalid parameter. Index: {perr}"); } /// /// The NetLocalGroupAddMembers function adds membership of one or more existing user accounts or global group accounts to an /// existing local group. The function does not change the membership status of users or global groups that are currently members of /// the local group. /// /// /// /// Pointer to a constant string that specifies the DNS or NetBIOS name of the remote server on which the function is to execute. If /// this parameter is NULL, the local computer is used. /// /// /// Pointer to a constant string that specifies the name of the local group to which the specified users or global groups will be /// added. For more information, see the following Remarks section. /// /// /// The data for the new local group members. The format of this data depends on the value of the level parameter. For more /// information, see Network Management Function Buffers. /// /// /// Specifies the information level of the data. This parameter can be one of the following values. /// /// /// Value /// Meaning /// /// /// 0 /// /// Specifies the security identifier (SID) of the new local group member. The buf parameter points to an array of /// LOCALGROUP_MEMBERS_INFO_0 structures. /// /// /// /// 3 /// /// Specifies the domain and name of the new local group member. The buf parameter points to an array of LOCALGROUP_MEMBERS_INFO_3 structures. /// /// /// /// /// /// /// If you call this function on a domain controller that is running Active Directory, access is allowed or denied based on the /// access control list (ACL) for the securable object. The default ACL permits only Domain Admins and Account Operators to call this /// function. On a member server or workstation, only Administrators and Power Users can call this function. For more information, /// see Security Requirements for the Network Management Functions. For more information on ACLs, ACEs, and access tokens, see Access /// Control Model. /// /// The security descriptor of the LocalGroup object is used to perform the access check for this function. /// /// User account names are limited to 20 characters and group names are limited to 256 characters. In addition, account names cannot /// be terminated by a period and they cannot include commas or any of the following printable characters: ", /, , [, ], :, |, <, /// >, +, =, ;, ?, *. Names also cannot include characters in the range 1-31, which are non-printable. /// /// /// If you are programming for Active Directory, you may be able to call certain Active Directory Service Interface (ADSI) methods to /// achieve the same functionality you can achieve by calling the network management local group functions. For more information, see IADsGroup. /// /// [PInvokeData("lmaccess.h", MSDNShortId = "3b2d3e4a-742e-4e67-8b28-3cd6d7e6a857")] public static void NetLocalGroupAddMembers([Optional] string servername, string groupname, T[] buf, uint level = uint.MaxValue) where T : struct { if (level == uint.MaxValue) level = (uint)GetLevelFromStructure(); using var mem = SafeHGlobalHandle.CreateFromList(buf); NetLocalGroupAddMembers(servername, groupname, level, mem, (uint)buf.Length).ThrowIfFailed(); } /// /// The NetLocalGroupDelMembers function removes one or more members from an existing local group. Local group members can be /// users or global groups. /// /// /// /// Pointer to a constant string that specifies the DNS or NetBIOS name of the remote server on which the function is to execute. If /// this parameter is NULL, the local computer is used. /// /// /// Pointer to a constant string that specifies the name of the local group from which the specified users or global groups will be /// removed. For more information, see the following Remarks section. /// /// /// The members to be removed. The format of this data depends on the value of the level parameter. For more information, see Network /// Management Function Buffers. /// /// /// Specifies the information level of the data. This parameter can be one of the following values. /// /// /// Value /// Meaning /// /// /// 0 /// /// Specifies the security identifier (SID) of a local group member to remove. The buf parameter points to an array of /// LOCALGROUP_MEMBERS_INFO_0 structures. /// /// /// /// 3 /// /// Specifies the domain and name of a local group member to remove. The buf parameter points to an array of /// LOCALGROUP_MEMBERS_INFO_3 structures. /// /// /// /// /// /// /// If you call this function on a domain controller that is running Active Directory, access is allowed or denied based on the /// access control list (ACL) for the securable object. The default ACL permits only Domain Admins and Account Operators to call this /// function. On a member server or workstation, only Administrators and Power Users can call this function. For more information, /// see Security Requirements for the Network Management Functions. For more information on ACLs, ACEs, and access tokens, see Access /// Control Model. /// /// The security descriptor of the LocalGroup object is used to perform the access check for this function. /// /// User account names are limited to 20 characters and group names are limited to 256 characters. In addition, account names cannot /// be terminated by a period and they cannot include commas or any of the following printable characters: ", /, , [, ], :, |, <, /// >, +, =, ;, ?, *. Names also cannot include characters in the range 1-31, which are non-printable. /// /// /// If you are programming for Active Directory, you may be able to call certain Active Directory Service Interface (ADSI) methods to /// achieve the same functionality you can achieve by calling the network management local group functions. For more information, see IADsGroup. /// /// [PInvokeData("lmaccess.h", MSDNShortId = "85ae796b-c94a-46a8-9fa8-6c612db38671")] public static void NetLocalGroupDelMembers([Optional] string servername, string groupname, T[] buf, uint level = uint.MaxValue) where T : struct { if (level == uint.MaxValue) level = (uint)GetLevelFromStructure(); using var mem = SafeHGlobalHandle.CreateFromList(buf); NetLocalGroupDelMembers(servername, groupname, level, mem, (uint)buf.Length).ThrowIfFailed(); } /// The NetLocalGroupEnum function returns information about each local group account on the specified server. /// /// /// Pointer to a constant string that specifies the DNS or NetBIOS name of the remote server on which the function is to execute. If /// this parameter is NULL, the local computer is used. /// /// /// Specifies the information level of the data. This parameter can be one of the following values. /// /// /// Value /// Meaning /// /// /// 0 /// Return local group names. The bufptr parameter points to an array of LOCALGROUP_INFO_0 structures. /// /// /// 1 /// /// Return local group names and the comment associated with each group. The bufptr parameter points to an array of LOCALGROUP_INFO_1 structures. /// /// /// /// /// The information structure. The format of this data depends on the value of the level parameter. /// /// /// If you call this function on a domain controller that is running Active Directory, access is allowed or denied based on the /// access control list (ACL) for the securable object. The default ACL permits all authenticated users and members of the /// "Pre-Windows 2000 compatible access" group to view the information. If you call this function on a member server or workstation, /// all authenticated users can view the information. For information about anonymous access and restricting anonymous access on /// these platforms, see Security Requirements for the Network Management Functions. For more information on ACLs, ACEs, and access /// tokens, see Access Control Model. /// /// /// The function only returns information to which the caller has Read access. The caller must have List Contents access to the /// Domain object, and Enumerate Entire SAM Domain access on the SAM Server object located in the System container. /// /// /// To determine the exact total number of local groups, you must enumerate the entire tree, which can be a costly operation. To /// enumerate the entire tree, use the resumehandle parameter to continue the enumeration for consecutive calls, and use the /// entriesread parameter to accumulate the total number of local groups. If your application is communicating with a domain /// controller, you should consider using the ADSI LDAP Provider to retrieve this type of data more efficiently. The ADSI LDAP /// Provider implements a set of ADSI objects that support various ADSI interfaces. For more information, see ADSI Service Providers. /// /// /// User account names are limited to 20 characters and group names are limited to 256 characters. In addition, account names cannot /// be terminated by a period and they cannot include commas or any of the following printable characters: ", /, , [, ], :, |, <, /// >, +, =, ;, ?, *. Names also cannot include characters in the range 1-31, which are non-printable. /// /// /// If you are programming for Active Directory, you may be able to call certain Active Directory Service Interface (ADSI) methods to /// achieve the same functionality you can achieve by calling the network management local group functions. For more information, see IADsGroup. /// /// [PInvokeData("lmaccess.h", MSDNShortId = "fc27d7f1-bfbe-46d7-a154-f04eb9249248")] public static IEnumerable NetLocalGroupEnum([Optional] string servername, uint level = uint.MaxValue) where T : struct { if (level == uint.MaxValue) level = (uint)GetLevelFromStructure(); var h = IntPtr.Zero; NetLocalGroupEnum(servername, level, out var buf, MAX_PREFERRED_LENGTH, out var cnt, out var _, ref h).ThrowIfFailed(); return buf.ToIEnum((int)cnt); } /// The NetLocalGroupGetInfo function retrieves information about a particular local group account on a server. /// /// /// Pointer to a constant string that specifies the DNS or NetBIOS name of the remote server on which the function is to execute. If /// this parameter is NULL, the local computer is used. /// /// /// Pointer to a constant string that specifies the name of the local group account for which the information will be retrieved. For /// more information, see the following Remarks section. /// /// /// Specifies the information level of the data. This parameter can be the following value. /// /// /// Value /// Meaning /// /// /// 1 /// Return the comment associated with the local group. The bufptr parameter points to a LOCALGROUP_INFO_1 structure. /// /// /// /// The return information structure. /// /// /// If you call this function on a domain controller that is running Active Directory, access is allowed or denied based on the /// access control list (ACL) for the securable object. The default ACL permits all authenticated users and members of the /// "Pre-Windows 2000 compatible access" group to view the information. If you call this function on a member server or workstation, /// all authenticated users can view the information. For information about anonymous access and restricting anonymous access on /// these platforms, see Security Requirements for the Network Management Functions. For more information on ACLs, ACEs, and access /// tokens, see Access Control Model. /// /// The security descriptor of the LocalGroup object is used to perform the access check for this function. /// /// User account names are limited to 20 characters and group names are limited to 256 characters. In addition, account names cannot /// be terminated by a period and they cannot include commas or any of the following printable characters: ", /, , [, ], :, |, <, /// >, +, =, ;, ?, *. Names also cannot include characters in the range 1-31, which are non-printable. /// /// /// If you are programming for Active Directory, you may be able to call certain Active Directory Service Interface (ADSI) methods to /// achieve the same functionality you can achieve by calling the network management local group functions. For more information, see IADsGroup. /// /// [PInvokeData("lmaccess.h", MSDNShortId = "ee2f0be9-8d52-439b-ab65-f9e11a2872c5")] public static T NetLocalGroupGetInfo([Optional] string servername, string groupname, uint level = uint.MaxValue) where T : struct { if (level == uint.MaxValue) level = (uint)GetLevelFromStructure(); NetLocalGroupGetInfo(servername, groupname, level, out var buf).ThrowIfFailed(); return buf.ToStructure(); } /// /// The NetLocalGroupGetMembers function retrieves a list of the members of a particular local group in the security database, /// which is the security accounts manager (SAM) database or, in the case of domain controllers, the Active Directory. Local group /// members can be users or global groups. /// /// /// /// Pointer to a constant string that specifies the DNS or NetBIOS name of the remote server on which the function is to execute. If /// this parameter is NULL, the local computer is used. /// /// /// Pointer to a constant string that specifies the name of the local group whose members are to be listed. For more information, see /// the following Remarks section. /// /// /// Specifies the information level of the data. This parameter can be one of the following values. /// /// /// Value /// Meaning /// /// /// 0 /// /// Return the security identifier (SID) associated with the local group member. The bufptr parameter points to an array of /// LOCALGROUP_MEMBERS_INFO_0 structures. /// /// /// /// 1 /// /// Return the SID and account information associated with the local group member. The bufptr parameter points to an array of /// LOCALGROUP_MEMBERS_INFO_1 structures. /// /// /// /// 2 /// /// Return the SID, account information, and the domain name associated with the local group member. The bufptr parameter points to /// an array of LOCALGROUP_MEMBERS_INFO_2 structures. /// /// /// /// 3 /// /// Return the account and domain names of the local group member. The bufptr parameter points to an array of /// LOCALGROUP_MEMBERS_INFO_3 structures. /// /// /// /// /// The return information structures. The format of this data depends on the value of the level parameter. /// /// /// If you call this function on a domain controller that is running Active Directory, access is allowed or denied based on the /// access control list (ACL) for the securable object. The default ACL permits all authenticated users and members of the /// "Pre-Windows 2000 compatible access" group to view the information. If you call this function on a member server or workstation, /// all authenticated users can view the information. For information about anonymous access and restricting anonymous access on /// these platforms, see Security Requirements for the Network Management Functions. For more information on ACLs, ACEs, and access /// tokens, see Access Control Model. /// /// The security descriptor of the LocalGroup object is used to perform the access check for this function. /// /// User account names are limited to 20 characters and group names are limited to 256 characters. In addition, account names cannot /// be terminated by a period and they cannot include commas or any of the following printable characters: ", /, , [, ], :, |, <, /// >, +, =, ;, ?, *. Names also cannot include characters in the range 1-31, which are non-printable. /// /// /// If you are programming for Active Directory, you may be able to call certain Active Directory Service Interface (ADSI) methods to /// achieve the same functionality you can achieve by calling the network management local group functions. For more information, see IADsGroup. /// /// /// If this function returns ERROR_MORE_DATA, then it must be repeatedly called until ERROR_SUCCESS or /// NERR_success is returned. Failure to do so can result in an RPC connection leak. /// /// [PInvokeData("lmaccess.h", MSDNShortId = "35770b32-dae9-46f5-84e3-1c31ca22f708")] public static IEnumerable NetLocalGroupGetMembers([Optional] string servername, string localgroupname, uint level = uint.MaxValue) where T : struct { if (level == uint.MaxValue) level = (uint)GetLevelFromStructure(); var h = IntPtr.Zero; NetLocalGroupGetMembers(servername, localgroupname, level, out var buf, MAX_PREFERRED_LENGTH, out var cnt, out var _, ref h).ThrowIfFailed(); return buf.ToIEnum((int)cnt); } /// /// The NetLocalGroupSetInfo function changes the name of an existing local group. The function also associates a comment with /// a local group. /// /// /// /// Pointer to a constant string that specifies the DNS or NetBIOS name of the remote server on which the function is to execute. If /// this parameter is NULL, the local computer is used. /// /// /// Pointer to a constant string that specifies the name of the local group account to modify. For more information, see the /// following Remarks section. /// /// /// The local group information. The format of this data depends on the value of the level parameter. For more information, see /// Network Management Function Buffers. /// /// /// Specifies the information level of the data. This parameter can be one of the following values. /// /// /// Value /// Meaning /// /// /// 0 /// /// Specifies the local group name. The buf parameter points to a LOCALGROUP_INFO_0 structure. Use this level to change the name of /// an existing local group. /// /// /// /// 1 /// /// Specifies the local group name and a comment to associate with the group. The buf parameter points to a LOCALGROUP_INFO_1 structure. /// /// /// /// 1002 /// Specifies a comment to associate with the local group. The buf parameter points to a LOCALGROUP_INFO_1002 structure. /// /// /// /// /// /// If you call this function on a domain controller that is running Active Directory, access is allowed or denied based on the /// access control list (ACL) for the securable object. The default ACL permits only Domain Admins and Account Operators to call this /// function. On a member server or workstation, only Administrators and Power Users can call this function. For more information, /// see Security Requirements for the Network Management Functions. For more information on ACLs, ACEs, and access tokens, see Access /// Control Model. /// /// /// The security descriptor of the LocalGroup object is used to perform the access check for this function. Typically, callers must /// have write access to the entire object for calls to this function to succeed. /// /// /// To specify the new name of an existing local group, call NetLocalGroupSetInfo with LOCALGROUP_INFO_0 and specify a value /// using the lgrpi0_name member. If you call the NetLocalGroupSetInfo function with LOCALGROUP_INFO_1 and specify a /// new value using the lgrpi1_name member, that value will be ignored. /// /// /// If the NetLocalGroupSetInfo function returns ERROR_INVALID_PARAMETER, you can use the parm_err parameter to indicate the /// first member of the local group information structure that is invalid. (A local group information structure begins with /// LOCALGROUP_INFO_ and its format is specified by the level parameter.) The following table lists the values that can be returned /// in the parm_err parameter and the corresponding structure member that is in error. (The prefix lgrpi*_ indicates that the member /// can begin with multiple prefixes, for example, lgrpi0_ or lgrpi1_.) /// /// /// /// Value /// Member /// /// /// LOCALGROUP_NAME_PARMNUM /// lgrpi*_name /// /// /// LOCALGROUP_COMMENT_PARMNUM /// lgrpi*_comment /// /// /// /// User account names are limited to 20 characters and group names are limited to 256 characters. In addition, account names cannot /// be terminated by a period and they cannot include commas or any of the following printable characters: ", /, , [, ], :, |, <, /// >, +, =, ;, ?, *. Names also cannot include characters in the range 1-31, which are non-printable. /// /// /// If you are programming for Active Directory, you may be able to call certain Active Directory Service Interface (ADSI) methods to /// achieve the same functionality you can achieve by calling the network management local group functions. For more information, see IADsGroup. /// /// [PInvokeData("lmaccess.h", MSDNShortId = "c1d2a68b-0910-4815-9547-0f0f3c983164")] public static void NetLocalGroupSetInfo([Optional] string servername, string groupname, in T buf, uint level = uint.MaxValue) where T : struct { if (level == uint.MaxValue) level = (uint)GetLevelFromStructure(); var mem = SafeHGlobalHandle.CreateFromStructure(buf); var err = NetLocalGroupSetInfo(servername, groupname, level, mem, out var perr); if (err.Succeeded) return; if (err != Win32Error.ERROR_INVALID_PARAMETER) err.ThrowIfFailed(); throw err.GetException($"Invalid parameter. Index: {perr}"); } /// /// The NetLocalGroupSetMembers function sets the membership for the specified local group. Each user or global group /// specified is made a member of the local group. Users or global groups that are not specified but who are currently members of the /// local group will have their membership revoked. /// /// /// /// Pointer to a constant string that specifies the DNS or NetBIOS name of the remote server on which the function is to execute. If /// this parameter is NULL, the local computer is used. /// /// /// Pointer to a constant string that specifies the name of the local group in which the specified users or global groups should be /// granted membership. For more information, see the following Remarks section. /// /// /// The member information. The format of this data depends on the value of the level parameter. For more information, see Network /// Management Function Buffers. /// /// /// Specifies the information level of the data. This parameter can be one of the following values. /// /// /// Value /// Meaning /// /// /// 0 /// /// Specifies the security identifier (SID) associated with a local group member. The buf parameter points to an array of /// LOCALGROUP_MEMBERS_INFO_0 structures. /// /// /// /// 3 /// /// Specifies the account and domain names of the local group member. The buf parameter points to an array of /// LOCALGROUP_MEMBERS_INFO_3 structures. /// /// /// /// /// /// /// If you call this function on a domain controller that is running Active Directory, access is allowed or denied based on the /// access control list (ACL) for the securable object. The default ACL permits only Domain Admins and Account Operators to call this /// function. On a member server or workstation, only Administrators and Power Users can call this function. For more information, /// see Security Requirements for the Network Management Functions. For more information on ACLs, ACEs, and access tokens, see Access /// Control Model. /// /// The security descriptor of the LocalGroup object is used to perform the access check for this function. /// /// You can replace the local group membership with an entirely new list of members by calling the NetLocalGroupSetMembers /// function. The typical sequence of steps to perform this follows. /// /// To replace the local group membership /// /// /// Call the NetLocalGroupGetMembers function to retrieve the current membership list. /// /// /// Modify the returned membership list to reflect the new membership. /// /// /// Call the NetLocalGroupSetMembers function to replace the old membership list with the new membership list. /// /// /// /// To add one or more existing user accounts or global group accounts to an existing local group, you can call the /// NetLocalGroupAddMembers function. To remove one or more members from an existing local group, call the NetLocalGroupDelMembers function. /// /// /// User account names are limited to 20 characters and group names are limited to 256 characters. In addition, account names cannot /// be terminated by a period and they cannot include commas or any of the following printable characters: ", /, , [, ], :, |, <, /// >, +, =, ;, ?, *. Names also cannot include characters in the range 1-31, which are non-printable. /// /// /// If you are programming for Active Directory, you may be able to call certain Active Directory Service Interface (ADSI) methods to /// achieve the same functionality you can achieve by calling the network management local group functions. For more information, see IADsGroup. /// /// [PInvokeData("lmaccess.h", MSDNShortId = "4dce1e10-b74d-4d69-ac5a-12e7d9d84e5c")] public static void NetLocalGroupSetMembers([Optional] string servername, string groupname, T[] buf, uint level = uint.MaxValue) where T : struct { if (level == uint.MaxValue) level = (uint)GetLevelFromStructure(); using var mem = SafeHGlobalHandle.CreateFromList(buf); NetLocalGroupSetMembers(servername, groupname, level, mem, (uint)buf.Length).ThrowIfFailed(); } /// /// [ NetScheduleJobEnum is no longer available for use as of Windows 8. Instead, use the Task Scheduler 2.0 Interfaces. /// ] /// /// The NetScheduleJobEnum function lists the jobs queued on a specified computer. This function requires that the schedule /// service be started. /// /// /// /// A pointer to a constant string that specifies the DNS or NetBIOS name of the remote server on which the function is to execute. /// If this parameter is NULL, the local computer is used. /// /// The data. The return information is an array of AT_ENUM structures. /// /// /// Normally only members of the local Administrators group on the computer where the schedule job is being enumerated can /// successfully execute this function. If the server name passed in the string pointed to by the Servername parameter is a remote /// server, then only members of the local Administrators group on the server can successfully execute this function. /// /// /// If the following registry value has the least significant bit set (for example, 0x00000001), then users belonging to the Server /// Operators group can also successfully execute this function. /// /// HKLM\System\CurrentControlSet\Control\Lsa\SubmitControl /// /// Each entry returned contains an AT_ENUM structure. The value of the JobId member can be used when calling functions that /// require a job identifier parameter, such as the NetScheduleJobDel function. /// /// [PInvokeData("lmat.h", MSDNShortId = "e3384414-6a15-4979-bed4-6f94f046474a")] public static IEnumerable NetScheduleJobEnum([Optional] string Servername) { var h = 0U; NetScheduleJobEnum(Servername, out var buf, MAX_PREFERRED_LENGTH, out var cnt, out var _, ref h).ThrowIfFailed(); return buf.ToIEnum((int)cnt); } /// /// [ NetScheduleJobGetInfo is no longer available for use as of Windows 8. Instead, use the Task Scheduler 2.0 Interfaces. /// ] /// /// The NetScheduleJobGetInfo function retrieves information about a particular job queued on a specified computer. This /// function requires that the schedule service be started. /// /// /// /// A pointer to a constant string that specifies the DNS or NetBIOS name of the remote server on which the function is to execute. /// If this parameter is NULL, the local computer is used. /// /// A value that indicates the identifier of the job for which to retrieve information. /// The AT_INFO structure describing the specified job. /// /// /// Normally only members of the local Administrators group on the computer where the schedule job is being enumerated can /// successfully execute this function. If the server name passed in the string pointed to by the Servername parameter is a remote /// server, then only members of the local Administrators group on the server can successfully execute this function. /// /// /// If the following registry value has the least significant bit set (for example, 0x00000001), then users belonging to the Server /// Operators group can also successfully execute this function. /// /// HKLM\System\CurrentControlSet\Control\Lsa\SubmitControl /// [PInvokeData("lmat.h", MSDNShortId = "44589715-edab-4737-9e49-6f491fd44c28")] public static AT_INFO NetScheduleJobGetInfo([Optional] string Servername, uint JobId) { NetScheduleJobGetInfo(Servername, JobId, out var buf).ThrowIfFailed(); return buf.ToStructure(); } /// /// The NetServerDiskEnum function retrieves a list of disk drives on a server. The function returns an array of /// three-character strings (a drive letter, a colon, and a terminating null character). /// /// /// A pointer to a string that specifies the DNS or NetBIOS name of the remote server on which the function is to execute. If this /// parameter is , the local computer is used. /// /// A sequence of strings (a drive letter followed by a colon). /// /// /// Only members of the Administrators or Server Operators local group can successfully execute the NetServerDiskEnum function /// on a remote computer. /// /// /// If you are programming for Active Directory, you may be able to call certain Active Directory Service Interface (ADSI) methods to /// achieve the same results you can achieve by calling the network management server functions. For more information, see the /// IADsComputer interface reference. /// /// [PInvokeData("lmserver.h", MSDNShortId = "56c981f4-7a1d-4465-bd7b-5996222c4210")] public static IEnumerable NetServerDiskEnum([Optional] string servername) { var h = 0U; NetServerDiskEnum(servername, 0, out var buf, MAX_PREFERRED_LENGTH, out var cnt, out var _, ref h).ThrowIfFailed(); var ptr = buf.DangerousGetHandle(); var chSz = StringHelper.GetCharSize(); for (var i = 0; i < cnt; i++) { yield return StringHelper.GetString(ptr); ptr = ptr.Offset(3 * chSz); } } /// The NetServerEnum function lists all servers of the specified type that are visible in a domain. /// The type of the structure to have filled in for each server. This must be SERVER_INFO_100 or SERVER_INFO_101. /// A value that filters the server entries to return from the enumeration. /// /// A string that specifies the name of the domain for which a list of servers is to be returned. The domain name must be a NetBIOS /// domain name (for example, Microsoft). The NetServerEnum function does not support DNS-style names (for example, microsoft.com). /// If this parameter is NULL, the primary domain is implied. /// /// /// The information level of the data requested. If this value is 0, then the method will extract all digits to form the level (e.g. /// SERVER_INFO_101 produces 101). /// /// A managed array of the requested type. public static IEnumerable NetServerEnum(NetServerEnumFilter netServerEnumFilter = NetServerEnumFilter.SV_TYPE_WORKSTATION | NetServerEnumFilter.SV_TYPE_SERVER, string domain = null, int level = 0) where T : struct, INetServerInfo { if (level == 0) level = GetLevelFromStructure(); if (level != 100 && level != 101) throw new ArgumentOutOfRangeException(nameof(level), @"Only SERVER_INFO_100 or SERVER_INFO_101 are supported as valid structures."); var resumeHandle = IntPtr.Zero; NetServerEnum(null, (uint)level, out var bufptr, MAX_PREFERRED_LENGTH, out var entriesRead, out _, netServerEnumFilter, domain, resumeHandle).ThrowIfFailed(); return bufptr.ToIEnum((int)entriesRead); } /// The NetServerGetInfo function retrieves current configuration information for the specified server. /// /// The type of the structure to have filled in for each server. This must be SERVER_INFO_100, SERVER_INFO_101, or SERVER_INFO_102. /// /// /// A string that specifies the name of the remote server on which the function is to execute. If this parameter is NULL, the local /// computer is used. /// /// /// The information level of the data requested. If this value is 0, then the method will extract all digits to form the level (e.g. /// SERVER_INFO_101 produces 101). /// /// The requested type with returned information about the server. public static T NetServerGetInfo([Optional] string serverName, int level = 0) where T : struct, INetServerInfo { if (level == 0) level = GetLevelFromStructure(); if (level != 100 && level != 101 && level != 102) throw new ArgumentOutOfRangeException(nameof(level), @"Only SERVER_INFO_100, SERVER_INFO_101, or SERVER_INFO_102 are supported as valid structures."); NetServerGetInfo(serverName, level, out var ptr).ThrowIfFailed(); return ptr.DangerousGetHandle().ToStructure(); } /// /// The NetServerTransportEnum function supplies information about transport protocols that are managed by the server. /// /// /// A string that specifies the DNS or NetBIOS name of the remote server on which the function is to execute. If this parameter is /// , the local computer is used. /// /// /// Specifies the information level of the data. This parameter can be one of the following values. /// /// /// Value /// Meaning /// /// /// 0 /// /// Return information about the transport protocol, including name, address, and location on the network. The bufptr parameter /// points to an array of SERVER_TRANSPORT_INFO_0 structures. /// /// /// /// 1 /// /// Return information about the transport protocol, including name, address, network location, and domain. The bufptr parameter /// points to an array of SERVER_TRANSPORT_INFO_1 structures. /// /// /// /// /// The data sequence. The format of this data depends on the value of the level parameter. /// /// /// Only Authenticated Users can successfully call this function. Windows XP/2000: No special group membership is required to /// successfully execute this function. /// /// Examples /// /// The following code sample demonstrates how to retrieve information about transport protocols that are managed by the server, /// using a call to the NetServerTransportEnum function. The sample calls NetServerTransportEnum, specifying /// information level 0 ( SERVER_TRANSPORT_INFO_0). The sample prints the name of each transport protocol and the total number /// enumerated. Finally, the code sample frees the memory allocated for the information buffer. /// /// [PInvokeData("lmserver.h", MSDNShortId = "db42ac44-d70d-4b89-882a-6ac83fd611fd")] public static IEnumerable NetServerTransportEnum([Optional] string servername, int level = -1) where T : struct { if (level == -1) level = GetLevelFromStructure(); var h = 0U; NetServerTransportEnum(servername, level, out var buf, MAX_PREFERRED_LENGTH, out var cnt, out var _, ref h).ThrowIfFailed(); return buf.ToIEnum((int)cnt); } /// Provides information about sessions established on a server. /// The expected element return type associated with the . /// /// A string that specifies the DNS or NetBIOS name of the remote server on which the function is to execute. If this parameter is /// , the local computer is used. /// /// /// A string that specifies the name of the computer session for which information is to be returned. If this parameter is /// , NetSessionEnum returns information for all computer sessions on the server. /// /// /// A string that specifies the name of the user for which information is to be returned. If this parameter is /// , NetSessionEnum returns information for all users. /// /// /// /// Specifies the information level of the data. This parameter can be one of the following values. If /// omitted or , this value will be extracted from the last digits of the name of . /// /// /// /// Value /// Meaning /// /// /// 0 /// Return the name of the computer that established the session. The return value is an array of SESSION_INFO_0 structures. /// /// /// 1 /// /// Return the name of the computer, name of the user, and open files, pipes, and devices on the computer. The bufptr parameter /// points to an array of SESSION_INFO_1 structures. /// /// /// /// 2 /// /// In addition to the information indicated for level 1, return the type of client and how the user established the session. The /// return value is an array of SESSION_INFO_2 structures. /// /// /// /// 10 /// /// Return the name of the computer, name of the user, and active and idle times for the session. The return value is an array of /// SESSION_INFO_10 structures. /// /// /// /// 502 /// /// Return the name of the computer; name of the user; open files, pipes, and devices on the computer; and the name of the transport /// the client is using. The return value is an array of SESSION_INFO_502 structures. /// /// /// /// /// This resulting list of sessions. The format of this data depends on the value of the parameter. /// /// /// Only members of the Administrators or Server Operators local group can successfully execute the NetSessionEnum function at /// level 1 or level 2. No special group membership is required for level 0 or level 10 calls. /// /// /// If you are programming for Active Directory, you may be able to call certain Active Directory Service Interface (ADSI) methods to /// achieve the same functionality you can achieve by calling the network management session functions. For more information, see /// IADsSession and IADsFileServiceOperations. /// /// Examples /// /// The following code sample demonstrates how to retrieve information about current sessions using a call to the /// NetSessionEnum function. The sample calls NetSessionEnum, specifying information level 10 ( SESSION_INFO_10). The /// sample loops through the entries and prints the retrieved information. Finally, the code prints the total number of sessions /// enumerated and frees the memory allocated for the information buffer. /// /// [PInvokeData("lmshare.h", MSDNShortId = "5923a8cc-bf7a-4ffa-b089-fd7f26ee42d2")] public static IEnumerable NetSessionEnum([Optional] string servername, [Optional] string UncClientName, [Optional] string username, uint level = uint.MaxValue) where T : struct { if (level == uint.MaxValue) level = (uint)GetLevelFromStructure(); var h = 0U; NetSessionEnum(servername, UncClientName, username, level, out var buf, MAX_PREFERRED_LENGTH, out var cnt, out var _, ref h).ThrowIfFailed(); return buf.ToIEnum((int)cnt); } /// Retrieves information about a session established between a particular server and workstation. /// The expected return type associated with the . /// /// A string that specifies the DNS or NetBIOS name of the remote server on which the function is to execute. If this parameter is /// , the local computer is used. /// /// /// A string that specifies the name of the computer session for which information is to be returned. This parameter is required and /// cannot be . For more information, see NetSessionEnum. /// /// /// A string that specifies the name of the user whose session information is to be returned. This parameter is required and cannot /// be . /// /// /// Specifies the information level of the data. This parameter can be one of the following values. /// /// /// Value /// Meaning /// /// /// 0 /// Return the name of the computer that established the session. The return value is a SESSION_INFO_0 structure. /// /// /// 1 /// /// Return the name of the computer, name of the user, and open files, pipes, and devices on the computer. The return value is a /// SESSION_INFO_1 structure. /// /// /// /// 2 /// /// In addition to the information indicated for level 1, return the type of client and how the user established the session. The /// return value is a SESSION_INFO_2 structure. /// /// /// /// 10 /// /// Return the name of the computer; name of the user; and active and idle times for the session. The return value is a /// SESSION_INFO_10 structure. /// /// /// /// /// The data. The format of this data depends on the value of the level parameter. /// /// /// Only members of the Administrators or Server Operators local group can successfully execute the NetSessionGetInfo function /// at level 1 or level 2. No special group membership is required for level 0 or level 10 calls. /// /// /// If you are programming for Active Directory, you may be able to call certain Active Directory Service Interface (ADSI) methods to /// achieve the same functionality you can achieve by calling the network management session functions. For more information, see /// IADsSession and IADsFileServiceOperations. /// /// /// If you call this function at information level 1 or 2 on a member server or workstation, all authenticated users can view the information. /// /// Examples /// /// The following code sample demonstrates how to retrieve information about a session using a call to the NetSessionGetInfo /// function. The sample calls NetSessionGetInfo, specifying information level 10 ( SESSION_INFO_10). If the call succeeds, /// the code prints information about the session. Finally, the sample frees the memory allocated for the information buffer. /// /// [PInvokeData("lmshare.h", MSDNShortId = "d44fb8d8-2b64-4268-8603-7784e2c5f2d5")] public static T NetSessionGetInfo([Optional] string servername, string UncClientName, string username, uint level = uint.MaxValue) where T : struct { if (level == uint.MaxValue) level = (uint)GetLevelFromStructure(); NetSessionGetInfo(servername, UncClientName, username, level, out var buf).ThrowIfFailed(); return buf.ToStructure(); } /// Shares a server resource. /// The data structure used to describe the share. /// /// A string that specifies the DNS or NetBIOS name of the remote server on which the function is to execute. If this parameter is /// , the local computer is used. /// /// Value that specifies the data. The format of this data depends on the value of the level parameter. /// /// Specifies the information level of the data. This parameter can be one of the following values. /// /// /// Value /// Meaning /// /// /// 2 /// /// Specifies information about the shared resource, including the name of the resource, type and permissions, and number of /// connections. The buf parameter points to a SHARE_INFO_2 structure. /// /// /// /// 502 /// /// Specifies information about the shared resource, including the name of the resource, type and permissions, number of connections, /// and other pertinent information. The buf parameter points to a SHARE_INFO_502 structure. /// /// /// /// 503 /// /// Specifies information about the shared resource, including the name of the resource, type and permissions, number of connections, /// and other pertinent information. The buf parameter points to a SHARE_INFO_503 structure. /// /// /// /// /// /// /// This function applies only to Server Message Block (SMB) shares. For other types of shares, such as Distributed File System (DFS) /// or WebDAV shares, use Windows Networking (WNet) functions, which support all types of shares. /// /// /// Only members of the Administrators, System Operators, or Power Users local group can add file shares with a call to the /// NetShareAdd function. The Print Operator can add printer shares. /// /// /// If you are programming for Active Directory, you may be able to call certain Active Directory Service Interface (ADSI) methods to /// achieve the same functionality you can achieve by calling the network management share functions. For more information, see IADsFileShare. /// /// /// If 503 is specified for the level parameter, the remote server specified in the shi503_servername member of the /// SHARE_INFO_503 structure must have been bound to a transport protocol using the NetServerTransportAddEx function. In the call to /// NetServerTransportAddEx, either 2 or 3 must have been specified for the level parameter, and the SVTI2_SCOPED_NAME /// flag must have been specified in the SERVER_TRANSPORT_INFO_2 structure for the transport protocol. /// /// [PInvokeData("lmshare.h", MSDNShortId = "8b51c155-24e8-4d39-b818-eb2d1bb0ee8b")] public static void NetShareAdd([Optional] string servername, in T buf, uint level = uint.MaxValue) where T : struct { if (level == uint.MaxValue) level = (uint)GetLevelFromStructure(); var mem = SafeHGlobalHandle.CreateFromStructure(buf); var err = NetShareAdd(servername, level, mem, out var perr); if (err.Succeeded) return; if (err != Win32Error.ERROR_INVALID_PARAMETER) err.ThrowIfFailed(); throw err.GetException($"Invalid parameter. Index: {perr}"); } /// /// Retrieves information about each shared resource on a server. /// /// You can also use the WNetEnumResource function to retrieve resource information. However, WNetEnumResource does not /// enumerate hidden shares or users connected to a share. /// /// /// The expected element return type associated with the . /// /// A string that specifies the DNS or NetBIOS name of the remote server on which the function is to execute. If this parameter is /// , the local computer is used. /// /// /// Specifies the information level of the data. This parameter can be one of the following values. /// /// /// Value /// Meaning /// /// /// 0 /// Return share names. The return value is an array of SHARE_INFO_0 structures. /// /// /// 1 /// /// Return information about shared resources, including the name and type of the resource, and a comment associated with the /// resource. The return value is an array of SHARE_INFO_1 structures. /// /// /// /// 2 /// /// Return information about shared resources, including name of the resource, type and permissions, password, and number of /// connections. The return value is an array of SHARE_INFO_2 structures. /// /// /// /// 502 /// /// Return information about shared resources, including name of the resource, type and permissions, number of connections, and other /// pertinent information. The return value is an array of SHARE_INFO_502 structures. Shares from different scopes are not returned. /// For more information about scoping, see the Remarks section of the documentation for the NetServerTransportAddEx function. /// /// /// /// 503 /// /// Return information about shared resources, including the name of the resource, type and permissions, number of connections, and /// other pertinent information. The return value is an array of SHARE_INFO_503 structures. Shares from all scopes are returned. If /// the shi503_servername member of this structure is "*", there is no configured server name and the NetShareEnum function /// enumerates shares for all the unscoped names. Windows Server 2003 and Windows XP: This information level is not supported. /// /// /// /// /// The data. The format of this data depends on the value of the parameter. /// /// /// This function applies only to Server Message Block (SMB) shares. For other types of shares, such as Distributed File System (DFS) /// or WebDAV shares, use Windows Networking (WNet) functions, which support all types of shares. /// /// /// For interactive users (users who are logged on locally to the machine), no special group membership is required to execute the /// NetShareEnum function. For non-interactive users, Administrator, Power User, Print Operator, or Server Operator group /// membership is required to successfully execute the NetShareEnum function at levels 2, 502, and 503. No special group /// membership is required for level 0 or level 1 calls. /// /// /// Windows Server 2003 and Windows XP: For all users, Administrator, Power User, Print Operator, or Server Operator group /// membership is required to successfully execute the NetShareEnum function at levels 2 and 502. /// /// /// To retrieve a value that indicates whether a share is the root volume in a DFS tree structure, you must call the NetShareGetInfo /// function and specify information level 1005. /// /// /// If you are programming for Active Directory, you may be able to call certain Active Directory Service Interface (ADSI) methods to /// achieve the same functionality you can achieve by calling the network management share functions. For more information, see IADsFileShare. /// /// [PInvokeData("lmshare.h", MSDNShortId = "9114c54d-3905-4d40-9162-b3ea605f6fcb")] public static IEnumerable NetShareEnum([Optional] string servername, uint level = uint.MaxValue) where T : struct { if (level == uint.MaxValue) level = (uint)GetLevelFromStructure(); var h = 0U; NetShareEnum(servername, level, out var buf, MAX_PREFERRED_LENGTH, out var cnt, out var _, ref h).ThrowIfFailed(); return buf.ToIEnum((int)cnt); } /// Retrieves information about a particular shared resource on a server. /// /// /// A string that specifies the DNS or NetBIOS name of the remote server on which the function is to execute. If this parameter is /// , the local computer is used. /// /// A string that specifies the name of the share for which to return information. /// /// Specifies the information level of the data. This parameter can be one of the following values. /// /// /// Value /// Meaning /// /// /// 0 /// Return the share name. The return value is a SHARE_INFO_0 structure. /// /// /// 1 /// /// Return information about the shared resource, including the name and type of the resource, and a comment associated with the /// resource. The return value is a SHARE_INFO_1 structure. /// /// /// /// 2 /// /// Return information about the shared resource, including name of the resource, type and permissions, password, and number of /// connections. The return value is a SHARE_INFO_2 structure. /// /// /// /// 501 /// /// Return the name and type of the resource, and a comment associated with the resource. The return value is a SHARE_INFO_501 structure. /// /// /// /// 502 /// /// Return information about the shared resource, including name of the resource, type and permissions, number of connections, and /// other pertinent information. The return value is a SHARE_INFO_502 structure. /// /// /// /// 503 /// /// Specifies information about the shared resource, including the name of the resource, type and permissions, number of connections, /// and other pertinent information. The return value is a SHARE_INFO_503 structure. If the shi503_servername member of this /// structure is "*", there is no configured server name. Windows Server 2003 and Windows XP: This information level is not supported. /// /// /// /// 1005 /// /// Return a value that indicates whether the share is the root volume in a Dfs tree structure. The return value is a SHARE_INFO_1005 structure. /// /// /// /// /// The data. The format of this data depends on the value of the parameter. /// /// /// This function applies only to Server Message Block (SMB) shares. For other types of shares, such as Distributed File System (DFS) /// or WebDAV shares, use Windows Networking (WNet) functions, which support all types of shares. /// /// /// For interactive users (users who are logged on locally to the machine), no special group membership is required to execute the /// NetShareGetInfo function. For non-interactive users, Administrator, Power User, Print Operator, or Server Operator group /// membership is required to successfully execute the NetShareEnum function at levels 2, 502, and 503. No special group membership /// is required for level 0 or level 1 calls. /// /// /// Windows Server 2003 and Windows XP: For all users, Administrator, Power User, Print Operator, or Server Operator group /// membership is required to successfully execute the NetShareGetInfo function at levels 2 and 502. /// /// /// If you are programming for Active Directory, you may be able to call certain Active Directory Service Interface (ADSI) methods to /// achieve the same functionality you can achieve by calling the network management share functions. For more information, see IADsFileShare. /// /// /// If 503 is specified for the level parameter, the remote server specified in the shi503_servername member of the /// SHARE_INFO_503 structure must have been bound to a transport protocol using the NetServerTransportAddEx function. In the call to /// NetServerTransportAddEx, either 2 or 3 must have been specified for the level parameter, and the SVTI2_SCOPED_NAME /// flag must have been specified in the SERVER_TRANSPORT_INFO_2 structure for the transport protocol. /// /// [PInvokeData("lmshare.h", MSDNShortId = "672ea208-4048-4d2f-9606-ee3e2133765b")] public static T NetShareGetInfo([Optional] string servername, string netname, uint level = uint.MaxValue) where T : struct { if (level == uint.MaxValue) level = (uint)GetLevelFromStructure(); NetShareGetInfo(servername, netname, level, out var buf).ThrowIfFailed(); return buf.ToStructure(); } /// Sets the parameters of a shared resource. /// The type of the data being set. /// /// Pointer to a string that specifies the DNS or NetBIOS name of the remote server on which the function is to execute. If this /// parameter is NULL, the local computer is used. /// /// Pointer to a string that specifies the name of the share to set information on. /// The buf. /// /// Specifies the information level of the data. This parameter can be one of the following values. /// /// /// Value /// Meaning /// /// /// 1 /// /// Specifies information about the shared resource, including the name and type of the resource, and a comment associated with the /// resource. The buf parameter points to a SHARE_INFO_1 structure. /// /// /// /// 2 /// /// Specifies information about the shared resource, including the name of the resource, type and permissions, password, and number /// of connections. The buf parameter points to a SHARE_INFO_2 structure. /// /// /// /// 502 /// /// Specifies information about the shared resource, including the name and type of the resource, required permissions, number of /// connections, and other pertinent information. The buf parameter points to a SHARE_INFO_502 structure. /// /// /// /// 503 /// /// Specifies the name of the shared resource. The buf parameter points to a SHARE_INFO_503 structure. All members of this structure /// except shi503_servername are ignored by the NetShareSetInfo function. Windows Server 2003 and Windows XP: This information level /// is not supported. /// /// /// /// 1004 /// Specifies a comment associated with the shared resource. The buf parameter points to a SHARE_INFO_1004 structure. /// /// /// 1005 /// Specifies a set of flags describing the shared resource. The buf parameter points to a SHARE_INFO_1005 structure. /// /// /// 1006 /// /// Specifies the maximum number of concurrent connections that the shared resource can accommodate. The buf parameter points to a /// SHARE_INFO_1006 structure. /// /// /// /// 1501 /// Specifies the SECURITY_DESCRIPTOR associated with the specified share. The buf parameter points to a SHARE_INFO_1501 structure. /// /// /// /// /// /// This function applies only to Server Message Block (SMB) shares. For other types of shares, such as Distributed File System (DFS) /// or WebDAV shares, use Windows Networking (WNet) functions, which support all types of shares. /// /// /// Only members of the Administrators or Power Users local group, or those with Print or Server Operator group membership, can /// successfully execute the NetShareSetInfo function. The Print Operator can set information only about Printer shares. /// /// /// If the NetShareSetInfo function returns ERROR_INVALID_PARAMETER, you can use the parm_err parameter to indicate the /// first member of the share information structure that is not valid. (A share information structure begins with SHARE_INFO_ /// and its format is specified by the level parameter.) The following table lists the values that can be returned in the parm_err /// parameter and the corresponding structure member that is in error. (The prefix shi* indicates that the member can begin /// with multiple prefixes, for example, shi2 or shi502_.) /// /// /// /// Value /// Member /// /// /// SHARE_NETNAME_PARMNUM /// shi*_netname /// /// /// SHARE_TYPE_PARMNUM /// shi*_type /// /// /// SHARE_REMARK_PARMNUM /// shi*_remark /// /// /// SHARE_PERMISSIONS_PARMNUM /// shi*_permissions /// /// /// SHARE_MAX_USES_PARMNUM /// shi*_max_uses /// /// /// SHARE_CURRENT_USES_PARMNUM /// shi*_current_uses /// /// /// SHARE_PATH_PARMNUM /// shi*_path /// /// /// SHARE_PASSWD_PARMNUM /// shi*_passwd /// /// /// SHARE_FILE_SD_PARMNUM /// shi*_security_descriptor /// /// /// /// If you are programming for Active Directory, you may be able to call certain Active Directory Service Interface (ADSI) methods to /// achieve the same functionality you can achieve by calling the network management share functions. For more information, see IADsFileShare. /// /// /// If 503 is specified for the level parameter, the remote server specified in the shi503_servername member of the /// SHARE_INFO_503 structure must have been bound to a transport protocol using the NetServerTransportAddEx function. In the call to /// NetServerTransportAddEx, either 2 or 3 must have been specified for the level parameter, and the SVTI2_SCOPED_NAME /// flag must have been specified in the SERVER_TRANSPORT_INFO_2 structure for the transport protocol. /// /// [PInvokeData("lmshare.h", MSDNShortId = "216b0b78-87da-4734-ad07-5ad1c9edf494")] public static void NetShareSetInfo([Optional] string servername, string netname, in T buf, uint level = uint.MaxValue) where T : struct { var mem = SafeHGlobalHandle.CreateFromStructure(buf); if (level == uint.MaxValue) level = (uint)GetLevelFromStructure(); var err = NetShareSetInfo(servername, netname, level, mem, out var perr); if (err.Succeeded) return; if (err != Win32Error.ERROR_INVALID_PARAMETER) err.ThrowIfFailed(); throw err.GetException($"Invalid parameter. Index: {perr}"); } /// /// The NetUseAdd function establishes a connection between the local computer and a remote server. You can specify a local /// drive letter or a printer device to connect. If you do not specify a local drive letter or printer device, the function /// authenticates the client with the server for future connections. /// /// /// /// /// The UNC name of the computer on which to execute this function. If this parameter is NULL, then the local computer is /// used. If the UncServerName parameter specified is a remote computer, then the remote computer must support remote RPC calls using /// the legacy Remote Access Protocol mechanism. /// /// This string is Unicode if _WIN32_WINNT or FORCE_UNICODE are defined. /// /// The data. The format of this data depends on the value of the Level parameter. /// /// A value that specifies the information level of the data. This parameter can be one of the following values. /// /// /// Value /// Meaning /// /// /// 1 /// /// Specifies information about the connection between a local device and a shared resource. Information includes the connection /// status and type. The Buf parameter is a pointer to a USE_INFO_1 structure. /// /// /// /// 2 /// /// Specifies information about the connection between a local device and a shared resource. Information includes the connection /// status and type, and a user name and domain name. The Buf parameter is a pointer to a USE_INFO_2 structure. /// /// /// /// /// /// You can also use the WNetAddConnection2 and WNetAddConnection3 functions to redirect a local device to a network resource. /// /// No special group membership is required to call the NetUseAdd function. This function cannot be executed on a remote /// server except in cases of downlevel compatibility. /// /// /// This function applies only to the Server Message Block (LAN Manager Workstation) client. The NetUseAdd function does not /// support Distributed File System (DFS) shares. To add a share using a different network provider (WebDAV or a DFS share, for /// example), use the WNetAddConnection2 or WNetAddConnection3 function. /// /// /// If the NetUseAdd function returns ERROR_INVALID_PARAMETER, you can use the ParmError parameter to indicate the first /// member of the information structure that is invalid. (The information structure begins with USE_INFO_ and its format is specified /// by the Level parameter.) The following table lists the values that can be returned in the ParmError parameter and the /// corresponding structure member that is in error. (The prefix ui*_ indicates that the member can begin with multiple prefixes, for /// example, ui1_ or ui2_.) /// /// /// /// Constant /// Value /// Member /// /// /// USE_LOCAL_PARMNUM /// 1 /// ui*_local /// /// /// USE_REMOTE_PARMNUM /// 2 /// ui*_remote /// /// /// USE_PASSWORD_PARMNUM /// 3 /// ui*_password /// /// /// USE_ASGTYPE_PARMNUM /// 4 /// ui*_asg_type /// /// /// USE_USERNAME_PARMNUM /// 5 /// ui*_username /// /// /// USE_DOMAINNAME_PARMNUM /// 6 /// ui*_domainname /// /// /// [PInvokeData("lmuse.h", MSDNShortId = "22550c17-003a-4f59-80f0-58fa3e286844")] public static void NetUseAdd([Optional] string servername, in T buf, uint LevelFlags = uint.MaxValue) where T : struct { if (LevelFlags == uint.MaxValue) LevelFlags = (uint)GetLevelFromStructure(); var mem = SafeHGlobalHandle.CreateFromStructure(buf); var err = NetUseAdd(servername, LevelFlags, mem, out var perr); if (err.Succeeded) return; if (err != Win32Error.ERROR_INVALID_PARAMETER) err.ThrowIfFailed(); throw err.GetException($"Invalid parameter. Index: {perr}"); } /// /// The NetUseEnum function lists all current connections between the local computer and resources on remote servers. /// You can also use the WNetOpenEnum and the WNetEnumResource functions to enumerate network resources or connections. /// /// The expected element return type associated with the . /// /// /// The UNC name of the computer on which to execute this function. If this is parameter is NULL, then the local computer is /// used. If the UncServerName parameter specified is a remote computer, then the remote computer must support remote RPC calls using /// the legacy Remote Access Protocol mechanism. /// /// This string is Unicode if _WIN32_WINNT or FORCE_UNICODE are defined. /// /// /// The information level of the data requested. This parameter can be one of the following values. /// /// /// Value /// Meaning /// /// /// 0 /// /// Specifies a local device name and the share name of a remote resource. The BufPtr parameter points to an array of USE_INFO_0 structures. /// /// /// /// 1 /// /// Specifies information about the connection between a local device and a shared resource, including connection status and type. /// The BufPtr parameter points to an array of USE_INFO_1 structures. /// /// /// /// 2 /// /// Specifies information about the connection between a local device and a shared resource. Information includes the connection /// status, connection type, user name, and domain name. The BufPtr parameter points to an array of USE_INFO_2 structures. /// /// /// /// /// The information structures. The format of this data depends on the value of the Level parameter. /// /// /// No special group membership is required to call the NetUseEnum function. This function cannot be executed on a remote /// server except in cases of downlevel compatibility using the legacy Remote Access Protocol. /// /// To retrieve information about one network connection, you can call the NetUseGetInfo function. /// /// This function applies only to the Server Message Block (LAN Manager Workstation) client. The NetUseEnum function does not /// support Distributed File System (DFS) shares. To enumerate shares using a different network provider (WebDAV or a DFS share, for /// example), use the WNetOpenEnum, WNetEnumResource, and WNetCloseEnum functions. /// /// [PInvokeData("lmuse.h", MSDNShortId = "fb527f85-baea-48e8-b837-967870834ec5")] public static IEnumerable NetUseEnum([Optional] string UncServerName, uint LevelFlags = uint.MaxValue) where T : struct { if (LevelFlags == uint.MaxValue) LevelFlags = (uint)GetLevelFromStructure(); var h = 0U; NetUseEnum(UncServerName, LevelFlags, out var buf, MAX_PREFERRED_LENGTH, out var cnt, out var _, ref h).ThrowIfFailed(); return buf.ToIEnum((int)cnt); } /// /// The NetUseGetInfo function retrieves information about a connection to a shared resource. /// You can also use the WNetGetConnection function to retrieve the name of a network resource associated with a local device. /// /// /// /// The UNC name of computer on which to execute this function. If this is parameter is NULL, then the local computer is used. /// If the UncServerName parameter specified is a remote computer, then the remote computer must support remote RPC calls using the /// legacy Remote Access Protocol mechanism. /// /// This string is Unicode if _WIN32_WINNT or FORCE_UNICODE are defined. /// /// /// A pointer to a string that specifies the name of the connection for which to return information. /// This string is Unicode if _WIN32_WINNT or FORCE_UNICODE are defined. /// /// /// The information level of the data requested. This parameter can be one of the following values. /// /// /// Value /// Meaning /// /// /// 0 /// /// Specifies a local device name and the share name of a remote resource. The BufPtr parameter is a pointer to a USE_INFO_0 structure. /// /// /// /// 1 /// /// Specifies information about the connection between a local device and a shared resource, including connection status and type. /// The BufPtr parameter is a pointer to a USE_INFO_1 structure. /// /// /// /// 2 /// /// Specifies information about the connection between a local device and a shared resource. Information includes the connection /// status, connection type, user name, and domain name. The BufPtr parameter is a pointer to a USE_INFO_2 structure. /// /// /// /// /// The data. The format of this data depends on the value of the Level parameter. /// /// /// No special group membership is required to call the NetUseGetInfo function. This function cannot be executed on a remote /// server except in cases of downlevel compatibility. /// /// /// To list all current connections between the local computer and resources on remote servers, you can call the NetUseEnum function. /// /// /// This function applies only to the Server Message Block (LAN Manager Workstation) client. The NetUseGetInfo function does /// not support Distributed File System (DFS) shares. To retrieve information for a share using a different network provider (WebDAV /// or a DFS share, for example), use the WNetGetConnection function. /// /// [PInvokeData("lmuse.h", MSDNShortId = "257875db-5ed9-4569-8dbb-5dcc7a6af95c")] public static T NetUseGetInfo([Optional] string UncServerName, string UseName, uint LevelFlags = uint.MaxValue) where T : struct { if (LevelFlags == uint.MaxValue) LevelFlags = (uint)GetLevelFromStructure(); NetUseGetInfo(UncServerName, UseName, LevelFlags, out var buf).ThrowIfFailed(); return buf.ToStructure(); } /// The NetUserAdd function adds a user account and assigns a password and privilege level. /// /// /// /// Pointer to a constant string that specifies the DNS or NetBIOS name of the remote server on which the function is to execute. If /// this parameter is NULL, the local computer is used. /// /// This string is Unicode if _WIN32_WINNT or FORCE_UNICODE are defined. /// /// /// The data. The format of this data depends on the value of the level parameter. For more information, see Network Management /// Function Buffers. /// /// /// Specifies the information level of the data. This parameter can be one of the following values. /// /// /// Value /// Meaning /// /// /// 1 /// /// Specifies information about the user account. The buf parameter points to a USER_INFO_1 structure. When you specify this level, /// the call initializes certain attributes to their default values. For more information, see the following Remarks section. /// /// /// /// 2 /// /// Specifies level one information and additional attributes about the user account. The buf parameter points to a USER_INFO_2 structure. /// /// /// /// 3 /// /// Specifies level two information and additional attributes about the user account. This level is valid only on servers. The buf /// parameter points to a USER_INFO_3 structure. Note that it is recommended that you use USER_INFO_4 instead. /// /// /// /// 4 /// /// Specifies level two information and additional attributes about the user account. This level is valid only on servers. The buf /// parameter points to a USER_INFO_4 structure. Windows 2000: This level is not supported. /// /// /// /// /// /// /// If you are programming for Active Directory, you may be able to call certain Active Directory Service Interface (ADSI) methods to /// achieve the same functionality you can achieve by calling the network management user functions. For more information, see /// IADsUser and IADsComputer. /// /// /// If you call this function on a domain controller that is running Active Directory, access is allowed or denied based on the /// access control list (ACL) for the securable object. The default ACL permits only Domain Admins and Account Operators to call this /// function. On a member server or workstation, only Administrators and Power Users can call this function. For more information, /// see Security Requirements for the Network Management Functions. For more information on ACLs, ACEs, and access tokens, see Access /// Control Model. /// /// /// The security descriptor of the user container is used to perform the access check for this function. The caller must be able to /// create child objects of the user class. /// /// /// Server users must use a system in which the server creates a system account for the new user. The creation of this account is /// controlled by several parameters in the server's LanMan.ini file. /// /// /// If the newly added user already exists as a system user, the usri1_home_dir member of the USER_INFO_1 structure is ignored. /// /// /// When you call the NetUserAdd function and specify information level 1, the call initializes the additional members in the /// USER_INFO_2, USER_INFO_3, and USER_INFO_4 structures to their default values. You can change the default values by making /// subsequent calls to the NetUserSetInfo function. The default values supplied are listed following. (The prefix usriX indicates /// that the member can begin with multiple prefixes, for example, usri2_ or usri4_.) /// /// /// /// Member /// Default Value /// /// /// usriX_auth_flags /// None (0) /// /// /// usriX_full_name /// None (null string) /// /// /// usriX_usr_comment /// None (null string) /// /// /// usriX_parms /// None (null string) /// /// /// usriX_workstations /// All (null string) /// /// /// usriX_acct_expires /// Never (TIMEQ_FOREVER) /// /// /// usriX_max_storage /// Unlimited (USER_MAXSTORAGE_UNLIMITED) /// /// /// usriX_logon_hours /// Logon allowed at any time (each element 0xFF; all bits set to 1) /// /// /// usriX_logon_server /// Any domain controller (\\*) /// /// /// usriX_country_code /// 0 /// /// /// usriX_code_page /// 0 /// /// /// /// User account names are limited to 20 characters and group names are limited to 256 characters. In addition, account names cannot /// be terminated by a period and they cannot include commas or any of the following printable characters: ", /, , [, ], :, |, <, /// >, +, =, ;, ?, *. Names also cannot include characters in the range 1-31, which are non-printable. /// /// Examples /// /// The following code sample demonstrates how to add a user account and assign a privilege level using a call to the /// NetUserAdd function. The code sample fills in the members of the USER_INFO_1 structure and calls NetUserAdd, /// specifying information level 1. /// /// [PInvokeData("lmaccess.h", MSDNShortId = "b5ca5f76-d40b-4abf-925a-0de54fc476e4")] public static void NetUserAdd([Optional] string servername, in T buf, uint level = uint.MaxValue) where T : struct { if (level == uint.MaxValue) level = (uint)GetLevelFromStructure(); var mem = SafeHGlobalHandle.CreateFromStructure(buf); var err = NetUserAdd(servername, level, mem, out var perr); if (err.Succeeded) return; if (err != Win32Error.ERROR_INVALID_PARAMETER) err.ThrowIfFailed(); throw err.GetException($"Invalid parameter. Index: {perr}"); } /// The NetUserEnum function retrieves information about all user accounts on a server. /// /// /// A pointer to a constant string that specifies the DNS or NetBIOS name of the remote server on which the function is to execute. /// If this parameter is NULL, the local computer is used. /// /// /// /// A value that specifies the user account types to be included in the enumeration. A value of zero indicates that all normal user, /// trust data, and machine account data should be included. /// /// This parameter can also be a combination of the following values. /// /// /// Value /// Meaning /// /// /// FILTER_TEMP_DUPLICATE_ACCOUNT /// /// Enumerates account data for users whose primary account is in another domain. This account type provides user access to this /// domain, but not to any domain that trusts this domain. The User Manager refers to this account type as a local user account. /// /// /// /// FILTER_NORMAL_ACCOUNT /// Enumerates normal user account data. This account type is associated with a typical user. /// /// /// FILTER_INTERDOMAIN_TRUST_ACCOUNT /// /// Enumerates interdomain trust account data. This account type is associated with a trust account for a domain that trusts other domains. /// /// /// /// FILTER_WORKSTATION_TRUST_ACCOUNT /// /// Enumerates workstation or member server trust account data. This account type is associated with a machine account for a computer /// that is a member of the domain. /// /// /// /// FILTER_SERVER_TRUST_ACCOUNT /// /// Enumerates member server machine account data. This account type is associated with a computer account for a backup domain /// controller that is a member of the domain. /// /// /// /// /// /// Specifies the information level of the data. This parameter can be one of the following values. /// /// /// Value /// Meaning /// /// /// 0 /// Return user account names. The bufptr parameter points to an array of USER_INFO_0 structures. /// /// /// 1 /// Return detailed information about user accounts. The bufptr parameter points to an array of USER_INFO_1 structures. /// /// /// 2 /// /// Return detailed information about user accounts, including authorization levels and logon information. The bufptr parameter /// points to an array of USER_INFO_2 structures. /// /// /// /// 3 /// /// Return detailed information about user accounts, including authorization levels, logon information, RIDs for the user and the /// primary group, and profile information. The bufptr parameter points to an array of USER_INFO_3 structures. /// /// /// /// 10 /// Return user and account names and comments. The bufptr parameter points to an array of USER_INFO_10 structures. /// /// /// 11 /// Return detailed information about user accounts. The bufptr parameter points to an array of USER_INFO_11 structures. /// /// /// 20 /// /// Return the user's name and identifier and various account attributes. The bufptr parameter points to an array of USER_INFO_20 /// structures. Note that on Windows XP and later, it is recommended that you use USER_INFO_23 instead. /// /// /// /// /// The data. The format of this data depends on the value of the level parameter. /// /// /// The NetUserEnum function retrieves information about all user accounts on a specified remote server or the local computer. /// /// /// The NetQueryDisplayInformation function can be used to quickly enumerate user, computer, or global group account information for /// display in user interfaces . /// /// /// If you are programming for Active Directory, you may be able to call certain Active Directory Service Interface (ADSI) methods to /// achieve the same functionality you can achieve by calling the network management user functions. For more information, see /// IADsUser and IADsComputer. /// /// /// If you call the NetUserEnum function on a domain controller that is running Active Directory, access is allowed or denied /// based on the access control list (ACL) for the securable object. The default ACL permits all authenticated users and members of /// the "Pre-Windows 2000 compatible access" group to view the information. If you call this function on a member server or /// workstation, all authenticated users can view the information. For information about anonymous access and restricting anonymous /// access on these platforms, see Security Requirements for the Network Management Functions. For more information on ACLs, ACEs, /// and access tokens, see Access Control Model. /// /// /// The NetUserEnum function only returns information to which the caller has Read access. The caller must have List Contents /// access to the Domain object, and Enumerate Entire SAM Domain access on the SAM Server object located in the System container. /// /// /// The LsaEnumerateTrustedDomains or LsaEnumerateTrustedDomainsEx function can be used to retrieve the names and SIDs of domains /// trusted by a Local Security Authority (LSA) policy object. /// /// /// The NetUserEnum function does not return all system users. It returns only those users who have been added with a call to /// the NetUserAdd function. There is no guarantee that the list of users will be returned in sorted order. /// /// /// If you call the NetUserEnum function and specify information level 1, 2, or 3, for the level parameter, the password /// member of each structure retrieved is set to NULL to maintain password security. /// /// /// User account names are limited to 20 characters and group names are limited to 256 characters. In addition, account names cannot /// be terminated by a period and they cannot include commas or any of the following printable characters: ", /, , [, ], :, |, <, /// >, +, =, ;, ?, *. Names also cannot include characters in the range 1-31, which are non-printable. /// /// /// The NetUserEnum function does not support a level parameter of 4 and the USER_INFO_4 structure. The NetUserGetInfo /// function supports a level parameter of 4 and the USER_INFO_4 structure. /// /// Examples /// /// The following code sample demonstrates how to retrieve information about the user accounts on a server with a call to the /// NetUserEnum function. The sample calls NetUserEnum, specifying information level 0 (USER_INFO_0) to enumerate only /// global user accounts. If the call succeeds, the code loops through the entries and prints the name of each user account. Finally, /// the code sample frees the memory allocated for the information buffer and prints a total of the users enumerated. /// /// [PInvokeData("lmaccess.h", MSDNShortId = "b26ef3c0-934a-4840-8c06-4eaff5c9ff86")] public static IEnumerable NetUserEnum([Optional] string servername, UserEnumFilter filter = 0, uint level = uint.MaxValue) where T : struct { if (level == uint.MaxValue) level = (uint)GetLevelFromStructure(); var h = 0U; NetUserEnum(servername, level, filter, out var buf, MAX_PREFERRED_LENGTH, out var cnt, out var _, ref h).ThrowIfFailed(); return buf.ToIEnum((int)cnt); } /// The NetUserGetGroups function retrieves a list of global groups to which a specified user belongs. /// /// /// A pointer to a constant string that specifies the DNS or NetBIOS name of the remote server on which the function is to execute. /// If this parameter is NULL, the local computer is used. /// /// /// A pointer to a constant string that specifies the name of the user to search for in each group account. For more information, see /// the following Remarks section. /// /// /// The information level of the data requested. This parameter can be one of the following values. /// /// /// Value /// Meaning /// /// /// 0 /// /// Return the names of the global groups to which the user belongs. The bufptr parameter points to an array of GROUP_USERS_INFO_0 structures. /// /// /// /// 1 /// /// Return the names of the global groups to which the user belongs with attributes. The bufptr parameter points to an array of /// GROUP_USERS_INFO_1 structures. /// /// /// /// /// The data. /// /// /// If you are programming for Active Directory, you may be able to call certain Active Directory Service Interface (ADSI) methods to /// achieve the same functionality you can achieve by calling the network management user functions. For more information, see /// IADsUser and IADsComputer. /// /// /// If you call this function on a domain controller that is running Active Directory, access is allowed or denied based on the /// access control list (ACL) for the securable object. The default ACL permits all authenticated users and members of the /// "Pre-Windows 2000 compatible access" group to view the information. If you call this function on a member server or workstation, /// all authenticated users can view the information. For information about anonymous access and restricting anonymous access on /// these platforms, see Security Requirements for the Network Management Functions. For more information on ACLs, ACEs, and access /// tokens, see Access Control Model. /// /// The security descriptor of the User object is used to perform the access check for this function. /// /// To retrieve a list of the local groups to which a user belongs, you can call the NetUserGetLocalGroups function. Network groups /// are separate and distinct from Windows NT system groups. /// /// /// User account names are limited to 20 characters and group names are limited to 256 characters. In addition, account names cannot /// be terminated by a period and they cannot include commas or any of the following printable characters: ", /, , [, ], :, |, <, /// >, +, =, ;, ?, *. Names also cannot include characters in the range 1-31, which are non-printable. /// /// Examples /// /// The following code sample demonstrates how to retrieve a list of global groups to which a user belongs with a call to the /// NetUserGetGroups function. The sample calls NetUserGetGroups, specifying information level 0 ( GROUP_USERS_INFO_0). /// The code loops through the entries and prints the name of the global groups in which the user has membership. The sample also /// prints the total number of entries that are available and the number of entries actually enumerated if they do not match. /// Finally, the code sample frees the memory allocated for the buffer. /// /// [PInvokeData("lmaccess.h", MSDNShortId = "ecf1a94c-5dda-4f49-81bd-93e551e089f1")] public static IEnumerable NetUserGetGroups([Optional] string servername, string username, uint level = uint.MaxValue) where T : struct { if (level == uint.MaxValue) level = (uint)GetLevelFromStructure(); NetUserGetGroups(servername, username, level, out var buf, MAX_PREFERRED_LENGTH, out var cnt, out var _).ThrowIfFailed(); return buf.ToIEnum((int)cnt); } /// The NetUserGetInfo function retrieves information about a particular user account on a server. /// /// /// A pointer to a constant string that specifies the DNS or NetBIOS name of the remote server on which the function is to execute. /// If this parameter is NULL, the local computer is used. /// /// /// A pointer to a constant string that specifies the name of the user account for which to return information. For more information, /// see the following Remarks section. /// /// /// The information level of the data. This parameter can be one of the following values. /// /// /// Value /// Meaning /// /// /// 0 /// Return the user account name. The bufptr parameter points to a USER_INFO_0 structure. /// /// /// 1 /// Return detailed information about the user account. The bufptr parameter points to a USER_INFO_1 structure. /// /// /// 2 /// /// Return detailed information and additional attributes about the user account. The bufptr parameter points to a USER_INFO_2 structure. /// /// /// /// 3 /// /// Return detailed information and additional attributes about the user account. This level is valid only on servers. The bufptr /// parameter points to a USER_INFO_3 structure. Note that it is recommended that you use USER_INFO_4 instead. /// /// /// /// 4 /// /// Return detailed information and additional attributes about the user account. This level is valid only on servers. The bufptr /// parameter points to a USER_INFO_4 structure. /// /// /// /// 10 /// Return user and account names and comments. The bufptr parameter points to a USER_INFO_10 structure. /// /// /// 11 /// Return detailed information about the user account. The bufptr parameter points to a USER_INFO_11 structure. /// /// /// 20 /// /// Return the user's name and identifier and various account attributes. The bufptr parameter points to a USER_INFO_20 structure. /// Note that on Windows XP and later, it is recommended that you use USER_INFO_23 instead. /// /// /// /// 23 /// Return the user's name and identifier and various account attributes. The bufptr parameter points to a USER_INFO_23 structure. /// /// /// 24 /// /// Return user account information for accounts which are connected to an Internet identity. The bufptr parameter points to a /// USER_INFO_24 structure. /// /// /// /// /// The data. The format of this data depends on the value of the level parameter. /// /// /// If you are programming for Active Directory, you may be able to call certain Active Directory Service Interface (ADSI) methods to /// achieve the same functionality you can achieve by calling the network management user functions. For more information, see /// IADsUser and IADsComputer. /// /// /// If you call this function on a domain controller that is running Active Directory, access is allowed or denied based on the /// access control list (ACL) for the securable object. The default ACL permits all authenticated users and members of the /// "Pre-Windows 2000 compatible access" group to view the information. If you call this function on a member server or workstation, /// all authenticated users can view the information. For information about anonymous access and restricting anonymous access on /// these platforms, see Security Requirements for the Network Management Functions. For more information on ACLs, ACEs, and access /// tokens, see Access Control Model. /// /// The security descriptor of the User object is used to perform the access check for this function. /// /// User account names are limited to 20 characters and group names are limited to 256 characters. In addition, account names cannot /// be terminated by a period and they cannot include commas or any of the following printable characters: ", /, , [, ], :, |, <, /// >, +, =, ;, ?, *. Names also cannot include characters in the range 1-31, which are non-printable. /// /// /// If the information level specified in the level parameter is set to 24, the servername parameter specified must resolve to the /// local computer. If the servername resolves to a remote computer or to a domain controller, the NetUserGetInfo function /// will fail. /// /// Examples /// /// The following code sample demonstrates how to retrieve information about a particular user account with a call to the /// NetUserGetInfo function. The sample calls NetUserGetInfo, specifying various information levels . If the call /// succeeds, the code prints information about the user account. Finally, the sample frees the memory allocated for the information buffer. /// /// [PInvokeData("lmaccess.h", MSDNShortId = "5bd13bed-938a-4273-840e-99fca99f7139")] public static T NetUserGetInfo([Optional] string servername, string username, uint level = uint.MaxValue) where T : struct { if (level == uint.MaxValue) level = (uint)GetLevelFromStructure(); NetUserGetInfo(servername, username, level, out var buf).ThrowIfFailed(); return buf.ToStructure(); } /// The NetUserGetLocalGroups function retrieves a list of local groups to which a specified user belongs. /// /// /// A pointer to a constant string that specifies the DNS or NetBIOS name of the remote server on which the function is to execute. /// If this parameter is NULL, the local computer is used. /// /// /// A pointer to a constant string that specifies the name of the user for which to return local group membership information. If the /// string is of the form DomainName<i>UserName the user name is expected to be found on that domain. If the string is of the /// form UserName, the user name is expected to be found on the server specified by the servername parameter. For more information, /// see the Remarks section. /// /// /// A bitmask of flags that affect the operation. Currently, only the value defined is LG_INCLUDE_INDIRECT. If this bit is /// set, the function also returns the names of the local groups in which the user is indirectly a member (that is, the user has /// membership in a global group that is itself a member of one or more local groups). /// /// /// The information level of the data. This parameter can be the following value. /// /// /// Value /// Meaning /// /// /// 0 /// /// Return the names of the local groups to which the user belongs. The bufptr parameter points to an array of /// LOCALGROUP_USERS_INFO_0 structures. /// /// /// /// /// The data. The format of this data depends on the value of the level parameter. /// /// /// If you are programming for Active Directory, you may be able to call certain Active Directory Service Interface (ADSI) methods to /// achieve the same functionality you can achieve by calling the network management user functions. For more information, see /// IADsUser and IADsComputer. /// /// /// If you call this function on a domain controller that is running Active Directory, access is allowed or denied based on the /// access control list (ACL) for the securable object. The default ACL permits all authenticated users and members of the /// "Pre-Windows 2000 compatible access" group to view the information. If you call this function on a member server or workstation, /// all authenticated users can view the information. For information about anonymous access and restricting anonymous access on /// these platforms, see Security Requirements for the Network Management Functions. For more information on ACLs, ACEs, and access /// tokens, see Access Control Model. /// /// /// The security descriptor of the Domain object is used to perform the access check for this function. The caller must have Read /// Property permission on the Domain object. /// /// To retrieve a list of global groups to which a specified user belongs, you can call the NetUserGetGroups function. /// /// User account names are limited to 20 characters and group names are limited to 256 characters. In addition, account names cannot /// be terminated by a period and they cannot include commas or any of the following printable characters: ", /, , [, ], :, |, <, /// >, +, =, ;, ?, *. Names also cannot include characters in the range 1-31, which are non-printable. /// /// Examples /// /// The following code sample demonstrates how to retrieve a list of the local groups to which a user belongs with a call to the /// NetUserGetLocalGroups function. The sample calls NetUserGetLocalGroups, specifying information level 0 /// (LOCALGROUP_USERS_INFO_0). The sample loops through the entries and prints the name of each local group in which the user has /// membership. If all available entries are not enumerated, it also prints the number of entries actually enumerated and the total /// number of entries available. Finally, the code sample frees the memory allocated for the information buffer. /// /// [PInvokeData("lmaccess.h", MSDNShortId = "cc5c1c15-cad7-4103-a2c9-1a8adf742703")] public static IEnumerable NetUserGetLocalGroups([Optional] string servername, string username, GetLocalGroupFlags flags = 0, uint level = uint.MaxValue) where T : struct { if (level == uint.MaxValue) level = (uint)GetLevelFromStructure(); NetUserGetLocalGroups(servername, username, level, flags, out var buf, MAX_PREFERRED_LENGTH, out var cnt, out var _).ThrowIfFailed(); return buf.ToIEnum((int)cnt); } /// /// The NetUserModalsGet function retrieves global information for all users and global groups in the security database, which /// is the security accounts manager (SAM) database or, in the case of domain controllers, the Active Directory. /// /// /// /// A pointer to a constant string that specifies the DNS or NetBIOS name of the remote server on which the function is to execute. /// If this parameter is NULL, the local computer is used. For more information, see the following Remarks section. /// /// /// The information level of the data requested. This parameter can be one of the following values. /// /// /// Value /// Meaning /// /// /// 0 /// Return global password parameters. The bufptr parameter points to a USER_MODALS_INFO_0 structure. /// /// /// 1 /// Return logon server and domain controller information. The bufptr parameter points to a USER_MODALS_INFO_1 structure. /// /// /// 2 /// /// Return domain name and identifier. The bufptr parameter points to a USER_MODALS_INFO_2 structure. For more information, see the /// following Remarks section. /// /// /// /// 3 /// Return lockout information. The bufptr parameter points to a USER_MODALS_INFO_3 structure. /// /// /// A null session logon can call NetUserModalsGet anonymously at information levels 0 and 3. /// /// The data. The format of this data depends on the value of the level parameter. /// /// /// If you are programming for Active Directory, you may be able to call certain Active Directory Service Interface (ADSI) methods to /// achieve the same functionality you can achieve by calling the network management user modal functions. For more information, see IADsDomain. /// /// /// If you call this function on a domain controller that is running Active Directory, access is allowed or denied based on the /// access control list (ACL) for the securable object. The default ACL permits all authenticated users and members of the /// "Pre-Windows 2000 compatible access" group to view the information. If you call this function on a member server or workstation, /// all authenticated users can view the information. For information about anonymous access and restricting anonymous access on /// these platforms, see Security Requirements for the Network Management Functions. For more information on ACLs, ACEs, and access /// tokens, see Access Control Model. /// /// The security descriptor of the Domain object is used to perform the access check for this function. /// /// To retrieve the security identifier (SID) of the domain to which the computer belongs, call the NetUserModalsGet function /// specifying a USER_MODALS_INFO_2 structure and NULL in the servername parameter. If the computer isn't a member of a /// domain, the function returns a NULL pointer. /// /// Examples /// /// The following code sample demonstrates how to retrieve global information for all users and global groups with a call to the /// NetUserModalsGet function. The sample calls NetUserModalsGet, specifying information level 0 (USER_MODALS_INFO_0). /// If the call succeeds, the sample prints global password information. Finally, the code sample frees the memory allocated for the /// information buffer. /// /// [PInvokeData("lmaccess.h", MSDNShortId = "5bb18144-82a6-4e9b-8321-c06a667bdd03")] public static T NetUserModalsGet([Optional] string servername, uint level = uint.MaxValue) where T : struct { if (level == uint.MaxValue) level = (uint)GetLevelFromStructure(); NetUserModalsGet(servername, level, out var buf).ThrowIfFailed(); return buf.ToStructure(); } /// /// The NetUserModalsSet function sets global information for all users and global groups in the security database, which is /// the security accounts manager (SAM) database or, in the case of domain controllers, the Active Directory. /// /// /// /// Pointer to a constant string that specifies the DNS or NetBIOS name of the remote server on which the function is to execute. If /// this parameter is NULL, the local computer is used. /// /// /// The data. The format of this data depends on the value of the level parameter. For more information, see Network Management /// Function Buffers. /// /// /// Specifies the information level of the data. This parameter can be one of the following values. /// /// /// Value /// Meaning /// /// /// 0 /// Specifies global password parameters. The buf parameter points to a USER_MODALS_INFO_0 structure. /// /// /// 1 /// Specifies logon server and domain controller information. The buf parameter points to a USER_MODALS_INFO_1 structure. /// /// /// 2 /// Specifies the domain name and identifier. The buf parameter points to a USER_MODALS_INFO_2 structure. /// /// /// 3 /// Specifies lockout information. The buf parameter points to a USER_MODALS_INFO_3 structure. /// /// /// 1001 /// Specifies the minimum allowable password length. The buf parameter points to a USER_MODALS_INFO_1001 structure. /// /// /// 1002 /// Specifies the maximum allowable password age. The buf parameter points to a USER_MODALS_INFO_1002 structure. /// /// /// 1003 /// Specifies the minimum allowable password age. The buf parameter points to a USER_MODALS_INFO_1003 structure. /// /// /// 1004 /// Specifies forced logoff information. The buf parameter points to a USER_MODALS_INFO_1004 structure. /// /// /// 1005 /// Specifies the length of the password history. The buf parameter points to a USER_MODALS_INFO_1005 structure. /// /// /// 1006 /// Specifies the role of the logon server. The buf parameter points to a USER_MODALS_INFO_1006 structure. /// /// /// 1007 /// Specifies domain controller information. The buf parameter points to a USER_MODALS_INFO_1007 structure. /// /// /// /// /// /// If you are programming for Active Directory, you may be able to call certain Active Directory Service Interface (ADSI) methods to /// achieve the same functionality you can achieve by calling the network management user modal functions. For more information, see IADsDomain. /// /// /// If you call this function on a domain controller that is running Active Directory, access is allowed or denied based on the /// access control list (ACL) for the securable object. The default ACL permits only Domain Admins and Account Operators to call this /// function. On a member server or workstation, only Administrators and Power Users can call this function. For more information, /// see Security Requirements for the Network Management Functions. For more information on ACLs, ACEs, and access tokens, see Access /// Control Model. /// /// /// The security descriptor of the Domain object is used to perform the access check for this function. Typically, callers must have /// write access to the entire object for calls to this function to succeed. /// /// /// If the NetUserModalsSet function returns ERROR_INVALID_PARAMETER, you can use the parm_err parameter to indicate the first /// member of the information structure that is invalid. (The information structure begins with USER_MODALS_INFO_ and its format is /// specified by the level parameter.) The following table lists the values that can be returned in the parm_err parameter and the /// corresponding structure member that is in error. (The prefix usrmod*_ indicates that the member can begin with multiple prefixes, /// for example, usrmod2_ or usrmod1002_.) /// /// /// /// Value /// Member /// /// /// MODALS_MIN_PASSWD_LEN_PARMNUM /// usrmod*_min_passwd_len /// /// /// MODALS_MAX_PASSWD_AGE_PARMNUM /// usrmod*_max_passwd_age /// /// /// MODALS_MIN_PASSWD_AGE_PARMNUM /// usrmod*_min_passwd_age /// /// /// MODALS_FORCE_LOGOFF_PARMNUM /// usrmod*_force_logoff /// /// /// MODALS_PASSWD_HIST_LEN_PARMNUM /// usrmod*_password_hist_len /// /// /// MODALS_ROLE_PARMNUM /// usrmod*_role /// /// /// MODALS_PRIMARY_PARMNUM /// usrmod*_primary /// /// /// MODALS_DOMAIN_NAME_PARMNUM /// usrmod*_domain_name /// /// /// MODALS_DOMAIN_ID_PARMNUM /// usrmod*_domain_id /// /// /// MODALS_LOCKOUT_DURATION_PARMNUM /// usrmod*_lockout_duration /// /// /// MODALS_LOCKOUT_OBSERVATION_WINDOW_PARMNUM /// usrmod*_lockout_observation_window /// /// /// MODALS_LOCKOUT_THRESHOLD_PARMNUM /// usrmod*_lockout_threshold /// /// /// Examples /// /// The following code sample demonstrates how to set the global information for all users and global groups with a call to the /// NetUserModalsSet function. The sample fills in the members of the USER_MODALS_INFO_0 structure and calls /// NetUserModalsSet, specifying information level 0. /// /// [PInvokeData("lmaccess.h", MSDNShortId = "9884e076-ee6a-4aca-abe6-a79754667759")] public static void NetUserModalsSet([Optional] string servername, in T buf, uint level = uint.MaxValue) where T : struct { if (level == uint.MaxValue) level = (uint)GetLevelFromStructure(); var mem = SafeHGlobalHandle.CreateFromStructure(buf); var err = NetUserModalsSet(servername, level, mem, out var perr); if (err.Succeeded) return; if (err != Win32Error.ERROR_INVALID_PARAMETER) err.ThrowIfFailed(); throw err.GetException($"Invalid parameter. Index: {perr}"); } /// The NetUserSetGroups function sets global group memberships for a specified user account. /// /// /// A pointer to a constant string that specifies the DNS or NetBIOS name of the remote server on which the function is to execute. /// If this parameter is NULL, the local computer is used. /// /// /// A pointer to a constant string that specifies the name of the user for which to set global group memberships. For more /// information, see the Remarks section. /// /// The data. For more information, see Network Management Function Buffers. /// /// The information level of the data. This parameter can be one of the following values. /// /// /// Value /// Meaning /// /// /// 0 /// The buf parameter points to an array of GROUP_USERS_INFO_0 structures that specifies global group names. /// /// /// 1 /// The buf parameter points to an array of GROUP_USERS_INFO_1 structures that specifies global group names with attributes. /// /// /// /// /// /// If you are programming for Active Directory, you may be able to call certain Active Directory Service Interface (ADSI) methods to /// achieve the same functionality you can achieve by calling the network management user functions. For more information, see /// IADsUser and IADsComputer. /// /// /// If you call this function on a domain controller that is running Active Directory, access is allowed or denied based on the /// access control list (ACL) for the securable object. The default ACL permits only Domain Admins and Account Operators to call this /// function. On a member server or workstation, only Administrators and Power Users can call this function. For more information, /// see Security Requirements for the Network Management Functions. For more information on ACLs, ACEs, and access tokens, see Access /// Control Model. /// /// The security descriptor of the User object is used to perform the access check for this function. /// To grant a user membership in one existing global group, you can call the NetGroupAddUser function. /// /// User account names are limited to 20 characters and group names are limited to 256 characters. In addition, account names cannot /// be terminated by a period and they cannot include commas or any of the following printable characters: ", /, , [, ], :, |, <, /// >, +, =, ;, ?, *. Names also cannot include characters in the range 1-31, which are non-printable. /// /// Examples /// /// The following code sample demonstrates how to set global group memberships for a user account with a call to the /// NetUserSetGroups function. The code sample fills in the grui0_name member of the GROUP_USERS_INFO_0 structure and /// calls NetUserSetGroups, specifying information level 0. /// /// [PInvokeData("lmaccess.h", MSDNShortId = "7042c43a-09d1-4179-8074-eb055dc279a6")] public static void NetUserSetGroups([Optional] string servername, string username, T[] buf, uint level = uint.MaxValue) where T : struct { if (level == uint.MaxValue) level = (uint)GetLevelFromStructure(); using var mem = SafeHGlobalHandle.CreateFromList(buf); NetUserSetGroups(servername, username, level, mem, (uint)buf.Length).ThrowIfFailed(); } /// The NetUserSetInfo function sets the parameters of a user account. /// /// /// A pointer to a constant string that specifies the DNS or NetBIOS name of the remote server on which the function is to execute. /// If this parameter is NULL, the local computer is used. /// /// /// A pointer to a constant string that specifies the name of the user account for which to set information. For more information, /// see the following Remarks section. /// /// /// The data. The format of this data depends on the value of the level parameter. For more information, see Network Management /// Function Buffers. /// /// /// The information level of the data. This parameter can be one of the following values. /// /// /// Value /// Meaning /// /// /// 0 /// /// Specifies the user account name. The buf parameter points to a USER_INFO_0 structure. Use this structure to specify a new group /// name. For more information, see the following Remarks section. /// /// /// /// 1 /// Specifies detailed information about the user account. The buf parameter points to a USER_INFO_1 structure. /// /// /// 2 /// /// Specifies level one information and additional attributes about the user account. The buf parameter points to a USER_INFO_2 structure. /// /// /// /// 3 /// /// Specifies level two information and additional attributes about the user account. This level is valid only on servers. The buf /// parameter points to a USER_INFO_3 structure. Note that it is recommended that you use USER_INFO_4 instead. /// /// /// /// 4 /// /// Specifies level two information and additional attributes about the user account. This level is valid only on servers. The buf /// parameter points to a USER_INFO_4 structure. /// /// /// /// 21 /// Specifies a one-way encrypted LAN Manager 2.x-compatible password. The buf parameter points to a USER_INFO_21 structure. /// /// /// 22 /// Specifies detailed information about the user account. The buf parameter points to a USER_INFO_22 structure. /// /// /// 1003 /// Specifies a user password. The buf parameter points to a USER_INFO_1003 structure. /// /// /// 1005 /// Specifies a user privilege level. The buf parameter points to a USER_INFO_1005 structure. /// /// /// 1006 /// Specifies the path of the home directory for the user. The buf parameter points to a USER_INFO_1006 structure. /// /// /// 1007 /// Specifies a comment to associate with the user account. The buf parameter points to a USER_INFO_1007 structure. /// /// /// 1008 /// Specifies user account attributes. The buf parameter points to a USER_INFO_1008 structure. /// /// /// 1009 /// Specifies the path for the user's logon script file. The buf parameter points to a USER_INFO_1009 structure. /// /// /// 1010 /// Specifies the user's operator privileges. The buf parameter points to a USER_INFO_1010 structure. /// /// /// 1011 /// Specifies the full name of the user. The buf parameter points to a USER_INFO_1011 structure. /// /// /// 1012 /// Specifies a comment to associate with the user. The buf parameter points to a USER_INFO_1012 structure. /// /// /// 1014 /// Specifies the names of workstations from which the user can log on. The buf parameter points to a USER_INFO_1014 structure. /// /// /// 1017 /// Specifies when the user account expires. The buf parameter points to a USER_INFO_1017 structure. /// /// /// 1020 /// Specifies the times during which the user can log on. The buf parameter points to a USER_INFO_1020 structure. /// /// /// 1024 /// Specifies the user's country/region code. The buf parameter points to a USER_INFO_1024 structure. /// /// /// 1051 /// /// Specifies the relative identifier of a global group that represents the enrolled user. The buf parameter points to a /// USER_INFO_1051 structure. /// /// /// /// 1052 /// Specifies the path to a network user's profile. The buf parameter points to a USER_INFO_1052 structure. /// /// /// 1053 /// Specifies the drive letter assigned to the user's home directory. The buf parameter points to a USER_INFO_1053 structure. /// /// /// /// /// /// If you are programming for Active Directory, you may be able to call certain Active Directory Service Interface (ADSI) methods to /// achieve the same functionality you can achieve by calling the network management user functions. For more information, see /// IADsUser and IADsComputer. /// /// /// If you call this function on a domain controller that is running Active Directory, access is allowed or denied based on the /// access control list (ACL) for the securable object. The default ACL permits only Domain Admins and Account Operators to call this /// function. On a member server or workstation, only Administrators and Power Users can call this function. For more information, /// see Security Requirements for the Network Management Functions. For more information on ACLs, ACEs, and access tokens, see Access /// Control Model. /// /// The security descriptor of the User object is used to perform the access check for this function. /// /// Only users or applications having administrative privileges can call the NetUserSetInfo function to change a user's /// password. When an administrator calls NetUserSetInfo, the only restriction applied is that the new password length must be /// consistent with system modals. A user or application that knows a user's current password can call the NetUserChangePassword /// function to change the password. For more information about calling functions that require administrator privileges, see Running /// with Special Privileges. /// /// /// Members of the Administrators local group can set any modifiable user account elements. All users can set the /// usri2_country_code member of the USER_INFO_2 structure (and the usri1024_country_code member of the USER_INFO_1024 /// structure) for their own accounts. /// /// /// A member of the Account Operator's local group cannot set details for an Administrators class account, give an existing account /// Administrator privilege, or change the operator privilege of any account. If you attempt to change the privilege level or disable /// the last account with Administrator privilege in the security database, (the security accounts manager (SAM) database or, in the /// case of domain controllers, the Active Directory), the NetUserSetInfo function fails and returns NERR_LastAdmin. /// /// To set the following user account control flags, the following privileges and control access rights are required. /// /// /// Account control flag /// Privilege or right required /// /// /// UF_TRUSTED_TO_AUTHENTICATE_FOR_DELEGATION /// SeEnableDelegationPrivilege privilege, which is granted to Administrators by default. /// /// /// UF_TRUSTED_FOR_DELEGATION /// SeEnableDelegationPrivilege. /// /// /// UF_PASSWD_NOTREQD /// "Update password not required" control access right on the Domain object, which is granted to authenticated users by default. /// /// /// UF_DONT_EXPIRE_PASSWD /// "Unexpire password" control access right on the Domain object, which is granted to authenticated users by default. /// /// /// UF_ENCRYPTED_TEXT_PASSWORD_ALLOWED /// /// "Enable per user reversibly encrypted password" control access right on the Domain object, which is granted to authenticated /// users by default. /// /// /// /// UF_SERVER_TRUST_ACCOUNT /// "Add/remove replica in domain" control access right on the Domain object, which is granted to Administrators by default. /// /// /// For a list of privilege constants, see Authorization Constants. /// /// The correct way to specify the new name for an account is to call NetUserSetInfo with USER_INFO_0 and to specify the new /// value using the usri0_name member. If you call NetUserSetInfo with other information levels and specify a value /// using a usriX_name member, the value is ignored. /// /// /// Note that calls to NetUserSetInfo can change the home directory only for user accounts that the network server creates. /// /// /// If the NetUserSetInfo function returns ERROR_INVALID_PARAMETER, you can use the parm_err parameter to indicate the first /// member of the user information structure that is invalid. (A user information structure begins with USER_INFO_ and its format is /// specified by the level parameter.) The following table lists the values that can be returned in the parm_err parameter and the /// corresponding structure member that is in error. (The prefix usri*_ indicates that the member can begin with multiple prefixes, /// for example, usri10_ or usri1003_.) /// /// /// /// Value /// Member /// /// /// USER_NAME_PARMNUM /// usri*_name /// /// /// USER_PASSWORD_PARMNUM /// usri*_password /// /// /// USER_PASSWORD_AGE_PARMNUM /// usri*_password_age /// /// /// USER_PRIV_PARMNUM /// usri*_priv /// /// /// USER_HOME_DIR_PARMNUM /// usri*_home_dir /// /// /// USER_COMMENT_PARMNUM /// usri*_comment /// /// /// USER_FLAGS_PARMNUM /// usri*_flags /// /// /// USER_SCRIPT_PATH_PARMNUM /// usri*_script_path /// /// /// USER_AUTH_FLAGS_PARMNUM /// usri*_auth_flags /// /// /// USER_FULL_NAME_PARMNUM /// usri*_full_name /// /// /// USER_USR_COMMENT_PARMNUM /// usri*_usr_comment /// /// /// USER_PARMS_PARMNUM /// usri*_parms /// /// /// USER_WORKSTATIONS_PARMNUM /// usri*_workstations /// /// /// USER_LAST_LOGON_PARMNUM /// usri*_last_logon /// /// /// USER_LAST_LOGOFF_PARMNUM /// usri*_last_logoff /// /// /// USER_ACCT_EXPIRES_PARMNUM /// usri*_acct_expires /// /// /// USER_MAX_STORAGE_PARMNUM /// usri*_max_storage /// /// /// USER_UNITS_PER_WEEK_PARMNUM /// usri*_units_per_week /// /// /// USER_LOGON_HOURS_PARMNUM /// usri*_logon_hours /// /// /// USER_PAD_PW_COUNT_PARMNUM /// usri*_bad_pw_count /// /// /// USER_NUM_LOGONS_PARMNUM /// usri*_num_logons /// /// /// USER_LOGON_SERVER_PARMNUM /// usri*_logon_server /// /// /// USER_COUNTRY_CODE_PARMNUM /// usri*_country_code /// /// /// USER_CODE_PAGE_PARMNUM /// usri*_code_page /// /// /// USER_PRIMARY_GROUP_PARMNUM /// usri*_primary_group_id /// /// /// USER_PROFILE_PARMNUM /// usri*_profile /// /// /// USER_HOME_DIR_DRIVE_PARMNUM /// usri*_home_dir_drive /// /// /// /// User account names are limited to 20 characters and group names are limited to 256 characters. In addition, account names cannot /// be terminated by a period and they cannot include commas or any of the following printable characters: ", /, , [, ], :, |, <, /// >, +, =, ;, ?, *. Names also cannot include characters in the range 1-31, which are non-printable. /// /// /// The NetUserSetInfo function does not control how the password parameters are secured when sent over the network to a /// remote server to change a user password. Any encryption of these parameters is handled by the Remote Procedure Call (RPC) /// mechanism supported by the network redirector that provides the network transport. Encryption is also controlled by the security /// mechanisms supported by the local computer and the security mechanisms supported by remote network server specified in the /// servername parameter. For more details on security when the Microsoft network redirector is used and the remote network server is /// running Microsoft Windows, see the protocol documentation for MS-RPCE and MS-SAMR. /// /// Examples /// /// The following code sample demonstrates how to disable a user account with a call to the NetUserSetInfo function. The code /// sample fills in the usri1008_flags member of the USER_INFO_1008 structure, specifying the value UF_ACCOUNTDISABLE. Then /// the sample calls NetUserSetInfo, specifying information level 0. /// /// [PInvokeData("lmaccess.h", MSDNShortId = "ffe49d4b-e7e8-4982-8087-59bb7534b257")] public static void NetUserSetInfo([Optional] string servername, string username, in T buf, uint level = uint.MaxValue) where T : struct { if (level == uint.MaxValue) level = (uint)GetLevelFromStructure(); var mem = SafeHGlobalHandle.CreateFromStructure(buf); var err = NetUserSetInfo(servername, username, level, mem, out var perr); if (err.Succeeded) return; if (err != Win32Error.ERROR_INVALID_PARAMETER) err.ThrowIfFailed(); throw err.GetException($"Invalid parameter. Index: {perr}"); } /// The NetWkstaGetInfo function returns information about the configuration of a workstation. /// The type of structure to get. /// /// Pointer to a string that specifies the DNS or NetBIOS name of the remote server on which the function is to execute. If this /// parameter is NULL, the local computer is used. /// /// /// Specifies the information level of the data. This parameter can be one of the following values. /// /// /// Value /// Meaning /// /// /// 100 /// /// Return information about the workstation environment, including platform-specific information, the name of the domain and the /// local computer, and information concerning the operating system. The bufptr parameter points to a WKSTA_INFO_100 structure. /// /// /// /// 101 /// /// In addition to level 100 information, return the path to the LANMAN directory. The bufptr parameter points to a WKSTA_INFO_101 structure. /// /// /// /// 102 /// /// In addition to level 101 information, return the number of users who are logged on to the local computer. The bufptr parameter /// points to a WKSTA_INFO_102 structure. /// /// /// /// /// The data. The format of this data depends on the value of the level parameter. /// /// /// Windows Server 2003 and Windows XP: If you call this function on a domain controller that is running Active Directory, /// access is allowed or denied based on the ACL for the securable object. To enable anonymous access, the user Anonymous must be a /// member of the "Pre-Windows 2000 compatible access" group. This is because anonymous tokens do not include the Everyone group SID /// by default. If you call this function on a member server or workstation, all authenticated users can view the information. /// Anonymous access is also permitted if the EveryoneIncludesAnonymous policy setting allows anonymous access. Anonymous access is /// always permitted for level 100. If you call this function at level 101, authenticated users can view the information. Members of /// the Administrators, and the Server, System and Print Operator local groups can view information at levels 102 and 502. For more /// information about restricting anonymous access, see Security Requirements for the Network Management Functions. For more /// information on ACLs, ACEs, and access tokens, see Access Control Model. /// /// /// Windows 2000: If you call this function on a domain controller that is running Active Directory, access is allowed or /// denied based on the access control list (ACL) for the securable object. The default ACL permits all authenticated users and /// members of the " Pre-Windows 2000 compatible access" group to view the information. By default, the "Pre-Windows 2000 compatible /// access" group includes Everyone as a member. This enables anonymous access to the information if the system allows anonymous /// access. If you call this function on a member server or workstation, all authenticated users can view the information. Anonymous /// access is also permitted if the RestrictAnonymous policy setting allows anonymous access. /// /// /// To compile an application that uses this function, define the _WIN32_WINNT macro as 0x0400 or later. For more information,see /// Using the Windows Headers. /// /// [PInvokeData("lmwksta.h", MSDNShortId = "08777069-1afd-4482-8090-c65ef0bec1ea")] public static T NetWkstaGetInfo(string servername, uint level = uint.MaxValue) where T : struct { if (level == uint.MaxValue) level = (uint)GetLevelFromStructure(); NetWkstaGetInfo(servername, level, out var buf).ThrowIfFailed(); return buf.ToStructure(); } /// /// The NetWkstaSetInfo function configures a workstation with information that remains in effect after the system has been reinitialized. /// /// The type of the data to set. /// /// A pointer to a string that specifies the DNS or NetBIOS name of the remote server on which the function is to execute. If this /// parameter is NULL, the local computer is used. /// /// The data. The format of this data depends on the value of the level parameter. /// /// The information level of the data. This parameter can be one of the following values. /// /// /// Value /// Meaning /// /// /// 100 /// /// Windows NT: Specifies information about a workstation environment, including platform-specific information, the names of the /// domain and the local computer, and information concerning the operating system. The buffer parameter points to a WKSTA_INFO_100 /// structure. The wk100_computername and wk100_langroup fields of this structure cannot be set by calling this function. To set /// these values, call SetComputerName/SetComputerNameEx or NetJoinDomain, respectively. /// /// /// /// 101 /// /// Windows NT: In addition to level 100 information, specifies the path to the LANMAN directory. The buffer parameter points to a /// WKSTA_INFO_101 structure. The wk101_computername and wk101_langroup fields of this structure cannot be set by calling this /// function. To set these values, call SetComputerName/SetComputerNameEx or NetJoinDomain, respectively. /// /// /// /// 102 /// /// Windows NT: In addition to level 101 information, specifies the number of users who are logged on to the local computer. The /// buffer parameter points to a WKSTA_INFO_102 structure. The wk102_computername and wk102_langroup fields of this structure cannot /// be set by calling this function. To set these values, call SetComputerName/SetComputerNameEx or NetJoinDomain, respectively. /// /// /// /// 502 /// /// Windows NT: The buffer parameter points to a WKSTA_INFO_502 structure that contains information about the workstation environment. /// /// /// /// Do not set levels 1010-1013, 1018, 1023, 1027, 1028, 1032, 1033, 1035, or 1041-1062. /// /// /// Only members of the Administrators group can successfully execute the NetWkstaSetInfo function on a remote server. /// /// The NetWkstaSetInfo function calls the workstation service on the local system or a remote system. Only a limited number /// of members of the WKSTA_INFO_502 structure can actually be changed using the NetWkstaSetInfo function. No errors are /// returned if a member is set that is ignored by the workstation service. The workstation service is primarily configured using /// settings in the registry. /// /// /// The NetWkstaUserSetInfo function can be used instead of the NetWkstaSetInfo function to set configuration information on /// the local system. The NetWkstaUserSetInfo function calls the Local Security Authority (LSA). /// /// /// If the NetWkstaSetInfo function returns ERROR_INVALID_PARAMETER, you can use the parm_err parameter to indicate the first /// member of the workstation information structure that is invalid. (A workstation information structure begins with WKSTA_INFO_ and /// its format is specified by the level parameter.) The following table lists the values that can be returned in the parm_err /// parameter and the corresponding structure member that is in error. (The prefix wki*_ indicates that the member can begin with /// multiple prefixes, for example, wki100_ or wki402_.) /// /// /// /// Value /// Member /// /// /// WKSTA_PLATFORM_ID_PARMNUM /// wki*_platform_id /// /// /// WKSTA_COMPUTERNAME_PARMNUM /// wki*_computername /// /// /// WKSTA_LANGROUP_PARMNUM /// wki*_langroup /// /// /// WKSTA_VER_MAJOR_PARMNUM /// wki*_ver_major /// /// /// WKSTA_VER_MINOR_PARMNUM /// wki*_ver_minor /// /// /// WKSTA_LOGGED_ON_USERS_PARMNUM /// wki*_logged_on_users /// /// /// WKSTA_LANROOT_PARMNUM /// wki*_lanroot /// /// /// WKSTA_LOGON_DOMAIN_PARMNUM /// wki*_logon_domain /// /// /// WKSTA_LOGON_SERVER_PARMNUM /// wki*_logon_server /// /// /// WKSTA_CHARWAIT_PARMNUM /// wki*_char_wait /// /// /// WKSTA_CHARTIME_PARMNUM /// wki*_collection_time /// /// /// WKSTA_CHARCOUNT_PARMNUM /// wki*_maximum_collection_count /// /// /// WKSTA_KEEPCONN_PARMNUM /// wki*_keep_conn /// /// /// WKSTA_KEEPSEARCH_PARMNUM /// wki*_keep_search /// /// /// WKSTA_MAXCMDS_PARMNUM /// wki*_max_cmds /// /// /// WKSTA_NUMWORKBUF_PARMNUM /// wki*_num_work_buf /// /// /// WKSTA_MAXWRKCACHE_PARMNUM /// wki*_max_wrk_cache /// /// /// WKSTA_SESSTIMEOUT_PARMNUM /// wki*_sess_timeout /// /// /// WKSTA_SIZERROR_PARMNUM /// wki*_siz_error /// /// /// WKSTA_NUMALERTS_PARMNUM /// wki*_num_alerts /// /// /// WKSTA_NUMSERVICES_PARMNUM /// wki*_num_services /// /// /// WKSTA_ERRLOGSZ_PARMNUM /// wki*_errlog_sz /// /// /// WKSTA_PRINTBUFTIME_PARMNUM /// wki*_print_buf_time /// /// /// WKSTA_NUMCHARBUF_PARMNU /// wki*_num_char_buf /// /// /// WKSTA_SIZCHARBUF_PARMNUM /// wki*_siz_char_buf /// /// /// WKSTA_WRKHEURISTICS_PARMNUM /// wki*_wrk_heuristics /// /// /// WKSTA_MAILSLOTS_PARMNUM /// wki*_mailslots /// /// /// WKSTA_MAXTHREADS_PARMNUM /// wki*_max_threads /// /// /// WKSTA_SIZWORKBUF_PARMNUM /// wki*_siz_work_buf /// /// /// WKSTA_NUMDGRAMBUF_PARMNUM /// wki*_num_dgram_buf /// /// /// /// The workstation service parameter settings are stored in the registry, not in the LanMan.ini file used prveiously by LAN Manager. /// The NetWkstaSetInfo function does not change the values in the LanMan.ini file. When the workstation service is stopped /// and restarted, workstation parameters are reset to the default values specified in the registry (unless they are overwritten by /// command-line parameters). Values set by previous calls to NetWkstaSetInfo can be overwritten when workstation parameters /// are reset. /// /// Examples /// /// The following code sample demonstrates how to set the session time-out value associated with a workstation using a call to the /// NetServerSetInfo function. (The session time-out is the number of seconds the server waits before disconnecting an /// inactive session.) The code specifies information level 502 (WKSTA_INFO_502). /// /// [PInvokeData("lmwksta.h", MSDNShortId = "d746b6c9-5ef1-4174-a84f-44e4e50200cd")] public static void NetWkstaSetInfo(string servername, in T buffer, uint level = uint.MaxValue) where T : struct { var mem = SafeHGlobalHandle.CreateFromStructure(buffer); if (level == uint.MaxValue) level = (uint)GetLevelFromStructure(); var err = NetWkstaSetInfo(servername, level, mem, out var perr); if (err.Succeeded) return; if (err != Win32Error.ERROR_INVALID_PARAMETER) err.ThrowIfFailed(); throw err.GetException($"Invalid parameter. Index: {perr}"); } /// /// The NetWkstaUserEnum function lists information about all users currently logged on to the workstation. This list includes /// interactive, service and batch logons. /// /// /// /// Pointer to a string that specifies the DNS or NetBIOS name of the remote server on which the function is to execute. If this /// parameter is NULL, the local computer is used. /// /// /// Specifies the information level of the data. This parameter can be one of the following values. /// /// /// Value /// Meaning /// /// /// 0 /// /// Return the names of users currently logged on to the workstation. The bufptr parameter points to an array of WKSTA_USER_INFO_0 structures. /// /// /// /// 1 /// /// Return the names of the current users and the domains accessed by the workstation. The bufptr parameter points to an array of /// WKSTA_USER_INFO_1 structures. /// /// /// /// /// The data enumeration. The format of this data depends on the value of the level parameter. /// /// /// Note that since the NetWkstaUserEnum function lists entries for service and batch logons, as well as for interactive /// logons, the function can return entries for users who have logged off a workstation. This can occur, for example, when a user /// calls a service that impersonates the user. In this instance, NetWkstaUserEnum returns an entry for the user until the /// service stops impersonating the user. /// /// /// Windows Server 2003 and Windows XP: If you call this function on a domain controller that is running Active Directory, /// access is allowed or denied based on the ACL for the securable object. To enable anonymous access, the user Anonymous must be a /// member of the "Pre-Windows 2000 compatible access" group. This is because anonymous tokens do not include the Everyone group SID /// by default. If you call this function on a member server or workstation, all authenticated users can view the information. /// Anonymous access is also permitted if the RestrictAnonymous policy setting permits anonymous access. If the RestrictAnonymous /// policy setting does not permit anonymous access, only an administrator can successfully execute the function. Members of the /// Administrators, and the Server, System and Print Operator local groups can also view information. For more information about /// restricting anonymous access, see Security Requirements for the Network Management Functions. For more information on ACLs, ACEs, /// and access tokens, see Access Control Model. /// /// /// Windows 2000: If you call this function on a domain controller that is running Active Directory, access is allowed or /// denied based on the access control list (ACL) for the securable object. The default ACL permits all authenticated users and /// members of the " Pre-Windows 2000 compatible access" group to view the information. By default, the "Pre-Windows 2000 compatible /// access" group includes Everyone as a member. This enables anonymous access to the information if the system allows anonymous /// access. If you call this function on a member server or workstation, all authenticated users can view the information. Anonymous /// access is also permitted if the RestrictAnonymous policy setting allows anonymous access. /// /// /// To compile an application that uses this function, define the _WIN32_WINNT macro as 0x0400 or later. For more information,see /// Using the Windows Headers. /// /// [PInvokeData("lmwksta.h", MSDNShortId = "42eaeb70-3ce8-4eae-b20b-4729db90a7ef")] public static IEnumerable NetWkstaUserEnum([Optional] string servername, uint level = uint.MaxValue) where T : struct { if (level == uint.MaxValue) level = (uint)GetLevelFromStructure(); var h = 0U; NetWkstaUserEnum(servername, level, out var buf, MAX_PREFERRED_LENGTH, out var cnt, out var _, ref h).ThrowIfFailed(); return buf.ToIEnum((int)cnt); } /// /// The NetWkstaUserGetInfo function returns information about the currently logged-on user. This function must be called in /// the context of the logged-on user. /// /// /// /// Specifies the information level of the data. This parameter can be one of the following values. /// /// /// Value /// Meaning /// /// /// 0 /// /// Return the name of the user currently logged on to the workstation. The bufptr parameter points to a WKSTA_USER_INFO_0 structure. /// /// /// /// 1 /// /// Return information about the workstation, including the name of the current user and the domains accessed by the workstation. The /// bufptr parameter points to a WKSTA_USER_INFO_1 structure. /// /// /// /// 1101 /// Return domains browsed by the workstation. The bufptr parameter points to a WKSTA_USER_INFO_1101 structure. /// /// /// /// The data. The format of this data depends on the value of the bufptr parameter. /// /// The NetWkstaUserGetInfo function only works locally. /// Examples /// /// The following code sample demonstrates how to retrieve information about the currently logged-on user using a call to the /// NetWkstaUserGetInfo function. The sample calls NetWkstaUserGetInfo, specifying information level 1 ( /// WKSTA_USER_INFO_1). If the call succeeds, the sample prints information about the logged-on user. Finally, the sample frees the /// memory allocated for the information buffer. /// /// [PInvokeData("lmwksta.h", MSDNShortId = "25ec7a49-fd26-4105-823b-a257a57f724e")] public static T NetWkstaUserGetInfo(uint level = uint.MaxValue) where T : struct { if (level == uint.MaxValue) level = (uint)GetLevelFromStructure(); NetWkstaUserGetInfo(null, level, out var buf).ThrowIfFailed(); return buf.ToStructure(); } /// /// The NetWkstaUserSetInfo function sets the user-specific information about the configuration elements for a workstation. /// /// /// Specifies the information level of the data. This parameter can be one of the following values. /// /// /// Value /// Meaning /// /// /// 1 /// /// Specifies information about the workstation, including the name of the current user and the domains accessed by the workstation. /// The buf parameter points to a WKSTA_USER_INFO_1 structure. /// /// /// /// 1101 /// Specifies domains browsed by the workstation. The buf parameter points to a WKSTA_USER_INFO_1101 structure. /// /// /// /// /// Pointer to the buffer that specifies the data. The format of this data depends on the value of the level parameter. For more /// information, see Network Management Function Buffers. /// /// /// If the function succeeds, the return value is NERR_Success. /// If the function fails, the return value can be one of the following error codes. /// /// /// Return code /// Description /// /// /// ERROR_INVALID_LEVEL /// The level parameter is invalid. /// /// /// ERROR_INVALID_PARAMETER /// One of the function parameters is invalid. /// /// /// /// /// The NetWkstaUserSetInfo function only works locally. Administrator group membership is required. /// /// Domain names in the wkui1101_oth_domains member of the WKSTA_USER_INFO_1101 structure are separated by spaces. An empty /// list is valid. A NULL pointer means to leave the member unmodified. The wkui1101_oth_domains member cannot be set /// with MS-DOS. When setting this element, NetWkstaUserSetInfo rejects the request if the name list was invalid or if a name /// could not be added to one or more of the network adapters managed by the system. /// /// /// If the NetWkstaUserSetInfo function returns ERROR_INVALID_PARAMETER, you can use the parm_err parameter to indicate the /// member of the workstation user information structure that is invalid. (A workstation user information structure begins with /// WKSTA_USER_INFO_ and its format is specified by the level parameter.) The following table lists the value that can be returned in /// the parm_err parameter and the corresponding structure member that is in error. (The prefix wkui*_ indicates that the member can /// begin with multiple prefixes, for example, wkui0_ or wkui1_.) /// /// /// /// Value /// Member /// /// /// WKSTA_OTH_DOMAINS_PARMNUM /// wkui*_oth_domains /// /// /// Examples /// /// The following code sample demonstrates how to set user-specific information for a workstation using a call to the /// NetWkstaUserSetInfo function, specifying information level 1101 ( WKSTA_USER_INFO_1101). /// /// [PInvokeData("lmwksta.h", MSDNShortId = "d48667a3-5ae9-4a7d-9af6-14f08835940d")] public static void NetWkstaUserSetInfo(in T buf, uint level = uint.MaxValue) where T : struct { if (level == uint.MaxValue) level = (uint)GetLevelFromStructure(); var mem = SafeHGlobalHandle.CreateFromStructure(buf); var err = NetWkstaSetInfo(null, level, mem, out var perr); if (err.Succeeded) return; if (err != Win32Error.ERROR_INVALID_PARAMETER) err.ThrowIfFailed(); throw err.GetException($"Invalid parameter. Index: {perr}"); } private static int GetLevelFromStructure() { var m = System.Text.RegularExpressions.Regex.Match(typeof(T).Name, @"(\d+)$"); var i = 0; if (m.Success) int.TryParse(m.Value, out i); return i; } } }