📄 d12_driverdevice.cpp
字号:
// Comments:
//
NTSTATUS D12_DriverDevice::Close(KIrp I)
{
NTSTATUS status;
t << "Entering D12_DriverDevice::Close, " << I << EOL;
// TODO: Add driver specific close handling code here
// Generally a close IRP is targeted at our FDO, so we don't need
// to pass it down to the PDO. We have found for some devices, the
// PDO is not expecting this Irp and returns an error code.
// The default wizard code, therefore completes the Irp here using
// PnpComplete(). The following commented code could be used instead
// of PnpComplete() to pass the Irp to the PDO, which would complete it.
//
// I.ForceReuseOfCurrentStackLocationInCalldown();
// status = m_Lower.PnpCall(this, I);
status = I.PnpComplete(this, STATUS_SUCCESS, IO_NO_INCREMENT);
t << "D12_DriverDevice::Close Status " << (ULONG)status << EOL;
return status;
}
////////////////////////////////////////////////////////////////////////
// D12_DriverDevice::Cleanup
//
// Routine Description:
// Handler for IRP_MJ_CLEANUP
//
// Parameters:
// I - Current IRP
//
// Return Value:
// NTSTATUS - Result code
//
// Comments:
//
NTSTATUS D12_DriverDevice::CleanUp(KIrp I)
{
t << "Entering CleanUp, " << I << EOL;
// TODO: Insert your code to respond to the CLEANUP message.
return I.PnpComplete(this, STATUS_SUCCESS);
}
////////////////////////////////////////////////////////////////////////
// D12_DriverDevice::DeviceControl
//
// Routine Description:
// Handler for IRP_MJ_DEVICE_CONTROL
//
// Parameters:
// I - Current IRP
//
// Return Value:
// None
//
// Comments:
// This routine is the first handler for Device Control requests.
// The KPnpDevice class handles restricting IRP flow
// if the device is stopping or being removed.
//
NTSTATUS D12_DriverDevice::DeviceControl(KIrp I)
{
NTSTATUS status;
t << "Entering D12_DriverDevice::Device Control, " << I << EOL;
switch (I.IoctlCode())
{
case D12_DRIVER_READ:
status = D12_DRIVER_READ_Handler(I);
break;
case D12_DRIVER_WRITE:
status = D12_DRIVER_WRITE_Handler(I);
break;
case D12_DRIVER_BULK_IN:
status = D12_DRIVER_BULK_IN_Handler(I);
break;
case D12_DRIVER_BULK_OUT:
status = D12_DRIVER_BULK_OUT_Handler(I);
break;
case D12_DRIVER_VENDOR_REQUEST:
status = D12_DRIVER_VENDOR_REQUEST_Handler(I);
break;
default:
// Unrecognized IOCTL request
status = STATUS_INVALID_PARAMETER;
break;
}
// If the IRP's IOCTL handler deferred processing using some driver
// specific scheme, the status variable is set to STATUS_PENDING.
// In this case we simply return that status, and the IRP will be
// completed later. Otherwise, complete the IRP using the status
// returned by the IOCTL handler.
if (status == STATUS_PENDING)
{
return status;
}
else
{
return I.PnpComplete(this, status);
}
}
////////////////////////////////////////////////////////////////////////
// D12_DriverDevice::D12_DRIVER_READ_Handler
//
// Routine Description:
// Handler for IO Control Code D12_DRIVER_READ
//
// Parameters:
// I - IRP containing IOCTL request
//
// Return Value:
// NTSTATUS - Status code indicating success or failure
//
// Comments:
// This routine implements the D12_DRIVER_READ function.
// This routine runs at passive level.
//
NTSTATUS D12_DriverDevice::D12_DRIVER_READ_Handler(KIrp I)
{
PURB pUrb;
NTSTATUS status;
t << "Entering D12_DriverDevice::D12_DRIVER_READ_Handler, " << I << EOL;
// TODO: Verify that the input parameters are correct
// If not, return STATUS_INVALID_PARAMETER
// TODO: Handle the the D12_DRIVER_READ request, or
// defer the processing of the IRP (i.e. by queuing) and set
// status to STATUS_PENDING.
// TODO: Assuming that the request was handled here. Set I.Information
// to indicate how much data to copy back to the user.
// Always ok to read 0 elements.
if (I.IoctlOutputBufferSize() == 0)
{
I.Information() = 0;
return I.PnpComplete(this, STATUS_SUCCESS);
}
// Declare a memory object
ULONG dwTotalSize = I.IoctlInputBufferSize(CURRENT);
ULONG dwMaxSize = m_Endpoint2In.MaximumTransferSize();
// If the total requested read size is greater than the Maximum Transfer
// Size for the Pipe, request to read only the Maximum Transfer Size since
// the bus driver will fail an URB with a TransferBufferLength of greater
// than the Maximum Transfer Size.
if (dwTotalSize > dwMaxSize)
{
ASSERT(dwMaxSize);
dwTotalSize = dwMaxSize;
}
ULONG dwBytesRead = 0;
pUrb = m_Endpoint1In.BuildInterruptTransfer(
(unsigned char *)I.IoctlBuffer(), // transfer buffer
I.IoctlInputBufferSize(), // transfer buffer size
TRUE, // Short Ok
NULL, // link urb
NULL // new urb
);
if ( pUrb != NULL)
{
// Submit the URB to our USB device, synchronously - say less is OK
// pUrb->UrbBulkOrInterruptTransfer.TransferFlags =
// (USBD_TRANSFER_DIRECTION_IN | USBD_SHORT_TRANSFER_OK);
status = m_Endpoint1In.SubmitUrb(pUrb, NULL, NULL,300);
if ( NT_SUCCESS(status) )
{
dwBytesRead = pUrb->UrbBulkOrInterruptTransfer.TransferBufferLength;
if (dwBytesRead > 0)
t << "Read got " << dwTotalSize << " bytes from USB\n";
}
delete pUrb;
}
else
{
status=STATUS_INSUFFICIENT_RESOURCES;
}
I.Information() = dwBytesRead;
return status;
}
////////////////////////////////////////////////////////////////////////
// D12_DriverDevice::D12_DRIVER_WRITE_Handler
//
// Routine Description:
// Handler for IO Control Code D12_DRIVER_WRITE
//
// Parameters:
// I - IRP containing IOCTL request
//
// Return Value:
// NTSTATUS - Status code indicating success or failure
//
// Comments:
// This routine implements the D12_DRIVER_WRITE function.
// This routine runs at passive level.
//
NTSTATUS D12_DriverDevice::D12_DRIVER_WRITE_Handler(KIrp I)
{
PURB pUrb;
NTSTATUS status;
t << "Entering D12_DriverDevice::D12_DRIVER_WRITE_Handler, " << I << EOL;
// TODO: Verify that the input parameters are correct
// If not, return STATUS_INVALID_PARAMETER
// TODO: Handle the the D12_DRIVER_WRITE request, or
// defer the processing of the IRP (i.e. by queuing) and set
// status to STATUS_PENDING.
// TODO: Assuming that the request was handled here. Set I.Information
// to indicate how much data to copy back to the user.
if (I.IoctlOutputBufferSize() == 0)
{
I.Information() = 0;
return I.PnpComplete(this, STATUS_SUCCESS);
}
// Declare a memory object
ULONG dwTotalSize = I.IoctlOutputBufferSize(CURRENT);
ULONG dwMaxSize = m_Endpoint2In.MaximumTransferSize();
// If the total requested read size is greater than the Maximum Transfer
// Size for the Pipe, request to read only the Maximum Transfer Size since
// the bus driver will fail an URB with a TransferBufferLength of greater
// than the Maximum Transfer Size.
if (dwTotalSize > dwMaxSize)
{
ASSERT(dwMaxSize);
dwTotalSize = dwMaxSize;
}
ULONG dwBytesRead = 0;
pUrb = m_Endpoint1Out.BuildInterruptTransfer(
(unsigned char *)I.IoctlBuffer(), // transfer buffer
I.IoctlOutputBufferSize(), // transfer buffer size
TRUE, // Short Ok
NULL, // link urb
NULL // new urb
);
if ( pUrb != NULL)
{
// Submit the URB to our USB device, synchronously - say less is OK
status = m_Endpoint1Out.SubmitUrb(pUrb, NULL, NULL);
if ( NT_SUCCESS(status) )
{
dwBytesRead = pUrb->UrbBulkOrInterruptTransfer.TransferBufferLength;
if (dwBytesRead > 0)
t << "Write got " << dwTotalSize << " bytes from USB\n";
}
delete pUrb;
}
else
{
status=STATUS_INSUFFICIENT_RESOURCES;
}
I.Information() = dwBytesRead;
return status;
}
VOID D12_DriverDevice::Cancel(KIrp I)
{
t << "Cancel(KIrp I)\n";
if ( (PIRP)I == CurrentIrp() )
{
CurrentIrp() = NULL;
CancelSpinLock::Release(I.CancelIrql());
I.Information() = 0;
I.PnpComplete(this, STATUS_CANCELLED);
IncrementOutstandingRequestCount();
m_pItem.Queue(LinkTo(Workitem), this);
}
else
CancelSpinLock::Release(I.CancelIrql());
}
VOID D12_DriverDevice::Workitem()
{
m_Endpoint1In.Abort();
m_Endpoint1Out.Abort();
m_Endpoint2In.Abort();
m_Endpoint2Out.Abort();
DecrementOutstandingRequestCount();
}
NTSTATUS D12_DriverDevice::OnQueryCapabilities(KIrp I)
{
I.CopyParametersDown();
I.SetCompletionRoutine(LinkTo(OnQueryCapabilitiesComplete), this);
return m_Lower.PnpCall(this, I);
}
NTSTATUS D12_DriverDevice::OnQueryCapabilitiesComplete(KIrp I)
{
t << "Capabilities Completion routine\n";
if (I->PendingReturned)
I.MarkPending();
I.DeviceCapabilities()->SurpriseRemovalOK = TRUE;
return STATUS_SUCCESS;
}
NTSTATUS D12_DriverDevice::D12_DRIVER_BULK_OUT_Handler(KIrp I)
{
PURB pUrb;
NTSTATUS status;
t << "D12_DRIVER_BULK_OUT_Handler, " << I << EOL ;
if (I.IoctlOutputBufferSize() == 0)
{
I.Information() = 0;
return I.PnpComplete(this, STATUS_SUCCESS);
}
// Declare a memory object
ULONG dwTotalSize = I.IoctlOutputBufferSize(CURRENT);
ULONG dwMaxSize = m_Endpoint2In.MaximumTransferSize();
// If the total requested read size is greater than the Maximum Transfer
// Size for the Pipe, request to read only the Maximum Transfer Size since
// the bus driver will fail an URB with a TransferBufferLength of greater
// than the Maximum Transfer Size.
if (dwTotalSize > dwMaxSize)
{
ASSERT(dwMaxSize);
dwTotalSize = dwMaxSize;
}
ULONG dwBytesRead = 0;
pUrb = m_Endpoint2Out.BuildBulkTransfer(
(unsigned char *)I.IoctlBuffer(), // transfer buffer
I.IoctlOutputBufferSize(), // transfer buffer size
FALSE, // Device To Host
NULL, // link urb
FALSE, // Short Ok
NULL // new urb
);
if ( pUrb != NULL)
{
// Submit the URB to our USB device, synchronously - say less is OK
status = m_Endpoint2Out.SubmitUrb(pUrb, NULL, NULL);
if ( NT_SUCCESS(status) )
{
dwBytesRead = pUrb->UrbBulkOrInterruptTransfer.TransferBufferLength;
if (dwBytesRead > 0)
t << "BULK_OUT got " << dwTotalSize << " bytes from USB\n";
}
delete pUrb;
}
else
{
status=STATUS_INSUFFICIENT_RESOURCES;
}
I.Information() = dwBytesRead;
return status;
}
NTSTATUS D12_DriverDevice::D12_DRIVER_VENDOR_REQUEST_Handler(KIrp I)
{
PURB pUrb;
NTSTATUS status;
// UCHAR buffer1[]={0,0,0,0x20,0,0x80};
t << "D12_DRIVER_VENDOR_REQUEST_Handler, " << I << EOL;
pUrb = m_Lower.BuildVendorRequest(
(unsigned char *)I.IoctlBuffer(), // transfer buffer
I.IoctlInputBufferSize(), // transfer buffer size
// buffer1,
// 6,
0, // ReservedBits
0x0c, // Request
0, // Value
0, // Direction
0, // bShortOk
NULL, // Link
0x0471, // wIndex
URB_FUNCTION_VENDOR_DEVICE, // Function
NULL //pUrb
);
if ( pUrb == NULL )
{
status = STATUS_INSUFFICIENT_RESOURCES;
}
else
{
// submit the URB to USBD
status = m_Lower.SubmitUrb(pUrb);
delete pUrb;
}
return status;
}
NTSTATUS D12_DriverDevice::D12_DRIVER_BULK_IN_Handler(KIrp I)
{
PURB pUrb;
NTSTATUS status;
t << "Entering DddDevice::BULK_IN, " << I << EOL;
// TODO: Check the incoming request. Replace "FALSE" in the following
// line with a check that returns TRUE if the request is not valid.
if (I.IoctlOutputBufferSize() == 0)
{
I.Information() = 0;
return I.PnpComplete(this, STATUS_SUCCESS);
}
// Declare a memory object
ULONG dwTotalSize = I.IoctlInputBufferSize(CURRENT);
ULONG dwMaxSize = m_Endpoint2In.MaximumTransferSize();
// If the total requested read size is greater than the Maximum Transfer
// Size for the Pipe, request to read only the Maximum Transfer Size since
// the bus driver will fail an URB with a TransferBufferLength of greater
// than the Maximum Transfer Size.
if (dwTotalSize > dwMaxSize)
{
ASSERT(dwMaxSize);
dwTotalSize = dwMaxSize;
}
ULONG dwBytesRead = 0;
// Create an URB to do actual Bulk read from the pipe
pUrb = m_Endpoint2In.BuildBulkTransfer(
(unsigned char *)I.IoctlBuffer(), // transfer buffer
dwTotalSize, // transfer buffer size
TRUE, // Host To Device
NULL, // link urb
FALSE, // Short Ok
NULL // new urb
);
if ( pUrb != NULL)
{
// Submit the URB to our USB device, synchronously - say less is OK
// pUrb->UrbBulkOrInterruptTransfer.TransferFlags =
// (USBD_TRANSFER_DIRECTION_IN | USBD_SHORT_TRANSFER_OK);
status = m_Endpoint1In.SubmitUrb(pUrb, NULL, NULL,300);
if ( NT_SUCCESS(status) )
{
dwBytesRead = pUrb->UrbBulkOrInterruptTransfer.TransferBufferLength;
if (dwBytesRead > 0)
t << "BULK_IN got " << dwTotalSize << " bytes from USB\n";
}
delete pUrb;
}
else
{
status=STATUS_INSUFFICIENT_RESOURCES;
}
I.Information() = dwBytesRead;
return status;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -