windows-nt/Source/XPSP1/NT/base/fs/mailslot/msfunc.h
2020-09-26 16:20:57 +08:00

908 lines
18 KiB
C
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*++
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_