소켓에서 제어 작업 수행
Winsock Kernel(WSK) 애플리케이션이 소켓을 성공적으로 만든 후에는 소켓에서 제어 작업을 수행할 수 있습니다. 소켓에서 수행할 수 있는 제어 작업에는 소켓 옵션 설정 및 검색 및 소켓 IOCTL 작업 실행이 포함됩니다.
WSK 애플리케이션은 WskControlSocket 함수를 호출하여 소켓에서 제어 작업을 수행합니다. WskControlSocket 함수는 소켓 공급자 디스패치 구조의 WskControlSocket 멤버가 가리켰습니다. 소켓의 공급자 디스패치 구조는 소켓을 만드는 동안 WSK 하위 시스템에 의해 반환된 소켓 개체 구조(WSK_SOCKET)의 Dispatch 멤버가 가리켰습니다.
다음 코드 예제에서는 WSK 애플리케이션이 데이터그램 소켓에서 SO_EXCLUSIVEADDRUSE 소켓 옵션을 설정하는 방법을 보여 줍니다.
// Prototype for the control socket IoCompletion routine
NTSTATUS
ControlSocketComplete(
PDEVICE_OBJECT DeviceObject,
PIRP Irp,
PVOID Context
);
// Function to set the SO_EXCLUSIVEADDRUSE socket option
// on a datagram socket
NTSTATUS
SetExclusiveAddrUse(
PWSK_SOCKET Socket
)
{
PWSK_PROVIDER_DATAGRAM_DISPATCH Dispatch;
PIRP Irp;
ULONG SocketOptionState;
NTSTATUS Status;
// Get pointer to the socket's provider dispatch structure
Dispatch =
(PWSK_PROVIDER_DATAGRAM_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,
ControlSocketComplete,
Socket, // Use the socket object for the context
TRUE,
TRUE,
TRUE
);
// Set the socket option state to 1 to set the socket option
SocketOptionState = 1;
// Initiate the control operation on the socket
Status =
Dispatch->WskControlSocket(
Socket,
WskSetOption,
SO_EXCLUSIVEADDRUSE,
SOL_SOCKET,
sizeof(ULONG),
&SocketOptionState,
0,
NULL,
NULL,
Irp
);
// Return the status of the call to WskControlSocket()
return Status;
}
// Control socket IoCompletion routine
NTSTATUS
ControlSocketComplete(
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)
{
// 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;
}
지원되는 각 소켓 옵션에 대한 자세한 내용은 WSK 소켓 옵션을 참조하세요.
다음 코드 예제에서는 WSK 애플리케이션이 데이터그램 소켓에서 SIO_WSK_SET_REMOTE_ADDRESS 소켓 IOCTL 작업을 실행할 수 있는 방법을 보여 줍니다.
// Prototype for the control socket IoCompletion routine
NTSTATUS
ControlSocketComplete(
PDEVICE_OBJECT DeviceObject,
PIRP Irp,
PVOID Context
);
// Function to perform the SIO_WSK_SET_REMOTE_ADDRESS socket
// IOCTL operation on a datagram socket
NTSTATUS
SetRemoteAddress(
PWSK_SOCKET Socket,
PSOCKADDR RemoteAddress
)
{
PWSK_PROVIDER_DATAGRAM_DISPATCH Dispatch;
PIRP Irp;
NTSTATUS Status;
// Get pointer to the socket's provider dispatch structure
Dispatch =
(PWSK_PROVIDER_DATAGRAM_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,
ControlSocketComplete,
Socket, // Use the socket object for the context
TRUE,
TRUE,
TRUE
);
// Initiate the IOCTL operation on the socket
Status =
Dispatch->WskControlSocket(
Socket,
WskIoctl,
SIO_WSK_SET_REMOTE_ADDRESS,
0,
sizeof(SOCKADDR_IN), // AF_INET
RemoteAddress,
0,
NULL,
NULL,
Irp
);
// Return the status of the call to WskControlSocket()
return Status;
}
// Control socket IoCompletion routine
NTSTATUS
ControlSocketComplete(
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)
{
// 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;
}
지원되는 각 소켓 IOCTL 작업에 대한 자세한 내용은 WSK 소켓 IOCTL 작업을 참조하세요.