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.
Aplikacja Winsock Kernel (WSK) może implementować funkcje wywołania zwrotnego zdarzeń, które podsystem WSK wywołuje asynchronicznie, aby powiadomić aplikację, gdy niektóre zdarzenia wystąpią na gnieździe. Aplikacja WSK może zapewnić klientowi strukturę tablicy dyspozytorów podsystemowi WSK za każdym razem, gdy tworzy gniazdo lub akceptuje gniazdo na gnieździe nasłuchującym. Ta tabela zdarzeń zawiera wskaźniki do funkcji wywoływania zwrotnego zdarzeń aplikacji WSK dla nowego gniazda. Jeśli aplikacja WSK nie implementuje żadnych funkcji wywołania zwrotnego zdarzeń dla określonego gniazda, nie musi zapewniać struktury tabeli wysyłania klienta do podsystemu WSK dla tego gniazda.
Wszystkie funkcje wywoływania zwrotnego zdarzeń gniazda, z wyjątkiem funkcji wywoływania zdarzeń dla gniazda nasłuchującego WskInspectEvent oraz WskAbortEvent, można włączyć lub wyłączyć, korzystając z opcji gniazda SO_WSK_EVENT_CALLBACK. Aplikacja WSK może jednocześnie włączyć wiele funkcji wywołania zwrotnego zdarzeń na jednym gnieździe. Jednak aplikacja WSK musi osobno wyłączyć każdą funkcję wywołania zwrotnego zdarzenia.
Poniższy przykład kodu pokazuje, jak aplikacja WSK może użyć opcji gniazda SO_WSK_EVENT_CALLBACK, aby włączyć funkcje wywołania zwrotnego dla zdarzeń WskDisconnectEvent oraz WskReceiveEvent na gnieździe zorientowanym na połączenie.
// Function to enable the WskDisconnectEvent and WskReceiveEvent
// event callback functions on a connection-oriented socket
NTSTATUS
EnableDisconnectAndRecieveCallbacks(
PWSK_SOCKET Socket
)
{
PWSK_PROVIDER_CONNECTION_DISPATCH Dispatch;
WSK_EVENT_CALLBACK_CONTROL EventCallbackControl;
NTSTATUS Status;
// Get pointer to the socket's provider dispatch structure
Dispatch =
(PWSK_PROVIDER_CONNECTION_DISPATCH)(Socket->Dispatch);
// Specify the WSK NPI identifier
EventCallbackControl.NpiId = &NPI_WSK_INTERFACE_ID;
// Set the event flags for the event callback functions that
// are to be enabled on the socket
EventCallbackControl.EventMask =
WSK_EVENT_DISCONNECT | WSK_EVENT_RECEIVE;
// Initiate the control operation on the socket
Status =
Dispatch->WskControlSocket(
Socket,
WskSetOption,
SO_WSK_EVENT_CALLBACK,
SOL_SOCKET,
sizeof(WSK_EVENT_CALLBACK_CONTROL),
&EventCallbackControl,
0,
NULL,
NULL,
NULL // No IRP for this control operation
);
// Return the status of the call to WskControlSocket()
return Status;
}
Poniższy przykład kodu pokazuje, jak aplikacja WSK może użyć opcji gniazda SO_WSK_EVENT_CALLBACK, aby wyłączyć funkcje zwrotnych wywołań zdarzeń WskReceiveEvent na gnieździe zorientowanym na połączenie.
// Prototype for the disable disconnect IoCompletion routine
NTSTATUS
DisableDisconnectComplete(
PDEVICE_OBJECT DeviceObject,
PIRP Irp,
PVOID Context
);
// Function to disable the WskDisconnectEvent event
// callback functions on a connection-oriented socket
NTSTATUS
DisableDisconnectCallback(
PWSK_SOCKET Socket
)
{
PWSK_PROVIDER_CONNECTION_DISPATCH Dispatch;
PIRP Irp;
WSK_EVENT_CALLBACK_CONTROL EventCallbackControl;
NTSTATUS Status;
// Get pointer to the socket's provider dispatch structure
Dispatch =
(PWSK_PROVIDER_CONNECTION_DISPATCH)(Socket->Dispatch);
// Allocate an IRP
Irp =
IoAllocateIrp(
1,
FALSE
);
// Check result
if (!Irp)
{
// Return error
return STATUS_INSUFFICIENT_RESOURCES;
}
// Set the completion routine for the IRP
IoSetCompletionRoutine(
Irp,
DisableDisconnectComplete,
Socket, // Use the socket object for the context
TRUE,
TRUE,
TRUE
);
// Specify the WSK NPI identifier
EventCallbackControl.NpiId = &NPI_WSK_INTERFACE_ID;
// Set the event flag for the event callback function that
// is to be disabled on the socket along with the disable flag
EventCallbackControl.EventMask =
WSK_EVENT_DISCONNECT | WSK_EVENT_DISABLE;
// Initiate the control operation on the socket
Status =
Dispatch->WskControlSocket(
Socket,
WskSetOption,
SO_WSK_EVENT_CALLBACK,
SOL_SOCKET,
sizeof(WSK_EVENT_CALLBACK_CONTROL),
&EventCallbackControl,
0,
NULL,
NULL,
Irp
);
// Return the status of the call to WskControlSocket()
return Status;
}
// Disable disconnect IoCompletion routine
NTSTATUS
DisableDisconnectComplete(
PDEVICE_OBJECT DeviceObject,
PIRP Irp,
PVOID Context
)
{
UNREFERENCED_PARAMETER(DeviceObject);
PWSK_SOCKET Socket;
// Check the result of the control operation
if (Irp->IoStatus.Status == STATUS_SUCCESS)
{
// The WskDisconnectEvent event callback
// function is now disabled
// Get the socket object from the context
Socket = (PWSK_SOCKET)Context;
// Perform the next operation on the socket
...
}
// Error status
else
{
// Handle error
...
}
// Free the IRP
IoFreeIrp(Irp);
// Always return STATUS_MORE_PROCESSING_REQUIRED to
// terminate the completion processing of the IRP.
return STATUS_MORE_PROCESSING_REQUIRED;
}
W przypadku gniazd nasłuchiwania, funkcje wywołania zwrotnego zdarzeń WskInspectEvent i WskAbortEvent są włączone tylko wtedy, gdy aplikacja WSK włącza w gnieździe tryb akceptacji warunkowej. Aplikacja WSK włącza tryb warunkowego akceptowania na gnieździe nasłuchującym, ustawiając opcję gniazda SO_CONDITIONAL_ACCEPT dla gniazda przed związaniem gniazda z lokalnym adresem transportowym. Aby uzyskać więcej informacji na temat ustawiania opcji gniazda, zobacz Wykonywanie operacji sterowania na gnieździe.
Po włączeniu trybu akceptowania warunkowego na gnieździe nasłuchującym nie można wyłączyć funkcji wywołania zwrotnego zdarzeń WskInspectEvent oraz WskAbortEvent. Aby uzyskać więcej informacji na temat warunkowego akceptowania połączeń przychodzących na gniazdach nasłuchiwania, zobacz Nasłuchiwanie i akceptowanie połączeń przychodzących.
Gniazdo nasłuchiwania może automatycznie włączać funkcje zwrotne wywołania zdarzeń na gniazdach zorientowanych na połączenie, które są akceptowane przez funkcję wywołania zwrotnego zdarzeń WskAcceptEvent gniazda nasłuchującego. Aplikacja WSK automatycznie włącza te funkcje wywołania zwrotnego, umożliwiając włączenie funkcji wywołania zwrotnego zdarzeń gniazda zorientowanego na połączenie na gnieździe nasłuchującym. Aby uzyskać więcej informacji na temat tego procesu, zobacz SO_WSK_EVENT_CALLBACK.
Jeśli aplikacja WSK zawsze włącza pewne funkcje zwrotne zdarzeń na każdym gnieździe, które tworzy, aplikacja może skonfigurować podsystem WSK, aby automatycznie włączyć te funkcje zwrotne zdarzeń przy użyciu operacji sterowania klientem WSK_SET_STATIC_EVENT_CALLBACKS. Funkcje wywołania zwrotnego zdarzeń, które zostały w ten sposób włączone, są zawsze włączone i nie mogą być wyłączone ani ponownie włączone później przez aplikację WSK. Jeśli aplikacja WSK zawsze włącza pewne funkcje wywołania zwrotnego zdarzeń na każdym utworzonym przez nią gniazdo, aplikacja powinna użyć tej metody, aby automatycznie włączyć te funkcje wywołania zwrotnego zdarzeń, ponieważ zapewni znacznie lepszą wydajność.
Poniższy przykład kodu pokazuje, jak aplikacja WSK może używać operacji sterowania klienta WSK_SET_STATIC_EVENT_CALLBACKS w celu automatycznego włączenia funkcji zdarzeń zwrotnych WskReceiveFromEvent na gniazdach datagramowych oraz funkcji WskReceiveEvent na gniazdach zorientowanych na połączenie.
// Function to set static event callbacks
NTSTATUS
SetStaticEventCallbacks(
PWSK_APP_BINDING_CONTEXT BindingContext,
)
{
WSK_EVENT_CALLBACK_CONTROL EventCallbackControl;
NTSTATUS Status;
// Specify the WSK NPI identifier
EventCallbackControl.NpiId = &NPI_WSK_INTERFACE_ID;
// Set the event flags for the event callback functions that
// are to be automatically enabled on every new socket
EventCallbackControl.EventMask =
WSK_EVENT_RECEIVE_FROM | WSK_EVENT_RECEIVE;
// Perform client control operation
Status =
BindingContext->
WskProviderDispatch->
WskControlClient(
BindingContext->WskClient,
WSK_SET_STATIC_EVENT_CALLBACKS,
sizeof(WSK_EVENT_CALLBACK_CONTROL),
&EventCallbackControl,
0,
NULL,
NULL,
NULL // No IRP for this control operation
);
// Return status of client control operation
return Status;
}
Jeśli aplikacja WSK używa operacji sterowania klienta WSK_SET_STATIC_EVENT_CALLBACKS, aby automatycznie włączyć niektóre funkcje wywołania zwrotnego zdarzeń, musi to zrobić przed utworzeniem jakichkolwiek gniazd.