📄 usb.c
字号:
#include "wdm.h"
#include "stdarg.h"
#include "stdio.h"
#define DRIVER
#include "usbdi.h"
#include "usbdlib.h"
#include "Usb.h"
//int gDebugLevel = DBGLVL_DEFAULT ;
int gExAllocCount =0;
#if DBG
USB_DBGDATA gDbgBuf = { 0, 0, 0, 0 };
PUSB_DBGDATA gpDbg = &gDbgBuf;
#endif
/*
PVOID
USB_ExAllocatePool(
IN POOL_TYPE PoolType,
IN ULONG NumberOfBytes
)
{
gExAllocCount++;
USB_KdPrint( DBGLVL_HIGH,("USB_ExAllocatePool() gExAllocCount = dec %d\n", gExAllocCount ));
return ExAllocatePool( PoolType, NumberOfBytes );
}
*/
VOID
USB_ExFreePool(
IN PVOID p
)
{
gExAllocCount--;
USB_KdPrint( DBGLVL_HIGH,("USB_ExFreePool() gExAllocCount = dec %d\n", gExAllocCount ));
ExFreePool( p );
}
NTSTATUS
DriverEntry(
IN PDRIVER_OBJECT DriverObject,
IN PUNICODE_STRING RegistryPath
)
{
NTSTATUS ntStatus = STATUS_SUCCESS;
PDEVICE_OBJECT deviceObject = NULL;
BOOLEAN fRes;
USB_KdPrint( DBGLVL_MINIMUM ,("Entering DriverEntry(), RegistryPath=\n %ws\n", RegistryPath->Buffer ));
DriverObject->DriverExtension->AddDevice = USB_PnPAddDevice;
DriverObject->MajorFunction[IRP_MJ_CREATE] = USB_Create;
DriverObject->MajorFunction[IRP_MJ_CLOSE] = USB_Close;
DriverObject->DriverUnload = USB_Unload;
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = USB_ProcessIOCTL;
DriverObject->MajorFunction[IRP_MJ_WRITE] = USB_Write;
DriverObject->MajorFunction[IRP_MJ_READ] = USB_Read;
DriverObject->MajorFunction[IRP_MJ_SYSTEM_CONTROL] = USB_ProcessSysControlIrp;
DriverObject->MajorFunction[IRP_MJ_PNP] = USB_ProcessPnPIrp;
DriverObject->MajorFunction[IRP_MJ_POWER] = USB_ProcessPowerIrp;
USB_KdPrint( DBGLVL_DEFAULT,("exiting DriverEntry (%x)\n", ntStatus));
return ntStatus;
}
NTSTATUS
USB_ProcessSysControlIrp(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
{
PIO_STACK_LOCATION irpStack;
PDEVICE_EXTENSION deviceExtension;
NTSTATUS ntStatus = STATUS_SUCCESS;
NTSTATUS waitStatus;
PDEVICE_OBJECT stackDeviceObject;
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = 0;
//
// Get a pointer to the current location in the Irp. This is where
// the function codes and parameters are located.
//
irpStack = IoGetCurrentIrpStackLocation (Irp);
//
// Get a pointer to the device extension
//
deviceExtension = DeviceObject->DeviceExtension;
stackDeviceObject = deviceExtension->TopOfStackDeviceObject;
USB_KdPrint( DBGLVL_HIGH, ( "enter USB_ProcessSysControlIrp()\n") );
USB_IncrementIoCount(DeviceObject);
USB_ASSERT( IRP_MJ_SYSTEM_CONTROL == irpStack->MajorFunction );
IoCopyCurrentIrpStackLocationToNext(Irp);
ntStatus = IoCallDriver(stackDeviceObject,
Irp);
USB_DecrementIoCount(DeviceObject);
USB_KdPrint( DBGLVL_HIGH,("USB_ProcessSysControlIrp() Exit USB_ProcessSysControlIrp %x\n", ntStatus));
return ntStatus;
}
VOID
USB_Unload(
IN PDRIVER_OBJECT DriverObject
)
{
USB_KdPrint( DBGLVL_HIGH,("enter USB_Unload\n"));
USB_ASSERT( gExAllocCount == 0 );
USB_KdPrint( DBGLVL_DEFAULT,("exit USB_Unload\n"));
}
NTSTATUS
USB_SymbolicLink(
IN PDEVICE_OBJECT DeviceObject,
IN OUT PUNICODE_STRING deviceLinkUnicodeString
)
{
NTSTATUS ntStatus = STATUS_SUCCESS;
// Create the symbolic link
// IoRegisterDeviceInterface registers device functionality (a device interface)
// that a driver will enable for use by applications or other system components.
ntStatus = IoRegisterDeviceInterface(
DeviceObject,
(LPGUID)&GUID_CLASS_I68001_BULK,
NULL,
deviceLinkUnicodeString);
USB_KdPrintCond( DBGLVL_MEDIUM, (!(NT_SUCCESS(ntStatus))),
("FAILED to IoRegisterDeviceInterface()\n"));
if (NT_SUCCESS(ntStatus)) {
// IoSetDeviceInterfaceState enables or disables a previously
// registered device interface. Applications and other system components
// can open only interfaces that are enabled.
ntStatus = IoSetDeviceInterfaceState(deviceLinkUnicodeString, TRUE);
USB_KdPrintCond( DBGLVL_MEDIUM,
(!(NT_SUCCESS(ntStatus))),
("FAILED to IoSetDeviceInterfaceState()\n"));
USB_KdPrintCond( DBGLVL_MEDIUM,
((NT_SUCCESS(ntStatus))),
("SUCCEEDED IoSetDeviceInterfaceState()\n"));
}
return ntStatus;
}
NTSTATUS
USB_CreateDeviceObject(
IN PDRIVER_OBJECT DriverObject,
IN PDEVICE_OBJECT PhysicalDeviceObject,
IN PDEVICE_OBJECT *DeviceObject
)
{
NTSTATUS ntStatus;
UNICODE_STRING deviceLinkUnicodeString;
PDEVICE_EXTENSION deviceExtension;
USHORT i;
USB_KdPrint( DBGLVL_DEFAULT,("enter USB_CreateDeviceObject() \n"));
ntStatus = USB_SymbolicLink( PhysicalDeviceObject, &deviceLinkUnicodeString );
USB_KdPrintCond( DBGLVL_DEFAULT,
(NT_SUCCESS(ntStatus)),
("USB_CreateDeviceObject() SUCCESS Create GUID_CLASS_USB_BULK-based Device name\n %ws\n Length decimal %d, MaximumLength decimal %d\n",
deviceLinkUnicodeString.Buffer,
deviceLinkUnicodeString.Length,
deviceLinkUnicodeString.MaximumLength));
USB_KdPrintCond( DBGLVL_DEFAULT,
(!(NT_SUCCESS(ntStatus))),
("USB_CreateDeviceObject() FAILED to Create GUID_CLASS_USB_BULK-based Device name\n"));
if (NT_SUCCESS(ntStatus)) {
ntStatus = IoCreateDevice (DriverObject,
sizeof (DEVICE_EXTENSION),
NULL,
FILE_DEVICE_UNKNOWN,
FILE_AUTOGENERATED_DEVICE_NAME,
FALSE,
DeviceObject);
if (NT_SUCCESS(ntStatus)) {
deviceExtension = (PDEVICE_EXTENSION) ((*DeviceObject)->DeviceExtension);
}
USB_KdPrintCond( DBGLVL_DEFAULT,
(!(NT_SUCCESS(ntStatus))),
("USB_CreateDeviceObject() IoCreateDevice() FAILED\n"));
if (!NT_SUCCESS(ntStatus)) {
return ntStatus;
}
deviceExtension->MaximumTransferSize = USB_MAX_TRANSFER_SIZE ;
RtlCopyMemory(deviceExtension->DeviceLinkNameBuffer,
deviceLinkUnicodeString.Buffer,
deviceLinkUnicodeString.Length);
KeInitializeEvent(&deviceExtension->RemoveEvent, NotificationEvent, FALSE);
KeInitializeEvent(&deviceExtension->SelfRequestedPowerIrpEvent, NotificationEvent, FALSE);
KeInitializeEvent(&deviceExtension->StagingDoneEvent, NotificationEvent, FALSE);
KeInitializeEvent(&deviceExtension->NoPendingIoEvent, NotificationEvent, FALSE);
KeInitializeSpinLock (&deviceExtension->IoCountSpinLock);
KeInitializeSpinLock(&deviceExtension->FastCompleteSpinlock);
RtlFreeUnicodeString( &deviceLinkUnicodeString );
}
return ntStatus;
}
NTSTATUS
USB_CallUSBD(
IN PDEVICE_OBJECT DeviceObject,
IN PURB Urb
)
{
NTSTATUS ntStatus, status = STATUS_SUCCESS;
PDEVICE_EXTENSION deviceExtension;
PIRP irp;
KEVENT event;
IO_STATUS_BLOCK ioStatus;
PIO_STACK_LOCATION nextStack;
USB_KdPrint( DBGLVL_MAXIMUM,("enter USB_CallUSBD\n"));
deviceExtension = DeviceObject->DeviceExtension;
//
// issue a synchronous request
//
KeInitializeEvent(&event, NotificationEvent, FALSE);
irp = IoBuildDeviceIoControlRequest(
IOCTL_INTERNAL_USB_SUBMIT_URB,
deviceExtension->TopOfStackDeviceObject, //Points to the next-lower driver's device object
NULL, // optional input bufer; none needed here
0, // input buffer len if used
NULL, // optional output bufer; none needed here
0, // output buffer len if used
TRUE, // If InternalDeviceControl is TRUE the target driver's Dispatch
// outine for IRP_MJ_INTERNAL_DEVICE_CONTROL or IRP_MJ_SCSI
// is called; otherwise, the Dispatch routine for
// IRP_MJ_DEVICE_CONTROL is called.
&event, // event to be signalled on completion
&ioStatus); // Specifies an I/O status block to be set when the request is completed the lower driver.
//
// As an alternative, we could call KeDelayExecutionThread, wait for some
// period of time, and try again....but we keep it simple for right now
//
if (!irp) {
return STATUS_INSUFFICIENT_RESOURCES;
}
//
// Call the class driver to perform the operation. If the returned status
// is PENDING, wait for the request to complete.
//
nextStack = IoGetNextIrpStackLocation(irp);
USB_ASSERT(nextStack != NULL);
//
// pass the URB to the USB driver stack
//
nextStack->Parameters.Others.Argument1 = Urb;
ntStatus = IoCallDriver(deviceExtension->TopOfStackDeviceObject, irp);
USB_KdPrint( DBGLVL_MAXIMUM,("USB_CallUSBD() return from IoCallDriver USBD %x\n", ntStatus));
if (ntStatus == STATUS_PENDING) {
status = KeWaitForSingleObject(
&event,
Suspended,
KernelMode,
FALSE,
NULL);
} else {
ioStatus.Status = ntStatus;
}
USB_KdPrint( DBGLVL_MAXIMUM,("USB_CallUSBD() URB status = %x status = %x irp status %x\n",
Urb->UrbHeader.Status, status, ioStatus.Status));
//
// USBD maps the error code for us
//
ntStatus = ioStatus.Status;
USB_KdPrintCond( DBGLVL_MAXIMUM, !NT_SUCCESS( ntStatus ), ("exit USB_CallUSBD FAILED (%x)\n", ntStatus));
return ntStatus;
}
NTSTATUS
USB_ConfigureDevice(
IN PDEVICE_OBJECT DeviceObject
)
{
PDEVICE_EXTENSION deviceExtension;
NTSTATUS ntStatus;
PURB urb;
ULONG siz;
USB_KdPrint( DBGLVL_DEFAULT,("enter USB_ConfigureDevice\n"));
deviceExtension = DeviceObject->DeviceExtension;
USB_ASSERT( deviceExtension->UsbConfigurationDescriptor == NULL );
urb = USB_ExAllocatePool(NonPagedPool,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -