|
|
/*++
Copyright (c) 1989 Microsoft Corporation
Module Name:
msfuncs.h
Abstract:
This module defines all of the globally used procedures in the mailslot file system. It also defines the functions that are implemented as macros.
Author:
Manny Weiser (mannyw) 7-Jan-1991
Revision History:
--*/
#ifndef _MSFUNCS_
#define _MSFUNCS_
//
// Internal mailslot data Structure Routines, implemented in strucsup.c.
// These routines maniuplate the in memory data structures.
//
NTSTATUS MsInitializeData ( VOID );
VOID MsUninitializeData( VOID );
VOID MsInitializeVcb ( IN PVCB Vcb );
VOID MsDeleteVcb ( IN PVCB Vcb );
PROOT_DCB MsCreateRootDcb ( IN PVCB Vcb );
VOID MsDeleteRootDcb ( IN PROOT_DCB Dcb );
NTSTATUS MsCreateFcb ( IN PVCB Vcb, IN PDCB ParentDcb, IN PUNICODE_STRING FileName, IN PEPROCESS CreatorProcess, IN ULONG MailslotQuota, IN ULONG MaximumMessageSize, OUT PFCB *ppFcb );
VOID MsDeleteFcb ( IN PFCB Fcb );
NTSTATUS MsCreateCcb ( IN PFCB Fcb, OUT PCCB *ppCcb );
PROOT_DCB_CCB MsCreateRootDcbCcb ( IN PROOT_DCB RootDcb, IN PVCB Vcb );
VOID MsDeleteCcb ( IN PCCB Ccb );
VOID MsDereferenceNode ( IN PNODE_HEADER NodeHeader );
VOID MsDereferenceVcb ( IN PVCB Vcb );
VOID MsReferenceVcb ( IN PVCB Vcb );
VOID MsReferenceRootDcb ( IN PROOT_DCB RootDcb );
VOID MsDereferenceRootDcb ( IN PROOT_DCB RootDcb );
VOID MsDereferenceFcb ( IN PFCB Fcb );
VOID MsRemoveFcbName ( IN PFCB Fcb );
VOID MsDereferenceCcb ( IN PCCB Ccb );
//
// Data queue support routines, implemented in DataSup.c
//
NTSTATUS MsInitializeDataQueue ( IN PDATA_QUEUE DataQueue, IN PEPROCESS Process, IN ULONG Quota, IN ULONG MaximumMessageSize );
VOID MsUninitializeDataQueue ( IN PDATA_QUEUE DataQueue, IN PEPROCESS Process );
NTSTATUS MsAddDataQueueEntry ( IN PDATA_QUEUE DataQueue, IN QUEUE_STATE Who, IN ULONG DataSize, IN PIRP Irp, IN PWORK_CONTEXT WorkContext );
PIRP MsRemoveDataQueueEntry ( IN PDATA_QUEUE DataQueue, IN PDATA_ENTRY DataEntry );
VOID MsRemoveDataQueueIrp ( IN PIRP Irp, IN PDATA_QUEUE DataQueue );
//
// The follow routines provide common read/write data queue support
// for buffered read/write, and peek
//
IO_STATUS_BLOCK MsReadDataQueue ( // implemented in ReadSup.c
IN PDATA_QUEUE ReadQueue, IN ENTRY_TYPE Operation, IN PUCHAR ReadBuffer, IN ULONG ReadLength, OUT PULONG MessageLength );
NTSTATUS MsWriteDataQueue ( // implemented in WriteSup.c
IN PDATA_QUEUE WriteQueue, IN PUCHAR WriteBuffer, IN ULONG WriteLength ); extern PIRP MsResetCancelRoutine( IN PIRP Irp );
//
// Largest matching prefix searching routines, implemented in PrefxSup.c
//
PFCB MsFindPrefix ( IN PVCB Vcb, IN PUNICODE_STRING String, IN BOOLEAN CaseInsensitive, OUT PUNICODE_STRING RemainingPart );
NTSTATUS MsFindRelativePrefix ( IN PDCB Dcb, IN PUNICODE_STRING String, IN BOOLEAN CaseInsensitive, OUT PUNICODE_STRING RemainingPart, OUT PFCB *Fcb );
//
// The following routines are used to manipulate the fscontext fields of
// a file object, implemented in FilObSup.c
//
VOID MsSetFileObject ( IN PFILE_OBJECT FileObject OPTIONAL, IN PVOID FsContext, IN PVOID FsContext2 );
NODE_TYPE_CODE MsDecodeFileObject ( IN PFILE_OBJECT FileObject, OUT PVOID *FsContext, OUT PVOID *FsContext2 );
//
// The following routines are used to manipulate the input buffers and are
// implemented in deviosup.c
//
VOID MsMapUserBuffer ( IN OUT PIRP Irp, IN KPROCESSOR_MODE AccessMode, OUT PVOID *UserBuffer );
//
// Miscellaneous support routines
//
//
// This is function is called at DPC level if a read timer expires.
//
VOID MsReadTimeoutHandler( IN PKDPC Dpc, IN PVOID DeferredContext, IN PVOID SystemArgument1, IN PVOID SystemArgument2 );
//
// This macro returns TRUE if a flag in a set of flags is on and FALSE
// otherwise.
//
#ifdef FlagOn
#undef FlagOn
#endif
#define FlagOn(Flags,SingleFlag) ( \
(BOOLEAN)(((Flags) & (SingleFlag)) != 0 ? TRUE : FALSE) \ )
//
// 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)); \ }
//
// The following routines/macros are used for gaining shared and exclusive
// access to the global/vcb data structures. The routines are implemented
// in ResrcSup.c. There is a global resources that everyone tries to take
// out shared to do their work, with the exception of mount/dismount which
// take out the global resource exclusive. All other resources only work
// on their individual item. For example, an Fcb resource does not take out
// a Vcb resource. But the way the file system is structured we know
// that when we are processing an Fcb other threads cannot be trying to remove
// or alter the Fcb, so we do not need to acquire the Vcb.
//
// The procedures/macros are:
//
// Macro Vcb Fcb Ccb Subsequent macros
//
// AcquireExclusiveVcb Read None None ReleaseVcb
// Write
//
// AcquireSharedVcb Read None None ReleaseVcb
//
// AcquireExclusiveFcb None Read None ReleaseFcb
// Write
//
// AcquireSharedFcb None Read None ReleaseFcb
//
// AcquireExclusiveCcb None None Read ReleaseCcb
// Write
//
// AcquireSharedCcb None None Read ReleaseCcb
//
// ReleaseVcb
//
// ReleaseFcb
//
// ReleaseCcb
//
//
// VOID
// MsAcquireExclusiveVcb (
// IN PVCB Vcb
// );
//
// VOID
// MsAcquireSharedVcb (
// IN PVCB Vcb
// );
//
// VOID
// MsAcquireExclusiveFcb (
// IN PFCB Fcb
// );
//
// VOID
// MsAcquireSharedFcb (
// IN PFCB Fcb
// );
//
// VOID
// MsAcquireExclusiveCcb (
// IN PCCB Ccb
// );
//
// VOID
// MsAcquireSharedCcb (
// IN PCCB Ccb
// );
//
// VOID
// MsReleaseVcb (
// IN PVCB Vcb
// );
//
// VOID
// MsReleaseFcb (
// IN PFCB Fcb
// );
//
// VOID
// MsReleaseCcb (
// IN PCCB NonpagedCcb
// );
//
#define MsAcquireGlobalLock() ((VOID) \
ExAcquireResourceExclusiveLite( MsGlobalResource, TRUE ) \ )
#define MsReleaseGlobalLock() ( \
ExReleaseResourceLite( MsGlobalResource ) \ )
#define MsAcquireExclusiveVcb(VCB) ((VOID) \
ExAcquireResourceExclusiveLite( &(VCB)->Resource, TRUE ) \ )
#define MsAcquireSharedVcb(VCB) ((VOID) \
ExAcquireResourceSharedLite( &(VCB)->Resource, TRUE ) \ )
#define MsIsAcquiredExclusiveVcb(VCB) ExIsResourceAcquiredExclusiveLite( &(VCB)->Resource )
#define MsAcquireExclusiveFcb(FCB) ((VOID) \
ExAcquireResourceExclusiveLite( &(FCB)->Resource, TRUE ) \ )
#define MsAcquireSharedFcb(FCB) ((VOID) \
ExAcquireResourceSharedLite( &(FCB)->Resource, TRUE ) \ )
#define MsReleaseVcb(VCB) { \
ExReleaseResourceLite( &((VCB)->Resource) ); \ }
#define MsReleaseFcb(FCB) { \
ExReleaseResourceLite( &((FCB)->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 msfs device object), and a pointer to the IRP.
//
NTSTATUS MsFsdCreate ( // implemented in Create.c
IN PMSFS_DEVICE_OBJECT MsfsDeviceObject, IN PIRP Irp );
NTSTATUS MsFsdCreateMailslot ( // implemented in Createms.c
IN PMSFS_DEVICE_OBJECT MsfsDeviceObject, IN PIRP Irp );
NTSTATUS MsFsdClose ( // implemented in Close.c
IN PMSFS_DEVICE_OBJECT MsfsDeviceObject, IN PIRP Irp );
NTSTATUS MsFsdRead ( // implemented in Read.c
IN PMSFS_DEVICE_OBJECT MsfsDeviceObject, IN PIRP Irp );
NTSTATUS MsFsdWrite ( // implemented in Write.c
IN PMSFS_DEVICE_OBJECT MsfsDeviceObject, IN PIRP Irp );
NTSTATUS MsFsdQueryInformation ( // implemented in FileInfo.c
IN PMSFS_DEVICE_OBJECT MsfsDeviceObject, IN PIRP Irp );
NTSTATUS MsFsdSetInformation ( // implemented in FileInfo.c
IN PMSFS_DEVICE_OBJECT MsfsDeviceObject, IN PIRP Irp );
NTSTATUS MsFsdQueryVolumeInformation ( // implemented in VolInfo.c
IN PMSFS_DEVICE_OBJECT MsfsDeviceObject, IN PIRP Irp );
NTSTATUS MsFsdCleanup ( // implemented in Cleanup.c
IN PMSFS_DEVICE_OBJECT MsfsDeviceObject, IN PIRP Irp );
VOID MsCancelTimer ( // implemented in Cleanup.c
IN PDATA_ENTRY DataEntry );
NTSTATUS MsFsdDirectoryControl ( // implemented in Dir.c
IN PMSFS_DEVICE_OBJECT MsfsDeviceObject, IN PIRP Irp );
NTSTATUS MsFsdFsControl ( // implemented in FsContrl.c
IN PMSFS_DEVICE_OBJECT MsfsDeviceObject, IN PIRP Irp );
NTSTATUS MsFsdQuerySecurityInfo ( IN PMSFS_DEVICE_OBJECT MsfsDeviceObject, IN PIRP Irp );
NTSTATUS MsFsdSetSecurityInfo ( IN PMSFS_DEVICE_OBJECT MsfsDeviceObject, IN PIRP Irp );
//
// The node verification functions. These functions verify that a node
// is still active.
//
NTSTATUS MsVerifyFcb ( IN PFCB Fcb );
NTSTATUS MsVerifyCcb ( IN PCCB Ccb );
NTSTATUS MsVerifyDcbCcb ( IN PROOT_DCB_CCB RootDcb );
//
// Miscellaneous routines.
//
VOID MsTimeoutRead ( // implemented in readsup.c
IN PDEVICE_OBJECT DeviceObject, IN PVOID Context );
VOID MsCheckForNotify ( // implemented in Dir.c
IN PDCB Dcb, IN BOOLEAN CheckAllOutstandingIrps, IN NTSTATUS FinalStatus );
VOID MsFlushNotifyForFile ( // implemented in Dir.c
IN PDCB Dcb, IN PFILE_OBJECT FileObject ); //
// The following functions are used for MSFS exception handling
//
LONG MsExceptionFilter ( IN NTSTATUS ExceptionCode );
NTSTATUS MsProcessException ( IN PMSFS_DEVICE_OBJECT MsfsDeviceObject, IN PIRP Irp, IN NTSTATUS ExceptionCode );
//
// The following macro is used by the FSP and FSD routines to complete
// an IRP.
//
#define MsCompleteRequest(IRP,STATUS) { \
FsRtlCompleteRequest( (IRP), (STATUS) ); \ }
//
// Reference count macros. These macro can be called only with
// MsGlobalResource held.
//
#define MsReferenceNode( nodeHeader ) (nodeHeader)->ReferenceCount++;
//
// Debugging functions.
//
#ifdef MSDBG
VOID _DebugTrace( LONG Indent, ULONG Level, PSZ X, ULONG Y );
#endif
//
// 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; }
//
// The following macros queries the state of data queues
//
//
// BOOLEAN
// MsIsDataQueueEmpty (
// IN PDATA_QUEUE DataQueue
// )
//
// Routine Description:
//
// This routine indicates to the caller if the data queue is empty.
//
// Arguments:
//
// DataQueue - Supplies a pointer to the data queue being queried
//
// Return Value:
//
// BOOLEAN - TRUE if the queue is empty and FALSE otherwise.
//
#define MsIsDataQueueEmpty( _dataQueue ) \
((BOOLEAN) IsListEmpty(&(_dataQueue)->DataEntryList))
//
// BOOLEAN
// MsIsDataQueueReaders (
// IN PDATA_QUEUE DataQueue
// )
//
// Routine Description:
//
// This routine indicates to the caller if the data queue is full of
// read requests.
//
// Arguments:
//
// DataQueue - Supplies a pointer to the data queue being queried
//
// Return Value:
//
// BOOLEAN - TRUE if the queue contains read requests and FALSE otherwise
//
#define MsIsDataQueueReaders( _dataQueue ) \
((BOOLEAN) ((_dataQueue)->QueueState == ReadEntries))
//
// BOOLEAN
// MsIsDataQueueWriters (
// IN PDATA_QUEUE DataQueue
// )
//
// Routine Description:
//
// This routine indicates to the caller if the data queue is full of
// write requests.
//
// Arguments:
//
// DataQueue - Supplies a pointer to the data queue being queried
//
// Return Value:
//
// BOOLEAN - TRUE if the queue contains write requests and FALSE otherwise
#define MsIsDataQueueWriters( _dataQueue ) \
((BOOLEAN)((_dataQueue)->QueueState == WriteEntries))
//
// PLIST_ENTRY
// MsGetNextDataQueueEntry (
// IN PDATA_QUEUE DataQueue
// )
//
// Routine Description:
//
// This routine will return a pointer to the next data queue entry in the
// indicated data queue without changing any of the data queue.
//
// Arguments:
//
// DataQueue - Supplies a pointer to the data queue being queried.
//
// Return Value:
//
// PLIST_ENTRY - Returns a pointer to the next data queue entry.
//
#define MsGetNextDataQueueEntry( _dataQueue ) \
(_dataQueue)->DataEntryList.Flink
#define MsIrpDataQueue(Irp) \
((Irp)->Tail.Overlay.DriverContext[0])
#define MsIrpChargedQuota(Irp) \
((Irp)->Tail.Overlay.DriverContext[1])
#define MsIrpWorkContext(Irp) \
((Irp)->Tail.Overlay.DriverContext[2])
//
// PVOID
// MsAllocatePagedPool (
// IN ULONG Size,
// IN ULONG Tag)
// Routine Description:
//
// This routine will return a pointer to paged pool or NULL if no memory exists.
//
// Arguments:
//
// Size - Size of memory to allocate
// Tag - Tag to use for the pool allocation
//
// Return Value:
//
// PVOID - pointer to allocated memory or null
//
#define MsAllocatePagedPool( Size, Tag) \
ExAllocatePoolWithTag( PagedPool, Size, Tag )
#define MsAllocatePagedPoolCold( Size, Tag) \
ExAllocatePoolWithTag( (PagedPool|POOL_COLD_ALLOCATION), Size, Tag )
//
// PVOID
// MsAllocateNonPagedPool (
// IN ULONG Size,
// IN ULONG Tag)
// Routine Description:
//
// This routine will return a pointer to paged pool or NULL if no memory exists.
//
// Arguments:
//
// Size - Size of memory to allocate
// Tag - Tag to use for the pool allocation
//
// Return Value:
//
// PVOID - pointer to allocated memory or null
//
#define MsAllocateNonPagedPool( Size, Tag) \
ExAllocatePoolWithTag( NonPagedPool, Size, Tag )
//
// PVOID
// MsAllocatePagedPoolWithQuota (
// IN ULONG Size,
// IN ULONG Tag)
// Routine Description:
//
// This routine will return a pointer to charged paged pool or NULL if no memory exists.
//
// Arguments:
//
// Size - Size of memory to allocate
// Tag - Tag to use for the pool allocation
//
// Return Value:
//
// PVOID - pointer to allocated memory or null
//
#define MsAllocatePagedPoolWithQuota( Size, Tag) \
ExAllocatePoolWithQuotaTag( PagedPool|POOL_QUOTA_FAIL_INSTEAD_OF_RAISE, Size, Tag )
#define MsAllocatePagedPoolWithQuotaCold( Size, Tag) \
ExAllocatePoolWithQuotaTag( PagedPool|POOL_QUOTA_FAIL_INSTEAD_OF_RAISE|POOL_COLD_ALLOCATION, Size, Tag )
//
// PVOID
// MsAllocateNonPagedPoolWithQuota (
// IN ULONG Size,
// IN ULONG Tag)
// Routine Description:
//
// This routine will return a charged pointer to non-paged pool or NULL if no memory exists.
//
// Arguments:
//
// Size - Size of memory to allocate
// Tag - Tag to use for the pool allocation
//
// Return Value:
//
// PVOID - pointer to allocated memory or null
//
#define MsAllocateNonPagedPoolWithQuota( Size, Tag) \
ExAllocatePoolWithQuotaTag( NonPagedPool|POOL_QUOTA_FAIL_INSTEAD_OF_RAISE, Size, Tag )
//
// VOID
// MsFreePool (
// IN PVOID Mem)
//
// Routine Description:
//
//
//
// Arguments:
//
// Mem - Memory to be freed
//
// Return Value:
//
// None
//
#define MsFreePool(Mem) ExFreePool (Mem)
#endif // _MSFUNCS_
|