Status timeout from umdf virtualserial port

I am working on VirtualSerial at the following link.

https://github.com/microsoft/Windows-driver-samples/tree/master/serial/VirtualSerial

This sample working good as expected with reading & writing through serial port applications.

How can I response STATUS_TIMEOUT to IRP_MJ_READ request when there is no reading data ?

Using standart usb serial port devices response STATUS_TIMEOUT, but virtualserial can not.
I tried following options , but it is not STATUS_TIMEOUT response.

        //
        // No data to read. Queue the request for later processing.
        //
        pSavedRequest->ForwardToIoQueue(pFxReadQueue);
        //pSavedRequest->Complete(E_FAIL);
        //pSavedRequest->Complete(STATUS_TIMEOUT);
        //pSavedRequest->CompleteWithInformation(E_FAIL, STATUS_TIMEOUT);
        //pSavedRequest->CompleteWithInformation(STATUS_TIMEOUT, 0);

I find out WdfTimerCreate function to handle this issue, but i do not know how can fix for virtual serial.

In sampe repository, in Serial device project , there is some code part about creating timers to current read complete as following :

NTSTATUS
SerialCreateTimersAndDpcs(
    IN PSERIAL_DEVICE_EXTENSION pDevExt
    )
/*++

Routine Description:

   This function creates all the timers and DPC objects. All the objects
   are associated with the WDFDEVICE and the callbacks are serialized
   with the device callbacks. Also these objects will be deleted automatically
   when the device is deleted, so there is no need for the driver to explicitly
   delete the objects.

Arguments:

   PDevExt - Pointer to the device extension for the device

Return Value:

    return NTSTATUS

--*/
{
   WDF_DPC_CONFIG dpcConfig;
   WDF_TIMER_CONFIG timerConfig;
   NTSTATUS status;
   WDF_OBJECT_ATTRIBUTES dpcAttributes;
   WDF_OBJECT_ATTRIBUTES timerAttributes;

   //
   // Initialize all the timers used to timeout operations.
   //
   //
   // This timer dpc is fired off if the timer for the total timeout
   // for the read expires.  It will cause the current read to complete.
   //

   WDF_TIMER_CONFIG_INIT(&timerConfig, SerialReadTimeout);

   timerConfig.AutomaticSerialization = TRUE;

   WDF_OBJECT_ATTRIBUTES_INIT(&timerAttributes);
   timerAttributes.ParentObject = pDevExt->WdfDevice;

   status = WdfTimerCreate(&timerConfig,
                           &timerAttributes,
                                    &pDevExt->ReadRequestTotalTimer);

The question confuses me. If you have a request, and you want it to fail with a timeout error, you do pSavedRequest->Complete(STATUS_TIMEOUT); Serial drivers usually have to check their saved settings to see whether they should fail an empty read request immediately, or wait for a timer to expire, but the method of failing the request is the same. The second snipped you showed is for KMDF or UMDF v2; that’s not how you do a timer with UMDF v1.