📄 forusbdevice.cpp
字号:
// The base class will handle completion of the IRP
T.Trace(TraceInfo, __FUNCTION__"--. IRP %p, STATUS %x\n", I, status);
return status;
}
///////////////////////////////////////////////////////////////////////////////////////////////////
// ForUsbDevice::OnDeviceSleep
// Handler for IRP_MJ_POWER subfcn IRP_MN_SET_POWER
// for a request to go to a low power state from a high power state
// This function was called by the framework from the IRP_MJ_POWER
// dispatch handler in KPnpDevice prior to forwarding to the PDO.
// The hardware has yet to be powered down and this driver can now
// access the hardware device.
// This routine runs at PASSIVE_LEVEL.
//
// Arguments:
// IN I
// the power IRP
//
// Return Value:
// NTSTATUS
//
NTSTATUS ForUsbDevice::OnDeviceSleep(KIrp I)
{
T.Trace(TraceInfo, __FUNCTION__"++. IRP %p\n", I);
NTSTATUS status = STATUS_SUCCESS;
// TODO: Add device-specific code to:
// Save any context to the hardware device that will be required
// during a power up request. See the OnDevicePowerUp function.
// Do NOT complete this IRP. The base class handles forwarding
// this IRP to the PDO.
T.Trace(TraceInfo, __FUNCTION__"--. IRP %p, STATUS %x\n", I, status);
return status;
}
///////////////////////////////////////////////////////////////////////////////////////////////////
// ForUsbDevice::Create
// Dispatch routine for IRP_MJ_CREATE requests.
//
// Arguments:
// IN I
// the create IRP
//
// Return Value:
// NTSTATUS
//
NTSTATUS ForUsbDevice::Create(KIrp I)
{
T.Trace(TraceInfo, __FUNCTION__"++. IRP %p\n", I);
// TODO: For any IRP, to display the contents of the IRP
// in a formatted way, use the KTrace << operator:
// T << I;
NTSTATUS status = STATUS_SUCCESS;
// TODO: At this point, perform custom processing for IRP_MJ_CREATE
// Generally a create IRP is targeted at our FDO, so its not needed
// to pass it down to the PDO.
I.Information() = 0;
I.PnpComplete(this, status);
T.Trace(TraceInfo, __FUNCTION__"--. IRP %p, STATUS %x\n", I, status);
return status;
}
///////////////////////////////////////////////////////////////////////////////////////////////////
// ForUsbDevice::Close
// Dispatch routine for IRP_MJ_CLOSE requests.
//
// Arguments:
// IN I
// the close IRP
//
// Return Value:
// NTSTATUS
//
NTSTATUS ForUsbDevice::Close(KIrp I)
{
T.Trace(TraceInfo, __FUNCTION__"++. IRP %p\n", I);
NTSTATUS status = STATUS_SUCCESS;
// TODO: At this point, perform custom processing for IRP_MJ_CLOSE
// Generally a close IRP is targeted at our FDO, so we don't need
// to pass it down to the PDO.
I.Information() = 0;
I.PnpComplete(this, status);
T.Trace(TraceInfo, __FUNCTION__"--. IRP %p, STATUS %x\n", I, status);
return status;
}
///////////////////////////////////////////////////////////////////////////////////////////////////
// ForUsbDevice::SerialRead
// Handler for serialized IRP_MJ_READ requests. This routine is called
// when the IRP is removed from the queue. This guarantees that multiple
// requests are never processed simultaneously. This routine is called
// at DISPATCH_LEVEL unless the Queue class is initialized to call this
// at less than DISPATCH_LEVEL. The IRP was validated in the Read() method.
//
// Arguments:
// IN I
// the serialized read IRP
//
// Return Value:
// NTSTATUS
//
void ForUsbDevice::SerialRead(KIrp I)
{
T.Trace(TraceInfo, __FUNCTION__"++. IRP %p\n", I);
NTSTATUS status = STATUS_SUCCESS;
KMemory Mem(I.Mdl()); // Declare a memory object
// Get a pointer to the caller's buffer. Note that this
// routine is safe on all platforms.
PUCHAR pBuffer = (PUCHAR) Mem.MapToSystemSpace();
ULONG readSize = I.ReadSize();
ULONG bytesRead = 0;
I.Status() = status;
// NextIrp completes this IRP and starts processing
// for the next IRP in the driver managed queue.
Pipe2Queue.PnpNextIrp(I);
T.Trace(TraceInfo, __FUNCTION__"--. IRP %p, STATUS %x\n", I, status);
}
///////////////////////////////////////////////////////////////////////////////////////////////////
// ForUsbDevice::Read
// Dispatch routine for IRP_MJ_READ requests.
//
// Arguments:
// IN I
// the read IRP
//
// Return Value:
// NTSTATUS
//
NTSTATUS ForUsbDevice::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)
{
I.Information() = 0;
I.PnpComplete(this, status);
T.Trace(TraceInfo, __FUNCTION__"--. IRP %p, STATUS %x\n", I, status);
return status;
}
// Queue the IRP for processing in the driver managed queue.
// The actual read function is performed in SerialRead
// TODO: The Wizard creates a single queue class for all Irps and
// one or more instances of the class. Review the number
// and types of queues. Select the appropriate queue for
// this Irp here.
status = Pipe2Queue.QueueIrp(I);
T.Trace(TraceInfo, __FUNCTION__"--. IRP %p, STATUS %x\n", I, status);
return status;
}
///////////////////////////////////////////////////////////////////////////////////////////////////
// ForUsbDevice::SerialWrite
// Handler for serialized IRP_MJ_WRITE requests. This routine is called
// when the IRP is removed from the queue. This guarantees that multiple
// requests are never processed simultaneously. This routine is called
// at DISPATCH_LEVEL unless the Queue class is initialized to call this
// at less than DISPATCH_LEVEL. The IRP was validated in the Write() method.
//
// Arguments:
// IN I
// the serialized write IRP
//
// Return Value:
// NTSTATUS
//
void ForUsbDevice::SerialWrite(KIrp I)
{
T.Trace(TraceInfo, __FUNCTION__"++. IRP %p\n", I);
NTSTATUS status = STATUS_SUCCESS;
KMemory Mem(I.Mdl()); // Declare a memory object
// Get a pointer to the caller's buffer. Note that this
// routine is safe on all platforms.
PUCHAR pBuffer = (PUCHAR) Mem.MapToSystemSpace();
ULONG writeSize = I.WriteSize();
ULONG bytesSent = 0;
I.Status() = status;
// NextIrp completes this IRP and starts processing
// for the next IRP in the driver managed queue.
Pipe3Queue.PnpNextIrp(I);
T.Trace(TraceInfo, __FUNCTION__"--. IRP %p, STATUS %x\n", I, status);
}
///////////////////////////////////////////////////////////////////////////////////////////////////
// ForUsbDevice::Write
// Dispatch routine for IRP_MJ_WRITE requests.
//
// Arguments:
// IN I
// the write IRP
//
// Return Value:
// NTSTATUS
//
NTSTATUS ForUsbDevice::Write(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 write 0 elements
if (I.WriteSize() == 0)
{
I.Information() = 0;
I.PnpComplete(this, status);
T.Trace(TraceInfo, __FUNCTION__"--. IRP %p, STATUS %x\n", I, status);
return status;
}
// Queue the IRP for processing in the driver managed queue.
// The actual write function is performed in SerialWrite
// TODO: The Wizard creates a single queue class for all Irps and
// one or more instances of the class. Review the number
// and types of queues. Select the appropriate queue for
// this Irp here.
status = Pipe3Queue.QueueIrp(I);
T.Trace(TraceInfo, __FUNCTION__"--. IRP %p, STATUS %x\n", I, status);
return status;
}
///////////////////////////////////////////////////////////////////////////////////////////////////
// ForUsbDevice::DeviceControl
// Dispatch routine for IRP_MJ_DEVICE_CONTROL requests.
//
// Arguments:
// IN I
// the ioctl IRP
//
// Return Value:
// NTSTATUS
//
NTSTATUS ForUsbDevice::DeviceControl(KIrp I)
{
T.Trace(TraceInfo, __FUNCTION__"++. IRP %p\n", I);
NTSTATUS status = STATUS_SUCCESS;
switch (I.IoctlCode())
{
case IOCTL_Read:
// Queue the IRP for processing in the driver managed queue.
// The actual write function is performed in Serial_IOCTL_Read_Handler
// TODO: The Wizard creates a single queue class for all Irps and
// one or more instances of the class. Review the number
// and types of queues. Select the appropriate queue for
// this Irp here.
status = Pipe2Queue.QueueIrp(I);
break;
case IOCTL_Write:
// Queue the IRP for processing in the driver managed queue.
// The actual write function is performed in Serial_IOCTL_Write_Handler
// TODO: The Wizard creates a single queue class for all Irps and
// one or more instances of the class. Review the number
// and types of queues. Select the appropriate queue for
// this Irp here.
status = Pipe3Queue.QueueIrp(I);
break;
default:
status = STATUS_INVALID_DEVICE_REQUEST;
break;
}
// If the IRP was queued, or its 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)
{
I.PnpComplete(this, status);
}
T.Trace(TraceInfo, __FUNCTION__"--. IRP %p, STATUS %x\n", I, status);
return status;
}
///////////////////////////////////////////////////////////////////////////////////////////////////
// ForUsbDevice::Serial_IOCTL_Read_Handler
// Handler for ioctl IOCTL_Read.
//
// Arguments:
// IN I
// the serialized ioctl IRP
//
// Return Value:
// NTSTATUS
//
void ForUsbDevice::Serial_IOCTL_Read_Handler(KIrp I)
{
T.Trace(TraceInfo, __FUNCTION__"++. IRP %p\n", I);
NTSTATUS status = STATUS_SUCCESS;
ULONG inputSize = I.IoctlInputBufferSize();
ULONG outputSize = I.IoctlOutputBufferSize();
// Direct ioctl
PVOID inputBuffer = I.IoctlBuffer();
PVOID outputBuffer = NULL;
if (I.Mdl() != NULL)
{
KMemory Mem(I.Mdl());
// Note that this routine is safe on all platforms.
outputBuffer = Mem.MapToSystemSpace();
}
// 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;
}
else
{
}
I.Status() = status;
// NextIrp completes this IRP and starts processing
// for the next IRP in the driver managed queue.
Pipe2Queue.PnpNextIrp(I);
T.Trace(NT_SUCCESS(status)?TraceInfo:TraceWarning, __FUNCTION__"--. IRP %p, STATUS %x\n", I, status);
}
///////////////////////////////////////////////////////////////////////////////////////////////////
// ForUsbDevice::Serial_IOCTL_Write_Handler
// Handler for ioctl IOCTL_Write.
//
// Arguments:
// IN I
// the serialized ioctl IRP
//
// Return Value:
// NTSTATUS
//
void ForUsbDevice::Serial_IOCTL_Write_Handler(KIrp I)
{
T.Trace(TraceInfo, __FUNCTION__"++. IRP %p\n", I);
NTSTATUS status = STATUS_SUCCESS;
ULONG inputSize = I.IoctlInputBufferSize();
ULONG outputSize = I.IoctlOutputBufferSize();
// Direct ioctl
PVOID inputBuffer = I.IoctlBuffer();
PVOID outputBuffer = NULL;
if (I.Mdl() != NULL)
{
KMemory Mem(I.Mdl());
// Note that this routine is safe on all platforms.
outputBuffer = Mem.MapToSystemSpace();
}
// 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;
}
else
{
}
I.Status() = status;
// NextIrp completes this IRP and starts processing
// for the next IRP in the driver managed queue.
Pipe3Queue.PnpNextIrp(I);
T.Trace(NT_SUCCESS(status)?TraceInfo:TraceWarning, __FUNCTION__"--. IRP %p, STATUS %x\n", I, status);
}
///////////////////////////////////////////////////////////////////////////////////////////////////
// ForUsbDevice::CleanUp
// Dispatch routine for IRP_MJ_CLEANUP requests.
//
// Arguments:
// IN I
// the cleanup IRP
//
// Return Value:
// NTSTATUS
//
NTSTATUS ForUsbDevice::CleanUp(KIrp I)
{
T.Trace(TraceInfo, __FUNCTION__"++. IRP %p\n", I);
NTSTATUS status = STATUS_SUCCESS;
// TODO: At this point, perform custom processing for IRP_MJ_CLEANUP
// Clean up the driver managed IRP queues for the file
// object specified in the cleanup IRP
Pipe2Queue.PnpCleanUp(this, I.FileObject());
Pipe3Queue.PnpCleanUp(this, I.FileObject());
I.PnpComplete(this, status);
T.Trace(TraceInfo, __FUNCTION__"--. IRP %p, STATUS %x\n", I, status);
return status;
}
///////////////////////////////////////////////////////////////////////////////////////////////////
// ForUsbDevice::Invalidate
// This method performs resource cleanup.
// This function is called from OnStopDevice, OnRemoveDevice and
// OnStartDevice (in error conditions). It calls the Invalidate
// member funcitons for each resource to free the underlying system
// resource if allocated. It is safe to call Invalidate more than
// once for a resource, or for an uninitialized resource.
//
// Arguments:
// none
//
// Return Value:
// none
//
VOID ForUsbDevice::Invalidate()
{
NTSTATUS status = STATUS_SUCCESS;
status = m_Lower.DeActivateConfiguration();
if (!NT_SUCCESS(status))
{
T.Trace(TraceWarning, __FUNCTION__" DeActivateConfiguration failed, STATUS %x\n", status);
}
m_Lower.ReleaseResources();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -