拡張インターフェイスの登録
Winsock カーネル (WSK) アプリケーションは、ソケットを正常に作成した後、WSK サブシステムによってサポートされている 1 つ以上の拡張インターフェイスにそのソケットを登録できます。 WSK アプリケーションは、WSK サブシステムがアタッチ時にアプリケーションに返した WSK_PROVIDER_DISPATCH 構造の Version メンバーを調べることにより、WSK サブシステムでサポートされている拡張インターフェイスのセットを決定します。
各拡張インターフェイスは、WSK NPI に依存しない NPI によって定義されます。 ただし、拡張インターフェイスの NPI では NPI 固有の特性がサポートされないことに注意してください。
WSK アプリケーションは、ソケットで SIO_WSK_REGISTER_EXTENSION ソケット IOCTL 操作を実行することによって拡張インターフェイスに登録します。 ソケット IOCTL 操作の実行について詳しくは、「ソケットでの制御操作の実行」をご覧ください。
WSK アプリケーションが、WSK サブシステムによってサポートされていない拡張インターフェイスのソケットを登録しようとすると、SIO_WSK_REGISTER_EXTENSION ソケット IOCTL 操作は STATUS_NOT_SUPPORTED を返します。
たとえば、次のコード例のように拡張インターフェイスが定義されるとします。
const NPIID EXAMPLE_EXTIF_NPIID = {...};
typedef struct _EXAMPLE_EXTIF_PROVIDER_DISPATCH {
.
. // Function pointers for the functions that are
. // defined by the extension interface.
.
} EXAMPLE_EXTIF_PROVIDER_DISPATCH, *PEXAMPLE_EXTIF_PROVIDER_DISPATCH;
typedef struct _EXAMPLE_EXTIF_CLIENT_DISPATCH {
.
. // Function pointers for the callback functions
. // that are defined by the extension interface.
.
} EXAMPLE_EXTIF_CLIENT_DISPATCH, *PEXAMPLE_EXTIF_CLIENT_DISPATCH;
次に、WSK アプリケーションが接続指向ソケットのこの拡張インターフェイスに登録する方法を示します。
// Client dispatch structure for the extension interface
const EXAMPLE_EXTIF_CLIENT_DISPATCH ExtIfClientDispatch = {
.
. // The WSK application's callback functions
. // for the extension interface
.
};
// Context structure type for the example extension interface
typedef struct _EXAMPLE_EXTIF_CLIENT_CONTEXT
{
const EXAMPLE_EXTIF_PROVIDER_DISPATCH *ExtIfProviderDispatch;
PVOID ExtIfProviderContext;
.
. // Other application-specific members
.
} EXAMPLE_EXTIF_CLIENT_CONTEXT, *PEXAMPLE_EXTIF_CLIENT_CONTEXT;
// Function to register the example extension interface
NTSTATUS
RegisterExampleExtIf(
PWSK_SOCKET Socket,
PEXAMPLE_EXTIF_CLIENT_CONTEXT ExtIfClientContext
)
{
PWSK_PROVIDER_CONNECTION_DISPATCH Dispatch;
WSK_EXTENSION_CONTROL_IN ExtensionControlIn;
WSK_EXTENSION_CONTROL_OUT ExtensionControlOut;
NTSTATUS Status;
// Get pointer to the socket's provider dispatch structure
Dispatch =
(PWSK_PROVIDER_CONNECTION_DISPATCH)(Socket->Dispatch);
// Fill in the WSK_EXTENSION_CONTROL_IN structure
ExtensionControlIn.NpiId = &EXAMPLE_EXTIF_NPIID;
ExtensionControlIn.ClientContext = ExtIfClientContext;
ExtensionControlIn.ClientDispatch = &ExtIfClientDispatch;
// Initiate the IOCTL operation on the socket
Status =
Dispatch->WskControlSocket(
Socket,
WskIoctl,
SIO_WSK_REGISTER_EXTENSION,
0,
sizeof(WSK_EXTENSION_CONTROL_IN),
&ExtensionControlIn,
sizeof(WSK_EXTENSION_CONTROL_OUT),
&ExtensionControlOut,
NULL,
NULL // No IRP used for this IOCTL operation
);
// Check result
if (Status == STATUS_SUCCESS)
{
// Save provider dispatch table and provider context
ExtIfClientContext->ExtIfProviderDispatch =
(const EXAMPLE_EXTIF_PROVIDER_DISPATCH *)
ExtensionControlOut.ProviderDispatch;
ExtIfClientContext->ExtIfProviderContext =
ExtensionControlOut.ProviderContext;
}
// Return the status of the call to WskControlSocket()
return Status;
}
WSK アプリケーションは、ソケットごとに拡張インターフェイスに登録されます。