Примечание.
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
Приложение Winsock Kernel (WSK) может реализовать функции обратного вызова событий, которые подсистема WSK вызывает асинхронно, чтобы уведомить приложение, когда определенные события происходят в сокете. Приложение WSK может предоставить в подсистему WSK структуру таблицы распределения всякий раз, когда оно создает сокет или принимает соединение на прослушивающем сокете. Эта диспетчерская таблица содержит указатели на функции обратного вызова событий приложения WSK для нового сокета. Если приложение WSK не реализует никаких функций обратного вызова событий для определенного сокета, то не требуется предоставлять структуру таблицы диспетчеризации клиента подсистеме WSK для этого сокета.
Все функции обратного вызова событий сокета, за исключением функций обратного вызова WskInspectEvent и WskAbortEvent для слушающего сокета, можно включить или отключить с помощью параметра сокета SO_WSK_EVENT_CALLBACK. Приложение WSK может включить несколько функций обратного вызова событий в сокете одновременно. Однако приложение WSK должно отключить каждую функцию обратного вызова событий по отдельности.
В следующем примере кода показано, как приложение WSK может использовать параметр сокета SO_WSK_EVENT_CALLBACK, чтобы включить функции обратного вызова для событий WskDisconnectEvent и WskReceiveEvent на подключенном сокете.
// 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;
}
В следующем примере кода показано, как приложение WSK может использовать параметр сокета SO_WSK_EVENT_CALLBACK для отключения функций обратного вызова событий WskReceiveEvent в сокете, ориентированном на подключение.
// 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;
}
Для прослушивающих сокетов функции обратного вызова событий WskInspectEvent и WskAbortEvent активируются только если приложение WSK включает режим условного принятия на сокете. Приложение WSK включает режим условного принятия на сокете прослушивания, задавая параметр SO_CONDITIONAL_ACCEPT для сокета перед привязкой к локальному транспортному адресу. Дополнительные сведения о настройке параметров сокета см. в разделе о выполнении управляющих операций на сокете.
После того как для сокета прослушивания включен условный режим принятия, функции обратного вызова событий WskInspectEvent и WskAbortEvent не могут быть отключены. Дополнительные сведения об условном принятии входящих подключений для прослушивающих сокетов см. в разделе Прослушивание и принятие входящих подключений.
Слушающий сокет может автоматически включать функции обратного вызова событий для соединительных сокетов, которые принимаются функцией обратного вызова событий WskAcceptEvent этого слушающего сокета. Приложение WSK автоматически включает эти функции обратного вызова путем включения функций обратного вызова событий, ориентированных на подключение, в сокете прослушивания. Дополнительные сведения об этом процессе см. в SO_WSK_EVENT_CALLBACK.
Если приложение WSK всегда включает определенные функции обратного вызова событий на каждом сокете, который оно создает, приложение может настроить подсистему WSK для автоматического включения этих функций обратного вызова событий с помощью операции управления клиентом WSK_SET_STATIC_EVENT_CALLBACKS. Функции обратного вызова событий, включенные таким образом, всегда включены и не могут быть отключены или повторно включены позже приложением WSK. Если приложение WSK всегда включает определенные функции обратного вызова событий на каждом сокете, который он создает, приложение должно использовать этот метод для автоматического включения этих функций обратного вызова событий, так как это обеспечит гораздо более высокую производительность.
В следующем примере кода показано, как приложение WSK может использовать операцию управления клиентом WSK_SET_STATIC_EVENT_CALLBACKS для автоматического включения функции обратного вызова событий WskReceiveFromEvent для сокетов данных и функции обратного вызова событий WskReceiveEvent для сокетов, ориентированных на подключение.
// 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;
}
Если приложение WSK использует операцию управления клиентом WSK_SET_STATIC_EVENT_CALLBACKS для автоматического включения определённых функций обратного вызова событий, оно должно сделать это до создания каких-либо сокетов.