📄 usbsoftlockdevice.cpp
字号:
// USBSoftLockDevice::Close
//
// Routine Description:
// Handler for IRP_MJ_CLOSE
//
// Parameters:
// I - Current IRP
//
// Return Value:
// NTSTATUS - Result code
//
// Comments:
//
NTSTATUS USBSoftLockDevice::Close(KIrp I)
{
NTSTATUS status;
t << "Entering USBSoftLockDevice::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 << "USBSoftLockDevice::Close Status " << (ULONG)status << EOL;
return status;
}
////////////////////////////////////////////////////////////////////////
// USBSoftLockDevice::Cleanup
//
// Routine Description:
// Handler for IRP_MJ_CLEANUP
//
// Parameters:
// I - Current IRP
//
// Return Value:
// NTSTATUS - Result code
//
// Comments:
//
NTSTATUS USBSoftLockDevice::CleanUp(KIrp I)
{
t << "Entering CleanUp, " << I << EOL;
// TODO: Insert your code to respond to the CLEANUP message.
return I.PnpComplete(this, STATUS_SUCCESS);
}
////////////////////////////////////////////////////////////////////////
// USBSoftLockDevice::Read
//
// Routine Description:
// Handler for IRP_MJ_READ
//
// Parameters:
// I Current IRP
//
// Return Value:
// NTSTATUS Result code
//
// Comments:
// This routine handles read requests.
//
// The KPnpDevice class handles restricting IRP flow
// if the device is stopping or being removed.
//
NTSTATUS USBSoftLockDevice::Read(KIrp I)
{
t << "Entering USBSoftLockDevice::Read, " << 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 (FALSE) // If (Request is invalid)
{
// Invalid parameter in the Read request
I.Information() = 0;
return I.PnpComplete(this, STATUS_INVALID_PARAMETER);
}
// Always ok to read 0 elements.
if (I.ReadSize() == 0)
{
I.Information() = 0;
return I.PnpComplete(this, STATUS_SUCCESS);
}
// Declare a memory object
KMemory Mem(I.Mdl());
ULONG dwTotalSize = I.ReadSize(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;
}
// Allocate a new context structure for Irp completion
USB_COMPLETION_INFO* pCompInfo = new (NonPagedPool) USB_COMPLETION_INFO;
if (pCompInfo == NULL)
{
I.Information() = 0;
return I.PnpComplete(this, STATUS_INSUFFICIENT_RESOURCES);
}
// TODO: Select the correct pipe to read from
// Create an URB to do actual Bulk read from the pipe
PURB pUrb = m_Endpoint2IN.BuildBulkTransfer(
Mem, // Where is data coming from?
dwTotalSize, // How much data to read?
TRUE, // direction (TRUE = IN)
NULL, // Link to next URB
TRUE // Allow a short transfer
);
if (pUrb == NULL)
{
delete pCompInfo;
I.Information() = 0;
return I.PnpComplete(this, STATUS_INSUFFICIENT_RESOURCES);
}
// Initialize context structure
pCompInfo->m_pClass = this;
pCompInfo->m_pUrb = pUrb;
// Submit the URB to our USB device
NTSTATUS status;
status = m_Endpoint2IN.SubmitUrb(I, pUrb, LinkTo(ReadComplete), pCompInfo, 0);
return status;
}
////////////////////////////////////////////////////////////////////////
// USBSoftLockDevice::ReadComplete
//
// Routine Description:
// Completion Handler for IRP_MJ_READ
//
// Parameters:
// I - IRP just completed by USB
// pContext - Context structure containing pointer to Urb
//
// Parameters:
// NTSTATUS - STATUS_SUCCESS
//
// Comments:
// This routine is called when USBD completes the read request
//
NTSTATUS USBSoftLockDevice::ReadComplete(KIrp I, USB_COMPLETION_INFO* pContext)
{
// Normal completion routine code to propagate pending flag
if (I->PendingReturned)
{
I.MarkPending();
}
NTSTATUS status = I.Status();
PURB pUrb = pContext->m_pUrb;
ULONG nBytesRead = 0;
if ( NT_SUCCESS(status) )
{
nBytesRead = pUrb->UrbBulkOrInterruptTransfer.TransferBufferLength;
if (nBytesRead > 0)
t << "Read() got " << nBytesRead<< " bytes from USB\n";
}
// Deallocate Urb and context structure
delete pUrb;
delete pContext;
// set returned count
I.Information() = nBytesRead;
// Plug and Play accounting
DecrementOutstandingRequestCount();
// allow IRP completion processing
return STATUS_SUCCESS;
}
////////////////////////////////////////////////////////////////////////
// USBSoftLockDevice::Write
//
// Routine Description:
// Handler for IRP_MJ_WRITE
//
// Parameters:
// I - Current IRP
//
// Return Value:
// NTSTATUS - Result code
//
// Comments:
// This routine handles write requests.
//
// The KPnpDevice class handles restricting IRP flow
// if the device is stopping or being removed.
//
NTSTATUS USBSoftLockDevice::Write(KIrp I)
{
t << "Entering USBSoftLockDevice::Write, " << 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 (FALSE)
{
// Invalid parameter in the Write request
I.Information() = 0;
return I.PnpComplete(this, STATUS_INVALID_PARAMETER);
}
// Always ok to write 0 elements.
if (I.WriteSize() == 0)
{
I.Information() = 0;
return I.PnpComplete(this, STATUS_SUCCESS);
}
ULONG dwTotalSize = I.WriteSize(CURRENT);
ULONG dwMaxSize = m_Endpoint2OUT.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;
}
// Declare a memory object
KMemory Mem(I.Mdl());
// Allocate a new context structure for Irp completion
USB_COMPLETION_INFO* pCompInfo = new (NonPagedPool) USB_COMPLETION_INFO;
if (pCompInfo == NULL)
{
I.Information() = 0;
return I.PnpComplete(this, STATUS_INSUFFICIENT_RESOURCES);
}
// TODO: Select the correct pipe to write to
// Create an URB to do actual Bulk write to the pipe
PURB pUrb = m_Endpoint2OUT.BuildBulkTransfer(
Mem, // Where is data coming from?
dwTotalSize, // How much data to read?
FALSE, // direction (FALSE = OUT)
NULL // Link to next URB
);
if (pUrb == NULL)
{
delete pCompInfo;
I.Information() = 0;
return I.PnpComplete(this, STATUS_INSUFFICIENT_RESOURCES);
}
// Initialize context structure
pCompInfo->m_pClass = this;
pCompInfo->m_pUrb = pUrb;
// Submit the URB to our USB device
NTSTATUS status;
status = m_Endpoint2OUT.SubmitUrb(I, pUrb, LinkTo(WriteComplete), pCompInfo, 0);
return status;
}
////////////////////////////////////////////////////////////////////////
// USBSoftLockDevice::WriteComplete
//
// Routine Description:
// Completion Handler for IRP_MJ_WRITE
//
// Parameters:
// I - IRP just completed by USB
// pContext - Context structure containing pointer to Urb
//
// Return Value:
// NTSTATUS STATUS_SUCCESS
//
// Comments:
// This routine is called when USBD completes the write request
//
NTSTATUS USBSoftLockDevice::WriteComplete(KIrp I, USB_COMPLETION_INFO* pContext)
{
// Normal completion routine code to propagate pending flag
if (I->PendingReturned)
{
I.MarkPending();
}
NTSTATUS status = I.Status();
PURB pUrb = pContext->m_pUrb;
ULONG nBytesWritten = 0;
if ( NT_SUCCESS(status) )
{
nBytesWritten = pUrb->UrbBulkOrInterruptTransfer.TransferBufferLength;
if (nBytesWritten > 0)
t << "Wrote " << nBytesWritten << " bytes to USB\n";
}
// Deallocate Urb and context structure
delete pUrb;
delete pContext;
// set returned count
I.Information() = nBytesWritten;
// Plug and Play accounting
DecrementOutstandingRequestCount();
// allow IRP completion processing
return STATUS_SUCCESS;
}
////////////////////////////////////////////////////////////////////////
// USBSoftLockDevice::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 USBSoftLockDevice::DeviceControl(KIrp I)
{
NTSTATUS status;
t << "Entering USBSoftLockDevice::Device Control, " << I << EOL;
switch (I.IoctlCode())
{
case USBSOFTLOCK_IOCTL_GET_PASSWORD:
status = USBSOFTLOCK_IOCTL_GET_PASSWORD_Handler(I);
break;
case USBSOFTLOCK_IOCTL_SET_PASSWORD:
status = USBSOFTLOCK_IOCTL_SET_PASSWORD_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);
}
}
////////////////////////////////////////////////////////////////////////
// USBSoftLockDevice::USBSOFTLOCK_IOCTL_GET_PASSWORD_Handler
//
// Routine Description:
// Handler for IO Control Code USBSOFTLOCK_IOCTL_GET_PASSWORD
//
// Parameters:
// I - IRP containing IOCTL request
//
// Return Value:
// NTSTATUS - Status code indicating success or failure
//
// Comments:
// This routine implements the USBSOFTLOCK_IOCTL_GET_PASSWORD function.
// This routine runs at passive level.
//
NTSTATUS USBSoftLockDevice::USBSOFTLOCK_IOCTL_GET_PASSWORD_Handler(KIrp I)
{
NTSTATUS status = STATUS_SUCCESS;
t << "Entering USBSoftLockDevice::USBSOFTLOCK_IOCTL_GET_PASSWORD_Handler, " << I << EOL;
// TODO: Verify that the input parameters are correct
// If not, return STATUS_INVALID_PARAMETER
// TODO: Handle the the USBSOFTLOCK_IOCTL_GET_PASSWORD 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.
t << "IOctrlBuffer address is " << (LONG)(I.IoctlBuffer()) << EOL;
t << "BufferedReadDest address is " << (LONG)(I.BufferedReadDest()) << EOL;
t << "BufferedWriteSource address is " << (LONG)(I.BufferedWriteSource()) << EOL;
t << "IoctlOutputBufferSize is " << (LONG)(I.IoctlOutputBufferSize()) << EOL;
UCHAR buffer[8];
// build vendor request
PURB pUrb = m_Lower.BuildVendorRequest(
buffer,
PASSWORD_LENGTH,
0,
REQUEST_GET_PASSWORD,
0,
TRUE );
status = m_Lower.SubmitUrb(pUrb, NULL, NULL, OPERATION_TIMEOUT);
if (status == STATUS_SUCCESS) {
t << "Received buffer is ";
for (int i=0;i<PASSWORD_LENGTH;i++) {
t << " " << buffer[i];
}
t << EOL;
PUCHAR output_buffer = (PUCHAR)(I.IoctlBuffer());
memcpy(output_buffer, buffer, PASSWORD_LENGTH);
}
else {
}
return status;
}
////////////////////////////////////////////////////////////////////////
// USBSoftLockDevice::USBSOFTLOCK_IOCTL_SET_PASSWORD_Handler
//
// Routine Description:
// Handler for IO Control Code USBSOFTLOCK_IOCTL_SET_PASSWORD
//
// Parameters:
// I - IRP containing IOCTL request
//
// Return Value:
// NTSTATUS - Status code indicating success or failure
//
// Comments:
// This routine implements the USBSOFTLOCK_IOCTL_SET_PASSWORD function.
// This routine runs at passive level.
//
NTSTATUS USBSoftLockDevice::USBSOFTLOCK_IOCTL_SET_PASSWORD_Handler(KIrp I)
{
NTSTATUS status = STATUS_SUCCESS;
t << "Entering USBSoftLockDevice::USBSOFTLOCK_IOCTL_SET_PASSWORD_Handler, " << I << EOL;
// TODO: Verify that the input parameters are correct
// If not, return STATUS_INVALID_PARAMETER
// TODO: Handle the the USBSOFTLOCK_IOCTL_SET_PASSWORD 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.
I.Information() = PASSWORD_LENGTH;
UCHAR buffer[PASSWORD_LENGTH];
memset(buffer, 0, PASSWORD_LENGTH);
PUCHAR input_buffer = (PUCHAR)(I.IoctlBuffer());
memcpy(buffer, input_buffer, PASSWORD_LENGTH);
t << "Buffer to send is ";
for (int i=0;i<PASSWORD_LENGTH;i++) {
t << " " << buffer[i];
}
t << EOL;
// build vendor request
PUSHORT value, index;
PURB pUrb;
value = (PUSHORT)buffer;
index = (PUSHORT)(buffer+2);
pUrb = m_Lower.BuildVendorRequest(
NULL,
0,
0,
REQUEST_SET_PASSWORD_HIGH,
(*value),
FALSE,
FALSE,
NULL,
(*index));
status = m_Lower.SubmitUrb(pUrb, NULL, NULL, OPERATION_TIMEOUT);
value = (PUSHORT)(buffer+4);
index = (PUSHORT)(buffer+6);
pUrb = m_Lower.BuildVendorRequest(
NULL,
0,
0,
REQUEST_SET_PASSWORD_LOW,
(*value),
FALSE,
FALSE,
NULL,
(*index));
status = m_Lower.SubmitUrb(pUrb, NULL, NULL, OPERATION_TIMEOUT);
return status;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -