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

📄 dllmain.c

📁 winNT技术操作系统,国外开放的原代码和LIUX一样
💻 C
📖 第 1 页 / 共 5 页
字号:
 *     lpErrno = Address of buffer for error information
 * RETURNS:
 *     0, or SOCKET_ERROR if the socket could not be bound
 */
{
	IO_STATUS_BLOCK				IOSB;
	PAFD_BIND_DATA				BindData;
	PSOCKET_INFORMATION			Socket = NULL;
	NTSTATUS					Status;
	UCHAR						BindBuffer[0x1A];
	SOCKADDR_INFO				SocketInfo;
	HANDLE                                  SockEvent;

	Status = NtCreateEvent( &SockEvent, GENERIC_READ | GENERIC_WRITE,
				NULL, 1, FALSE );

	if( !NT_SUCCESS(Status) ) return -1;

	/* Get the Socket Structure associate to this Socket*/
	Socket = GetSocketStructure(Handle);

	/* Dynamic Structure...ugh */
	BindData = (PAFD_BIND_DATA)BindBuffer;

	/* Set up Address in TDI Format */
	BindData->Address.TAAddressCount = 1;
	BindData->Address.Address[0].AddressLength = SocketAddressLength - sizeof(SocketAddress->sa_family);
	BindData->Address.Address[0].AddressType = SocketAddress->sa_family;
	RtlCopyMemory (BindData->Address.Address[0].Address,
					SocketAddress->sa_data,
					SocketAddressLength - sizeof(SocketAddress->sa_family));
	
	/* Get Address Information */
	Socket->HelperData->WSHGetSockaddrType ((PSOCKADDR)SocketAddress, 
											SocketAddressLength, 
											&SocketInfo);

	/* Set the Share Type */
	if (Socket->SharedData.ExclusiveAddressUse) {
		BindData->ShareType = AFD_SHARE_EXCLUSIVE;
	}
	else if (SocketInfo.EndpointInfo == SockaddrEndpointInfoWildcard) {
		BindData->ShareType = AFD_SHARE_WILDCARD;
	}
	else if (Socket->SharedData.ReuseAddresses) {
		BindData->ShareType = AFD_SHARE_REUSE;
	} else {
		BindData->ShareType = AFD_SHARE_UNIQUE;
	}

	/* Send IOCTL */
	Status = NtDeviceIoControlFile( (HANDLE)Socket->Handle,
					SockEvent,
					NULL,
					NULL,
					&IOSB,
					IOCTL_AFD_BIND,
					BindData,
					0xA + Socket->SharedData.SizeOfLocalAddress, /* Can't figure out a way to calculate this in C*/
					BindData,
					0xA + Socket->SharedData.SizeOfLocalAddress); /* Can't figure out a way to calculate this C */
        
	/* Wait for return */
	if (Status == STATUS_PENDING) {
		WaitForSingleObject(SockEvent, INFINITE);
	}         
	
	/* Set up Socket Data */
	Socket->SharedData.State = SocketBound;
	Socket->TdiAddressHandle = (HANDLE)IOSB.Information;

	NtClose( SockEvent );

	return MsafdReturnWithErrno
	    ( IOSB.Status, lpErrno, IOSB.Information, NULL );
}

int 
WSPAPI
WSPListen(
	SOCKET Handle, 
	int Backlog, 
	LPINT lpErrno)
{
	IO_STATUS_BLOCK				IOSB;
	AFD_LISTEN_DATA				ListenData;
	PSOCKET_INFORMATION			Socket = NULL;
	HANDLE                                  SockEvent;
	NTSTATUS				Status;

	Status = NtCreateEvent( &SockEvent, GENERIC_READ | GENERIC_WRITE,
				NULL, 1, FALSE );

	if( !NT_SUCCESS(Status) ) return -1;

	/* Get the Socket Structure associate to this Socket*/
	Socket = GetSocketStructure(Handle);

	/* Set Up Listen Structure */
	ListenData.UseSAN = FALSE;
	ListenData.UseDelayedAcceptance = Socket->SharedData.UseDelayedAcceptance;
	ListenData.Backlog = Backlog;

	/* Send IOCTL */
	Status = NtDeviceIoControlFile( (HANDLE)Socket->Handle,
					SockEvent,
					NULL,
					NULL,
					&IOSB,
					IOCTL_AFD_START_LISTEN,
					&ListenData,
					sizeof(ListenData),
					NULL,
					0);
        
	/* Wait for return */
	if (Status == STATUS_PENDING) {
		WaitForSingleObject(SockEvent, INFINITE);
	}         

	/* Set to Listening */
	Socket->SharedData.Listening = TRUE;

	NtClose( SockEvent );

	return MsafdReturnWithErrno
	    ( IOSB.Status, lpErrno, IOSB.Information, NULL );
}


