📄 dllmain.c
字号:
TdiAddress = HeapAlloc(GlobalHeap, 0, TdiAddressSize);
if ( TdiAddress == NULL ) {
NtClose( SockEvent );
*lpErrno = WSAENOBUFS;
return SOCKET_ERROR;
}
SocketAddress = &TdiAddress->Address;
/* Send IOCTL */
Status = NtDeviceIoControlFile( (HANDLE)Socket->Handle,
SockEvent,
NULL,
NULL,
&IOSB,
IOCTL_AFD_GET_SOCK_NAME,
NULL,
0,
TdiAddress,
TdiAddressSize);
/* Wait for return */
if (Status == STATUS_PENDING) {
WaitForSingleObject(SockEvent, INFINITE);
Status = IOSB.Status;
}
NtClose( SockEvent );
if (NT_SUCCESS(Status)) {
if (*NameLength >= SocketAddress->Address[0].AddressLength) {
Name->sa_family = SocketAddress->Address[0].AddressType;
RtlCopyMemory (Name->sa_data,
SocketAddress->Address[0].Address,
SocketAddress->Address[0].AddressLength);
*NameLength = 2 + SocketAddress->Address[0].AddressLength;
AFD_DbgPrint
(MID_TRACE,
("NameLength %d Address: %x Port %x\n",
*NameLength,
((struct sockaddr_in *)Name)->sin_addr.s_addr,
((struct sockaddr_in *)Name)->sin_port));
HeapFree(GlobalHeap, 0, TdiAddress);
return 0;
} else {
HeapFree(GlobalHeap, 0, TdiAddress);
*lpErrno = WSAEFAULT;
return SOCKET_ERROR;
}
}
return MsafdReturnWithErrno
( IOSB.Status, lpErrno, 0, NULL );
}
INT
WSPAPI
WSPGetPeerName(
IN SOCKET s,
OUT LPSOCKADDR Name,
IN OUT LPINT NameLength,
OUT LPINT lpErrno)
{
IO_STATUS_BLOCK IOSB;
ULONG TdiAddressSize;
PTDI_ADDRESS_INFO TdiAddress;
PTRANSPORT_ADDRESS SocketAddress;
PSOCKET_INFORMATION Socket = NULL;
NTSTATUS Status;
HANDLE SockEvent;
Status = NtCreateEvent( &SockEvent, GENERIC_READ | GENERIC_WRITE,
NULL, 1, FALSE );
if( !NT_SUCCESS(Status) ) return SOCKET_ERROR;
/* Get the Socket Structure associate to this Socket*/
Socket = GetSocketStructure(s);
/* Allocate a buffer for the address */
TdiAddressSize = FIELD_OFFSET(TDI_ADDRESS_INFO,
Address.Address[0].Address) +
Socket->SharedData.SizeOfLocalAddress;
TdiAddress = HeapAlloc(GlobalHeap, 0, TdiAddressSize);
if ( TdiAddress == NULL ) {
NtClose( SockEvent );
*lpErrno = WSAENOBUFS;
return SOCKET_ERROR;
}
SocketAddress = &TdiAddress->Address;
/* Send IOCTL */
Status = NtDeviceIoControlFile( (HANDLE)Socket->Handle,
SockEvent,
NULL,
NULL,
&IOSB,
IOCTL_AFD_GET_PEER_NAME,
NULL,
0,
TdiAddress,
TdiAddressSize);
/* Wait for return */
if (Status == STATUS_PENDING) {
WaitForSingleObject(SockEvent, INFINITE);
Status = IOSB.Status;
}
NtClose( SockEvent );
if (NT_SUCCESS(Status)) {
if (*NameLength >= SocketAddress->Address[0].AddressLength) {
Name->sa_family = SocketAddress->Address[0].AddressType;
RtlCopyMemory (Name->sa_data,
SocketAddress->Address[0].Address,
SocketAddress->Address[0].AddressLength);
*NameLength = 2 + SocketAddress->Address[0].AddressLength;
AFD_DbgPrint
(MID_TRACE,
("NameLength %d Address: %s Port %x\n",
*NameLength,
((struct sockaddr_in *)Name)->sin_addr.s_addr,
((struct sockaddr_in *)Name)->sin_port));
HeapFree(GlobalHeap, 0, TdiAddress);
return 0;
} else {
HeapFree(GlobalHeap, 0, TdiAddress);
*lpErrno = WSAEFAULT;
return SOCKET_ERROR;
}
}
return MsafdReturnWithErrno
( IOSB.Status, lpErrno, 0, NULL );
}
INT
WSPAPI
WSPIoctl(
IN SOCKET Handle,
IN DWORD dwIoControlCode,
IN LPVOID lpvInBuffer,
IN DWORD cbInBuffer,
OUT LPVOID lpvOutBuffer,
IN DWORD cbOutBuffer,
OUT LPDWORD lpcbBytesReturned,
IN LPWSAOVERLAPPED lpOverlapped,
IN LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine,
IN LPWSATHREADID lpThreadId,
OUT LPINT lpErrno)
{
PSOCKET_INFORMATION Socket = NULL;
/* Get the Socket Structure associate to this Socket*/
Socket = GetSocketStructure(Handle);
switch( dwIoControlCode ) {
case FIONBIO:
if( cbInBuffer < sizeof(INT) ) return SOCKET_ERROR;
Socket->SharedData.NonBlocking = *((PINT)lpvInBuffer) ? 1 : 0;
AFD_DbgPrint(MID_TRACE,("[%x] Set nonblocking %d\n",
Handle, Socket->SharedData.NonBlocking));
return 0;
default:
*lpErrno = WSAEINVAL;
return SOCKET_ERROR;
}
}
INT
WSPAPI
WSPGetSockOpt(
IN SOCKET Handle,
IN INT Level,
IN INT OptionName,
OUT CHAR FAR* OptionValue,
IN OUT LPINT OptionLength,
OUT LPINT lpErrno)
{
PSOCKET_INFORMATION Socket = NULL;
PVOID Buffer;
INT BufferSize;
BOOLEAN BoolBuffer;
/* Get the Socket Structure associate to this Socket*/
Socket = GetSocketStructure(Handle);
if (Socket == NULL)
{
*lpErrno = WSAENOTSOCK;
return SOCKET_ERROR;
}
AFD_DbgPrint(MID_TRACE, ("Called\n"));
switch (Level)
{
case SOL_SOCKET:
switch (OptionName)
{
case SO_TYPE:
Buffer = &Socket->SharedData.SocketType;
BufferSize = sizeof(INT);
break;
case SO_RCVBUF:
Buffer = &Socket->SharedData.SizeOfRecvBuffer;
BufferSize = sizeof(INT);
break;
case SO_SNDBUF:
Buffer = &Socket->SharedData.SizeOfSendBuffer;
BufferSize = sizeof(INT);
break;
case SO_ACCEPTCONN:
BoolBuffer = Socket->SharedData.Listening;
Buffer = &BoolBuffer;
BufferSize = sizeof(BOOLEAN);
break;
case SO_BROADCAST:
BoolBuffer = Socket->SharedData.Broadcast;
Buffer = &BoolBuffer;
BufferSize = sizeof(BOOLEAN);
break;
case SO_DEBUG:
BoolBuffer = Socket->SharedData.Debug;
Buffer = &BoolBuffer;
BufferSize = sizeof(BOOLEAN);
break;
/* case SO_CONDITIONAL_ACCEPT: */
case SO_DONTLINGER:
case SO_DONTROUTE:
case SO_ERROR:
case SO_GROUP_ID:
case SO_GROUP_PRIORITY:
case SO_KEEPALIVE:
case SO_LINGER:
case SO_MAX_MSG_SIZE:
case SO_OOBINLINE:
case SO_PROTOCOL_INFO:
case SO_REUSEADDR:
AFD_DbgPrint(MID_TRACE, ("Unimplemented option (%x)\n",
OptionName));
default:
*lpErrno = WSAEINVAL;
return SOCKET_ERROR;
}
if (*OptionLength < BufferSize)
{
*lpErrno = WSAEFAULT;
*OptionLength = BufferSize;
return SOCKET_ERROR;
}
RtlCopyMemory(OptionValue, Buffer, BufferSize);
return 0;
case IPPROTO_TCP: /* FIXME */
default:
*lpErrno = WSAEINVAL;
return SOCKET_ERROR;
}
}
INT
WSPAPI
WSPStartup(
IN WORD wVersionRequested,
OUT LPWSPDATA lpWSPData,
IN LPWSAPROTOCOL_INFOW lpProtocolInfo,
IN WSPUPCALLTABLE UpcallTable,
OUT LPWSPPROC_TABLE lpProcTable)
/*
* FUNCTION: Initialize service provider for a client
* ARGUMENTS:
* wVersionRequested = Highest WinSock SPI version that the caller can use
* lpWSPData = Address of WSPDATA structure to initialize
* lpProtocolInfo = Pointer to structure that defines the desired protocol
* UpcallTable = Pointer to upcall table of the WinSock DLL
* lpProcTable = Address of procedure table to initialize
* RETURNS:
* Status of operation
*/
{
NTSTATUS Status;
AFD_DbgPrint(MAX_TRACE, ("wVersionRequested (0x%X) \n", wVersionRequested));
Status = NO_ERROR;
Upcalls = UpcallTable;
if (Status == NO_ERROR) {
lpProcTable->lpWSPAccept = WSPAccept;
lpProcTable->lpWSPAddressToString = WSPAddressToString;
lpProcTable->lpWSPAsyncSelect = WSPAsyncSelect;
lpProcTable->lpWSPBind = WSPBind;
lpProcTable->lpWSPCancelBlockingCall = WSPCancelBlockingCall;
lpProcTable->lpWSPCleanup = WSPCleanup;
lpProcTable->lpWSPCloseSocket = WSPCloseSocket;
lpProcTable->lpWSPConnect = WSPConnect;
lpProcTable->lpWSPDuplicateSocket = WSPDuplicateSocket;
lpProcTable->lpWSPEnumNetworkEvents = WSPEnumNetworkEvents;
lpProcTable->lpWSPEventSelect = WSPEventSelect;
lpProcTable->lpWSPGetOverlappedResult = WSPGetOverlappedResult;
lpProcTable->lpWSPGetPeerName = WSPGetPeerName;
lpProcTable->lpWSPGetSockName = WSPGetSockName;
lpProcTable->lpWSPGetSockOpt = WSPGetSockOpt;
lpProcTable->lpWSPGetQOSByName = WSPGetQOSByName;
lpProcTable->lpWSPIoctl = WSPIoctl;
lpProcTable->lpWSPJoinLeaf = WSPJoinLeaf;
lpProcTable->lpWSPListen = WSPListen;
lpProcTable->lpWSPRecv = WSPRecv;
lpProcTable->lpWSPRecvDisconnect = WSPRecvDisconnect;
lpProcTable->lpWSPRecvFrom = WSPRecvFrom;
lpProcTable->lpWSPSelect = WSPSelect;
lpProcTable->lpWSPSend = WSPSend;
lpProcTable->lpWSPSendDisconnect = WSPSendDisconnect;
lpProcTable->lpWSPSendTo = WSPSendTo;
lpProcTable->lpWSPSetSockOpt = WSPSetSockOpt;
lpProcTable->lpWSPShutdown = WSPShutdown;
lpProcTable->lpWSPSocket = WSPSocket;
lpProcTable->lpWSPStringToAddress = WSPStringToAddress;
lpWSPData->wVersion = MAKEWORD(2, 2);
lpWSPData->wHighVersion = MAKEWORD(2, 2);
}
AFD_DbgPrint(MAX_TRACE, ("Status (%d).\n", Status));
return Status;
}
INT
WSPAPI
WSPCleanup(
OUT LPINT lpErrno)
/*
* FUNCTION: Cleans up service provider for a client
* ARGUMENTS:
* lpErrno = Address of buffer for error information
* RETURNS:
* 0 if successful, or SOCKET_ERROR if not
*/
{
AFD_DbgPrint(MAX_TRACE, ("\n"));
AFD_DbgPrint(MAX_TRACE, ("Leaving.\n"));
*lpErrno = NO_ERROR;
return 0;
}
int
GetSocketInformation(
PSOCKET_INFORMATION Socket,
ULONG AfdInformationClass,
PULONG Ulong OPTIONAL,
PLARGE_INTEGER LargeInteger OPTIONAL)
{
IO_STATUS_BLOCK IOSB;
AFD_INFO InfoData;
NTSTATUS Status;
HANDLE SockEvent;
Status = NtCreateEvent( &SockEvent, GENERIC_READ | GENERIC_WRITE,
NULL, 1, FALSE );
if( !NT_SUCCESS(Status) ) return -1;
/* Set Info Class */
InfoData.InformationClass = AfdInformationClass;
/* Send IOCTL */
Status = NtDeviceIoControlFile( (HANDLE)Socket->Handle,
SockEvent,
NULL,
NULL,
&IOSB,
IOCTL_AFD_GET_INFO,
&InfoData,
sizeof(InfoData),
&InfoData,
sizeof(InfoData));
/* Wait for return */
if (Status == STATUS_PENDING) {
WaitForSingleObject(SockEvent, INFINITE);
}
/* Return Information */
*Ulong = InfoData.Information.Ulong;
if (LargeInteger != NULL) {
*LargeInteger = InfoData.Information.LargeInteger;
}
NtClose( SockEvent );
return 0;
}
int
SetSocketInformation(
PSOCKET_INFORMATION Socket,
ULONG AfdInformationClass,
PULONG Ulong OPTIONAL,
PLARGE_INTEGER LargeInteger OPTIONAL)
{
IO_STATUS_BLOCK IOSB;
AFD_INFO InfoData;
NTSTATUS Status;
HANDLE SockEvent;
Status = NtCreateEvent( &SockEvent, GENERIC_READ | GENERIC_WRITE,
NULL, 1, FALSE );
if( !NT_SUCCESS(Status) ) return -1;
/* Set Info Class */
InfoData.InformationClass = AfdInformationClass;
/* Set Information */
InfoData.Information.Ulong = *Ulong;
if (LargeInteger != NULL) {
InfoData.Information.LargeInteger = *LargeInteger;
}
AFD_DbgPrint(MID_TRACE,("XXX Info %x (Data %x)\n",
AfdInformationClass, *Ulong));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -