|
|
/*++
Copyright (c) 1989 Microsoft Corporation
Module Name:
SmbPse.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 _SMBPSE_H_
#define _SMBPSE_H_
IMPORTANT_STRUCTURE(SMB_PSE_ORDINARY_EXCHANGE);
//CODE.IMPROVEMENT is this the right place for this?
#define StorageType(co) ((co) & FILE_STORAGE_TYPE_MASK)
#define StorageFlag(co) ((co) & FILE_STORAGE_TYPE_SPECIFIED)
#define IsStorageTypeSpecified(co) (StorageFlag(co) == FILE_STORAGE_TYPE_SPECIFIED)
#define MustBeDirectory(co) ((co) & FILE_DIRECTORY_FILE)
#define MustBeFile(co) ((co) & FILE_NON_DIRECTORY_FILE)
//CODE.IMPROVEMENT The following should get fixed - use Tom's literal!
#define CLUSTER_SIZE 0x1000
//CODE.IMPROVEMENT.STACKSPACE we could save a dword of stack space
// by not passing rxcontext
// and by retrieving it from ordinaryexchange
#define SMBPSE_ORDINARY_EXCHANGE_ARGUMENT_SIGNATURE \
PSMB_PSE_ORDINARY_EXCHANGE OrdinaryExchange, \ PRX_CONTEXT RxContext
//CODE.IMPROVEMENT this is not used consistently. in particular, it is not used in the OE start wrapper
// in order to not have any extra variables on the stack....a good idea but it breaks
// this encapsulation. on a risc machine, they would be in registers anyway. so, it makes
// sense to put in a comment there (and maybe the x86-specific code.......)
#define SMBPSE_ORDINARY_EXCHANGE_ARGUMENTS \
OrdinaryExchange,RxContext
#if DBG
#define OECHKLINKAGE_FLAG_NO_REQPCKT_CHECK 0x00000001
VOID __SmbPseOEAssertConsistentLinkage( PSZ MsgPrefix, PSZ File, unsigned Line, PRX_CONTEXT RxContext, PSMB_PSE_ORDINARY_EXCHANGE OrdinaryExchange, PSMBSTUFFER_BUFFER_STATE StufferState, ULONG Flags ); #define SmbPseOEAssertConsistentLinkage(a) {\
__SmbPseOEAssertConsistentLinkage(a,__FILE__,__LINE__,RxContext,OrdinaryExchange,StufferState,0);\ } #define SmbPseOEAssertConsistentLinkageFromOE(a) {\
ASSERT_ORDINARY_EXCHANGE(OrdinaryExchange); \ __SmbPseOEAssertConsistentLinkage(a,__FILE__,__LINE__, \ OrdinaryExchange->RxContext, \ OrdinaryExchange, \ &OrdinaryExchange->AssociatedStufferState,0); \ } #define SmbPseOEAssertConsistentLinkageFromOEwithFlags(a,FLAGS) {\
ASSERT_ORDINARY_EXCHANGE(OrdinaryExchange); \ __SmbPseOEAssertConsistentLinkage(a,__FILE__,__LINE__, \ OrdinaryExchange->RxContext, \ OrdinaryExchange, \ &OrdinaryExchange->AssociatedStufferState,FLAGS); \ } #else
#define SmbPseOEAssertConsistentLinkage(a) {NOTHING;}
#define SmbPseOEAssertConsistentLinkageFromOE(a) {NOTHING;}
#define SmbPseOEAssertConsistentLinkageFromOEwithFlags(a,b) {NOTHING;}
#endif
typedef NTSTATUS (*PSMB_PSE_OE_START_ROUTINE) ( SMBPSE_ORDINARY_EXCHANGE_ARGUMENT_SIGNATURE );
typedef NTSTATUS (*PSMB_PSE_CONTINUATION_ROUTINE) ( PSMB_PSE_ORDINARY_EXCHANGE );
#define SMBPSE_OE_HISTORY_SIZE 32
typedef struct _SMBPSE_HISTORY { ULONG Next; ULONG Submits; //could be shortened....
struct { ULONG Longs[2]; } Markers[SMBPSE_OE_HISTORY_SIZE]; } SMBPSE_HISTORY;
#if DBG
VOID SmbPseUpdateOEHistory( PSMB_PSE_ORDINARY_EXCHANGE OrdinaryExchange, ULONG Tag1, ULONG Tag2 ); #define UPDATE_OE_HISTORY_LONG(a) {SmbPseUpdateOEHistory(OrdinaryExchange,a,0);}
#define UPDATE_OE_HISTORY_2SHORTS(a,b) {SmbPseUpdateOEHistory(OrdinaryExchange,a,b);}
#else
#define UPDATE_OE_HISTORY_LONG(a)
#define UPDATE_OE_HISTORY_2SHORTS(a,b)
#endif //if DBG
typedef enum _SMB_PSE_ORDINARY_EXCHANGE_TYPE { SMBPSE_OETYPE_LATENT_HEADEROPS, SMBPSE_OETYPE_CREATE, SMBPSE_OETYPE_COREOPEN, // SMBPSE_OETYPE_CLEANUP,
SMBPSE_OETYPE_FINDCLOSE, SMBPSE_OETYPE_READ, SMBPSE_OETYPE_WRITE, SMBPSE_OETYPE_EXTEND_WRITE, SMBPSE_OETYPE_CORETRUNCATE, SMBPSE_OETYPE_LOCKS, SMBPSE_OETYPE_ASSERTBUFFEREDLOCKS, SMBPSE_OETYPE_FLUSH, SMBPSE_OETYPE_CLOSE, SMBPSE_OETYPE_CLOSEAFTERCORECREATE, //SMBPSE_OETYPE_SEARCH,
SMBPSE_OETYPE_RENAME, SMBPSE_OETYPE_T2_FOR_NT_FILE_ALLOCATION_INFO, //MUST BE FIRST T2
SMBPSE_OETYPE_T2_FOR_NT_DISKATTRIBUTES_INFO, SMBPSE_OETYPE_T2_FOR_ONE_FILE_DIRCTRL, SMBPSE_OETYPE_T2_FOR_LANMAN_DISKATTRIBUTES_INFO, SMBPSE_OETYPE_T2_FOR_LANMAN_VOLUMELABEL_INFO, //MUST BE LAST T2
SMBPSE_OETYPE_GFA, // SMBPSE_OETYPE_GFA2,
SMBPSE_OETYPE_COREINFO, SMBPSE_OETYPE_CORECREATE, SMBPSE_OETYPE_DELETEFORSUPERSEDEORCLOSE, SMBPSE_OETYPE_DELETE_FOR_RENAME, SMBPSE_OETYPE_CORECREATEDIRECTORY, SMBPSE_OETYPE_CORECHECKDIRECTORY, SMBPSE_OETYPE_SFA, SMBPSE_OETYPE_SFA2, SMBPSE_OETYPE_COREQUERYLABEL, SMBPSE_OETYPE_CORESEARCH, SMBPSE_OETYPE_CORESEARCHFORCHECKEMPTY, SMBPSE_OETYPE_COREQUERYDISKATTRIBUTES, SMBPSE_OETYPE_CREATEPRINTFILE, SMBPSE_OETYPE_IOCTL, SMBPSE_OETYPE_MAXIMUM } SMB_PSE_ORDINARY_EXCHANGE_TYPE;
typedef enum _SMB_PSE_ORDINARY_EXCHANGE_ENTRYPOINTS { SMBPSE_OE_FROM_QUERYDIRECTORY, SMBPSE_OE_FROM_QUERYFILEINFO, SMBPSE_OE_FROM_SETFILEINFO, SMBPSE_OE_FROM_QUERYVOLUMEINFO, SMBPSE_OE_FROM_EXTENDFILEFORCACHEING, SMBPSE_OE_FROM_LOCKS, SMBPSE_OE_FROM_FLUSH, SMBPSE_OE_FROM_ASSERTBUFFEREDLOCKS, SMBPSE_OE_FROM_CLEANUPFOBX, SMBPSE_OE_FROM_CLOSESRVCALL, SMBPSE_OE_FROM_CLOSECOPYCHUNKSRVCALL, SMBPSE_OE_FROM_GETFILEINFOFORCSHADOW, SMBPSE_OE_FROM_CREATE, SMBPSE_OE_FROM_RENAME, SMBPSE_OE_FROM_READ, SMBPSE_OE_FROM_WRITE, SMBPSE_OE_FROM_FAKESETDELETEDISPOSITION, SMBPSE_OE_FROM_GETPRINTJOBID, SMBPSE_OE_FROM_MAXIMUM } SMB_PSE_ORDINARY_EXCHANGE_ENTRYPOINTS;
#define SMBPSE_DEFINE_OE_FLAG(a,c) RX_DEFINE_FLAG(SMBPSE_OE_FLAG_##a,c,0xffff)
typedef enum { SMBPSE_DEFINE_OE_FLAG(HEADER_ALREADY_PARSED, 0) SMBPSE_DEFINE_OE_FLAG(OE_ALREADY_RESUMED, 1) SMBPSE_DEFINE_OE_FLAG(VALIDATE_FID, 2) SMBPSE_DEFINE_OE_FLAG(OE_HDR_PARTIAL_INITIALIZED, 3) SMBPSE_DEFINE_OE_FLAG(OE_ALLOCATED_DATA_PARTIAL, 4) SMBPSE_DEFINE_OE_FLAG(OE_HDR_LOCKED, 5) //SMBPSE_DEFINE_OE_FLAG(SMBBUF_IS_A_MDL, 6)
SMBPSE_DEFINE_OE_FLAG(NO_RESPONSE_EXPECTED, 7) SMBPSE_DEFINE_OE_FLAG(MUST_SUCCEED_ALLOCATED_OE, 8) SMBPSE_DEFINE_OE_FLAG(MUST_SUCCEED_ALLOCATED_SMBBUF, 9) SMBPSE_DEFINE_OE_FLAG(OE_AWAITING_DISPATCH, 10) SMBPSE_DEFINE_OE_FLAG(TURNON_DFS_FLAG, 11) //SMBPSE_DEFINE_OE_FLAG(NETROOT_GOOD, 15)
} SMBPSE_OE_FLAGS;
typedef enum _SMB_PSE_OE_INNERIO_STATE { SmbPseOEInnerIoStates_Initial = 0, SmbPseOEInnerIoStates_ReadyToSend, SmbPseOEInnerIoStates_OperationOutstanding, SmbPseOEInnerIoStates_OperationCompleted } SMB_PSE_OE_INNERIO_STATE;
typedef enum _SMB_PSE_OE_READWRITE_STATE { SmbPseOEReadWriteIoStates_Initial = 0, SmbPseOEReadWriteIoStates_OperationOutstanding, SmbPseOEReadWriteIoStates_OperationCompleted, SmbPseOEReadWriteIoStates_OperationAbandoned } SMB_PSE_OE_READWRITE_STATE;
#define MAX_PAGES_SPANNED_BY_PARTIAL_DATA_MDL (20)
#define MAX_PAGES_SPANNED_BY_PARTIAL_EXCHANGE_MDL (2)
#define MAX_PARTIAL_DATA_MDL_BUFFER_SIZE \
(MAX_PAGES_SPANNED_BY_PARTIAL_DATA_MDL * PAGE_SIZE)
#define MAX_PARTIAL_EXCHANGE_MDL_BUFFER_SIZE \
(MAX_PAGES_SPANNED_BY_PARTIAL_EXCHANGE_MDL * PAGE_SIZE)
extern FAST_MUTEX MRxSmbReadWriteMutex;
typedef struct _SMB_PSE_OE_READWRITE {
// don't add fields to the beginning of this struct
// see CODE.IMPROVEMENT.ASHAMED below (in OrdinarySMB_PSE_ORDINARY_EXCHANGE definition)
union { PBYTE UserBufferBase; PLOWIO_LOCK_LIST LockList; };
PRX_CONTEXT RxContext; ULONG RemainingByteCount; ULONG ThisBytesRequested; ULONG ThisByteCount; ULONG ThisBufferOffset; LARGE_INTEGER ByteOffsetAsLI; ULONG BytesReturned;
BOOLEAN PartialExchangeMdlInUse; BOOLEAN PartialDataMdlInUse; BOOLEAN CompressedRequestInProgress; BOOLEAN CompressedReadOrWrite; BOOLEAN WriteToTheEnd; BOOLEAN ReadWriteFinalized;
ULONG CompressedDataInfoLength; PBYTE pCompressedDataBuffer;
ULONG UserBufferPortionLength; ULONG ExchangeBufferPortionLength;
union { MDL PartialDataMdl; COMPRESSED_DATA_INFO CompressedDataInfo; BYTE ByteBuffer1[ sizeof(MDL) + sizeof(ULONG) * MAX_PAGES_SPANNED_BY_PARTIAL_DATA_MDL]; };
union { MDL PartialExchangeMdl; BYTE PartialExchangeMdlBuffer[ sizeof(MDL) + sizeof(ULONG) * MAX_PAGES_SPANNED_BY_PARTIAL_EXCHANGE_MDL]; };
ULONG TotalNumOfSections; ULONG NumOfOutstandingOperations; ULONG MaximumBufferSize; ULONG CurrentSection; ULONG RefCount; PKEVENT CompletionEvent; NTSTATUS CompletionStatus; SMBFCB_HOLDING_STATE SmbFcbHoldingState; SMB_PSE_OE_READWRITE_STATE SectionState[]; } SMB_PSE_OE_READWRITE, *PSMB_PSE_OE_READWRITE;
#define OE_RW_FLAG_SUCCESS_IN_COPYHANDLER (0x01)
#define OE_RW_FLAG_REDUCE_RETURNCOUNT (0x20) //used in pipewrites to track rawmode
#define OE_RW_FLAG_SUBSEQUENT_OPERATION (0x40) //used in pipewrites to distinguish the first
#define OE_RW_FLAG_MSGMODE_PIPE_OPERATION (0x80) //MAX VALUE, it's just a byte.....
#define SMB_PSE_OE_HDR_MDL_PAGES (2 + (ADDRESS_AND_SIZE_TO_SPAN_PAGES( (ULONG) 0, MAXIMUM_SMB_BUFFER_SIZE )))
typedef struct _SMB_PSE_ORDINARY_EXCHANGE{ union { SMB_EXCHANGE Exchange; SMB_EXCHANGE; }; SMB_PSE_ORDINARY_EXCHANGE_TYPE OEType; SMB_PSE_ORDINARY_EXCHANGE_ENTRYPOINTS EntryPoint; ULONG SmbBufSize; ULONG StartEntryCount; PMDL DataPartialMdl; USHORT Flags; UCHAR OpSpecificFlags; UCHAR OpSpecificState; UCHAR LastSmbCommand; ULONG SendOptions; GENERIC_ANDX ParseResumeState; NTSTATUS NoCopyFinalStatus; NTSTATUS SendCompletionStatus; ULONG MessageLength; SMBFCB_HOLDING_STATE SmbFcbHoldingState; //plenty of pad....only 2 bits used
PSMB_PSE_OE_START_ROUTINE AsyncResumptionRoutine; PSMB_PSE_OE_START_ROUTINE StartRoutine; PSMB_PSE_CONTINUATION_ROUTINE ContinuationRoutine;
union { struct { SMBPSE_FILEINFO_BUNDLE FileInfo; PMRX_SMB_SRV_OPEN smbSrvOpen; RX_FILE_TYPE StorageTypeFromGFA; ///DO NOT CHANGE ABOVE HERE UNLESS YOU CHANGE THE INFO ARM AS WELL
MRXSMB_CREATE_PARAMETERS SmbCp; BOOLEAN MustRegainExclusiveResource; BOOLEAN CreateWithEasSidsOrLongName; ULONG FidReturnedFromCreate; ULONG FidReturnedFromOpen; ULONG FileSizeReturnedFromOpen; BOOLEAN FileWasCreated; BOOLEAN FileWasTruncated; //UNICODE_STRING PathNameForCoreOperation;
} Create; SMB_PSE_OE_READWRITE ReadWrite; //also used for locks
struct { SMBPSE_FILEINFO_BUNDLE FileInfo; PMRX_SMB_SRV_OPEN smbSrvOpen; RX_FILE_TYPE StorageTypeFromGFA; ///DO NOT CHANGE ABOVE HERE UNLESS YOU CHANGE THE CREATE ARM AS WELL
PVOID Buffer; PULONG pBufferLength; ULONG InfoClass; union { struct { UCHAR CoreLabel[13]; //right from smb.h
} QFSVolInfo; struct { ULONG CountRemaining; ULONG CountRemainingInSmbbuf; PSMB_DIRECTORY_INFORMATION NextDirInfo; //there should be a union here
PSMB_RESUME_KEY EmptyCheckResumeKey; SMB_RESUME_KEY EmptyCheckResumeKeyBuffer; } CoreSearch; }; } Info; struct { LARGE_INTEGER AllocationSize; } Transact2; 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; } ; PSMB_PSE_OE_READWRITE GlobalReadWrite;
PUNICODE_STRING pPathArgument1; // Unicode path
union { PUNICODE_STRING pPathArgument2; // secondary unicode path
PVOID Find32WithinSmbbuf; }; PSMBSTUFFER_BUFFER_STATE StufferStateDbgPtr; //this is just for the debugger....get rid of it
SMBSTUFFER_BUFFER_STATE AssociatedStufferState; struct { union { MDL; MDL Mdl; }; ULONG Pages2[SMB_PSE_OE_HDR_MDL_PAGES]; } HeaderMdl; struct { union { MDL; MDL Mdl; }; ULONG Pages2[SMB_PSE_OE_HDR_MDL_PAGES]; } HeaderPartialMdl; //#if DBG CODE.IMPROVEMENT we should get rid of what we don't really, really need
ULONG SerialNumber; SMBPSE_HISTORY History; PIRP RxContextCapturedRequestPacket; PMDL SaveDataMdlForDebug; ULONG SaveLengthForDebug; PMDL SaveIrpMdlForDebug; //#endif
ULONG BytesAvailableCopy; ULONG BytesIndicatedCopy; } SMB_PSE_ORDINARY_EXCHANGE, *PSMB_PSE_ORDINARY_EXCHANGE;
// CODE.IMPROVEMENT actually, we have to get rid of a message...we need to know the length in the long term
// in the short term this will be okay. i think that what i really have to do is to return error_discard
// or something like that
#define SmbPseDiscardProtocol(__STATUS__) { \
*pBytesTaken = BytesAvailable; \ pExchange->Status = (__STATUS__); \ }
NTSTATUS SmbPseOrdinaryExchange( SMBPSE_ORDINARY_EXCHANGE_ARGUMENT_SIGNATURE, IN SMB_PSE_ORDINARY_EXCHANGE_TYPE OEType );
NTSTATUS SmbPseResumeOrdinaryExchange( IN OUT PRX_CONTEXT RxContext );
#define ASSERT_ORDINARY_EXCHANGE(__p) ASSERT(NodeType(__p)==SMB_EXCHANGE_NTC(ORDINARY_EXCHANGE))
NTSTATUS __SmbPseCreateOrdinaryExchange ( IN PRX_CONTEXT RxContext, IN PMRX_V_NET_ROOT VNetRoot, IN SMB_PSE_ORDINARY_EXCHANGE_ENTRYPOINTS EntryPoint, IN PSMB_PSE_OE_START_ROUTINE StartRoutine, IN OUT SMBFCB_HOLDING_STATE *SmbFcbHoldingState OPTIONAL, OUT PSMB_PSE_ORDINARY_EXCHANGE *OrdinaryExchangePtr ); #define SmbPseCreateOrdinaryExchange(__rxcontext,__vnetroot,__entrypoint,__start,__ordinaryexchangeptr) \
__SmbPseCreateOrdinaryExchange(__rxcontext,__vnetroot,__entrypoint,__start,NULL,__ordinaryexchangeptr)
BOOLEAN SmbPseFinalizeOrdinaryExchange ( IN OUT PSMB_PSE_ORDINARY_EXCHANGE OrdinaryExchange );
#define SmbPseInitiateOrdinaryExchange(OrdinaryExchange) (SmbCeInitiateExchange(&OrdinaryExchange->Exchange))
// 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. so, we better get rid of the partial first.
// 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 SmbPseAsyncCompletionIfNecessary(OE,RXCONTEXT) { \
if (StartEntryCount>1) { \ BOOLEAN FinalizationComplete; \ if (FALSE) {DbgBreakPoint(); } \ if ( (OE)->DataPartialMdl ) { \ if (FlagOn((OE)->Flags, SMBPSE_OE_FLAG_MUST_SUCCEED_ALLOCATED_SMBBUF)){\ MmPrepareMdlForReuse((OE)->DataPartialMdl); \ } else { \ IoFreeMdl((OE)->DataPartialMdl); \ (OE)->DataPartialMdl = NULL; \ ClearFlag((OE)->Flags,SMBPSE_OE_FLAG_OE_ALLOCATED_DATA_PARTIAL); \ } \ } \ (RXCONTEXT)->StoredStatus = Status; \ \ RxLowIoCompletion((RXCONTEXT)); \ FinalizationComplete = SmbPseFinalizeOrdinaryExchange((OE)); \ ASSERT(!FinalizationComplete); \ Status = STATUS_PENDING; \ }}
/* ------------------------------------------
------------------------------------------ Receive Handler Stuff ------------------------------------------ ------------------------------------------ */
VOID SmbPseInitializeTables( void );
typedef NTSTATUS (*PSMBPSE_RECEIVE_HANDLER) ( PSMB_PSE_ORDINARY_EXCHANGE OrdinaryExchange, PBYTE Response );
//boy, talk about a load of arguments
typedef UCHAR (*PSMBPSE_NOCOPY_RECEIVE_HANDLER) ( IN OUT PSMB_PSE_ORDINARY_EXCHANGE OrdinaryExchange, IN ULONG BytesIndicated, IN ULONG BytesAvailable, OUT ULONG *pBytesTaken, IN PSMB_HEADER pSmbHeader, OUT PMDL *pDataBufferPointer, OUT PULONG pDataSize, #if DBG
IN UCHAR ThisIsAReenter, #endif
IN PBYTE Response ); #define SMBPSE_NOCOPYACTION_NORMALFINISH 0x00
#define SMBPSE_NOCOPYACTION_MDLFINISH 0x01
#define SMBPSE_NOCOPYACTION_DISCARD 0x02
#define SMBPSE_NOCOPYACTION_COPY_FOR_RESUME 0x03
#define SMBPSE_RMP_MODELED (0x00000001)
#define SMBPSE_RMP_THIS_IS_ANDX (0x00000002)
#define SMBPSE_RMP_WARNINGS_OK (0x00000004)
#define SMBPSE_RMP_NOCOPY_HANDLER (0x00000008)
#define SMBPSE_RMP_FORCE_SYNC (0x00000010)
typedef enum _SMBPSE_RECEIVE_HANDLER_TOKEN { SMBPSE_RECEIVE_HANDLER_TOKEN_READ_ANDX_HANDLER = 0, SMBPSE_RECEIVE_HANDLER_TOKEN_READ_HANDLER, SMBPSE_RECEIVE_HANDLER_TOKEN_WRITE_ANDX_HANDLER, SMBPSE_RECEIVE_HANDLER_TOKEN_WRITE_HANDLER, SMBPSE_RECEIVE_HANDLER_TOKEN_LOCKING_ANDX_HANDLER, SMBPSE_RECEIVE_HANDLER_TOKEN_OPEN_PRINTFILE_HANDLER, SMBPSE_RECEIVE_HANDLER_TOKEN_WRITE_PRINTFILE_HANDLER, SMBPSE_RECEIVE_HANDLER_TOKEN_CLOSE_HANDLER, //also close_print_file
SMBPSE_RECEIVE_HANDLER_TOKEN_NTCREATE_ANDX_HANDLER, SMBPSE_RECEIVE_HANDLER_TOKEN_OPEN_ANDX_HANDLER, SMBPSE_RECEIVE_HANDLER_TOKEN_CREATE_HANDLER, //also create_new
SMBPSE_RECEIVE_HANDLER_TOKEN_OPEN_HANDLER, SMBPSE_RECEIVE_HANDLER_TOKEN_TRANS2_ANDX_HANDLER, SMBPSE_RECEIVE_HANDLER_TOKEN_GFA_HANDLER, SMBPSE_RECEIVE_HANDLER_TOKEN_SEARCH_HANDLER, SMBPSE_RECEIVE_HANDLER_TOKEN_QUERYDISKINFO_HANDLER, SMBPSE_RECEIVE_HANDLER_TOKEN_IOCTL_HANDLER, SMBPSE_RECEIVE_HANDLER_TOKEN_MAXIMUM } SMBPSE_RECEIVE_HANDLER_TOKEN;
PSMBPSE_RECEIVE_HANDLER SmbPseReceiveHandlers[SMBPSE_RECEIVE_HANDLER_TOKEN_MAXIMUM]; typedef struct _SMBPSE_RECEIVE_MODEL_PARAMETERS { UCHAR Flags; UCHAR ReceiveHandlerToken; #if DBG
USHORT Dummy; PSMBPSE_RECEIVE_HANDLER ReceiveHandler; PBYTE IndicationString; SMB_PSE_ORDINARY_EXCHANGE_TYPE LowType,HighType; #endif
} SMBPSE_RECEIVE_MODEL_PARAMETERS, *PSMBPSE_RECEIVE_MODEL_PARAMETERS;
SMBPSE_RECEIVE_MODEL_PARAMETERS SmbPseReceiveModelParameters[256]; //there are 256 possible smbs
typedef struct _SMBPSE_VESTIGIAL_SMBBUF { NT_SMB_HEADER Header; union { REQ_WRITE Write; REQ_NT_WRITE_ANDX WriteAndX; REQ_FLUSH Flush; struct { REQ_LOCKING_ANDX LockingAndX; NTLOCKING_ANDX_RANGE Locks[20]; //CODE.IMPROVEMENT.ASHAMED see locks.c
}; REQ_FIND_CLOSE2 FindClose; REQ_CLOSE Close; }; ULONG Pad; } SMBPSE_VESTIGIAL_SMBBUF;
// Finishing routines - these are all cast into the correct procedure type
// so that the response will already have the correct SMB format
// on entry to the routine
//CODE.IMPROVEMENT the names of these routines should be changed from FinishX to X_Handler
//CODE.IMPROVEMENT also, any routine that doesn't retrieve data should be changed over to a nocopy handler
NTSTATUS MRxSmbFinishNTCreateAndX ( IN OUT PSMB_PSE_ORDINARY_EXCHANGE OrdinaryExchange, IN PRESP_NT_CREATE_ANDX Response ); #define MRxSmbReceiveHandler_NTCreateAndX ((PSMBPSE_RECEIVE_HANDLER)MRxSmbFinishNTCreateAndX)
NTSTATUS MRxSmbFinishOpenAndX ( IN OUT PSMB_PSE_ORDINARY_EXCHANGE OrdinaryExchange, IN PRESP_OPEN_ANDX Response ); #define MRxSmbReceiveHandler_OpenAndX ((PSMBPSE_RECEIVE_HANDLER)MRxSmbFinishOpenAndX)
NTSTATUS MRxSmbFinishClose ( IN OUT PSMB_PSE_ORDINARY_EXCHANGE OrdinaryExchange, IN PRESP_CLOSE Response ); //use the close finsh routine for closeprintfile as well
#define MRxSmbReceiveHandler_Close ((PSMBPSE_RECEIVE_HANDLER)MRxSmbFinishClose)
NTSTATUS MRxSmbFinishGFA ( IN OUT PSMB_PSE_ORDINARY_EXCHANGE OrdinaryExchange, IN PVOID Response ); #define MRxSmbReceiveHandler_GetFileAttributes ((PSMBPSE_RECEIVE_HANDLER)MRxSmbFinishGFA)
NTSTATUS MRxSmbFinishTransaction2 ( IN OUT PSMB_PSE_ORDINARY_EXCHANGE OrdinaryExchange, IN PRESP_TRANSACTION Response ); #define MRxSmbReceiveHandler_Transact2 ((PSMBPSE_RECEIVE_HANDLER)MRxSmbFinishTransaction2)
NTSTATUS MRxSmbFinishCoreOpen ( IN OUT PSMB_PSE_ORDINARY_EXCHANGE OrdinaryExchange, IN PRESP_OPEN Response ); #define MRxSmbReceiveHandler_CoreOpen ((PSMBPSE_RECEIVE_HANDLER)MRxSmbFinishCoreOpen)
NTSTATUS MRxSmbFinishCoreCreate ( IN OUT PSMB_PSE_ORDINARY_EXCHANGE OrdinaryExchange, IN PRESP_CREATE Response ); #define MRxSmbReceiveHandler_CoreCreate ((PSMBPSE_RECEIVE_HANDLER)MRxSmbFinishCoreCreate)
NTSTATUS MRxSmbFinishCoreIoCtl( PSMB_PSE_ORDINARY_EXCHANGE OrdinaryExchange, PRESP_IOCTL Response ); #define MRxSmbReceiveHandler_Ioctl ((PSMBPSE_RECEIVE_HANDLER)MRxSmbFinishCoreIoCtl)
//NTSTATUS
//MRxSmbFinishRead (
// IN OUT PSMB_PSE_ORDINARY_EXCHANGE OrdinaryExchange,
// IN PRESP_READ_ANDX Response
// );
//#define MRxSmbReceiveHandler_ReadAndX ((PSMBPSE_RECEIVE_HANDLER)MRxSmbFinishRead)
//NTSTATUS
//MRxSmbFinishCoreRead (
// IN OUT PSMB_PSE_ORDINARY_EXCHANGE OrdinaryExchange,
// IN PRESP_READ Response
// );
//#define MRxSmbReceiveHandler_CoreRead ((PSMBPSE_RECEIVE_HANDLER)MRxSmbFinishCoreRead)
UCHAR MRxSmbReadHandler_NoCopy ( IN OUT PSMB_PSE_ORDINARY_EXCHANGE OrdinaryExchange, IN ULONG BytesIndicated, IN ULONG BytesAvailable, OUT ULONG *pBytesTaken, IN PSMB_HEADER pSmbHeader, OUT PMDL *pDataBufferPointer, OUT PULONG pDataSize, #if DBG
IN UCHAR ThisIsAReenter, #endif
IN PRESP_READ_ANDX Response ); #define MRxSmbReceiveHandler_Read_NoCopy ((PSMBPSE_RECEIVE_HANDLER)MRxSmbReadHandler_NoCopy)
NTSTATUS MRxSmbFinishCreatePrintFile ( IN OUT PSMB_PSE_ORDINARY_EXCHANGE OrdinaryExchange, IN PRESP_OPEN_PRINT_FILE Response ); #define MRxSmbReceiveHandler_OpenPrintFile ((PSMBPSE_RECEIVE_HANDLER)MRxSmbFinishCreatePrintFile)
NTSTATUS MRxSmbFinishWrite ( IN OUT PSMB_PSE_ORDINARY_EXCHANGE OrdinaryExchange, IN PBYTE Response );
#define MRxSmbReceiveHandler_WritePrintFile ((PSMBPSE_RECEIVE_HANDLER)MRxSmbFinishWrite)
#define MRxSmbReceiveHandler_WriteAndX ((PSMBPSE_RECEIVE_HANDLER)MRxSmbFinishWrite)
#define MRxSmbReceiveHandler_CoreWrite ((PSMBPSE_RECEIVE_HANDLER)MRxSmbFinishWrite)
NTSTATUS MRxSmbFinishLocks ( IN OUT PSMB_PSE_ORDINARY_EXCHANGE OrdinaryExchange, IN PRESP_LOCKING_ANDX Response ); #define MRxSmbReceiveHandler_LockingAndX ((PSMBPSE_RECEIVE_HANDLER)MRxSmbFinishLocks)
#if 0
NTSTATUS MRxSmbFinishFlush ( IN OUT PSMB_PSE_ORDINARY_EXCHANGE OrdinaryExchange, IN PRESP_FLUSH Response ); #endif //if 0
NTSTATUS MRxSmbFinishSearch ( PSMB_PSE_ORDINARY_EXCHANGE OrdinaryExchange, PRESP_SEARCH Response ); #define MRxSmbReceiveHandler_Search ((PSMBPSE_RECEIVE_HANDLER)MRxSmbFinishSearch)
NTSTATUS MRxSmbFinishQueryDiskInfo ( PSMB_PSE_ORDINARY_EXCHANGE OrdinaryExchange, PRESP_QUERY_INFORMATION_DISK Response ); #define MRxSmbReceiveHandler_QueryDiskInfo ((PSMBPSE_RECEIVE_HANDLER)MRxSmbFinishQueryDiskInfo)
//CODE.IMPROVEMENT.ASHAMED it would be so much better if
// __MRxSmbSimpleSyncTransact2were divided into two routines.....one for
// building and another for submitting. it would save some stack space.
typedef NTSTATUS (*PSMB_PSE_OE_T2_FIXUP_ROUTINE) ( PSMB_PSE_ORDINARY_EXCHANGE );
NTSTATUS __MRxSmbSimpleSyncTransact2( SMBPSE_ORDINARY_EXCHANGE_ARGUMENT_SIGNATURE, IN SMB_PSE_ORDINARY_EXCHANGE_TYPE OEType, IN ULONG TransactSetupCode, IN PVOID Params, IN ULONG ParamsLength, IN PVOID Data, IN ULONG DataLength, IN PSMB_PSE_OE_T2_FIXUP_ROUTINE FixupRoutine ); #define MRxSmbSimpleSyncTransact2(a,b,c,d,e,f,g) \
__MRxSmbSimpleSyncTransact2(a,b,c,d,e,f,g,NULL);
NTSTATUS MRxSmbDeferredCreate ( IN OUT PRX_CONTEXT RxContext ); NTSTATUS MRxSmbConstructDeferredOpenContext ( IN OUT PRX_CONTEXT RxContext );
//downlevel stuff....
NTSTATUS MRxSmbPseudoOpenTailFromGFAResponse ( PSMB_PSE_ORDINARY_EXCHANGE OrdinaryExchange );
NTSTATUS MRxSmbPseudoOpenTailFromFakeGFAResponse ( PSMB_PSE_ORDINARY_EXCHANGE OrdinaryExchange, RX_FILE_TYPE StorageType //CODE.IMPROVEMENT this should be a RDBSS_STORAGE_TYPE
);
NTSTATUS MRxSmbCoreTruncate( SMBPSE_ORDINARY_EXCHANGE_ARGUMENT_SIGNATURE, ULONG Fid, ULONG FileTruncationPoint );
NTSTATUS MRxSmbCoreInformation( IN OUT PRX_CONTEXT RxContext, IN ULONG InformationClass, IN OUT PVOID pBuffer, IN OUT PULONG pBufferLength, IN SMB_PSE_ORDINARY_EXCHANGE_ENTRYPOINTS EntryPoint );
ULONG MRxSmbMapSmbAttributes ( IN USHORT SmbAttribs );
USHORT MRxSmbMapDisposition ( IN ULONG Disposition );
USHORT MRxSmbMapShareAccess ( IN USHORT ShareAccess );
USHORT MRxSmbMapDesiredAccess ( IN ULONG DesiredAccess );
USHORT MRxSmbMapFileAttributes ( IN ULONG FileAttributes );
ULONG MRxSmbUnmapDisposition ( IN USHORT SmbDisposition, IN ULONG Disposition );
LARGE_INTEGER MRxSmbConvertSmbTimeToTime ( //IN PSMB_EXCHANGE Exchange OPTIONAL,
IN PSMBCE_SERVER Server OPTIONAL, IN SMB_TIME Time, IN SMB_DATE Date );
BOOLEAN MRxSmbConvertTimeToSmbTime ( IN PLARGE_INTEGER InputTime, IN PSMB_EXCHANGE Exchange OPTIONAL, OUT PSMB_TIME Time, OUT PSMB_DATE Date );
BOOLEAN MRxSmbTimeToSecondsSince1970 ( IN PLARGE_INTEGER CurrentTime, IN PSMBCE_SERVER Server OPTIONAL, OUT PULONG SecondsSince1970 );
VOID MRxSmbSecondsSince1970ToTime ( IN ULONG SecondsSince1970, IN PSMBCE_SERVER Server OPTIONAL, OUT PLARGE_INTEGER CurrentTime );
VOID MRxSmbResumeAsyncReadWriteRequests( PRX_CONTEXT RxContext);
#endif // _SMBPSE_H_
|