Hello All,
Can anyone have idea what could be the issues here.
Hope I explained the prblem here in readable way.
I am facing the following problem in my USB driver.
I have ReadFile() Dispatch routine and a ReadThread as follows.
I store the ReadFile() Irp in the Device Extension(ReadIrp) and
complete it later if no data immediately available in the receive
buffer. Incase of timeout also the Irp is completed.
If I make the deviceExtension->ReadIrp to NULL as in
below functions, my second ReadFile() kills the ReadThread function.
Am I making mistake here Or anything I should take care before doing so?
Any suggestion welcome. Thanks in advane.
NTSTATUS Dispatch_Read(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
{
// Declarations …
// initializing a device extension PIRP to null
deviceExtension->ReadIrp = NULL;
irpStack = IoGetCurrentIrpStackLocation(Irp);
lengthRequested = irpStack->Parameters.Read.Length;
// Do some checks here on the parameters…
// Create s system thread to read data from the rx data queue.
//When receiving first time ReadFile() call, thread is created
if(deviceExtension->ThreadHandle == NULL)
{
// Clear the user read complete event
KeClearEvent(&deviceExtension->UserReadEvent);
if( STATUS_SUCCESS !=
PsCreateSystemThread(
&deviceExtension->ThreadHandle,
(ACCESS_MASK) 0L,
NULL,
NULL,
NULL,
(PKSTART_ROUTINE)ReadThread,
DeviceObject))
{
// Completes the Irp with status as insuficient resources
}
}
// Check data in receive queue and return success if available
// If data available Status and Information filled up in the
// function itself.
ntStatus = PerformReadFromReceiveQueue(DeviceObject, Irp);
if(NT_SUCCESS(ntStatus))
{
// Complete the Irp. Data received. Return STATUS_SUCCESS
}
// Data not available in the queue. Mark Irp pending.
IoSetCancelRoutine(Irp, (PDRIVER_CANCEL)BtUsb_CancelRead);
IoMarkIrpPending(Irp);
// Store the Irp in device extension variable
deviceExtension->ReadIrp = Irp;
ntStatus = STATUS_PENDING;
// used in ReadThread
KeClearEvent(&deviceExtension->UserReadCompleteEvent);
// used in ReadThread
KeSetEvent(&deviceExtension->UserReadEvent, 1, FALSE);
return ntStatus; // returns STATUS_PENDING
}
// ReadThread() Funtion
void ReadThread(PDEVICE_OBJECT DeviceObject)
{
// Declarations …
deviceExtension = DeviceObject->DeviceExtension;
// Thread start
while(1)
{
// Wait for the read event to be signaled. This will be signaled
// when a ReadFile() is issued from the application
ntStatus = KeWaitForSingleObject(
&deviceExtension->UserReadEvent,
Executive,
KernelMode,
FALSE,
NULL);
// Clear the user read compplete event
KeClearEvent(&deviceExtension->UserReadEvent);
// This condition fails during second ReadFile()issue
if(deviceExtension->ReadIrp != NULL)
{
// ReadTimeout set to Xms value. Event will be SET if data
// received in parallel to the receive queue.
// otherwise timesout will cause the event to SET.
ReadTimeout.QuadPart =
((LONG)deviceExtension->ReadTimeout * -10000);
ntStatus = KeWaitForSingleObject(
&deviceExtension->UserReadCompleteEvent,
Executive,
KernelMode,
FALSE,
&ReadTimeout);
// clear the notification event
KeClearEvent(&deviceExtension->UserReadCompleteEvent);
if(deviceExtension->ReadIrp != NULL)
{
if(ntStatus != STATUS_TIMEOUT)
{
// Read data and fills up the status and information field of ReadIrp
ntStatus = PerformReadFromReceiveQueue(DeviceObject,
deviceExtension->ReadIrp);
if(ntStatus != STATUS_SUCCESS)
{
deviceExtension->ReadIrp->IoStatus.Status = STATUS_CANCELLED;
deviceExtension->ReadIrp->IoStatus.Information = 0;
}
}
else
{
deviceExtension->ReadIrp->IoStatus.Status =
STATUS_IO_TIMEOUT;
deviceExtension->ReadIrp->IoStatus.Information = 0;
}
//
IoCompleteRequest(deviceExtension->ReadIrp,
IO_NO_INCREMENT);
// Causes my thread to terminate in second ReadFile()
deviceExtension->ReadIrp = NULL;
}
else
{
break; // to kill the thread if ReadIrp is NULL
}
}
else
{
break; // // to kill the thread if ReadIrp is NULL
}
} // end while()
// Terminate the system thread which was created for reading
PsTerminateSystemThread(STATUS_SUCCESS);
}
Thanks in Advance,
- Palani