You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
293 lines
5.9 KiB
293 lines
5.9 KiB
/*++
|
|
|
|
Copyright (c) Microsoft Corporation. All rights reserved.
|
|
|
|
Module Name:
|
|
|
|
ppvutil.c
|
|
|
|
Abstract:
|
|
|
|
This module implements various utilities required to do driver verification.
|
|
|
|
Author:
|
|
|
|
Adrian J. Oney (adriao) 20-Apr-1998
|
|
|
|
Environment:
|
|
|
|
Kernel mode
|
|
|
|
Revision History:
|
|
|
|
AdriaO 02/10/2000 - Seperated out from ntos\io\trackirp.c
|
|
|
|
--*/
|
|
|
|
#include "pnpmgrp.h"
|
|
|
|
#ifdef ALLOC_PRAGMA
|
|
#pragma alloc_text(PAGEVRFY, PpvUtilInit)
|
|
//#pragma alloc_text(PAGEVRFY, PpvUtilFailDriver)
|
|
//#pragma alloc_text(PAGEVRFY, PpvUtilCallAddDevice)
|
|
//#pragma alloc_text(PAGEVRFY, PpvUtilTestStartedPdoStack)
|
|
|
|
#ifndef NO_VERIFIER
|
|
#pragma alloc_text(PAGEVRFY, PpvUtilGetDevnodeRemovalOption)
|
|
#pragma alloc_text(PAGEVRFY, PpvUtilIsHardwareBeingVerified)
|
|
#endif // NO_VERIFIER
|
|
|
|
#endif // ALLOC_PRAGMA
|
|
|
|
|
|
//
|
|
// This entire implementation is specific to the verifier
|
|
//
|
|
#ifndef NO_VERIFIER
|
|
|
|
BOOLEAN PpvUtilVerifierEnabled = FALSE;
|
|
|
|
|
|
VOID
|
|
FASTCALL
|
|
PpvUtilInit(
|
|
VOID
|
|
)
|
|
{
|
|
PpvUtilVerifierEnabled = TRUE;
|
|
}
|
|
|
|
|
|
NTSTATUS
|
|
FASTCALL
|
|
PpvUtilCallAddDevice(
|
|
IN PDEVICE_OBJECT PhysicalDeviceObject,
|
|
IN PDRIVER_OBJECT DriverObject,
|
|
IN PDRIVER_ADD_DEVICE AddDeviceFunction,
|
|
IN VF_DEVOBJ_TYPE DevObjType
|
|
)
|
|
{
|
|
NTSTATUS status;
|
|
|
|
if (!PpvUtilVerifierEnabled) {
|
|
|
|
return AddDeviceFunction(DriverObject, PhysicalDeviceObject);
|
|
}
|
|
|
|
//
|
|
// Notify the verifier prior to AddDevice
|
|
//
|
|
VfDevObjPreAddDevice(
|
|
PhysicalDeviceObject,
|
|
DriverObject,
|
|
AddDeviceFunction,
|
|
DevObjType
|
|
);
|
|
|
|
status = AddDeviceFunction(DriverObject, PhysicalDeviceObject);
|
|
|
|
//
|
|
// Let the verifier know how it turned out.
|
|
//
|
|
VfDevObjPostAddDevice(
|
|
PhysicalDeviceObject,
|
|
DriverObject,
|
|
AddDeviceFunction,
|
|
DevObjType,
|
|
status
|
|
);
|
|
|
|
return status;
|
|
}
|
|
|
|
|
|
VOID
|
|
FASTCALL
|
|
PpvUtilTestStartedPdoStack(
|
|
IN PDEVICE_OBJECT DeviceObject
|
|
)
|
|
{
|
|
if (PpvUtilVerifierEnabled) {
|
|
|
|
VfMajorTestStartedPdoStack(DeviceObject);
|
|
}
|
|
}
|
|
|
|
|
|
VOID
|
|
FASTCALL
|
|
PpvUtilFailDriver(
|
|
IN PPVFAILURE_TYPE FailureType,
|
|
IN PVOID CulpritAddress,
|
|
IN PDEVICE_OBJECT DeviceObject OPTIONAL,
|
|
IN PVOID ExtraneousInfo OPTIONAL
|
|
)
|
|
{
|
|
if (!PpvUtilVerifierEnabled) {
|
|
|
|
return;
|
|
}
|
|
|
|
switch(FailureType) {
|
|
|
|
case PPVERROR_DUPLICATE_PDO_ENUMERATED:
|
|
WDM_FAIL_ROUTINE((
|
|
DCERROR_DUPLICATE_ENUMERATION,
|
|
DCPARAM_ROUTINE + DCPARAM_DEVOBJ*2,
|
|
CulpritAddress,
|
|
DeviceObject,
|
|
ExtraneousInfo
|
|
));
|
|
break;
|
|
|
|
case PPVERROR_MISHANDLED_TARGET_DEVICE_RELATIONS:
|
|
WDM_FAIL_ROUTINE((
|
|
DCERROR_MISHANDLED_TARGET_DEVICE_RELATIONS,
|
|
DCPARAM_ROUTINE + DCPARAM_DEVOBJ,
|
|
CulpritAddress,
|
|
DeviceObject
|
|
));
|
|
break;
|
|
|
|
case PPVERROR_DDI_REQUIRES_PDO:
|
|
WDM_FAIL_ROUTINE((
|
|
DCERROR_DDI_REQUIRES_PDO,
|
|
DCPARAM_ROUTINE + DCPARAM_DEVOBJ,
|
|
CulpritAddress,
|
|
DeviceObject
|
|
));
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
PPVREMOVAL_OPTION
|
|
FASTCALL
|
|
PpvUtilGetDevnodeRemovalOption(
|
|
IN PDEVICE_OBJECT PhysicalDeviceObject
|
|
)
|
|
{
|
|
PDEVICE_NODE devNode;
|
|
|
|
devNode = PhysicalDeviceObject->DeviceObjectExtension->DeviceNode;
|
|
|
|
if (devNode == NULL) {
|
|
|
|
//
|
|
// This must be PartMgr device, we have no opinion
|
|
//
|
|
return PPVREMOVAL_MAY_DEFER_DELETION;
|
|
}
|
|
|
|
if (devNode->Flags & DNF_ENUMERATED) {
|
|
|
|
//
|
|
// It's still present, so it mustn't delete itself.
|
|
//
|
|
return PPVREMOVAL_SHOULDNT_DELETE;
|
|
|
|
} else if (devNode->Flags & DNF_DEVICE_GONE) {
|
|
|
|
//
|
|
// It's been reported missing, it must delete itself now as it's parent
|
|
// may already have been removed.
|
|
//
|
|
return PPVREMOVAL_SHOULD_DELETE;
|
|
|
|
} else {
|
|
|
|
//
|
|
// Corner case - in theory it should delete itself, but it's parent
|
|
// will get a remove immediately after it does. As such it can defer
|
|
// it's deletion.
|
|
//
|
|
return PPVREMOVAL_MAY_DEFER_DELETION;
|
|
}
|
|
}
|
|
|
|
|
|
BOOLEAN
|
|
FASTCALL
|
|
PpvUtilIsHardwareBeingVerified(
|
|
IN PDEVICE_OBJECT PhysicalDeviceObject
|
|
)
|
|
{
|
|
PDEVICE_NODE devNode;
|
|
|
|
if (!IS_PDO(PhysicalDeviceObject)) {
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
devNode = PhysicalDeviceObject->DeviceObjectExtension->DeviceNode;
|
|
|
|
if ((devNode->Flags & DNF_HARDWARE_VERIFICATION) != 0) {
|
|
return TRUE;
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
#else // NO_VERIFIER
|
|
|
|
|
|
//
|
|
// The code below should be built into a future stub that deadens out IO
|
|
// support for the verifier.
|
|
//
|
|
|
|
VOID
|
|
FASTCALL
|
|
PpvUtilInit(
|
|
VOID
|
|
)
|
|
{
|
|
}
|
|
|
|
|
|
NTSTATUS
|
|
FASTCALL
|
|
PpvUtilCallAddDevice(
|
|
IN PDEVICE_OBJECT PhysicalDeviceObject,
|
|
IN PDRIVER_OBJECT DriverObject,
|
|
IN PDRIVER_ADD_DEVICE AddDeviceFunction,
|
|
IN VF_DEVOBJ_TYPE DevObjType
|
|
)
|
|
{
|
|
UNREFERENCED_PARAMETER(DevObjType);
|
|
|
|
return AddDeviceFunction(DriverObject, PhysicalDeviceObject);
|
|
}
|
|
|
|
|
|
VOID
|
|
FASTCALL
|
|
PpvUtilTestStartedPdoStack(
|
|
IN PDEVICE_OBJECT DeviceObject
|
|
)
|
|
{
|
|
UNREFERENCED_PARAMETER(DeviceObject);
|
|
}
|
|
|
|
|
|
VOID
|
|
FASTCALL
|
|
PpvUtilFailDriver(
|
|
IN PPVFAILURE_TYPE FailureType,
|
|
IN PVOID CulpritAddress,
|
|
IN PDEVICE_OBJECT DeviceObject OPTIONAL,
|
|
IN PVOID ExtraneousInfo OPTIONAL
|
|
)
|
|
{
|
|
UNREFERENCED_PARAMETER(FailureType);
|
|
UNREFERENCED_PARAMETER(CulpritAddress);
|
|
UNREFERENCED_PARAMETER(DeviceObject);
|
|
UNREFERENCED_PARAMETER(ExtraneousInfo);
|
|
}
|
|
|
|
#endif
|
|
|