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

📄 plugplaypdo.cpp

📁 一本在讲述USB驱动程式的书 及其范例原码
💻 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 + -