www.pudn.com > WDM_PnPEvent.rar > PnPEventDevice.cpp
// PnPEventDevice.cpp // Implementation of PnPEventDevice device class // // Generated by DriverWizard version DriverStudio 2.6.0 (Build 336) // Requires Compuware's DriverWorks classes // #pragma warning(disable:4065) // Allow switch statement with no cases #include#include #include extern "C" NTKERNELAPI NTSTATUS IoReportTargetDeviceChangeAsynchronous( IN PDEVICE_OBJECT PhysicalDeviceObject, IN PVOID NotificationStructure, // always begins with a PLUGPLAY_NOTIFICATION_HEADER IN PDEVICE_CHANGE_COMPLETE_CALLBACK Callback OPTIONAL, IN PVOID Context OPTIONAL ); #include "..\PnPEventioctl.h" #include "..\PnPEventDeviceinterface.h" #include "PnPEvent.h" #include "PnPEventDevice.h" #pragma hdrstop("PnPEvent.pch") extern PDRIVER_OBJECT MyDriverObject; KIoWorkItem m_pItem; VOID TestWorkitem(PDEVICE_OBJECT DeviceObject, PVOID Context); // COMMENT_ONLY PVOID InterfaceNotificationEntry = NULL; PVOID FileNotificationEntry = NULL; PFILE_OBJECT TargetFileObject; UNICODE_STRING SymbolicLinkName; GUID TargetGuid=ReadWriteDevice_CLASS_GUID; NTSTATUS OnPnpNotify(PPLUGPLAY_NOTIFICATION_HEADER p,IN PVOID Context); GUID PnPEventDevice_Guid = PnPEventDevice_CLASS_GUID; PnPEventDevice::PnPEventDevice(PDEVICE_OBJECT Pdo, ULONG Unit) : KPnpDevice(Pdo, &PnPEventDevice_Guid) { // Check constructor status if ( ! NT_SUCCESS(m_ConstructorStatus) ) { return; } // Remember our unit number m_Unit = Unit; // Initialize the lower device m_Lower.Initialize(this, Pdo); // Inform the base class of the lower edge device object SetLowerDevice(&m_Lower); // Initialize the PnP Policy settings to the "standard" policy SetPnpPolicy(); m_pItem.Initialize(Pdo); IoRegisterPlugPlayNotification( EventCategoryDeviceInterfaceChange, PNPNOTIFY_DEVICE_INTERFACE_INCLUDE_EXISTING_INTERFACES, &TargetGuid, MyDriverObject, (PDRIVER_NOTIFICATION_CALLBACK_ROUTINE) OnPnpNotify, this, &InterfaceNotificationEntry); } PnPEventDevice::~PnPEventDevice() { if (FileNotificationEntry) { IoUnregisterPlugPlayNotification(FileNotificationEntry); FileNotificationEntry = NULL; ObDereferenceObject(TargetFileObject); TargetFileObject = NULL; } if (InterfaceNotificationEntry) { IoUnregisterPlugPlayNotification(InterfaceNotificationEntry); InterfaceNotificationEntry = NULL; } } NTSTATUS PnPEventDevice::DefaultPnp(KIrp I) { I.ForceReuseOfCurrentStackLocationInCalldown(); return m_Lower.PnpCall(this, I); } NTSTATUS PnPEventDevice::DefaultPower(KIrp I) { I.IndicatePowerIrpProcessed(); I.CopyParametersDown(); return m_Lower.PnpPowerCall(this, I); } NTSTATUS PnPEventDevice::SystemControl(KIrp I) { I.ForceReuseOfCurrentStackLocationInCalldown(); return m_Lower.PnpCall(this, I); } NTSTATUS PnPEventDevice::OnStartDevice(KIrp I) { return STATUS_SUCCESS; } NTSTATUS PnPEventDevice::OnStopDevice(KIrp I) { return STATUS_SUCCESS; } NTSTATUS PnPEventDevice::OnRemoveDevice(KIrp I) { return STATUS_SUCCESS; } NTSTATUS PnPEventDevice::Create(KIrp I) { return I.PnpComplete(this, STATUS_SUCCESS, IO_NO_INCREMENT); } NTSTATUS PnPEventDevice::Close(KIrp I) { return I.PnpComplete(this, STATUS_SUCCESS, IO_NO_INCREMENT); } NTSTATUS PnPEventDevice::DeviceControl(KIrp I) { NTSTATUS status; switch (I.IoctlCode()) { case PNPEVENT_IOCTL_800: TARGET_DEVICE_CUSTOM_NOTIFICATION notify; notify.Version = 1; notify.Size = sizeof(TARGET_DEVICE_CUSTOM_NOTIFICATION) + sizeof(ULONG) - sizeof(UCHAR); notify.Event = GUID_PNPEVENT_EVENT; notify.FileObject = NULL; notify.NameBufferOffset = 0; *((PULONG) (&(notify.CustomDataBuffer[0]))) = 0; status = IoReportTargetDeviceChangeAsynchronous(m_Lower.PDO(), ¬ify, NULL, NULL); if (NT_SUCCESS(status)) status = STATUS_SUCCESS; else status = STATUS_UNSUCCESSFUL; break; default: // Unrecognized IOCTL request status = STATUS_INVALID_PARAMETER; break; } return I.PnpComplete(this, status); } NTSTATUS OnPnpNotify(PPLUGPLAY_NOTIFICATION_HEADER p,IN PVOID Context) { // OnPnpNotify PDEVICE_INTERFACE_CHANGE_NOTIFICATION q=NULL; if (p->Event == GUID_DEVICE_INTERFACE_ARRIVAL) { DbgPrint("arrival\n"); q = (PDEVICE_INTERFACE_CHANGE_NOTIFICATION) p; SymbolicLinkName.MaximumLength = q->SymbolicLinkName->MaximumLength; SymbolicLinkName.Length = 0; SymbolicLinkName.Buffer = (PWSTR)ExAllocatePool( PagedPool, SymbolicLinkName.MaximumLength); if( SymbolicLinkName.Buffer!=NULL) { RtlCopyUnicodeString(&SymbolicLinkName,q->SymbolicLinkName); // queue the work item PnPEventDevice* m_pnp=(PnPEventDevice*)Context; m_pnp->IncrementOutstandingRequestCount(); m_pItem.Queue(TestWorkitem,Context); } } else if (p->Event == GUID_DEVICE_INTERFACE_REMOVAL) DbgPrint("removal\n"); else if (p->Event == GUID_TARGET_DEVICE_QUERY_REMOVE) { DbgPrint("target query remove\n"); if (FileNotificationEntry) { IoUnregisterPlugPlayNotification(FileNotificationEntry); FileNotificationEntry = NULL; ObDereferenceObject(TargetFileObject); TargetFileObject = NULL; } } else if (p->Event == GUID_TARGET_DEVICE_REMOVE_CANCELLED) DbgPrint("target remove cancelled\n"); else if (p->Event == GUID_TARGET_DEVICE_REMOVE_COMPLETE) DbgPrint("target remove complete\n"); else DbgPrint("custom notification"); return STATUS_SUCCESS; } VOID TestWorkitem(PDEVICE_OBJECT DeviceObject, PVOID Context) // COMMENT_ONLY { NTSTATUS status; DbgPrint("Entering Workitem\n"); PDEVICE_OBJECT junk; status = IoGetDeviceObjectPointer( &SymbolicLinkName, 0, &TargetFileObject, &junk); if (NT_SUCCESS(status)) { // register for notifications status = IoRegisterPlugPlayNotification( EventCategoryTargetDeviceChange, 0, TargetFileObject, MyDriverObject, (PDRIVER_NOTIFICATION_CALLBACK_ROUTINE) OnPnpNotify, NULL, &FileNotificationEntry); } if( SymbolicLinkName.Buffer!=NULL) ExFreePool(SymbolicLinkName.Buffer); PnPEventDevice* m_pnp=(PnPEventDevice*)Context; m_pnp->DecrementOutstandingRequestCount(); }