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