📄 sndrcv.c
字号:
}
IOSB->Status = STATUS_PENDING;
/* Send IOCTL */
Status = NtDeviceIoControlFile((HANDLE)Handle,
SockEvent,
APCFunction,
APCContext,
IOSB,
IOCTL_AFD_RECV_DATAGRAM,
&RecvInfo,
sizeof(RecvInfo),
NULL,
0);
/* Wait for completition of not overlapped */
if (Status == STATUS_PENDING && lpOverlapped == NULL) {
WaitForSingleObject(SockEvent, INFINITE); // BUGBUG, shouldn wait infintely for receive...
Status = IOSB->Status;
}
NtClose( SockEvent );
/* Return the Flags */
*ReceiveFlags = 0;
switch (Status) {
case STATUS_RECEIVE_EXPEDITED: *ReceiveFlags = MSG_OOB; break;
case STATUS_RECEIVE_PARTIAL_EXPEDITED:
*ReceiveFlags = MSG_PARTIAL | MSG_OOB; break;
case STATUS_RECEIVE_PARTIAL: *ReceiveFlags = MSG_PARTIAL; break;
}
/* Re-enable Async Event */
SockReenableAsyncSelectEvent(Socket, FD_READ);
return MsafdReturnWithErrno
( Status, lpErrno, IOSB->Information, lpNumberOfBytesRead );
}
int
WSPAPI
WSPSend(
SOCKET Handle,
LPWSABUF lpBuffers,
DWORD dwBufferCount,
LPDWORD lpNumberOfBytesSent,
DWORD iFlags,
LPWSAOVERLAPPED lpOverlapped,
LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine,
LPWSATHREADID lpThreadId,
LPINT lpErrno)
{
PIO_STATUS_BLOCK IOSB;
IO_STATUS_BLOCK DummyIOSB;
AFD_SEND_INFO SendInfo;
NTSTATUS Status;
PVOID APCContext;
PVOID APCFunction;
HANDLE Event;
HANDLE SockEvent;
PSOCKET_INFORMATION Socket;
/* Get the Socket Structure associate to this Socket*/
Socket = GetSocketStructure(Handle);
Status = NtCreateEvent( &SockEvent, GENERIC_READ | GENERIC_WRITE,
NULL, 1, FALSE );
if( !NT_SUCCESS(Status) ) return -1;
AFD_DbgPrint(MID_TRACE,("Called\n"));
/* Set up the Send Structure */
SendInfo.BufferArray = (PAFD_WSABUF)lpBuffers;
SendInfo.BufferCount = dwBufferCount;
SendInfo.TdiFlags = 0;
SendInfo.AfdFlags = Socket->SharedData.NonBlocking ? AFD_IMMEDIATE : 0;
/* Set the TDI Flags */
if (iFlags) {
if (iFlags & MSG_OOB) {
SendInfo.TdiFlags |= TDI_SEND_EXPEDITED;
}
if (iFlags & MSG_PARTIAL) {
SendInfo.TdiFlags |= TDI_SEND_PARTIAL;
}
}
/* Verifiy if we should use APC */
if (lpOverlapped == NULL) {
/* Not using Overlapped structure, so use normal blocking on event */
APCContext = NULL;
APCFunction = NULL;
Event = SockEvent;
IOSB = &DummyIOSB;
} else {
if (lpCompletionRoutine == NULL) {
/* Using Overlapped Structure, but no Completition Routine, so no need for APC */
APCContext = lpOverlapped;
APCFunction = NULL;
Event = lpOverlapped->hEvent;
} else {
/* Using Overlapped Structure and a Completition Routine, so use an APC */
APCFunction = NULL; // should be a private io completition function inside us
APCContext = lpCompletionRoutine;
SendInfo.AfdFlags = AFD_SKIP_FIO;
}
IOSB = (PIO_STATUS_BLOCK)&lpOverlapped->Internal;
SendInfo.AfdFlags |= AFD_OVERLAPPED;
}
IOSB->Status = STATUS_PENDING;
/* Send IOCTL */
Status = NtDeviceIoControlFile((HANDLE)Handle,
SockEvent,
APCFunction,
APCContext,
IOSB,
IOCTL_AFD_SEND,
&SendInfo,
sizeof(SendInfo),
NULL,
0);
/* Wait for completition of not overlapped */
if (Status == STATUS_PENDING && lpOverlapped == NULL) {
WaitForSingleObject(SockEvent, INFINITE); // BUGBUG, shouldn wait infintely for send...
Status = IOSB->Status;
}
NtClose( SockEvent );
if (Status == STATUS_PENDING) {
AFD_DbgPrint(MID_TRACE,("Leaving (Pending)\n"));
return WSA_IO_PENDING;
}
/* Re-enable Async Event */
SockReenableAsyncSelectEvent(Socket, FD_WRITE);
AFD_DbgPrint(MID_TRACE,("Leaving (Success, %d)\n", IOSB->Information));
return MsafdReturnWithErrno
( Status, lpErrno, IOSB->Information, lpNumberOfBytesSent );
}
int
WSPAPI
WSPSendTo(
SOCKET Handle,
LPWSABUF lpBuffers,
DWORD dwBufferCount,
LPDWORD lpNumberOfBytesSent,
DWORD iFlags,
const struct sockaddr *SocketAddress,
int SocketAddressLength,
LPWSAOVERLAPPED lpOverlapped,
LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine,
LPWSATHREADID lpThreadId,
LPINT lpErrno)
{
PIO_STATUS_BLOCK IOSB;
IO_STATUS_BLOCK DummyIOSB;
AFD_SEND_INFO_UDP SendInfo;
NTSTATUS Status;
PVOID APCContext;
PVOID APCFunction;
HANDLE Event;
PTRANSPORT_ADDRESS RemoteAddress;
UCHAR TdiBuffer[0x16];
PSOCKADDR BindAddress;
INT BindAddressLength;
HANDLE SockEvent;
PSOCKET_INFORMATION Socket;
/* Get the Socket Structure associate to this Socket*/
Socket = GetSocketStructure(Handle);
Status = NtCreateEvent( &SockEvent, GENERIC_READ | GENERIC_WRITE,
NULL, 1, FALSE );
if( !NT_SUCCESS(Status) ) return -1;
/* Bind us First */
if (Socket->SharedData.State == SocketOpen) {
/* Get the Wildcard Address */
BindAddressLength = Socket->HelperData->MaxWSAddressLength;
BindAddress = HeapAlloc(GlobalHeap, 0, BindAddressLength);
Socket->HelperData->WSHGetWildcardSockaddr (Socket->HelperContext,
BindAddress,
&BindAddressLength);
/* Bind it */
WSPBind(Handle, BindAddress, BindAddressLength, NULL);
}
/* Set up Address in TDI Format */
RemoteAddress = (PTRANSPORT_ADDRESS)TdiBuffer;
RemoteAddress->TAAddressCount = 1;
RemoteAddress->Address[0].AddressLength = SocketAddressLength - sizeof(SocketAddress->sa_family);
RtlCopyMemory(&RemoteAddress->Address[0].AddressType, SocketAddress, SocketAddressLength);
/* Set up Structure */
SendInfo.BufferArray = (PAFD_WSABUF)lpBuffers;
SendInfo.AfdFlags = Socket->SharedData.NonBlocking ? AFD_IMMEDIATE : 0;
SendInfo.BufferCount = dwBufferCount;
SendInfo.RemoteAddress = RemoteAddress;
SendInfo.SizeOfRemoteAddress = Socket->HelperData->MaxTDIAddressLength;
/* Verifiy if we should use APC */
if (lpOverlapped == NULL) {
/* Not using Overlapped structure, so use normal blocking on event */
APCContext = NULL;
APCFunction = NULL;
Event = SockEvent;
IOSB = &DummyIOSB;
} else {
if (lpCompletionRoutine == NULL) {
/* Using Overlapped Structure, but no Completition Routine, so no need for APC */
APCContext = lpOverlapped;
APCFunction = NULL;
Event = lpOverlapped->hEvent;
} else {
/* Using Overlapped Structure and a Completition Routine, so use an APC */
APCFunction = NULL; // should be a private io completition function inside us
APCContext = lpCompletionRoutine;
SendInfo.AfdFlags = AFD_SKIP_FIO;
}
IOSB = (PIO_STATUS_BLOCK)&lpOverlapped->Internal;
SendInfo.AfdFlags |= AFD_OVERLAPPED;
}
/* Send IOCTL */
Status = NtDeviceIoControlFile((HANDLE)Handle,
SockEvent,
APCFunction,
APCContext,
IOSB,
IOCTL_AFD_SEND_DATAGRAM,
&SendInfo,
sizeof(SendInfo),
NULL,
0);
/* Wait for completition of not overlapped */
if (Status == STATUS_PENDING && lpOverlapped == NULL) {
WaitForSingleObject(SockEvent, INFINITE); // BUGBUG, shouldn wait infintely for send...
Status = IOSB->Status;
}
NtClose( SockEvent );
if (Status == STATUS_PENDING) {
return WSA_IO_PENDING;
}
/* Re-enable Async Event */
SockReenableAsyncSelectEvent(Socket, FD_WRITE);
return MsafdReturnWithErrno
( Status, lpErrno, IOSB->Information, lpNumberOfBytesSent );
}
INT
WSPAPI
WSPRecvDisconnect(
IN SOCKET s,
OUT LPWSABUF lpInboundDisconnectData,
OUT LPINT lpErrno)
{
UNIMPLEMENTED
return 0;
}
INT
WSPAPI
WSPSendDisconnect(
IN SOCKET s,
IN LPWSABUF lpOutboundDisconnectData,
OUT LPINT lpErrno)
{
UNIMPLEMENTED
return 0;
}
/* EOF */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -