260 lines
8.8 KiB
C
260 lines
8.8 KiB
C
/*++
|
||
|
||
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_
|
||
|
||
|