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

📄 plugplayfdo.cpp

📁 Programming the Microsoft Windows driver model.2nd 随书光盘。内有很多作者送的实用工具和随书源码。WDM编程
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// Plug and Play handlers for main device FDO in MULFUNC driver sample

// Copyright (C) 1999 by Walter Oney

// All rights reserved



#include "stddcls.h"

#include "driver.h"



static NTSTATUS DefaultPnpHandler(IN PDEVICE_OBJECT fdo, IN PIRP Irp);

static NTSTATUS HandleCancelRemove(IN PDEVICE_OBJECT fdo, IN PIRP Irp);

static NTSTATUS HandleCancelStop(IN PDEVICE_OBJECT fdo, IN PIRP Irp);

static NTSTATUS HandleQueryCapabilities(IN PDEVICE_OBJECT fdo, IN PIRP Irp);

static NTSTATUS HandleQueryRelations(PDEVICE_OBJECT fdo, PIRP Irp);

static NTSTATUS HandleQueryRemove(IN PDEVICE_OBJECT fdo, IN PIRP Irp);

static NTSTATUS HandleQueryStop(IN PDEVICE_OBJECT fdo, IN PIRP Irp);

static NTSTATUS HandleRemoveDevice(IN PDEVICE_OBJECT fdo, IN PIRP Irp);

static NTSTATUS HandleStartDevice(IN PDEVICE_OBJECT fdo, IN PIRP Irp);

static NTSTATUS HandleStopDevice(IN PDEVICE_OBJECT fdo, IN PIRP Irp);

static NTSTATUS HandleSurpriseRemoval(IN PDEVICE_OBJECT fdo, IN PIRP Irp);



static NTSTATUS StartDevice(PDEVICE_OBJECT fdo, PCM_PARTIAL_RESOURCE_LIST raw, PCM_PARTIAL_RESOURCE_LIST translated);

static VOID StopDevice(PDEVICE_OBJECT fdo, BOOLEAN oktouch);



#if DBG

static VOID ShowResources(IN PCM_PARTIAL_RESOURCE_LIST list);



static char* statenames[] = {

	"STOPPED",

	"WORKING",

	"PENDINGSTOP",

	"PENDINGREMOVE",

	"SURPRISEREMOVED",

	"REMOVED",

	};



#endif



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



#pragma PAGEDCODE



NTSTATUS DispatchPnpFdo(IN PDEVICE_OBJECT fdo, IN PIRP Irp)

	{							// DispatchPnpFdo

	PAGED_CODE();

	PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) fdo->DeviceExtension;

	NTSTATUS status = IoAcquireRemoveLock(&pdx->RemoveLock, Irp);

	if (!NT_SUCCESS(status))

		return CompleteRequest(Irp, status, 0);



	PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(Irp);

	ASSERT(stack->MajorFunction == IRP_MJ_PNP);



	static NTSTATUS (*fcntab[])(IN PDEVICE_OBJECT fdo, IN PIRP Irp) = {

		HandleStartDevice,		// IRP_MN_START_DEVICE

		HandleQueryRemove,		// IRP_MN_QUERY_REMOVE_DEVICE

		HandleRemoveDevice,		// IRP_MN_REMOVE_DEVICE

		HandleCancelRemove,		// IRP_MN_CANCEL_REMOVE_DEVICE

		HandleStopDevice,		// IRP_MN_STOP_DEVICE

		HandleQueryStop,		// IRP_MN_QUERY_STOP_DEVICE

		HandleCancelStop,		// IRP_MN_CANCEL_STOP_DEVICE

		HandleQueryRelations,	// IRP_MN_QUERY_DEVICE_RELATIONS

		DefaultPnpHandler,		// IRP_MN_QUERY_INTERFACE

		HandleQueryCapabilities,// IRP_MN_QUERY_CAPABILITIES

		DefaultPnpHandler,		// IRP_MN_QUERY_RESOURCES

		DefaultPnpHandler,		// IRP_MN_QUERY_RESOURCE_REQUIREMENTS

		DefaultPnpHandler,		// IRP_MN_QUERY_DEVICE_TEXT

		DefaultPnpHandler,		// IRP_MN_FILTER_RESOURCE_REQUIREMENTS

		DefaultPnpHandler,		// 

		DefaultPnpHandler,		// IRP_MN_READ_CONFIG

		DefaultPnpHandler,		// IRP_MN_WRITE_CONFIG

		DefaultPnpHandler,		// IRP_MN_EJECT

		DefaultPnpHandler,		// IRP_MN_SET_LOCK

		DefaultPnpHandler,		// IRP_MN_QUERY_ID

		DefaultPnpHandler,		// IRP_MN_QUERY_PNP_DEVICE_STATE

		DefaultPnpHandler,		// IRP_MN_QUERY_BUS_INFORMATION

		DefaultPnpHandler,		// IRP_MN_DEVICE_USAGE_NOTIFICATION

		HandleSurpriseRemoval,	// IRP_MN_SURPRISE_REMOVAL

		};



	ULONG fcn = stack->MinorFunction;

	if (fcn >= arraysize(fcntab))

		{						// unknown function

		status = DefaultPnpHandler(fdo, Irp); // some function we don't know about

		IoReleaseRemoveLock(&pdx->RemoveLock, Irp);

		return status;

		}						// unknown function



#if DBG

	static char* fcnname[] = {

		"IRP_MN_START_DEVICE",

		"IRP_MN_QUERY_REMOVE_DEVICE",

		"IRP_MN_REMOVE_DEVICE",

		"IRP_MN_CANCEL_REMOVE_DEVICE",

		"IRP_MN_STOP_DEVICE",

		"IRP_MN_QUERY_STOP_DEVICE",

		"IRP_MN_CANCEL_STOP_DEVICE",

		"IRP_MN_QUERY_DEVICE_RELATIONS",

		"IRP_MN_QUERY_INTERFACE",

		"IRP_MN_QUERY_CAPABILITIES",

		"IRP_MN_QUERY_RESOURCES",

		"IRP_MN_QUERY_RESOURCE_REQUIREMENTS",

		"IRP_MN_QUERY_DEVICE_TEXT",

		"IRP_MN_FILTER_RESOURCE_REQUIREMENTS",

		"",

		"IRP_MN_READ_CONFIG",

		"IRP_MN_WRITE_CONFIG",

		"IRP_MN_EJECT",

		"IRP_MN_SET_LOCK",

		"IRP_MN_QUERY_ID",

		"IRP_MN_QUERY_PNP_DEVICE_STATE",

		"IRP_MN_QUERY_BUS_INFORMATION",

		"IRP_MN_DEVICE_USAGE_NOTIFICATION",

		"IRP_MN_SURPRISE_REMOVAL",

		};



	KdPrint((DRIVERNAME " (FDO) - PNP Request (%s)\n", fcnname[fcn]));

#endif // DBG



	status = (*fcntab[fcn])(fdo, Irp);

	if (fcn != IRP_MN_REMOVE_DEVICE)

		IoReleaseRemoveLock(&pdx->RemoveLock, Irp);

	return status;

	}							// DispatchPnp



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



NTSTATUS CreateChild(PDEVICE_EXTENSION pdx, ULONG flags, PDEVICE_OBJECT* ppdo)

	{							// CreateChild

	NTSTATUS status;

	PDEVICE_OBJECT child;



	status = IoCreateDevice(pdx->DriverObject, sizeof(PDO_EXTENSION), NULL,

		FILE_DEVICE_UNKNOWN, FILE_AUTOGENERATED_DEVICE_NAME, FALSE, &child);

	if (!NT_SUCCESS(status))

		{

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

		return status;

		}



	PPDO_EXTENSION px = (PPDO_EXTENSION) child->DeviceExtension;

	px->flags = ISPDO | flags;

	px->DeviceObject = child;

	px->Fdo = pdx->DeviceObject;



	child->Flags &= ~DO_DEVICE_INITIALIZING;

	*ppdo = child;

	return STATUS_SUCCESS;

	}							// CreateChild



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

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



static NTSTATUS DefaultPnpHandler(IN PDEVICE_OBJECT fdo, IN PIRP Irp)

	{							// DefaultPnpHandler

	IoSkipCurrentIrpStackLocation(Irp);

	PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) fdo->DeviceExtension;

	return IoCallDriver(pdx->LowerDeviceObject, Irp);

	}							// DefaultPnpHandler



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



static NTSTATUS HandleCancelRemove(IN PDEVICE_OBJECT fdo, IN PIRP Irp)

	{							// HandleCancelRemove

	PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) fdo->DeviceExtension;

	if (pdx->state == PENDINGREMOVE)

		{						// we succeeded earlier query



		// Lower-level drivers are presumably in the pending-remove state as

		// well, so we need to tell them that the remove has been cancelled

		// before we start sending IRPs down to them.



		NTSTATUS status = ForwardAndWait(fdo, Irp); // wait for lower layers

		if (NT_SUCCESS(status))

			{					// completed successfully

			KdPrint((DRIVERNAME " - To %s from PENDINGREMOVE\n", statenames[pdx->prevstate]));

			if ((pdx->state = pdx->prevstate) == WORKING)

				{				// back to working state

				}				// back to working state

			}					// completed successfully

		else

			KdPrint((DRIVERNAME " - Status %8.8lX returned by PDO for IRP_MN_CANCEL_REMOVE_DEVICE", status));



		return CompleteRequest(Irp, status, Irp->IoStatus.Information);

		}						// we succeeded earlier query

	

	return DefaultPnpHandler(fdo, Irp); // unexpected cancel

	}							// HandleCancelRemove



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



static NTSTATUS HandleCancelStop(IN PDEVICE_OBJECT fdo, IN PIRP Irp)

	{							// HandleCancelStop

	PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) fdo->DeviceExtension;

	if (pdx->state == PENDINGSTOP)

		{						// we succeeded earlier query



		// Lower level drivers are presumably in the pending-stop state as

		// well, so we need to tell them that the stop has been cancelled

		// before we start sending IRPs down to them.



		NTSTATUS status = ForwardAndWait(fdo, Irp); // wait for lower layers

		if (NT_SUCCESS(status))

			{					// completed successfully

			KdPrint((DRIVERNAME " - To WORKING from PENDINGSTOP\n"));

			pdx->state = WORKING;

			}					// completed successfully

		else

			KdPrint((DRIVERNAME " - Status %8.8lX returned by PDO for IRP_MN_CANCEL_STOP_DEVICE", status));

		

		return CompleteRequest(Irp, status, Irp->IoStatus.Information);

		}						// we succeeded earlier query



	return DefaultPnpHandler(fdo, Irp); // unexpected cancel

	}							// HandleCancelStop



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



static NTSTATUS HandleQueryCapabilities(IN PDEVICE_OBJECT fdo, IN PIRP Irp)

	{							// HandleQueryCapabilities

	PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(Irp);

	PDEVICE_CAPABILITIES pdc = stack->Parameters.DeviceCapabilities.Capabilities;

	PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) fdo->DeviceExtension;



	// Check to be sure we know how to handle this version of the capabilities structure



	if (pdc->Version < 1)

		return DefaultPnpHandler(fdo, Irp);



	NTSTATUS status = ForwardAndWait(fdo, Irp);

	if (NT_SUCCESS(status))

		{						// IRP succeeded

		stack = IoGetCurrentIrpStackLocation(Irp);

		pdc = stack->Parameters.DeviceCapabilities.Capabilities;



		// TODO Modify any capabilities that must be set on the way back up



		pdx->devcaps = *pdc;	// save capabilities for whoever needs to see them

		}						// IRP succeeded



	return CompleteRequest(Irp, status, Irp->IoStatus.Information);

	}							// HandleQueryCapabilities



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



static NTSTATUS HandleQueryRelations(PDEVICE_OBJECT fdo, PIRP Irp)

	{							// HandleQueryRelations

	PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) fdo->DeviceExtension;

	PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(Irp);



	if (stack->Parameters.QueryDeviceRelations.Type != BusRelations)

		return DefaultPnpHandler(fdo, Irp);



	NTSTATUS status = STATUS_SUCCESS;



	PDEVICE_RELATIONS oldrel = (PDEVICE_RELATIONS) Irp->IoStatus.Information;

	PDEVICE_RELATIONS newrel;

	

	if (oldrel)

		{						// extend existing list

		ULONG size = sizeof(DEVICE_RELATIONS) + (oldrel->Count + 1) * sizeof(PDEVICE_OBJECT);

		newrel = (PDEVICE_RELATIONS) ExAllocatePool(PagedPool, size);

		if (newrel)

			{					// copy & extend

			RtlCopyMemory(newrel, oldrel, size -  2 * sizeof(PDEVICE_OBJECT));

			ExFreePool(oldrel);

			}					// copy & extend

		}						// extend existing list

	else

		{						// create new list

		newrel = (PDEVICE_RELATIONS) ExAllocatePool(PagedPool, sizeof(DEVICE_RELATIONS) + sizeof(PDEVICE_OBJECT));

		newrel->Count = 0;

		}						// create new list



	if (newrel)

		{						// build new list

		if (pdx->ChildA)

			{

			ObReferenceObject(pdx->ChildA);

			newrel->Objects[newrel->Count++] = pdx->ChildA;

			}

		

		if (pdx->ChildB)

			{

			ObReferenceObject(pdx->ChildB);

			newrel->Objects[newrel->Count++] = pdx->ChildB;

			}



		Irp->IoStatus.Information = (ULONG_PTR) newrel;

		}						// build new list

	else

		status = STATUS_INSUFFICIENT_RESOURCES;



	Irp->IoStatus.Status = status;

	return DefaultPnpHandler(fdo, Irp);

	}							// HandleQueryRelations



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



static NTSTATUS HandleQueryRemove(IN PDEVICE_OBJECT fdo, IN PIRP Irp)

	{							// HandleQueryRemove

	PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) fdo->DeviceExtension;

⌨️ 快捷键说明

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