⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dllmain.c

📁 winNT技术操作系统,国外开放的原代码和LIUX一样
💻 C
📖 第 1 页 / 共 5 页
字号:
								&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 + -