mirror of https://github.com/tongzx/nt5src
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.
345 lines
7.0 KiB
345 lines
7.0 KiB
/*++
|
|
|
|
Copyright (c) 1989 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
Filter.c
|
|
|
|
Abstract:
|
|
|
|
The Exception filter is used by the file system and cache manager
|
|
to handle error recovery. The basic idea is to have the top level
|
|
file system entry points (i.e., the FSD entry points and FSP dispatch
|
|
loop) have a try-except around their code, and then whenever the
|
|
file system or cache manager reach an error case they raise an
|
|
appropriate status. Then the exception handler catches the exception
|
|
and can either complete the request, send it off to the fsp, verify the
|
|
volume, or bugcheck. We only bugcheck if the raised exception is
|
|
unexpected (i.e., unhandled).
|
|
|
|
This module provides two routines for filtering out exceptions. The
|
|
first routine is used to normalize status values to be one of the
|
|
value handled by the filter. That way if we get an exception not handled
|
|
by the filter then we know that the system is in real trouble and we
|
|
just bugcheck the machine. The second routine is used to ask if
|
|
a status value is within the set of values handled by the filter.
|
|
|
|
The value of status handled by this filter are listed in the routine
|
|
FsRtlIsNtstatusExpected.
|
|
|
|
Author:
|
|
|
|
Gary Kimura [GaryKi] 4-Jan-1991
|
|
|
|
Revision History:
|
|
|
|
--*/
|
|
|
|
#include "FsRtlP.h"
|
|
|
|
//
|
|
// Trace level for the module
|
|
//
|
|
|
|
#define Dbg (0x80000000)
|
|
|
|
|
|
NTSTATUS
|
|
FsRtlNormalizeNtstatus (
|
|
IN NTSTATUS Exception,
|
|
IN NTSTATUS GenericException
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine is used to normalize an NTSTATUS into a status
|
|
that is handled by the file system's top level exception handlers.
|
|
|
|
Arguments:
|
|
|
|
Exception - Supplies the exception being normalized
|
|
|
|
GenericException - Supplies a second exception to translate to
|
|
if the first exception is not within the set of exceptions
|
|
handled by the filter
|
|
|
|
Return Value:
|
|
|
|
NTSTATUS - Returns Exception if the value is already handled
|
|
by the filter, and GenericException otherwise.
|
|
|
|
--*/
|
|
|
|
{
|
|
return (FsRtlIsNtstatusExpected(Exception) ? Exception : GenericException);
|
|
}
|
|
|
|
|
|
BOOLEAN
|
|
FsRtlIsNtstatusExpected (
|
|
IN NTSTATUS Exception
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine is used to decide if a status is within the set of values
|
|
handled by the exception filter.
|
|
|
|
Arguments:
|
|
|
|
Exception - Supplies the exception being queried
|
|
|
|
Return Value:
|
|
|
|
BOOLEAN - Returns TRUE if the value is handled by the filter, and
|
|
FALSE otherwise.
|
|
|
|
--*/
|
|
|
|
{
|
|
switch (Exception) {
|
|
|
|
case STATUS_DATATYPE_MISALIGNMENT:
|
|
case STATUS_ACCESS_VIOLATION:
|
|
case STATUS_ILLEGAL_INSTRUCTION:
|
|
case STATUS_INSTRUCTION_MISALIGNMENT:
|
|
|
|
return FALSE;
|
|
|
|
default:
|
|
|
|
return TRUE;
|
|
}
|
|
}
|
|
|
|
|
|
#undef FsRtlAllocatePool
|
|
|
|
PVOID
|
|
FsRtlAllocatePool (
|
|
IN POOL_TYPE PoolType,
|
|
IN ULONG NumberOfBytes
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine is used to allocate executive level pool. It either
|
|
returns a non null pointer to the newly allocated pool or it raises
|
|
a status of insufficient resources.
|
|
|
|
Arguments:
|
|
|
|
PoolType - Supplies the type of executive pool to allocate
|
|
|
|
NumberOfBytes - Supplies the number of bytes to allocate
|
|
|
|
Return Value:
|
|
|
|
PVOID - Returns a non null pointer to the newly allocated pool.
|
|
|
|
--*/
|
|
|
|
{
|
|
PVOID p;
|
|
|
|
//
|
|
// Allocate executive pool and if we get back null then raise
|
|
// a status of insufficient resources
|
|
//
|
|
|
|
if ((p = ExAllocatePoolWithTag( PoolType, NumberOfBytes, 'trSF')) == NULL) {
|
|
|
|
ExRaiseStatus( STATUS_INSUFFICIENT_RESOURCES );
|
|
}
|
|
|
|
return p;
|
|
}
|
|
|
|
#undef FsRtlAllocatePoolWithQuota
|
|
|
|
|
|
PVOID
|
|
FsRtlAllocatePoolWithQuota (
|
|
IN POOL_TYPE PoolType,
|
|
IN ULONG NumberOfBytes
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine is used to allocate executive level pool with quota. It
|
|
either returns a non null pointer to the newly allocated pool or it raises
|
|
a status of insufficient resources.
|
|
|
|
Arguments:
|
|
|
|
PoolType - Supplies the type of executive pool to allocate
|
|
|
|
NumberOfBytes - Supplies the number of bytes to allocate
|
|
|
|
Return Value:
|
|
|
|
PVOID - Returns a non null pointer to the newly allocated pool.
|
|
|
|
--*/
|
|
|
|
{
|
|
PVOID p;
|
|
|
|
//
|
|
// Allocate executive pool and if we get back null then raise
|
|
// a status of insufficient resources
|
|
//
|
|
|
|
if ((p = ExAllocatePoolWithQuotaTag ( PoolType, NumberOfBytes, 'trSF')) == NULL) {
|
|
|
|
ExRaiseStatus( STATUS_INSUFFICIENT_RESOURCES );
|
|
}
|
|
|
|
return p;
|
|
}
|
|
|
|
|
|
#undef FsRtlAllocatePoolWithTag
|
|
|
|
PVOID
|
|
FsRtlAllocatePoolWithTag (
|
|
IN POOL_TYPE PoolType,
|
|
IN ULONG NumberOfBytes,
|
|
IN ULONG Tag
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine is used to allocate executive level pool with a tag.
|
|
|
|
Arguments:
|
|
|
|
PoolType - Supplies the type of executive pool to allocate
|
|
|
|
NumberOfBytes - Supplies the number of bytes to allocate
|
|
|
|
Tag - Supplies the tag for the pool block
|
|
|
|
Return Value:
|
|
|
|
PVOID - Returns a non null pointer to the newly allocated pool.
|
|
|
|
--*/
|
|
|
|
{
|
|
PVOID p;
|
|
|
|
//
|
|
// Allocate executive pool and if we get back null then raise
|
|
// a status of insufficient resources
|
|
//
|
|
|
|
if ((p = ExAllocatePoolWithTag( PoolType, NumberOfBytes, Tag)) == NULL) {
|
|
|
|
ExRaiseStatus( STATUS_INSUFFICIENT_RESOURCES );
|
|
}
|
|
|
|
return p;
|
|
}
|
|
|
|
|
|
#undef FsRtlAllocatePoolWithQuotaTag
|
|
|
|
PVOID
|
|
FsRtlAllocatePoolWithQuotaTag (
|
|
IN POOL_TYPE PoolType,
|
|
IN ULONG NumberOfBytes,
|
|
IN ULONG Tag
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine is used to allocate executive level pool with a quota tag.
|
|
|
|
Arguments:
|
|
|
|
PoolType - Supplies the type of executive pool to allocate
|
|
|
|
NumberOfBytes - Supplies the number of bytes to allocate
|
|
|
|
Tag - Supplies the tag for the pool block
|
|
|
|
Return Value:
|
|
|
|
PVOID - Returns a non null pointer to the newly allocated pool.
|
|
|
|
--*/
|
|
|
|
{
|
|
PVOID p;
|
|
|
|
//
|
|
// Allocate executive pool and if we get back null then raise
|
|
// a status of insufficient resources
|
|
//
|
|
|
|
if ((p = ExAllocatePoolWithQuotaTag( PoolType, NumberOfBytes, Tag)) == NULL) {
|
|
|
|
ExRaiseStatus( STATUS_INSUFFICIENT_RESOURCES );
|
|
}
|
|
|
|
return p;
|
|
}
|
|
|
|
|
|
BOOLEAN
|
|
FsRtlIsTotalDeviceFailure(
|
|
IN NTSTATUS Status
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine is given an NTSTATUS value and make a determination as to
|
|
if this value indicates that the complete device has failed and therefore
|
|
should no longer be used, or if the failure is one that indicates that
|
|
continued use of the device is ok (i.e. a sector failure).
|
|
|
|
Arguments:
|
|
|
|
Status - the NTSTATUS value to test.
|
|
|
|
Return Value:
|
|
|
|
TRUE - The status value given is believed to be a fatal device error.
|
|
FALSE - The status value given is believed to be a sector failure, but not
|
|
a complete device failure.
|
|
--*/
|
|
|
|
{
|
|
if (NT_SUCCESS(Status)) {
|
|
|
|
//
|
|
// All warning and informational errors will be resolved here.
|
|
//
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
switch (Status) {
|
|
case STATUS_CRC_ERROR:
|
|
case STATUS_DEVICE_DATA_ERROR:
|
|
return FALSE;
|
|
default:
|
|
return TRUE;
|
|
}
|
|
}
|