⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 control.cpp

📁 Programming the Microsoft Windows Driver Model(2nd)
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// Control.cpp -- IOCTL handlers for pnpmon driver

// Copyright (C) 1999 by Walter Oney

// All rights reserved



#include "stddcls.h"

#include <initguid.h>

#include <wdmguid.h>

#include "driver.h"

#include "ioctls.h"



NTSTATUS Register(PDEVICE_EXTENSION pdx, PREGISTER_PARAMS p);

NTSTATUS Deregister(PDEVICE_EXTENSION pdx, PUNREGISTER_PARAMS p);

VOID DeregisterAll(PDEVICE_EXTENSION pdx);

NTSTATUS OnPnpNotify(PPLUGPLAY_NOTIFICATION_HEADER p, PREG_RECORD reg);

VOID KillRegRecord(PREG_RECORD reg);

void SubscribeForTargetNotifications(PDEVICE_INTERFACE_CHANGE_NOTIFICATION q, PREG_RECORD reg);



typedef struct _SUBSCRIBE_CALLBACK_CONTEXT {

	PIO_WORKITEM item;

	PREG_RECORD reg;

	WCHAR name[1];

	} SUBSCRIBE_CALLBACK_CONTEXT, *PSUBSCRIBE_CALLBACK_CONTEXT;



void SubscribeCallback(PDEVICE_OBJECT DeviceObject, PSUBSCRIBE_CALLBACK_CONTEXT context);



///////////////////////////////////////////////////////////////////////////////



#pragma PAGEDCODE



NTSTATUS DispatchControl(PDEVICE_OBJECT fdo, PIRP Irp)

	{							// DispatchControl

	PAGED_CODE();

	PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) fdo->DeviceExtension;



	NTSTATUS status = STATUS_SUCCESS;

	ULONG info = 0;



	PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(Irp);

	ULONG cbin = stack->Parameters.DeviceIoControl.InputBufferLength;

	ULONG cbout = stack->Parameters.DeviceIoControl.OutputBufferLength;

	ULONG code = stack->Parameters.DeviceIoControl.IoControlCode;



	switch (code)

		{						// process request



	case IOCTL_REGISTER:				// code == 0x800

		{						// IOCTL_REGISTER

		if (cbin < sizeof(REGISTER_PARAMS))

			{

			status = STATUS_INVALID_PARAMETER;

			break;

			}

		status = Register(pdx, (REGISTER_PARAMS*) Irp->AssociatedIrp.SystemBuffer);

		break;

		}						// IOCTL_REGISTER



	case IOCTL_DEREGISTER:				// code == 0x801

		{						// IOCTL_DEREGISTER

		if (cbin < sizeof(UNREGISTER_PARAMS))

			{

			status = STATUS_INVALID_PARAMETER;

			break;

			}

		status = Deregister(pdx, (UNREGISTER_PARAMS*) Irp->AssociatedIrp.SystemBuffer);

		break;

		}						// IOCTL_DEREGISTER



	case IOCTL_GETEVENT:				// code == 0x802

		{						// IOCTL_GETEVENT

		if (cbout < sizeof(GETEVENT_PARAMS))

			{

			status = STATUS_INVALID_PARAMETER;

			break;

			}



		PLIST_ENTRY list = ExInterlockedRemoveHeadList(&pdx->events, &pdx->eventlock);

		if (!list)

			{

			status = STATUS_NO_MORE_ENTRIES;

			break;

			}



		PEVENT_RECORD evrec = CONTAINING_RECORD(list, EVENT_RECORD, ListEntry);

		*(PGETEVENT_PARAMS) Irp->AssociatedIrp.SystemBuffer = evrec->params;

		info = sizeof(GETEVENT_PARAMS);

		ExFreePool(evrec);

		break;

		}						// IOCTL_GETEVENT



	default:

		status = STATUS_INVALID_DEVICE_REQUEST;

		break;



		}						// process request



	return CompleteRequest(Irp, status, info);

	}							// DispatchControl



///////////////////////////////////////////////////////////////////////////////



#pragma PAGEDCODE



