Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

841 lines
28 KiB

  1. /*++
  2. Copyright (c) 1989 Microsoft Corporation
  3. Module Name:
  4. SmbPse.h
  5. Abstract:
  6. This module defines the types and functions related to the SMB protocol
  7. selection engine: the component that translates minirdr calldowns into
  8. SMBs.
  9. Revision History:
  10. --*/
  11. #ifndef _SMBPSE_H_
  12. #define _SMBPSE_H_
  13. IMPORTANT_STRUCTURE(SMB_PSE_ORDINARY_EXCHANGE);
  14. //CODE.IMPROVEMENT is this the right place for this?
  15. #define StorageType(co) ((co) & FILE_STORAGE_TYPE_MASK)
  16. #define StorageFlag(co) ((co) & FILE_STORAGE_TYPE_SPECIFIED)
  17. #define IsStorageTypeSpecified(co) (StorageFlag(co) == FILE_STORAGE_TYPE_SPECIFIED)
  18. #define MustBeDirectory(co) ((co) & FILE_DIRECTORY_FILE)
  19. #define MustBeFile(co) ((co) & FILE_NON_DIRECTORY_FILE)
  20. //CODE.IMPROVEMENT The following should get fixed - use Tom's literal!
  21. #define CLUSTER_SIZE 0x1000
  22. //CODE.IMPROVEMENT.STACKSPACE we could save a dword of stack space
  23. // by not passing rxcontext
  24. // and by retrieving it from ordinaryexchange
  25. #define SMBPSE_ORDINARY_EXCHANGE_ARGUMENT_SIGNATURE \
  26. PSMB_PSE_ORDINARY_EXCHANGE OrdinaryExchange, \
  27. PRX_CONTEXT RxContext
  28. //CODE.IMPROVEMENT this is not used consistently. in particular, it is not used in the OE start wrapper
  29. // in order to not have any extra variables on the stack....a good idea but it breaks
  30. // this encapsulation. on a risc machine, they would be in registers anyway. so, it makes
  31. // sense to put in a comment there (and maybe the x86-specific code.......)
  32. #define SMBPSE_ORDINARY_EXCHANGE_ARGUMENTS \
  33. OrdinaryExchange,RxContext
  34. #if DBG
  35. #define OECHKLINKAGE_FLAG_NO_REQPCKT_CHECK 0x00000001
  36. VOID
  37. __SmbPseOEAssertConsistentLinkage(
  38. PSZ MsgPrefix,
  39. PSZ File,
  40. unsigned Line,
  41. PRX_CONTEXT RxContext,
  42. PSMB_PSE_ORDINARY_EXCHANGE OrdinaryExchange,
  43. PSMBSTUFFER_BUFFER_STATE StufferState,
  44. ULONG Flags
  45. );
  46. #define SmbPseOEAssertConsistentLinkage(a) {\
  47. __SmbPseOEAssertConsistentLinkage(a,__FILE__,__LINE__,RxContext,OrdinaryExchange,StufferState,0);\
  48. }
  49. #define SmbPseOEAssertConsistentLinkageFromOE(a) {\
  50. ASSERT_ORDINARY_EXCHANGE(OrdinaryExchange); \
  51. __SmbPseOEAssertConsistentLinkage(a,__FILE__,__LINE__, \
  52. OrdinaryExchange->RxContext, \
  53. OrdinaryExchange, \
  54. &OrdinaryExchange->AssociatedStufferState,0); \
  55. }
  56. #define SmbPseOEAssertConsistentLinkageFromOEwithFlags(a,FLAGS) {\
  57. ASSERT_ORDINARY_EXCHANGE(OrdinaryExchange); \
  58. __SmbPseOEAssertConsistentLinkage(a,__FILE__,__LINE__, \
  59. OrdinaryExchange->RxContext, \
  60. OrdinaryExchange, \
  61. &OrdinaryExchange->AssociatedStufferState,FLAGS); \
  62. }
  63. #else
  64. #define SmbPseOEAssertConsistentLinkage(a) {NOTHING;}
  65. #define SmbPseOEAssertConsistentLinkageFromOE(a) {NOTHING;}
  66. #define SmbPseOEAssertConsistentLinkageFromOEwithFlags(a,b) {NOTHING;}
  67. #endif
  68. typedef
  69. NTSTATUS
  70. (*PSMB_PSE_OE_START_ROUTINE) (
  71. SMBPSE_ORDINARY_EXCHANGE_ARGUMENT_SIGNATURE
  72. );
  73. typedef
  74. NTSTATUS
  75. (*PSMB_PSE_CONTINUATION_ROUTINE) (
  76. PSMB_PSE_ORDINARY_EXCHANGE
  77. );
  78. #define SMBPSE_OE_HISTORY_SIZE 32
  79. typedef struct _SMBPSE_HISTORY {
  80. ULONG Next;
  81. ULONG Submits; //could be shortened....
  82. struct {
  83. ULONG Longs[2];
  84. } Markers[SMBPSE_OE_HISTORY_SIZE];
  85. } SMBPSE_HISTORY;
  86. #if DBG
  87. VOID SmbPseUpdateOEHistory(
  88. PSMB_PSE_ORDINARY_EXCHANGE OrdinaryExchange,
  89. ULONG Tag1,
  90. ULONG Tag2
  91. );
  92. #define UPDATE_OE_HISTORY_LONG(a) {SmbPseUpdateOEHistory(OrdinaryExchange,a,0);}
  93. #define UPDATE_OE_HISTORY_2SHORTS(a,b) {SmbPseUpdateOEHistory(OrdinaryExchange,a,b);}
  94. #else
  95. #define UPDATE_OE_HISTORY_LONG(a)
  96. #define UPDATE_OE_HISTORY_2SHORTS(a,b)
  97. #endif //if DBG
  98. typedef enum _SMB_PSE_ORDINARY_EXCHANGE_TYPE {
  99. SMBPSE_OETYPE_LATENT_HEADEROPS,
  100. SMBPSE_OETYPE_CREATE,
  101. SMBPSE_OETYPE_COREOPEN,
  102. // SMBPSE_OETYPE_CLEANUP,
  103. SMBPSE_OETYPE_FINDCLOSE,
  104. SMBPSE_OETYPE_READ,
  105. SMBPSE_OETYPE_WRITE, SMBPSE_OETYPE_EXTEND_WRITE, SMBPSE_OETYPE_CORETRUNCATE,
  106. SMBPSE_OETYPE_LOCKS, SMBPSE_OETYPE_ASSERTBUFFEREDLOCKS,
  107. SMBPSE_OETYPE_FLUSH,
  108. SMBPSE_OETYPE_CLOSE, SMBPSE_OETYPE_CLOSEAFTERCORECREATE,
  109. //SMBPSE_OETYPE_SEARCH,
  110. SMBPSE_OETYPE_RENAME,
  111. SMBPSE_OETYPE_T2_FOR_NT_FILE_ALLOCATION_INFO, //MUST BE FIRST T2
  112. SMBPSE_OETYPE_T2_FOR_NT_DISKATTRIBUTES_INFO,
  113. SMBPSE_OETYPE_T2_FOR_ONE_FILE_DIRCTRL,
  114. SMBPSE_OETYPE_T2_FOR_LANMAN_DISKATTRIBUTES_INFO,
  115. SMBPSE_OETYPE_T2_FOR_LANMAN_VOLUMELABEL_INFO, //MUST BE LAST T2
  116. SMBPSE_OETYPE_GFA,
  117. // SMBPSE_OETYPE_GFA2,
  118. SMBPSE_OETYPE_COREINFO,
  119. SMBPSE_OETYPE_CORECREATE,
  120. SMBPSE_OETYPE_DELETEFORSUPERSEDEORCLOSE, SMBPSE_OETYPE_DELETE_FOR_RENAME,
  121. SMBPSE_OETYPE_CORECREATEDIRECTORY,
  122. SMBPSE_OETYPE_CORECHECKDIRECTORY,
  123. SMBPSE_OETYPE_SFA,
  124. SMBPSE_OETYPE_SFA2,
  125. SMBPSE_OETYPE_COREQUERYLABEL, SMBPSE_OETYPE_CORESEARCH, SMBPSE_OETYPE_CORESEARCHFORCHECKEMPTY,
  126. SMBPSE_OETYPE_COREQUERYDISKATTRIBUTES,
  127. SMBPSE_OETYPE_CREATEPRINTFILE,
  128. SMBPSE_OETYPE_IOCTL,
  129. SMBPSE_OETYPE_MAXIMUM
  130. } SMB_PSE_ORDINARY_EXCHANGE_TYPE;
  131. typedef enum _SMB_PSE_ORDINARY_EXCHANGE_ENTRYPOINTS {
  132. SMBPSE_OE_FROM_QUERYDIRECTORY,
  133. SMBPSE_OE_FROM_QUERYFILEINFO,
  134. SMBPSE_OE_FROM_SETFILEINFO,
  135. SMBPSE_OE_FROM_QUERYVOLUMEINFO,
  136. SMBPSE_OE_FROM_EXTENDFILEFORCACHEING,
  137. SMBPSE_OE_FROM_LOCKS,
  138. SMBPSE_OE_FROM_FLUSH,
  139. SMBPSE_OE_FROM_ASSERTBUFFEREDLOCKS,
  140. SMBPSE_OE_FROM_CLEANUPFOBX,
  141. SMBPSE_OE_FROM_CLOSESRVCALL,
  142. SMBPSE_OE_FROM_CLOSECOPYCHUNKSRVCALL,
  143. SMBPSE_OE_FROM_GETFILEINFOFORCSHADOW,
  144. SMBPSE_OE_FROM_CREATE,
  145. SMBPSE_OE_FROM_RENAME,
  146. SMBPSE_OE_FROM_READ,
  147. SMBPSE_OE_FROM_WRITE,
  148. SMBPSE_OE_FROM_FAKESETDELETEDISPOSITION,
  149. SMBPSE_OE_FROM_GETPRINTJOBID,
  150. SMBPSE_OE_FROM_MAXIMUM
  151. } SMB_PSE_ORDINARY_EXCHANGE_ENTRYPOINTS;
  152. #define SMBPSE_DEFINE_OE_FLAG(a,c) RX_DEFINE_FLAG(SMBPSE_OE_FLAG_##a,c,0xffff)
  153. typedef enum {
  154. SMBPSE_DEFINE_OE_FLAG(HEADER_ALREADY_PARSED, 0)
  155. SMBPSE_DEFINE_OE_FLAG(OE_ALREADY_RESUMED, 1)
  156. SMBPSE_DEFINE_OE_FLAG(VALIDATE_FID, 2)
  157. SMBPSE_DEFINE_OE_FLAG(OE_HDR_PARTIAL_INITIALIZED, 3)
  158. SMBPSE_DEFINE_OE_FLAG(OE_ALLOCATED_DATA_PARTIAL, 4)
  159. SMBPSE_DEFINE_OE_FLAG(OE_HDR_LOCKED, 5)
  160. //SMBPSE_DEFINE_OE_FLAG(SMBBUF_IS_A_MDL, 6)
  161. SMBPSE_DEFINE_OE_FLAG(NO_RESPONSE_EXPECTED, 7)
  162. SMBPSE_DEFINE_OE_FLAG(MUST_SUCCEED_ALLOCATED_OE, 8)
  163. SMBPSE_DEFINE_OE_FLAG(MUST_SUCCEED_ALLOCATED_SMBBUF, 9)
  164. SMBPSE_DEFINE_OE_FLAG(OE_AWAITING_DISPATCH, 10)
  165. SMBPSE_DEFINE_OE_FLAG(TURNON_DFS_FLAG, 11)
  166. //SMBPSE_DEFINE_OE_FLAG(NETROOT_GOOD, 15)
  167. } SMBPSE_OE_FLAGS;
  168. typedef enum _SMB_PSE_OE_INNERIO_STATE {
  169. SmbPseOEInnerIoStates_Initial = 0,
  170. SmbPseOEInnerIoStates_ReadyToSend,
  171. SmbPseOEInnerIoStates_OperationOutstanding,
  172. SmbPseOEInnerIoStates_OperationCompleted
  173. } SMB_PSE_OE_INNERIO_STATE;
  174. typedef enum _SMB_PSE_OE_READWRITE_STATE {
  175. SmbPseOEReadWriteIoStates_Initial = 0,
  176. SmbPseOEReadWriteIoStates_OperationOutstanding,
  177. SmbPseOEReadWriteIoStates_OperationCompleted,
  178. SmbPseOEReadWriteIoStates_OperationAbandoned
  179. } SMB_PSE_OE_READWRITE_STATE;
  180. #define MAX_PAGES_SPANNED_BY_PARTIAL_DATA_MDL (20)
  181. #define MAX_PAGES_SPANNED_BY_PARTIAL_EXCHANGE_MDL (2)
  182. #define MAX_PARTIAL_DATA_MDL_BUFFER_SIZE \
  183. (MAX_PAGES_SPANNED_BY_PARTIAL_DATA_MDL * PAGE_SIZE)
  184. #define MAX_PARTIAL_EXCHANGE_MDL_BUFFER_SIZE \
  185. (MAX_PAGES_SPANNED_BY_PARTIAL_EXCHANGE_MDL * PAGE_SIZE)
  186. extern FAST_MUTEX MRxSmbReadWriteMutex;
  187. typedef struct _SMB_PSE_OE_READWRITE {
  188. // don't add fields to the beginning of this struct
  189. // see CODE.IMPROVEMENT.ASHAMED below (in OrdinarySMB_PSE_ORDINARY_EXCHANGE definition)
  190. union {
  191. PBYTE UserBufferBase;
  192. PLOWIO_LOCK_LIST LockList;
  193. };
  194. PRX_CONTEXT RxContext;
  195. ULONG RemainingByteCount;
  196. ULONG ThisBytesRequested;
  197. ULONG ThisByteCount;
  198. ULONG ThisBufferOffset;
  199. LARGE_INTEGER ByteOffsetAsLI;
  200. ULONG BytesReturned;
  201. BOOLEAN PartialExchangeMdlInUse;
  202. BOOLEAN PartialDataMdlInUse;
  203. BOOLEAN CompressedRequestInProgress;
  204. BOOLEAN CompressedReadOrWrite;
  205. BOOLEAN WriteToTheEnd;
  206. BOOLEAN ReadWriteFinalized;
  207. ULONG CompressedDataInfoLength;
  208. PBYTE pCompressedDataBuffer;
  209. ULONG UserBufferPortionLength;
  210. ULONG ExchangeBufferPortionLength;
  211. union {
  212. MDL PartialDataMdl;
  213. COMPRESSED_DATA_INFO CompressedDataInfo;
  214. BYTE ByteBuffer1[
  215. sizeof(MDL) +
  216. sizeof(ULONG) * MAX_PAGES_SPANNED_BY_PARTIAL_DATA_MDL];
  217. };
  218. union {
  219. MDL PartialExchangeMdl;
  220. BYTE PartialExchangeMdlBuffer[
  221. sizeof(MDL) +
  222. sizeof(ULONG) * MAX_PAGES_SPANNED_BY_PARTIAL_EXCHANGE_MDL];
  223. };
  224. ULONG TotalNumOfSections;
  225. ULONG NumOfOutstandingOperations;
  226. ULONG MaximumBufferSize;
  227. ULONG CurrentSection;
  228. ULONG RefCount;
  229. PKEVENT CompletionEvent;
  230. NTSTATUS CompletionStatus;
  231. SMBFCB_HOLDING_STATE SmbFcbHoldingState;
  232. SMB_PSE_OE_READWRITE_STATE SectionState[];
  233. } SMB_PSE_OE_READWRITE, *PSMB_PSE_OE_READWRITE;
  234. #define OE_RW_FLAG_SUCCESS_IN_COPYHANDLER (0x01)
  235. #define OE_RW_FLAG_REDUCE_RETURNCOUNT (0x20) //used in pipewrites to track rawmode
  236. #define OE_RW_FLAG_SUBSEQUENT_OPERATION (0x40) //used in pipewrites to distinguish the first
  237. #define OE_RW_FLAG_MSGMODE_PIPE_OPERATION (0x80) //MAX VALUE, it's just a byte.....
  238. #define SMB_PSE_OE_HDR_MDL_PAGES (2 + (ADDRESS_AND_SIZE_TO_SPAN_PAGES( (ULONG) 0, MAXIMUM_SMB_BUFFER_SIZE )))
  239. typedef struct _SMB_PSE_ORDINARY_EXCHANGE{
  240. union {
  241. SMB_EXCHANGE Exchange;
  242. SMB_EXCHANGE;
  243. };
  244. SMB_PSE_ORDINARY_EXCHANGE_TYPE OEType;
  245. SMB_PSE_ORDINARY_EXCHANGE_ENTRYPOINTS EntryPoint;
  246. ULONG SmbBufSize;
  247. ULONG StartEntryCount;
  248. PMDL DataPartialMdl;
  249. USHORT Flags;
  250. UCHAR OpSpecificFlags;
  251. UCHAR OpSpecificState;
  252. UCHAR LastSmbCommand;
  253. ULONG SendOptions;
  254. GENERIC_ANDX ParseResumeState;
  255. NTSTATUS NoCopyFinalStatus;
  256. NTSTATUS SendCompletionStatus;
  257. ULONG MessageLength;
  258. SMBFCB_HOLDING_STATE SmbFcbHoldingState; //plenty of pad....only 2 bits used
  259. PSMB_PSE_OE_START_ROUTINE AsyncResumptionRoutine;
  260. PSMB_PSE_OE_START_ROUTINE StartRoutine;
  261. PSMB_PSE_CONTINUATION_ROUTINE ContinuationRoutine;
  262. union {
  263. struct {
  264. SMBPSE_FILEINFO_BUNDLE FileInfo;
  265. PMRX_SMB_SRV_OPEN smbSrvOpen;
  266. RX_FILE_TYPE StorageTypeFromGFA;
  267. ///DO NOT CHANGE ABOVE HERE UNLESS YOU CHANGE THE INFO ARM AS WELL
  268. MRXSMB_CREATE_PARAMETERS SmbCp;
  269. BOOLEAN MustRegainExclusiveResource;
  270. BOOLEAN CreateWithEasSidsOrLongName;
  271. ULONG FidReturnedFromCreate;
  272. ULONG FidReturnedFromOpen;
  273. ULONG FileSizeReturnedFromOpen;
  274. BOOLEAN FileWasCreated;
  275. BOOLEAN FileWasTruncated;
  276. //UNICODE_STRING PathNameForCoreOperation;
  277. } Create;
  278. SMB_PSE_OE_READWRITE ReadWrite; //also used for locks
  279. struct {
  280. SMBPSE_FILEINFO_BUNDLE FileInfo;
  281. PMRX_SMB_SRV_OPEN smbSrvOpen;
  282. RX_FILE_TYPE StorageTypeFromGFA;
  283. ///DO NOT CHANGE ABOVE HERE UNLESS YOU CHANGE THE CREATE ARM AS WELL
  284. PVOID Buffer;
  285. PULONG pBufferLength;
  286. ULONG InfoClass;
  287. union {
  288. struct {
  289. UCHAR CoreLabel[13]; //right from smb.h
  290. } QFSVolInfo;
  291. struct {
  292. ULONG CountRemaining;
  293. ULONG CountRemainingInSmbbuf;
  294. PSMB_DIRECTORY_INFORMATION NextDirInfo;
  295. //there should be a union here
  296. PSMB_RESUME_KEY EmptyCheckResumeKey;
  297. SMB_RESUME_KEY EmptyCheckResumeKeyBuffer;
  298. } CoreSearch;
  299. };
  300. } Info;
  301. struct {
  302. LARGE_INTEGER AllocationSize;
  303. } Transact2;
  304. struct {
  305. PUCHAR PtrToLockType; //this must be here because the beginning of the
  306. //lockstart code sets the locklist to zero which will be this
  307. //CODE.IMPROVEMENT.ASHAMED fix this up so that assert locks uses readwrite
  308. PMRX_SRV_OPEN SrvOpen;
  309. PRX_LOCK_ENUMERATOR LockEnumerator;
  310. PVOID ContinuationHandle;
  311. ULONG NumberOfLocksPlaced;
  312. LARGE_INTEGER NextLockOffset;
  313. LARGE_INTEGER NextLockRange;
  314. BOOLEAN NextLockIsExclusive;
  315. BOOLEAN LockAreaNonEmpty;
  316. BOOLEAN EndOfListReached;
  317. } AssertLocks;
  318. } ;
  319. PSMB_PSE_OE_READWRITE GlobalReadWrite;
  320. PUNICODE_STRING pPathArgument1; // Unicode path
  321. union {
  322. PUNICODE_STRING pPathArgument2; // secondary unicode path
  323. PVOID Find32WithinSmbbuf;
  324. };
  325. PSMBSTUFFER_BUFFER_STATE StufferStateDbgPtr; //this is just for the debugger....get rid of it
  326. SMBSTUFFER_BUFFER_STATE AssociatedStufferState;
  327. struct {
  328. union {
  329. MDL;
  330. MDL Mdl;
  331. };
  332. ULONG Pages2[SMB_PSE_OE_HDR_MDL_PAGES];
  333. } HeaderMdl;
  334. struct {
  335. union {
  336. MDL;
  337. MDL Mdl;
  338. };
  339. ULONG Pages2[SMB_PSE_OE_HDR_MDL_PAGES];
  340. } HeaderPartialMdl;
  341. //#if DBG CODE.IMPROVEMENT we should get rid of what we don't really, really need
  342. ULONG SerialNumber;
  343. SMBPSE_HISTORY History;
  344. PIRP RxContextCapturedRequestPacket;
  345. PMDL SaveDataMdlForDebug;
  346. ULONG SaveLengthForDebug;
  347. PMDL SaveIrpMdlForDebug;
  348. //#endif
  349. ULONG BytesAvailableCopy;
  350. ULONG BytesIndicatedCopy;
  351. } SMB_PSE_ORDINARY_EXCHANGE, *PSMB_PSE_ORDINARY_EXCHANGE;
  352. // CODE.IMPROVEMENT actually, we have to get rid of a message...we need to know the length in the long term
  353. // in the short term this will be okay. i think that what i really have to do is to return error_discard
  354. // or something like that
  355. #define SmbPseDiscardProtocol(__STATUS__) { \
  356. *pBytesTaken = BytesAvailable; \
  357. pExchange->Status = (__STATUS__); \
  358. }
  359. NTSTATUS
  360. SmbPseOrdinaryExchange(
  361. SMBPSE_ORDINARY_EXCHANGE_ARGUMENT_SIGNATURE,
  362. IN SMB_PSE_ORDINARY_EXCHANGE_TYPE OEType
  363. );
  364. NTSTATUS
  365. SmbPseResumeOrdinaryExchange(
  366. IN OUT PRX_CONTEXT RxContext
  367. );
  368. #define ASSERT_ORDINARY_EXCHANGE(__p) ASSERT(NodeType(__p)==SMB_EXCHANGE_NTC(ORDINARY_EXCHANGE))
  369. NTSTATUS
  370. __SmbPseCreateOrdinaryExchange (
  371. IN PRX_CONTEXT RxContext,
  372. IN PMRX_V_NET_ROOT VNetRoot,
  373. IN SMB_PSE_ORDINARY_EXCHANGE_ENTRYPOINTS EntryPoint,
  374. IN PSMB_PSE_OE_START_ROUTINE StartRoutine,
  375. IN OUT SMBFCB_HOLDING_STATE *SmbFcbHoldingState OPTIONAL,
  376. OUT PSMB_PSE_ORDINARY_EXCHANGE *OrdinaryExchangePtr
  377. );
  378. #define SmbPseCreateOrdinaryExchange(__rxcontext,__vnetroot,__entrypoint,__start,__ordinaryexchangeptr) \
  379. __SmbPseCreateOrdinaryExchange(__rxcontext,__vnetroot,__entrypoint,__start,NULL,__ordinaryexchangeptr)
  380. BOOLEAN
  381. SmbPseFinalizeOrdinaryExchange (
  382. IN OUT PSMB_PSE_ORDINARY_EXCHANGE OrdinaryExchange
  383. );
  384. #define SmbPseInitiateOrdinaryExchange(OrdinaryExchange) (SmbCeInitiateExchange(&OrdinaryExchange->Exchange))
  385. // this macro is used to do the async completion for read/write/locks. Note that the call to lowiocompletion
  386. // will try to complete the irp thereby freeing the user's mdl. so, we better get rid of the partial first.
  387. // we use this macro so that there will be only one version of this code. when we combine start routines,
  388. // this will be un macroed
  389. #define SmbPseAsyncCompletionIfNecessary(OE,RXCONTEXT) { \
  390. if (StartEntryCount>1) { \
  391. BOOLEAN FinalizationComplete; \
  392. if (FALSE) {DbgBreakPoint(); } \
  393. if ( (OE)->DataPartialMdl ) { \
  394. if (FlagOn((OE)->Flags, SMBPSE_OE_FLAG_MUST_SUCCEED_ALLOCATED_SMBBUF)){\
  395. MmPrepareMdlForReuse((OE)->DataPartialMdl); \
  396. } else { \
  397. IoFreeMdl((OE)->DataPartialMdl); \
  398. (OE)->DataPartialMdl = NULL; \
  399. ClearFlag((OE)->Flags,SMBPSE_OE_FLAG_OE_ALLOCATED_DATA_PARTIAL); \
  400. } \
  401. } \
  402. (RXCONTEXT)->StoredStatus = Status; \
  403. \
  404. RxLowIoCompletion((RXCONTEXT)); \
  405. FinalizationComplete = SmbPseFinalizeOrdinaryExchange((OE)); \
  406. ASSERT(!FinalizationComplete); \
  407. Status = STATUS_PENDING; \
  408. }}
  409. /* ------------------------------------------
  410. ------------------------------------------
  411. Receive Handler Stuff
  412. ------------------------------------------
  413. ------------------------------------------
  414. */
  415. VOID
  416. SmbPseInitializeTables(
  417. void
  418. );
  419. typedef
  420. NTSTATUS
  421. (*PSMBPSE_RECEIVE_HANDLER) (
  422. PSMB_PSE_ORDINARY_EXCHANGE OrdinaryExchange,
  423. PBYTE Response
  424. );
  425. //boy, talk about a load of arguments
  426. typedef
  427. UCHAR
  428. (*PSMBPSE_NOCOPY_RECEIVE_HANDLER) (
  429. IN OUT PSMB_PSE_ORDINARY_EXCHANGE OrdinaryExchange,
  430. IN ULONG BytesIndicated,
  431. IN ULONG BytesAvailable,
  432. OUT ULONG *pBytesTaken,
  433. IN PSMB_HEADER pSmbHeader,
  434. OUT PMDL *pDataBufferPointer,
  435. OUT PULONG pDataSize,
  436. #if DBG
  437. IN UCHAR ThisIsAReenter,
  438. #endif
  439. IN PBYTE Response
  440. );
  441. #define SMBPSE_NOCOPYACTION_NORMALFINISH 0x00
  442. #define SMBPSE_NOCOPYACTION_MDLFINISH 0x01
  443. #define SMBPSE_NOCOPYACTION_DISCARD 0x02
  444. #define SMBPSE_NOCOPYACTION_COPY_FOR_RESUME 0x03
  445. #define SMBPSE_RMP_MODELED (0x00000001)
  446. #define SMBPSE_RMP_THIS_IS_ANDX (0x00000002)
  447. #define SMBPSE_RMP_WARNINGS_OK (0x00000004)
  448. #define SMBPSE_RMP_NOCOPY_HANDLER (0x00000008)
  449. #define SMBPSE_RMP_FORCE_SYNC (0x00000010)
  450. typedef enum _SMBPSE_RECEIVE_HANDLER_TOKEN {
  451. SMBPSE_RECEIVE_HANDLER_TOKEN_READ_ANDX_HANDLER = 0,
  452. SMBPSE_RECEIVE_HANDLER_TOKEN_READ_HANDLER,
  453. SMBPSE_RECEIVE_HANDLER_TOKEN_WRITE_ANDX_HANDLER,
  454. SMBPSE_RECEIVE_HANDLER_TOKEN_WRITE_HANDLER,
  455. SMBPSE_RECEIVE_HANDLER_TOKEN_LOCKING_ANDX_HANDLER,
  456. SMBPSE_RECEIVE_HANDLER_TOKEN_OPEN_PRINTFILE_HANDLER,
  457. SMBPSE_RECEIVE_HANDLER_TOKEN_WRITE_PRINTFILE_HANDLER,
  458. SMBPSE_RECEIVE_HANDLER_TOKEN_CLOSE_HANDLER, //also close_print_file
  459. SMBPSE_RECEIVE_HANDLER_TOKEN_NTCREATE_ANDX_HANDLER,
  460. SMBPSE_RECEIVE_HANDLER_TOKEN_OPEN_ANDX_HANDLER,
  461. SMBPSE_RECEIVE_HANDLER_TOKEN_CREATE_HANDLER, //also create_new
  462. SMBPSE_RECEIVE_HANDLER_TOKEN_OPEN_HANDLER,
  463. SMBPSE_RECEIVE_HANDLER_TOKEN_TRANS2_ANDX_HANDLER,
  464. SMBPSE_RECEIVE_HANDLER_TOKEN_GFA_HANDLER,
  465. SMBPSE_RECEIVE_HANDLER_TOKEN_SEARCH_HANDLER,
  466. SMBPSE_RECEIVE_HANDLER_TOKEN_QUERYDISKINFO_HANDLER,
  467. SMBPSE_RECEIVE_HANDLER_TOKEN_IOCTL_HANDLER,
  468. SMBPSE_RECEIVE_HANDLER_TOKEN_MAXIMUM
  469. } SMBPSE_RECEIVE_HANDLER_TOKEN;
  470. PSMBPSE_RECEIVE_HANDLER SmbPseReceiveHandlers[SMBPSE_RECEIVE_HANDLER_TOKEN_MAXIMUM];
  471. typedef struct _SMBPSE_RECEIVE_MODEL_PARAMETERS {
  472. UCHAR Flags;
  473. UCHAR ReceiveHandlerToken;
  474. #if DBG
  475. USHORT Dummy;
  476. PSMBPSE_RECEIVE_HANDLER ReceiveHandler;
  477. PBYTE IndicationString;
  478. SMB_PSE_ORDINARY_EXCHANGE_TYPE LowType,HighType;
  479. #endif
  480. } SMBPSE_RECEIVE_MODEL_PARAMETERS, *PSMBPSE_RECEIVE_MODEL_PARAMETERS;
  481. SMBPSE_RECEIVE_MODEL_PARAMETERS SmbPseReceiveModelParameters[256]; //there are 256 possible smbs
  482. typedef struct _SMBPSE_VESTIGIAL_SMBBUF {
  483. NT_SMB_HEADER Header;
  484. union {
  485. REQ_WRITE Write;
  486. REQ_NT_WRITE_ANDX WriteAndX;
  487. REQ_FLUSH Flush;
  488. struct {
  489. REQ_LOCKING_ANDX LockingAndX;
  490. NTLOCKING_ANDX_RANGE Locks[20]; //CODE.IMPROVEMENT.ASHAMED see locks.c
  491. };
  492. REQ_FIND_CLOSE2 FindClose;
  493. REQ_CLOSE Close;
  494. };
  495. ULONG Pad;
  496. } SMBPSE_VESTIGIAL_SMBBUF;
  497. // Finishing routines - these are all cast into the correct procedure type
  498. // so that the response will already have the correct SMB format
  499. // on entry to the routine
  500. //CODE.IMPROVEMENT the names of these routines should be changed from FinishX to X_Handler
  501. //CODE.IMPROVEMENT also, any routine that doesn't retrieve data should be changed over to a nocopy handler
  502. NTSTATUS
  503. MRxSmbFinishNTCreateAndX (
  504. IN OUT PSMB_PSE_ORDINARY_EXCHANGE OrdinaryExchange,
  505. IN PRESP_NT_CREATE_ANDX Response
  506. );
  507. #define MRxSmbReceiveHandler_NTCreateAndX ((PSMBPSE_RECEIVE_HANDLER)MRxSmbFinishNTCreateAndX)
  508. NTSTATUS
  509. MRxSmbFinishOpenAndX (
  510. IN OUT PSMB_PSE_ORDINARY_EXCHANGE OrdinaryExchange,
  511. IN PRESP_OPEN_ANDX Response
  512. );
  513. #define MRxSmbReceiveHandler_OpenAndX ((PSMBPSE_RECEIVE_HANDLER)MRxSmbFinishOpenAndX)
  514. NTSTATUS
  515. MRxSmbFinishClose (
  516. IN OUT PSMB_PSE_ORDINARY_EXCHANGE OrdinaryExchange,
  517. IN PRESP_CLOSE Response
  518. );
  519. //use the close finsh routine for closeprintfile as well
  520. #define MRxSmbReceiveHandler_Close ((PSMBPSE_RECEIVE_HANDLER)MRxSmbFinishClose)
  521. NTSTATUS
  522. MRxSmbFinishGFA (
  523. IN OUT PSMB_PSE_ORDINARY_EXCHANGE OrdinaryExchange,
  524. IN PVOID Response
  525. );
  526. #define MRxSmbReceiveHandler_GetFileAttributes ((PSMBPSE_RECEIVE_HANDLER)MRxSmbFinishGFA)
  527. NTSTATUS
  528. MRxSmbFinishTransaction2 (
  529. IN OUT PSMB_PSE_ORDINARY_EXCHANGE OrdinaryExchange,
  530. IN PRESP_TRANSACTION Response
  531. );
  532. #define MRxSmbReceiveHandler_Transact2 ((PSMBPSE_RECEIVE_HANDLER)MRxSmbFinishTransaction2)
  533. NTSTATUS
  534. MRxSmbFinishCoreOpen (
  535. IN OUT PSMB_PSE_ORDINARY_EXCHANGE OrdinaryExchange,
  536. IN PRESP_OPEN Response
  537. );
  538. #define MRxSmbReceiveHandler_CoreOpen ((PSMBPSE_RECEIVE_HANDLER)MRxSmbFinishCoreOpen)
  539. NTSTATUS
  540. MRxSmbFinishCoreCreate (
  541. IN OUT PSMB_PSE_ORDINARY_EXCHANGE OrdinaryExchange,
  542. IN PRESP_CREATE Response
  543. );
  544. #define MRxSmbReceiveHandler_CoreCreate ((PSMBPSE_RECEIVE_HANDLER)MRxSmbFinishCoreCreate)
  545. NTSTATUS
  546. MRxSmbFinishCoreIoCtl(
  547. PSMB_PSE_ORDINARY_EXCHANGE OrdinaryExchange,
  548. PRESP_IOCTL Response
  549. );
  550. #define MRxSmbReceiveHandler_Ioctl ((PSMBPSE_RECEIVE_HANDLER)MRxSmbFinishCoreIoCtl)
  551. //NTSTATUS
  552. //MRxSmbFinishRead (
  553. // IN OUT PSMB_PSE_ORDINARY_EXCHANGE OrdinaryExchange,
  554. // IN PRESP_READ_ANDX Response
  555. // );
  556. //#define MRxSmbReceiveHandler_ReadAndX ((PSMBPSE_RECEIVE_HANDLER)MRxSmbFinishRead)
  557. //NTSTATUS
  558. //MRxSmbFinishCoreRead (
  559. // IN OUT PSMB_PSE_ORDINARY_EXCHANGE OrdinaryExchange,
  560. // IN PRESP_READ Response
  561. // );
  562. //#define MRxSmbReceiveHandler_CoreRead ((PSMBPSE_RECEIVE_HANDLER)MRxSmbFinishCoreRead)
  563. UCHAR
  564. MRxSmbReadHandler_NoCopy (
  565. IN OUT PSMB_PSE_ORDINARY_EXCHANGE OrdinaryExchange,
  566. IN ULONG BytesIndicated,
  567. IN ULONG BytesAvailable,
  568. OUT ULONG *pBytesTaken,
  569. IN PSMB_HEADER pSmbHeader,
  570. OUT PMDL *pDataBufferPointer,
  571. OUT PULONG pDataSize,
  572. #if DBG
  573. IN UCHAR ThisIsAReenter,
  574. #endif
  575. IN PRESP_READ_ANDX Response
  576. );
  577. #define MRxSmbReceiveHandler_Read_NoCopy ((PSMBPSE_RECEIVE_HANDLER)MRxSmbReadHandler_NoCopy)
  578. NTSTATUS
  579. MRxSmbFinishCreatePrintFile (
  580. IN OUT PSMB_PSE_ORDINARY_EXCHANGE OrdinaryExchange,
  581. IN PRESP_OPEN_PRINT_FILE Response
  582. );
  583. #define MRxSmbReceiveHandler_OpenPrintFile ((PSMBPSE_RECEIVE_HANDLER)MRxSmbFinishCreatePrintFile)
  584. NTSTATUS
  585. MRxSmbFinishWrite (
  586. IN OUT PSMB_PSE_ORDINARY_EXCHANGE OrdinaryExchange,
  587. IN PBYTE Response
  588. );
  589. #define MRxSmbReceiveHandler_WritePrintFile ((PSMBPSE_RECEIVE_HANDLER)MRxSmbFinishWrite)
  590. #define MRxSmbReceiveHandler_WriteAndX ((PSMBPSE_RECEIVE_HANDLER)MRxSmbFinishWrite)
  591. #define MRxSmbReceiveHandler_CoreWrite ((PSMBPSE_RECEIVE_HANDLER)MRxSmbFinishWrite)
  592. NTSTATUS
  593. MRxSmbFinishLocks (
  594. IN OUT PSMB_PSE_ORDINARY_EXCHANGE OrdinaryExchange,
  595. IN PRESP_LOCKING_ANDX Response
  596. );
  597. #define MRxSmbReceiveHandler_LockingAndX ((PSMBPSE_RECEIVE_HANDLER)MRxSmbFinishLocks)
  598. #if 0
  599. NTSTATUS
  600. MRxSmbFinishFlush (
  601. IN OUT PSMB_PSE_ORDINARY_EXCHANGE OrdinaryExchange,
  602. IN PRESP_FLUSH Response
  603. );
  604. #endif //if 0
  605. NTSTATUS
  606. MRxSmbFinishSearch (
  607. PSMB_PSE_ORDINARY_EXCHANGE OrdinaryExchange,
  608. PRESP_SEARCH Response
  609. );
  610. #define MRxSmbReceiveHandler_Search ((PSMBPSE_RECEIVE_HANDLER)MRxSmbFinishSearch)
  611. NTSTATUS
  612. MRxSmbFinishQueryDiskInfo (
  613. PSMB_PSE_ORDINARY_EXCHANGE OrdinaryExchange,
  614. PRESP_QUERY_INFORMATION_DISK Response
  615. );
  616. #define MRxSmbReceiveHandler_QueryDiskInfo ((PSMBPSE_RECEIVE_HANDLER)MRxSmbFinishQueryDiskInfo)
  617. //CODE.IMPROVEMENT.ASHAMED it would be so much better if
  618. // __MRxSmbSimpleSyncTransact2were divided into two routines.....one for
  619. // building and another for submitting. it would save some stack space.
  620. typedef
  621. NTSTATUS
  622. (*PSMB_PSE_OE_T2_FIXUP_ROUTINE) (
  623. PSMB_PSE_ORDINARY_EXCHANGE
  624. );
  625. NTSTATUS
  626. __MRxSmbSimpleSyncTransact2(
  627. SMBPSE_ORDINARY_EXCHANGE_ARGUMENT_SIGNATURE,
  628. IN SMB_PSE_ORDINARY_EXCHANGE_TYPE OEType,
  629. IN ULONG TransactSetupCode,
  630. IN PVOID Params,
  631. IN ULONG ParamsLength,
  632. IN PVOID Data,
  633. IN ULONG DataLength,
  634. IN PSMB_PSE_OE_T2_FIXUP_ROUTINE FixupRoutine
  635. );
  636. #define MRxSmbSimpleSyncTransact2(a,b,c,d,e,f,g) \
  637. __MRxSmbSimpleSyncTransact2(a,b,c,d,e,f,g,NULL);
  638. NTSTATUS
  639. MRxSmbDeferredCreate (
  640. IN OUT PRX_CONTEXT RxContext
  641. );
  642. NTSTATUS
  643. MRxSmbConstructDeferredOpenContext (
  644. IN OUT PRX_CONTEXT RxContext
  645. );
  646. //downlevel stuff....
  647. NTSTATUS
  648. MRxSmbPseudoOpenTailFromGFAResponse (
  649. PSMB_PSE_ORDINARY_EXCHANGE OrdinaryExchange
  650. );
  651. NTSTATUS
  652. MRxSmbPseudoOpenTailFromFakeGFAResponse (
  653. PSMB_PSE_ORDINARY_EXCHANGE OrdinaryExchange,
  654. RX_FILE_TYPE StorageType //CODE.IMPROVEMENT this should be a RDBSS_STORAGE_TYPE
  655. );
  656. NTSTATUS
  657. MRxSmbCoreTruncate(
  658. SMBPSE_ORDINARY_EXCHANGE_ARGUMENT_SIGNATURE,
  659. ULONG Fid,
  660. ULONG FileTruncationPoint
  661. );
  662. NTSTATUS
  663. MRxSmbCoreInformation(
  664. IN OUT PRX_CONTEXT RxContext,
  665. IN ULONG InformationClass,
  666. IN OUT PVOID pBuffer,
  667. IN OUT PULONG pBufferLength,
  668. IN SMB_PSE_ORDINARY_EXCHANGE_ENTRYPOINTS EntryPoint
  669. );
  670. ULONG
  671. MRxSmbMapSmbAttributes (
  672. IN USHORT SmbAttribs
  673. );
  674. USHORT
  675. MRxSmbMapDisposition (
  676. IN ULONG Disposition
  677. );
  678. USHORT
  679. MRxSmbMapShareAccess (
  680. IN USHORT ShareAccess
  681. );
  682. USHORT
  683. MRxSmbMapDesiredAccess (
  684. IN ULONG DesiredAccess
  685. );
  686. USHORT
  687. MRxSmbMapFileAttributes (
  688. IN ULONG FileAttributes
  689. );
  690. ULONG
  691. MRxSmbUnmapDisposition (
  692. IN USHORT SmbDisposition,
  693. IN ULONG Disposition
  694. );
  695. LARGE_INTEGER
  696. MRxSmbConvertSmbTimeToTime (
  697. //IN PSMB_EXCHANGE Exchange OPTIONAL,
  698. IN PSMBCE_SERVER Server OPTIONAL,
  699. IN SMB_TIME Time,
  700. IN SMB_DATE Date
  701. );
  702. BOOLEAN
  703. MRxSmbConvertTimeToSmbTime (
  704. IN PLARGE_INTEGER InputTime,
  705. IN PSMB_EXCHANGE Exchange OPTIONAL,
  706. OUT PSMB_TIME Time,
  707. OUT PSMB_DATE Date
  708. );
  709. BOOLEAN
  710. MRxSmbTimeToSecondsSince1970 (
  711. IN PLARGE_INTEGER CurrentTime,
  712. IN PSMBCE_SERVER Server OPTIONAL,
  713. OUT PULONG SecondsSince1970
  714. );
  715. VOID
  716. MRxSmbSecondsSince1970ToTime (
  717. IN ULONG SecondsSince1970,
  718. IN PSMBCE_SERVER Server OPTIONAL,
  719. OUT PLARGE_INTEGER CurrentTime
  720. );
  721. VOID
  722. MRxSmbResumeAsyncReadWriteRequests(
  723. PRX_CONTEXT RxContext);
  724. #endif // _SMBPSE_H_