testpnp.c
来自「usb开发」· C语言 代码 · 共 526 行 · 第 1/2 页
C
526 行
#include "TestInc.h"
NTSTATUS PnpHandleStartDevice(IN PDEVICE_OBJECT fdo,IN PIRP Irp);
NTSTATUS ForwardAndWait(IN PDEVICE_OBJECT fdo,IN PIRP Irp);
NTSTATUS ForwardIrpComplete(IN PDEVICE_OBJECT fdo,
IN PIRP Irp,
IN PKEVENT pev);
NTSTATUS UsbStartDevice(IN PDEVICE_OBJECT fdo);
NTSTATUS UsbConfigureDevice(IN PDEVICE_OBJECT fdo);
NTSTATUS UsbSelectInterfaces(IN PDEVICE_OBJECT fdo,
IN PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor,
IN PUSBD_INTERFACE_INFORMATION Interface);
NTSTATUS PnpHandleDefault(IN PDEVICE_OBJECT fdo,IN PIRP Irp);
NTSTATUS PnpHandleStopDevice(IN PDEVICE_OBJECT fdo);
NTSTATUS PnpHandleRemoveDevice(IN PDEVICE_OBJECT fdo,IN PIRP Irp);
NTSTATUS UsbRemoveDevice(IN PDEVICE_OBJECT fdo);
//
NTSTATUS TestAddDevice(IN PDRIVER_OBJECT DriverObject,
IN PDEVICE_OBJECT PhysicalDeviceObject)
{
NTSTATUS ntStatus = STATUS_SUCCESS;
WCHAR KernelName_u[] = L"\\Device\\ghjusb";
UNICODE_STRING KernelName_us;
WCHAR SymLinkName_u[] = L"\\??\\ghjusb";
UNICODE_STRING SymLinkName_us;
PDEVICE_OBJECT fdo = NULL;
PDEVICE_EXTENSION pdx;
RtlInitUnicodeString (&KernelName_us,
KernelName_u);
ntStatus = IoCreateDevice (DriverObject,
sizeof (DEVICE_EXTENSION),
&KernelName_us,
FILE_DEVICE_UNKNOWN,
0,
FALSE,
&fdo);
if( !NT_SUCCESS(ntStatus))
return ntStatus;
RtlInitUnicodeString (&SymLinkName_us,
SymLinkName_u);
ntStatus = IoCreateSymbolicLink (&SymLinkName_us,
&KernelName_us);
pdx = (PDEVICE_EXTENSION) (fdo->DeviceExtension);
RtlCopyMemory(pdx->DeviceLinkName,SymLinkName_u,sizeof(SymLinkName_u));
pdx->OpenHandles = 0;
pdx->ConfigurationHandle = NULL;
pdx->DeviceDescriptor = NULL;
pdx->Interface = NULL;
pdx->PhysicalDeviceObject=PhysicalDeviceObject;
pdx->LowerDeviceObject =
IoAttachDeviceToDeviceStack(fdo, PhysicalDeviceObject);
pdx->Usages = 1;
fdo->Flags &= ~DO_DEVICE_INITIALIZING;
fdo->Flags |= DO_BUFFERED_IO;
KeInitializeEvent(&pdx->evRemove,
NotificationEvent,
FALSE);
DbgPrint("AddDevice Called");
return ntStatus;
}
//
NTSTATUS TestPnpIrp(IN PDEVICE_OBJECT fdo, IN PIRP Irp)
{
NTSTATUS ntStatus=STATUS_SUCCESS;
PIO_STACK_LOCATION IrpStack;
PDEVICE_EXTENSION pdx = fdo->DeviceExtension;
ULONG MinorFunction;
if (!LockDevice(fdo))
return CompleteRequest(Irp, STATUS_DELETE_PENDING, 0);
IrpStack = IoGetCurrentIrpStackLocation (Irp);
MinorFunction = IrpStack->MinorFunction;
switch (MinorFunction)
{
case IRP_MN_START_DEVICE:
ntStatus = PnpHandleStartDevice(fdo,Irp);
DbgPrint("start Called");
break;
case IRP_MN_STOP_DEVICE:
PnpHandleDefault(fdo,Irp);
ntStatus = PnpHandleStopDevice(fdo);
DbgPrint("stop Called");
break;
case IRP_MN_REMOVE_DEVICE:
ntStatus = PnpHandleRemoveDevice(fdo,Irp);
DbgPrint("remove Called");
break;
case IRP_MN_QUERY_CAPABILITIES:
{
PDEVICE_CAPABILITIES pdc = IrpStack->Parameters.DeviceCapabilities.Capabilities;
if (pdc->Version < 1) {
ntStatus = PnpHandleDefault(fdo, Irp);
break;
}
ntStatus = ForwardAndWait(fdo, Irp);
if (NT_SUCCESS(ntStatus)) {
pdc = IrpStack->Parameters.DeviceCapabilities.Capabilities;
pdc->SurpriseRemovalOK = TRUE;
}
ntStatus = CompleteRequest(Irp, ntStatus, Irp->IoStatus.Information);
}
break;
default:
ntStatus = PnpHandleDefault(fdo, Irp);
}
if (MinorFunction != IRP_MN_REMOVE_DEVICE)
UnlockDevice(fdo);
return ntStatus;
}
BOOLEAN LockDevice(IN PDEVICE_OBJECT fdo)
{
PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) fdo->DeviceExtension;
LONG usage = InterlockedIncrement(&pdx->Usages);
if (pdx->Removing) {
if (InterlockedDecrement(&pdx->Usages) == 0)
KeSetEvent(&pdx->evRemove, 0, FALSE);
return FALSE;
}
return TRUE;
}
//
void UnlockDevice(PDEVICE_OBJECT fdo)
{
PDEVICE_EXTENSION pdx;
LONG usage;
pdx = (PDEVICE_EXTENSION) fdo->DeviceExtension;
usage = InterlockedDecrement(&pdx->Usages);
if (usage == 0) {
KeSetEvent(&pdx->evRemove, 0, FALSE);
}
}
//
NTSTATUS CompleteRequest(IN PIRP Irp,
IN NTSTATUS status,
IN ULONG info)
{
Irp->IoStatus.Status = status;
Irp->IoStatus.Information = info;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return status;
}
//
NTSTATUS PnpHandleStartDevice(IN PDEVICE_OBJECT fdo,IN PIRP Irp)
{
NTSTATUS ntStatus;
ntStatus = ForwardAndWait(fdo, Irp);
if (!NT_SUCCESS(ntStatus))
return CompleteRequest(Irp, ntStatus, Irp->IoStatus.Information);
ntStatus = UsbStartDevice(fdo);
return CompleteRequest(Irp, ntStatus, 0);
}
NTSTATUS ForwardAndWait(IN PDEVICE_OBJECT fdo,IN PIRP Irp)
{
NTSTATUS ntStatus;
PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) fdo->DeviceExtension;
KEVENT event;
KeInitializeEvent(&event, NotificationEvent, FALSE);
IoCopyCurrentIrpStackLocationToNext(Irp);
IoSetCompletionRoutine(Irp, (PIO_COMPLETION_ROUTINE)ForwardIrpComplete,
(PVOID) &event, TRUE, TRUE, TRUE);
ntStatus = IoCallDriver(pdx->LowerDeviceObject, Irp);
if (ntStatus == STATUS_PENDING) {
KeWaitForSingleObject(&event, Executive, KernelMode, FALSE, NULL);
ntStatus = Irp->IoStatus.Status;
}
return ntStatus;
}
//
NTSTATUS ForwardIrpComplete(IN PDEVICE_OBJECT fdo,
IN PIRP Irp,
IN PKEVENT pev)
{
KeSetEvent(pev, 0, FALSE);
return STATUS_MORE_PROCESSING_REQUIRED;
}
//
NTSTATUS UsbStartDevice(IN PDEVICE_OBJECT fdo)
{
NTSTATUS ntStatus;
PDEVICE_EXTENSION pdx;
PUSB_DEVICE_DESCRIPTOR deviceDescriptor = NULL;
PURB urb;
USHORT SizeUrb;
ULONG SizeDescriptor;
pdx = fdo->DeviceExtension;
SizeUrb=sizeof(struct _URB_CONTROL_DESCRIPTOR_REQUEST);
urb = ExAllocatePool( NonPagedPool,SizeUrb);
if (urb==NULL) return STATUS_NO_MEMORY;
SizeDescriptor = sizeof(USB_DEVICE_DESCRIPTOR);
deviceDescriptor = ExAllocatePool(NonPagedPool,SizeDescriptor);
if (deviceDescriptor==NULL) {
ExFreePool(urb);
return STATUS_NO_MEMORY;
}
UsbBuildGetDescriptorRequest(urb,
SizeUrb,
USB_DEVICE_DESCRIPTOR_TYPE,
0,
0,
deviceDescriptor,
NULL,
SizeDescriptor,
NULL);
ntStatus = CallUSBDI(fdo, urb);
if (NT_SUCCESS(ntStatus)) {
pdx->DeviceDescriptor = deviceDescriptor;
pdx->Stop = FALSE;
}
else {
ExFreePool(deviceDescriptor);
pdx->DeviceDescriptor = NULL;
}
ExFreePool(urb);
if (NT_SUCCESS(ntStatus)) {
ntStatus = UsbConfigureDevice(fdo);
}
return ntStatus;
}
//调用USB总线驱动程序的接口.
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?