Failure to receive data TDI connection endpoint. Please help

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

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.