792 lines
16 KiB
C
792 lines
16 KiB
C
/*++
|
||
|
||
Copyright (c) 1989 Microsoft Corporation
|
||
|
||
Module Name:
|
||
|
||
NpProcs.h
|
||
|
||
Abstract:
|
||
|
||
This module defines all of the globally used procedures in the Named
|
||
Pipe file system.
|
||
|
||
Author:
|
||
|
||
Gary Kimura [GaryKi] 20-Aug-1990
|
||
|
||
Revision History:
|
||
|
||
--*/
|
||
|
||
#ifndef _NPPROCS_
|
||
#define _NPPROCS_
|
||
|
||
#include <NtIfs.h>
|
||
|
||
//#include <Ntos.h>
|
||
//#include <FsRtl.h>
|
||
//#include <String.h>
|
||
|
||
#include "NodeType.h"
|
||
#include "NpStruc.h"
|
||
#include "NpData.h"
|
||
|
||
//
|
||
// Tag all of our allocations if tagging is turned on
|
||
//
|
||
|
||
#undef FsRtlAllocatePool
|
||
#undef FsRtlAllocatePoolWithQuota
|
||
|
||
#define FsRtlAllocatePool(a,b) FsRtlAllocatePoolWithTag(a,b,'sfpN')
|
||
#define FsRtlAllocatePoolWithQuota(a,b) FsRtlAllocatePoolWithQuotaTag(a,b,'sfpN')
|
||
|
||
|
||
//
|
||
// Data queue support routines, implemented in DataSup.c
|
||
//
|
||
|
||
VOID
|
||
NpInitializeDataQueue (
|
||
IN PDATA_QUEUE DataQueue,
|
||
IN PEPROCESS Process,
|
||
IN ULONG Quota
|
||
);
|
||
|
||
VOID
|
||
NpUninitializeDataQueue (
|
||
IN PDATA_QUEUE DataQueue,
|
||
IN PEPROCESS Process
|
||
);
|
||
|
||
PDATA_ENTRY
|
||
NpAddDataQueueEntry (
|
||
IN PDATA_QUEUE DataQueue,
|
||
IN QUEUE_STATE Who,
|
||
IN DATA_ENTRY_TYPE Type,
|
||
IN ULONG DataSize,
|
||
IN PIRP Irp OPTIONAL,
|
||
IN PVOID DataPointer OPTIONAL
|
||
);
|
||
|
||
PIRP
|
||
NpRemoveDataQueueEntry (
|
||
IN PDATA_QUEUE DataQueue
|
||
);
|
||
|
||
//PDATA_ENTRY
|
||
//NpGetNextDataQueueEntry (
|
||
// IN PDATA_QUEUE DataQueue,
|
||
// IN PDATA_ENTRY PreviousDataEntry OPTIONAL
|
||
// );
|
||
#define NpGetNextDataQueueEntry(_dq,_pde) \
|
||
((_pde) != NULL ? ((PDATA_ENTRY)(_pde))->Next : (_dq)->FrontOfQueue)
|
||
|
||
PDATA_ENTRY
|
||
NpGetNextRealDataQueueEntry (
|
||
IN PDATA_QUEUE DataQueue
|
||
);
|
||
|
||
//BOOLEAN
|
||
//NpIsDataQueueEmpty (
|
||
// IN PDATA_QUEUE DataQueue
|
||
// );
|
||
#define NpIsDataQueueEmpty(_dq) ((_dq)->QueueState == Empty)
|
||
|
||
//BOOLEAN
|
||
//NpIsDataQueueReaders (
|
||
// IN PDATA_QUEUE DataQueue
|
||
// );
|
||
#define NpIsDataQueueReaders(_dq) ((_dq)->QueueState == ReadEntries)
|
||
|
||
//BOOLEAN
|
||
//NpIsDataQueueWriters (
|
||
// IN PDATA_QUEUE DataQueue
|
||
// );
|
||
#define NpIsDataQueueWriters(_dq) ((_dq)->QueueState == WriteEntries)
|
||
|
||
|
||
//
|
||
// The following routines are used to manipulate the input buffers and are
|
||
// implemented in DevioSup.c
|
||
//
|
||
|
||
//PVOID
|
||
//NpMapUserBuffer (
|
||
// IN OUT PIRP Irp
|
||
// );
|
||
#define NpMapUserBuffer(_irp) \
|
||
(Irp->MdlAddress == NULL ? Irp->UserBuffer : \
|
||
MmGetSystemAddressForMdl( Irp->MdlAddress ))
|
||
|
||
|
||
VOID
|
||
NpLockUserBuffer (
|
||
IN OUT PIRP Irp,
|
||
IN LOCK_OPERATION Operation,
|
||
IN ULONG BufferLength
|
||
);
|
||
|
||
|
||
//
|
||
// The event support routines, implemented in EventSup.c
|
||
//
|
||
|
||
RTL_GENERIC_COMPARE_RESULTS
|
||
NpEventTableCompareRoutine (
|
||
IN PRTL_GENERIC_TABLE EventTable,
|
||
IN PVOID FirstStruct,
|
||
IN PVOID SecondStruct
|
||
);
|
||
|
||
PVOID
|
||
NpEventTableAllocate (
|
||
IN PRTL_GENERIC_TABLE EventTable,
|
||
IN CLONG ByteSize
|
||
);
|
||
|
||
VOID
|
||
NpEventTableDeallocate (
|
||
IN PRTL_GENERIC_TABLE EventTable,
|
||
IN PVOID Buffer
|
||
);
|
||
|
||
//
|
||
// VOID
|
||
// NpInitializeEventTable (
|
||
// IN PEVENT_TABLE EventTable
|
||
// );
|
||
//
|
||
|
||
#define NpInitializeEventTable(_et) { \
|
||
RtlInitializeGenericTable( &(_et)->Table, \
|
||
NpEventTableCompareRoutine, \
|
||
NpEventTableAllocate, \
|
||
NpEventTableDeallocate, \
|
||
(PVOID)NonPagedPool ); \
|
||
}
|
||
|
||
|
||
//VOID
|
||
//NpUninitializeEventTable (
|
||
// IN PEVENT_TABLE EventTable
|
||
// );
|
||
#define NpUninitializeEventTable(_et) NOTHING
|
||
|
||
PEVENT_TABLE_ENTRY
|
||
NpAddEventTableEntry (
|
||
IN PEVENT_TABLE EventTable,
|
||
IN PCCB Ccb,
|
||
IN NAMED_PIPE_END NamedPipeEnd,
|
||
IN HANDLE EventHandle,
|
||
IN ULONG KeyValue,
|
||
IN PEPROCESS Process,
|
||
IN KPROCESSOR_MODE PreviousMode
|
||
);
|
||
|
||
VOID
|
||
NpDeleteEventTableEntry (
|
||
IN PEVENT_TABLE EventTable,
|
||
IN PEVENT_TABLE_ENTRY Template
|
||
);
|
||
|
||
// VOID
|
||
// NpSignalEventTableEntry (
|
||
// IN PEVENT_TABLE_ENTRY EventTableEntry OPTIONAL
|
||
// );
|
||
#define NpSignalEventTableEntry(_ete) \
|
||
if (ARGUMENT_PRESENT(_ete)) { \
|
||
KeSetEvent((PKEVENT)(_ete)->Event, 0, FALSE); \
|
||
}
|
||
|
||
PEVENT_TABLE_ENTRY
|
||
NpGetNextEventTableEntry (
|
||
IN PEVENT_TABLE EventTable,
|
||
IN PVOID *RestartKey
|
||
);
|
||
|
||
|
||
//
|
||
// The following routines are used to manipulate the fscontext fields of
|
||
// a file object, implemented in FilObSup.c
|
||
//
|
||
|
||
VOID
|
||
NpSetFileObject (
|
||
IN PFILE_OBJECT FileObject OPTIONAL,
|
||
IN PVOID FsContext,
|
||
IN PVOID FsContext2,
|
||
IN NAMED_PIPE_END NamedPipeEnd
|
||
);
|
||
|
||
NODE_TYPE_CODE
|
||
NpDecodeFileObject (
|
||
IN PFILE_OBJECT FileObject,
|
||
OUT PFCB *Fcb OPTIONAL,
|
||
OUT PCCB *Ccb,
|
||
OUT PNAMED_PIPE_END NamedPipeEnd OPTIONAL
|
||
);
|
||
|
||
|
||
//
|
||
// Largest matching prefix searching routines, implemented in PrefxSup.c
|
||
//
|
||
|
||
PFCB
|
||
NpFindPrefix (
|
||
IN PUNICODE_STRING String,
|
||
IN BOOLEAN CaseInsensitive,
|
||
OUT PUNICODE_STRING RemainingPart
|
||
);
|
||
|
||
PFCB
|
||
NpFindRelativePrefix (
|
||
IN PDCB Dcb,
|
||
IN PUNICODE_STRING String,
|
||
IN BOOLEAN CaseInsensitive,
|
||
OUT PUNICODE_STRING RemainingPart
|
||
);
|
||
|
||
|
||
//
|
||
// Pipe name aliases, implemented in AliasSup.c
|
||
//
|
||
|
||
NTSTATUS
|
||
NpInitializeAliases (
|
||
VOID
|
||
);
|
||
|
||
NTSTATUS
|
||
NpTranslateAlias (
|
||
IN OUT PUNICODE_STRING String
|
||
);
|
||
|
||
|
||
//
|
||
// The follow routine provides common read data queue support
|
||
// for buffered read, unbuffered read, peek, and transceive
|
||
//
|
||
|
||
IO_STATUS_BLOCK
|
||
NpReadDataQueue ( // implemented in ReadSup.c
|
||
IN PDATA_QUEUE ReadQueue,
|
||
IN BOOLEAN PeekOperation,
|
||
IN BOOLEAN ReadOverflowOperation,
|
||
IN PUCHAR ReadBuffer,
|
||
IN ULONG ReadLength,
|
||
IN READ_MODE ReadMode,
|
||
IN PCCB Ccb
|
||
);
|
||
|
||
|
||
//
|
||
// The following routines are used for setting and manipulating the
|
||
// security fields in the data entry, and nonpaged ccb, implemented in
|
||
// SecurSup.c
|
||
//
|
||
|
||
NTSTATUS
|
||
NpInitializeSecurity (
|
||
IN PCCB Ccb,
|
||
IN PSECURITY_QUALITY_OF_SERVICE SecurityQos,
|
||
IN PETHREAD UserThread
|
||
);
|
||
|
||
VOID
|
||
NpUninitializeSecurity (
|
||
IN PCCB Ccb
|
||
);
|
||
|
||
NTSTATUS
|
||
NpSetDataEntryClientContext (
|
||
IN NAMED_PIPE_END NamedPipeEnd,
|
||
IN PCCB Ccb,
|
||
IN PDATA_ENTRY DataEntry,
|
||
IN PETHREAD UserThread
|
||
);
|
||
|
||
VOID
|
||
NpCopyClientContext (
|
||
IN PCCB Ccb,
|
||
IN PDATA_ENTRY DataEntry
|
||
);
|
||
|
||
NTSTATUS
|
||
NpImpersonateClientContext (
|
||
IN PCCB Ccb
|
||
);
|
||
|
||
|
||
//
|
||
// The following routines are used to manipulate the named pipe state
|
||
// implemented in StateSup.c
|
||
//
|
||
|
||
VOID
|
||
NpInitializePipeState (
|
||
IN PCCB Ccb,
|
||
IN PFILE_OBJECT ServerFileObject
|
||
);
|
||
|
||
VOID
|
||
NpUninitializePipeState (
|
||
IN PCCB Ccb
|
||
);
|
||
|
||
NTSTATUS
|
||
NpSetListeningPipeState (
|
||
IN PCCB Ccb,
|
||
IN PIRP Irp
|
||
);
|
||
|
||
NTSTATUS
|
||
NpSetConnectedPipeState (
|
||
IN PCCB Ccb,
|
||
IN PFILE_OBJECT ClientFileObject
|
||
);
|
||
|
||
NTSTATUS
|
||
NpSetClosingPipeState (
|
||
IN PCCB Ccb,
|
||
IN PIRP Irp,
|
||
IN NAMED_PIPE_END NamedPipeEnd
|
||
);
|
||
|
||
NTSTATUS
|
||
NpSetDisconnectedPipeState (
|
||
IN PCCB Ccb
|
||
);
|
||
|
||
|
||
//
|
||
// Internal Named Pipe data Structure Routines, implemented in StrucSup.c.
|
||
//
|
||
// These routines maniuplate the in memory data structures.
|
||
//
|
||
|
||
VOID
|
||
NpInitializeVcb (
|
||
VOID
|
||
);
|
||
|
||
VOID
|
||
NpDeleteVcb (
|
||
VOID
|
||
);
|
||
|
||
VOID
|
||
NpCreateRootDcb (
|
||
VOID
|
||
);
|
||
|
||
VOID
|
||
NpDeleteRootDcb (
|
||
IN PROOT_DCB Dcb
|
||
);
|
||
|
||
PFCB
|
||
NpCreateFcb (
|
||
IN PDCB ParentDcb,
|
||
IN PUNICODE_STRING FileName,
|
||
IN ULONG MaximumInstances,
|
||
IN LARGE_INTEGER DefaultTimeOut,
|
||
IN NAMED_PIPE_CONFIGURATION NamedPipeConfiguration,
|
||
IN NAMED_PIPE_TYPE NamedPipeType
|
||
);
|
||
|
||
VOID
|
||
NpDeleteFcb (
|
||
IN PFCB Fcb
|
||
);
|
||
|
||
PCCB
|
||
NpCreateCcb (
|
||
IN PFCB Fcb,
|
||
IN PFILE_OBJECT ServerFileObject,
|
||
IN NAMED_PIPE_STATE NamedPipeState,
|
||
IN READ_MODE ServerReadMode,
|
||
IN COMPLETION_MODE ServerCompletionMode,
|
||
IN PEPROCESS CreatorProcess,
|
||
IN ULONG InBoundQuota,
|
||
IN ULONG OutBoundQuota
|
||
);
|
||
|
||
PROOT_DCB_CCB
|
||
NpCreateRootDcbCcb (
|
||
);
|
||
|
||
VOID
|
||
NpDeleteCcb (
|
||
IN PCCB Ccb
|
||
);
|
||
|
||
|
||
//
|
||
// Waiting for a named pipe support routines, implemented in WaitSup.c
|
||
//
|
||
|
||
VOID
|
||
NpInitializeWaitQueue (
|
||
IN PWAIT_QUEUE WaitQueue
|
||
);
|
||
|
||
VOID
|
||
NpUninitializeWaitQueue (
|
||
IN PWAIT_QUEUE WaitQueue
|
||
);
|
||
|
||
VOID
|
||
NpAddWaiter (
|
||
IN PWAIT_QUEUE WaitQueue,
|
||
IN LARGE_INTEGER DefaultTimeOut,
|
||
IN PIRP Irp
|
||
);
|
||
|
||
VOID
|
||
NpCancelWaiter (
|
||
IN PWAIT_QUEUE WaitQueue,
|
||
IN PUNICODE_STRING NameOfPipe
|
||
);
|
||
|
||
|
||
//
|
||
// The follow routine provides common write data queue support
|
||
// for buffered write, unbuffered write, peek, and transceive
|
||
//
|
||
|
||
BOOLEAN
|
||
NpWriteDataQueue ( // implemented in WriteSup.c
|
||
IN PDATA_QUEUE WriteQueue,
|
||
IN READ_MODE ReadMode,
|
||
IN PUCHAR WriteBuffer,
|
||
IN ULONG WriteLength,
|
||
IN NAMED_PIPE_TYPE PipeType,
|
||
OUT PULONG WriteRemaining,
|
||
IN PCCB Ccb,
|
||
IN NAMED_PIPE_END NamedPipeEnd,
|
||
IN PETHREAD UserThread
|
||
);
|
||
|
||
|
||
//
|
||
// Miscellaneous support routines
|
||
//
|
||
|
||
#define BooleanFlagOn(F,SF) ( \
|
||
(BOOLEAN)(((F) & (SF)) != 0) \
|
||
)
|
||
|
||
//
|
||
// This macro takes a pointer (or ulong) and returns its rounded up word
|
||
// value
|
||
//
|
||
|
||
#define WordAlign(Ptr) ( \
|
||
((((ULONG)(Ptr)) + 1) & 0xfffffffe) \
|
||
)
|
||
|
||
//
|
||
// This macro takes a pointer (or ulong) and returns its rounded up longword
|
||
// value
|
||
//
|
||
|
||
#define LongAlign(Ptr) ( \
|
||
((((ULONG)(Ptr)) + 3) & 0xfffffffc) \
|
||
)
|
||
|
||
//
|
||
// This macro takes a pointer (or ulong) and returns its rounded up quadword
|
||
// value
|
||
//
|
||
|
||
#define QuadAlign(Ptr) ( \
|
||
((((ULONG)(Ptr)) + 7) & 0xfffffff8) \
|
||
)
|
||
|
||
//
|
||
// The following types and macros are used to help unpack the packed and
|
||
// misaligned fields found in the Bios parameter block
|
||
//
|
||
|
||
typedef union _UCHAR1 {
|
||
UCHAR Uchar[1];
|
||
UCHAR ForceAlignment;
|
||
} UCHAR1, *PUCHAR1;
|
||
|
||
typedef union _UCHAR2 {
|
||
UCHAR Uchar[2];
|
||
USHORT ForceAlignment;
|
||
} UCHAR2, *PUCHAR2;
|
||
|
||
typedef union _UCHAR4 {
|
||
UCHAR Uchar[4];
|
||
ULONG ForceAlignment;
|
||
} UCHAR4, *PUCHAR4;
|
||
|
||
//
|
||
// This macro copies an unaligned src byte to an aligned dst byte
|
||
//
|
||
|
||
#define CopyUchar1(Dst,Src) { \
|
||
*((UCHAR1 *)(Dst)) = *((UNALIGNED UCHAR1 *)(Src)); \
|
||
}
|
||
|
||
//
|
||
// This macro copies an unaligned src word to an aligned dst word
|
||
//
|
||
|
||
#define CopyUchar2(Dst,Src) { \
|
||
*((UCHAR2 *)(Dst)) = *((UNALIGNED UCHAR2 *)(Src)); \
|
||
}
|
||
|
||
//
|
||
// This macro copies an unaligned src longword to an aligned dsr longword
|
||
//
|
||
|
||
#define CopyUchar4(Dst,Src) { \
|
||
*((UCHAR4 *)(Dst)) = *((UNALIGNED UCHAR4 *)(Src)); \
|
||
}
|
||
|
||
|
||
//
|
||
// VOID
|
||
// NpAcquireExclusiveVcb (
|
||
// );
|
||
//
|
||
// VOID
|
||
// NpAcquireSharedVcb (
|
||
// );
|
||
//
|
||
// VOID
|
||
// NpReleaseVcb (
|
||
// );
|
||
//
|
||
|
||
#define NpAcquireExclusiveVcb() (VOID)ExAcquireResourceExclusive( &NpVcb->Resource, TRUE )
|
||
|
||
#define NpAcquireSharedVcb() (VOID)ExAcquireResourceShared( &NpVcb->Resource, TRUE )
|
||
|
||
#define NpReleaseVcb() ExReleaseResource( &NpVcb->Resource )
|
||
|
||
#define NpAcquireExclusiveCcb(Ccb) ExAcquireResourceExclusive(&Ccb->NonpagedCcb->Resource,TRUE);
|
||
#define NpReleaseCcb(Ccb) ExReleaseResource(&Ccb->NonpagedCcb->Resource);
|
||
|
||
|
||
|
||
//
|
||
// The FSD Level dispatch routines. These routines are called by the
|
||
// I/O system via the dispatch table in the Driver Object.
|
||
//
|
||
// They each accept as input a pointer to a device object (actually most
|
||
// expect an npfs device object), and a pointer to the IRP.
|
||
//
|
||
|
||
NTSTATUS
|
||
NpFsdCreate ( // implemented in Create.c
|
||
IN PNPFS_DEVICE_OBJECT NpfsDeviceObject,
|
||
IN PIRP Irp
|
||
);
|
||
|
||
NTSTATUS
|
||
NpFsdCreateNamedPipe ( // implemented in CreateNp.c
|
||
IN PNPFS_DEVICE_OBJECT NpfsDeviceObject,
|
||
IN PIRP Irp
|
||
);
|
||
|
||
NTSTATUS
|
||
NpFsdClose ( // implemented in Close.c
|
||
IN PNPFS_DEVICE_OBJECT NpfsDeviceObject,
|
||
IN PIRP Irp
|
||
);
|
||
|
||
NTSTATUS
|
||
NpFsdRead ( // implemented in Read.c
|
||
IN PNPFS_DEVICE_OBJECT NpfsDeviceObject,
|
||
IN PIRP Irp
|
||
);
|
||
|
||
NTSTATUS
|
||
NpFsdWrite ( // implemented in Write.c
|
||
IN PNPFS_DEVICE_OBJECT NpfsDeviceObject,
|
||
IN PIRP Irp
|
||
);
|
||
|
||
NTSTATUS
|
||
NpFsdQueryInformation ( // implemented in FileInfo.c
|
||
IN PNPFS_DEVICE_OBJECT NpfsDeviceObject,
|
||
IN PIRP Irp
|
||
);
|
||
|
||
NTSTATUS
|
||
NpFsdSetInformation ( // implemented in FileInfo.c
|
||
IN PNPFS_DEVICE_OBJECT NpfsDeviceObject,
|
||
IN PIRP Irp
|
||
);
|
||
|
||
NTSTATUS
|
||
NpFsdCleanup ( // implemented in Cleanup.c
|
||
IN PNPFS_DEVICE_OBJECT NpfsDeviceObject,
|
||
IN PIRP Irp
|
||
);
|
||
|
||
NTSTATUS
|
||
NpFsdFlushBuffers ( // implemented in Flush.c
|
||
IN PNPFS_DEVICE_OBJECT NpfsDeviceObject,
|
||
IN PIRP Irp
|
||
);
|
||
|
||
NTSTATUS
|
||
NpFsdDirectoryControl ( // implemented in Dir.c
|
||
IN PNPFS_DEVICE_OBJECT NpfsDeviceObject,
|
||
IN PIRP Irp
|
||
);
|
||
|
||
NTSTATUS
|
||
NpFsdFileSystemControl ( // implemented in FsContrl.c
|
||
IN PNPFS_DEVICE_OBJECT NpfsDeviceObject,
|
||
IN PIRP Irp
|
||
);
|
||
|
||
NTSTATUS
|
||
NpFsdSetSecurityInfo ( // implemented in SeInfo.c
|
||
IN PNPFS_DEVICE_OBJECT NpfsDeviceObject,
|
||
IN PIRP Irp
|
||
);
|
||
|
||
NTSTATUS
|
||
NpFsdQuerySecurityInfo ( // implemented in SeInfo.c
|
||
IN PNPFS_DEVICE_OBJECT NpfsDeviceObject,
|
||
IN PIRP Irp
|
||
);
|
||
|
||
NTSTATUS
|
||
NpFsdQueryVolumeInformation ( // implemented in VolInfo.c
|
||
IN PNPFS_DEVICE_OBJECT NpfsDeviceObject,
|
||
IN PIRP Irp
|
||
);
|
||
|
||
|
||
//
|
||
// The following procedures are callbacks used to do fast I/O
|
||
//
|
||
|
||
BOOLEAN
|
||
NpFastRead (
|
||
IN PFILE_OBJECT FileObject,
|
||
IN PLARGE_INTEGER FileOffset,
|
||
IN ULONG Length,
|
||
IN BOOLEAN Wait,
|
||
IN ULONG LockKey,
|
||
OUT PVOID Buffer,
|
||
OUT PIO_STATUS_BLOCK IoStatus,
|
||
IN PDEVICE_OBJECT DeviceObject
|
||
);
|
||
|
||
BOOLEAN
|
||
NpFastWrite (
|
||
IN PFILE_OBJECT FileObject,
|
||
IN PLARGE_INTEGER FileOffset,
|
||
IN ULONG Length,
|
||
IN BOOLEAN Wait,
|
||
IN ULONG LockKey,
|
||
IN PVOID Buffer,
|
||
OUT PIO_STATUS_BLOCK IoStatus,
|
||
IN PDEVICE_OBJECT DeviceObject
|
||
);
|
||
|
||
|
||
//
|
||
// Miscellaneous routines.
|
||
//
|
||
|
||
VOID
|
||
NpCheckForNotify ( // implemented in Dir.c
|
||
IN PDCB Dcb,
|
||
IN BOOLEAN CheckAllOutstandingIrps
|
||
);
|
||
|
||
//
|
||
// The following macro is used by the FSD routines to complete
|
||
// an IRP.
|
||
//
|
||
|
||
#define NpCompleteRequest(IRP,STATUS) { \
|
||
IoSetCancelRoutine( (IRP), NULL ); \
|
||
FsRtlCompleteRequest( (IRP), (STATUS) ); \
|
||
}
|
||
|
||
|
||
//
|
||
// The following two macro are used by the Fsd exception handlers to
|
||
// process an exception. The first macro is the exception filter used in the
|
||
// Fsd to decide if an exception should be handled at this level.
|
||
// The second macro decides if the exception is to be finished off by
|
||
// completing the IRP, and cleaning up the Irp Context, or if we should
|
||
// bugcheck. Exception values such as STATUS_FILE_INVALID (raised by
|
||
// VerfySup.c) cause us to complete the Irp and cleanup, while exceptions
|
||
// such as accvio cause us to bugcheck.
|
||
//
|
||
// The basic structure for fsd exception handling is as follows:
|
||
//
|
||
// NpFsdXxx(...)
|
||
// {
|
||
// try {
|
||
//
|
||
// ...
|
||
//
|
||
// } except(NpExceptionFilter( GetExceptionCode() )) {
|
||
//
|
||
// Status = NpProcessException( NpfsDeviceObject, Irp, GetExceptionCode() );
|
||
// }
|
||
//
|
||
// Return Status;
|
||
// }
|
||
//
|
||
|
||
LONG
|
||
NpExceptionFilter (
|
||
IN NTSTATUS ExceptionCode
|
||
);
|
||
|
||
NTSTATUS
|
||
NpProcessException (
|
||
IN PNPFS_DEVICE_OBJECT NpfsDeviceObject,
|
||
IN PIRP Irp,
|
||
IN NTSTATUS ExceptionCode
|
||
);
|
||
|
||
|
||
//
|
||
// The following macros are used to establish the semantics needed
|
||
// to do a return from within a try-finally clause. As a rule every
|
||
// try clause must end with a label call try_exit. For example,
|
||
//
|
||
// try {
|
||
// :
|
||
// :
|
||
//
|
||
// try_exit: NOTHING;
|
||
// } finally {
|
||
//
|
||
// :
|
||
// :
|
||
// }
|
||
//
|
||
// Every return statement executed inside of a try clause should use the
|
||
// try_return macro. If the compiler fully supports the try-finally construct
|
||
// then the macro should be
|
||
//
|
||
// #define try_return(S) { return(S); }
|
||
//
|
||
// If the compiler does not support the try-finally construct then the macro
|
||
// should be
|
||
//
|
||
// #define try_return(S) { S; goto try_exit; }
|
||
//
|
||
|
||
#define try_return(S) { S; goto try_exit; }
|
||
|
||
#endif // _NPPROCS_
|