using System; using System.Runtime.InteropServices; using Vanara.Extensions; using Vanara.InteropServices; using FILETIME = System.Runtime.InteropServices.ComTypes.FILETIME; namespace Vanara.PInvoke { /// Functions, structures and constants from wcmapi.h. public static partial class WcmApi { /// The highest version of the Wi-Fi Direct API the client supports. public const uint WCM_UNKNOWN_DATAPLAN_STATUS = uint.MaxValue; /// The WCM_CONNECTION_COST enumerated type determines the connection cost type and flags. // https://docs.microsoft.com/en-us/windows/win32/api/wcmapi/ne-wcmapi-wcm_connection_cost typedef enum _WCM_CONNECTION_COST { // WCM_CONNECTION_COST_UNKNOWN, WCM_CONNECTION_COST_UNRESTRICTED, WCM_CONNECTION_COST_FIXED, WCM_CONNECTION_COST_VARIABLE, // WCM_CONNECTION_COST_OVERDATALIMIT, WCM_CONNECTION_COST_CONGESTED, WCM_CONNECTION_COST_ROAMING, // WCM_CONNECTION_COST_APPROACHINGDATALIMIT } WCM_CONNECTION_COST, *PWCM_CONNECTION_COST; [PInvokeData("wcmapi.h", MSDNShortId = "1ab36082-3394-42e3-aee3-01df5e211ba7")] [Flags] public enum WCM_CONNECTION_COST { /// Connection cost information is not available. WCM_CONNECTION_COST_UNKNOWN = 0x0, /// The connection is unlimited and has unrestricted usage constraints. WCM_CONNECTION_COST_UNRESTRICTED = 0x1, /// Usage counts toward a fixed allotment of data which the user has already paid for (or agreed to pay for). WCM_CONNECTION_COST_FIXED = 0x2, /// The connection cost is on a per-byte basis. WCM_CONNECTION_COST_VARIABLE = 0x4, /// The connection has exceeded its data limit. WCM_CONNECTION_COST_OVERDATALIMIT = 0x10000, /// The connection is throttled due to high traffic. WCM_CONNECTION_COST_CONGESTED = 0x20000, /// The connection is outside of the home network. WCM_CONNECTION_COST_ROAMING = 0x40000, /// The connection is approaching its data limit. WCM_CONNECTION_COST_APPROACHINGDATALIMIT = 0x80000, } /// The WCM_CONNECTION_COST_SOURCE enumerated type specifies the source that provides connection cost information. // https://docs.microsoft.com/en-us/windows/win32/api/wcmapi/ne-wcmapi-wcm_connection_cost_source typedef enum // _WCM_CONNECTION_COST_SOURCE { WCM_CONNECTION_COST_SOURCE_DEFAULT, WCM_CONNECTION_COST_SOURCE_GP, WCM_CONNECTION_COST_SOURCE_USER, // WCM_CONNECTION_COST_SOURCE_OPERATOR } WCM_CONNECTION_COST_SOURCE, *PWCM_CONNECTION_COST_SOURCE; [PInvokeData("wcmapi.h", MSDNShortId = "cd9e5562-dd50-46fc-be11-0ea89e6933c0")] public enum WCM_CONNECTION_COST_SOURCE { /// Default source. WCM_CONNECTION_COST_SOURCE_DEFAULT, /// The source for the connection cost is Group Policy. WCM_CONNECTION_COST_SOURCE_GP, /// The source for the connection cost is the user. WCM_CONNECTION_COST_SOURCE_USER, /// The source for the connection cost is the operator. WCM_CONNECTION_COST_SOURCE_OPERATOR, } /// The WCM_MEDIA_TYPE enumerated type specifies the type of media for a connection. // https://docs.microsoft.com/en-us/windows/win32/api/wcmapi/ne-wcmapi-wcm_media_type typedef enum _WCM_MEDIA_TYPE { // wcm_media_unknown, wcm_media_ethernet, wcm_media_wlan, wcm_media_mbn, wcm_media_invalid, wcm_media_max } WCM_MEDIA_TYPE, *PWCM_MEDIA_TYPE; [PInvokeData("wcmapi.h", MSDNShortId = "76617f35-c7a1-49ff-a630-482f2fe45dd7")] public enum WCM_MEDIA_TYPE { /// Unknown media. wcm_media_unknown, /// Ethernet. wcm_media_ethernet, /// WLAN. wcm_media_wlan, /// Mobile broadband. wcm_media_mbn, /// Invalid type. wcm_media_invalid, /// Maximum value for testing purposes. wcm_media_max, } /// The WCM_PROPERTY enumerated type specifies a property of a connection. // https://docs.microsoft.com/en-us/windows/win32/api/wcmapi/ne-wcmapi-wcm_property typedef enum _WCM_PROPERTY { // wcm_global_property_domain_policy, wcm_global_property_minimize_policy, wcm_global_property_roaming_policy, // wcm_global_property_powermanagement_policy, wcm_intf_property_connection_cost, wcm_intf_property_dataplan_status, // wcm_intf_property_hotspot_profile } WCM_PROPERTY, *PWCM_PROPERTY; [PInvokeData("wcmapi.h", MSDNShortId = "4cb5f7aa-2f06-4a8a-814d-f8e01b496fb9")] public enum WCM_PROPERTY { /// Domain policy. [CorrespondingType(typeof(WCM_POLICY_VALUE))] wcm_global_property_domain_policy, /// Minimize policy. [CorrespondingType(typeof(WCM_POLICY_VALUE))] wcm_global_property_minimize_policy, /// Roaming policy. [CorrespondingType(typeof(WCM_POLICY_VALUE))] wcm_global_property_roaming_policy, /// Power management policy. [CorrespondingType(typeof(WCM_POLICY_VALUE))] wcm_global_property_powermanagement_policy, /// The cost level and flags for the connection [CorrespondingType(typeof(WCM_CONNECTION_COST_DATA))] wcm_intf_property_connection_cost, /// The plan data associated with the new cost. [CorrespondingType(typeof(WCM_DATAPLAN_STATUS))] wcm_intf_property_dataplan_status, /// The hotspot profile. [CorrespondingType(typeof(string))] wcm_intf_property_hotspot_profile, } /// The WcmFreeMemory function is used to release memory resources allocated by the WCM functions. /// Pointer to the memory to be freed. /// This function does not return a value. // https://docs.microsoft.com/en-us/windows/win32/api/wcmapi/nf-wcmapi-wcmfreememory void WcmFreeMemory( __deallocate(Mem)PVOID // pMemory ); [DllImport(Lib.Wcmapi, SetLastError = false, ExactSpelling = true)] [PInvokeData("wcmapi.h", MSDNShortId = "43377f58-9702-472d-874a-898f29b743d8")] public static extern void WcmFreeMemory(IntPtr pMemory); /// /// The WcmGetProfileList function retrieves a list of profiles in preferred order, descending from the most preferred to the /// least preferred. The list includes all WCM-managed auto-connect profiles across all WCM-managed media types. /// /// /// Type: PVOID /// Reserved. /// /// /// Type: PWCM_PROFILE_INFO_LIST* /// The list of profiles. /// /// /// Type: DWORD /// Returns ERROR_SUCCESS if successful, or an error value otherwise. /// // https://docs.microsoft.com/en-us/windows/win32/api/wcmapi/nf-wcmapi-wcmgetprofilelist DWORD WcmGetProfileList( PVOID pReserved, // WCM_PROFILE_INFO_LIST **ppProfileList ); [DllImport(Lib.Wcmapi, SetLastError = false, ExactSpelling = true)] [PInvokeData("wcmapi.h", MSDNShortId = "ceef4e74-3c67-4267-a82a-9912c039f41c")] public static extern Win32Error WcmGetProfileList([Optional] IntPtr pReserved, [MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(WcmMarshaler))] out WCM_PROFILE_INFO_LIST ppProfileList); /// The WcmQueryProperty function retrieves the value of a specified WCM property. /// /// Type: const GUID* /// The interface to query. For global properties, this parameter is NULL. /// /// /// Type: LPCWSTR /// /// The name of the profile. If querying a non-global property ( connection_cost, dataplan_status, or /// hotspot_profile), the profile must be specified or the call will fail. /// /// /// /// Type: WCM_PROPERTY /// The WCM property to query. /// /// /// Type: PVOID /// Reserved. /// /// /// Type: PDWORD /// The size of the returned property value. /// /// /// Type: PBYTE* /// The returned property value. /// /// /// Type: DWORD /// Returns ERROR_SUCCESS if successful, or an error value otherwise. /// /// /// /// The type of data stored in the ppData parameter will vary, depending on which property is being queried. This table shows the /// data type of each property. /// /// /// /// Property name /// Data type /// /// /// wcm_global_property_domain_policy /// WCM_POLICY_VALUE /// /// /// wcm_global_property_minimize_policy /// WCM_POLICY_VALUE /// /// /// wcm_global_property_roaming_policy /// WCM_POLICY_VALUE /// /// /// wcm_global_property_powermanagement_policy /// WCM_POLICY_VALUE /// /// /// wcm_intf_property_connection_cost /// WCM_CONNECTION_COST_DATA /// /// /// wcm_intf_property_dataplan_status /// WCM_DATAPLAN_STATUS /// /// /// wcm_intf_property_hotspot_profile /// Contains zero-length output. /// /// /// // https://docs.microsoft.com/en-us/windows/win32/api/wcmapi/nf-wcmapi-wcmqueryproperty DWORD WcmQueryProperty( const GUID // *pInterface, LPCWSTR strProfileName, WCM_PROPERTY Property, PVOID pReserved, PDWORD pdwDataSize, PBYTE *ppData ); [DllImport(Lib.Wcmapi, SetLastError = false, ExactSpelling = true)] [PInvokeData("wcmapi.h", MSDNShortId = "07c0993e-2892-4908-be3f-d24210ccc300")] public static extern Win32Error WcmQueryProperty(in Guid pInterface, [Optional, MarshalAs(UnmanagedType.LPWStr)] string strProfileName, WCM_PROPERTY Property, [Optional] IntPtr pReserved, out uint pdwDataSize, out SafeWcmMemory ppData); /// The WcmQueryProperty function retrieves the value of a specified WCM property. /// /// Type: const GUID* /// The interface to query. For global properties, this parameter is NULL. /// /// /// Type: LPCWSTR /// /// The name of the profile. If querying a non-global property ( connection_cost, dataplan_status, or /// hotspot_profile), the profile must be specified or the call will fail. /// /// /// /// Type: WCM_PROPERTY /// The WCM property to query. /// /// /// Type: PVOID /// Reserved. /// /// /// Type: PDWORD /// The size of the returned property value. /// /// /// Type: PBYTE* /// The returned property value. /// /// /// Type: DWORD /// Returns ERROR_SUCCESS if successful, or an error value otherwise. /// /// /// /// The type of data stored in the ppData parameter will vary, depending on which property is being queried. This table shows the /// data type of each property. /// /// /// /// Property name /// Data type /// /// /// wcm_global_property_domain_policy /// WCM_POLICY_VALUE /// /// /// wcm_global_property_minimize_policy /// WCM_POLICY_VALUE /// /// /// wcm_global_property_roaming_policy /// WCM_POLICY_VALUE /// /// /// wcm_global_property_powermanagement_policy /// WCM_POLICY_VALUE /// /// /// wcm_intf_property_connection_cost /// WCM_CONNECTION_COST_DATA /// /// /// wcm_intf_property_dataplan_status /// WCM_DATAPLAN_STATUS /// /// /// wcm_intf_property_hotspot_profile /// Contains zero-length output. /// /// /// // https://docs.microsoft.com/en-us/windows/win32/api/wcmapi/nf-wcmapi-wcmqueryproperty DWORD WcmQueryProperty( const GUID // *pInterface, LPCWSTR strProfileName, WCM_PROPERTY Property, PVOID pReserved, PDWORD pdwDataSize, PBYTE *ppData ); [DllImport(Lib.Wcmapi, SetLastError = false, ExactSpelling = true)] [PInvokeData("wcmapi.h", MSDNShortId = "07c0993e-2892-4908-be3f-d24210ccc300")] public static extern Win32Error WcmQueryProperty([Optional] IntPtr pInterface, [Optional] IntPtr strProfileName, WCM_PROPERTY Property, [Optional] IntPtr pReserved, out uint pdwDataSize, out SafeWcmMemory ppData); /// The WcmQueryProperty function retrieves the value of a specified WCM property. /// The type of the requested property. /// /// Type: const GUID* /// The interface to query. For global properties, this parameter is NULL. /// /// /// Type: LPCWSTR /// /// The name of the profile. If querying a non-global property ( connection_cost, dataplan_status, or /// hotspot_profile), the profile must be specified or the call will fail. /// /// /// /// Type: WCM_PROPERTY /// The WCM property to query. /// /// The returned property value. /// /// Type: DWORD /// Returns ERROR_SUCCESS if successful, or an error value otherwise. /// /// /// /// The type of data stored in the ppData parameter will vary, depending on which property is being queried. This table shows the /// data type of each property. /// /// /// /// Property name /// Data type /// /// /// wcm_global_property_domain_policy /// WCM_POLICY_VALUE /// /// /// wcm_global_property_minimize_policy /// WCM_POLICY_VALUE /// /// /// wcm_global_property_roaming_policy /// WCM_POLICY_VALUE /// /// /// wcm_global_property_powermanagement_policy /// WCM_POLICY_VALUE /// /// /// wcm_intf_property_connection_cost /// WCM_CONNECTION_COST_DATA /// /// /// wcm_intf_property_dataplan_status /// WCM_DATAPLAN_STATUS /// /// /// wcm_intf_property_hotspot_profile /// Contains zero-length output. /// /// /// [PInvokeData("wcmapi.h", MSDNShortId = "07c0993e-2892-4908-be3f-d24210ccc300")] public static Win32Error WcmQueryProperty(WCM_PROPERTY Property, [Optional] Guid? pInterface, [Optional] string strProfileName, out T ppData) { ppData = default; if (!CorrespondingTypeAttribute.CanGet(Property, typeof(T))) return Win32Error.ERROR_DATATYPE_MISMATCH; SafeWcmMemory mem; uint sz; Win32Error res; if (pInterface.HasValue) res = WcmQueryProperty(pInterface.Value, strProfileName, Property, default, out sz, out mem); else res = WcmQueryProperty(IntPtr.Zero, IntPtr.Zero, Property, default, out sz, out mem); using (mem) { if (res.Succeeded) { if (typeof(T).IsValueType) ppData = mem.ToStructure(sz); else if (typeof(T) == typeof(string)) ppData = (T)(object)mem.ToString(sz); else return Win32Error.ERROR_DATATYPE_MISMATCH; } } return res; } /// The WcmSetProfileList function reorders a profile list or a subset of a profile list. /// /// Type: WCM_PROFILE_INFO_LIST* /// /// The list of profiles to be reordered, provided in the preferred order (descending from the most preferred to the least preferred). /// /// /// /// Type: DWORD /// Specifies the position in the list to start the reorder. /// /// /// Type: BOOL /// /// True if any profiles in pProfileList which do not exist should be ignored; the call will proceed with the remainder of the list. /// False if the call should fail without modifying the profile order if any profiles in pProfileList do not exist. /// /// /// /// Type: PVOID /// Reserved. /// /// /// Type: DWORD /// Returns ERROR_SUCCESS if successful, or an error value otherwise. /// // https://docs.microsoft.com/en-us/windows/win32/api/wcmapi/nf-wcmapi-wcmsetprofilelist DWORD WcmSetProfileList( // WCM_PROFILE_INFO_LIST *pProfileList, DWORD dwPosition, BOOL fIgnoreUnknownProfiles, PVOID pReserved ); [DllImport(Lib.Wcmapi, SetLastError = false, ExactSpelling = true)] [PInvokeData("wcmapi.h", MSDNShortId = "c5efb2e8-c4c4-4e13-9f7a-ea2a40744655")] public static extern Win32Error WcmSetProfileList([In] WCM_PROFILE_INFO_LIST pProfileList, uint dwPosition, [MarshalAs(UnmanagedType.Bool)] bool fIgnoreUnknownProfiles, [Optional] IntPtr pReserved); /// The WcmSetProperty function sets the value of a WCM property. /// /// Type: const GUID* /// The interface to set. For global properties, this parameter is NULL. /// /// /// Type: LPCWSTR /// The profile name. /// /// /// Type: WCM_PROPERTY /// The WCM property to set. /// /// /// Type: PVOID /// Reserved. /// /// /// Type: DWORD /// The size of the new property value. /// /// /// Type: const BYTE* /// The new property value. /// /// /// Type: DWORD /// Returns ERROR_SUCCESS if successful, or an error value otherwise. /// /// /// /// The type of data stored in the pbData parameter will vary, depending on which property is being set. This table shows the data /// type of each property. /// /// /// /// Property name /// Data type /// /// /// wcm_global_property_domain_policy /// WCM_POLICY_VALUE /// /// /// wcm_global_property_minimize_policy /// WCM_POLICY_VALUE /// /// /// wcm_global_property_roaming_policy /// WCM_POLICY_VALUE /// /// /// wcm_global_property_powermanagement_policy /// WCM_POLICY_VALUE /// /// /// wcm_intf_property_connection_cost /// WCM_CONNECTION_COST_DATA /// /// /// wcm_intf_property_dataplan_status /// WCM_DATAPLAN_STATUS /// /// /// wcm_intf_property_hotspot_profile /// Variable-length XML string. See the HotSpotProfile schema for more information. /// /// /// // https://docs.microsoft.com/en-us/windows/win32/api/wcmapi/nf-wcmapi-wcmsetproperty DWORD WcmSetProperty( const GUID *pInterface, // LPCWSTR strProfileName, WCM_PROPERTY Property, PVOID pReserved, DWORD dwDataSize, const BYTE *pbData ); [DllImport(Lib.Wcmapi, SetLastError = false, ExactSpelling = true)] [PInvokeData("wcmapi.h", MSDNShortId = "79985d5e-a6a1-447c-b12e-11c6022c19a6")] public static extern Win32Error WcmSetProperty(in Guid pInterface, [Optional, MarshalAs(UnmanagedType.LPWStr)] string strProfileName, WCM_PROPERTY Property, [Optional] IntPtr pReserved, uint dwDataSize, [In, Optional] IntPtr pbData); /// The WcmSetProperty function sets the value of a WCM property. /// /// Type: const GUID* /// The interface to set. For global properties, this parameter is NULL. /// /// /// Type: LPCWSTR /// The profile name. /// /// /// Type: WCM_PROPERTY /// The WCM property to set. /// /// /// Type: PVOID /// Reserved. /// /// /// Type: DWORD /// The size of the new property value. /// /// /// Type: const BYTE* /// The new property value. /// /// /// Type: DWORD /// Returns ERROR_SUCCESS if successful, or an error value otherwise. /// /// /// /// The type of data stored in the pbData parameter will vary, depending on which property is being set. This table shows the data /// type of each property. /// /// /// /// Property name /// Data type /// /// /// wcm_global_property_domain_policy /// WCM_POLICY_VALUE /// /// /// wcm_global_property_minimize_policy /// WCM_POLICY_VALUE /// /// /// wcm_global_property_roaming_policy /// WCM_POLICY_VALUE /// /// /// wcm_global_property_powermanagement_policy /// WCM_POLICY_VALUE /// /// /// wcm_intf_property_connection_cost /// WCM_CONNECTION_COST_DATA /// /// /// wcm_intf_property_dataplan_status /// WCM_DATAPLAN_STATUS /// /// /// wcm_intf_property_hotspot_profile /// Variable-length XML string. See the HotSpotProfile schema for more information. /// /// /// // https://docs.microsoft.com/en-us/windows/win32/api/wcmapi/nf-wcmapi-wcmsetproperty DWORD WcmSetProperty( const GUID *pInterface, // LPCWSTR strProfileName, WCM_PROPERTY Property, PVOID pReserved, DWORD dwDataSize, const BYTE *pbData ); [DllImport(Lib.Wcmapi, SetLastError = false, ExactSpelling = true)] [PInvokeData("wcmapi.h", MSDNShortId = "79985d5e-a6a1-447c-b12e-11c6022c19a6")] public static extern Win32Error WcmSetProperty([Optional] IntPtr pInterface, [Optional, MarshalAs(UnmanagedType.LPWStr)] string strProfileName, WCM_PROPERTY Property, [Optional] IntPtr pReserved, uint dwDataSize, [In, Optional] IntPtr pbData); /// The WcmSetProperty function sets the value of a WCM property. /// The type of the value to set. /// /// Type: const GUID* /// The interface to set. For global properties, this parameter is NULL. /// /// /// Type: LPCWSTR /// The profile name. /// /// /// Type: WCM_PROPERTY /// The WCM property to set. /// /// /// Type: const BYTE* /// The new property value. /// /// /// Type: DWORD /// Returns ERROR_SUCCESS if successful, or an error value otherwise. /// /// /// /// The type of data stored in the pbData parameter will vary, depending on which property is being set. This table shows the data /// type of each property. /// /// /// /// Property name /// Data type /// /// /// wcm_global_property_domain_policy /// WCM_POLICY_VALUE /// /// /// wcm_global_property_minimize_policy /// WCM_POLICY_VALUE /// /// /// wcm_global_property_roaming_policy /// WCM_POLICY_VALUE /// /// /// wcm_global_property_powermanagement_policy /// WCM_POLICY_VALUE /// /// /// wcm_intf_property_connection_cost /// WCM_CONNECTION_COST_DATA /// /// /// wcm_intf_property_dataplan_status /// WCM_DATAPLAN_STATUS /// /// /// wcm_intf_property_hotspot_profile /// Variable-length XML string. See the HotSpotProfile schema for more information. /// /// /// [PInvokeData("wcmapi.h", MSDNShortId = "79985d5e-a6a1-447c-b12e-11c6022c19a6")] public static Win32Error WcmSetProperty(WCM_PROPERTY Property, [Optional] Guid? pInterface, [Optional] string strProfileName, in T data) { using var mem = data is string s ? new SafeCoTaskMemHandle(s) : SafeCoTaskMemHandle.CreateFromStructure(data); if (pInterface.HasValue) return WcmSetProperty(pInterface.Value, strProfileName, Property, default, mem.Size, mem); return WcmSetProperty(IntPtr.Zero, strProfileName, Property, default, mem.Size, mem); } /// The WCM_BILLING_CYCLE_INFO structure specifies information about the billing cycle. // https://docs.microsoft.com/en-us/windows/win32/api/wcmapi/ns-wcmapi-wcm_billing_cycle_info typedef struct WCM_BILLING_CYCLE_INFO // { FILETIME StartDate; WCM_TIME_INTERVAL Duration; BOOL Reset; } WCM_BILLING_CYCLE_INFO; [PInvokeData("wcmapi.h", MSDNShortId = "5cfcdfb7-aa33-4582-ba17-e1a305b830f5")] [StructLayout(LayoutKind.Sequential)] public struct WCM_BILLING_CYCLE_INFO { /// /// Type: FILETIME /// Specifies the start date of the cycle. /// public FILETIME StartDate; /// /// Type: WCM_TIME_INTERVAL /// Specifies the billing cycle duration. /// public WCM_TIME_INTERVAL Duration; /// /// Type: BOOL /// /// True if at the end of the billing cycle, a new billing cycle of the same duration will start. False if the service will /// terminate at the end of the billing cycle. /// /// [MarshalAs(UnmanagedType.Bool)] public bool Reset; } /// The WCM_CONNECTION_COST_DATA structure specifies information about a connection cost. // https://docs.microsoft.com/en-us/windows/win32/api/wcmapi/ns-wcmapi-wcm_connection_cost_data typedef struct // _WCM_CONNECTION_COST_DATA { DWORD ConnectionCost; WCM_CONNECTION_COST_SOURCE CostSource; } WCM_CONNECTION_COST_DATA, *PWCM_CONNECTION_COST_DATA; [PInvokeData("wcmapi.h", MSDNShortId = "18fcc708-74b1-408f-a7ee-64455742324d")] [StructLayout(LayoutKind.Sequential)] public struct WCM_CONNECTION_COST_DATA { /// /// Type: DWORD /// Specifies the connection cost type. /// This must include one (and only one) of the following flags: /// /// /// Value /// Meaning /// /// /// WCM_CONNECTION_COST_UNKNOWN 0x0 /// Connection cost information is not available. /// /// /// WCM_CONNECTION_COST_UNRESTRICTED 0x1 /// The connection is unlimited and has unrestricted usage constraints. /// /// /// WCM_CONNECTION_COST_FIXED 0x2 /// Usage counts toward a fixed allotment of data which the user has already paid for (or agreed to pay for). /// /// /// WCM_CONNECTION_COST_VARIABLE 0x4 /// The connection cost is on a per-byte basis. /// /// /// And may include any combination of the following flags: /// /// /// Value /// Meaning /// /// /// WCM_CONNECTION_COST_OVERDATALIMIT 0x10000 /// The connection has exceeded its data limit. /// /// /// WCM_CONNECTION_COST_CONGESTED 0x20000 /// The connection is throttled due to high traffic. /// /// /// WCM_CONNECTION_COST_ROAMING 0x40000 /// The connection is outside of the home network. /// /// /// public WCM_CONNECTION_COST ConnectionCost; /// /// Type: WCM_CONNECTION_COST_SOURCE /// Specifies the cost source. /// public WCM_CONNECTION_COST_SOURCE CostSource; } /// The WCM_DATAPLAN_STATUS structure specifies subscription information for a network connection. // https://docs.microsoft.com/en-us/windows/win32/api/wcmapi/ns-wcmapi-wcm_dataplan_status typedef struct _WCM_DATAPLAN_STATUS { // WCM_USAGE_DATA UsageData; DWORD DataLimitInMegabytes; DWORD InboundBandwidthInKbps; DWORD OutboundBandwidthInKbps; // WCM_BILLING_CYCLE_INFO BillingCycle; DWORD MaxTransferSizeInMegabytes; DWORD Reserved; } WCM_DATAPLAN_STATUS, *PWCM_DATAPLAN_STATUS; [PInvokeData("wcmapi.h", MSDNShortId = "6ed0f05c-a9f8-49bb-9fb0-b91af8594d76")] [StructLayout(LayoutKind.Sequential)] public struct WCM_DATAPLAN_STATUS { /// /// Type: WCM_USAGE_DATA /// Contains usage data. /// public WCM_USAGE_DATA UsageData; /// /// Type: DWORD /// Specifies the data limit, in megabytes. /// public uint DataLimitInMegabytes; /// /// Type: DWORD /// Specifies the inbound bandwidth, in kilobits per second. /// public uint InboundBandwidthInKbps; /// /// Type: DWORD /// Specifies the outbound bandwidth, in kilobits per second. /// public uint OutboundBandwidthInKbps; /// /// Type: WCM_BILLING_CYCLE_INFO /// Contains information about the billing cycle. /// public WCM_BILLING_CYCLE_INFO BillingCycle; /// /// Type: DWORD /// Specifies the maximum size of a file that can be transferred, in megabytes. /// public uint MaxTransferSizeInMegabytes; /// /// Type: DWORD /// Reserved. /// public uint Reserved; } /// The WCM_POLICY_VALUE structure contains information about the current value of a policy. // https://docs.microsoft.com/en-us/windows/win32/api/wcmapi/ns-wcmapi-wcm_policy_value typedef struct _WCM_POLICY_VALUE { BOOL // fValue; BOOL fIsGroupPolicy; } WCM_POLICY_VALUE, *PWCM_POLICY_VALUE; [PInvokeData("wcmapi.h", MSDNShortId = "0f259661-723b-4c76-8652-c86e0b8c9ebf")] [StructLayout(LayoutKind.Sequential)] public struct WCM_POLICY_VALUE { /// /// Type: BOOL /// True if the policy is enabled; otherwise, false. /// [MarshalAs(UnmanagedType.Bool)] public bool fValue; /// /// Type: BOOL /// True if the current value was provided by Group Policy; otherwise, false. /// [MarshalAs(UnmanagedType.Bool)] public bool fIsGroupPolicy; } /// The WCM_PROFILE_INFO structure contains information about a specific profile. // https://docs.microsoft.com/en-us/windows/win32/api/wcmapi/ns-wcmapi-wcm_profile_info typedef struct _WCM_PROFILE_INFO { WCHAR // strProfileName[WCM_MAX_PROFILE_NAME]; GUID AdapterGUID; WCM_MEDIA_TYPE Media; } WCM_PROFILE_INFO, *PWCM_PROFILE_INFO; [PInvokeData("wcmapi.h", MSDNShortId = "bf917afa-c6c5-408a-bd34-b4a4c7b991b9")] [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] public struct WCM_PROFILE_INFO { /// /// Type: WCHAR[WCM_MAX_PROFILE_NAME] /// The profile name. /// [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)] public string strProfileName; /// /// Type: GUID /// The GUID of the adapter. /// public Guid AdapterGUID; /// /// Type: WCM_MEDIA_TYPE /// The media type for the profile. /// public WCM_MEDIA_TYPE Media; } /// The WCM_PROFILE_INFO_LIST structure contains a list of profiles in preferred order. // https://docs.microsoft.com/en-us/windows/win32/api/wcmapi/ns-wcmapi-wcm_profile_info_list typedef struct _WCM_PROFILE_INFO_LIST { // DWORD dwNumberOfItems; #if ... WCM_PROFILE_INFO *ProfileInfo[]; #else WCM_PROFILE_INFO ProfileInfo[1]; #endif } // WCM_PROFILE_INFO_LIST, *PWCM_PROFILE_INFO_LIST; [PInvokeData("wcmapi.h", MSDNShortId = "73ddb610-233a-470b-900d-ae62a1e7121a")] [VanaraMarshaler(typeof(SafeAnysizeStructMarshaler), nameof(dwNumberOfItems))] [StructLayout(LayoutKind.Sequential)] public class WCM_PROFILE_INFO_LIST { /// /// Type: DWORD /// The number of profiles in the list. /// public uint dwNumberOfItems; /// /// Type: WCM_PROFILE_INFO[1] /// Information about each profile. /// [MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)] public WCM_PROFILE_INFO[] ProfileInfo; } /// The WCM_TIME_INTERVAL structure defines a time interval. // https://docs.microsoft.com/en-us/windows/win32/api/wcmapi/ns-wcmapi-wcm_time_interval typedef struct _WCM_TIME_INTERVAL { WORD // wYear; WORD wMonth; WORD wDay; WORD wHour; WORD wMinute; WORD wSecond; WORD wMilliseconds; } WCM_TIME_INTERVAL; [PInvokeData("wcmapi.h", MSDNShortId = "7744a577-5f3d-4cdd-b74d-a1430ea20b37")] [StructLayout(LayoutKind.Sequential)] public struct WCM_TIME_INTERVAL { /// /// Type: WORD /// Years. /// public ushort wYear; /// /// Type: WORD /// Months. /// public ushort wMonth; /// /// Type: WORD /// Days. /// public ushort wDay; /// /// Type: WORD /// Hours. /// public ushort wHour; /// /// Type: WORD /// Minutes. /// public ushort wMinute; /// /// Type: WORD /// Seconds. /// public ushort wSecond; /// /// Type: WORD /// Milliseconds. /// public ushort wMilliseconds; } /// The WCM_USAGE_DATA structure contains information related to connection usage. // https://docs.microsoft.com/en-us/windows/win32/api/wcmapi/ns-wcmapi-wcm_usage_data typedef struct _WCM_USAGE_DATA { DWORD // UsageInMegabytes; FILETIME LastSyncTime; } WCM_USAGE_DATA, *PWCM_USAGE_DATA; [PInvokeData("wcmapi.h", MSDNShortId = "c6a483cf-d392-495f-854d-ccc782b30aa5")] [StructLayout(LayoutKind.Sequential)] public struct WCM_USAGE_DATA { /// /// Type: DWORD /// The connection usage, in megabytes. /// public uint UsageInMegabytes; /// /// Type: FILETIME /// Specifies the last time that usage information was reconciled with the carrier's billing system. /// public FILETIME LastSyncTime; } /// Provides a for WCM memory that is disposed using . public class SafeWcmMemory : SafeHANDLE { /// Initializes a new instance of the class and assigns an existing handle. /// An object that represents the pre-existing handle to use. /// /// to reliably release the handle during the finalization phase; otherwise, (not recommended). /// public SafeWcmMemory(IntPtr preexistingHandle, bool ownsHandle = true) : base(preexistingHandle, ownsHandle) { } /// Initializes a new instance of the class. private SafeWcmMemory() : base() { } /// Converts this memory to a string value. /// If known, the total number of bytes allocated to the native memory. /// A that represents this instance. public string ToString(SizeT allocatedBytes) => StringHelper.GetString(handle, CharSet.Unicode, allocatedBytes); /// /// Marshals data from an unmanaged block of memory to a newly allocated managed object of the type specified by a generic type parameter. /// /// The type of the object to which the data is to be copied. This must be a structure. /// If known, the total number of bytes allocated to the native memory. /// A managed object that contains the requested data. public T ToStructure(SizeT allocatedBytes = default) => handle.ToStructure(allocatedBytes); /// Performs an implicit conversion from to . /// The memory. /// The resulting instance from the conversion. public static implicit operator IntPtr(SafeWcmMemory mem) => mem.handle; /// protected override bool InternalReleaseHandle() { WcmFreeMemory(handle); return true; } } internal class WcmMarshaler : ICustomMarshaler { private WcmMarshaler(string _) { } /// Gets the instance. /// The cookie. /// public static ICustomMarshaler GetInstance(string cookie) => new WcmMarshaler(cookie); void ICustomMarshaler.CleanUpManagedData(object ManagedObj) => throw new NotImplementedException(); void ICustomMarshaler.CleanUpNativeData(IntPtr pNativeData) => WcmFreeMemory(pNativeData); int ICustomMarshaler.GetNativeDataSize() => -1; IntPtr ICustomMarshaler.MarshalManagedToNative(object ManagedObj) => throw new NotImplementedException(); object ICustomMarshaler.MarshalNativeToManaged(IntPtr pNativeData) => typeof(T) == typeof(string) ? StringHelper.GetString(pNativeData, CharSet.Unicode) : (object)pNativeData.ToStructure(); } } }