📄 mavioctl.c
字号:
//****************************************************************************
//
// MAVIOCTL.C - IOCTL handler for the Maverick(tm) USB driver.
//
// Copyright (c) 2000 Cirrus Logic, Inc.
// Copyright (c) 1997-1998 Microsoft Corporation. All Rights Reserved.
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
// KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
// PURPOSE.
//
//****************************************************************************
#include "wdm.h"
#include "usbdi.h"
#include "usbdlib.h"
#include "mavusb.h"
#include "mavproto.h"
#include "../../player/usbven.h"
//****************************************************************************
//
// Dispatch table handler for IRP_MJ_DEVICE_CONTROL; handles DeviceIoControl()
// calls from User mode.
//
// Arguments:
//
// DeviceObject - pointer to the FDO for this instance of the device.
//
// Irp - pointer to the IRP
//
// Return Value:
//
// NT status code
//
//****************************************************************************
NTSTATUS
MavUsb_ProcessIOCTL(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
{
PIO_STACK_LOCATION irpStack;
PVOID ioBuffer;
ULONG inputBufferLength;
ULONG outputBufferLength;
PDEVICE_EXTENSION deviceExtension;
NTSTATUS ntStatus = STATUS_SUCCESS;
ULONG length;
PUSB_CONFIGURATION_DESCRIPTOR configurationDescriptor;
//
// Increment the pending IRP count.
//
MavUsb_IncrementIoCount(DeviceObject);
//
// Get a pointer to the device extension.
//
deviceExtension = DeviceObject->DeviceExtension;
//
// Can't accept a new IO request if:
// 1) device is removed,
// 2) has never been started,
// 3) is stopped,
// 4) has a remove request pending,
// 5) has a stop device pending.
//
if(!MavUsb_CanAcceptIoRequests(DeviceObject))
{
//
// Set the status to delete pending.
//
ntStatus = STATUS_DELETE_PENDING;
//
// Set the status in the IRP.
//
Irp->IoStatus.Status = ntStatus;
Irp->IoStatus.Information = 0;
//
// Complete the IRP.
//
IoCompleteRequest(Irp, IO_NO_INCREMENT);
//
// Decrement the pending IRP count.
//
MavUsb_DecrementIoCount(DeviceObject);
//
// Return the result.
//
return(ntStatus);
}
//
// Get a pointer to the current location on the IRP stack.
//
irpStack = IoGetCurrentIrpStackLocation(Irp);
//
// Set the default status to success.
//
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = 0;
//
// Get pointers and lengths of the caller's (user's) IO buffer.
//
ioBuffer = Irp->AssociatedIrp.SystemBuffer;
inputBufferLength = irpStack->Parameters.DeviceIoControl.InputBufferLength;
outputBufferLength =
irpStack->Parameters.DeviceIoControl.OutputBufferLength;
//
// Determine which IOCTL we were sent.
//
switch(irpStack->Parameters.DeviceIoControl.IoControlCode)
{
//
// Reset the given pipe.
//
case IOCTL_MAVUSB_RESET_PIPE:
{
PUSBD_PIPE_INFORMATION pipe;
PFILE_OBJECT fileObject;
//
// Get our context and see if it is a pipe.
//
fileObject = irpStack->FileObject;
pipe = (PUSBD_PIPE_INFORMATION)fileObject->FsContext;
//
// See if this is a pipe.
//
if(pipe == NULL)
{
//
// Error, this is not a pipe.
//
ntStatus = Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
}
else
{
//
// Reset the pipe.
//
MavUsb_ResetPipe(DeviceObject, pipe);
}
//
// We're done handling this IOCTL.
//
break;
}
//
// Get a copy of the configuration descriptor and all endpoint and
// interface descriptors.
//
case IOCTL_MAVUSB_GET_CONFIG_DESCRIPTOR:
{
//
// Get a copy of the configuration descriptor pointer.
//
configurationDescriptor =
deviceExtension->UsbConfigurationDescriptor;
//
// See if there is a configuration descriptor.
//
if(configurationDescriptor)
{
//
// Get the length of the configuration descriptor.
//
length = configurationDescriptor->wTotalLength;
//
// See if there is enough space in the output buffer for the
// entire configuration descriptor.
//
if(outputBufferLength >= length)
{
//
// Copy the configuration descriptor into the output
// buffer.
//
RtlCopyMemory(ioBuffer, configurationDescriptor, length);
//
// Return the actual length in the IRP.
//
Irp->IoStatus.Information = length;
}
else
{
//
// There is not enough space in the output buffer, so
// return an invalid parameter status.
//
ntStatus = Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
Irp->IoStatus.Information = 0;
}
}
else
{
//
// There is no configuration descriptor, so return a device
// data error.
//
ntStatus = Irp->IoStatus.Status = STATUS_DEVICE_DATA_ERROR;
Irp->IoStatus.Information = 0;
}
//
// We're done with the IOCTL.
//
break;
}
//
// Reset the device.
//
case IOCTL_MAVUSB_RESET_DEVICE:
{
//
// Reset the device.
//
ntStatus = Irp->IoStatus.Status = MavUsb_ResetDevice(DeviceObject);
//
// We're done with this IOCTL.
//
break;
}
//
// Send a vendor command to the device.
//
case IOCTL_MAVUSB_DEVICE_REQUEST:
{
//
// Process the IRP.
//
ntStatus = Irp->IoStatus.Status =
MavUsb_VendorCommand(DeviceObject, Irp, irpStack);
//
// We're done with this IOCTL.
//
break;
}
//
// Reset the count of bytes transferred.
//
case IOCTL_MAVUSB_RESET_TRANSFER_COUNT:
{
//
// Reset the transfer count.
//
deviceExtension->StagedBytesTransferred = 0;
//
// The status is success.
//
ntStatus = Irp->IoStatus.Status = STATUS_SUCCESS;
//
// We're done with this IOCTL.
//
break;
}
//
// Get the current count of bytes transferred.
//
case IOCTL_MAVUSB_GET_TRANSFER_COUNT:
{
//
// Get the transfer count.
//
*((PULONG)ioBuffer) = deviceExtension->StagedBytesTransferred;
//
// The length of the return is 4.
//
Irp->IoStatus.Information = 4;
//
// The status is success.
//
ntStatus = Irp->IoStatus.Status = STATUS_SUCCESS;
//
// We're done with this IOCTL.
//
break;
}
//
// Get the name of the device.
//
case IOCTL_MAVUSB_GET_NAME:
{
unsigned char *pucBuffer = ioBuffer;
int size, index;
PURB urb;
//
// Allocate memory for a URB.
//
size = sizeof(struct _URB_CONTROL_DESCRIPTOR_REQUEST);
urb = ExAllocatePool(NonPagedPool, size);
if(!urb)
{
ntStatus = Irp->IoStatus.Status =
STATUS_INSUFFICIENT_RESOURCES;
break;
}
//
// Get the index of the product description string.
//
index = deviceExtension->UsbDeviceDescriptor->iProduct;
//
// Make sure that there is a product description string.
//
if(index == 0)
{
ntStatus = Irp->IoStatus.Status =
STATUS_INVALID_PARAMETER;
break;
}
//
// Build the get descriptor request URB.
//
UsbBuildGetDescriptorRequest(urb, (USHORT)size,
USB_STRING_DESCRIPTOR_TYPE,
(UCHAR)index, 0x0409, pucBuffer, NULL,
outputBufferLength, NULL);
//
// Send the URB to the USB driver.
//
ntStatus = Irp->IoStatus.Status =
MavUsb_CallUSBD(DeviceObject, urb);
//
// Free the memory for the URB.
//
ExFreePool(urb);
//
// See if the request succeeded.
//
if(NT_SUCCESS(ntStatus))
{
//
// Determine the length of the string.
//
if(pucBuffer[0] > outputBufferLength)
{
size = outputBufferLength - 2;
}
else
{
size = pucBuffer[0] - 2;
}
//
// 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;
}
//
// Get the name of the device manufacturer.
//
case IOCTL_MAVUSB_GET_MANUFACTURER_NAME:
{
unsigned char *pucBuffer = ioBuffer;
int size, index;
PURB urb;
//
// Allocate memory for a URB.
//
size = sizeof(struct _URB_CONTROL_DESCRIPTOR_REQUEST);
urb = ExAllocatePool(NonPagedPool, size);
if(!urb)
{
ntStatus = Irp->IoStatus.Status =
STATUS_INSUFFICIENT_RESOURCES;
break;
}
//
// Get the index of the product description string.
//
index = deviceExtension->UsbDeviceDescriptor->iManufacturer;
//
// Make sure that there is a product description string.
//
if(index == 0)
{
ntStatus = Irp->IoStatus.Status =
STATUS_INVALID_PARAMETER;
break;
}
//
// Build the get descriptor request URB.
//
UsbBuildGetDescriptorRequest(urb, (USHORT)size,
USB_STRING_DESCRIPTOR_TYPE,
(UCHAR)index, 0x0409, pucBuffer, NULL,
outputBufferLength, NULL);
//
// Send the URB to the USB driver.
//
ntStatus = Irp->IoStatus.Status =
MavUsb_CallUSBD(DeviceObject, urb);
//
// Free the memory for the URB.
//
ExFreePool(urb);
//
// See if the request succeeded.
//
if(NT_SUCCESS(ntStatus))
{
//
// Determine the length of the string.
//
if(pucBuffer[0] > outputBufferLength)
{
size = outputBufferLength - 2;
}
else
{
size = pucBuffer[0] - 2;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -