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.

836 lines
31 KiB

  1. /*++ BUILD Version: 0009 // Increment this if a change has global effects
  2. Copyright (c) 1987-1993 Microsoft Corporation
  3. Module Name:
  4. smbcxchng.h
  5. Abstract:
  6. This is the include file that defines all constants and types for
  7. SMB exchange implementation.
  8. Author:
  9. Balan Sethu Raman (SethuR) 06-Feb-95 Created
  10. Notes:
  11. An exchange is the core abstarction on which the SMB connection engine and
  12. the mini RDR are implemented. It encapsulates the notion of sending an SMB to
  13. the server and receiving the associated response, i.e, exchanging an SMB and
  14. hence the name.
  15. The exchange of an SMB with the server involves the following steps ....
  16. 1) Submitting the formatted SMB buffer for transmission.
  17. 2) Processing a send complete indication which ensures that at the
  18. transport level the SMB has been sent to the server.
  19. 3) Processing the receive indication which contains all/part of the
  20. response sent by the server.
  21. 4) Copying additional data not indicated by the transport
  22. There are a number of variations on this theme. For example there are certain
  23. SMB's for which no response is expected, e.g., write mailslots and there are
  24. certain SMB's which are inherently multi part in nature, TRANSACT smb's.
  25. In addition the steps outlined above will not always happen in that order. The
  26. precise sequence of events is dictated by the underlying transport chosen and
  27. the network conditions. It is this dependency that makes the implementation
  28. of exchanges challenging.
  29. The two primary goals that the current implementation was designed for are (1)
  30. performance and (2) encapsulation of transport dependencies. Goal(1) is
  31. important because this constitutes an integral part of the code path for
  32. exchanging any packet with the server. Goal (2) is important to ensure
  33. customization of the Rdr for different transports. This encapsulation provides
  34. a convenient vehicle for isolating SMB protocol level decisions from transport
  35. level decisons as much as possible.
  36. In addition the following goals were used to guide the implementation process ...
  37. 1) The exchange implementation must be able to handle asynchronous
  38. operations and synchronous operations well. The trade offs were made in
  39. favour of asynchronous operations as and when required.
  40. 2) Sufficient infrastructure support must be provided so as to ease the
  41. implementation of different flavours of exchanges.
  42. The SMB_EXCHANGE consists of a dispatch vector with the following functions
  43. 1) Start -- to initiate the exchange
  44. 2) Receive -- to handle response indications from the server
  45. 3) CopyDataHandler -- to handle portions of the response not indicated
  46. 4) SendCompletionHandler -- to handle send complete indications from the transport.
  47. 5) QuiescentStateHandler -- to handle transitions to a quiescent state, i.e., no
  48. SMB connection engine operations are outstanding.
  49. Most kinds of exchange use the QuiescentStateHandler to finalize the
  50. operation and discard the exchange. However, certain kinds of exchanges
  51. which implement the notion of a macro exchange, i.e., exchange multiple
  52. SMB's use this to delineate different phases of the multiple exchange,
  53. e.g., ORDINARY_EXCHANGE which implements most file io operations.
  54. In addition to the dispatch vector the vanilla exchange consists of state
  55. information to record the current state of the exchange, sufficient context
  56. for resumption and context for handling SMB protocol related operations. The
  57. SMB protocol requires that each SMB sent to the server be stamped with a MID
  58. ( multiplex id. ) in order to distinguish between concurrent SMB exchanges.
  59. The connection engine provides this service.
  60. The exchange also encapsulates a SMBCE_EXCHANGE_CONTEXT instance which
  61. encapsulates all the information required for building a SMB_HEADER.
  62. --*/
  63. #ifndef _SMBXCHNG_H_
  64. #define _SMBXCHNG_H_
  65. typedef enum _SMBCE_STATE_ {
  66. SMBCE_START_IN_PROGRESS,
  67. SMBCE_STARTED,
  68. SMBCE_STOP_IN_PROGRESS,
  69. SMBCE_STOPPED
  70. } SMBCE_STATE, *PSMBCE_STATE;
  71. typedef struct _SMBCE_STARTSTOP_CONTEXT_ {
  72. SMBCE_STATE State;
  73. LONG ActiveExchanges;
  74. KEVENT StopEvent;
  75. PKEVENT pServerEntryTearDownEvent;
  76. LIST_ENTRY SessionSetupRequests;
  77. } SMBCE_STARTSTOP_CONTEXT, *PSMBCE_STARTSTOP_CONTEXT;
  78. extern SMBCE_STARTSTOP_CONTEXT SmbCeStartStopContext;
  79. //
  80. // SMB_PROTOCOL_EXCHANGE dispatch vector function prototypes ..
  81. //
  82. // the initiator or the start routine
  83. typedef
  84. NTSTATUS
  85. (*PSMB_EXCHANGE_START)(
  86. IN struct _SMB_EXCHANGE *pExchange);
  87. // The SMB receive handler
  88. typedef
  89. NTSTATUS
  90. (*PSMB_EXCHANGE_IND_RECEIVE)(
  91. IN struct _SMB_EXCHANGE *pExchange, // The exchange instance
  92. IN ULONG BytesIndicated,
  93. IN ULONG BytesAvailable,
  94. OUT ULONG *BytesTaken,
  95. IN PSMB_HEADER pSmbHeader,
  96. OUT PMDL *pDataBufferPointer, // buffer to copy unindicated data
  97. OUT PULONG pDataSize, // buffer size
  98. IN ULONG ReceiveFlags
  99. );
  100. // the SMB xmit callback
  101. typedef
  102. NTSTATUS
  103. (*PSMB_EXCHANGE_IND_SEND_CALLBACK)(
  104. IN struct _SMB_EXCHANGE *pExchange, // The exchange instance
  105. IN PMDL pDataBuffer,
  106. IN NTSTATUS SendCompletionStatus
  107. );
  108. // the copy data callback for fetching large data
  109. typedef
  110. NTSTATUS
  111. (*PSMB_EXCHANGE_IND_COPY_DATA_CALLBACK)(
  112. IN struct _SMB_EXCHANGE *pExchange, // the exchange instance
  113. IN PMDL pCopyDataBuffer, // the buffer
  114. IN ULONG CopyDataSize // amount of data copied
  115. );
  116. // the finalization routine
  117. // This particular routine has a signature that is NT specific the IRQL
  118. // parameter that is passed in and the notion of posting. This helps consolidate
  119. // the NT transport driver model of indications at DPC level in SmbCeFinalizeExchange.
  120. // On WIN95 the lease restrictive value of IRQL can be passed in.
  121. typedef
  122. NTSTATUS
  123. (*PSMB_EXCHANGE_FINALIZE)(
  124. IN OUT struct _SMB_EXCHANGE *pExchange,
  125. OUT BOOLEAN *pPostRequest);
  126. typedef
  127. NTSTATUS
  128. (*PSMB_EXCHANGE_IND_ASSOCIATED_EXCHANGES_COMPLETION)(
  129. IN OUT struct _SMB_EXCHANGE *pExchange,
  130. OUT BOOLEAN *pPostRequest);
  131. // The Exchange dispatch vector definition
  132. typedef struct _SMB_EXCHANGE_DISPATCH_VECTOR_ {
  133. PSMB_EXCHANGE_START Start;
  134. PSMB_EXCHANGE_IND_RECEIVE Receive;
  135. PSMB_EXCHANGE_IND_COPY_DATA_CALLBACK CopyDataHandler;
  136. PSMB_EXCHANGE_IND_SEND_CALLBACK SendCompletionHandler;
  137. PSMB_EXCHANGE_FINALIZE Finalize;
  138. PSMB_EXCHANGE_IND_ASSOCIATED_EXCHANGES_COMPLETION AssociatedExchangesCompletionHandler;
  139. } SMB_EXCHANGE_DISPATCH_VECTOR, *PSMB_EXCHANGE_DISPATCH_VECTOR;
  140. // An enumerated type listing the type of exchanges
  141. typedef enum _SMB_EXCHANGE_TYPE_ {
  142. CONSTRUCT_NETROOT_EXCHANGE,
  143. ORDINARY_EXCHANGE,
  144. TRANSACT_EXCHANGE,
  145. EXTENDED_SESSION_SETUP_EXCHANGE,
  146. ADMIN_EXCHANGE,
  147. SENTINEL_EXCHANGE
  148. } SMB_EXCHANGE_TYPE, *PSMB_EXCHANGE_TYPE;
  149. // known exchange type dispatch vectors
  150. extern SMB_EXCHANGE_DISPATCH_VECTOR ConstructNetRootExchangeDispatch;
  151. extern SMB_EXCHANGE_DISPATCH_VECTOR OrdinaryExchangeDispatch;
  152. extern SMB_EXCHANGE_DISPATCH_VECTOR TransactExchangeDispatch;
  153. // The various states of the exchange. Each exchange transitions from
  154. // the SMBCE_EXCHANGE_INITIALIZATION_START to SMBCE_EXCHANGE_INITIATED or
  155. // SMBCE_EXCHANGE_ABORTED state.
  156. typedef enum _SMBCE_EXCHANGE_STATE_ {
  157. SMBCE_EXCHANGE_INITIALIZATION_START,
  158. SMBCE_EXCHANGE_SERVER_INITIALIZED,
  159. SMBCE_EXCHANGE_SESSION_INITIALIZED,
  160. SMBCE_EXCHANGE_NETROOT_INITIALIZED,
  161. // SMBCE_EXCHANGE_SECURITYBUFFER_INITIALIZED,
  162. SMBCE_EXCHANGE_INITIATED,
  163. SMBCE_EXCHANGE_ABORTED
  164. } SMBCE_EXCHANGE_STATE, *PSMBCE_EXCHANGE_STATE;
  165. // The exchange encapsulates the transport information from the clients. The
  166. // Exchange engine is sandwiched between the protocol selection engine in the
  167. // mini redirector on one side and the various transports on the other side.
  168. // The transport information encapsulates the various categories of transport
  169. // the exchange engine understands.
  170. typedef struct SMBCE_EXCHANGE_TRANSPORT_INFORMATION {
  171. union {
  172. struct {
  173. struct _SMBCE_VC *pVc;
  174. } Vcs;
  175. struct {
  176. ULONG Dummy;
  177. } Datagrams;
  178. struct {
  179. ULONG Dummy;
  180. } Hybrid;
  181. };
  182. } SMBCE_EXCHANGE_TRANSPORT_CONTEXT,
  183. *PSMBCE_EXCHANGE_TRANSPORT_CONTEXT;
  184. typedef struct _SMBCE_EXCHANGE_CONTEXT_ {
  185. PMRX_V_NET_ROOT pVNetRoot;
  186. PSMBCEDB_SERVER_ENTRY pServerEntry;
  187. PSMBCE_V_NET_ROOT_CONTEXT pVNetRootContext;
  188. SMBCE_EXCHANGE_TRANSPORT_CONTEXT TransportContext;
  189. } SMBCE_EXCHANGE_CONTEXT,*PSMBCE_EXCHANGE_CONTEXT;
  190. //
  191. // Similar to the subclassing of SMB net roots the SMB_EXCHANGE will be subclassed
  192. // further to deal with various types of SMB exchanges. SMB exchanges can be roughly
  193. // classified into the following types based on the interactions involved ...
  194. //
  195. // The SMB's that need to be exchanged need to be augmented with some admin SMB's which
  196. // are required for the maintenance of SMB's in the connection engine.
  197. #define SMBCE_EXCHANGE_MID_VALID (0x00000001)
  198. #define SMBCE_EXCHANGE_RETAIN_MID (0x00000002)
  199. #define SMBCE_EXCHANGE_MULTIPLE_SENDS_POSSIBLE (0x00000004)
  200. #define SMBCE_EXCHANGE_FINALIZED (0x00000008)
  201. #define SMBCE_EXCHANGE_ATTEMPT_RECONNECTS (0x00000010)
  202. #define SMBCE_EXCHANGE_INDEFINITE_DELAY_IN_RESPONSE (0x00000020)
  203. #define SMBCE_EXCHANGE_MAILSLOT_OPERATION (0x00000040)
  204. #define SMBCE_EXCHANGE_SESSION_CONSTRUCTOR (0x00000100)
  205. #define SMBCE_EXCHANGE_NETROOT_CONSTRUCTOR (0x00000200)
  206. #define SMBCE_EXCHANGE_NOT_FROM_POOL (0x00000800)
  207. #define SMBCE_EXCHANGE_TIMED_RECEIVE_OPERATION (0x00001000)
  208. #define SMBCE_EXCHANGE_TIMEDOUT (0x00002000)
  209. #define SMBCE_EXCHANGE_FULL_PROCESSID_SPECIFIED (0x00004000)
  210. #define SMBCE_EXCHANGE_SMBCE_STOPPED (0x00008000)
  211. #define SMBCE_EXCHANGE_EXTENDED_SIGNATURES (0x00010000)
  212. // #define SMBCE_EXCHANGE_SIGNATURE_BUFFER_ALLOCATED (0x01000000)
  213. #define SMBCE_EXCHANGE_DEBUG_SYSCACHE (0x02000000)
  214. #define SMBCE_ASSOCIATED_EXCHANGE (0x80000000)
  215. #define SMBCE_ASSOCIATED_EXCHANGES_COMPLETION_HANDLER_ACTIVATED (0x40000000)
  216. #define SMBCE_EXCHANGE_FLAGS_TO_PRESERVE (SMBCE_EXCHANGE_NOT_FROM_POOL)
  217. #define SMBCE_OPLOCK_RESPONSE_MID (0xffff)
  218. #define SMBCE_MAILSLOT_OPERATION_MID (0xffff)
  219. #define SMBCE_ECHO_PROBE_MID (0xfffe)
  220. //
  221. // The cancellation status is defined as a PVOID instead of a BOOLEAN to allow
  222. // us the use of Interlocked manipulation instructions
  223. // There are only two states SMBCE_EXCHANGE_CANCELLED, SMBCE_EXCHANGE_ACTIVE
  224. //
  225. #define SMBCE_EXCHANGE_CANCELLED (0xcccccccc)
  226. #define SMBCE_EXCHANGE_NOT_CANCELLED (0xaaaaaaaa)
  227. // The Exchange definition
  228. typedef struct _SMB_EXCHANGE {
  229. union {
  230. UCHAR Type;
  231. struct {
  232. NODE_TYPE_CODE NodeTypeCode; // node type.
  233. NODE_BYTE_SIZE NodeByteSize; // node size.
  234. LONG ReferenceCount;
  235. };
  236. };
  237. LIST_ENTRY SmbMmInUseListEntry;
  238. PRX_CONTEXT RxContext; //use of these two fields is advisory
  239. PVOID LastExecutingThread; //OE and Xact will use them
  240. union {
  241. NTSTATUS SmbStatus;
  242. PMRX_SMB_SRV_OPEN SmbSrvOpen;
  243. };
  244. NTSTATUS Status;
  245. ULONG ServerVersion;
  246. SMB_EXCHANGE_ID Id;
  247. USHORT SmbCeState;
  248. USHORT MidCookie;
  249. SMB_MPX_ID Mid;
  250. LONG CancellationStatus;
  251. ULONG SmbCeFlags;
  252. SMBCE_EXCHANGE_CONTEXT SmbCeContext;
  253. LONG SendCompletePendingOperations;
  254. LONG CopyDataPendingOperations;
  255. LONG ReceivePendingOperations;
  256. LONG LocalPendingOperations;
  257. PKEVENT pSmbCeSynchronizationEvent;
  258. LIST_ENTRY ExchangeList;
  259. LARGE_INTEGER ExpiryTime;
  260. PSMB_EXCHANGE_DISPATCH_VECTOR pDispatchVector;
  261. union {
  262. struct {
  263. struct _SMB_EXCHANGE *pMasterExchange;
  264. SINGLE_LIST_ENTRY NextAssociatedExchange;
  265. } Associated;
  266. struct {
  267. SINGLE_LIST_ENTRY AssociatedExchangesToBeFinalized;
  268. LONG PendingAssociatedExchanges;
  269. } Master;
  270. };
  271. RX_WORK_QUEUE_ITEM WorkQueueItem;
  272. ULONG SmbSecuritySignatureIndex;
  273. ULONG ExchangeTransportInitialized;
  274. NTSTATUS SessionSetupStatus;
  275. BOOLEAN IsOffLineFile;
  276. BOOLEAN IsSecuritySignatureEnabled;
  277. BOOLEAN SecuritySignatureReturned;
  278. BOOLEAN MD5ContextInitialized;
  279. LIST_ENTRY CancelledList;
  280. MD5_CTX MD5Context;
  281. UCHAR SmbCommand;
  282. CHAR ResponseSignature[SMB_SECURITY_SIGNATURE_LENGTH];
  283. PBYTE pBufSecSigData;
  284. PMDL pBufSecSigMdl;
  285. } SMB_EXCHANGE, *PSMB_EXCHANGE;
  286. INLINE PSMBCEDB_SERVER_ENTRY
  287. SmbCeGetExchangeServerEntry(PVOID pExchange)
  288. {
  289. PSMB_EXCHANGE pSmbExchange = (PSMB_EXCHANGE)pExchange;
  290. ASSERT(pSmbExchange->SmbCeContext.pServerEntry != NULL);
  291. return pSmbExchange->SmbCeContext.pServerEntry;
  292. }
  293. INLINE PSMBCE_SERVER
  294. SmbCeGetExchangeServer(PVOID pExchange)
  295. {
  296. PSMB_EXCHANGE pSmbExchange = (PSMB_EXCHANGE)pExchange;
  297. return &(pSmbExchange->SmbCeContext.pServerEntry->Server);
  298. }
  299. INLINE PSMBCEDB_SESSION_ENTRY
  300. SmbCeGetExchangeSessionEntry(PVOID pExchange)
  301. {
  302. PSMB_EXCHANGE pSmbExchange = (PSMB_EXCHANGE)pExchange;
  303. if (pSmbExchange->SmbCeContext.pVNetRootContext != NULL) {
  304. return pSmbExchange->SmbCeContext.pVNetRootContext->pSessionEntry;
  305. } else {
  306. return NULL;
  307. }
  308. }
  309. INLINE PSMBCE_SESSION
  310. SmbCeGetExchangeSession(PVOID pExchange)
  311. {
  312. PSMB_EXCHANGE pSmbExchange = (PSMB_EXCHANGE)pExchange;
  313. if (pSmbExchange->SmbCeContext.pVNetRootContext != NULL) {
  314. return &(pSmbExchange->SmbCeContext.pVNetRootContext->pSessionEntry->Session);
  315. } else {
  316. return NULL;
  317. }
  318. }
  319. INLINE PSMBCEDB_NET_ROOT_ENTRY
  320. SmbCeGetExchangeNetRootEntry(PVOID pExchange)
  321. {
  322. PSMB_EXCHANGE pSmbExchange = (PSMB_EXCHANGE)pExchange;
  323. if (pSmbExchange->SmbCeContext.pVNetRootContext != NULL) {
  324. return pSmbExchange->SmbCeContext.pVNetRootContext->pNetRootEntry;
  325. } else {
  326. return NULL;
  327. }
  328. }
  329. INLINE PSMBCE_NET_ROOT
  330. SmbCeGetExchangeNetRoot(PVOID pExchange)
  331. {
  332. PSMB_EXCHANGE pSmbExchange = (PSMB_EXCHANGE)pExchange;
  333. if (pSmbExchange->SmbCeContext.pVNetRootContext != NULL) {
  334. return &(pSmbExchange->SmbCeContext.pVNetRootContext->pNetRootEntry->NetRoot);
  335. } else {
  336. return NULL;
  337. }
  338. }
  339. INLINE PMRX_V_NET_ROOT
  340. SmbCeGetExchangeVNetRoot(PVOID pExchange)
  341. {
  342. PSMB_EXCHANGE pSmbExchange = (PSMB_EXCHANGE)pExchange;
  343. return pSmbExchange->SmbCeContext.pVNetRoot;
  344. }
  345. INLINE PSMBCE_V_NET_ROOT_CONTEXT
  346. SmbCeGetExchangeVNetRootContext(PVOID pExchange)
  347. {
  348. PSMB_EXCHANGE pSmbExchange = (PSMB_EXCHANGE)pExchange;
  349. return pSmbExchange->SmbCeContext.pVNetRootContext;
  350. }
  351. extern ULONG SmbCeTraceExchangeReferenceCount;
  352. // The following functions ( inline, macros and otherwise ) are defined
  353. // to manipulate the exchanges
  354. // The reset exchange macro provides a mechanism for forcing the exchange
  355. // instance to a well known start state. This is used by the protocol
  356. // selection engine to transceive different SMB's. A note of caution --
  357. // ensure that the conditions are O.K for initialization. There is no well
  358. // known mechanism in the exchange engine to prevent overwriting an
  359. // exchange instance while in use.
  360. #define SmbCeResetExchange(pExchange) \
  361. (pExchange)->SmbCeFlags &= ~SMBCE_EXCHANGE_FINALIZED; \
  362. (pExchange)->ReceivePendingOperations = 0; \
  363. (pExchange)->CopyDataPendingOperations = 0; \
  364. (pExchange)->SendCompletePendingOperations = 0; \
  365. (pExchange)->LocalPendingOperations = 0; \
  366. (pExchange)->Status = STATUS_SUCCESS; \
  367. (pExchange)->SmbStatus = STATUS_SUCCESS
  368. // The following macros provide a mechanism for referencing and dereferencing
  369. // the exchange. The reference count provides a mechanism for detecting
  370. // when an exchange instance can be safely discarded. The reference count
  371. // differs from the pending operations count maintained in the exchange
  372. // which are used to detect when a quiescent state is reached.
  373. #define SmbCeReferenceExchange(pExchange) \
  374. InterlockedIncrement(&(pExchange)->ReferenceCount); \
  375. if (SmbCeTraceExchangeReferenceCount) { \
  376. DbgPrint("Reference Exchange %lx Type(%ld) %s %ld %ld\n", \
  377. (pExchange), \
  378. (pExchange)->Type, \
  379. __FILE__, \
  380. __LINE__, \
  381. (pExchange)->ReferenceCount); \
  382. }
  383. #define SmbCeDereferenceExchange(pExchange) \
  384. InterlockedDecrement(&(pExchange)->ReferenceCount); \
  385. if (SmbCeTraceExchangeReferenceCount) { \
  386. DbgPrint("Dereference Exchange %lx Type(%ld) %s %ld %ld\n", \
  387. (pExchange), \
  388. (pExchange)->Type, \
  389. __FILE__, \
  390. __LINE__, \
  391. (pExchange)->ReferenceCount); \
  392. }
  393. #define SmbCeDereferenceAndDiscardExchange(pExchange) \
  394. if (InterlockedDecrement(&(pExchange)->ReferenceCount) == 0) { \
  395. SmbCeDiscardExchange(pExchange); \
  396. } \
  397. if (SmbCeTraceExchangeReferenceCount) { \
  398. DbgPrint("Dereference Exchange %lx Type(%ld) %s %ld %ld\n", \
  399. (pExchange), \
  400. (pExchange)->Type, \
  401. __FILE__, \
  402. __LINE__, \
  403. (pExchange)->ReferenceCount); \
  404. }
  405. // Macros to hide the syntactic details of dereferencing and calling a
  406. // routine in a dispatch vector. These macros are purely intended for
  407. // use in the connection engine only and is not meant for use by
  408. // other modules.
  409. #define SMB_EXCHANGE_DISPATCH(pExchange,Routine,Arguments) \
  410. (*((pExchange)->pDispatchVector->Routine))##Arguments
  411. #define SMB_EXCHANGE_POST(pExchange,Routine) \
  412. RxPostToWorkerThread(&(pExchange)->WorkItem.WorkQueueItem, \
  413. (pExchange)->pDispatchVector->Routine, \
  414. (pExchange))
  415. // The following enum type defines the result of invoking the finalization routine
  416. // on an exchange instance.
  417. typedef enum _SMBCE_EXCHANGE_STATUS_ {
  418. SmbCeExchangeAlreadyFinalized,
  419. SmbCeExchangeFinalized,
  420. SmbCeExchangeNotFinalized
  421. } SMBCE_EXCHANGE_STATUS, *PSMBCE_EXCHANGE_STATUS;
  422. // The pending operations associated with an exchange are classified into four kinds
  423. // Receive operations, Copy Data Operations, Send Complete and Local operations.
  424. // These need to be incremented under the protection of a spinlock. However they
  425. // are decremented in the absence of a spinlock ( with the respective assert ).
  426. #define SMBCE_LOCAL_OPERATION 0x1
  427. #define SMBCE_SEND_COMPLETE_OPERATION 0x2
  428. #define SMBCE_COPY_DATA_OPERATION 0x4
  429. #define SMBCE_RECEIVE_OPERATION 0x8
  430. extern NTSTATUS
  431. SmbCeIncrementPendingOperations(
  432. PSMB_EXCHANGE pExchange,
  433. ULONG PendingOperationsMask,
  434. PVOID FileName,
  435. ULONG FileLine);
  436. extern NTSTATUS
  437. SmbCeDecrementPendingOperations(
  438. PSMB_EXCHANGE pExchange,
  439. ULONG PendingOperationsMask,
  440. PVOID FileName,
  441. ULONG FileLine);
  442. extern SMBCE_EXCHANGE_STATUS
  443. SmbCeDecrementPendingOperationsAndFinalize(
  444. PSMB_EXCHANGE pExchange,
  445. ULONG PendingOperationsMask,
  446. PVOID FileName,
  447. ULONG FileLine);
  448. // the pending operations increment routines
  449. #define SmbCeIncrementPendingReceiveOperations(pExchange) \
  450. SmbCeIncrementPendingOperations(pExchange,(SMBCE_RECEIVE_OPERATION),__FILE__,__LINE__)
  451. #define SmbCeIncrementPendingSendCompleteOperations(pExchange) \
  452. SmbCeIncrementPendingOperations(pExchange,(SMBCE_SEND_COMPLETE_OPERATION),__FILE__,__LINE__)
  453. #define SmbCeIncrementPendingCopyDataOperations(pExchange) \
  454. SmbCeIncrementPendingOperations(pExchange,(SMBCE_COPY_DATA_OPERATION),__FILE__,__LINE__)
  455. #define SmbCeIncrementPendingLocalOperations(pExchange) \
  456. SmbCeIncrementPendingOperations(pExchange,(SMBCE_LOCAL_OPERATION),__FILE__,__LINE__)
  457. // The pending operations decrement routines
  458. // Note the special casing of ReceivePendingOperations since it is the only one
  459. // that can be forced by a disconnect indication. There are two variations in
  460. // the decrement macros. The first flavour is to be used when it can be
  461. // guaranteed that the decrement operation will not lead to the finalization
  462. // of the exchange and the second is to be used when we cannot ensure the criterion
  463. // for the first. The difference between the two is that it eliminates
  464. // acquisition/release of a spinlock.
  465. #define SmbCeDecrementPendingReceiveOperations(pExchange) \
  466. SmbCeDecrementPendingOperations(pExchange,(SMBCE_RECEIVE_OPERATION),__FILE__,__LINE__)
  467. #define SmbCeDecrementPendingSendCompleteOperations(pExchange) \
  468. SmbCeDecrementPendingOperations(pExchange,(SMBCE_SEND_COMPLETE_OPERATION),__FILE__,__LINE__)
  469. #define SmbCeDecrementPendingCopyDataOperations(pExchange) \
  470. SmbCeDecrementPendingOperations(pExchange,(SMBCE_COPY_DATA_OPERATION),__FILE__,__LINE__)
  471. #define SmbCeDecrementPendingLocalOperations(pExchange) \
  472. SmbCeDecrementPendingOperations(pExchange,(SMBCE_LOCAL_OPERATION),__FILE__,__LINE__)
  473. // The pending operations decrement routines
  474. #define SmbCeDecrementPendingReceiveOperationsAndFinalize(pExchange) \
  475. SmbCeDecrementPendingOperationsAndFinalize(pExchange,(SMBCE_RECEIVE_OPERATION),__FILE__,__LINE__)
  476. #define SmbCeDecrementPendingSendCompleteOperationsAndFinalize(pExchange) \
  477. SmbCeDecrementPendingOperationsAndFinalize(pExchange,(SMBCE_SEND_COMPLETE_OPERATION),__FILE__,__LINE__)
  478. #define SmbCeDecrementPendingCopyDataOperationsAndFinalize(pExchange) \
  479. SmbCeDecrementPendingOperationsAndFinalize(pExchange,(SMBCE_COPY_DATA_OPERATION),__FILE__,__LINE__)
  480. #define SmbCeDecrementPendingLocalOperationsAndFinalize(pExchange) \
  481. SmbCeDecrementPendingOperationsAndFinalize(pExchange,(SMBCE_LOCAL_OPERATION),__FILE__,__LINE__)
  482. //
  483. // This is the pid that will be used by the rdr; rdr1 used 0xcafe.
  484. // only this pid is ever sent except for nt<-->nt creates. in these cases,
  485. // we have to send the full 32bit process id for RPC. actually, we only have to do
  486. // for pipes but we do it all the time instead.
  487. //
  488. #define MRXSMB_PROCESS_ID (0xfeff)
  489. INLINE VOID
  490. SmbCeSetFullProcessIdInHeader(
  491. PSMB_EXCHANGE pExchange,
  492. ULONG ProcessId,
  493. PNT_SMB_HEADER pNtSmbHeader)
  494. {
  495. pExchange->SmbCeFlags |= SMBCE_EXCHANGE_FULL_PROCESSID_SPECIFIED;
  496. SmbPutUshort(&pNtSmbHeader->Pid, (USHORT)((ProcessId) & 0xFFFF));
  497. SmbPutUshort(&pNtSmbHeader->PidHigh, (USHORT)((ProcessId) >> 16));
  498. }
  499. // The exchange engine API, for creation and manipulation of exchange instances
  500. // Initialization/Creation of an exchange instance
  501. extern NTSTATUS
  502. SmbCepInitializeExchange(
  503. PSMB_EXCHANGE *pExchangePointer,
  504. PRX_CONTEXT pRxContext,
  505. PSMBCEDB_SERVER_ENTRY pServerEntry,
  506. PMRX_V_NET_ROOT pVNetRoot,
  507. SMB_EXCHANGE_TYPE ExchangeType,
  508. PSMB_EXCHANGE_DISPATCH_VECTOR pDispatchVector);
  509. INLINE NTSTATUS
  510. SmbCeInitializeExchange(
  511. PSMB_EXCHANGE *pExchangePointer,
  512. PRX_CONTEXT pRxContext,
  513. PMRX_V_NET_ROOT pVNetRoot,
  514. SMB_EXCHANGE_TYPE ExchangeType,
  515. PSMB_EXCHANGE_DISPATCH_VECTOR pDispatchVector)
  516. {
  517. return SmbCepInitializeExchange(
  518. pExchangePointer,
  519. pRxContext,
  520. NULL,
  521. pVNetRoot,
  522. ExchangeType,
  523. pDispatchVector);
  524. }
  525. INLINE NTSTATUS
  526. SmbCeInitializeExchange2(
  527. PSMB_EXCHANGE *pExchangePointer,
  528. PRX_CONTEXT pRxContext,
  529. PSMBCEDB_SERVER_ENTRY pServerEntry,
  530. SMB_EXCHANGE_TYPE ExchangeType,
  531. PSMB_EXCHANGE_DISPATCH_VECTOR pDispatchVector)
  532. {
  533. return SmbCepInitializeExchange(
  534. pExchangePointer,
  535. pRxContext,
  536. pServerEntry,
  537. NULL,
  538. ExchangeType,
  539. pDispatchVector);
  540. }
  541. extern NTSTATUS
  542. SmbCeInitializeAssociatedExchange(
  543. PSMB_EXCHANGE *pAssociatedExchangePointer,
  544. PSMB_EXCHANGE pMasterExchange,
  545. SMB_EXCHANGE_TYPE Type,
  546. PSMB_EXCHANGE_DISPATCH_VECTOR pDispatchVector);
  547. // converting one type of exchange to another
  548. extern NTSTATUS
  549. SmbCeTransformExchange(
  550. PSMB_EXCHANGE pExchange,
  551. SMB_EXCHANGE_TYPE NewType,
  552. PSMB_EXCHANGE_DISPATCH_VECTOR pDispatchVector);
  553. // Initiating an exchange
  554. extern NTSTATUS
  555. SmbCeInitiateExchange(PSMB_EXCHANGE pExchange);
  556. extern NTSTATUS
  557. SmbCeInitiateAssociatedExchange(
  558. PSMB_EXCHANGE pAssociatedExchange,
  559. BOOLEAN EnableCompletionHandlerInMasterExchange);
  560. // Resuming an exchange
  561. extern NTSTATUS
  562. SmbCeResumeExchange(PSMB_EXCHANGE pExchange);
  563. // aborting an initiated exchange
  564. extern NTSTATUS
  565. SmbCeAbortExchange(PSMB_EXCHANGE pExchange);
  566. // discarding an exchnge instance
  567. extern VOID
  568. SmbCeDiscardExchange(PVOID pExchange);
  569. // In addition to providing a flexible mechanism for exchanging packets with
  570. // the server the exchange engine also provides a mechanism for building and
  571. // parsing SMB_HEADER's. This functionality is built into the connection
  572. // engine because the meta data in the headers is used to update the connection
  573. // engine database.
  574. // building SMB headers
  575. extern NTSTATUS
  576. SmbCeBuildSmbHeader(
  577. IN OUT PSMB_EXCHANGE pExchange,
  578. IN OUT PVOID pBuffer,
  579. IN ULONG BufferLength,
  580. OUT PULONG pRemainingBuffer,
  581. OUT PUCHAR pLastCommandInHeader,
  582. OUT PUCHAR *pNextCommand);
  583. // parsing SMB headers.
  584. extern NTSTATUS
  585. SmbCeParseSmbHeader(
  586. PSMB_EXCHANGE pExchange,
  587. PSMB_HEADER pSmbHeader,
  588. PGENERIC_ANDX pCommandToProcess,
  589. NTSTATUS *pSmbResponseStatus,
  590. ULONG BytesAvailable,
  591. ULONG BytesIndicated,
  592. PULONG pBytesConsumed);
  593. // The following routines are intended for use in the connection engine only.
  594. extern NTSTATUS
  595. MRxSmbInitializeSmbCe();
  596. extern NTSTATUS
  597. MRxSmbTearDownSmbCe();
  598. extern NTSTATUS
  599. SmbCePrepareExchangeForReuse(PSMB_EXCHANGE pExchange);
  600. extern PVOID
  601. SmbCeMapSendBufferToCompletionContext(
  602. PSMB_EXCHANGE pExchange,
  603. PVOID pBuffer);
  604. extern PVOID
  605. SmbCeMapSendCompletionContextToBuffer(
  606. PSMB_EXCHANGE pExchange,
  607. PVOID pContext);
  608. extern SMBCE_EXCHANGE_STATUS
  609. SmbCeFinalizeExchange(PSMB_EXCHANGE pExchange);
  610. extern VOID
  611. SmbCeFinalizeExchangeOnDisconnect(
  612. PSMB_EXCHANGE pExchange);
  613. extern NTSTATUS
  614. SmbCeReferenceServer(
  615. PSMB_EXCHANGE pExchange);
  616. extern NTSTATUS
  617. SmbCeIncrementActiveExchangeCount();
  618. extern VOID
  619. SmbCeDecrementActiveExchangeCount();
  620. extern VOID
  621. SmbCeSetExpiryTime(
  622. PSMB_EXCHANGE pExchange);
  623. extern BOOLEAN
  624. SmbCeDetectExpiredExchanges(
  625. PSMBCEDB_SERVER_ENTRY pServerEntry);
  626. extern VOID
  627. SmbCepFinalizeAssociatedExchange(
  628. PSMB_EXCHANGE pExchange);
  629. extern NTSTATUS
  630. SmbCeCancelExchange(
  631. PRX_CONTEXT pRxContext);
  632. typedef struct _SMB_CONSTRUCT_NETROOT_EXCHANGE_ {
  633. union {
  634. SMB_EXCHANGE;
  635. SMB_EXCHANGE Exchange;
  636. };
  637. SMB_TREE_ID TreeId;
  638. SMB_USER_ID UserId;
  639. BOOLEAN fUpdateDefaultSessionEntry;
  640. BOOLEAN fInitializeNetRoot;
  641. PMRX_NETROOT_CALLBACK NetRootCallback;
  642. PMDL pSmbRequestMdl;
  643. PMDL pSmbResponseMdl;
  644. PVOID pSmbActualBuffer; // Originally allocated buffer
  645. PVOID pSmbBuffer; // Start of header
  646. PMRX_CREATENETROOT_CONTEXT pCreateNetRootContext;
  647. CSC_SHARE_HANDLE hShare;
  648. } SMB_CONSTRUCT_NETROOT_EXCHANGE, *PSMB_CONSTRUCT_NETROOT_EXCHANGE;
  649. extern
  650. NTSTATUS
  651. GetSmbResponseNtStatus(
  652. IN PSMB_HEADER pSmbHeader,
  653. IN PSMB_EXCHANGE pExchange
  654. );
  655. extern CHAR InitialSecuritySignature[];
  656. #endif // _SMBXCHNG_H_