int
WSPAPI 
WSPSelect(
	int nfds, 
	fd_set *readfds,
	fd_set *writefds, 
	fd_set *exceptfds, 
	struct timeval *timeout, 
	LPINT lpErrno)
{
    IO_STATUS_BLOCK			IOSB;
    PAFD_POLL_INFO			PollInfo;
    NTSTATUS				Status;
    ULONG				HandleCount, OutCount = 0;
    ULONG				PollBufferSize;
    PVOID				PollBuffer;
    ULONG				i, j = 0, x;
    HANDLE                              SockEvent;
    BOOL                                HandleCounted;
    LARGE_INTEGER                       Timeout;
    
    /* Find out how many sockets we have, and how large the buffer needs 
     * to be */
    
    HandleCount = 
	( readfds ? readfds->fd_count : 0 ) + 
	( writefds ? writefds->fd_count : 0 ) + 
	( exceptfds ? exceptfds->fd_count : 0 );

    if( HandleCount < 0 || nfds != 0 ) HandleCount = nfds * 3;

    PollBufferSize = sizeof(*PollInfo) + (HandleCount * sizeof(AFD_HANDLE));
    
    AFD_DbgPrint(MID_TRACE,("HandleCount: %d BufferSize: %d\n", 
                            HandleCount, PollBufferSize));

    /* Convert Timeout to NT Format */
    if (timeout == NULL) {
	Timeout.u.LowPart = -1;
	Timeout.u.HighPart = 0x7FFFFFFF;
	AFD_DbgPrint(MAX_TRACE,("Infinite timeout\n"));
    } else {
	Timeout = RtlEnlargedIntegerMultiply
	    ((timeout->tv_sec * 1000) + (timeout->tv_usec / 1000), -10000);
	/* Negative timeouts are illegal.  Since the kernel represents an 
	 * incremental timeout as a negative number, we check for a positive
	 * result.
	 */
	if (Timeout.QuadPart > 0) {
	  if (lpErrno) *lpErrno = WSAEINVAL;
	  return SOCKET_ERROR;
	}
	AFD_DbgPrint(MAX_TRACE,("Timeout: Orig %d.%06d kernel %d\n",
				timeout->tv_sec, timeout->tv_usec,
				Timeout.u.LowPart));
    }
    
    Status = NtCreateEvent( &SockEvent, GENERIC_READ | GENERIC_WRITE,
			    NULL, 1, FALSE );
    
    if( !NT_SUCCESS(Status) ) return SOCKET_ERROR;
    
    /* Allocate */
    PollBuffer = HeapAlloc(GlobalHeap, 0, PollBufferSize);

    if (!PollBuffer) {
      if (*lpErrno) *lpErrno = WSAEFAULT;
      NtClose(SockEvent);
      return SOCKET_ERROR;
    }

    PollInfo = (PAFD_POLL_INFO)PollBuffer;

    RtlZeroMemory( PollInfo, PollBufferSize );

    /* Number of handles for AFD to Check */
    PollInfo->HandleCount = HandleCount;
    PollInfo->Exclusive = FALSE;
    PollInfo->Timeout = Timeout;
    
    if (readfds != NULL) {
	for (i = 0; i < readfds->fd_count; i++, j++) {
	    PollInfo->Handles[j].Handle = readfds->fd_array[i];
	    PollInfo->Handles[j].Events = AFD_EVENT_RECEIVE | 
	                                  AFD_EVENT_DISCONNECT |
	                                  AFD_EVENT_ABORT |
	                                  AFD_EVENT_ACCEPT;
	} 
    }
    if (writefds != NULL) {
	for (i = 0; i < writefds->fd_count; i++, j++) {
	    PollInfo->Handles[j].Handle = writefds->fd_array[i];
	    PollInfo->Handles[j].Events = AFD_EVENT_SEND |
	                                  AFD_EVENT_CONNECT;
	}	
    }
    if (exceptfds != NULL) {
	for (i = 0; i < exceptfds->fd_count; i++, j++) {
	    PollInfo->Handles[j].Handle = exceptfds->fd_array[i];
	    PollInfo->Handles[j].Events = AFD_EVENT_OOB_RECEIVE |
	                                  AFD_EVENT_CONNECT_FAIL;
	}
    }
    
    /* Send IOCTL */
    Status = NtDeviceIoControlFile( (HANDLE)PollInfo->Handles[0].Handle,
				    SockEvent,
				    NULL,
				    NULL,
				    &IOSB,
				    IOCTL_AFD_SELECT,
				    PollInfo,
				    PollBufferSize,
				    PollInfo,
				    PollBufferSize);

    AFD_DbgPrint(MID_TRACE,("DeviceIoControlFile => %x\n", Status));
    
    /* Wait for Completition */
    if (Status == STATUS_PENDING) {
	WaitForSingleObject(SockEvent, INFINITE);
    }
    
    /* Clear the Structures */
    if( readfds ) FD_ZERO(readfds);
    if( writefds ) FD_ZERO(writefds);
    if( exceptfds ) FD_ZERO(exceptfds);
    
    /* Loop through return structure */
    HandleCount = PollInfo->HandleCount;
    
    /* Return in FDSET Format */
    for (i = 0; i < HandleCount; i++) {
	HandleCounted = FALSE;
	for(x = 1; x; x<<=1) {
	    switch (PollInfo->Handles[i].Events & x) {
	    case AFD_EVENT_RECEIVE: 
	    case AFD_EVENT_DISCONNECT: 
	    case AFD_EVENT_ABORT: 
	    case AFD_EVENT_ACCEPT: 
	    case AFD_EVENT_CLOSE:
		AFD_DbgPrint(MID_TRACE,("Event %x on handle %x\n",
					PollInfo->Handles[i].Events,
					PollInfo->Handles[i].Handle));
		if (! HandleCounted) {
		    OutCount++;
		    HandleCounted = TRUE;
		}
		if( readfds ) FD_SET(PollInfo->Handles[i].Handle, readfds);
		break;

	    case AFD_EVENT_SEND: case AFD_EVENT_CONNECT:
		AFD_DbgPrint(MID_TRACE,("Event %x on handle %x\n",
					PollInfo->Handles[i].Events,
					PollInfo->Handles[i].Handle));
		if (! HandleCounted) {
		    OutCount++;
		    HandleCounted = TRUE;
		}
		if( writefds ) FD_SET(PollInfo->Handles[i].Handle, writefds);
		break;
		
	    case AFD_EVENT_OOB_RECEIVE: case AFD_EVENT_CONNECT_FAIL:
		AFD_DbgPrint(MID_TRACE,("Event %x on handle %x\n",
					PollInfo->Handles[i].Events,
					PollInfo->Handles[i].Handle));
		if (! HandleCounted) {
		    OutCount++;
		    HandleCounted = TRUE;
		}
		if( exceptfds ) FD_SET(PollInfo->Handles[i].Handle, exceptfds);
		break;
	    }
	}
    }

    HeapFree( GlobalHeap, 0, PollBuffer );
    NtClose( SockEvent );

    AFD_DbgPrint(MID_TRACE,("lpErrno = %x\n", lpErrno));

    if( lpErrno ) {
	switch( IOSB.Status ) {
	case STATUS_SUCCESS: 
	case STATUS_TIMEOUT: *lpErrno = 0; break;
	default: *lpErrno = WSAEINVAL; break;
	}
    }

    AFD_DbgPrint(MID_TRACE,("%d events\n", OutCount));
    
    return OutCount;
}

