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(); 
}