Failure to receive data TDI connection endpoint. Please help

Home Forums Discussions General Discussion Failure to receive data TDI connection endpoint. Please help

This topic contains 3 replies, has 2 voices, and was last updated by  Taras 13 years, 2 months ago.

Viewing 4 posts - 1 through 4 (of 4 total)
  • Author
    Posts
  • #4878

    rvd
    Participant

    Dear experts,

    I seem to be getting a STATUS_INVALID_DEVICE_STATE (status = 0xC00000184) whenever I try to receive data from connection enpoint. My code follow:

    NTSTATUS Recv(PFILE_OBJECT FileObject, PVOID Data,
    ULONG Length)
    {
    NTSTATUS status;
    PIRP Irp;
    PDEVICE_OBJECT DeviceObject;
    PMDL Mdl;
    KEVENT Event;
    IO_STATUS_BLOCK IoStatus;

    ASSERT( KeGetCurrentIrql() == PASSIVE_LEVEL );
    KeInitializeEvent(&Event, NotificationEvent,FALSE);

    DeviceObject = IoGetRelatedDeviceObject(FileObject);

    Irp = TdiBuildInternalDeviceControlIrp(TDI_RECEIVE,
    DeviceObject,
    FileObject,
    &Event, &IoStatus);

    if (Irp == NULL)
    {
    VLSDLogS(“VLSD: Receiving data fail because of insufficient MDL resources.”);
    DbgPrint(“VLSD: Receiving data fail because of insufficient MDL resources.n”);
    return STATUS_INSUFFICIENT_RESOURCES;
    }

    Mdl = IoAllocateMdl(Data, Length, FALSE, FALSE, Irp);
    if (Mdl == NULL)
    {
    VLSDLogS(“VLSD: Receiving data fail because of insufficient MDL resources.”);
    DbgPrint(“VLSD: Receiving data fail because of insufficient MDL resources.n”);
    IoFreeIrp(Irp);
    return STATUS_INSUFFICIENT_RESOURCES;
    }

    //MmProbeAndLockPages(Mdl, KernelMode, IoModifyAccess);
    __try{
    MmProbeAndLockPages ( Mdl, KernelMode, IoModifyAccess );
    } __except ( EXCEPTION_EXECUTE_HANDLER ) {
    DbgPrint ( “VLSD: Exception at MmProbeAndLockPagesn” );
    IoFreeMdl( Mdl );
    Mdl = NULL;
    return STATUS_INSUFFICIENT_RESOURCES;
    }

    TdiBuildReceive(Irp, DeviceObject, FileObject, 0, 0, Mdl, TDI_RECEIVE_NORMAL, Length);

    status = IoCallDriver(DeviceObject, Irp); // Error happend here
    if (status == STATUS_PENDING)
    {
    VLSDLogS(“VLSD: Wait a moment for receiving all data.”);
    DbgPrint(“VLSD: Wait a moment for receiving all data.n”);

    ASSERT( KeGetCurrentIrql() == PASSIVE_LEVEL );
    status = KeWaitForSingleObject(&Event, UserRequest,
    KernelMode, FALSE, 0);
    if(!NT_SUCCESS(status))
    {
    VLSDLogSL(“VLSD: Cannot wait, time out or error 0x.”, status);
    DbgPrint(“VLSD: Cannot wait, time out or error.n”);
    }
    }

    MmUnlockPages(Mdl);
    //IoFreeIrp(Irp);

    DbgPrint(“VLSD: Status = %lx, IoStatus.Status = %lx, IoStatus.Information = %ld.n”,
    status, IoStatus.Status, IoStatus.Information);

    return status == STATUS_SUCCESS ? IoStatus.Status : status;
    }

    NTSTATUS EventReceive(PVOID eventContext,
    CONNECTION_CONTEXT connectionContext,
    ULONG Flags,
    ULONG Indicated,
    ULONG Available,
    PULONG Taken,
    PVOID tsduBuff,
    PIRP *Irp)
    {
    DbgPrint(“VLSD: Receive Flags = %lx, ReceiveFlags = %ld, BytesAvailable = %ld.n”,
    Flags, Indicated, Available);

    *Taken = Available; *Irp = 0;

    return STATUS_SUCCESS;
    }

    And server send out 2048 bytes in two times (1024 bytes/time). EventReceive debug print out:
    ReceiveFlags = 0xe20, BytesIndicated = 1024, BytesAvailable = 1024.
    ReceiveFlags = 0xe20, BytesIndicated = 1024, BytesAvailable = 1024.

    And debug print out:
    Status = 0xC00000184
    IoStatus.Status = 0x2e0064
    IoStatus.Information = 7274604

    Anyone can help me?

    Thanks in adv, VL

    #5633

    Taras
    Participant

    I think problem is your routine Recv does nit work at all
    KeWaitForSingleObject(&Event, UserRequest,
    KernelMode, FALSE, 0); dont wait (timeout == 0!!!!), your check
    if(!NT_SUCCESS(status)) dont work
    see declaration:
    #define NT_SUCCESS(Status) ((NTSTATUS)(Status) >= 0)
    and
    STATUS_TIMEOUT ((DWORD )0x00000102L)
    that is your IRP was not handled

    Your debug out is content of uninitialized IoStatus struct and may be different.

    Solve problem:
    Your Recv never will work because you have registerd your Receive Event Handler. You should replace your code from Recv to EventReceive. But you should note, that EventReceive works at IRQL = DISPATCH_LEVEL

    #5634

    rvd
    Participant

    Thanks so much Taras. I have got your idea, my Recv function is called whenever other virtual disk driver need (tdi driver is export driver), not follow receiving event. So I disable the EventReceive function and driver work fine. And now I would like to ask you for clearly about it. I don’t know why after call set event handle for EventReceive function, the Recv function don’t work. Thanks again for you help.

    VL.

    #5635

    Taras
    Participant

    When tcpip.sys has received data it call Receive Handler for endpoint (if it has set). If your driver regsiter such handler, th must retrieve data (it should setup IRP for last parameter of the handler). If your driver is not interested in the incoming data, it set this irp = 0. Tcpip after seeing this irp = 0 thinks client dont need this data and dont take any action for saving data. So, exsiting client with registered ReceiveHandler which always return irp = 0 way to loose all incoming data for endpoint.

Viewing 4 posts - 1 through 4 (of 4 total)

You must be logged in to reply to this topic.