Windows2000/private/ntos/fsrtl/filter.c
2020-09-30 17:12:32 +02:00

346 lines
6.9 KiB
C

/*++
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;
}
}