Catatan
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba masuk atau mengubah direktori.
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba mengubah direktori.
Aplikasi Winsock Kernel (WSK) dapat mengimplementasikan fungsi panggilan balik peristiwa yang dipanggil subsistem WSK secara asinkron untuk memberi tahu aplikasi saat peristiwa tertentu terjadi pada soket. Aplikasi WSK dapat menyediakan struktur tabel pengiriman klien ke subsistem WSK setiap kali membuat soket atau menerima soket pada soket mendengarkan. Tabel pengiriman ini berisi penunjuk ke fungsi callback event aplikasi WSK untuk soket baru. Jika aplikasi WSK tidak menerapkan fungsi panggilan balik peristiwa apa pun untuk soket tertentu, maka tidak perlu menyediakan struktur tabel pengiriman klien ke subsistem WSK untuk soket tersebut.
Semua fungsi panggilan balik peristiwa dari soket, kecuali untuk fungsi panggilan balik peristiwa WskInspectEvent dan WskAbortEvent dari soket yang mendengarkan, dapat diaktifkan atau dinonaktifkan dengan menggunakan opsi soket SO_WSK_EVENT_CALLBACK. Aplikasi WSK dapat mengaktifkan beberapa fungsi panggilan balik peristiwa pada soket secara bersamaan. Namun, aplikasi WSK harus menonaktifkan setiap fungsi panggilan balik peristiwa satu per satu.
Contoh kode berikut menunjukkan bagaimana aplikasi WSK dapat menggunakan opsi soket SO_WSK_EVENT_CALLBACK untuk mengaktifkan fungsi panggilan balik peristiwa WskDisconnectEvent dan WskReceiveEvent pada soket berorientasi koneksi.
// 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;
}
Contoh kode berikut menunjukkan bagaimana aplikasi WSK dapat menggunakan opsi soket SO_WSK_EVENT_CALLBACK untuk menonaktifkan fungsi panggilan balik peristiwa WskReceiveEvent pada soket berorientasi koneksi.
// 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;
}
Untuk mendengarkan soket, fungsi panggilan balik peristiwa WskInspectEvent dan WskAbortEvent diaktifkan hanya jika aplikasi WSK memungkinkan mode penerimaan bersyarkat pada soket. Aplikasi WSK memungkinkan mode terima bersyarkat pada soket mendengarkan dengan mengatur opsi soket SO_CONDITIONAL_ACCEPT untuk soket sebelum mengikat soket ke alamat transportasi lokal. Untuk informasi selengkapnya tentang cara mengatur opsi soket, lihat Melakukan Operasi Kontrol pada Soket.
Setelah mode terima kondisional diaktifkan pada soket mendengarkan, fungsi panggilan balik peristiwa WskInspectEvent dan WskAbortEvent soket tidak dapat dinonaktifkan. Untuk informasi selengkapnya tentang menerima koneksi masuk secara kondisional pada soket mendengarkan, lihat Mendengarkan dan Menerima Koneksi Masuk.
Socket yang mendengarkan dapat mengaktifkan secara otomatis fungsi panggilan balik peristiwa pada socket berorientasi koneksi, yang diterima oleh fungsi panggilan balik peristiwa WskAcceptEvent dari socket yang mendengarkan. Aplikasi WSK secara otomatis mengaktifkan fungsi panggilan balik ini dengan mengaktifkan fungsi panggilan balik peristiwa soket berorientasi koneksi pada soket mendengarkan. Untuk informasi selengkapnya tentang proses ini, lihat SO_WSK_EVENT_CALLBACK.
Jika aplikasi WSK selalu mengaktifkan fungsi panggilan balik peristiwa tertentu pada setiap soket yang dibuatnya, aplikasi dapat mengonfigurasi subsistem WSK untuk mengaktifkan fungsi panggilan balik peristiwa tersebut secara otomatis dengan menggunakan operasi kontrol klien WSK_SET_STATIC_EVENT_CALLBACKS . Fungsi panggilan balik peristiwa yang diaktifkan dengan cara ini selalu diaktifkan dan tidak dapat dinonaktifkan atau diaktifkan kembali nanti oleh aplikasi WSK. Jika aplikasi WSK selalu mengaktifkan fungsi panggilan balik peristiwa tertentu pada setiap soket yang dibuatnya, aplikasi harus menggunakan metode ini untuk mengaktifkan fungsi panggilan balik peristiwa tersebut secara otomatis karena akan menghasilkan performa yang jauh lebih baik.
Contoh kode berikut menunjukkan bagaimana aplikasi WSK dapat menggunakan operasi kontrol klien WSK_SET_STATIC_EVENT_CALLBACKS untuk mengaktifkan fungsi panggilan balik peristiwa WskReceiveFromEvent secara otomatis pada soket datagram dan fungsi panggilan balik peristiwa WskReceiveEvent pada soket berorientasi koneksi.
// 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;
}
Jika aplikasi WSK menggunakan operasi kontrol klien WSK_SET_STATIC_EVENT_CALLBACKS untuk mengaktifkan fungsi panggilan balik peristiwa tertentu secara otomatis, aplikasi harus melakukannya sebelum membuat soket apa pun.