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

📄 control.cpp

📁 Programming the Microsoft Windows driver model.2nd 随书光盘。内有很多作者送的实用工具和随书源码。WDM编程
💻 CPP
字号:
// Control.cpp -- IOCTL handlers for evwait driver

// Copyright (C) 1999 by Walter Oney

// All rights reserved



#include "stddcls.h"

#include "driver.h"

#include "ioctls.h"



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



#pragma LOCKEDCODE				// locked because uses a spin lock



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



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

	// IOCTL_REGISTER_EVENT registers or deregisters an event object that the

	// driver shares with a user-mode application.



	case IOCTL_REGISTER_EVENT:				// code == 0x800

		{						// IOCTL_REGISTER_EVENT

		if (cbin < sizeof(HANDLE))

			{

			status = STATUS_INVALID_PARAMETER;

			break;

			}



		// If a new event is being registered, get a pointer to the underlying

		// KEVENT object. This must be done at PASSIVE_LEVEL. This function call is

		// really the main thing this sample illustrates, by the way. Note that the

		// only access we require to the event is EVENT_MODIFY_STATE, so that's all

		// we insist be present for this handle.



		HANDLE hevent = *(PHANDLE) Irp->AssociatedIrp.SystemBuffer;

		PKEVENT pevent;

		if (hevent)

			status = ObReferenceObjectByHandle(hevent, EVENT_MODIFY_STATE, *ExEventObjectType,

				Irp->RequestorMode, (PVOID*) &pevent, NULL);

		else

			pevent = NULL;



		if (!NT_SUCCESS(status))

			break;				// punt -- there's a problem with the handle



		// This driver only allows one handle to be open at a time, so we don't

		// need to worry about where to store the event pointers registered by

		// multiple applications. If you wanted to allow multiple opens and to

		// allow each handle owner to have its own event, you could use

		// stack->FileObject->FsContext or FsContext2 for that purpose, for example.

		//

		// Even though there can be just one handle, an application could use overlapped

		// I/O operations to issue several conflicting calls simultaneously. Hence the

		// use of a synchronization object to guard access to the "event" pointer. In

		// this particular driver, all access to the event pointer occurs at PASSIVE_LEVEL

		// and we could therefore use, e.g., a fast mutex. In general, though, you're going

		// to want to set the event from DISPATCH_LEVEL code. To make your life easier

		// if you're just cutting and pasting code, I therefore used a spin lock. Note

		// that this routine therefore has to be in the locked code segment.



		KIRQL oldirql;

		KeAcquireSpinLock(&pdx->eventlock, &oldirql);



		// First deregister any old event. Then remember the one we just located

		// or NULL.



		if (pdx->event)

			ObDereferenceObject(pdx->event);	// safe to call at <= DISPATCH_LEVEL

		pdx->event = pevent;



		// Now release the synchronization



		KeReleaseSpinLock(&pdx->eventlock, oldirql);

		break;

		}						// IOCTL_REGISTER_EVENT



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

	// IOCTL_SIGNAL_EVENT event signals the shared event. This particular IOCTL

	// is a hack so you can have a way to test the registration aspect of this sample.

	// In a real situation, there would be some hardware event that would trigger

	// the signalling operation.



	case IOCTL_SIGNAL_EVENT:				// code == 0x801

		{						// IOCTL_SIGNAL_EVENT



		// Synchronize access to the event pointer. In particular, we need to worry about

		// someone coming along and dereferencing the event pointer while we're doing

		// our thing here. You would need synchronization like this in a real driver,

		// where a hardware event triggers the signalling.



		KIRQL oldirql;

		KeAcquireSpinLock(&pdx->eventlock, &oldirql);



		if (pdx->event)

			KeSetEvent(pdx->event, EVENT_INCREMENT, FALSE);



		KeReleaseSpinLock(&pdx->eventlock, oldirql);



		break;

		}						// IOCTL_SIGNAL_EVENT



	default:

		status = STATUS_INVALID_DEVICE_REQUEST;

		break;



		}						// process request



	return CompleteRequest(Irp, status, info);

	}							// DispatchControl

⌨️ 快捷键说明

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