Notatka
Dostęp do tej strony wymaga autoryzacji. Może spróbować zalogować się lub zmienić katalogi.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
Po pomyślnym utworzeniu gniazda przez aplikację jądra Winsock (WSK) można zarejestrować to gniazdo dla co najmniej jednego interfejsu rozszerzenia obsługiwanych przez podsystem WSK. Aplikacja WSK określa, który zestaw interfejsów rozszerzeń jest obsługiwany przez podsystem WSK, sprawdzając element wersji struktury WSK_PROVIDER_DISPATCH, którą podsystem WSK zwrócił do aplikacji podczas dołączenia.
Każdy interfejs rozszerzenia jest definiowany przez NPI, który jest niezależny od NPI WSK. Należy jednak pamiętać, że NPI dla interfejsów rozszerzeń nie obsługują specyficznych cech NPI.
Aplikacja WSK rejestruje interfejs rozszerzenia, wykonując operację IOCTL gniazda SIO_WSK_REGISTER_EXTENSION na gnieździe. Aby uzyskać więcej informacji na temat wykonywania operacji IOCTL gniazda, zobacz Wykonywanie operacji kontrolnych na gnieździe.
Jeśli aplikacja WSK próbuje zarejestrować gniazdo dla interfejsu rozszerzenia, który nie jest obsługiwany przez podsystem WSK, operacja IOCTL gniazda SIO_WSK_REGISTER_EXTENSION zwróci STATUS_NOT_SUPPORTED.
Załóżmy na przykład, że interfejs rozszerzenia jest zdefiniowany tak jak w poniższym przykładzie kodu.
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;
Poniżej pokazano, jak aplikacja WSK może zarejestrować się do tego interfejsu rozszerzenia dla gniazda zorientowanego na połączenie.
// 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;
}
Aplikacja WSK rejestruje interfejsy rozszerzeń indywidualnie dla każdego gniazda.