using System; using System.Runtime.InteropServices; using System.Text; using static Vanara.PInvoke.Ole32; namespace Vanara.PInvoke { /// Interfaces and constants for Windows Connect Now. public static partial class WcnApi { /// Flags for WCN_VENDOR_EXTENSION_SPEC [Flags] public enum WCN_FLAG : uint { /// The vendor extension was not available before the session started. The vendor extension is not secure. WCN_FLAG_DISCOVERY_VE = 0x0001, /// /// The vendor extension is authentic. Only devices that pass authentication can read or write authenticated vendor extensions. /// WCN_FLAG_AUTHENTICATED_VE = 0x0002, /// /// The vendor extension is authentic and encrypted. In addition to the guarantee of authenticated vendor extensions, vendor /// extensions are encrypted before transmission. /// WCN_FLAG_ENCRYPTED_VE = 0x0004, } /// The WCN_PASSWORD_TYPE enumeration defines the authentication that will be used in a WPS session. // https://docs.microsoft.com/en-us/windows/win32/api/wcndevice/ne-wcndevice-wcn_password_type typedef enum tagWCN_PASSWORD_TYPE { // WCN_PASSWORD_TYPE_PUSH_BUTTON, WCN_PASSWORD_TYPE_PIN, WCN_PASSWORD_TYPE_PIN_REGISTRAR_SPECIFIED, WCN_PASSWORD_TYPE_OOB_SPECIFIED, // WCN_PASSWORD_TYPE_WFDS } WCN_PASSWORD_TYPE; [PInvokeData("wcndevice.h", MSDNShortId = "NE:wcndevice.tagWCN_PASSWORD_TYPE")] public enum WCN_PASSWORD_TYPE { /// /// Indicates the device uses a WPS button interface to put the device into wireless provisioning mode. If this value is /// specified when calling IWCNDevice::SetPassword, set dwPasswordLength to zero and pbPassword to NULL. /// WCN_PASSWORD_TYPE_PUSH_BUTTON = 0, /// /// Indicates that authentication is secured via a PIN. The user must provide the PIN of the device. Usually, the PIN is a 4 or /// 8-digit number printed on a label attached to the device, or displayed on the screen. If this value is specified when /// calling IWCNDevice::SetPassword, set dwPasswordLength to the number of digits in the password, and pbPassword to point to a /// buffer containing the ASCII representation of the pin. /// WCN_PASSWORD_TYPE_PIN, /// Indicates that authentication is secured via a PIN, as above, but that the PIN is specified by the registrar. WCN_PASSWORD_TYPE_PIN_REGISTRAR_SPECIFIED, /// WCN_PASSWORD_TYPE_OOB_SPECIFIED, /// WCN_PASSWORD_TYPE_WFDS, } /// The WCN_SESSION_STATUS enumeration defines the outcome status of a WPS session. // https://docs.microsoft.com/en-us/windows/win32/api/wcndevice/ne-wcndevice-wcn_session_status typedef enum tagWCN_SESSION_STATUS { // WCN_SESSION_STATUS_SUCCESS, WCN_SESSION_STATUS_FAILURE_GENERIC, WCN_SESSION_STATUS_FAILURE_TIMEOUT } WCN_SESSION_STATUS; [PInvokeData("wcndevice.h", MSDNShortId = "NE:wcndevice.tagWCN_SESSION_STATUS")] public enum WCN_SESSION_STATUS { /// Indicates that the session is successful. WCN_SESSION_STATUS_SUCCESS = 0, /// WCN_SESSION_STATUS_FAILURE_GENERIC, /// WCN_SESSION_STATUS_FAILURE_TIMEOUT, } /// Use this interface to receive a success or failure notification when a Windows Connect Now connect session completes. // https://docs.microsoft.com/en-us/windows/win32/api/wcndevice/nn-wcndevice-iwcnconnectnotify [PInvokeData("wcndevice.h", MSDNShortId = "NN:wcndevice.IWCNConnectNotify")] [ComImport, Guid("C100BE9F-D33A-4a4b-BF23-BBEF4663D017"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] public interface IWCNConnectNotify { /// /// The IWCNConnectNotify::ConnectSucceeded callback method that indicates a successful IWCNDevice::Connect operation. /// /// ... /// /// /// Notification of success does not implicitly indicate that the device is ready, as some devices reboot in order to apply /// settings provided during the IWCNDevice::Connect operation. /// /// /// If the IWCNDevice interface was used to obtain network settings from a device, then the network profile is immediately ready /// for use. /// /// // https://docs.microsoft.com/en-us/windows/win32/api/wcndevice/nf-wcndevice-iwcnconnectnotify-connectsucceeded HRESULT ConnectSucceeded(); [PreserveSig] HRESULT ConnectSucceeded(); /// The IWCNConnectNotify::ConnectFailed callback method indicates a IWCNDevice::Connect failure. /// An HRESULT that specifies the reason for the connection failure. /// This method does not return a value. // https://docs.microsoft.com/en-us/windows/win32/api/wcndevice/nf-wcndevice-iwcnconnectnotify-connectfailed HRESULT // ConnectFailed( HRESULT hrFailure ); [PreserveSig] HRESULT ConnectFailed(HRESULT hrFailure); } /// Use this interface to configure the device and initiate the session. // https://docs.microsoft.com/en-us/windows/win32/api/wcndevice/nn-wcndevice-iwcndevice [PInvokeData("wcndevice.h", MSDNShortId = "NN:wcndevice.IWCNDevice")] [ComImport, Guid("C100BE9C-D33A-4a4b-BF23-BBEF4663D017"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown), CoClass(typeof(WCNDeviceObject))] public interface IWCNDevice { /// /// The IWCNDevice::SetPassword method configures the authentication method value, and if required, a password used for /// the pending session. This method may only be called prior to IWCNDevice::Connect. /// /// /// A WCN_PASSWORD_TYPE value that specifies the authentication method used for the session. /// /// /// Value /// Meaning /// /// /// WCN_PASSWORD_TYPE_PUSH_BUTTON /// Use PushButton authentication. The value of dwPasswordLength must be NULL. /// /// /// WCN_PASSWORD_TYPE_PIN /// Use PIN-based authentication. /// /// /// /// Number of bytes in the buffer pbPassword. /// A byte array of the password, encoded in ASCII. /// /// This method can return one of these values. /// /// /// Return code /// Description /// /// /// S_OK /// The password will be used for the pending session. /// /// /// E_INVALIDARG /// /// The password type is WCN_PASSWORD_TYPE_PUSH_BUTTON and the password length is not zero. The password type is not /// WCN_PASSWORD_TYPE_PUSH_BUTTON or WCN_PASSWORD_TYPE_PIN. /// /// /// /// /// /// The byte array is not NULL-terminated. For example, if the password is a 4-digit PIN, you should pass /// dwPasswordLength as 4 and pbPassword should point to a 4-byte array containing the PIN in ASCII. /// // https://docs.microsoft.com/en-us/windows/win32/api/wcndevice/nf-wcndevice-iwcndevice-setpassword HRESULT SetPassword( // WCN_PASSWORD_TYPE Type, DWORD dwPasswordLength, const BYTE [] pbPassword ); [PreserveSig] HRESULT SetPassword(WCN_PASSWORD_TYPE Type, uint dwPasswordLength, [MarshalAs(UnmanagedType.LPStr)] string pbPassword); /// The IWCNDevice::Connect method initiates the session. /// /// A pointer to the implemented IWCNConnectNotify callback interface which specifies if a connection has been successfully established. /// /// /// This method can return one of these values. /// /// /// Return code /// Description /// /// /// S_OK /// The operation has succeeded. /// /// /// HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED) /// The device does not support the connection options queued via IWCNDevice::Set. /// /// /// WCN_E_PEER_NOT_FOUND /// The device could not be located on the network. /// /// /// /// /// /// After calling this method you may not call any other IWCNDevice 'Set' methods. There is no way to cancel or roll back device /// settings once a connection has been established. /// /// /// NULL can be passed via pNotify, in place of the IWCNConnectNotify callback interface to prevent notification from /// being sent when the connect operation is complete. /// /// // https://docs.microsoft.com/en-us/windows/win32/api/wcndevice/nf-wcndevice-iwcndevice-connect HRESULT Connect( // IWCNConnectNotify *pNotify ); [PreserveSig] HRESULT Connect([In, Optional] IWCNConnectNotify pNotify); /// The IWCNDevice::GetAttribute method gets a cached attribute from the device. /// /// A WCN_ATTRIBUTE_TYPE value that represents a specific attribute value (for example, WCN_PASSWORD_TYPE). /// /// The allocated size, in bytes, of pbBuffer. /// A user-allocated buffer that, on successful return, contains the contents of the attribute. /// On return, contains the size of the attribute in bytes. /// /// This method can return one of these values. /// /// /// Return code /// Description /// /// /// S_OK /// The attribute was retrieved successfully. /// /// /// HRESULT_FROM_WIN32(ERROR_NOT_FOUND) /// The attribute specified is not available. /// /// /// HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER) /// The buffer specified by pbBuffer is not large enough to contain the returned attribute value. /// /// /// /// /// To only query the size of an attribute, a value of 0 (zero) can be passed via dwMaxBufferSize and pdwBufferUsed will be /// filled appropriately. /// // https://docs.microsoft.com/en-us/windows/win32/api/wcndevice/nf-wcndevice-iwcndevice-getattribute HRESULT GetAttribute( // WCN_ATTRIBUTE_TYPE AttributeType, DWORD dwMaxBufferSize, BYTE [] pbBuffer, DWORD *pdwBufferUsed ); [PreserveSig] HRESULT GetAttribute(WCN_ATTRIBUTE_TYPE AttributeType, uint dwMaxBufferSize, [Out] IntPtr pbBuffer, out uint pdwBufferUsed); /// The GetIntegerAttribute method gets a cached attribute from the device as an integer. /// /// A WCN_ATTRIBUTE_TYPE value that represents a specific attribute value (for example, WCN_PASSWORD_TYPE). /// /// Pointer to an unsigned-integer that represents the retrieved attribute value. /// /// This method can return one of these values. /// /// /// Return code /// Description /// /// /// S_OK /// The attribute was retrieved successfully. /// /// /// HRESULT_FROM_WIN32(ERROR_NOT_FOUND) /// The attribute specified is not available. /// /// /// HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER) /// The buffer specified by pbBuffer is not large enough to contain the returned attribute value. /// /// /// HRESULT_FROM_WIN32(ERROR_INVALID_DATATYPE) /// This attribute cannot be expressed as an integer. For example, if it is a string. /// /// /// // https://docs.microsoft.com/en-us/windows/win32/api/wcndevice/nf-wcndevice-iwcndevice-getintegerattribute HRESULT // GetIntegerAttribute( WCN_ATTRIBUTE_TYPE AttributeType, UINT *puInteger ); [PreserveSig] HRESULT GetIntegerAttribute(WCN_ATTRIBUTE_TYPE AttributeType, out uint puInteger); /// The IWCNDevice::GetStringAttribute method gets a cached attribute from the device as a string. /// /// A WCN_ATTRIBUTE_TYPE value that represents a specific attribute value (for example, WCN_PASSWORD_TYPE). If the /// attribute is not natively a string data type (for example, WCN_TYPE_VERSION is natively an integer, and /// WNC_TYPE_SSID is natively a blob), this function will fail with HRESULT_FROM_WIN32(ERROR_INVALID_DATATYPE). /// /// The size of the buffer wszString, in characters. /// /// A user-allocated buffer that, on successful return, contains a NULL-terminated string value of the vendor extension. /// /// /// ... /// /// /// Return code /// Description /// /// /// S_OK /// The attribute was retrieved successfully. /// /// /// HRESULT_FROM_WIN32(ERROR_NOT_FOUND) /// The attribute specified is not available. /// /// /// HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER) /// The buffer specified by wszString is not large enough to contain the returned attribute value. /// /// /// HRESULT_FROM_WIN32(ERROR_INVALID_DATATYPE) /// This attribute cannot be expressed as a string. For example, if it is an integer. /// /// /// // https://docs.microsoft.com/en-us/windows/win32/api/wcndevice/nf-wcndevice-iwcndevice-getstringattribute HRESULT // GetStringAttribute( WCN_ATTRIBUTE_TYPE AttributeType, DWORD cchMaxString, WCHAR [] wszString ); [PreserveSig] HRESULT GetStringAttribute(WCN_ATTRIBUTE_TYPE AttributeType, uint cchMaxString, [MarshalAs(UnmanagedType.LPWStr)] StringBuilder wszString); /// The IWCNDevice::GetNetworkProfile method gets a network profile from the device. /// The allocated size, in characters, of wszProfile. /// A string that specifies the XML WLAN network profile type. /// /// This method can return one of these values. /// /// /// Return code /// Description /// /// /// S_OK /// The network profile was successfully retrieved. /// /// /// /// This function can only be called after IWCNDevice::Connect has been called, and the session has completed successfully. // https://docs.microsoft.com/en-us/windows/win32/api/wcndevice/nf-wcndevice-iwcndevice-getnetworkprofile HRESULT // GetNetworkProfile( DWORD cchMaxStringLength, LPWSTR wszProfile ); [PreserveSig] HRESULT GetNetworkProfile(uint cchMaxStringLength, [MarshalAs(UnmanagedType.LPWStr)] StringBuilder wszProfile); /// /// The IWCNDevice::SetNetworkProfile method queues an XML WLAN profile to be provisioned to the device. This method may /// only be called prior to IWCNDevice::Connect. /// /// The XML WLAN profile XML string. /// /// This method can return one of these values. /// /// /// Return code /// Description /// /// /// S_OK /// The attribute was retrieved successfully. /// /// /// HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED) /// The WLAN profile is not supported for WCN connections. /// /// /// HRESULT_FROM_WIN32(ERROR_BAD_PROFILE) /// The provided XML profile cannot be read. /// /// /// /// /// Currently, the Windows Connect Now API (WCNAPI) supports the following profile types: /// /// /// None (Open or Shared) /// /// /// WEP (Open or Shared) /// /// /// WPA-PSK (TKIP or AES) /// /// /// WPA2-PSK (TKIP or AES) /// /// /// /// If the specified WLAN profile has extraneous settings (like IHV settings), these settings will be ignored. In the event a /// WLAN profile is not compatible with the WCNAPI, an HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED) value is returned. /// /// // https://docs.microsoft.com/en-us/windows/win32/api/wcndevice/nf-wcndevice-iwcndevice-setnetworkprofile HRESULT // SetNetworkProfile( LPCWSTR pszProfileXml ); [PreserveSig] HRESULT SetNetworkProfile([MarshalAs(UnmanagedType.LPWStr)] string pszProfileXml); /// The GetVendorExtension method gets a cached vendor extension from the device. /// /// A pointer to a user-defined WCN_VENDOR_EXTENSION_SPEC structure that describes the vendor extension to query for. /// /// The size, in bytes, of pbBuffer. /// An allocated buffer that, on return, contains the contents of the vendor extension. /// On return, contains the size of the vendor extension in bytes. /// /// This method can return one of these values. /// /// /// Return code /// Description /// /// /// S_OK /// The vendor extension was retrieved successfully. /// /// /// HRESULT_FROM_WIN32(ERROR_NOT_FOUND) /// The vendor extension specified is not available. /// /// /// HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER) /// The buffer specified by pbBuffer is not large enough to contain the returned vendor extension. /// /// /// /// /// To query the size of a vendor extension, you can pass a value of 0 with the dwMaxBufferSize parameter, and pdwBufferUsed /// will receive the size. /// // https://docs.microsoft.com/en-us/windows/win32/api/wcndevice/nf-wcndevice-iwcndevice-getvendorextension HRESULT // GetVendorExtension( const WCN_VENDOR_EXTENSION_SPEC *pVendorExtSpec, DWORD dwMaxBufferSize, BYTE [] pbBuffer, DWORD // *pdwBufferUsed ); [PreserveSig] HRESULT GetVendorExtension(in WCN_VENDOR_EXTENSION_SPEC pVendorExtSpec, uint dwMaxBufferSize, [Out] IntPtr pbBuffer, out uint pdwBufferUsed); /// /// The IWCNDevice::SetVendorExtension method queues a vendor extension for use in the pending session. This function may /// only be called prior to IWCNDevice::Connect. /// /// /// A pointer to a WCN_VENDOR_EXTENSION_SPEC structure that contains the vendor extension specification. /// /// The number of bytes contained in pbBuffer. /// Pointer to a buffer that contains the data to set in the vendor extension. /// /// This method can return one of these values. /// /// /// Return code /// Description /// /// /// S_OK /// The vendor extension will be sent in the pending session. /// /// /// E_INVALIDARG /// The specified WCN_VENDOR_EXTENSION_SPEC contains an illegal VendorID, sub-type, or flag. /// /// /// HRESULT_FROM_WIN32(ERROR_IMPLEMENTATION_LIMIT) /// /// The number of vendor extensions has exceeded the current implementation limit, which is currently equal to 25 vendor /// extensions per session. /// /// /// /// // https://docs.microsoft.com/en-us/windows/win32/api/wcndevice/nf-wcndevice-iwcndevice-setvendorextension HRESULT // SetVendorExtension( const WCN_VENDOR_EXTENSION_SPEC *pVendorExtSpec, DWORD cbBuffer, const BYTE [] pbBuffer ); [PreserveSig] HRESULT SetVendorExtension(in WCN_VENDOR_EXTENSION_SPEC pVendorExtSpec, uint cbBuffer, [In] IntPtr pbBuffer); /// The IWCNDevice::Unadvise method removes any callback previously set via IWCNDevice::Connect. /// This method does not return a value. /// /// It is not necessary to call IWCNDevice::Unadvise unless the application is shutting down and must ensure that no more /// callbacks are received on its IWCNConnectNotify callback. Do not call IWCNDevice::Unadvise from within an /// IWCNConnectNotify callback, since that will cause a deadlock. Note that IWCNDevice::Unadvise does not cancel /// the connect operation on the wire. /// // https://docs.microsoft.com/en-us/windows/win32/api/wcndevice/nf-wcndevice-iwcndevice-unadvise HRESULT Unadvise(); [PreserveSig] HRESULT Unadvise(); /// Sets the NFC password parameters. /// The password type. /// The password identifier. /// Length of the password. /// The password. /// Length of the remote public key hash. /// The remote public key hash. /// Length of the key BLOB. /// The key BLOB. /// [PreserveSig] HRESULT SetNFCPasswordParams(WCN_PASSWORD_TYPE Type, uint dwOOBPasswordID, uint dwPasswordLength, [In] IntPtr pbPassword, uint dwRemotePublicKeyHashLength, [In] IntPtr pbRemotePublicKeyHash, uint dwDHKeyBlobLength, [In] IntPtr pbDHKeyBlob); } /// The GetIntegerAttribute method gets a cached attribute from the device as an integer. /// The type to which the retrieved integer is converted. /// The instance. /// A WCN_ATTRIBUTE_TYPE value that represents a specific attribute value (for example, WCN_PASSWORD_TYPE). /// The retrieved attribute value. public static T GetIntegerAttribute(this IWCNDevice iDev, WCN_ATTRIBUTE_TYPE AttributeType) where T : struct, IConvertible { var hr = iDev.GetIntegerAttribute(AttributeType, out var u); return hr.Succeeded ? (T)Convert.ChangeType(u, typeof(T)) : throw hr.GetException(); } /// The WCN_VENDOR_EXTENSION_SPEC structure contains data that defines a vendor extension. // https://docs.microsoft.com/en-us/windows/win32/api/wcndevice/ns-wcndevice-wcn_vendor_extension_spec typedef struct // tagWCN_VENDOR_EXTENSION_SPEC { DWORD VendorId; DWORD SubType; DWORD Index; DWORD Flags; } WCN_VENDOR_EXTENSION_SPEC; [PInvokeData("wcndevice.h", MSDNShortId = "NS:wcndevice.tagWCN_VENDOR_EXTENSION_SPEC")] [StructLayout(LayoutKind.Sequential)] public struct WCN_VENDOR_EXTENSION_SPEC { /// /// Set this value to the SMI Enterprise ID Number of the vendor that defines the vendor extension. For example, the Microsoft /// ID is '311' (WCN_MICROSOFT_VENDOR_ID). /// public uint VendorId; /// /// The subtype, as defined by the first two bytes of the vendor extension. If the vendor has not provided the two-byte subtype /// prefix, use WCN_NO_SUBTYPE. /// public uint SubType; /// Distinguishes between multiple vendor extensions with the same VendorID and SubType. The index begins at zero. public uint Index; /// /// Applications must specify one of the following flag values: /// /// /// Value /// Meaning /// /// /// WCN_FLAG_DISCOVERY_VE 0x0001 /// The vendor extension was not available before the session started. The vendor extension is not secure. /// /// /// WCN_FLAG_AUTHENTICATED_VE 0x0002 /// The vendor extension is authentic. Only devices that pass authentication can read or write authenticated vendor extensions. /// /// /// WCN_FLAG_ENCRYPTED_VE 0x0004 /// /// The vendor extension is authentic and encrypted. In addition to the guarantee of authenticated vendor extensions, vendor /// extensions are encrypted before transmission. /// /// /// /// public WCN_FLAG Flags; } /// Class object for . [ComImport, Guid("C100BEA7-D33A-4a4b-BF23-BBEF4663D017"), ClassInterface(ClassInterfaceType.None)] public class WCNDeviceObject { } } }