///////////////////////////////////////////////////////////////////////////////////////////////////
// BoardDevice::Read
// Dispatch routine for IRP_MJ_READ requests.
//
// Arguments:
// IN I
// the read IRP
//
// Return Value:
// NTSTATUS
//
NTSTATUS BoardDevice::Read(KIrp I)
{
T.Trace(TraceInfo, __FUNCTION__"++. IRP %p\n", I);
NTSTATUS status = STATUS_SUCCESS;
// TODO: Validate the parameters of the IRP. Replace "FALSE"
// in the following line with error checking code that
// evaulates to TRUE if the request is not valid.
if (FALSE)
{
status = STATUS_INVALID_PARAMETER;
I.Information() = 0;
I.PnpComplete(status);
T.Trace(TraceWarning, __FUNCTION__"--. IRP %p, STATUS %x\n", I, status);
return status;
}
// Always ok to read 0 elements
if (I.ReadSize() == 0)
{
ULONG dwTotalSize = I.ReadSize(CURRENT); // Requested read size
ULONG dwMaxSize = Endpoint2IN.MaximumTransferSize();
T.Trace(TraceInfo, __FUNCTION__" READ: Requested=%d MaxSize=%d\n", dwTotalSize, dwMaxSize);
I.Information() = 0;
I.PnpComplete(this, status);
T.Trace(TraceInfo, __FUNCTION__"--. IRP %p, STATUS %x\n", I, status);
return status;
}
// Get a pointer to the caller's buffer.
PUCHAR pBuffer = (PUCHAR) I.BufferedReadDest();
ULONG bytesRead = 0;
// TODO: At this point, perform any processing for IRP_MJ_READ
// To satisfy the read now, transfer data from the driver
// to the caller's buffer at "pBuffer". Then, indicate
// how much data was transferred:
/*****************************************************/
ULONG dwTotalSize = I.ReadSize(CURRENT); // Requested read size
ULONG dwMaxSize = Endpoint2IN.MaximumTransferSize();
T.Trace(TraceInfo, __FUNCTION__" READ: Requested=%d MaxSize=%d\n", dwTotalSize, dwMaxSize);
if (dwTotalSize > dwMaxSize)
{
dwTotalSize = dwMaxSize;
}
for (int i=0; i<8; i++)
((PCHAR)(pBuffer))[i] = (CHAR)(7-i);
PURB pUrb = Endpoint2IN.BuildBulkTransfer(
pBuffer, // Where is data coming from?
dwTotalSize, // How much data to read?
TRUE, // TRUE = IN
NULL,
FALSE, // Short
NULL
);
if (pUrb == NULL)
{
I.Information() = 0;
T.Trace(TraceInfo, __FUNCTION__" ERROR: BuildInterrupt\n");
return I.PnpComplete(this, STATUS_INSUFFICIENT_RESOURCES);
}
T.Trace(TraceInfo, __FUNCTION__" BuildBulkTransfer passed successfully\n");
// Submit the URB to our USB device, synchronously - say less is OK
pUrb->UrbBulkOrInterruptTransfer.TransferFlags =
(USBD_TRANSFER_DIRECTION_IN | USBD_SHORT_TRANSFER_OK);
if (!Endpoint2IN.IsOpen())
{
I.Information() = 0;
T.Trace(TraceInfo, __FUNCTION__" ERROR: m_Endpoint2IN is not open!\n");
return I.PnpComplete(this, STATUS_INSUFFICIENT_RESOURCES);
}
T.Trace(TraceInfo, __FUNCTION__" Before SubmitUrb\n");
status = Endpoint2IN.SubmitUrb(pUrb);
T.Trace(TraceInfo, __FUNCTION__" After SubmitUrb\n");
bytesRead = pUrb->UrbBulkOrInterruptTransfer.TransferBufferLength;
if ( status == STATUS_SUCCESS)
{
T.Trace(TraceInfo, __FUNCTION__" Read SUCCESS %d bytes\n", bytesRead);
}
else
{
T.Trace(TraceInfo, __FUNCTION__" ERROR: SubmitUrb (%d) error code=%X\n", bytesRead, status);
}
for (i=0; i<8; i++)
{
T.Trace(TraceInfo, __FUNCTION__" %d\n",((PCHAR)(pBuffer))[i]);
}
delete pUrb;
/*****************************************************/
I.Information() = bytesRead;
I.PnpComplete(this, status);
T.Trace(TraceInfo, __FUNCTION__"--. IRP %p, STATUS %x\n", I, status);
return status;
}