📄 dllmain.c
字号:
&PendingAcceptData,
sizeof(PendingAcceptData),
PendingData,
PendingDataLength);
/* Wait for return */
if (Status == STATUS_PENDING) {
WaitForSingleObject(SockEvent, INFINITE);
Status = IOSB.Status;
}
if (!NT_SUCCESS(Status)) {
NtClose( SockEvent );
MsafdReturnWithErrno( Status, lpErrno, 0, NULL );
return INVALID_SOCKET;
}
}
}
if ((Socket->SharedData.ServiceFlags1 & XP1_QOS_SUPPORTED) != 0) {
/* I don't support this yet */
}
/* Build Callee ID */
CalleeID.buf = (PVOID)Socket->LocalAddress;
CalleeID.len = Socket->SharedData.SizeOfLocalAddress;
/* Set up Address in SOCKADDR Format */
RtlCopyMemory (RemoteAddress,
&ListenReceiveData->Address.Address[0].AddressType,
sizeof(*RemoteAddress));
/* Build Caller ID */
CallerID.buf = (PVOID)RemoteAddress;
CallerID.len = sizeof(*RemoteAddress);
/* Build Caller Data */
CallerData.buf = PendingData;
CallerData.len = PendingDataLength;
/* Check if socket supports Conditional Accept */
if (Socket->SharedData.UseDelayedAcceptance != 0) {
/* Allocate Buffer for Callee Data */
CalleeDataBuffer = HeapAlloc(GlobalHeap, 0, 4096);
CalleeData.buf = CalleeDataBuffer;
CalleeData.len = 4096;
} else {
/* Nothing */
CalleeData.buf = 0;
CalleeData.len = 0;
}
/* Call the Condition Function */
CallBack = (lpfnCondition)( &CallerID,
CallerData.buf == NULL
? NULL
: & CallerData,
NULL,
NULL,
&CalleeID,
CalleeData.buf == NULL
? NULL
: & CalleeData,
&GroupID,
dwCallbackData);
if (((CallBack == CF_ACCEPT) && GroupID) != 0) {
/* TBD: Check for Validity */
}
if (CallBack == CF_ACCEPT) {
if ((Socket->SharedData.ServiceFlags1 & XP1_QOS_SUPPORTED) != 0) {
/* I don't support this yet */
}
if (CalleeData.buf) {
// SockSetConnectData Sockets(SocketID), IOCTL_AFD_SET_CONNECT_DATA, CalleeData.Buffer, CalleeData.BuffSize, 0
}
} else {
/* Callback rejected. Build Defer Structure */
DeferData.SequenceNumber = ListenReceiveData->SequenceNumber;
DeferData.RejectConnection = (CallBack == CF_REJECT);
/* Send IOCTL */
Status = NtDeviceIoControlFile( (HANDLE)Socket->Handle,
SockEvent,
NULL,
NULL,
&IOSB,
IOCTL_AFD_DEFER_ACCEPT,
&DeferData,
sizeof(DeferData),
NULL,
0);
/* Wait for return */
if (Status == STATUS_PENDING) {
WaitForSingleObject(SockEvent, INFINITE);
Status = IOSB.Status;
}
NtClose( SockEvent );
if (!NT_SUCCESS(Status)) {
MsafdReturnWithErrno( Status, lpErrno, 0, NULL );
return INVALID_SOCKET;
}
if (CallBack == CF_REJECT ) {
*lpErrno = WSAECONNREFUSED;
return INVALID_SOCKET;
} else {
*lpErrno = WSAECONNREFUSED;
return INVALID_SOCKET;
}
}
}
/* Create a new Socket */
ProtocolInfo.dwCatalogEntryId = Socket->SharedData.CatalogEntryId;
ProtocolInfo.dwServiceFlags1 = Socket->SharedData.ServiceFlags1;
ProtocolInfo.dwProviderFlags = Socket->SharedData.ProviderFlags;
AcceptSocket = WSPSocket (Socket->SharedData.AddressFamily,
Socket->SharedData.SocketType,
Socket->SharedData.Protocol,
&ProtocolInfo,
GroupID,
Socket->SharedData.CreateFlags,
NULL);
/* Set up the Accept Structure */
AcceptData.ListenHandle = AcceptSocket;
AcceptData.SequenceNumber = ListenReceiveData->SequenceNumber;
/* Send IOCTL to Accept */
Status = NtDeviceIoControlFile( (HANDLE)Socket->Handle,
SockEvent,
NULL,
NULL,
&IOSB,
IOCTL_AFD_ACCEPT,
&AcceptData,
sizeof(AcceptData),
NULL,
0);
/* Wait for return */
if (Status == STATUS_PENDING) {
WaitForSingleObject(SockEvent, INFINITE);
Status = IOSB.Status;
}
if (!NT_SUCCESS(Status)) {
WSPCloseSocket( AcceptSocket, lpErrno );
MsafdReturnWithErrno( Status, lpErrno, 0, NULL );
return INVALID_SOCKET;
}
/* Return Address in SOCKADDR FORMAT */
if( SocketAddress ) {
RtlCopyMemory (SocketAddress,
&ListenReceiveData->Address.Address[0].AddressType,
sizeof(*RemoteAddress));
if( SocketAddressLength )
*SocketAddressLength =
ListenReceiveData->Address.Address[0].AddressLength;
}
NtClose( SockEvent );
/* Re-enable Async Event */
SockReenableAsyncSelectEvent(Socket, FD_ACCEPT);
AFD_DbgPrint(MID_TRACE,("Socket %x\n", AcceptSocket));
*lpErrno = 0;
/* Return Socket */
return AcceptSocket;
}
int
WSPAPI
WSPConnect(
SOCKET Handle,
const struct sockaddr * SocketAddress,
int SocketAddressLength,
LPWSABUF lpCallerData,
LPWSABUF lpCalleeData,
LPQOS lpSQOS,
LPQOS lpGQOS,
LPINT lpErrno)
{
IO_STATUS_BLOCK IOSB;
PAFD_CONNECT_INFO ConnectInfo;
PSOCKET_INFORMATION Socket = NULL;
NTSTATUS Status;
UCHAR ConnectBuffer[0x22];
ULONG ConnectDataLength;
ULONG InConnectDataLength;
INT BindAddressLength;
PSOCKADDR BindAddress;
HANDLE SockEvent;
Status = NtCreateEvent( &SockEvent, GENERIC_READ | GENERIC_WRITE,
NULL, 1, FALSE );
if( !NT_SUCCESS(Status) ) return -1;
AFD_DbgPrint(MID_TRACE,("Called\n"));
/* Get the Socket Structure associate to this Socket*/
Socket = GetSocketStructure(Handle);
/* Bind us First */
if (Socket->SharedData.State == SocketOpen) {
/* Get the Wildcard Address */
BindAddressLength = Socket->HelperData->MaxWSAddressLength;
BindAddress = HeapAlloc(GetProcessHeap(), 0, BindAddressLength);
Socket->HelperData->WSHGetWildcardSockaddr (Socket->HelperContext,
BindAddress,
&BindAddressLength);
/* Bind it */
WSPBind(Handle, BindAddress, BindAddressLength, NULL);
}
/* Set the Connect Data */
if (lpCallerData != NULL) {
ConnectDataLength = lpCallerData->len;
Status = NtDeviceIoControlFile((HANDLE)Handle,
SockEvent,
NULL,
NULL,
&IOSB,
IOCTL_AFD_SET_CONNECT_DATA,
lpCallerData->buf,
ConnectDataLength,
NULL,
0);
/* Wait for return */
if (Status == STATUS_PENDING) {
WaitForSingleObject(SockEvent, INFINITE);
Status = IOSB.Status;
}
}
/* Dynamic Structure...ugh */
ConnectInfo = (PAFD_CONNECT_INFO)ConnectBuffer;
/* Set up Address in TDI Format */
ConnectInfo->RemoteAddress.TAAddressCount = 1;
ConnectInfo->RemoteAddress.Address[0].AddressLength = SocketAddressLength - sizeof(SocketAddress->sa_family);
ConnectInfo->RemoteAddress.Address[0].AddressType = SocketAddress->sa_family;
RtlCopyMemory (ConnectInfo->RemoteAddress.Address[0].Address,
SocketAddress->sa_data,
SocketAddressLength - sizeof(SocketAddress->sa_family));
/*
* Disable FD_WRITE and FD_CONNECT
* The latter fixes a race condition where the FD_CONNECT is re-enabled
* at the end of this function right after the Async Thread disables it.
* This should only happen at the *next* WSPConnect
*/
if (Socket->SharedData.AsyncEvents & FD_CONNECT) {
Socket->SharedData.AsyncDisabledEvents |= FD_CONNECT | FD_WRITE;
}
/* Tell AFD that we want Connection Data back, have it allocate a buffer */
if (lpCalleeData != NULL) {
InConnectDataLength = lpCalleeData->len;
Status = NtDeviceIoControlFile((HANDLE)Handle,
SockEvent,
NULL,
NULL,
&IOSB,
IOCTL_AFD_SET_CONNECT_DATA_SIZE,
&InConnectDataLength,
sizeof(InConnectDataLength),
NULL,
0);
/* Wait for return */
if (Status == STATUS_PENDING) {
WaitForSingleObject(SockEvent, INFINITE);
Status = IOSB.Status;
}
}
/* AFD doesn't seem to care if these are invalid, but let's 0 them anyways */
ConnectInfo->Root = 0;
ConnectInfo->UseSAN = FALSE;
ConnectInfo->Unknown = 0;
/* FIXME: Handle Async Connect */
if (Socket->SharedData.NonBlocking) {
AFD_DbgPrint(MIN_TRACE, ("Async Connect UNIMPLEMENTED!\n"));
}
/* Send IOCTL */
Status = NtDeviceIoControlFile((HANDLE)Handle,
SockEvent,
NULL,
NULL,
&IOSB,
IOCTL_AFD_CONNECT,
ConnectInfo,
0x22,
NULL,
0);
/* Wait for return */
if (Status == STATUS_PENDING) {
WaitForSingleObject(SockEvent, INFINITE);
Status = IOSB.Status;
}
/* Get any pending connect data */
if (lpCalleeData != NULL) {
Status = NtDeviceIoControlFile((HANDLE)Handle,
SockEvent,
NULL,
NULL,
&IOSB,
IOCTL_AFD_GET_CONNECT_DATA,
NULL,
0,
lpCalleeData->buf,
lpCalleeData->len);
/* Wait for return */
if (Status == STATUS_PENDING) {
WaitForSingleObject(SockEvent, INFINITE);
Status = IOSB.Status;
}
}
/* Re-enable Async Event */
SockReenableAsyncSelectEvent(Socket, FD_WRITE);
/* FIXME: THIS IS NOT RIGHT!!! HACK HACK HACK! */
SockReenableAsyncSelectEvent(Socket, FD_CONNECT);
AFD_DbgPrint(MID_TRACE,("Ending\n"));
NtClose( SockEvent );
return MsafdReturnWithErrno( IOSB.Status, lpErrno, 0, NULL );
}
int
WSPAPI
WSPShutdown(
SOCKET Handle,
int HowTo,
LPINT lpErrno)
{
IO_STATUS_BLOCK IOSB;
AFD_DISCONNECT_INFO DisconnectInfo;
PSOCKET_INFORMATION Socket = NULL;
NTSTATUS Status;
HANDLE SockEvent;
Status = NtCreateEvent( &SockEvent, GENERIC_READ | GENERIC_WRITE,
NULL, 1, FALSE );
if( !NT_SUCCESS(Status) ) return -1;
AFD_DbgPrint(MID_TRACE,("Called\n"));
/* Get the Socket Structure associate to this Socket*/
Socket = GetSocketStructure(Handle);
/* Set AFD Disconnect Type */
switch (HowTo) {
case SD_RECEIVE:
DisconnectInfo.DisconnectType = AFD_DISCONNECT_RECV;
Socket->SharedData.ReceiveShutdown = TRUE;
break;
case SD_SEND:
DisconnectInfo.DisconnectType= AFD_DISCONNECT_SEND;
Socket->SharedData.SendShutdown = TRUE;
break;
case SD_BOTH:
DisconnectInfo.DisconnectType = AFD_DISCONNECT_RECV | AFD_DISCONNECT_SEND;
Socket->SharedData.ReceiveShutdown = TRUE;
Socket->SharedData.SendShutdown = TRUE;
break;
}
DisconnectInfo.Timeout = RtlConvertLongToLargeInteger(-1);
/* Send IOCTL */
Status = NtDeviceIoControlFile((HANDLE)Handle,
SockEvent,
NULL,
NULL,
&IOSB,
IOCTL_AFD_DISCONNECT,
&DisconnectInfo,
sizeof(DisconnectInfo),
NULL,
0);
/* Wait for return */
if (Status == STATUS_PENDING) {
WaitForSingleObject(SockEvent, INFINITE);
}
AFD_DbgPrint(MID_TRACE,("Ending\n"));
NtClose( SockEvent );
return MsafdReturnWithErrno( IOSB.Status, lpErrno, 0, NULL );
}
INT
WSPAPI
WSPGetSockName(
IN SOCKET Handle,
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(Handle);
/* Allocate a buffer for the address */
TdiAddressSize = FIELD_OFFSET(TDI_ADDRESS_INFO,
Address.Address[0].Address) +
Socket->SharedData.SizeOfLocalAddress;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -