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

📄 plugplaypdo.cpp

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

// Copyright (C) 1999 by Walter Oney

// All rights reserved



#include "stddcls.h"

#include "driver.h"

#include <initguid.h>

#include "suballoc.h"



static NTSTATUS HandleQueryId(PDEVICE_OBJECT pdo, PIRP Irp);

static NTSTATUS HandleQueryInterface(PDEVICE_OBJECT pdo, PIRP Irp);

static NTSTATUS HandleQueryRelations(PDEVICE_OBJECT pdo, PIRP Irp);

static NTSTATUS IgnoreRequest(PDEVICE_OBJECT pdo, PIRP Irp);

static NTSTATUS OnRepeaterComplete(PDEVICE_OBJECT tdo, PIRP subirp, PVOID needsvote);

static NTSTATUS RepeatRequest(PDEVICE_OBJECT pdo, PIRP Irp);

static NTSTATUS SucceedRequest(PDEVICE_OBJECT pdo, PIRP Irp);

static VOID SuballocInterfaceReference(PDEVICE_EXTENSION fdx); 

static VOID SuballocInterfaceDereference(PDEVICE_EXTENSION fdx); 

static NTSTATUS GetChildResources(PDEVICE_EXTENSION fdx, PDEVICE_OBJECT pdo, PCM_RESOURCE_LIST* raw, PCM_RESOURCE_LIST* translated);



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



#pragma PAGEDCODE



NTSTATUS DispatchPnpPdo(IN PDEVICE_OBJECT pdo, IN PIRP Irp)

	{							// DispatchPnpPdo

	PAGED_CODE();

	PPDO_EXTENSION pdx = (PPDO_EXTENSION) pdo->DeviceExtension;



	PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(Irp);

	ASSERT(stack->MajorFunction == IRP_MJ_PNP);

	ASSERT(pdx->flags & ISPDO);

	NTSTATUS status;



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

		SucceedRequest,			// IRP_MN_START_DEVICE

		SucceedRequest,			// IRP_MN_QUERY_REMOVE_DEVICE

		SucceedRequest,			// IRP_MN_REMOVE_DEVICE

		SucceedRequest,			// IRP_MN_CANCEL_REMOVE_DEVICE

		SucceedRequest,			// IRP_MN_STOP_DEVICE

		SucceedRequest,			// IRP_MN_QUERY_STOP_DEVICE

		SucceedRequest,			// IRP_MN_CANCEL_STOP_DEVICE

		HandleQueryRelations,	// IRP_MN_QUERY_DEVICE_RELATIONS

		HandleQueryInterface,	// IRP_MN_QUERY_INTERFACE

		RepeatRequest,			// IRP_MN_QUERY_CAPABILITIES

		SucceedRequest,			// IRP_MN_QUERY_RESOURCES

		SucceedRequest,			// IRP_MN_QUERY_RESOURCE_REQUIREMENTS

		IgnoreRequest,			// IRP_MN_QUERY_DEVICE_TEXT

		SucceedRequest,			// IRP_MN_FILTER_RESOURCE_REQUIREMENTS

		SucceedRequest,			// 

		RepeatRequest,			// IRP_MN_READ_CONFIG

		RepeatRequest,			// IRP_MN_WRITE_CONFIG

		RepeatRequest,			// IRP_MN_EJECT

		RepeatRequest,			// IRP_MN_SET_LOCK

		HandleQueryId,			// IRP_MN_QUERY_ID

		RepeatRequest,			// IRP_MN_QUERY_PNP_DEVICE_STATE

		RepeatRequest,			// IRP_MN_QUERY_BUS_INFORMATION

		RepeatRequest,			// IRP_MN_DEVICE_USAGE_NOTIFICATION

		SucceedRequest,			// IRP_MN_SURPRISE_REMOVAL

		RepeatRequest,			// IRP_MN_QUERY_LEGACY_BUS_INFORMATION

		};



	ULONG fcn = stack->MinorFunction;

	if (fcn >= arraysize(fcntab))

		{						// unknown function

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

		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",

		"IRP_MN_QUERY_LEGACY_BUS_INFORMATION",

		};



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

#endif // DBG



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

	return status;

	}							// DispatchPnp



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

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



#pragma PAGEDCODE



static NTSTATUS HandleQueryId(PDEVICE_OBJECT pdo, PIRP Irp)

	{							// HandleQueryId

	PPDO_EXTENSION pdx = (PPDO_EXTENSION) pdo->DeviceExtension;

	PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(Irp);



	PWCHAR idstring;



	switch (stack->Parameters.QueryId.IdType)

		{						// select based on id type



	case BusQueryInstanceID:

		idstring = L"0000";

		break;



	// For the device ID, we need to supply an enumerator name plus a device identifer.

	// The enumerator name is something you should choose to be unique, which is why

	// I used the name of the driver in this instance.



	case BusQueryDeviceID:

		idstring = (pdx->flags & CHILDTYPEA) ? LDRIVERNAME L"\\*WCO1104" : LDRIVERNAME L"\\*WCO1105";

		break;



	case BusQueryHardwareIDs:

		idstring = (pdx->flags & CHILDTYPEA) ? L"*WCO1104" : L"*WCO1105";

		break;



	case BusQueryCompatibleIDs:

	default:

		return CompleteRequest(Irp, STATUS_NOT_SUPPORTED, 0);



		}						// select based on id type



	ULONG nchars = wcslen(idstring);

	ULONG size = (nchars + 2) * sizeof(WCHAR);

	PWCHAR id = (PWCHAR) ExAllocatePool(PagedPool, size);

	if (!id)

		return CompleteRequest(Irp, STATUS_INSUFFICIENT_RESOURCES, 0);

	wcscpy(id, idstring);

	id[nchars+1] = 0;			// extra null terminator



	return CompleteRequest(Irp, STATUS_SUCCESS, (ULONG_PTR) id);

	}							// HandleQueryId



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



#pragma PAGEDCODE



static NTSTATUS HandleQueryInterface(PDEVICE_OBJECT pdo, PIRP Irp)

	{							// HandleQueryInterface

	PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(Irp);

	

	// See if caller is asking for the resource suballocation interface. If not,

	// repeat this request in the parent device stack. Even though the DDK doc says

	// you shouldn't do this, there is no other way for a child-stack driver to get

	// at one of the interfaces implemented by a parent-stack driver. And, yes, it

	// is true that the parent stack can't be removed until all references to such

	// interfaces are released, but that's not especially fascinating news.



	if (*stack->Parameters.QueryInterface.InterfaceType != GUID_RESOURCE_SUBALLOCATE_STANDARD)

		return RepeatRequest(pdo, Irp);



	// Determine what version of the interface to return.



	USHORT version = RESOURCE_SUBALLOCATE_STANDARD_VERSION; // assume current version

	if (version > stack->Parameters.QueryInterface.Version)

		version = stack->Parameters.QueryInterface.Version; // negotiate down to requested version

	if (version == 0)

		return CompleteRequest(Irp, Irp->IoStatus.Status);	// fail -- no compatible version supported

	

	PPDO_EXTENSION pdx = (PPDO_EXTENSION) pdo->DeviceExtension;

	PDEVICE_OBJECT fdo = pdx->Fdo;

	PDEVICE_EXTENSION fdx = (PDEVICE_EXTENSION) fdo->DeviceExtension;



	// Fill in caller's interface descriptor structure



	switch (version)

		{						// fill in specified version of interface structure



	case 1:

		{						// version 1

		if (stack->Parameters.QueryInterface.Size < sizeof(RESOURCE_SUBALLOCATE_STANDARD))

			return CompleteRequest(Irp, STATUS_INVALID_PARAMETER); // not big enough

		PRESOURCE_SUBALLOCATE_STANDARD ifp = (PRESOURCE_SUBALLOCATE_STANDARD) stack->Parameters.QueryInterface.Interface;

		ifp->Size = sizeof(RESOURCE_SUBALLOCATE_STANDARD);

		ifp->Version = 1;

		ifp->Context = (PVOID) fdx;

		ifp->InterfaceReference = (PINTERFACE_REFERENCE) SuballocInterfaceReference;

		ifp->InterfaceDereference = (PINTERFACE_DEREFERENCE) SuballocInterfaceDereference;

		ifp->GetResources = (PGETRESOURCES) GetChildResources;

		break;

		}						// version 1



	default:

		ASSERT(FALSE);			// version negotiation above went awry

		return CompleteRequest(Irp, Irp->IoStatus.Status);

		}						// fill in specified version of interface structure



	SuballocInterfaceReference(fdx);

	return CompleteRequest(Irp, STATUS_SUCCESS, 0);

	}							// HandleQueryInterface



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



#pragma PAGEDCODE



static NTSTATUS HandleQueryRelations(PDEVICE_OBJECT pdo, PIRP Irp)

	{							// HandleQueryRelations

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

	PDEVICE_RELATIONS newrel = NULL;

	NTSTATUS status = Irp->IoStatus.Status;

	PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(Irp);



	if (stack->Parameters.QueryDeviceRelations.Type == TargetDeviceRelation)

⌨️ 快捷键说明

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