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 { }
}
}