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