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

📄 read.c

📁 ReactOS是一些高手根据Windows XP的内核编写出的类XP。内核实现机理和API函数调用几乎相同。甚至可以兼容XP的程序。喜欢研究系统内核的人可以看一看。
💻 C
📖 第 1 页 / 共 2 页
字号:
    InsertTailList( &FCB->PendingIrpList[FUNCTION_RECV],
                    &Irp->Tail.Overlay.ListEntry );

    /************ From this point, the IRP is not ours ************/

    Status = ReceiveActivity( FCB, Irp );

    if( Status == STATUS_PENDING && RecvReq->AfdFlags & AFD_IMMEDIATE ) {
        AFD_DbgPrint(MID_TRACE,("Nonblocking\n"));
        Status = STATUS_CANT_WAIT;
        TotalBytesCopied = 0;
        RemoveEntryList( &Irp->Tail.Overlay.ListEntry );
        UnlockBuffers( RecvReq->BufferArray, RecvReq->BufferCount, FALSE );
        return UnlockAndMaybeComplete( FCB, Status, Irp,
                                       TotalBytesCopied, NULL, TRUE );
    } else if( Status == STATUS_PENDING ) {
        AFD_DbgPrint(MID_TRACE,("Leaving read irp\n"));
        IoMarkIrpPending( Irp );
    } else {
        AFD_DbgPrint(MID_TRACE,("Completed with status %x\n", Status));
    }

    SocketStateUnlock( FCB );
    return Status;
}


static NTSTATUS STDCALL
SatisfyPacketRecvRequest( PAFD_FCB FCB, PIRP Irp,
			  PAFD_STORED_DATAGRAM DatagramRecv,
			  PUINT TotalBytesCopied ) {
    NTSTATUS Status = STATUS_SUCCESS;
    PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation( Irp );
    PAFD_RECV_INFO RecvReq =
	IrpSp->Parameters.DeviceIoControl.Type3InputBuffer;
    UINT BytesToCopy = 0, BytesAvailable = DatagramRecv->Len, AddrLen = 0;
    PAFD_MAPBUF Map;

    Map = (PAFD_MAPBUF)(RecvReq->BufferArray +
			RecvReq->BufferCount +
			EXTRA_LOCK_BUFFERS);

    BytesToCopy =
	MIN( RecvReq->BufferArray[0].len, BytesAvailable );

    AFD_DbgPrint(MID_TRACE,("BytesToCopy: %d len %d\n", BytesToCopy,
			    RecvReq->BufferArray[0].len));

    if( Map[0].Mdl ) {
	/* Copy the address */
	if( Map[1].Mdl && Map[2].Mdl ) {
	    AFD_DbgPrint(MID_TRACE,("Checking TAAddressCount\n"));

	    if( DatagramRecv->Address->TAAddressCount != 1 ) {
		AFD_DbgPrint
		    (MID_TRACE,
		     ("Wierd address count %d\n",
		      DatagramRecv->Address->TAAddressCount));
	    }

	    AFD_DbgPrint(MID_TRACE,("Computing addr len\n"));

	    AddrLen = MIN(DatagramRecv->Address->Address->AddressLength +
			  sizeof(USHORT),
			  RecvReq->BufferArray[1].len);

	    AFD_DbgPrint(MID_TRACE,("Copying %d bytes of address\n", AddrLen));

	    Map[1].BufferAddress = MmMapLockedPages( Map[1].Mdl, KernelMode );

	    AFD_DbgPrint(MID_TRACE,("Done mapping, copying address\n"));

	    RtlCopyMemory( Map[1].BufferAddress,
			   &DatagramRecv->Address->Address->AddressType,
			   AddrLen );

	    MmUnmapLockedPages( Map[1].BufferAddress, Map[1].Mdl );

	    AFD_DbgPrint(MID_TRACE,("Copying address len\n"));

	    Map[2].BufferAddress = MmMapLockedPages( Map[2].Mdl, KernelMode );
	    *((PINT)Map[2].BufferAddress) = AddrLen;
	    MmUnmapLockedPages( Map[2].BufferAddress, Map[2].Mdl );
	}

	AFD_DbgPrint(MID_TRACE,("Mapping data buffer pages\n"));

	Map[0].BufferAddress = MmMapLockedPages( Map[0].Mdl, KernelMode );

	AFD_DbgPrint(MID_TRACE,("Buffer %d: %x:%d\n",
				0,
				Map[0].BufferAddress,
				BytesToCopy));

	/* OskitDumpBuffer
	   ( FCB->Recv.Window + FCB->Recv.BytesUsed, BytesToCopy ); */

	RtlCopyMemory( Map[0].BufferAddress,
		       FCB->Recv.Window + FCB->Recv.BytesUsed,
		       BytesToCopy );

	MmUnmapLockedPages( Map[0].BufferAddress, Map[0].Mdl );

	FCB->Recv.BytesUsed = 0;
	*TotalBytesCopied = BytesToCopy;
    }

    Status = Irp->IoStatus.Status = STATUS_SUCCESS;
    Irp->IoStatus.Information = BytesToCopy;
    ExFreePool( DatagramRecv->Address );
    ExFreePool( DatagramRecv );

    AFD_DbgPrint(MID_TRACE,("Done\n"));

    return Status;
}

NTSTATUS NTAPI
PacketSocketRecvComplete(
  PDEVICE_OBJECT DeviceObject,
  PIRP Irp,
  PVOID Context ) {
    NTSTATUS Status = STATUS_SUCCESS;
    PAFD_FCB FCB = Context;
    PIRP NextIrp;
    PIO_STACK_LOCATION NextIrpSp;
    PLIST_ENTRY ListEntry;
    PAFD_RECV_INFO RecvReq;
    PAFD_STORED_DATAGRAM DatagramRecv;
    UINT DGSize = Irp->IoStatus.Information + sizeof( AFD_STORED_DATAGRAM );

    AFD_DbgPrint(MID_TRACE,("Called on %x\n", FCB));

    if( !SocketAcquireStateLock( FCB ) ) return STATUS_UNSUCCESSFUL;

    FCB->ReceiveIrp.InFlightRequest = NULL;

    if( FCB->State == SOCKET_STATE_CLOSED ) {
	SocketStateUnlock( FCB );
	DestroySocket( FCB );
	return STATUS_SUCCESS;
    }

    DatagramRecv = ExAllocatePool( NonPagedPool, DGSize );

    if( DatagramRecv ) {
	DatagramRecv->Len = Irp->IoStatus.Information;
	RtlCopyMemory( DatagramRecv->Buffer, FCB->Recv.Window,
		       DatagramRecv->Len );
	AFD_DbgPrint(MID_TRACE,("Received (A %x)\n",
				FCB->AddressFrom->RemoteAddress));
	DatagramRecv->Address =
	    TaCopyTransportAddress( FCB->AddressFrom->RemoteAddress );

	InsertTailList( &FCB->DatagramList, &DatagramRecv->ListEntry );
    } else Status = STATUS_NO_MEMORY;

    /* Satisfy as many requests as we can */

    while( NT_SUCCESS(Status) &&
	   !IsListEmpty( &FCB->DatagramList ) &&
	   !IsListEmpty( &FCB->PendingIrpList[FUNCTION_RECV] ) ) {
	AFD_DbgPrint(MID_TRACE,("Looping trying to satisfy request\n"));
	ListEntry = RemoveHeadList( &FCB->DatagramList );
	DatagramRecv = CONTAINING_RECORD( ListEntry, AFD_STORED_DATAGRAM,
					  ListEntry );
	ListEntry = RemoveHeadList( &FCB->PendingIrpList[FUNCTION_RECV] );
	NextIrp = CONTAINING_RECORD( ListEntry, IRP, Tail.Overlay.ListEntry );
	NextIrpSp = IoGetCurrentIrpStackLocation( NextIrp );
	RecvReq = NextIrpSp->Parameters.DeviceIoControl.Type3InputBuffer;

	AFD_DbgPrint(MID_TRACE,("RecvReq: %x, DatagramRecv: %x\n",
				RecvReq, DatagramRecv));

	if( DatagramRecv->Len > RecvReq->BufferArray[0].len &&
	    !(RecvReq->TdiFlags & TDI_RECEIVE_PARTIAL) ) {
	    InsertHeadList( &FCB->DatagramList,
			    &DatagramRecv->ListEntry );
	    Status = NextIrp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL;
	    NextIrp->IoStatus.Information = DatagramRecv->Len;
	    UnlockBuffers( RecvReq->BufferArray, RecvReq->BufferCount, TRUE );
	    IoCompleteRequest( NextIrp, IO_NETWORK_INCREMENT );
	} else {
	    AFD_DbgPrint(MID_TRACE,("Satisfying\n"));
	    Status = SatisfyPacketRecvRequest
		( FCB, NextIrp, DatagramRecv,
		  (PUINT)&NextIrp->IoStatus.Information );
	    AFD_DbgPrint(MID_TRACE,("Unlocking\n"));
	    UnlockBuffers( RecvReq->BufferArray, RecvReq->BufferCount, TRUE );
	    AFD_DbgPrint(MID_TRACE,("Completing\n"));
	    IoCompleteRequest( NextIrp, IO_NETWORK_INCREMENT );
	}
    }

    if( !IsListEmpty( &FCB->DatagramList ) ) {
	AFD_DbgPrint(MID_TRACE,("Signalling\n"));
	FCB->PollState |= AFD_EVENT_RECEIVE;
    } else
	FCB->PollState &= ~AFD_EVENT_RECEIVE;

    PollReeval( FCB->DeviceExt, FCB->FileObject );

    if( NT_SUCCESS(Irp->IoStatus.Status) ) {
	/* Now relaunch the datagram request */
	SocketCalloutEnter( FCB );

	Status = TdiReceiveDatagram
	    ( &FCB->ReceiveIrp.InFlightRequest,
	      FCB->AddressFile.Object,
	      0,
	      FCB->Recv.Window,
	      FCB->Recv.Size,
	      FCB->AddressFrom,
	      &FCB->ReceiveIrp.Iosb,
	      PacketSocketRecvComplete,
	      FCB );

	SocketCalloutLeave( FCB );
    }

    SocketStateUnlock( FCB );

    return STATUS_SUCCESS;
}

