Esempio n. 1
0
BOOLEAN
TtdiReceive()
{
    USHORT i, Iteration, Increment;
    SHORT j,k;
    HANDLE SvrHandle, SvrConnectionHandle;
    PFILE_OBJECT AddressObject, ConnectionObject;
    PDEVICE_OBJECT DeviceObject;
    NTSTATUS Status;
    PMDL SendMdl, ReceiveMdl;
    IO_STATUS_BLOCK Iosb1;
    TDI_CONNECTION_INFORMATION RequestInformation;
    TDI_CONNECTION_INFORMATION ReturnInformation;
    PTRANSPORT_ADDRESS ListenBlock;
    PTRANSPORT_ADDRESS ConnectBlock;
    PTDI_ADDRESS_NETBIOS temp;
    PUCHAR MessageBuffer;
    ULONG MessageBufferLength;
    ULONG CurrentBufferLength;
    PUCHAR SendBuffer;
    ULONG SendBufferLength;
    PIRP Irp;
    KEVENT Event1;

    Status = KeWaitForSingleObject (&TdiReceiveEvent, Suspended, KernelMode, FALSE, NULL);

    SendBufferLength = (ULONG)BUFFER_SIZE;
    MessageBufferLength = (ULONG)BUFFER_SIZE;


    DbgPrint( "\n****** Start of Receive Test ******\n" );

    XBuff = ExAllocatePool (NonPagedPool, BUFFER_SIZE);
    if (XBuff == (PVOID)NULL) {
        DbgPrint ("Unable to allocate nonpaged pool for send buffer exiting\n");
        return FALSE;
    }
    RBuff = ExAllocatePool (NonPagedPool, BUFFER_SIZE);
    if (RBuff == (PVOID)NULL) {
        DbgPrint ("Unable to allocate nonpaged pool for receive buffer exiting\n");
        return FALSE;
    }

    ListenBlock = ExAllocatePool (NonPagedPool, sizeof (TRANSPORT_ADDRESS) +
                                                sizeof (TDI_ADDRESS_NETBIOS));
    ConnectBlock = ExAllocatePool (NonPagedPool, sizeof (TRANSPORT_ADDRESS) +
                                                sizeof (TDI_ADDRESS_NETBIOS));

    ListenBlock->TAAddressCount = 1;
    ListenBlock->Address[0].AddressType = TDI_ADDRESS_TYPE_NETBIOS;
    ListenBlock->Address[0].AddressLength = sizeof (TDI_ADDRESS_NETBIOS);
    temp = (PTDI_ADDRESS_NETBIOS)ListenBlock->Address[0].Address;

    temp->NetbiosNameType = TDI_ADDRESS_NETBIOS_TYPE_UNIQUE;
    for (i=0;i<16;i++) {
        temp->NetbiosName[i] = ClientName[i];
    }

    ConnectBlock->TAAddressCount = 1;
    ConnectBlock->Address[0].AddressType = TDI_ADDRESS_TYPE_NETBIOS;
    ConnectBlock->Address[0].AddressLength = sizeof (TDI_ADDRESS_NETBIOS);
    temp = (PTDI_ADDRESS_NETBIOS)ConnectBlock->Address[0].Address;

    temp->NetbiosNameType = TDI_ADDRESS_NETBIOS_TYPE_UNIQUE;
    for (i=0;i<16;i++) {
        temp->NetbiosName[i] = ServerName[i];
    }

    //
    // Create an event for the synchronous I/O requests that we'll be issuing.
    //

    KeInitializeEvent (
                &Event1,
                SynchronizationEvent,
                FALSE);

    Status = TtdiOpenAddress (&SvrHandle, ServerName);
    if (!NT_SUCCESS(Status)) {
        DbgPrint( "\n****** Receive Test:  FAILED on open of server Address: %lC ******\n", Status );
        return FALSE;
    }

    Status = ObReferenceObjectByHandle (
                SvrHandle,
                0L,
                NULL,
                KernelMode,
                (PVOID *) &AddressObject,
                NULL);

    if (!NT_SUCCESS(Status)) {
        DbgPrint( "\n****** Receive Test:  FAILED on open of server Address: %lC ******\n", Status );
        return FALSE;
    }

    Status = TtdiOpenConnection (&SvrConnectionHandle, 2);
    if (!NT_SUCCESS(Status)) {
        DbgPrint( "\n****** Receive Test:  FAILED on open of server Connection: %lC ******\n", Status );
        return FALSE;
    }

    Status = ObReferenceObjectByHandle (
                SvrConnectionHandle,
                0L,
                NULL,
                KernelMode,
                (PVOID *) &ConnectionObject,
                NULL);

    if (!NT_SUCCESS(Status)) {
        DbgPrint( "\n****** Receive Test:  FAILED on open of server Connection: %lC ******\n", Status );
        return FALSE;
    }

    //
    // Get a pointer to the stack location for the first driver.  This will be
    // used to pass the original function codes and parameters.
    //

    DeviceObject = IoGetRelatedDeviceObject( ConnectionObject );


    Irp = TdiBuildInternalDeviceControlIrp (
                TDI_ASSOCIATE_ADDRESS,
                DeviceObject,
                ConnectionObject,
                &Event1,
                &Iosb1);

    DbgPrint ("Build Irp %lx, Handle %lx \n",
            Irp, SvrHandle);

    TdiBuildAssociateAddress (
        Irp,
        DeviceObject,
        ConnectionObject,
        TSTRCVCompletion,
        &Event1,
        SvrHandle);
    InitWaitObject (&Event1);

    {
        PULONG Temp=(PULONG)IoGetNextIrpStackLocation (Irp);
        DbgPrint ("Built IrpSp %lx %lx %lx %lx %lx \n", *(Temp++),  *(Temp++),
            *(Temp++), *(Temp++), *(Temp++));
    }

    Status = IoCallDriver (DeviceObject, Irp);

//    IoFreeIrp (Irp);

    if (Status == STATUS_PENDING) {
        Status = KeWaitForSingleObject (&Event1, Suspended, KernelMode, TRUE, NULL);
        if (!NT_SUCCESS(Status)) {
            DbgPrint( "\n****** Receive Test:  FAILED Event1 Wait Associate: %lC ******\n", Status );
            return FALSE;
        }
        if (!NT_SUCCESS(Iosb1.Status)) {
            DbgPrint( "\n****** Receive Test:  FAILED Associate Iosb status: %lC ******\n", Status );
            return FALSE;
        }

    } else {
        if (!NT_SUCCESS (Status)) {
            DbgPrint( "\n****** Receive Test:  AssociateAddress FAILED  Status: %lC ******\n", Status );
            return FALSE;
        } else {
            DbgPrint ("********** Receive Test:  Success AssociateAddress\n");
        }
    }

    RequestInformation.RemoteAddress = ConnectBlock;
    RequestInformation.RemoteAddressLength = sizeof (TRANSPORT_ADDRESS) +
                                            sizeof (TDI_ADDRESS_NETBIOS);

    //
    // Post a TdiListen to the server endpoint.
    //

    KeInitializeEvent (
                &Event1,
                SynchronizationEvent,
                FALSE);

    Irp = TdiBuildInternalDeviceControlIrp (
                TDI_LISTEN,
                DeviceObject,
                ConnectionObject,
                &Event1,
                &Iosb1);

    TdiBuildListen (
        Irp,
        DeviceObject,
        ConnectionObject,
        TSTRCVCompletion,
        &Event1,
        0,
        &RequestInformation,
        &ReturnInformation);
    InitWaitObject (&Event1);

    Status = IoCallDriver (DeviceObject, Irp);

//    IoFreeIrp (Irp);

    if (Status == STATUS_PENDING) {
        Status = KeWaitForSingleObject (&Event1, Suspended, KernelMode, TRUE, NULL);
        if (!NT_SUCCESS(Status)) {
            DbgPrint( "\n****** Receive Test:  FAILED Event1 Wait Listen: %lC ******\n", Status );
            return FALSE;
        }
        if (!NT_SUCCESS(Iosb1.Status)) {
            DbgPrint( "\n****** Receive Test:  FAILED Listen Iosb status: %lC ******\n", Status );
            return FALSE;
        } else {
            DbgPrint ("********** Receive Test:  Success Listen IOSB\n");
        }

    } else {
        if (!NT_SUCCESS (Status)) {
            DbgPrint( "\n****** Receive Test: Listen FAILED  Status: %lC ******\n", Status );
            return FALSE;
        } else {
            DbgPrint ("********** Receive Test:  Success Listen Immediate\n");
        }
    }


    DbgPrint ("\n****** Receive Test: LISTEN just completed! ******\n");

    KeInitializeEvent (
                &Event1,
                SynchronizationEvent,
                FALSE);

    Irp = TdiBuildInternalDeviceControlIrp (
                TDI_ACCEPT,
                DeviceObject,
                ConnectionObject,
                &Event1,
                &Iosb1);

    TdiBuildAccept (Irp, DeviceObject, ConnectionObject, NULL, NULL, &RequestInformation, NULL, 0);
    InitWaitObject (&Event1);

    Status = IoCallDriver (DeviceObject, Irp);

//    IoFreeIrp (Irp);

    if (Status == STATUS_PENDING) {
        Status = KeWaitForSingleObject (&Event1, Suspended, KernelMode, TRUE, NULL);
        if (!NT_SUCCESS(Status)) {
            DbgPrint( "\n****** Receive Test:  FAILED Event1 Wait Accept: %lC ******\n", Status );
            return FALSE;
        }
        if (!NT_SUCCESS(Iosb1.Status)) {
            DbgPrint( "\n****** Receive Test:  FAILED Accept Iosb status: %lC ******\n", Status );
            return FALSE;
        }

    } else {
        if (!NT_SUCCESS (Status)) {
            DbgPrint( "\n****** Receive Test: Accept FAILED  Status: %lC ******\n", Status );
            return FALSE;
        }
    }

    //
    // We have the connection data now.  Sanity check it.
    //

    DbgPrint ("\n****** Receive Test:  LISTEN completed successfully! ******\n");

    //
    // Receive/receive 1 or  10 messages.
    //

    SendBuffer =  (PUCHAR)ExAllocatePool (NonPagedPool, SendBufferLength);
    if (SendBuffer == NULL) {
        DbgPrint ("\n****** Send Test:  ExAllocatePool failed! ******\n");
    }
    SendMdl = IoAllocateMdl (SendBuffer, SendBufferLength, FALSE, FALSE, NULL);
    MmBuildMdlForNonPagedPool (SendMdl);

    MessageBuffer=(PUCHAR)ExAllocatePool (NonPagedPool, MessageBufferLength);
    if (MessageBuffer == NULL) {
        DbgPrint ("\n****** Send Test:  ExAllocatePool failed! ******\n");
    }
    ReceiveMdl = IoAllocateMdl (MessageBuffer, MessageBufferLength, FALSE, FALSE, NULL);
    MmBuildMdlForNonPagedPool (ReceiveMdl);

    //
    // Cycle the buffer length from 0 up through the maximum for Tdi. after a
    // couple of shots at the full range in one byte steps, increment by ever
    // increasing amounts to get to the max.
    //

    CurrentBufferLength = 0;
    Increment = 1;
    for (Iteration=1; Iteration<(USHORT)c9_Iteration; Iteration++) {
        CurrentBufferLength += Increment;
        if (CurrentBufferLength > MessageBufferLength) {
            CurrentBufferLength = 0;
            Increment = 1;
        }
        if (CurrentBufferLength > 7500) {
            Increment++;
        }
        if ((USHORT)((Iteration / 100) * 100) == Iteration) {
            DbgPrint ("Iteration #%d Buffer Length: %lx Buffer Start: %x\n",
                Iteration, CurrentBufferLength,Iteration % 256);
        }
        for (i=0; i<(USHORT)CurrentBufferLength; i++) {
            SendBuffer [i] = (UCHAR)(i + Iteration % 256 );
            MessageBuffer [i] = 0;            // zap this sucker with something.
        }

        KeInitializeEvent (
                    &Event1,
                    SynchronizationEvent,
                    FALSE);

        Irp = TdiBuildInternalDeviceControlIrp (
                    TDI_RECEIVE,
                    DeviceObject,
                    ConnectionObject,
                    &Event1,
                    &Iosb1);

        TdiBuildReceive (Irp,
            DeviceObject,
            ConnectionObject,
            TSTRCVCompletion,
            &Event1,
            ReceiveMdl,
            MessageBufferLength);

        InitWaitObject (&Event1);

        Status = IoCallDriver (DeviceObject, Irp);

//        IoFreeIrp (Irp);

        if (Status == STATUS_PENDING) {
            Status = KeWaitForSingleObject (&Event1, Suspended, KernelMode, TRUE, NULL);
            if (!NT_SUCCESS(Status)) {
                DbgPrint( "\n****** Receive Test:  FAILED Event1 Wait Receive: %lC ******\n", Status );
                return FALSE;
            }
            if (!NT_SUCCESS(Iosb1.Status)) {
                DbgPrint( "\n****** Receive Test:  FAILED Receive Iosb status: %lC ******\n", Status );
                return FALSE;
            }

        } else {
            if (!NT_SUCCESS (Status)) {
                DbgPrint( "\n****** Receive Test: Listen FAILED  Status: %lC ******\n", Status );
                return FALSE;
            }
        }

        //
        // The receive completed.  Make sure the data is correct.
        //

        if (Iosb1.Information != CurrentBufferLength) {
            DbgPrint ("Iteration #%d Buffer Length: %lx Buffer Start: %x\n",
                Iteration, CurrentBufferLength,Iteration % 256);
            DbgPrint ("ReceiveTest: Bytes received <> bytes sent.\n");
            DbgPrint ("ReceiveTest: BytesToSend=%ld.  BytesReceived=%ld.\n",
                      CurrentBufferLength, Iosb1.Information);
        }

        if (i == (USHORT)CurrentBufferLength) {
//                DbgPrint ("ReceiveTest: Message contains correct data.\n");
        } else {
            DbgPrint ("ReceiveTest: Message data corrupted at offset %lx of %lx.\n", (ULONG)i, (ULONG)SendBufferLength);
            DbgPrint ("ReceiveTest: Data around corrupted location:\n");
            for (j=-4;j<=3;j++) {
                DbgPrint ("%08lx  ", (ULONG) i+j*16);
                for (k=(SHORT)i+(j*(SHORT)16);k<(SHORT)i+((j+(SHORT)1)*(SHORT)16);k++) {
                    DbgPrint ("%02x",MessageBuffer [k]);
                }
                for (k=(SHORT)i+(j*(SHORT)16);k<(SHORT)i+((j+(SHORT)1)*(SHORT)16);k++) {
                    DbgPrint ("%c",MessageBuffer [k]);
                }
                DbgPrint ("\n");
            }
            DbgPrint ("ReceiveTest: End of Corrupt Data.\n");
        }
    }

    //
    // We're done with this endpoint.  Close it and get out.
    //

    Status = CloseAddress (SvrHandle);
    if (!NT_SUCCESS(Status)) {
        DbgPrint( "\n****** Receive Test:  FAILED on 1st Close: %lC ******\n", Status );
        return FALSE;
    }

    DbgPrint( "\n****** End of Receive Test ******\n" );
    return TRUE;
} /* Receive */
Esempio n. 2
0
NTSTATUS
TcpTdiAccept(
	IN	PFILE_OBJECT		ControlFileObject,
	IN	PTDI_ADDRESS_IP		Address 
	)
{
	KEVENT						event;
    PDEVICE_OBJECT				deviceObject;
	PIRP						irp;
	IO_STATUS_BLOCK				ioStatusBlock;

	UCHAR						buffer[
										FIELD_OFFSET(TRANSPORT_ADDRESS, Address)
										+ FIELD_OFFSET(TA_ADDRESS, Address)
										+ TDI_ADDRESS_LENGTH_IP
										];

    PTRANSPORT_ADDRESS			serverTransportAddress;
    PTA_ADDRESS					taAddress;
	PTDI_ADDRESS_IP				addressName;

	NTSTATUS					ntStatus;
	TDI_CONNECTION_INFORMATION	connectionInfomation;

    TCPLtDebugPrint (3, ("[TcpTdi] TcpTdiConnect:  Entered\n"));

	//
	// Make Event.
	//
	KeInitializeEvent(&event, NotificationEvent, FALSE);

    deviceObject = IoGetRelatedDeviceObject(ControlFileObject);

	//
	// Make IRP.
	//
	irp = TdiBuildInternalDeviceControlIrp(
			TDI_CONNECT,
			deviceObject,
			connectionFileObject,
			&event,
			&ioStatusBlock
			);

	if(irp == NULL) {
		TCPLtDebugPrint(1, ("[TcpTdi]TdiConnect: Can't Build IRP.\n"));
		return STATUS_INSUFFICIENT_RESOURCES;
	}

	serverTransportAddress = (PTRANSPORT_ADDRESS)buffer;
	serverTransportAddress->TAAddressCount = 1;

    taAddress = (PTA_ADDRESS)serverTransportAddress->Address;
    taAddress->AddressType		= TDI_ADDRESS_TYPE_IP;
    taAddress->AddressLength	= TDI_ADDRESS_LENGTH_IP;

    addressName = (PTDI_ADDRESS_IP)taAddress->Address;

	RtlCopyMemory(
		addressName,
		Address,
		TDI_ADDRESS_LENGTH_IP
		);	

	//
	// Make Connection Info...
	//

	RtlZeroMemory(
		&connectionInfomation,
		sizeof(TDI_CONNECTION_INFORMATION)
		);

	connectionInfomation.UserDataLength = 0;
	connectionInfomation.UserData = NULL;
	connectionInfomation.OptionsLength = 0;
	connectionInfomation.Options = NULL;
	connectionInfomation.RemoteAddress = serverTransportAddress;
	connectionInfomation.RemoteAddressLength = 	FIELD_OFFSET(TRANSPORT_ADDRESS, Address)
													+ FIELD_OFFSET(TA_ADDRESS, Address)
													+ TDI_ADDRESS_LENGTH_IP;



	TdiBuildAccept(
		irp,
		deviceObject,
		ControlFileObject,
		NULL,
		NULL,
		&connectionInfomation,
		NULL
		);

	irp->MdlAddress = NULL;

	ntStatus = TcpTdiIoCallDriver(
				deviceObject,
				irp,
				&ioStatusBlock,
				&event
				);

	if(!NT_SUCCESS(ntStatus)) {
		TCPLtDebugPrint(1, ("[TcpTdi]TdiConnect: Failed.\n"));
	}



	return ntStatus;
} // TcpTdiConnect
Esempio n. 3
0
BOOLEAN
TtdiServer()
{
    USHORT i;
    HANDLE RdrHandle, SrvConnectionHandle;
    KEVENT Event1;
    PFILE_OBJECT AddressObject, ConnectionObject;
    PDEVICE_OBJECT DeviceObject;
    NTSTATUS Status;
    PMDL ReceiveMdl;
    IO_STATUS_BLOCK Iosb1;
    TDI_CONNECTION_INFORMATION RequestInformation;
    TDI_CONNECTION_INFORMATION ReturnInformation;
    PTRANSPORT_ADDRESS ListenBlock;
    PTRANSPORT_ADDRESS ConnectBlock;
    PTDI_ADDRESS_NETBIOS temp;
    PUCHAR MessageBuffer;
    ULONG MessageBufferLength;
    ULONG CurrentBufferLength;
    PIRP Irp;

    Status = KeWaitForSingleObject (&TdiServerEvent, Suspended, KernelMode, FALSE, NULL);

    MessageBufferLength = (ULONG)BUFFER_SIZE;


    DbgPrint( "\n****** Start of Server Test ******\n" );

    RBuff = ExAllocatePool (NonPagedPool, BUFFER_SIZE);
    if (RBuff == (PVOID)NULL) {
        DbgPrint ("Unable to allocate nonpaged pool for receive buffer exiting\n");
        return FALSE;
    }

    ListenBlock = ExAllocatePool (NonPagedPool, sizeof (TRANSPORT_ADDRESS) +
                                                sizeof (TDI_ADDRESS_NETBIOS));
    ConnectBlock = ExAllocatePool (NonPagedPool, sizeof (TRANSPORT_ADDRESS) +
                                                sizeof (TDI_ADDRESS_NETBIOS));

    ListenBlock->TAAddressCount = 1;
    ListenBlock->Address[0].AddressType = TDI_ADDRESS_TYPE_NETBIOS;
    ListenBlock->Address[0].AddressLength = sizeof (TDI_ADDRESS_NETBIOS);
    temp = (PTDI_ADDRESS_NETBIOS)ListenBlock->Address[0].Address;

    temp->NetbiosNameType = TDI_ADDRESS_NETBIOS_TYPE_UNIQUE;
    for (i=0;i<16;i++) {
        temp->NetbiosName[i] = AnyName[i];
    }

    ConnectBlock->TAAddressCount = 1;
    ConnectBlock->Address[0].AddressType = TDI_ADDRESS_TYPE_NETBIOS;
    ConnectBlock->Address[0].AddressLength = sizeof (TDI_ADDRESS_NETBIOS);
    temp = (PTDI_ADDRESS_NETBIOS)ConnectBlock->Address[0].Address;

    temp->NetbiosNameType = TDI_ADDRESS_NETBIOS_TYPE_UNIQUE;
    for (i=0;i<16;i++) {
        temp->NetbiosName[i] = ServerName[i];
    }

    //
    // Create an event for the synchronous I/O requests that we'll be issuing.
    //

    KeInitializeEvent (
                &Event1,
                SynchronizationEvent,
                FALSE);

    Status = TtdiOpenAddress (&RdrHandle, ServerName);
    if (!NT_SUCCESS(Status)) {
        DbgPrint( "\n****** Server Test:  FAILED on open of client: %lC ******\n", Status );
        return FALSE;
    }

    Status = ObReferenceObjectByHandle (
                RdrHandle,
                0L,
                NULL,
                KernelMode,
                (PVOID *) &AddressObject,
                NULL);

    //
    // Now loop forever trying to get a connection from a remote client to
    // this server. We will create connections until we run out of resources,
    // and we will echo the data we are sent back along the same connection.
    // Sends and Receives are always asynchronous, while listens are
    // synchronous.
    //

    while (TRUE) {

        //
        // Open the connection on the transport.
        //

        Status = TtdiOpenConnection (&SrvConnectionHandle, 1);
        if (!NT_SUCCESS(Status)) {
            DbgPrint( "\n****** Server Test:  FAILED on open of server Connection: %lC ******\n", Status );
            return FALSE;
        }

        Status = ObReferenceObjectByHandle (
                    SrvConnectionHandle,
                    0L,
                    NULL,
                    KernelMode,
                    (PVOID *) &ConnectionObject,
                    NULL);

        if (!NT_SUCCESS(Status)) {
            DbgPrint( "\n****** Server Test:  FAILED on open of server Connection: %lC ******\n", Status );
            return FALSE;
        }

        //
        // Get a pointer to the stack location for the first driver.  This will be
        // used to pass the original function codes and parameters.
        //

        DeviceObject = IoGetRelatedDeviceObject( ConnectionObject );

        //
        // Now register the device handler for receives
        //

//        Irp = TdiBuildInternalDeviceControlIrp (
//                    TDI_SET_EVENT_HANDLER,
//                    DeviceObject,
//                    ConnectionObject,
//                    &Event1,
//                    &Iosb1);

//        TdiBuildSetEventHandler (Irp,
//            DeviceObject,
//            ConnectionObject,
//            TSTRCVCompletion,
//            &Event1,
//            TDI_RECEIVE_HANDLER,
//            TdiTestReceiveHandler,
//            ConnectionObject);

//        Status = IoCallDriver (DeviceObject, Irp);

//       if (Status == STATUS_PENDING) {
//            Status = KeWaitForSingleObject (&Event1, Suspended, KernelMode, TRUE, NULL);
//            if (!NT_SUCCESS(Status)) {
//                DbgPrint( "\n****** Server Test:  FAILED Event1 Wait Register: %lC ******\n", Status );
//                return FALSE;
//            }
//            if (!NT_SUCCESS(Iosb1.Status)) {
//                DbgPrint( "\n****** Server Test:  FAILED Register Iosb status: %lC ******\n", Status );
//                return FALSE;
//            }
//
//        } else {
//            if (!NT_SUCCESS (Status)) {
//                DbgPrint( "\n****** Server Test:  RegisterHandler FAILED  Status: %lC ******\n", Status );
//                return FALSE;
//            }
//        }

        Irp = TdiBuildInternalDeviceControlIrp (
                    TDI_ASSOCIATE_ADDRESS,
                    DeviceObject,
                    ConnectionObject,
                    &Event1,
                    &Iosb1);

        TdiBuildAssociateAddress (Irp,
            DeviceObject,
            ConnectionObject,
            TSTRCVCompletion,
            &Event1,
            RdrHandle);

        Status = IoCallDriver (DeviceObject, Irp);

    //    IoFreeIrp (Irp);

        if (Status == STATUS_PENDING) {
            Status = KeWaitForSingleObject (&Event1, Suspended, KernelMode, TRUE, NULL);
            if (!NT_SUCCESS(Status)) {
                DbgPrint( "\n****** Server Test:  FAILED Event1 Wait Associate: %lC ******\n", Status );
                return FALSE;
            }
            if (!NT_SUCCESS(Iosb1.Status)) {
                DbgPrint( "\n****** Server Test:  FAILED Associate Iosb status: %lC ******\n", Status );
                return FALSE;
            }

        } else {
            if (!NT_SUCCESS (Status)) {
                DbgPrint( "\n****** Server Test:  AssociateAddress FAILED  Status: %lC ******\n", Status );
                return FALSE;
            }
        }

        //
        // Post a TdiListen to the server endpoint.
        //

        RequestInformation.RemoteAddress = ListenBlock;
        RequestInformation.RemoteAddressLength = sizeof (TRANSPORT_ADDRESS) +
                                                sizeof (TDI_ADDRESS_NETBIOS);

        KeInitializeEvent (
                    &Event1,
                    SynchronizationEvent,
                    FALSE);

        Irp = TdiBuildInternalDeviceControlIrp (
                    TDI_LISTEN,
                    DeviceObject,
                    ConnectionObject,
                    &Event1,
                    &Iosb1);

        TdiBuildListen (
            Irp,
            DeviceObject,
            ConnectionObject,
            TSTRCVCompletion,
            &Event1,
            0,
            &RequestInformation,
            NULL);

        Status = IoCallDriver (DeviceObject, Irp);

        if (Status == STATUS_PENDING) {
            Status = KeWaitForSingleObject (&Event1, Suspended, KernelMode, TRUE, NULL);
            if (!NT_SUCCESS(Status)) {
                DbgPrint( "\n****** Server Test:  FAILED Event1 Wait Listen: %lC ******\n", Status );
                return FALSE;
            }
            if (!NT_SUCCESS(Iosb1.Status)) {
                DbgPrint( "\n****** Server Test:  FAILED Listen Iosb status: %lC ******\n", Status );
                return FALSE;
            }

        } else {
            if (!NT_SUCCESS (Status)) {
                DbgPrint( "\n****** Server Test: Listen FAILED  Status: %lC ******\n", Status );
                return FALSE;
            }
        }

        DbgPrint ("\n****** Server Test: LISTEN just completed! ******\n");

        //
        // accept the connection from the remote
        //

        KeInitializeEvent (
                    &Event1,
                    SynchronizationEvent,
                    FALSE);

        Irp = TdiBuildInternalDeviceControlIrp (
                    TDI_ACCEPT,
                    DeviceObject,
                    ConnectionObject,
                    &Event1,
                    &Iosb1);

        TdiBuildAccept (
            Irp,
            DeviceObject,
            ConnectionObject,
            NULL,
            NULL,
            &RequestInformation,
            NULL,
            0);

        Status = IoCallDriver (DeviceObject, Irp);

    //    IoFreeIrp (Irp);

        if (Status == STATUS_PENDING) {
            Status = KeWaitForSingleObject (&Event1, Suspended, KernelMode, TRUE, NULL);
            if (!NT_SUCCESS(Status)) {
                DbgPrint( "\n****** Receive Test:  FAILED Event1 Wait Accept: %lC ******\n", Status );
                return FALSE;
            }
            if (!NT_SUCCESS(Iosb1.Status)) {
                DbgPrint( "\n****** Receive Test:  FAILED Accept Iosb status: %lC ******\n", Status );
                return FALSE;
            }

        } else {
            if (!NT_SUCCESS (Status)) {
                DbgPrint( "\n****** Accept Test: Listen FAILED  Status: %lC ******\n", Status );
                return FALSE;
            }
        }

        //
        // Get a buffer for the continued read/write loop.
        //

        MessageBuffer=(PUCHAR)ExAllocatePool (NonPagedPool, MessageBufferLength);
        if (MessageBuffer == NULL) {
            DbgPrint ("\n****** Send Test:  ExAllocatePool failed! ******\n");
        }
        ReceiveMdl = IoAllocateMdl (MessageBuffer, MessageBufferLength, FALSE, FALSE, NULL);
        MmBuildMdlForNonPagedPool (ReceiveMdl);

        //
        // have a receive buffer, and a connection; go ahead and read and write
        // until the remote disconnects.
        //

        while (TRUE) {

            KeInitializeEvent (
                        &Event1,
                        SynchronizationEvent,
                        FALSE);

            Irp = TdiBuildInternalDeviceControlIrp (
                        TDI_RECEIVE,
                        DeviceObject,
                        ConnectionObject,
                        &Event1,
                        &Iosb1);

            TdiBuildReceive (Irp,
                DeviceObject,
                ConnectionObject,
                TSTRCVCompletion,
                &Event1,
                ReceiveMdl,
                MessageBufferLength);

            InitWaitObject (&Event1);

            Status = IoCallDriver (DeviceObject, Irp);

            if (Status == STATUS_PENDING) {
                Status = KeWaitForSingleObject (&Event1, Suspended, KernelMode, TRUE, NULL);
                if (!NT_SUCCESS(Status)) {
                    DbgPrint( "\n****** Receive Test:  FAILED Event1 Wait Receive: %lC ******\n", Status );
                    return FALSE;
                }
                if (!NT_SUCCESS(Iosb1.Status)) {
                    DbgPrint( "\n****** Receive Test:  FAILED Receive Iosb status: %lC ******\n", Status );
                    return FALSE;
                }

            } else {
                if (!NT_SUCCESS (Status)) {

                    //
                    // Check to see if the remote has disconnected, which is
                    // the only reason for us shutting down/
                    //

                    if (Status == STATUS_REMOTE_DISCONNECT) {

                        //
                        // We've been disconnected from; get out
                        //

                        NtClose (SrvConnectionHandle);
                        break;
                    }

                    DbgPrint( "\n****** Receive Test: Listen FAILED  Status: %lC ******\n", Status );
                    return FALSE;
                } else {

                    //
                    // successful return, what length is the data?
                    //

                    CurrentBufferLength = Iosb1.Information;
                }
            }

            //
            // send the data back
            //

            KeInitializeEvent (
                        &Event1,
                        SynchronizationEvent,
                        FALSE);

            Irp = TdiBuildInternalDeviceControlIrp (
                        TDI_SEND,
                        DeviceObject,
                        ConnectionObject,
                        &Event1,
                        &Iosb1);

            TdiBuildSend (Irp,
                DeviceObject,
                ConnectionObject,
                TSTRCVCompletion,
                &Event1,
                ReceiveMdl,
                0,
                CurrentBufferLength);

            Status = IoCallDriver (DeviceObject, Irp);

            if (Status == STATUS_PENDING) {
                Status = KeWaitForSingleObject (&Event1, Suspended, KernelMode, TRUE, NULL);
                if (!NT_SUCCESS(Status)) {
                    DbgPrint( "\n****** Receive Test:  FAILED Event1 Wait Send: %lC ******\n", Status );
                    return FALSE;
                }
                if (!NT_SUCCESS(Iosb1.Status)) {
                    DbgPrint( "\n****** Receive Test:  FAILED Send Iosb status: %lC ******\n", Status );
                    return FALSE;
                }

            } else {
                if (!NT_SUCCESS (Status)) {

                    DbgPrint( "\n****** Receive Test: Send FAILED  Status: %lC ******\n", Status );
                    NtClose (SrvConnectionHandle);
                    break;

                }
            }
        } // end of receive/send while

        IoFreeMdl (ReceiveMdl);
        ExFreePool (MessageBuffer);

    }

    //
    // We're done with this address.  Close it and get out.
    //

    Status = CloseAddress (RdrHandle);
    if (!NT_SUCCESS(Status)) {
        DbgPrint( "\n****** Send Test:  FAILED on 2nd Close: %lC ******\n", Status );
        return FALSE;
    }

    DbgPrint( "\n****** End of Send Test ******\n" );
    return TRUE;
} /* Server */
Esempio n. 4
0
NTSTATUS 
KTdiStreamSocket::ConnectEventHandler(
       IN LONG RemoteAddressLength,
       IN PTA_IP_ADDRESS RemoteAddress,
       IN LONG UserDataLength,
       IN PVOID UserData,
       IN LONG OptionsLength,
       IN PVOID Options,
       OUT CONNECTION_CONTEXT* ConnectionContext,
       OUT PIRP *AcceptIrp
      )
{
  PTDI_CONNECTION_INFORMATION  pReturnConnectionInfo;
  NTSTATUS                     NtStatus = STATUS_CONNECTION_REFUSED;
  USHORT                       nRemotePort;
  ULONG                        nRemoteAddress;
  PDEVICE_OBJECT               pDeviceObject;
  PTA_IP_ADDRESS               pReturnAddress;
  PIRP                         pIrp = NULL;
  PTA_IP_ADDRESS               pRequestAddress;
  PTDI_ADDRESS_IP              pIp;

  *ConnectionContext = (CONNECTION_CONTEXT)NULL;
  *AcceptIrp = NULL;

  if (m_bConnected == TRUE)
  {
    return NtStatus;
  }

  if (
         RemoteAddressLength >= sizeof(TA_IP_ADDRESS)
      && RemoteAddress != NULL
      && RemoteAddress->Address[0].AddressType == TDI_ADDRESS_TYPE_IP
     )
  {
    nRemotePort = W_BIG_TO_LITTLE_ENDIAN(RemoteAddress->Address[0].Address[0].sin_port);
    nRemoteAddress = D_BIG_TO_LITTLE_ENDIAN(RemoteAddress->Address[0].Address[0].in_addr);

    DbgPrint ("ConnectEventHandler: %08x : %04x !!!\n", nRemoteAddress, nRemotePort);
    
    
    NtStatus = STATUS_MORE_PROCESSING_REQUIRED;
    if (m_nRemoteAddress != NULL)
    {
      if (m_nRemoteAddress != nRemoteAddress || m_nRemotePort != nRemotePort)
      {
        NtStatus = STATUS_CONNECTION_REFUSED;
      }
    }

    if (NtStatus == STATUS_MORE_PROCESSING_REQUIRED)
    {
      NtStatus = STATUS_INSUFFICIENT_RESOURCES;
      
      m_pRequestListenInfo = (PTDI_CONNECTION_INFORMATION) new char[2*sizeof(TDI_CONNECTION_INFORMATION) + 2*sizeof(TA_IP_ADDRESS) + sizeof(ULONG)];
      if (m_pRequestListenInfo != NULL)
      {
        memset(m_pRequestListenInfo, 0, sizeof(TDI_CONNECTION_INFORMATION) + sizeof(TA_IP_ADDRESS) + sizeof(ULONG));

        m_pReturnListenInfo = (PTDI_CONNECTION_INFORMATION)((PUCHAR)m_pRequestListenInfo + sizeof(TDI_CONNECTION_INFORMATION) + sizeof(TA_IP_ADDRESS));
        m_pReturnListenInfo->RemoteAddressLength = sizeof(TA_IP_ADDRESS);
        m_pReturnListenInfo->RemoteAddress = (PUCHAR)m_pRequestListenInfo + sizeof(TDI_CONNECTION_INFORMATION);

        pReturnAddress = (PTA_IP_ADDRESS)(m_pReturnListenInfo->RemoteAddress);
        pReturnAddress->TAAddressCount = 1;
        pReturnAddress->Address[0].AddressLength = sizeof(TDI_ADDRESS_IP);
        pReturnAddress->Address[0].AddressType = TDI_ADDRESS_TYPE_IP;
        
        if (m_nRemoteAddress != 0)
        {
          m_pRequestListenInfo->RemoteAddressLength = sizeof(TA_IP_ADDRESS);
          m_pRequestListenInfo->RemoteAddress = (PUCHAR)m_pRequestListenInfo + sizeof(TDI_CONNECTION_INFORMATION);

          pRequestAddress = (PTA_IP_ADDRESS)(m_pRequestListenInfo->RemoteAddress);
          pRequestAddress->TAAddressCount = 1;
          pRequestAddress->Address[0].AddressLength = sizeof(TDI_ADDRESS_IP);
          pRequestAddress->Address[0].AddressType = TDI_ADDRESS_TYPE_IP;
        
          pIp = (PTDI_ADDRESS_IP)(pRequestAddress->Address[0].Address);
          pIp->sin_port = W_LITTLE_TO_BIG_ENDIAN(m_nRemotePort);
          pIp->in_addr = D_LITTLE_TO_BIG_ENDIAN(m_nRemoteAddress);;
        }
        else
        {
          m_pRequestListenInfo->RemoteAddressLength = 0;
          m_pRequestListenInfo->RemoteAddress = NULL;
        }

        memset(&m_ListenStatusBlock, 0, sizeof(IO_STATUS_BLOCK));

        pDeviceObject = IoGetRelatedDeviceObject(m_pTdiConnectionObject);

        pIrp = TdiBuildInternalDeviceControlIrp(
                      TDI_ACCEPT, 
                      pDeviceObject, 
                      m_pTdiConnectionObject,
                      &m_kListenEvent, 
                      &m_ListenStatusBlock);
        if (pIrp != NULL)
        {
          TdiBuildAccept(
                 pIrp, 
                 pDeviceObject, 
                 m_pTdiConnectionObject,
                 AcceptCompletion, 
                 (PVOID)this,
                 m_pRequestListenInfo,
                 m_pReturnListenInfo);

          *ConnectionContext = (CONNECTION_CONTEXT)this;
          *AcceptIrp = pIrp;
          
          IoSetNextIrpStackLocation(pIrp);

          //InterlockedIncrement(&m_dwTreatAcceptIrpsCount);
          ++m_TreatAcceptIrpsCount;
          
          DbgPrint ("ConnectEventHandler: OK!!!\n");

          NtStatus = STATUS_MORE_PROCESSING_REQUIRED;
        }
      }
    }
    
  }

  return NtStatus;
}