windows-nt/Source/XPSP1/NT/base/fs/rdr2/rdbss/proxy.mrx/asynceng.h
2020-09-26 16:20:57 +08:00

260 lines
8.8 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:
MRxProxyAsyncEng.h
Abstract:
This module defines the types and functions related to the SMB protocol
selection engine: the component that translates minirdr calldowns into
SMBs.
Revision History:
--*/
#ifndef _ASYNCENG_H_
#define _ASYNCENG_H_
#include "innerio.h"
IMPORTANT_STRUCTURE(MRXPROXY_ASYNCENGINE_CONTEXT);
#define MRXPROXY_ASYNCENGINE_ARGUMENT_SIGNATURE \
PMRXPROXY_ASYNCENGINE_CONTEXT AsyncEngineContext, \
PRX_CONTEXT RxContext
#define MRXPROXY_ASYNCENGINE_ARGUMENTS \
AsyncEngineContext,RxContext
#if DBG
#define OECHKLINKAGE_FLAG_NO_REQPCKT_CHECK 0x00000001
VOID
__MRxProxyAsyncEngOEAssertConsistentLinkage(
PSZ MsgPrefix,
PSZ File,
unsigned Line,
PRX_CONTEXT RxContext,
PMRXPROXY_ASYNCENGINE_CONTEXT AsyncEngineContext,
ULONG Flags
);
#define MRxProxyAsyncEngOEAssertConsistentLinkage(a) {\
__MRxProxyAsyncEngOEAssertConsistentLinkage(a,__FILE__,__LINE__,RxContext,AsyncEngineContext,0);\
}
#define MRxProxyAsyncEngOEAssertConsistentLinkageFromOE(a) {\
ASSERT_ASYNCENG_CONTEXT(AsyncEngineContext); \
__MRxProxyAsyncEngOEAssertConsistentLinkage(a,__FILE__,__LINE__, \
AsyncEngineContext->RxContext, \
AsyncEngineContext,0); \
}
#define MRxProxyAsyncEngOEAssertConsistentLinkageFromOEwithFlags(a,FLAGS) {\
ASSERT_ASYNCENG_CONTEXT(AsyncEngineContext); \
__MRxProxyAsyncEngOEAssertConsistentLinkage(a,__FILE__,__LINE__, \
AsyncEngineContext->RxContext, \
AsyncEngineContext,FLAGS); \
}
#else
#define MRxProxyAsyncEngOEAssertConsistentLinkage(a) {NOTHING;}
#define MRxProxyAsyncEngOEAssertConsistentLinkageFromOE(a) {NOTHING;}
#define MRxProxyAsyncEngOEAssertConsistentLinkageFromOEwithFlags(a,b) {NOTHING;}
#endif
typedef
NTSTATUS
(*PMRXPROXY_ASYNCENG_CONTINUE_ROUTINE) (
MRXPROXY_ASYNCENGINE_ARGUMENT_SIGNATURE
);
//typedef
//NTSTATUS
//(*PMRXPROXY_ASYNCENG_FINISH_ROUTINE) (
// PMRXPROXY_ASYNCENGINE_CONTEXT
// );
#define MRXPROXY_ASYNCENG_OE_HISTORY_SIZE 32
typedef struct _ASYNCENG_HISTORY {
ULONG Next;
ULONG Submits; //could be shortened....
struct {
ULONG Longs[2];
} Markers[MRXPROXY_ASYNCENG_OE_HISTORY_SIZE];
} ASYNCENG_HISTORY;
#if DBG
VOID MRxProxyAsyncEngUpdateOEHistory(
PMRXPROXY_ASYNCENGINE_CONTEXT AsyncEngineContext,
ULONG Tag1,
ULONG Tag2
);
#define UPDATE_OE_HISTORY_LONG(a) {MRxProxyAsyncEngUpdateOEHistory(AsyncEngineContext,a,0);}
#define UPDATE_OE_HISTORY_2SHORTS(a,b) {MRxProxyAsyncEngUpdateOEHistory(AsyncEngineContext,a,b);}
#else
#define UPDATE_OE_HISTORY_LONG(a)
#define UPDATE_OE_HISTORY_2SHORTS(a,b)
#endif //if DBG
//these are used by the continuation routines to specify what kind of
//async submit is being done
typedef enum _MRXPROXY_ASYNCENGINE_CONTEXT_TYPE {
//MRXPROXY_ASYNCENG_AECTXTYPE_CREATE,
MRXPROXY_ASYNCENG_AECTXTYPE_READ,
MRXPROXY_ASYNCENG_AECTXTYPE_WRITE,
MRXPROXY_ASYNCENG_AECTXTYPE_QUERYDIR,
MRXPROXY_ASYNCENG_AECTXTYPE_LOCKS,
MRXPROXY_ASYNCENG_AECTXTYPE_FLUSH,
MRXPROXY_ASYNCENG_AECTXTYPE_CLOSE,
//MRXPROXY_ASYNCENG_AECTXTYPE_SEARCH,
MRXPROXY_ASYNCENG_AECTXTYPE_MAXIMUM
} MRXPROXY_ASYNCENGINE_CONTEXT_TYPE;
//these are used by the entry point routines to specify what entrypoint was
//called....this facilitates common continuation routines
typedef enum _MRXPROXY_ASYNCENGINE_CONTEXT_ENTRYPOINTS {
MRXPROXY_ASYNCENG_CTX_FROM_LOCKS,
MRXPROXY_ASYNCENG_CTX_FROM_FLUSH,
MRXPROXY_ASYNCENG_CTX_FROM_CLEANUPFOBX,
MRXPROXY_ASYNCENG_CTX_FROM_CLOSESRVCALL,
MRXPROXY_ASYNCENG_CTX_FROM_CREATE,
MRXPROXY_ASYNCENG_CTX_FROM_RENAME,
MRXPROXY_ASYNCENG_CTX_FROM_READ,
MRXPROXY_ASYNCENG_CTX_FROM_WRITE,
MRXPROXY_ASYNCENG_CTX_FROM_QUERYDIR,
MRXPROXY_ASYNCENG_CTX_FROM_FAKESETDELETEDISPOSITION,
MRXPROXY_ASYNCENG_CTX_FROM_MAXIMUM
} MRXPROXY_ASYNCENGINE_CONTEXT_ENTRYPOINTS;
#define MRXPROXY_ASYNCENG_DEFINE_CTX_FLAG(a,c) RX_DEFINE_FLAG(MRXPROXY_ASYNCENG_CTX_FLAG_##a,c,0xffff)
typedef enum {
MRXPROXY_ASYNCENG_DEFINE_CTX_FLAG(MUST_SUCCEED_ALLOCATED, 0)
MRXPROXY_ASYNCENG_DEFINE_CTX_FLAG(AWAITING_DISPATCH, 1)
MRXPROXY_ASYNCENG_DEFINE_CTX_FLAG(ASYNC_OPERATION, 2)
MRXPROXY_ASYNCENG_DEFINE_CTX_FLAG(POSTED_RESUME, 3)
//MRXPROXY_ASYNCENG_DEFINE_CTX_FLAG(NETROOT_GOOD, 15)
} RX_CONTEXT_CREATE_FLAGS;
typedef enum _MRXPROXY_ASYNCENG_OE_INNERIO_STATE {
MRxProxyAsyncEngOEInnerIoStates_Initial = 0,
MRxProxyAsyncEngOEInnerIoStates_ReadyToSend,
MRxProxyAsyncEngOEInnerIoStates_OperationOutstanding
} MRXPROXY_ASYNCENG_OE_INNERIO_STATE;
typedef struct _MRXPROXY_ASYNCENGINE_CONTEXT{
MRX_NORMAL_NODE_HEADER;
PRX_CONTEXT RxContext;
PIRP CalldownIrp;
union {
IO_STATUS_BLOCK;
IO_STATUS_BLOCK IoStatusBlock;
};
RX_WORK_QUEUE_ITEM WorkQueueItem;
MRXPROXY_ASYNCENGINE_CONTEXT_TYPE AECTXType;
MRXPROXY_ASYNCENGINE_CONTEXT_ENTRYPOINTS EntryPoint;
ULONG ContinueEntryCount;
USHORT Flags;
UCHAR OpSpecificFlags;
UCHAR OpSpecificState;
PMRXPROXY_ASYNCENG_CONTINUE_ROUTINE Continuation;
//PMRXPROXY_ASYNCENG_FINISH_ROUTINE FinishRoutine;
union {
struct {
PUCHAR PtrToLockType; //this must be here because the beginning of the
//lockstart code sets the locklist to zero which will be this
//CODE.IMPROVEMENT.ASHAMED fix this up so that assert locks uses readwrite
PMRX_SRV_OPEN SrvOpen;
PRX_LOCK_ENUMERATOR LockEnumerator;
PVOID ContinuationHandle;
ULONG NumberOfLocksPlaced;
LARGE_INTEGER NextLockOffset;
LARGE_INTEGER NextLockRange;
BOOLEAN NextLockIsExclusive;
BOOLEAN LockAreaNonEmpty;
BOOLEAN EndOfListReached;
} AssertLocks;
} ;
//#if DBG CODE.IMPROVEMENT we should get rid of what we don't really, really need
ULONG SerialNumber;
ASYNCENG_HISTORY History;
PIRP RxContextCapturedRequestPacket;
PMDL SaveDataMdlForDebug;
ULONG SaveLengthForDebug;
PMDL SaveIrpMdlForDebug;
//#endif
} MRXPROXY_ASYNCENGINE_CONTEXT, *PMRXPROXY_ASYNCENGINE_CONTEXT;
NTSTATUS
MRxProxySubmitAsyncEngRequest(
MRXPROXY_ASYNCENGINE_ARGUMENT_SIGNATURE,
IN MRXPROXY_ASYNCENGINE_CONTEXT_TYPE AECTXType
);
NTSTATUS
MRxProxyResumeAsyncEngineContext(
IN OUT PRX_CONTEXT RxContext
);
#define ASSERT_ASYNCENG_CONTEXT(__p) ASSERT(NodeType(__p)==PROXY_NTC_ASYNCENGINE_CONTEXT)
NTSTATUS
__MRxProxyAsyncEngineOuterWrapper (
IN PRX_CONTEXT RxContext,
IN MRXPROXY_ASYNCENGINE_CONTEXT_ENTRYPOINTS EntryPoint,
IN PMRXPROXY_ASYNCENG_CONTINUE_ROUTINE Continuation
#if DBG
,IN PSZ RoutineName,
IN BOOLEAN LoudProcessing,
IN BOOLEAN StopOnLoud
#endif
);
#if DBG
#define MRxProxyAsyncEngineOuterWrapper(r,e,c,x1,x2,x3) \
__MRxProxyAsyncEngineOuterWrapper(r,e,c,x1,x2,x3)
#else
#define MRxProxyAsyncEngineOuterWrapper(r,e,c,x1,x2,x3) \
__MRxProxyAsyncEngineOuterWrapper(r,e,c)
#endif
PMRXPROXY_ASYNCENGINE_CONTEXT
MRxProxyCreateAsyncEngineContext (
IN PRX_CONTEXT RxContext,
IN MRXPROXY_ASYNCENGINE_CONTEXT_ENTRYPOINTS EntryPoint
);
#define MRxProxyReferenceAsyncEngineContext(AsyncEngineContext) {\
ULONG result = InterlockedIncrement(&(AsyncEngineContext)->NodeReferenceCount); \
RxDbgTrace(0, (DEBUG_TRACE_MRXPROXY_ASYNCENG), \
("ReferenceAsyncEngineContext result=%08lx\n", result )); \
}
BOOLEAN
MRxProxyFinalizeAsyncEngineContext (
IN OUT PMRXPROXY_ASYNCENGINE_CONTEXT AsyncEngineContext
);
// this macro is used to do the async completion for read/write/locks. Note that the call to lowiocompletion
// will try to complete the irp thereby freeing the user's mdl.
// we use this macro so that there will be only one version of this code. when we combine start routines,
// this will be un macroed
#define MRxProxyAsyncEngAsyncCompletionIfNecessary(AECTX,RXCONTEXT) { \
if (ContinueEntryCount>1) { \
BOOLEAN FinalizationComplete; \
if (FALSE) {DbgBreakPoint(); } \
(RXCONTEXT)->StoredStatus = Status; \
RxLowIoCompletion((RXCONTEXT)); \
FinalizationComplete = MRxProxyFinalizeAsyncEngineContext((AECTX)); \
ASSERT(!FinalizationComplete); \
}}
NTSTATUS
MRxProxyAsyncEngineCalldownIrpCompletion (
IN PDEVICE_OBJECT DeviceObject,
IN PIRP CalldownIrp,
IN OUT PVOID Context
);
#endif // _ASYNCENG_H_