NTSTATUS DispatchCreate(PDEVICE_OBJECT fdo, PIRP Irp)

	{							// DispatchCreate

	PAGED_CODE();

	KdPrint((DRIVERNAME " - "

		"IRP_MJ_CREATE\n"));

	PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) fdo->DeviceExtension;



	PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(Irp);

	

	NTSTATUS status = STATUS_SUCCESS;

	if (InterlockedIncrement(&pdx->handles) > 1)

		{						// too many opens

		InterlockedDecrement(&pdx->handles);

		status = STATUS_ACCESS_DENIED;

		}						// too many opens



	return CompleteRequest(Irp, status, 0);

	}							// DispatchCreate



///////////////////////////////////////////////////////////////////////////////



#pragma PAGEDCODE



NTSTATUS DispatchClose(PDEVICE_OBJECT fdo, PIRP Irp)

	{							// DispatchClose

	PAGED_CODE();

	KdPrint((DRIVERNAME " - "

		"IRP_MJ_CLOSE\n"));

	PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) fdo->DeviceExtension;

	DeregisterAll(pdx);

	InterlockedDecrement(&pdx->handles);

	return CompleteRequest(Irp, STATUS_SUCCESS, 0);

	}							// DispatchClose



///////////////////////////////////////////////////////////////////////////////



#pragma PAGEDCODE



NTSTATUS Register(PDEVICE_EXTENSION pdx, PREGISTER_PARAMS p)

	{							// Register

	NTSTATUS status;



	// Get a pointer to the event object we will set when notifications about

	// the specified GUID occur

	

	PKEVENT event;

	status = ObReferenceObjectByHandle(p->hevent, EVENT_MODIFY_STATE, *ExEventObjectType,

		KernelMode, (PVOID*) &event, NULL);



	if (!NT_SUCCESS(status))

		{

		KdPrint((DRIVERNAME " - ObReferenceObjectByHandle failed - %X\n", status));

		return status;

		}



	// Create an event registration structure



	PREG_RECORD reg = (PREG_RECORD) ExAllocatePool(NonPagedPool, sizeof(REG_RECORD));



	if (!reg)

		{

		KdPrint((DRIVERNAME " - unable to allocate %d bytes for registration record\n", sizeof(REG_RECORD)));

		ObDereferenceObject(event);

		return STATUS_INSUFFICIENT_RESOURCES;

		}



	RtlZeroMemory(reg, sizeof(REG_RECORD));

	reg->Event = event;

	reg->Guid = p->guid;

	reg->DeviceExtension = pdx;



	// Register for PnP notifications



	status = IoRegisterPlugPlayNotification(EventCategoryDeviceInterfaceChange,

		PNPNOTIFY_DEVICE_INTERFACE_INCLUDE_EXISTING_INTERFACES,

		&p->guid, pdx->DriverObject,

		(PDRIVER_NOTIFICATION_CALLBACK_ROUTINE) OnPnpNotify, reg, &reg->InterfaceNotificationEntry);

	

	if (!NT_SUCCESS(status))

		{

		KdPrint((DRIVERNAME " - IoRegisterPlugPlayNotification failed - %X\n", status));

		ObDereferenceObject(event);

		ExFreePool(reg);

		return status;

		}



	// Put the registration record onto our list



	InsertTailList(&pdx->registered, &reg->ListEntry);

	return STATUS_SUCCESS;

	}							// Register



///////////////////////////////////////////////////////////////////////////////



#pragma PAGEDCODE



NTSTATUS Deregister(PDEVICE_EXTENSION pdx, PUNREGISTER_PARAMS p)

	{							// Deregister

	PLIST_ENTRY list;

	NTSTATUS status = STATUS_SUCCESS;



	for (list = pdx->registered.Flink; list != &pdx->registered; )

		{						// for each list element

		PLIST_ENTRY next = list->Flink;

		PREG_RECORD reg = CONTAINING_RECORD(list, REG_RECORD, ListEntry);

		if (reg->Guid == p->guid)

			{					// found a registration record

			RemoveEntryList(list);

			KillRegRecord(reg);

			break;

			}					// found a registration record

		list = next;

		}						// for each list element



	return status;

	}							// Deregister



///////////////////////////////////////////////////////////////////////////////



#pragma PAGEDCODE



VOID DeregisterAll(PDEVICE_EXTENSION pdx)

	{							// DeregisterAll

	while (!IsListEmpty(&pdx->registered))

		{						// deregister all notifications

		PLIST_ENTRY next = RemoveHeadList(&pdx->registered);

		PREG_RECORD reg = CONTAINING_RECORD(next, REG_RECORD, ListEntry);

		KillRegRecord(reg);

		}						// deregister all notifications

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -