523 lines
15 KiB
C
523 lines
15 KiB
C
/*++
|
|
|
|
Copyright (c) 2001 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
vfddi.c
|
|
|
|
Abstract:
|
|
|
|
This module contains the list of device driver interfaces exported by the
|
|
driver verifier and the kernel. Note that thunked exports are *not* placed
|
|
here.
|
|
|
|
All the exports are concentrated in one file because
|
|
|
|
1) There are relatively few driver verifier exports
|
|
|
|
2) The function naming convention differs from that used elsewhere in
|
|
the driver verifier.
|
|
|
|
Author:
|
|
|
|
Adrian J. Oney (adriao) 26-Apr-2001
|
|
|
|
Environment:
|
|
|
|
Kernel mode
|
|
|
|
Revision History:
|
|
|
|
--*/
|
|
|
|
#include "vfdef.h"
|
|
#include "viddi.h"
|
|
|
|
#ifdef ALLOC_PRAGMA
|
|
#pragma alloc_text(INIT, VfDdiInit)
|
|
//#pragma alloc_text(NONPAGED, VfFailDeviceNode)
|
|
//#pragma alloc_text(NONPAGED, VfFailSystemBIOS)
|
|
//#pragma alloc_text(NONPAGED, VfFailDriver)
|
|
//#pragma alloc_text(NONPAGED, VfIsVerificationEnabled)
|
|
#pragma alloc_text(PAGEVRFY, ViDdiThrowException)
|
|
#endif // ALLOC_PRAGMA
|
|
|
|
BOOLEAN ViDdiInitialized = FALSE;
|
|
|
|
#ifdef ALLOC_DATA_PRAGMA
|
|
#pragma const_seg("PAGEVRFC")
|
|
#endif
|
|
|
|
//
|
|
// These are the general "classifications" of device errors, along with the
|
|
// default flags that will be applied the first time this is hit.
|
|
//
|
|
const VFMESSAGE_CLASS ViDdiClassFailDeviceInField = {
|
|
VFM_FLAG_BEEP | VFM_LOGO_FAILURE | VFM_DEPLOYMENT_FAILURE,
|
|
"DEVICE FAILURE"
|
|
};
|
|
|
|
// VFM_DEPLOYMENT_FAILURE is set here because we don't yet have a "logo" mode
|
|
const VFMESSAGE_CLASS ViDdiClassFailDeviceLogo = {
|
|
VFM_FLAG_BEEP | VFM_LOGO_FAILURE | VFM_DEPLOYMENT_FAILURE,
|
|
"DEVICE FAILURE"
|
|
};
|
|
|
|
const VFMESSAGE_CLASS ViDdiClassFailDeviceUnderDebugger = {
|
|
VFM_FLAG_BEEP,
|
|
"DEVICE FAILURE"
|
|
};
|
|
|
|
#ifdef ALLOC_DATA_PRAGMA
|
|
#pragma const_seg()
|
|
#endif // ALLOC_DATA_PRAGMA
|
|
|
|
|
|
VOID
|
|
VfDdiInit(
|
|
VOID
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine initializes the Device Driver Interface support.
|
|
|
|
Arguments:
|
|
|
|
None.
|
|
|
|
Return Value:
|
|
|
|
None.
|
|
|
|
--*/
|
|
{
|
|
ViDdiInitialized = TRUE;
|
|
}
|
|
|
|
|
|
VOID
|
|
VfFailDeviceNode(
|
|
IN PDEVICE_OBJECT PhysicalDeviceObject,
|
|
IN ULONG BugCheckMajorCode,
|
|
IN ULONG BugCheckMinorCode,
|
|
IN VF_FAILURE_CLASS FailureClass,
|
|
IN OUT PULONG AssertionControl,
|
|
IN PSTR DebuggerMessageText,
|
|
IN PSTR ParameterFormatString,
|
|
...
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine fails a Pnp enumerated hardware or virtual device if
|
|
verification is enabled against it.
|
|
|
|
Arguments:
|
|
|
|
PhysicalDeviceObject - Bottom of the stack that identifies the PnP
|
|
device.
|
|
|
|
BugCheckMajorCode - BugCheck Major Code
|
|
|
|
BugCheckMinorCode - BugCheck Minor Code
|
|
Note - Zero is reserved!!!
|
|
|
|
FailureClass - Either VFFAILURE_FAIL_IN_FIELD,
|
|
VFFAILURE_FAIL_LOGO, or
|
|
VFFAILURE_FAIL_UNDER_DEBUGGER
|
|
|
|
AssertionControl - Points to a ULONG associated with the failure,
|
|
used to store information across multiple calls.
|
|
Must be statically preinitialized to zero.
|
|
|
|
DebuggerMessageText - Text to be displayed in the debugger. Note that
|
|
the text may reference parameters such as:
|
|
%Routine - passed in Routine
|
|
%Irp - passed in Irp
|
|
%DevObj - passed in DevObj
|
|
%Status - passed in Status
|
|
%Ulong - passed in ULONG
|
|
%Ulong1 - first passed in ULONG
|
|
%Ulong3 - third passed in ULONG (max 3, any param)
|
|
%Pvoid2 - second passed in PVOID
|
|
etc
|
|
(note, capitalization matters)
|
|
|
|
ParameterFormatString - Contains ordered list of parameters referenced by
|
|
above debugger text. For instance,
|
|
(..., "%Status1%Status2%Ulong1%Ulong2", Status1, Status2, Ulong1, Ulong2);
|
|
|
|
Note - If %Routine/%Routine1 is supplied as a param,
|
|
the driver at %Routine must also be under verification.
|
|
|
|
... - Actual parameters
|
|
|
|
Return Value:
|
|
|
|
None.
|
|
|
|
Note - this function may return if the device is not currently being
|
|
verified.
|
|
|
|
--*/
|
|
{
|
|
va_list arglist;
|
|
|
|
if (!VfIsVerificationEnabled(VFOBJTYPE_DEVICE, (PVOID) PhysicalDeviceObject)) {
|
|
|
|
return;
|
|
}
|
|
|
|
va_start(arglist, ParameterFormatString);
|
|
|
|
ViDdiThrowException(
|
|
BugCheckMajorCode,
|
|
BugCheckMinorCode,
|
|
FailureClass,
|
|
AssertionControl,
|
|
DebuggerMessageText,
|
|
ParameterFormatString,
|
|
&arglist
|
|
);
|
|
|
|
va_end(arglist);
|
|
}
|
|
|
|
|
|
VOID
|
|
VfFailSystemBIOS(
|
|
IN ULONG BugCheckMajorCode,
|
|
IN ULONG BugCheckMinorCode,
|
|
IN VF_FAILURE_CLASS FailureClass,
|
|
IN OUT PULONG AssertionControl,
|
|
IN PSTR DebuggerMessageText,
|
|
IN PSTR ParameterFormatString,
|
|
...
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine fails the system BIOS if verification is enabled against it.
|
|
|
|
Arguments:
|
|
|
|
BugCheckMajorCode - BugCheck Major Code
|
|
|
|
BugCheckMinorCode - BugCheck Minor Code
|
|
Note - Zero is reserved!!!
|
|
|
|
FailureClass - Either VFFAILURE_FAIL_IN_FIELD,
|
|
VFFAILURE_FAIL_LOGO, or
|
|
VFFAILURE_FAIL_UNDER_DEBUGGER
|
|
|
|
AssertionControl - Points to a ULONG associated with the failure,
|
|
used to store information across multiple calls.
|
|
Must be statically preinitialized to zero.
|
|
|
|
DebuggerMessageText - Text to be displayed in the debugger. Note that
|
|
the text may reference parameters such as:
|
|
%Routine - passed in Routine
|
|
%Irp - passed in Irp
|
|
%DevObj - passed in DevObj
|
|
%Status - passed in Status
|
|
%Ulong - passed in ULONG
|
|
%Ulong1 - first passed in ULONG
|
|
%Ulong3 - third passed in ULONG (max 3, any param)
|
|
%Pvoid2 - second passed in PVOID
|
|
etc
|
|
(note, capitalization matters)
|
|
|
|
ParameterFormatString - Contains ordered list of parameters referenced by
|
|
above debugger text. For instance,
|
|
(..., "%Status1%Status2%Ulong1%Ulong2", Status1, Status2, Ulong1, Ulong2);
|
|
|
|
Note - If %Routine/%Routine1 is supplied as a param,
|
|
the driver at %Routine must also be under verification.
|
|
|
|
... - Actual parameters
|
|
|
|
Return Value:
|
|
|
|
None.
|
|
|
|
Note - this function may return if the device is not currently being
|
|
verified.
|
|
|
|
--*/
|
|
{
|
|
va_list arglist;
|
|
|
|
if (!VfIsVerificationEnabled(VFOBJTYPE_SYSTEM_BIOS, NULL)) {
|
|
|
|
return;
|
|
}
|
|
|
|
va_start(arglist, ParameterFormatString);
|
|
|
|
ViDdiThrowException(
|
|
BugCheckMajorCode,
|
|
BugCheckMinorCode,
|
|
FailureClass,
|
|
AssertionControl,
|
|
DebuggerMessageText,
|
|
ParameterFormatString,
|
|
&arglist
|
|
);
|
|
|
|
va_end(arglist);
|
|
}
|
|
|
|
|
|
VOID
|
|
VfFailDriver(
|
|
IN ULONG BugCheckMajorCode,
|
|
IN ULONG BugCheckMinorCode,
|
|
IN VF_FAILURE_CLASS FailureClass,
|
|
IN OUT PULONG AssertionControl,
|
|
IN PSTR DebuggerMessageText,
|
|
IN PSTR ParameterFormatString,
|
|
...
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine fails a driver if verification is enabled against it.
|
|
|
|
Arguments:
|
|
|
|
BugCheckMajorCode - BugCheck Major Code
|
|
|
|
BugCheckMinorCode - BugCheck Minor Code
|
|
Note - Zero is reserved!!!
|
|
|
|
FailureClass - Either VFFAILURE_FAIL_IN_FIELD,
|
|
VFFAILURE_FAIL_LOGO, or
|
|
VFFAILURE_FAIL_UNDER_DEBUGGER
|
|
|
|
AssertionControl - Points to a ULONG associated with the failure.
|
|
Must be preinitialized to zero!!!
|
|
|
|
DebuggerMessageText - Text to be displayed in the debugger. Note that
|
|
the text may reference parameters such as:
|
|
%Routine - passed in Routine
|
|
%Irp - passed in Irp
|
|
%DevObj - passed in DevObj
|
|
%Status - passed in Status
|
|
%Ulong - passed in ULONG
|
|
%Ulong1 - first passed in ULONG
|
|
%Ulong3 - third passed in ULONG (max 3, any param)
|
|
%Pvoid2 - second passed in PVOID
|
|
etc
|
|
(note, capitalization matters)
|
|
|
|
ParameterFormatString - Contains ordered list of parameters referenced by
|
|
above debugger text. For instance,
|
|
(..., "%Status1%Status2%Ulong1%Ulong2", Status1, Status2, Ulong1, Ulong2);
|
|
|
|
One of these parameters should be %Routine. This will
|
|
be what the OS uses to identify the driver.
|
|
|
|
static minorFlags = 0;
|
|
|
|
VfFailDriver(
|
|
major,
|
|
minor,
|
|
VFFAILURE_FAIL_LOGO,
|
|
&minorFlags,
|
|
"Driver at %Routine returned %Ulong",
|
|
"%Ulong%Routine",
|
|
value,
|
|
routine
|
|
);
|
|
|
|
Return Value:
|
|
|
|
None.
|
|
|
|
Note - this function may return if the driver is not currently being
|
|
verified.
|
|
|
|
--*/
|
|
{
|
|
va_list arglist;
|
|
|
|
if (!ViDdiInitialized) {
|
|
|
|
return;
|
|
}
|
|
|
|
va_start(arglist, ParameterFormatString);
|
|
|
|
ViDdiThrowException(
|
|
BugCheckMajorCode,
|
|
BugCheckMinorCode,
|
|
FailureClass,
|
|
AssertionControl,
|
|
DebuggerMessageText,
|
|
ParameterFormatString,
|
|
&arglist
|
|
);
|
|
|
|
va_end(arglist);
|
|
}
|
|
|
|
|
|
VOID
|
|
ViDdiThrowException(
|
|
IN ULONG BugCheckMajorCode,
|
|
IN ULONG BugCheckMinorCode,
|
|
IN VF_FAILURE_CLASS FailureClass,
|
|
IN OUT PULONG AssertionControl,
|
|
IN PSTR DebuggerMessageText,
|
|
IN PSTR ParameterFormatString,
|
|
IN va_list * MessageParameters
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine fails either a devnode or a driver.
|
|
|
|
Arguments:
|
|
|
|
BugCheckMajorCode - BugCheck Major Code
|
|
|
|
BugCheckMinorCode - BugCheck Minor Code
|
|
Note - Zero is reserved!!!
|
|
|
|
FailureClass - Either VFFAILURE_FAIL_IN_FIELD,
|
|
VFFAILURE_FAIL_LOGO, or
|
|
VFFAILURE_FAIL_UNDER_DEBUGGER
|
|
|
|
AssertionControl - Points to a ULONG associated with the failure.
|
|
Must be preinitialized to zero.
|
|
|
|
DebuggerMessageText - Text to be displayed in the debugger. Note that
|
|
the text may reference parameters such as:
|
|
%Routine - passed in Routine
|
|
%Irp - passed in Irp
|
|
%DevObj - passed in DevObj
|
|
%Status - passed in Status
|
|
%Ulong - passed in ULONG
|
|
%Ulong1 - first passed in ULONG
|
|
%Ulong3 - third passed in ULONG (max 3, any param)
|
|
%Pvoid2 - second passed in PVOID
|
|
etc
|
|
(note, capitalization matters)
|
|
|
|
ParameterFormatString - Contains ordered list of parameters referenced by
|
|
above debugger text. For instance,
|
|
(..., "%Status1%Status2%Ulong1%Ulong2", Status1, Status2, Ulong1, Ulong2);
|
|
|
|
MessageParameters - arg list of parameters matching
|
|
ParameterFormatString
|
|
|
|
Return Value:
|
|
|
|
None.
|
|
|
|
Note - this function may return if the device is not currently being
|
|
verified.
|
|
|
|
--*/
|
|
{
|
|
PCVFMESSAGE_CLASS messageClass;
|
|
VFMESSAGE_TEMPLATE messageTemplates[2];
|
|
VFMESSAGE_TEMPLATE_TABLE messageTable;
|
|
NTSTATUS status;
|
|
|
|
ASSERT(BugCheckMinorCode != 0);
|
|
|
|
switch(FailureClass) {
|
|
case VFFAILURE_FAIL_IN_FIELD:
|
|
messageClass = &ViDdiClassFailDeviceInField;
|
|
break;
|
|
|
|
case VFFAILURE_FAIL_LOGO:
|
|
messageClass = &ViDdiClassFailDeviceLogo;
|
|
break;
|
|
|
|
case VFFAILURE_FAIL_UNDER_DEBUGGER:
|
|
messageClass = &ViDdiClassFailDeviceUnderDebugger;
|
|
break;
|
|
|
|
default:
|
|
ASSERT(0);
|
|
messageClass = NULL;
|
|
break;
|
|
}
|
|
|
|
//
|
|
// Program the template.
|
|
//
|
|
RtlZeroMemory(messageTemplates, sizeof(messageTemplates));
|
|
messageTemplates[0].MessageID = BugCheckMinorCode-1;
|
|
messageTemplates[1].MessageID = BugCheckMinorCode;
|
|
messageTemplates[1].MessageClass = messageClass;
|
|
messageTemplates[1].Flags = *AssertionControl;
|
|
messageTemplates[1].ParamString = ParameterFormatString;
|
|
messageTemplates[1].MessageText = DebuggerMessageText;
|
|
|
|
//
|
|
// Fill out the message table.
|
|
//
|
|
messageTable.TableID = 0;
|
|
messageTable.BugCheckMajor = BugCheckMajorCode;
|
|
messageTable.TemplateArray = messageTemplates;
|
|
messageTable.TemplateCount = ARRAY_COUNT(messageTemplates);
|
|
messageTable.OverrideArray = NULL;
|
|
messageTable.OverrideCount = 0;
|
|
|
|
status = VfBugcheckThrowException(
|
|
&messageTable,
|
|
BugCheckMinorCode,
|
|
ParameterFormatString,
|
|
MessageParameters
|
|
);
|
|
|
|
//
|
|
// Write back the assertion control.
|
|
//
|
|
*AssertionControl = messageTemplates[1].Flags;
|
|
}
|
|
|
|
|
|
BOOLEAN
|
|
VfIsVerificationEnabled(
|
|
IN VF_OBJECT_TYPE VfObjectType,
|
|
IN PVOID Object
|
|
)
|
|
{
|
|
if (!ViDdiInitialized) {
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
switch(VfObjectType) {
|
|
|
|
case VFOBJTYPE_DRIVER:
|
|
return (BOOLEAN) MmIsDriverVerifying((PDRIVER_OBJECT) Object);
|
|
|
|
case VFOBJTYPE_DEVICE:
|
|
|
|
if (!VfSettingsIsOptionEnabled(NULL, VERIFIER_OPTION_HARDWARE_VERIFICATION)) {
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
return PpvUtilIsHardwareBeingVerified((PDEVICE_OBJECT) Object);
|
|
|
|
case VFOBJTYPE_SYSTEM_BIOS:
|
|
return VfSettingsIsOptionEnabled(NULL, VERIFIER_OPTION_SYSTEM_BIOS_VERIFICATION);
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|