NTSTATUS STDCALL
AfdPacketSocketReadData(PDEVICE_OBJECT DeviceObject, PIRP Irp,
			PIO_STACK_LOCATION IrpSp ) {
    NTSTATUS Status = STATUS_SUCCESS;
    PFILE_OBJECT FileObject = IrpSp->FileObject;
    PAFD_FCB FCB = FileObject->FsContext;
    PAFD_RECV_INFO_UDP RecvReq;
    PLIST_ENTRY ListEntry;
    PAFD_STORED_DATAGRAM DatagramRecv;

    AFD_DbgPrint(MID_TRACE,("Called on %x\n", FCB));

    if( !SocketAcquireStateLock( FCB ) ) return LostSocket( Irp, FALSE );

    FCB->EventsFired &= ~AFD_EVENT_RECEIVE;

    /* Check that the socket is bound */
    if( FCB->State != SOCKET_STATE_BOUND )
	return UnlockAndMaybeComplete
	    ( FCB, STATUS_UNSUCCESSFUL, Irp, 0, NULL, FALSE );
    if( !(RecvReq = LockRequest( Irp, IrpSp )) )
	return UnlockAndMaybeComplete
	    ( FCB, STATUS_NO_MEMORY, Irp, 0, NULL, FALSE );

    AFD_DbgPrint(MID_TRACE,("Recv flags %x\n", RecvReq->AfdFlags));

    RecvReq->BufferArray = LockBuffers( RecvReq->BufferArray,
					RecvReq->BufferCount,
					RecvReq->Address,
					RecvReq->AddressLength,
					TRUE, TRUE );

    if( !IsListEmpty( &FCB->DatagramList ) ) {
	ListEntry = RemoveHeadList( &FCB->DatagramList );
	DatagramRecv = CONTAINING_RECORD
	    ( ListEntry, AFD_STORED_DATAGRAM, ListEntry );
	if( DatagramRecv->Len > RecvReq->BufferArray[0].len &&
	    !(RecvReq->TdiFlags & TDI_RECEIVE_PARTIAL) ) {
	    InsertHeadList( &FCB->DatagramList,
			    &DatagramRecv->ListEntry );
	    Status = Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL;
	    Irp->IoStatus.Information = DatagramRecv->Len;

	    if( IsListEmpty( &FCB->DatagramList ) )
		FCB->PollState &= ~AFD_EVENT_RECEIVE;
	    else
		FCB->PollState |= AFD_EVENT_RECEIVE;

	    PollReeval( FCB->DeviceExt, FCB->FileObject );

	    return UnlockAndMaybeComplete
		( FCB, Status, Irp, RecvReq->BufferArray[0].len, NULL, TRUE );
	} else {
	    Status = SatisfyPacketRecvRequest
		( FCB, Irp, DatagramRecv,
		  (PUINT)&Irp->IoStatus.Information );

	    if( IsListEmpty( &FCB->DatagramList ) )
		FCB->PollState &= ~AFD_EVENT_RECEIVE;
	    else
		FCB->PollState |= AFD_EVENT_RECEIVE;

	    PollReeval( FCB->DeviceExt, FCB->FileObject );

	    return UnlockAndMaybeComplete
		( FCB, Status, Irp, Irp->IoStatus.Information, NULL, TRUE );
	}
    } else if( RecvReq->AfdFlags & AFD_IMMEDIATE ) {
	AFD_DbgPrint(MID_TRACE,("Nonblocking\n"));
	Status = STATUS_CANT_WAIT;
	PollReeval( FCB->DeviceExt, FCB->FileObject );
	return UnlockAndMaybeComplete( FCB, Status, Irp, 0, NULL, TRUE );
    } else {
	PollReeval( FCB->DeviceExt, FCB->FileObject );
	return LeaveIrpUntilLater( FCB, Irp, FUNCTION_RECV );
    }
}

⌨️ 快捷键说明

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