Source code of Windows XP (NT5)
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.

834 lines
27 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. union {
  189. PBYTE UserBufferBase;
  190. PLOWIO_LOCK_LIST LockList;
  191. };
  192. ULONG RemainingByteCount;
  193. ULONG ThisBytesRequested;
  194. ULONG ThisByteCount;
  195. ULONG ThisBufferOffset;
  196. LARGE_INTEGER ByteOffsetAsLI;
  197. ULONG BytesReturned;
  198. BOOLEAN PartialExchangeMdlInUse;
  199. BOOLEAN PartialDataMdlInUse;
  200. BOOLEAN CompressedRequestInProgress;
  201. BOOLEAN CompressedReadOrWrite;
  202. BOOLEAN WriteToTheEnd;
  203. BOOLEAN ReadWriteFinalized;
  204. ULONG CompressedDataInfoLength;
  205. PBYTE pCompressedDataBuffer;
  206. ULONG UserBufferPortionLength;
  207. ULONG ExchangeBufferPortionLength;
  208. union {
  209. MDL PartialDataMdl;
  210. COMPRESSED_DATA_INFO CompressedDataInfo;
  211. BYTE ByteBuffer1[
  212. sizeof(MDL) +
  213. sizeof(ULONG) * MAX_PAGES_SPANNED_BY_PARTIAL_DATA_MDL];
  214. };
  215. union {
  216. MDL PartialExchangeMdl;
  217. BYTE PartialExchangeMdlBuffer[
  218. sizeof(MDL) +
  219. sizeof(ULONG) * MAX_PAGES_SPANNED_BY_PARTIAL_EXCHANGE_MDL];
  220. };
  221. ULONG TotalNumOfSections;
  222. ULONG NumOfOutstandingOperations;
  223. ULONG MaximumBufferSize;
  224. ULONG CurrentSection;
  225. ULONG RefCount;
  226. KEVENT CompletionEvent;
  227. NTSTATUS CompletionStatus;
  228. SMBFCB_HOLDING_STATE SmbFcbHoldingState;
  229. SMB_PSE_OE_READWRITE_STATE SectionState[];
  230. } SMB_PSE_OE_READWRITE, *PSMB_PSE_OE_READWRITE;
  231. #define OE_RW_FLAG_SUCCESS_IN_COPYHANDLER (0x01)
  232. #define OE_RW_FLAG_REDUCE_RETURNCOUNT (0x20) //used in pipewrites to track rawmode
  233. #define OE_RW_FLAG_SUBSEQUENT_OPERATION (0x40) //used in pipewrites to distinguish the first
  234. #define OE_RW_FLAG_MSGMODE_PIPE_OPERATION (0x80) //MAX VALUE, it's just a byte.....
  235. #define SMB_PSE_OE_HDR_MDL_PAGES (2 + (ADDRESS_AND_SIZE_TO_SPAN_PAGES( (ULONG) 0, MAXIMUM_SMB_BUFFER_SIZE )))
  236. typedef struct _SMB_PSE_ORDINARY_EXCHANGE{
  237. union {
  238. SMB_EXCHANGE Exchange;
  239. SMB_EXCHANGE;
  240. };
  241. SMB_PSE_ORDINARY_EXCHANGE_TYPE OEType;
  242. SMB_PSE_ORDINARY_EXCHANGE_ENTRYPOINTS EntryPoint;
  243. ULONG SmbBufSize;
  244. ULONG StartEntryCount;
  245. PMDL DataPartialMdl;
  246. USHORT Flags;
  247. UCHAR OpSpecificFlags;
  248. UCHAR OpSpecificState;
  249. UCHAR LastSmbCommand;
  250. ULONG SendOptions;
  251. GENERIC_ANDX ParseResumeState;
  252. NTSTATUS NoCopyFinalStatus;
  253. NTSTATUS SendCompletionStatus;
  254. ULONG MessageLength;
  255. SMBFCB_HOLDING_STATE SmbFcbHoldingState; //plenty of pad....only 2 bits used
  256. PSMB_PSE_OE_START_ROUTINE AsyncResumptionRoutine;
  257. PSMB_PSE_OE_START_ROUTINE StartRoutine;
  258. PSMB_PSE_CONTINUATION_ROUTINE ContinuationRoutine;
  259. union {
  260. struct {
  261. SMBPSE_FILEINFO_BUNDLE FileInfo;
  262. PMRX_SMB_SRV_OPEN smbSrvOpen;
  263. RX_FILE_TYPE StorageTypeFromGFA;
  264. ///DO NOT CHANGE ABOVE HERE UNLESS YOU CHANGE THE INFO ARM AS WELL
  265. MRXSMB_CREATE_PARAMETERS SmbCp;
  266. BOOLEAN MustRegainExclusiveResource;
  267. BOOLEAN CreateWithEasSidsOrLongName;
  268. ULONG FidReturnedFromCreate;
  269. ULONG FidReturnedFromOpen;
  270. ULONG FileSizeReturnedFromOpen;
  271. BOOLEAN FileWasCreated;
  272. BOOLEAN FileWasTruncated;
  273. //UNICODE_STRING PathNameForCoreOperation;
  274. } Create;
  275. SMB_PSE_OE_READWRITE ReadWrite; //also used for locks
  276. struct {
  277. SMBPSE_FILEINFO_BUNDLE FileInfo;
  278. PMRX_SMB_SRV_OPEN smbSrvOpen;
  279. RX_FILE_TYPE StorageTypeFromGFA;
  280. ///DO NOT CHANGE ABOVE HERE UNLESS YOU CHANGE THE CREATE ARM AS WELL
  281. PVOID Buffer;
  282. PULONG pBufferLength;
  283. ULONG InfoClass;
  284. union {
  285. struct {
  286. UCHAR CoreLabel[13]; //right from smb.h
  287. } QFSVolInfo;
  288. struct {
  289. ULONG CountRemaining;
  290. ULONG CountRemainingInSmbbuf;
  291. PSMB_DIRECTORY_INFORMATION NextDirInfo;
  292. //there should be a union here
  293. PSMB_RESUME_KEY EmptyCheckResumeKey;
  294. SMB_RESUME_KEY EmptyCheckResumeKeyBuffer;
  295. } CoreSearch;
  296. };
  297. } Info;
  298. struct {
  299. LARGE_INTEGER AllocationSize;
  300. } Transact2;
  301. struct {
  302. PUCHAR PtrToLockType; //this must be here because the beginning of the
  303. //lockstart code sets the locklist to zero which will be this
  304. //CODE.IMPROVEMENT.ASHAMED fix this up so that assert locks uses readwrite
  305. PMRX_SRV_OPEN SrvOpen;
  306. PRX_LOCK_ENUMERATOR LockEnumerator;
  307. PVOID ContinuationHandle;
  308. ULONG NumberOfLocksPlaced;
  309. LARGE_INTEGER NextLockOffset;
  310. LARGE_INTEGER NextLockRange;
  311. BOOLEAN NextLockIsExclusive;
  312. BOOLEAN LockAreaNonEmpty;
  313. BOOLEAN EndOfListReached;
  314. } AssertLocks;
  315. } ;
  316. PSMB_PSE_OE_READWRITE GlobalReadWrite;
  317. PUNICODE_STRING pPathArgument1; // Unicode path
  318. union {
  319. PUNICODE_STRING pPathArgument2; // secondary unicode path
  320. PVOID Find32WithinSmbbuf;
  321. };
  322. PSMBSTUFFER_BUFFER_STATE StufferStateDbgPtr; //this is just for the debugger....get rid of it
  323. SMBSTUFFER_BUFFER_STATE AssociatedStufferState;
  324. struct {
  325. union {
  326. MDL;
  327. MDL Mdl;
  328. };
  329. ULONG Pages2[SMB_PSE_OE_HDR_MDL_PAGES];
  330. } HeaderMdl;
  331. struct {
  332. union {
  333. MDL;
  334. MDL Mdl;
  335. };
  336. ULONG Pages2[SMB_PSE_OE_HDR_MDL_PAGES];
  337. } HeaderPartialMdl;
  338. //#if DBG CODE.IMPROVEMENT we should get rid of what we don't really, really need
  339. ULONG SerialNumber;
  340. SMBPSE_HISTORY History;
  341. PIRP RxContextCapturedRequestPacket;
  342. PMDL SaveDataMdlForDebug;
  343. ULONG SaveLengthForDebug;
  344. PMDL SaveIrpMdlForDebug;
  345. //#endif
  346. ULONG BytesAvailableCopy;
  347. ULONG BytesIndicatedCopy;
  348. } SMB_PSE_ORDINARY_EXCHANGE, *PSMB_PSE_ORDINARY_EXCHANGE;
  349. // CODE.IMPROVEMENT actually, we have to get rid of a message...we need to know the length in the long term
  350. // in the short term this will be okay. i think that what i really have to do is to return error_discard
  351. // or something like that
  352. #define SmbPseDiscardProtocol(__STATUS__) { \
  353. *pBytesTaken = BytesAvailable; \
  354. pExchange->Status = (__STATUS__); \
  355. }
  356. NTSTATUS
  357. SmbPseOrdinaryExchange(
  358. SMBPSE_ORDINARY_EXCHANGE_ARGUMENT_SIGNATURE,
  359. IN SMB_PSE_ORDINARY_EXCHANGE_TYPE OEType
  360. );
  361. NTSTATUS
  362. SmbPseResumeOrdinaryExchange(
  363. IN OUT PRX_CONTEXT RxContext
  364. );
  365. #define ASSERT_ORDINARY_EXCHANGE(__p) ASSERT(NodeType(__p)==SMB_EXCHANGE_NTC(ORDINARY_EXCHANGE))
  366. NTSTATUS
  367. __SmbPseCreateOrdinaryExchange (
  368. IN PRX_CONTEXT RxContext,
  369. IN PMRX_V_NET_ROOT VNetRoot,
  370. IN SMB_PSE_ORDINARY_EXCHANGE_ENTRYPOINTS EntryPoint,
  371. IN PSMB_PSE_OE_START_ROUTINE StartRoutine,
  372. IN OUT SMBFCB_HOLDING_STATE *SmbFcbHoldingState OPTIONAL,
  373. OUT PSMB_PSE_ORDINARY_EXCHANGE *OrdinaryExchangePtr
  374. );
  375. #define SmbPseCreateOrdinaryExchange(__rxcontext,__vnetroot,__entrypoint,__start,__ordinaryexchangeptr) \
  376. __SmbPseCreateOrdinaryExchange(__rxcontext,__vnetroot,__entrypoint,__start,NULL,__ordinaryexchangeptr)
  377. BOOLEAN
  378. SmbPseFinalizeOrdinaryExchange (
  379. IN OUT PSMB_PSE_ORDINARY_EXCHANGE OrdinaryExchange
  380. );
  381. #define SmbPseInitiateOrdinaryExchange(OrdinaryExchange) (SmbCeInitiateExchange(&OrdinaryExchange->Exchange))
  382. // this macro is used to do the async completion for read/write/locks. Note that the call to lowiocompletion
  383. // will try to complete the irp thereby freeing the user's mdl. so, we better get rid of the partial first.
  384. // we use this macro so that there will be only one version of this code. when we combine start routines,
  385. // this will be un macroed
  386. #define SmbPseAsyncCompletionIfNecessary(OE,RXCONTEXT) { \
  387. if (StartEntryCount>1) { \
  388. BOOLEAN FinalizationComplete; \
  389. if (FALSE) {DbgBreakPoint(); } \
  390. if ( (OE)->DataPartialMdl ) { \
  391. if (FlagOn((OE)->Flags, SMBPSE_OE_FLAG_MUST_SUCCEED_ALLOCATED_SMBBUF)){\
  392. MmPrepareMdlForReuse((OE)->DataPartialMdl); \
  393. } else { \
  394. IoFreeMdl((OE)->DataPartialMdl); \
  395. (OE)->DataPartialMdl = NULL; \
  396. ClearFlag((OE)->Flags,SMBPSE_OE_FLAG_OE_ALLOCATED_DATA_PARTIAL); \
  397. } \
  398. } \
  399. (RXCONTEXT)->StoredStatus = Status; \
  400. \
  401. RxLowIoCompletion((RXCONTEXT)); \
  402. FinalizationComplete = SmbPseFinalizeOrdinaryExchange((OE)); \
  403. ASSERT(!FinalizationComplete); \
  404. Status = STATUS_PENDING; \
  405. }}
  406. /* ------------------------------------------
  407. ------------------------------------------
  408. Receive Handler Stuff
  409. ------------------------------------------
  410. ------------------------------------------
  411. */
  412. VOID
  413. SmbPseInitializeTables(
  414. void
  415. );
  416. typedef
  417. NTSTATUS
  418. (*PSMBPSE_RECEIVE_HANDLER) (
  419. PSMB_PSE_ORDINARY_EXCHANGE OrdinaryExchange,
  420. PBYTE Response
  421. );
  422. //boy, talk about a load of arguments
  423. typedef
  424. UCHAR
  425. (*PSMBPSE_NOCOPY_RECEIVE_HANDLER) (
  426. IN OUT PSMB_PSE_ORDINARY_EXCHANGE OrdinaryExchange,
  427. IN ULONG BytesIndicated,
  428. IN ULONG BytesAvailable,
  429. OUT ULONG *pBytesTaken,
  430. IN PSMB_HEADER pSmbHeader,
  431. OUT PMDL *pDataBufferPointer,
  432. OUT PULONG pDataSize,
  433. #if DBG
  434. IN UCHAR ThisIsAReenter,
  435. #endif
  436. IN PBYTE Response
  437. );
  438. #define SMBPSE_NOCOPYACTION_NORMALFINISH 0x00
  439. #define SMBPSE_NOCOPYACTION_MDLFINISH 0x01
  440. #define SMBPSE_NOCOPYACTION_DISCARD 0x02
  441. #define SMBPSE_NOCOPYACTION_COPY_FOR_RESUME 0x03
  442. #define SMBPSE_RMP_MODELED (0x00000001)
  443. #define SMBPSE_RMP_THIS_IS_ANDX (0x00000002)
  444. #define SMBPSE_RMP_WARNINGS_OK (0x00000004)
  445. #define SMBPSE_RMP_NOCOPY_HANDLER (0x00000008)
  446. typedef enum _SMBPSE_RECEIVE_HANDLER_TOKEN {
  447. SMBPSE_RECEIVE_HANDLER_TOKEN_READ_ANDX_HANDLER = 0,
  448. SMBPSE_RECEIVE_HANDLER_TOKEN_READ_HANDLER,
  449. SMBPSE_RECEIVE_HANDLER_TOKEN_WRITE_ANDX_HANDLER,
  450. SMBPSE_RECEIVE_HANDLER_TOKEN_WRITE_HANDLER,
  451. SMBPSE_RECEIVE_HANDLER_TOKEN_LOCKING_ANDX_HANDLER,
  452. SMBPSE_RECEIVE_HANDLER_TOKEN_OPEN_PRINTFILE_HANDLER,
  453. SMBPSE_RECEIVE_HANDLER_TOKEN_WRITE_PRINTFILE_HANDLER,
  454. SMBPSE_RECEIVE_HANDLER_TOKEN_CLOSE_HANDLER, //also close_print_file
  455. SMBPSE_RECEIVE_HANDLER_TOKEN_NTCREATE_ANDX_HANDLER,
  456. SMBPSE_RECEIVE_HANDLER_TOKEN_OPEN_ANDX_HANDLER,
  457. SMBPSE_RECEIVE_HANDLER_TOKEN_CREATE_HANDLER, //also create_new
  458. SMBPSE_RECEIVE_HANDLER_TOKEN_OPEN_HANDLER,
  459. SMBPSE_RECEIVE_HANDLER_TOKEN_TRANS2_ANDX_HANDLER,
  460. SMBPSE_RECEIVE_HANDLER_TOKEN_GFA_HANDLER,
  461. SMBPSE_RECEIVE_HANDLER_TOKEN_SEARCH_HANDLER,
  462. SMBPSE_RECEIVE_HANDLER_TOKEN_QUERYDISKINFO_HANDLER,
  463. SMBPSE_RECEIVE_HANDLER_TOKEN_IOCTL_HANDLER,
  464. SMBPSE_RECEIVE_HANDLER_TOKEN_MAXIMUM
  465. } SMBPSE_RECEIVE_HANDLER_TOKEN;
  466. PSMBPSE_RECEIVE_HANDLER SmbPseReceiveHandlers[SMBPSE_RECEIVE_HANDLER_TOKEN_MAXIMUM];
  467. typedef struct _SMBPSE_RECEIVE_MODEL_PARAMETERS {
  468. UCHAR Flags;
  469. UCHAR ReceiveHandlerToken;
  470. #if DBG
  471. USHORT Dummy;
  472. PSMBPSE_RECEIVE_HANDLER ReceiveHandler;
  473. PBYTE IndicationString;
  474. SMB_PSE_ORDINARY_EXCHANGE_TYPE LowType,HighType;
  475. #endif
  476. } SMBPSE_RECEIVE_MODEL_PARAMETERS, *PSMBPSE_RECEIVE_MODEL_PARAMETERS;
  477. SMBPSE_RECEIVE_MODEL_PARAMETERS SmbPseReceiveModelParameters[256]; //there are 256 possible smbs
  478. typedef struct _SMBPSE_VESTIGIAL_SMBBUF {
  479. NT_SMB_HEADER Header;
  480. union {
  481. REQ_WRITE Write;
  482. REQ_NT_WRITE_ANDX WriteAndX;
  483. REQ_FLUSH Flush;
  484. struct {
  485. REQ_LOCKING_ANDX LockingAndX;
  486. NTLOCKING_ANDX_RANGE Locks[20]; //CODE.IMPROVEMENT.ASHAMED see locks.c
  487. };
  488. REQ_FIND_CLOSE2 FindClose;
  489. REQ_CLOSE Close;
  490. };
  491. ULONG Pad;
  492. } SMBPSE_VESTIGIAL_SMBBUF;
  493. // Finishing routines - these are all cast into the correct procedure type
  494. // so that the response will already have the correct SMB format
  495. // on entry to the routine
  496. //CODE.IMPROVEMENT the names of these routines should be changed from FinishX to X_Handler
  497. //CODE.IMPROVEMENT also, any routine that doesn't retrieve data should be changed over to a nocopy handler
  498. NTSTATUS
  499. MRxSmbFinishNTCreateAndX (
  500. IN OUT PSMB_PSE_ORDINARY_EXCHANGE OrdinaryExchange,
  501. IN PRESP_NT_CREATE_ANDX Response
  502. );
  503. #define MRxSmbReceiveHandler_NTCreateAndX ((PSMBPSE_RECEIVE_HANDLER)MRxSmbFinishNTCreateAndX)
  504. NTSTATUS
  505. MRxSmbFinishOpenAndX (
  506. IN OUT PSMB_PSE_ORDINARY_EXCHANGE OrdinaryExchange,
  507. IN PRESP_OPEN_ANDX Response
  508. );
  509. #define MRxSmbReceiveHandler_OpenAndX ((PSMBPSE_RECEIVE_HANDLER)MRxSmbFinishOpenAndX)
  510. NTSTATUS
  511. MRxSmbFinishClose (
  512. IN OUT PSMB_PSE_ORDINARY_EXCHANGE OrdinaryExchange,
  513. IN PRESP_CLOSE Response
  514. );
  515. //use the close finsh routine for closeprintfile as well
  516. #define MRxSmbReceiveHandler_Close ((PSMBPSE_RECEIVE_HANDLER)MRxSmbFinishClose)
  517. NTSTATUS
  518. MRxSmbFinishGFA (
  519. IN OUT PSMB_PSE_ORDINARY_EXCHANGE OrdinaryExchange,
  520. IN PVOID Response
  521. );
  522. #define MRxSmbReceiveHandler_GetFileAttributes ((PSMBPSE_RECEIVE_HANDLER)MRxSmbFinishGFA)
  523. NTSTATUS
  524. MRxSmbFinishTransaction2 (
  525. IN OUT PSMB_PSE_ORDINARY_EXCHANGE OrdinaryExchange,
  526. IN PRESP_TRANSACTION Response
  527. );
  528. #define MRxSmbReceiveHandler_Transact2 ((PSMBPSE_RECEIVE_HANDLER)MRxSmbFinishTransaction2)
  529. NTSTATUS
  530. MRxSmbFinishCoreOpen (
  531. IN OUT PSMB_PSE_ORDINARY_EXCHANGE OrdinaryExchange,
  532. IN PRESP_OPEN Response
  533. );
  534. #define MRxSmbReceiveHandler_CoreOpen ((PSMBPSE_RECEIVE_HANDLER)MRxSmbFinishCoreOpen)
  535. NTSTATUS
  536. MRxSmbFinishCoreCreate (
  537. IN OUT PSMB_PSE_ORDINARY_EXCHANGE OrdinaryExchange,
  538. IN PRESP_CREATE Response
  539. );
  540. #define MRxSmbReceiveHandler_CoreCreate ((PSMBPSE_RECEIVE_HANDLER)MRxSmbFinishCoreCreate)
  541. NTSTATUS
  542. MRxSmbFinishCoreIoCtl(
  543. PSMB_PSE_ORDINARY_EXCHANGE OrdinaryExchange,
  544. PRESP_IOCTL Response
  545. );
  546. #define MRxSmbReceiveHandler_Ioctl ((PSMBPSE_RECEIVE_HANDLER)MRxSmbFinishCoreIoCtl)
  547. //NTSTATUS
  548. //MRxSmbFinishRead (
  549. // IN OUT PSMB_PSE_ORDINARY_EXCHANGE OrdinaryExchange,
  550. // IN PRESP_READ_ANDX Response
  551. // );
  552. //#define MRxSmbReceiveHandler_ReadAndX ((PSMBPSE_RECEIVE_HANDLER)MRxSmbFinishRead)
  553. //NTSTATUS
  554. //MRxSmbFinishCoreRead (
  555. // IN OUT PSMB_PSE_ORDINARY_EXCHANGE OrdinaryExchange,
  556. // IN PRESP_READ Response
  557. // );
  558. //#define MRxSmbReceiveHandler_CoreRead ((PSMBPSE_RECEIVE_HANDLER)MRxSmbFinishCoreRead)
  559. UCHAR
  560. MRxSmbReadHandler_NoCopy (
  561. IN OUT PSMB_PSE_ORDINARY_EXCHANGE OrdinaryExchange,
  562. IN ULONG BytesIndicated,
  563. IN ULONG BytesAvailable,
  564. OUT ULONG *pBytesTaken,
  565. IN PSMB_HEADER pSmbHeader,
  566. OUT PMDL *pDataBufferPointer,
  567. OUT PULONG pDataSize,
  568. #if DBG
  569. IN UCHAR ThisIsAReenter,
  570. #endif
  571. IN PRESP_READ_ANDX Response
  572. );
  573. #define MRxSmbReceiveHandler_Read_NoCopy ((PSMBPSE_RECEIVE_HANDLER)MRxSmbReadHandler_NoCopy)
  574. NTSTATUS
  575. MRxSmbFinishCreatePrintFile (
  576. IN OUT PSMB_PSE_ORDINARY_EXCHANGE OrdinaryExchange,
  577. IN PRESP_OPEN_PRINT_FILE Response
  578. );
  579. #define MRxSmbReceiveHandler_OpenPrintFile ((PSMBPSE_RECEIVE_HANDLER)MRxSmbFinishCreatePrintFile)
  580. NTSTATUS
  581. MRxSmbFinishWrite (
  582. IN OUT PSMB_PSE_ORDINARY_EXCHANGE OrdinaryExchange,
  583. IN PBYTE Response
  584. );
  585. #define MRxSmbReceiveHandler_WritePrintFile ((PSMBPSE_RECEIVE_HANDLER)MRxSmbFinishWrite)
  586. #define MRxSmbReceiveHandler_WriteAndX ((PSMBPSE_RECEIVE_HANDLER)MRxSmbFinishWrite)
  587. #define MRxSmbReceiveHandler_CoreWrite ((PSMBPSE_RECEIVE_HANDLER)MRxSmbFinishWrite)
  588. NTSTATUS
  589. MRxSmbFinishLocks (
  590. IN OUT PSMB_PSE_ORDINARY_EXCHANGE OrdinaryExchange,
  591. IN PRESP_LOCKING_ANDX Response
  592. );
  593. #define MRxSmbReceiveHandler_LockingAndX ((PSMBPSE_RECEIVE_HANDLER)MRxSmbFinishLocks)
  594. #if 0
  595. NTSTATUS
  596. MRxSmbFinishFlush (
  597. IN OUT PSMB_PSE_ORDINARY_EXCHANGE OrdinaryExchange,
  598. IN PRESP_FLUSH Response
  599. );
  600. #endif //if 0
  601. NTSTATUS
  602. MRxSmbFinishSearch (
  603. PSMB_PSE_ORDINARY_EXCHANGE OrdinaryExchange,
  604. PRESP_SEARCH Response
  605. );
  606. #define MRxSmbReceiveHandler_Search ((PSMBPSE_RECEIVE_HANDLER)MRxSmbFinishSearch)
  607. NTSTATUS
  608. MRxSmbFinishQueryDiskInfo (
  609. PSMB_PSE_ORDINARY_EXCHANGE OrdinaryExchange,
  610. PRESP_QUERY_INFORMATION_DISK Response
  611. );
  612. #define MRxSmbReceiveHandler_QueryDiskInfo ((PSMBPSE_RECEIVE_HANDLER)MRxSmbFinishQueryDiskInfo)
  613. //CODE.IMPROVEMENT.ASHAMED it would be so much better if
  614. // __MRxSmbSimpleSyncTransact2were divided into two routines.....one for
  615. // building and another for submitting. it would save some stack space.
  616. typedef
  617. NTSTATUS
  618. (*PSMB_PSE_OE_T2_FIXUP_ROUTINE) (
  619. PSMB_PSE_ORDINARY_EXCHANGE
  620. );
  621. NTSTATUS
  622. __MRxSmbSimpleSyncTransact2(
  623. SMBPSE_ORDINARY_EXCHANGE_ARGUMENT_SIGNATURE,
  624. IN SMB_PSE_ORDINARY_EXCHANGE_TYPE OEType,
  625. IN ULONG TransactSetupCode,
  626. IN PVOID Params,
  627. IN ULONG ParamsLength,
  628. IN PVOID Data,
  629. IN ULONG DataLength,
  630. IN PSMB_PSE_OE_T2_FIXUP_ROUTINE FixupRoutine
  631. );
  632. #define MRxSmbSimpleSyncTransact2(a,b,c,d,e,f,g) \
  633. __MRxSmbSimpleSyncTransact2(a,b,c,d,e,f,g,NULL);
  634. NTSTATUS
  635. MRxSmbDeferredCreate (
  636. IN OUT PRX_CONTEXT RxContext
  637. );
  638. NTSTATUS
  639. MRxSmbConstructDeferredOpenContext (
  640. IN OUT PRX_CONTEXT RxContext
  641. );
  642. //downlevel stuff....
  643. NTSTATUS
  644. MRxSmbPseudoOpenTailFromGFAResponse (
  645. PSMB_PSE_ORDINARY_EXCHANGE OrdinaryExchange
  646. );
  647. NTSTATUS
  648. MRxSmbPseudoOpenTailFromFakeGFAResponse (
  649. PSMB_PSE_ORDINARY_EXCHANGE OrdinaryExchange,
  650. RX_FILE_TYPE StorageType //CODE.IMPROVEMENT this should be a RDBSS_STORAGE_TYPE
  651. );
  652. NTSTATUS
  653. MRxSmbCoreTruncate(
  654. SMBPSE_ORDINARY_EXCHANGE_ARGUMENT_SIGNATURE,
  655. ULONG Fid,
  656. ULONG FileTruncationPoint
  657. );
  658. NTSTATUS
  659. MRxSmbCoreInformation(
  660. IN OUT PRX_CONTEXT RxContext,
  661. IN ULONG InformationClass,
  662. IN OUT PVOID pBuffer,
  663. IN OUT PULONG pBufferLength,
  664. IN SMB_PSE_ORDINARY_EXCHANGE_ENTRYPOINTS EntryPoint
  665. );
  666. ULONG
  667. MRxSmbMapSmbAttributes (
  668. IN USHORT SmbAttribs
  669. );
  670. USHORT
  671. MRxSmbMapDisposition (
  672. IN ULONG Disposition
  673. );
  674. USHORT
  675. MRxSmbMapShareAccess (
  676. IN USHORT ShareAccess
  677. );
  678. USHORT
  679. MRxSmbMapDesiredAccess (
  680. IN ULONG DesiredAccess
  681. );
  682. USHORT
  683. MRxSmbMapFileAttributes (
  684. IN ULONG FileAttributes
  685. );
  686. ULONG
  687. MRxSmbUnmapDisposition (
  688. IN USHORT SmbDisposition,
  689. IN ULONG Disposition
  690. );
  691. LARGE_INTEGER
  692. MRxSmbConvertSmbTimeToTime (
  693. //IN PSMB_EXCHANGE Exchange OPTIONAL,
  694. IN PSMBCE_SERVER Server OPTIONAL,
  695. IN SMB_TIME Time,
  696. IN SMB_DATE Date
  697. );
  698. BOOLEAN
  699. MRxSmbConvertTimeToSmbTime (
  700. IN PLARGE_INTEGER InputTime,
  701. IN PSMB_EXCHANGE Exchange OPTIONAL,
  702. OUT PSMB_TIME Time,
  703. OUT PSMB_DATE Date
  704. );
  705. BOOLEAN
  706. MRxSmbTimeToSecondsSince1970 (
  707. IN PLARGE_INTEGER CurrentTime,
  708. IN PSMBCE_SERVER Server OPTIONAL,
  709. OUT PULONG SecondsSince1970
  710. );
  711. VOID
  712. MRxSmbSecondsSince1970ToTime (
  713. IN ULONG SecondsSince1970,
  714. IN PSMBCE_SERVER Server OPTIONAL,
  715. OUT PLARGE_INTEGER CurrentTime
  716. );
  717. VOID
  718. MRxSmbResumeAsyncReadWriteRequests(
  719. PRX_CONTEXT RxContext);
  720. #endif // _SMBPSE_H_