?? d12.c
字號:
// Yes,
// just pass it on
IoCopyCurrentIrpStackLocationToNext(Irp);
PoStartNextPowerIrp(Irp);
ntStatus = PoCallDriver(deviceExtension->TopOfStackDeviceObject,
Irp);
D12_DecrementIoCount(DeviceObject);
}
}
break;
case DevicePowerState:
ntStatus = D12_SetDevicePowerState(DeviceObject,
irpStack->Parameters.Power.State.DeviceState,
&hookIt);
IoCopyCurrentIrpStackLocationToNext(Irp);
if (hookIt) {
D12_KdPrint(("D12TEST.SYS: Set PowerIrp Completion Routine\n"));
IoSetCompletionRoutine(Irp,
D12_PowerIrp_Complete,
// always pass FDO to completion routine
DeviceObject,
hookIt,
hookIt,
hookIt);
}
PoStartNextPowerIrp(Irp);
ntStatus = PoCallDriver(deviceExtension->TopOfStackDeviceObject,
Irp);
D12_DecrementIoCount(DeviceObject);
break;
} /* case irpStack->Parameters.Power.Type */
}
break; /* IRP_MN_SET_POWER */
case IRP_MN_QUERY_POWER:
D12_KdPrint(("D12TEST.SYS: IRP_MN_QUERY_POWER\n"));
IoCopyCurrentIrpStackLocationToNext(Irp);
PoStartNextPowerIrp(Irp);
ntStatus = PoCallDriver(deviceExtension->TopOfStackDeviceObject,
Irp);
D12_DecrementIoCount(DeviceObject);
break; /* IRP_MN_QUERY_POWER */
default:
D12_KdPrint(("D12TEST.SYS: UNKNOWN POWER MESSAGE (%x)\n", irpStack->MinorFunction));
//
// All unahndled PnP messages are passed on to the PDO
//
IoCopyCurrentIrpStackLocationToNext(Irp);
//
// All PNP_POWER POWER messages get passed to
// TopOfStackDeviceObject and some are handled in the completion routine
//
// pass on to our PDO
PoStartNextPowerIrp(Irp);
ntStatus = PoCallDriver(deviceExtension->TopOfStackDeviceObject,
Irp);
D12_DecrementIoCount(DeviceObject);
} /* irpStack->MinorFunction */
return ntStatus;
}
NTSTATUS
D12_Dispatch(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
/*++
Routine Description:
Process the IRPs sent to this device.
Arguments:
DeviceObject - pointer to a device object
Irp - pointer to an I/O Request Packet
Return Value:
--*/
{
PIO_STACK_LOCATION irpStack;
PDEVICE_EXTENSION deviceExtension;
NTSTATUS ntStatus = STATUS_SUCCESS;
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;
D12_IncrementIoCount(DeviceObject);
switch (irpStack->MajorFunction) {
case IRP_MJ_SYSTEM_CONTROL:
D12_KdPrint (("D12TEST.SYS: IRP_MJ_SYSTEM_CONTROL\n"));
IoCopyCurrentIrpStackLocationToNext(Irp);
D12_KdPrint (("D12TEST.SYS: Passing SysCtrl Irp down\n"));
D12_DecrementIoCount(DeviceObject);
ntStatus = IoCallDriver(stackDeviceObject,
Irp);
goto D12_Dispatch_Done;
break;
case IRP_MJ_PNP:
D12_KdPrint (("D12TEST.SYS: IRP_MJ_PNP\n"));
switch (irpStack->MinorFunction) {
case IRP_MN_START_DEVICE:
{
KEVENT event;
D12_KdPrint (("D12TEST.SYS: IRP_MN_START_DEVICE\n"));
KeInitializeEvent(&event, NotificationEvent, FALSE);
IoCopyCurrentIrpStackLocationToNext(Irp);
IoSetCompletionRoutine(Irp,
D12_DeferIrpCompletion,
&event,
TRUE,
TRUE,
TRUE);
ntStatus = IoCallDriver(stackDeviceObject,
Irp);
if (ntStatus == STATUS_PENDING) {
// wait for irp to complete
TRAP(); // first time we hit this
KeWaitForSingleObject(
&event,
Suspended,
KernelMode,
FALSE,
NULL);
}
ntStatus = D12_StartDevice(DeviceObject);
Irp->IoStatus.Status = ntStatus;
goto D12_Dispatch_CompleteRequest;
}
break;
case IRP_MN_STOP_DEVICE:
D12_KdPrint (("D12TEST.SYS: IRP_MN_STOP_DEVICE\n"));
ntStatus = D12_StopDevice(DeviceObject);
break;
case IRP_MN_REMOVE_DEVICE:
D12_KdPrint (("D12TEST.SYS: IRP_MN_REMOVE_DEVICE\n"));
// match the inc at the begining of the dispatch
// routine
D12_DecrementIoCount(DeviceObject);
//
// ounce this flag is set no irps will be pased
// down the stack to lower drivers
//
deviceExtension->AcceptingRequests = FALSE;
if (deviceExtension->UserEvent != NULL) {
KeSetEvent(deviceExtension->UserEvent,
1,
FALSE);
}
if (NT_SUCCESS(ntStatus)) {
LONG pendingIoCount;
IoCopyCurrentIrpStackLocationToNext(Irp);
ntStatus = IoCallDriver(stackDeviceObject,
Irp);
//
// final decrement will trigger the remove
//
pendingIoCount = D12_DecrementIoCount(DeviceObject);
{
NTSTATUS status;
// wait for any io request pending in our driver to
// complete for finishing the remove
status = KeWaitForSingleObject(
&deviceExtension->RemoveEvent,
Suspended,
KernelMode,
FALSE,
NULL);
// TRAP();
}
//
// Delete the link and FDO we created
//
D12_RemoveDevice(DeviceObject);
D12_KdPrint (("D12TEST.SYS: Detaching from %08X\n",
deviceExtension->TopOfStackDeviceObject));
IoDetachDevice(deviceExtension->TopOfStackDeviceObject);
D12_KdPrint (("D12TEST.SYS: Deleting %08X\n",
DeviceObject));
IoDeleteDevice (DeviceObject);
goto D12_Dispatch_Done;
}
break;
case IRP_MN_QUERY_STOP_DEVICE:
D12_KdPrint (("D12TEST.SYS: IRP_MN_QUERY_STOP_DEVICE\n"));
break;
case IRP_MN_QUERY_REMOVE_DEVICE:
D12_KdPrint (("D12TEST.SYS: IRP_MN_QUERY_REMOVE_DEVICE\n"));
break;
case IRP_MN_CANCEL_STOP_DEVICE:
D12_KdPrint (("D12TEST.SYS: IRP_MN_CANCEL_STOP_DEVICE\n"));
break;
case IRP_MN_CANCEL_REMOVE_DEVICE:
D12_KdPrint (("D12TEST.SYS: IRP_MN_CANCEL_REMOVE_DEVICE\n"));
break;
default:
D12_KdPrint (("D12TEST.SYS: PnP IOCTL not handled\n"));
} /* case MinorFunction, MajorFunction == IRP_MJ_PNP_POWER */
if (!NT_SUCCESS(ntStatus)) {
Irp->IoStatus.Status = ntStatus;
goto D12_Dispatch_CompleteRequest;
}
IoCopyCurrentIrpStackLocationToNext(Irp);
//
// All PNP_POWER messages get passed to the TopOfStackDeviceObject
// we were given in PnPAddDevice
//
D12_KdPrint (("D12TEST.SYS: Passing PnP Irp down, status = %x\n", ntStatus));
ntStatus = IoCallDriver(stackDeviceObject,
Irp);
D12_DecrementIoCount(DeviceObject);
goto D12_Dispatch_Done;
break; // IRP_MJ_PNP
default:
D12_KdPrint (("D12TEST.SYS: MAJOR IOCTL not handled\n"));
Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
} /* case MajorFunction */
ntStatus = Irp->IoStatus.Status;
D12_Dispatch_CompleteRequest:
IoCompleteRequest (Irp,
IO_NO_INCREMENT
);
D12_DecrementIoCount(DeviceObject);
D12_Dispatch_Done:
D12_KdPrint (("D12TEST.SYS: Exit D12_Dispatch %x\n", ntStatus));
return ntStatus;
}
VOID
D12_Unload(
IN PDRIVER_OBJECT DriverObject
)
/*++
Routine Description:
Free all the allocated resources, etc.
Arguments:
DriverObject - pointer to a driver object
Return Value:
--*/
{
D12_KdPrint (("D12TEST.SYS: enter D12_Unload\n"));
//
// Free any global resources allocated
// in DriverEntry
//
D12_KdPrint (("D12TEST.SYS: exit D12_Unload\n"));
}
NTSTATUS
D12_StartDevice(
IN PDEVICE_OBJECT DeviceObject
)
/*++
Routine Description:
Initializes a given instance of the device on the USB.
All we do here is get the device descriptor and store it
Arguments:
DeviceObject - pointer to the device object for this instance of a
82930
Return Value:
NT status code
--*/
{
PDEVICE_EXTENSION deviceExtension;
NTSTATUS ntStatus;
PUSB_DEVICE_DESCRIPTOR deviceDescriptor = NULL;
PURB urb;
ULONG siz;
D12_KdPrint (("D12TEST.SYS: enter D12_StartDevice\n"));
deviceExtension = DeviceObject->DeviceExtension;
D12_ResetIrpQueue(DeviceObject);
urb = ExAllocatePool(NonPagedPool,
sizeof(struct _URB_CONTROL_DESCRIPTOR_REQUEST));
if (urb) {
siz = sizeof(USB_DEVICE_DESCRIPTOR);
deviceDescriptor = ExAllocatePool(NonPagedPool,
siz);
if (deviceDescriptor) {
UsbBuildGetDescriptorRequest(urb,
(USHORT) sizeof (struct _URB_CONTROL_DESCRIPTOR_REQUEST),
USB_DEVICE_DESCRIPTOR_TYPE,
0,
0,
deviceDescriptor,
NULL,
siz,
NULL);
ntStatus = D12_CallUSBD(DeviceObject, urb);
if (NT_SUCCESS(ntStatus)) {
D12_KdPrint (("D12TEST.SYS: Device Descriptor = %x, len %x\n",
deviceDescriptor,
urb->UrbControlDescriptorRequest.TransferBufferLength));
D12_KdPrint (("D12TEST.SYS: D12 Device Descriptor:\n"));
D12_KdPrint (("D12TEST.SYS: -------------------------\n"));
D12_KdPrint (("D12TEST.SYS: bLength %d\n", deviceDescriptor->bLength));
D12_KdPrint (("D12TEST.SYS: bDescriptorType 0x%x\n", deviceDescriptor->bDescriptorType));
D12_KdPrint (("D12TEST.SYS: bcdUSB 0x%x\n", deviceDescriptor->bcdUSB));
D12_KdPrint (("D12TEST.SYS: bDeviceClass 0x%x\n", deviceDescriptor->bDeviceClass));
D12_KdPrint (("D12TEST.SYS: bDeviceSubClass 0x%x\n", deviceDescriptor->bDeviceSubClass));
D12_KdPrint (("D12TEST.SYS: bDeviceProtocol 0x%x\n", deviceDescriptor->bDeviceProtocol));
D12_KdPrint (("D12TEST.SYS: bMaxPacketSize0 0x%x\n", deviceDescriptor->bMaxPacketSize0));
D12_KdPrint (("D12TEST.SYS: idVendor 0x%x\n", deviceDescriptor->idVendor));
D12_KdPrint (("D12TEST.SYS: idProduct 0x%x\n", deviceDescriptor->idProduct));
D12_KdPrint (("D12TEST.SYS: bcdDevice 0x%x\n", deviceDescriptor->bcdDevice));
D12_KdPrint (("D12TEST.SYS: iManufacturer 0x%x\n", deviceDescriptor->iManufacturer));
D12_KdPrint (("D12TEST.SYS: iProduct 0x%x\n", deviceDescriptor->iProduct));
D12_KdPrint (("D12TEST.SYS: iSerialNumber 0x%x\n", deviceDescriptor->iSerialNumber));
D12_KdPrint (("D12TEST.SYS: bNumConfigurations 0x%x\n", deviceDescriptor->bNumConfigurations));
}
} else {
ntStatus = STATUS_INSUFFICIENT_RESOURCES;
}
if (NT_SUCCESS(ntStatus)) {
deviceExtension->DeviceDescriptor = deviceDescriptor;
} else if (deviceDescriptor) {
ExFreePool(deviceDescriptor);
}
ExFreePool(urb);
} else {
ntStatus = STATUS_INSUFFICIENT_RESOURCES;
}
if (NT_SUCCESS(ntStatus)) {
ntStatus = D12_ConfigureDevice(DeviceObject);
}
if (NT_SUCCESS(ntStatus)) {
ntStatus = D12_BuildPipeList(DeviceObject);
}
D12_KdPrint (("D12TEST.SYS: exit D12_StartDevice (%x)\n", ntStatus));
return ntStatus;
}
NTSTATUS
D12_RemoveDevice(
IN PDEVICE_OBJECT DeviceObject
)
/*++
Routine Description:
Stops a given instance of a 82930 device on the USB.
Arguments:
DeviceObject - pointer to the device object for this instance of a 82930
Return Value:
NT status code
--*/
{
PDEVICE_EXTENSION deviceExtension;
NTSTATUS ntStatus = STATUS_SUCCESS;
UNICODE_STRING deviceLinkUnicodeString;
D12_KdPrint (("D12TEST.SYS: enter D12_RemoveDevice\n"));
deviceExtension = DeviceObject->DeviceExtension;
RtlInitUnicodeString (&deviceLinkUnicodeString,
deviceExtension->DeviceLinkNameBuffer);
// remove the GUID-based symbolic link
ntStatus = IoSetDeviceInterfaceState(&deviceLinkUnicodeString, FALSE);
//
// Free device descriptor structure
//
if (deviceExtension->DeviceDescriptor) {
ExFreePool(deviceExtension->DeviceDescriptor);
}
//
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -