📄 mavioctl.c
字号:
//
// Copy the string to the beginning of the buffer, blasting the
// two byte USB string descriptor header.
//
RtlCopyMemory(pucBuffer, pucBuffer + 2, size);
//
// Place an end-of-string character at the end of the string
// in the buffer.
//
pucBuffer[size] = 0;
pucBuffer[size + 1] = 0;
//
// Return the length of the string.
//
Irp->IoStatus.Information = size + 2;
}
//
// We're done with this IOCTL.
//
break;
}
//
// Return invalid parameter for all other IOCTLs.
//
default:
{
ntStatus = Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
}
}
//
// Complete the IRP.
//
IoCompleteRequest(Irp, IO_NO_INCREMENT);
//
// Decrement the count of pending IRPs.
//
MavUsb_DecrementIoCount(DeviceObject);
//
// Return the result.
//
return(ntStatus);
}
//****************************************************************************
//
// Checks port status; if OK, return success and does nothing more; if bad,
// it attempt to reset the device.
//
// Arguments:
//
// DeviceObject - pointer to the device object for this instance of the
// device.
//
// Return Value:
//
// NT status code
//
//****************************************************************************
NTSTATUS
MavUsb_ResetDevice(IN PDEVICE_OBJECT DeviceObject)
{
NTSTATUS ntStatus;
ULONG portStatus;
//
// Check the port state, if it is disabled we will need to re-enable it.
//
ntStatus = MavUsb_GetPortStatus(DeviceObject, &portStatus);
//
// See if the port is not enabled and is connected, in which case we will
// reset the parent port.
//
if(NT_SUCCESS(ntStatus) && !(portStatus & USBD_PORT_ENABLED) &&
(portStatus & USBD_PORT_CONNECTED))
{
//
// The port is disabled, attempt to reset the parent port.
//
ntStatus = MavUsb_ResetParentPort(DeviceObject);
}
//
// Return the result.
//
return(ntStatus);
}
//****************************************************************************
//
// Returns the port status for our device.
//
// Arguments:
//
// DeviceObject - pointer to the devic eobject for this instance of the
// device.
//
// PortStatus - status of the port.
//
// Return Value:
//
// STATUS_SUCCESS if successful,
// STATUS_UNSUCCESSFUL otherwise
//
//****************************************************************************
NTSTATUS
MavUsb_GetPortStatus(IN PDEVICE_OBJECT DeviceObject, IN PULONG PortStatus)
{
NTSTATUS ntStatus, status = STATUS_SUCCESS;
PIRP irp;
KEVENT event;
IO_STATUS_BLOCK ioStatus;
PIO_STACK_LOCATION nextStack;
PDEVICE_EXTENSION deviceExtension;
//
// Get a pointer to the device extension.
//
deviceExtension = DeviceObject->DeviceExtension;
//
// Initialize the port status to zero.
//
*PortStatus = 0;
//
// Initialize an IRP completion event.
//
KeInitializeEvent(&event, NotificationEvent, FALSE);
//
// IoBuildDeviceIoControlRequest allocates and sets up an IRP for a device
// control request.
//
irp =
IoBuildDeviceIoControlRequest(IOCTL_INTERNAL_USB_GET_PORT_STATUS,
deviceExtension->TopOfStackDeviceObject,
NULL, 0, NULL, 0, TRUE, &event,
&ioStatus);
//
// IoGetNextIrpStackLocation gives a higher level driver access to the
// next-lower driver's I/O stack location in an IRP so the caller can set
// it up for the lower driver.
//
nextStack = IoGetNextIrpStackLocation(irp);
//
// Setup the argument in the IRP stack.
//
nextStack->Parameters.Others.Argument1 = PortStatus;
//
// Send the IRP to the PDO.
//
ntStatus = IoCallDriver(deviceExtension->TopOfStackDeviceObject, irp);
//
// See if we should wait for the IRP to complete.
//
if(ntStatus == STATUS_PENDING)
{
//
// Wait for the IRP to complete.
//
KeWaitForSingleObject(&event, Suspended, KernelMode, FALSE, NULL);
}
else
{
//
// Set the status in the IO status block.
//
ioStatus.Status = ntStatus;
}
//
// USBD maps the error code for us.
//
ntStatus = ioStatus.Status;
//
// Return the status.
//
return(ntStatus);
}
//****************************************************************************
//
// Reset our parent port.
//
// Arguments:
//
// DeviceObject - pointer to the device object for this instance of the
// device.
//
// Return Value:
//
// STATUS_SUCCESS if successful,
// STATUS_UNSUCCESSFUL otherwise
//
//****************************************************************************
NTSTATUS
MavUsb_ResetParentPort(IN PDEVICE_OBJECT DeviceObject)
{
NTSTATUS ntStatus, status = STATUS_SUCCESS;
PIRP irp;
KEVENT event;
IO_STATUS_BLOCK ioStatus;
PIO_STACK_LOCATION nextStack;
PDEVICE_EXTENSION deviceExtension;
//
// Get a pointer to the device extension.
//
deviceExtension = DeviceObject->DeviceExtension;
//
// Initialize an IRP completion event.
//
KeInitializeEvent(&event, NotificationEvent, FALSE);
//
// Allocate and setup an IRP for a device control request.
//
irp =
IoBuildDeviceIoControlRequest(IOCTL_INTERNAL_USB_RESET_PORT,
deviceExtension->TopOfStackDeviceObject,
NULL, 0, NULL, 0, TRUE, &event,
&ioStatus);
//
// IoGetNextIrpStackLocation gives a higher level driver access to the
// next-lower driver's I/O stack location in an IRP so the caller can set
// it up for the lower driver.
//
nextStack = IoGetNextIrpStackLocation(irp);
//
// Send the IRP to the PDO.
//
ntStatus = IoCallDriver(deviceExtension->TopOfStackDeviceObject, irp);
//
// See if we should wait for the IRP to complete.
//
if(ntStatus == STATUS_PENDING)
{
//
// Wait for the IRP to complete.
//
KeWaitForSingleObject(&event, Suspended, KernelMode, FALSE, NULL);
}
else
{
//
// Set the status in the IO status block.
//
ioStatus.Status = ntStatus;
}
//
// USBD maps the error code for us.
//
ntStatus = ioStatus.Status;
//
// Return the status.
//
return(ntStatus);
}
//****************************************************************************
//
// Sends a vendor specific command to the device.
//
// Arguments:
//
// DeviceObject - pointer to the FDO for this instance of the device.
//
//****************************************************************************
NTSTATUS
MavUsb_SendVendorCommand(IN PDEVICE_OBJECT DeviceObject, IN PURB urb,
IN ULONG drive, IN ULONG request, IN USHORT value,
IN USHORT index, IN PUCHAR buffer, IN ULONG length)
{
NTSTATUS ntStatus;
//
// Build the vendor request.
//
UsbBuildVendorRequest(urb, URB_FUNCTION_VENDOR_DEVICE,
sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST),
USBD_TRANSFER_DIRECTION_IN | USBD_SHORT_TRANSFER_OK,
0, (UCHAR)((drive << 5) | request), value, index,
buffer, 0, length, 0);
//
// Send the URB to the device.
//
ntStatus = MavUsb_CallUSBD(DeviceObject, urb);
//
// Return the status.
//
return(ntStatus);
}
//****************************************************************************
//
// Performs a bulk transfer to/from the device.
//
//****************************************************************************
NTSTATUS
MavUsb_BulkXfer(IN PDEVICE_OBJECT DeviceObject, IN PUCHAR buffer,
IN ULONG length, IN BOOLEAN Read)
{
NTSTATUS ntStatus;
PDEVICE_EXTENSION deviceExtension;
PUSBD_INTERFACE_INFORMATION interface;
USBD_PIPE_HANDLE PipeHandle;
ULONG siz, flags;
PURB urb;
//
// Get a pointer to the device extension.
//
deviceExtension = DeviceObject->DeviceExtension;
//
// Get a pointer to the interface descriptor.
//
interface = deviceExtension->UsbInterface;
//
// Get the pipe info structure for the pipe to be used.
//
PipeHandle = interface->Pipes[Read ? 0 : 1].PipeHandle;
//
// Get the flags for the transfer.
//
if(Read)
{
flags = USBD_TRANSFER_DIRECTION_IN | USBD_SHORT_TRANSFER_OK;
}
else
{
flags = USBD_SHORT_TRANSFER_OK;
}
//
// Allocate memory for the URB.
//
siz = sizeof(struct _URB_BULK_OR_INTERRUPT_TRANSFER);
urb = ExAllocatePool(NonPagedPool, siz);
if(!urb)
{
return(STATUS_INSUFFICIENT_RESOURCES);
}
//
// Build the bulk transfer URB.
//
UsbBuildInterruptOrBulkTransferRequest(urb, (USHORT)siz, PipeHandle,
buffer, NULL, length, flags, NULL);
//
// Send the URB to the USB driver.
//
ntStatus = MavUsb_CallUSBD(DeviceObject, urb);
//
// Free the memory used for the URB.
//
ExFreePool(urb);
//
// Return the status.
//
return(ntStatus);
}
//****************************************************************************
//
// Sends a "connect" request to the device.
//
//****************************************************************************
NTSTATUS
MavUsb_VendorConnect(IN PDEVICE_OBJECT DeviceObject)
{
NTSTATUS ntStatus;
PURB urb;
ULONG ulTemp;
//
// Allocate memory from the non-paged pool for the URB.
//
urb = ExAllocatePool(NonPagedPool,
sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST));
if(!urb)
{
return(STATUS_INSUFFICIENT_RESOURCES);
}
//
// Send the "connect" vendor request.
//
ntStatus = MavUsb_SendVendorCommand(DeviceObject, urb, 0,
USB_Vendor_Connect, 0, 0,
(PUCHAR)&ulTemp, 4);
//
// Free the URB.
//
ExFreePool(urb);
//
// Return the result.
//
return(ntStatus);
}
//****************************************************************************
//
// Sends a "disconnect" request to the device.
//
//****************************************************************************
NTSTATUS
MavUsb_VendorDisconnect(IN PDEVICE_OBJECT DeviceObject)
{
NTSTATUS ntStatus;
PURB urb;
ULONG ulTemp;
//
// Allocate memory from the non-paged pool for the URB.
//
urb = ExAllocatePool(NonPagedPool,
sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST));
if(!urb)
{
return(STATUS_INSUFFICIENT_RESOURCES);
}
//
// Send the "disconnect" vendor request.
//
ntStatus = MavUsb_SendVendorCommand(DeviceObject, urb, 0,
USB_Vendor_Disconnect, 0, 0,
(PUCHAR)&ulTemp, 4);
//
// Free the URB.
//
ExFreePool(urb);
//
// Return the result.
//
return(ntStatus);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -