reactos/sdk/include/ddk/rxcontx.h
2019-01-02 15:02:15 +01:00

547 lines
17 KiB
C

#ifndef _RX_CONTEXT_STRUCT_DEFINED_
#define _RX_CONTEXT_STRUCT_DEFINED_
#define RX_TOPLEVELIRP_CONTEXT_SIGNATURE 'LTxR'
typedef struct _RX_TOPLEVELIRP_CONTEXT
{
union
{
#ifndef __cplusplus
LIST_ENTRY;
#endif
LIST_ENTRY ListEntry;
};
ULONG Signature;
PRDBSS_DEVICE_OBJECT RxDeviceObject;
PRX_CONTEXT RxContext;
PIRP Irp;
ULONG Flags;
PVOID Previous;
PETHREAD Thread;
} RX_TOPLEVELIRP_CONTEXT, *PRX_TOPLEVELIRP_CONTEXT;
BOOLEAN
RxTryToBecomeTheTopLevelIrp(
_Inout_ PRX_TOPLEVELIRP_CONTEXT TopLevelContext,
_In_ PIRP Irp,
_In_ PRDBSS_DEVICE_OBJECT RxDeviceObject,
_In_ BOOLEAN ForceTopLevel);
VOID
__RxInitializeTopLevelIrpContext(
_Inout_ PRX_TOPLEVELIRP_CONTEXT TopLevelContext,
_In_ PIRP Irp,
_In_ PRDBSS_DEVICE_OBJECT RxDeviceObject,
_In_ ULONG Flags);
#define RxInitializeTopLevelIrpContext(a,b,c) __RxInitializeTopLevelIrpContext(a,b,c,0)
PIRP
RxGetTopIrpIfRdbssIrp(
VOID);
PRDBSS_DEVICE_OBJECT
RxGetTopDeviceObjectIfRdbssIrp(
VOID);
VOID
RxUnwindTopLevelIrp(
_Inout_ PRX_TOPLEVELIRP_CONTEXT TopLevelContext);
BOOLEAN
RxIsThisTheTopLevelIrp(
_In_ PIRP Irp);
#ifdef RDBSS_TRACKER
typedef struct _RX_FCBTRACKER_CALLINFO
{
ULONG AcquireRelease;
USHORT SavedTrackerValue;
USHORT LineNumber;
PSZ FileName;
ULONG Flags;
} RX_FCBTRACKER_CALLINFO, *PRX_FCBTRACKER_CALLINFO;
#define RDBSS_TRACKER_HISTORY_SIZE 32
#endif
#define MRX_CONTEXT_FIELD_COUNT 4
#if (_WIN32_WINNT >= 0x0600)
typedef
NTSTATUS
(NTAPI *PRX_DISPATCH) (
_In_ PRX_CONTEXT RxContext,
_In_ PIRP Irp);
#else
typedef
NTSTATUS
(NTAPI *PRX_DISPATCH) (
_In_ PRX_CONTEXT RxContext);
#endif
typedef struct _DFS_NAME_CONTEXT_ *PDFS_NAME_CONTEXT;
typedef struct _NT_CREATE_PARAMETERS
{
ACCESS_MASK DesiredAccess;
LARGE_INTEGER AllocationSize;
ULONG FileAttributes;
ULONG ShareAccess;
ULONG Disposition;
ULONG CreateOptions;
PIO_SECURITY_CONTEXT SecurityContext;
SECURITY_IMPERSONATION_LEVEL ImpersonationLevel;
PVOID DfsContext;
PDFS_NAME_CONTEXT DfsNameContext;
} NT_CREATE_PARAMETERS, *PNT_CREATE_PARAMETERS;
typedef struct _RX_CONTEXT
{
NODE_TYPE_CODE NodeTypeCode;
NODE_BYTE_SIZE NodeByteSize;
volatile ULONG ReferenceCount;
LIST_ENTRY ContextListEntry;
UCHAR MajorFunction;
UCHAR MinorFunction;
BOOLEAN PendingReturned;
BOOLEAN PostRequest;
PDEVICE_OBJECT RealDevice;
PIRP CurrentIrp;
PIO_STACK_LOCATION CurrentIrpSp;
PMRX_FCB pFcb;
PMRX_FOBX pFobx;
PMRX_SRV_OPEN pRelevantSrvOpen;
PNON_PAGED_FCB NonPagedFcb;
PRDBSS_DEVICE_OBJECT RxDeviceObject;
PETHREAD OriginalThread;
PETHREAD LastExecutionThread;
volatile PVOID LockManagerContext;
PVOID RdbssDbgExtension;
RX_SCAVENGER_ENTRY ScavengerEntry;
ULONG SerialNumber;
ULONG FobxSerialNumber;
ULONG Flags;
BOOLEAN FcbResourceAcquired;
BOOLEAN FcbPagingIoResourceAcquired;
UCHAR MustSucceedDescriptorNumber;
union
{
struct
{
union
{
NTSTATUS StoredStatus;
PVOID StoredStatusAlignment;
};
ULONG_PTR InformationToReturn;
};
IO_STATUS_BLOCK IoStatusBlock;
};
union
{
ULONGLONG ForceLonglongAligmentDummyField;
PVOID MRxContext[MRX_CONTEXT_FIELD_COUNT];
};
PVOID WriteOnlyOpenRetryContext;
PMRX_CALLDOWN MRxCancelRoutine;
PRX_DISPATCH ResumeRoutine;
RX_WORK_QUEUE_ITEM WorkQueueItem;
LIST_ENTRY OverflowListEntry;
KEVENT SyncEvent;
LIST_ENTRY BlockedOperations;
PFAST_MUTEX BlockedOpsMutex;
LIST_ENTRY RxContextSerializationQLinks;
union
{
struct
{
union
{
FS_INFORMATION_CLASS FsInformationClass;
FILE_INFORMATION_CLASS FileInformationClass;
};
PVOID Buffer;
union
{
LONG Length;
LONG LengthRemaining;
};
BOOLEAN ReplaceIfExists;
BOOLEAN AdvanceOnly;
} Info;
struct
{
UNICODE_STRING SuppliedPathName;
NET_ROOT_TYPE NetRootType;
PIO_SECURITY_CONTEXT pSecurityContext;
} PrefixClaim;
};
union
{
struct
{
NT_CREATE_PARAMETERS NtCreateParameters;
ULONG ReturnedCreateInformation;
PWCH CanonicalNameBuffer;
PRX_PREFIX_ENTRY NetNamePrefixEntry;
PMRX_SRV_CALL pSrvCall;
PMRX_NET_ROOT pNetRoot;
PMRX_V_NET_ROOT pVNetRoot;
PVOID EaBuffer;
ULONG EaLength;
ULONG SdLength;
ULONG PipeType;
ULONG PipeReadMode;
ULONG PipeCompletionMode;
USHORT Flags;
NET_ROOT_TYPE Type;
UCHAR RdrFlags;
BOOLEAN FcbAcquired;
BOOLEAN TryForScavengingOnSharingViolation;
BOOLEAN ScavengingAlreadyTried;
BOOLEAN ThisIsATreeConnectOpen;
BOOLEAN TreeConnectOpenDeferred;
UNICODE_STRING TransportName;
UNICODE_STRING UserName;
UNICODE_STRING Password;
UNICODE_STRING UserDomainName;
} Create;
struct
{
ULONG FileIndex;
BOOLEAN RestartScan;
BOOLEAN ReturnSingleEntry;
BOOLEAN IndexSpecified;
BOOLEAN InitialQuery;
} QueryDirectory;
struct
{
PMRX_V_NET_ROOT pVNetRoot;
} NotifyChangeDirectory;
struct
{
PUCHAR UserEaList;
ULONG UserEaListLength;
ULONG UserEaIndex;
BOOLEAN RestartScan;
BOOLEAN ReturnSingleEntry;
BOOLEAN IndexSpecified;
} QueryEa;
struct
{
SECURITY_INFORMATION SecurityInformation;
ULONG Length;
} QuerySecurity;
struct
{
SECURITY_INFORMATION SecurityInformation;
PSECURITY_DESCRIPTOR SecurityDescriptor;
} SetSecurity;
struct
{
ULONG Length;
PSID StartSid;
PFILE_GET_QUOTA_INFORMATION SidList;
ULONG SidListLength;
BOOLEAN RestartScan;
BOOLEAN ReturnSingleEntry;
BOOLEAN IndexSpecified;
} QueryQuota;
struct
{
ULONG Length;
} SetQuota;
struct
{
PV_NET_ROOT VNetRoot;
PSRV_CALL SrvCall;
PNET_ROOT NetRoot;
} DosVolumeFunction;
struct {
ULONG FlagsForLowIo;
LOWIO_CONTEXT LowIoContext;
};
LUID FsdUid;
};
PWCH AlsoCanonicalNameBuffer;
PUNICODE_STRING LoudCompletionString;
#ifdef RDBSS_TRACKER
volatile LONG AcquireReleaseFcbTrackerX;
volatile ULONG TrackerHistoryPointer;
RX_FCBTRACKER_CALLINFO TrackerHistory[RDBSS_TRACKER_HISTORY_SIZE];
#endif
#if DBG
ULONG ShadowCritOwner;
#endif
} RX_CONTEXT, *PRX_CONTEXT;
typedef enum
{
RX_CONTEXT_FLAG_FROM_POOL = 0x00000001,
RX_CONTEXT_FLAG_WAIT = 0x00000002,
RX_CONTEXT_FLAG_WRITE_THROUGH = 0x00000004,
RX_CONTEXT_FLAG_FLOPPY = 0x00000008,
RX_CONTEXT_FLAG_RECURSIVE_CALL = 0x00000010,
RX_CONTEXT_FLAG_THIS_DEVICE_TOP_LEVEL = 0x00000020,
RX_CONTEXT_FLAG_DEFERRED_WRITE = 0x00000040,
RX_CONTEXT_FLAG_VERIFY_READ = 0x00000080,
RX_CONTEXT_FLAG_STACK_IO_CONTEZT = 0x00000100,
RX_CONTEXT_FLAG_IN_FSP = 0x00000200,
RX_CONTEXT_FLAG_CREATE_MAILSLOT = 0x00000400,
RX_CONTEXT_FLAG_MAILSLOT_REPARSE = 0x00000800,
RX_CONTEXT_FLAG_ASYNC_OPERATION = 0x00001000,
RX_CONTEXT_FLAG_NO_COMPLETE_FROM_FSP = 0x00002000,
RX_CONTEXT_FLAG_POST_ON_STABLE_CONDITION = 0x00004000,
RX_CONTEXT_FLAG_FSP_DELAYED_OVERFLOW_QUEUE = 0x00008000,
RX_CONTEXT_FLAG_FSP_CRITICAL_OVERFLOW_QUEUE = 0x00010000,
RX_CONTEXT_FLAG_MINIRDR_INVOKED = 0x00020000,
RX_CONTEXT_FLAG_WAITING_FOR_RESOURCE = 0x00040000,
RX_CONTEXT_FLAG_CANCELLED = 0x00080000,
RX_CONTEXT_FLAG_SYNC_EVENT_WAITERS = 0x00100000,
RX_CONTEXT_FLAG_NO_PREPOSTING_NEEDED = 0x00200000,
RX_CONTEXT_FLAG_BYPASS_VALIDOP_CHECK = 0x00400000,
RX_CONTEXT_FLAG_BLOCKED_PIPE_RESUME = 0x00800000,
RX_CONTEXT_FLAG_IN_SERIALIZATION_QUEUE = 0x01000000,
RX_CONTEXT_FLAG_NO_EXCEPTION_BREAKPOINT = 0x02000000,
RX_CONTEXT_FLAG_NEEDRECONNECT = 0x04000000,
RX_CONTEXT_FLAG_MUST_SUCCEED = 0x08000000,
RX_CONTEXT_FLAG_MUST_SUCCEED_NONBLOCKING = 0x10000000,
RX_CONTEXT_FLAG_MUST_SUCCEED_ALLOCATED = 0x20000000,
RX_CONTEXT_FLAG_MINIRDR_INITIATED = 0x80000000,
} RX_CONTEXT_FLAGS;
#define RX_CONTEXT_PRESERVED_FLAGS (RX_CONTEXT_FLAG_FROM_POOL | \
RX_CONTEXT_FLAG_MUST_SUCCEED_ALLOCATED | \
RX_CONTEXT_FLAG_IN_FSP)
#define RX_CONTEXT_INITIALIZATION_FLAGS (RX_CONTEXT_FLAG_WAIT | \
RX_CONTEXT_FLAG_MUST_SUCCEED | \
RX_CONTEXT_FLAG_MUST_SUCCEED_NONBLOCKING)
typedef enum
{
RX_CONTEXT_CREATE_FLAG_UNC_NAME = 0x1,
RX_CONTEXT_CREATE_FLAG_STRIPPED_TRAILING_BACKSLASH = 0x2,
RX_CONTEXT_CREATE_FLAG_ADDEDBACKSLASH = 0x4,
RX_CONTEXT_CREATE_FLAG_REPARSE = 0x8,
RX_CONTEXT_CREATE_FLAG_SPECIAL_PATH = 0x10,
} RX_CONTEXT_CREATE_FLAGS;
typedef enum {
RXCONTEXT_FLAG4LOWIO_PIPE_OPERATION = 0x1,
RXCONTEXT_FLAG4LOWIO_PIPE_SYNC_OPERATION = 0x2,
RXCONTEXT_FLAG4LOWIO_READAHEAD = 0x4,
RXCONTEXT_FLAG4LOWIO_THIS_READ_ENLARGED = 0x8,
RXCONTEXT_FLAG4LOWIO_THIS_IO_BUFFERED = 0x10,
RXCONTEXT_FLAG4LOWIO_LOCK_FCB_RESOURCE_HELD = 0x20,
RXCONTEXT_FLAG4LOWIO_LOCK_WAS_QUEUED_IN_LOCKMANAGER = 0x40,
RXCONTEXT_FLAG4LOWIO_THIS_IO_FAST = 0x80,
RXCONTEXT_FLAG4LOWIO_LOCK_OPERATION_COMPLETED = 0x100,
RXCONTEXT_FLAG4LOWIO_LOCK_BUFFERED_ON_ENTRY = 0x200
} RX_CONTEXT_LOWIO_FLAGS;
#if DBG
#define RxSaveAndSetExceptionNoBreakpointFlag(R, F) \
{ \
F = FlagOn(R->Flags, RX_CONTEXT_FLAG_NO_EXCEPTION_BREAKPOINT); \
SetFlag(R->Flags, RX_CONTEXT_FLAG_NO_EXCEPTION_BREAKPOINT); \
}
#define RxRestoreExceptionNoBreakpointFlag(R, F) \
{ \
ClearFlag(R->Flags, RX_CONTEXT_FLAG_NO_EXCEPTION_BREAKPOINT); \
SetFlag(R->Flags, F); \
}
#else
#define RxSaveAndSetExceptionNoBreakpointFlag(R, F)
#define RxRestoreExceptionNoBreakpointFlag(R, F)
#endif
#if DBG
VOID
__RxItsTheSameContext(
_In_ PRX_CONTEXT RxContext,
_In_ ULONG CapturedRxContextSerialNumber,
_In_ ULONG Line,
_In_ PCSTR File);
#define RxItsTheSameContext() { __RxItsTheSameContext(RxContext, CapturedRxContextSerialNumber, __LINE__, __FILE__); }
#else
#define RxItsTheSameContext() { NOTHING; }
#endif
extern NPAGED_LOOKASIDE_LIST RxContextLookasideList;
#define MINIRDR_CALL_THROUGH(STATUS, DISPATCH, FUNC, ARGLIST) \
{ \
ASSERT(DISPATCH); \
ASSERT(NodeType(DISPATCH) == RDBSS_NTC_MINIRDR_DISPATCH); \
if (DISPATCH->FUNC == NULL) \
{ \
STATUS = STATUS_NOT_IMPLEMENTED; \
} \
else \
{ \
STATUS = DISPATCH->FUNC ARGLIST; \
} \
}
#define MINIRDR_CALL(STATUS, CONTEXT, DISPATCH, FUNC, ARGLIST) \
{ \
ASSERT(DISPATCH); \
ASSERT(NodeType(DISPATCH) == RDBSS_NTC_MINIRDR_DISPATCH); \
if (DISPATCH->FUNC == NULL) \
{ \
STATUS = STATUS_NOT_IMPLEMENTED; \
} \
else \
{ \
if (!BooleanFlagOn((CONTEXT)->Flags, RX_CONTEXT_FLAG_CANCELLED)) \
{ \
RtlZeroMemory(&((CONTEXT)->MRxContext[0]), \
sizeof((CONTEXT)->MRxContext)); \
STATUS = DISPATCH->FUNC ARGLIST; \
} \
else \
{ \
STATUS = STATUS_CANCELLED; \
} \
} \
}
#define RxWaitSync(RxContext) \
(RxContext)->Flags |= RX_CONTEXT_FLAG_SYNC_EVENT_WAITERS; \
KeWaitForSingleObject(&(RxContext)->SyncEvent, \
Executive, KernelMode, FALSE, NULL)
#define RxSignalSynchronousWaiter(RxContext) \
(RxContext)->Flags &= ~RX_CONTEXT_FLAG_SYNC_EVENT_WAITERS; \
KeSetEvent(&(RxContext)->SyncEvent, 0, FALSE)
#define RxInsertContextInSerializationQueue(SerializationQueue, RxContext) \
(RxContext)->Flags |= RX_CONTEXT_FLAG_IN_SERIALIZATION_QUEUE; \
InsertTailList(SerializationQueue, &((RxContext)->RxContextSerializationQLinks))
FORCEINLINE
PRX_CONTEXT
RxRemoveFirstContextFromSerializationQueue(
PLIST_ENTRY SerializationQueue)
{
if (IsListEmpty(SerializationQueue))
{
return NULL;
}
else
{
PRX_CONTEXT Context = CONTAINING_RECORD(SerializationQueue->Flink,
RX_CONTEXT,
RxContextSerializationQLinks);
RemoveEntryList(SerializationQueue->Flink);
Context->RxContextSerializationQLinks.Flink = NULL;
Context->RxContextSerializationQLinks.Blink = NULL;
return Context;
}
}
#define RxTransferList(Destination, Source) \
if (IsListEmpty((Source))) \
InitializeListHead((Destination)); \
else \
{ \
*(Destination) = *(Source); \
(Destination)->Flink->Blink = (Destination); \
(Destination)->Blink->Flink = (Destination); \
InitializeListHead((Source)); \
}
#define RxTransferListWithMutex(Destination, Source, Mutex) \
{ \
ExAcquireFastMutex(Mutex); \
RxTransferList(Destination, Source); \
ExReleaseFastMutex(Mutex); \
}
NTSTATUS
RxCancelNotifyChangeDirectoryRequestsForVNetRoot(
PV_NET_ROOT VNetRoot,
BOOLEAN ForceFilesClosed);
VOID
RxCancelNotifyChangeDirectoryRequestsForFobx(
PFOBX Fobx
);
VOID
NTAPI
RxInitializeContext(
_In_ PIRP Irp,
_In_ PRDBSS_DEVICE_OBJECT RxDeviceObject,
_In_ ULONG InitialContextFlags,
_Inout_ PRX_CONTEXT RxContext);
PRX_CONTEXT
NTAPI
RxCreateRxContext(
_In_ PIRP Irp,
_In_ PRDBSS_DEVICE_OBJECT RxDeviceObject,
_In_ ULONG InitialContextFlags);
VOID
NTAPI
RxPrepareContextForReuse(
_Inout_ PRX_CONTEXT RxContext);
VOID
NTAPI
RxDereferenceAndDeleteRxContext_Real(
_In_ PRX_CONTEXT RxContext);
VOID
NTAPI
RxReinitializeContext(
_Inout_ PRX_CONTEXT RxContext);
#if DBG
#define RxDereferenceAndDeleteRxContext(RXCONTEXT) \
{ \
RxDereferenceAndDeleteRxContext_Real((RXCONTEXT)); \
(RXCONTEXT) = NULL; \
}
#else
#define RxDereferenceAndDeleteRxContext(RXCONTEXT) \
{ \
RxDereferenceAndDeleteRxContext_Real((RXCONTEXT)); \
}
#endif
extern FAST_MUTEX RxContextPerFileSerializationMutex;
VOID
NTAPI
RxResumeBlockedOperations_Serially(
_Inout_ PRX_CONTEXT RxContext,
_Inout_ PLIST_ENTRY BlockingIoQ);
VOID
RxResumeBlockedOperations_ALL(
_Inout_ PRX_CONTEXT RxContext);
#if (_WIN32_WINNT >= 0x0600)
VOID
RxCancelBlockingOperation(
_Inout_ PRX_CONTEXT RxContext,
_In_ PIRP Irp);
#else
VOID
RxCancelBlockingOperation(
_Inout_ PRX_CONTEXT RxContext);
#endif
VOID
RxRemoveOperationFromBlockingQueue(
_Inout_ PRX_CONTEXT RxContext);
#endif