SOCKET
WSPAPI 
WSPAccept(
	SOCKET Handle, 
	struct sockaddr *SocketAddress, 
	int *SocketAddressLength, 
	LPCONDITIONPROC lpfnCondition, 
	DWORD_PTR dwCallbackData, 
	LPINT lpErrno)
{
	IO_STATUS_BLOCK				IOSB;
	PAFD_RECEIVED_ACCEPT_DATA	ListenReceiveData;
	AFD_ACCEPT_DATA				AcceptData;
	AFD_DEFER_ACCEPT_DATA		DeferData;
	AFD_PENDING_ACCEPT_DATA		PendingAcceptData;
	PSOCKET_INFORMATION			Socket = NULL;
	NTSTATUS					Status;
	struct fd_set				ReadSet;
	struct timeval				Timeout;
	PVOID						PendingData = NULL;
	ULONG						PendingDataLength = 0;
	PVOID						CalleeDataBuffer;
	WSABUF						CallerData, CalleeID, CallerID, CalleeData;
	PSOCKADDR					RemoteAddress =  NULL;
	GROUP						GroupID = 0;
	ULONG						CallBack;
	WSAPROTOCOL_INFOW			ProtocolInfo;
	SOCKET						AcceptSocket;
	UCHAR						ReceiveBuffer[0x1A];
	HANDLE                                  SockEvent;

	Status = NtCreateEvent( &SockEvent, GENERIC_READ | GENERIC_WRITE,
				NULL, 1, FALSE );

	if( !NT_SUCCESS(Status) ) {
		MsafdReturnWithErrno( Status, lpErrno, 0, NULL );
		return INVALID_SOCKET;
	}

	/* Dynamic Structure...ugh */
	ListenReceiveData = (PAFD_RECEIVED_ACCEPT_DATA)ReceiveBuffer;

	/* Get the Socket Structure associate to this Socket*/
	Socket = GetSocketStructure(Handle);

	/* If this is non-blocking, make sure there's something for us to accept */
	FD_ZERO(&ReadSet);
	FD_SET(Socket->Handle, &ReadSet);
	Timeout.tv_sec=0;
	Timeout.tv_usec=0;

	WSPSelect(0, &ReadSet, NULL, NULL, &Timeout, NULL);

	if (ReadSet.fd_array[0] != Socket->Handle) return 0;

	/* Send IOCTL */
	Status = NtDeviceIoControlFile( (HANDLE)Socket->Handle,
					SockEvent,
					NULL,
					NULL,
					&IOSB,
					IOCTL_AFD_WAIT_FOR_LISTEN,
					NULL,
					0,
					ListenReceiveData,
					0xA + sizeof(*ListenReceiveData));
	
	/* 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 (lpfnCondition != NULL) {
		if ((Socket->SharedData.ServiceFlags1 & XP1_CONNECT_DATA) != 0) {
			/* Find out how much data is pending */
			PendingAcceptData.SequenceNumber = ListenReceiveData->SequenceNumber;
			PendingAcceptData.ReturnSize = TRUE;

			/* Send IOCTL */
			Status = NtDeviceIoControlFile( (HANDLE)Socket->Handle,
							SockEvent,
							NULL,
							NULL,
							&IOSB,
							IOCTL_AFD_GET_PENDING_CONNECT_DATA,
							&PendingAcceptData,
							sizeof(PendingAcceptData),
							&PendingAcceptData,
							sizeof(PendingAcceptData));
        
			/* 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;
			}

			/* How much data to allocate */
			PendingDataLength = IOSB.Information;

			if (PendingDataLength) {
				/* Allocate needed space */
				PendingData = HeapAlloc(GlobalHeap, 0, PendingDataLength);

				/* We want the data now */
				PendingAcceptData.ReturnSize = FALSE;

				/* Send IOCTL */
				Status = NtDeviceIoControlFile( (HANDLE)Socket->Handle,
								SockEvent,
								NULL,
								NULL,
								&IOSB,
								IOCTL_AFD_GET_PENDING_CONNECT_DATA,

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -