?? 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 <vdw.h>
#include <initguid.h>
#include <wdmguid.h>
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;
PVOID InterfaceNotificationEntry = NULL;
PVOID FileNotificationEntry = NULL;
PFILE_OBJECT TargetFileObject;
UNICODE_STRING SymbolicLinkName;
GUID TargetGuid=ReadWriteDevice_CLASS_GUID;
KIoWorkItem m_pItem;
NTSTATUS OnPnpNotify(PPLUGPLAY_NOTIFICATION_HEADER p,IN PVOID Context);
VOID Workitem(PDEVICE_OBJECT DeviceObject, 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);
//注冊內核模式接口通知,當ReadWrite實例的GUID接口被允許和禁止時,系統將
//調用OnPnpNotify回調例程
}
PnPEventDevice::~PnPEventDevice()
{
if (FileNotificationEntry)
{ //釋放文件句柄
ObDereferenceObject(TargetFileObject);
TargetFileObject = NULL;
//ObDereferenceObject與IoGetDeviceObjectPointer相對應,釋放文件句柄,
//否則系統卸載不掉ReadWrite
}
if (FileNotificationEntry)
{ //注銷句柄通知
IoUnregisterPlugPlayNotification(FileNotificationEntry);
FileNotificationEntry = 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)
{ //處理內核模式的接口和句柄通知
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);
//拷貝設備符號鏈接名
PnPEventDevice* m_pnp=(PnPEventDevice*)Context;
m_pnp->IncrementOutstandingRequestCount();
//增加未決IRP數目,在工作項完成之前,防止設備刪除
m_pItem.Queue(Workitem,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)
{
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");
IoUnregisterPlugPlayNotification(FileNotificationEntry);
FileNotificationEntry = NULL;
//注銷句柄通知
}
else
DbgPrint("custom notification");
return STATUS_SUCCESS;
}
VOID Workitem(PDEVICE_OBJECT DeviceObject, PVOID Context)
{
NTSTATUS status;
PDEVICE_OBJECT junk;
status = IoGetDeviceObjectPointer(
&SymbolicLinkName, 0, &TargetFileObject, &junk);
//根據設備符號鏈接名獲取其設備對象和文件對象指針
if (NT_SUCCESS(status))
{ // register for notifications
IoRegisterPlugPlayNotification(
EventCategoryTargetDeviceChange, 0,
TargetFileObject, MyDriverObject,
(PDRIVER_NOTIFICATION_CALLBACK_ROUTINE) OnPnpNotify,
NULL, &FileNotificationEntry);
}
//注冊內核模式句柄通知,當ReadWrite實例發生PnP事件時,系統將調用
//OnPnpNotify回調例程
if( SymbolicLinkName.Buffer!=NULL)
ExFreePool(SymbolicLinkName.Buffer); //釋放申請的內存
PnPEventDevice* m_pnp=(PnPEventDevice*)Context;
m_pnp->DecrementOutstandingRequestCount(); //減少未決IRP數目
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -