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.

525 lines
12 KiB

  1. /*++
  2. Copyright (c) 1989-2001 Microsoft Corporation
  3. Module Name:
  4. smbtdi.h
  5. Abstract:
  6. Wrappers for TDI
  7. Author:
  8. Jiandong Ruan
  9. Revision History:
  10. --*/
  11. #ifndef __SMBTDI_H__
  12. #define __SMBTDI_H__
  13. #ifndef TDI_MINIMUM_INDICATE
  14. #define TDI_MINIMUM_INDICATE 128
  15. #endif
  16. #define INVALID_INTERFACE_INDEX (0xffff)
  17. struct _SMB_ASYNC_CONTEXT;
  18. typedef struct _SMB_ASYNC_CONTEXT SMB_ASYNC_CONTEXT, *PSMB_ASYNC_CONTEXT;
  19. typedef void (*PSMB_TDI_COMPLETION) (
  20. IN PSMB_ASYNC_CONTEXT AsyncContext
  21. );
  22. struct _SMB_ASYNC_CONTEXT {
  23. LIST_ENTRY Linkage;
  24. PVOID AsyncInternalContext; // Internally used by the asychn routine.
  25. KTIMER Timer;
  26. KDPC Dpc;
  27. PSMB_TDI_COMPLETION Completion;
  28. PVOID ClientContext;
  29. DWORD Timeout;
  30. NTSTATUS status;
  31. };
  32. #define SMB_TDI_TIMEOUT_INFINITE (0xffffffffU)
  33. void __inline
  34. SmbInitAsyncContext(
  35. IN OUT PSMB_ASYNC_CONTEXT Context,
  36. IN PSMB_TDI_COMPLETION ClientCompletion,
  37. IN PVOID ClientContext,
  38. IN DWORD Timeout
  39. )
  40. {
  41. PAGED_CODE();
  42. InitializeListHead(&Context->Linkage);
  43. Context->AsyncInternalContext = NULL;
  44. Context->Completion = ClientCompletion;
  45. Context->ClientContext = ClientContext;
  46. Context->Timeout = Timeout;
  47. Context->status = STATUS_PENDING;
  48. }
  49. void __inline
  50. SmbAsyncStartTimer(
  51. IN OUT PSMB_ASYNC_CONTEXT Context,
  52. IN PKDEFERRED_ROUTINE TimeoutCompletion
  53. )
  54. {
  55. LARGE_INTEGER DueTime;
  56. PAGED_CODE();
  57. if (Context->Timeout != SMB_TDI_TIMEOUT_INFINITE) {
  58. KeInitializeTimer(&Context->Timer);
  59. KeInitializeDpc(&Context->Dpc, TimeoutCompletion, Context);
  60. DueTime.QuadPart = -Int32x32To64(Context->Timeout, 10000);
  61. KeSetTimer(&Context->Timer, DueTime, &Context->Dpc);
  62. }
  63. }
  64. void __inline
  65. SmbAsyncStopTimer(
  66. IN OUT PSMB_ASYNC_CONTEXT Context
  67. )
  68. {
  69. if (Context->Timeout != SMB_TDI_TIMEOUT_INFINITE) {
  70. KeCancelTimer(&Context->Timer);
  71. }
  72. }
  73. void __inline
  74. SmbAsyncCompleteRequest(
  75. IN OUT PSMB_ASYNC_CONTEXT Context
  76. )
  77. {
  78. SmbAsyncStopTimer(Context);
  79. Context->Completion((PSMB_ASYNC_CONTEXT)Context);
  80. }
  81. /*
  82. * TCP Address object
  83. */
  84. typedef struct {
  85. PDEVICE_OBJECT DeviceObject;
  86. HANDLE AddressHandle;
  87. PFILE_OBJECT AddressObject;
  88. } SMB_TCP_ADDRESS, *PSMB_TCP_ADDRESS;
  89. VOID __inline
  90. SmbInitTcpAddress(
  91. IN OUT PSMB_TCP_ADDRESS Context
  92. )
  93. {
  94. Context->DeviceObject = NULL;
  95. Context->AddressHandle = NULL;
  96. Context->AddressObject = NULL;
  97. }
  98. BOOL __inline
  99. ValidTcpAddress(
  100. IN OUT PSMB_TCP_ADDRESS Context
  101. )
  102. {
  103. return (Context->DeviceObject && Context->AddressHandle && Context->AddressObject);
  104. }
  105. typedef struct {
  106. HANDLE ConnectHandle;
  107. PFILE_OBJECT ConnectObject;
  108. PVOID UpperConnect;
  109. // for debugging purpose.
  110. // We save a copy here so that we
  111. // can find out the upper connection
  112. // even when UpperConnect is null-ed
  113. // out.
  114. PVOID pLastUprCnt;
  115. } SMB_TCP_CONNECT, *PSMB_TCP_CONNECT;
  116. VOID __inline
  117. SmbInitTcpConnect(
  118. IN OUT PSMB_TCP_CONNECT Context
  119. )
  120. {
  121. Context->ConnectHandle = NULL;
  122. Context->ConnectObject = NULL;
  123. Context->UpperConnect = NULL;
  124. }
  125. BOOL __inline
  126. ValidTcpConnect(
  127. IN OUT PSMB_TCP_CONNECT Context
  128. )
  129. {
  130. return (Context->ConnectHandle && Context->ConnectObject);
  131. }
  132. //
  133. // Placeholder for IP FastQuery routine to determine InterfaceContext + metric for dest addr
  134. //
  135. typedef NTSTATUS
  136. (*PIP4FASTQUERY)(
  137. IN IPAddr Address,
  138. OUT PULONG pIndex,
  139. OUT PULONG pMetric
  140. );
  141. typedef NTSTATUS
  142. (*PIP6FASTQUERY)(
  143. IN PSMB_IP6_ADDRESS Address,
  144. OUT PULONG pIndex,
  145. OUT PULONG pMetric
  146. );
  147. //
  148. // Placeholder for TCP Send routine if Fast Send is possible
  149. //
  150. typedef NTSTATUS
  151. (*PTCPSEND_DISPATCH) (
  152. IN PIRP Irp,
  153. IN PIO_STACK_LOCATION irpsp
  154. );
  155. //
  156. // SMB is bound to either TCP4 or TCP6, or both.
  157. // We have a record for each binding.
  158. //
  159. // We use this data structure to cache our connection object with TCP
  160. // Opening new TCP connection can only be done at PASSIVE level. However,
  161. // due to the following reasons, we need a TCP connection object at
  162. // DISPATCH level,
  163. // 1. For outbound request, we don't know whether we're going to use TCP4
  164. // or TCP6 until the name resoltuion is done. Our DNS name resolution
  165. // completion routine could be called at DISPATCH level.
  166. // 2. For inbound requests, we don't know whether we're going to use TCP4
  167. // or TCP6 until our TdiConnectHandler is called. Again, it is called
  168. // at DISPATCH level.
  169. // To allow SMB get an TCP connection whenever it needs it, we use the following
  170. // data structure to cache the connection object.
  171. //
  172. // The cache algorithm works as follow:
  173. // Parameters: L, M, L < M
  174. // 1. During initialization, we create M TCP connection object;
  175. // 2. Whenever the number of connection objects goes below L, we start a
  176. // worker thread to bring it up to M.
  177. //
  178. typedef struct _SMB_TCP_INFO {
  179. KSPIN_LOCK Lock;
  180. //
  181. // The TDI event context. We need this context to set TDI event handler
  182. //
  183. PVOID TdiEventContext;
  184. SMB_IP_ADDRESS IpAddress; // The local Ip address (in Network Order)
  185. USHORT Port; // The listening port (in network order)
  186. SMB_TCP_ADDRESS InboundAddressObject; // The TCP address object we're lisening on
  187. LIST_ENTRY InboundPool;
  188. LONG InboundNumber; // Number of entries in InboundPool
  189. LONG InboundLow, InboundMid, InboundHigh;
  190. LIST_ENTRY DelayedDestroyList;
  191. //
  192. // Control channel: used to send IOCTLs to TCP
  193. //
  194. USHORT TcpStackSize;
  195. PFILE_OBJECT TCPControlFileObject;
  196. PDEVICE_OBJECT TCPControlDeviceObject;
  197. PFILE_OBJECT IPControlFileObject;
  198. PDEVICE_OBJECT IPControlDeviceObject;
  199. //
  200. // FastSend and FastQuery routine
  201. //
  202. PTCPSEND_DISPATCH FastSend;
  203. PVOID FastQuery;
  204. //
  205. // We use the loopback interface index to determine if an IP is local or not
  206. // 1. Query the outgoing interface from TCP
  207. // 2. If the index of outgoing interface is loopback, then the IP is a local IP.
  208. //
  209. ULONG LoopbackInterfaceIndex;
  210. } SMB_TCP_INFO, *PSMB_TCP_INFO;
  211. //
  212. // Used to store the connection information with TCP
  213. //
  214. typedef struct {
  215. LIST_ENTRY Linkage;
  216. PSMB_TCP_INFO CacheOwner;
  217. //
  218. // The IRP which is used to do the disconnect
  219. // This field is put here only for saving debugging time
  220. // When we see disconnect problem, IRP can tell us
  221. // where we are. (We did see the request pending in TCP forever.)
  222. //
  223. PIRP DisconnectIrp;
  224. SMB_TCP_ADDRESS Address;
  225. SMB_TCP_CONNECT Connect;
  226. } SMB_TCP_CONTEXT, *PSMB_TCP_CONTEXT;
  227. NTSTATUS
  228. SmbInitTCP4(
  229. PSMB_TCP_INFO TcpInfo,
  230. USHORT Port,
  231. PVOID TdiEventContext
  232. );
  233. NTSTATUS
  234. SmbInitTCP6(
  235. PSMB_TCP_INFO TcpInfo,
  236. USHORT Port,
  237. PVOID TdiEventContext
  238. );
  239. NTSTATUS
  240. SmbShutdownTCP(
  241. PSMB_TCP_INFO TcpInfo
  242. );
  243. VOID
  244. SmbReadTCPConf(
  245. IN HANDLE hKey,
  246. PSMB_TCP_INFO TcpInfo
  247. );
  248. NTSTATUS
  249. SmbSynchConnCache(
  250. PSMB_TCP_INFO TcpInfo,
  251. BOOL Cleanup
  252. );
  253. PSMB_TCP_CONTEXT
  254. SmbAllocateOutbound(
  255. PSMB_TCP_INFO TcpInfo
  256. );
  257. VOID
  258. SmbFreeOutbound(
  259. PSMB_TCP_CONTEXT TcpCtx
  260. );
  261. PSMB_TCP_CONTEXT
  262. SmbAllocateInbound(
  263. PSMB_TCP_INFO TcpInfo
  264. );
  265. VOID
  266. SmbFreeInbound(
  267. PSMB_TCP_CONTEXT TcpCtx
  268. );
  269. VOID
  270. SmbFreeTcpContext(
  271. PSMB_TCP_CONTEXT TcpCtx
  272. );
  273. VOID
  274. SmbDelayedDestroyTcpContext(
  275. PSMB_TCP_CONTEXT TcpCtx
  276. );
  277. typedef struct _SMB_DEVICE SMB_DEVICE, *PSMB_DEVICE;
  278. NTSTATUS
  279. SmbWakeupWorkerThread(
  280. IN PSMB_DEVICE DeviceObject
  281. );
  282. VOID __inline
  283. SmbInitTcpContext(
  284. IN OUT PSMB_TCP_CONTEXT Context
  285. )
  286. {
  287. InitializeListHead(&Context->Linkage);
  288. Context->DisconnectIrp = NULL;
  289. SmbInitTcpAddress(&Context->Address);
  290. SmbInitTcpConnect(&Context->Connect);
  291. }
  292. NTSTATUS
  293. SmbOpenTcpAddress(
  294. IN PSMB_IP_ADDRESS addr,
  295. IN USHORT port,
  296. IN OUT PSMB_TCP_ADDRESS context
  297. );
  298. NTSTATUS
  299. SmbOpenUdpAddress(
  300. IN PSMB_IP_ADDRESS addr,
  301. IN USHORT port,
  302. IN OUT PSMB_TCP_ADDRESS context
  303. );
  304. NTSTATUS
  305. SmbCloseAddress(
  306. IN OUT PSMB_TCP_ADDRESS context
  307. );
  308. NTSTATUS
  309. SmbOpenTcpConnection(
  310. IN PSMB_TCP_ADDRESS Address,
  311. IN OUT PSMB_TCP_CONNECT Connect,
  312. IN PVOID ConnectionContext
  313. );
  314. NTSTATUS
  315. SmbCloseTcpConnection(
  316. IN OUT PSMB_TCP_CONNECT Connect
  317. );
  318. NTSTATUS
  319. TdiSetEventHandler(
  320. PFILE_OBJECT FileObject,
  321. ULONG EventType,
  322. PVOID EventHandler,
  323. PVOID Context
  324. );
  325. typedef struct {
  326. SMB_ASYNC_CONTEXT;
  327. ULONG Id; // TransactionId
  328. PTDI_ADDRESS_NETBIOS_UNICODE_EX pUnicodeAddress;
  329. UNICODE_STRING FQDN;
  330. LONG ipaddr_num;
  331. SMB_IP_ADDRESS ipaddr[SMB_MAX_IPADDRS_PER_HOST];
  332. } SMB_GETHOST_CONTEXT, *PSMB_GETHOST_CONTEXT;
  333. BOOL
  334. SmbLookupHost(
  335. WCHAR *host,
  336. PSMB_IP_ADDRESS ipaddr
  337. );
  338. void
  339. SmbAsyncGetHostByName(
  340. IN PUNICODE_STRING Name,
  341. IN PSMB_GETHOST_CONTEXT Context
  342. );
  343. typedef struct {
  344. SMB_ASYNC_CONTEXT;
  345. // Local end point
  346. SMB_TCP_CONNECT TcpConnect;
  347. //
  348. // GetHostByName returns multiple IP address.
  349. // We try to connect to each of them until
  350. // we succeed in making a connection
  351. //
  352. // the result of GetHostByName
  353. PSMB_GETHOST_CONTEXT pSmbGetHostContext;
  354. // the IP address currently being tried
  355. USHORT usCurrentIP;
  356. PIO_WORKITEM pIoWorkItem;
  357. } SMB_CONNECT_CONTEXT, *PSMB_CONNECT_CONTEXT;
  358. typedef struct _SMB_CONNECT SMB_CONNECT, *PSMB_CONNECT;
  359. typedef struct _SMB_DEVICE SMB_DEVICE, *PSMB_DEVICE;
  360. typedef NTSTATUS (*PRECEIVE_HANDLER) (
  361. IN PSMB_DEVICE DeviceObject,
  362. IN PSMB_CONNECT ConnectObject,
  363. IN ULONG ReceiveFlags,
  364. IN LONG BytesIndicated,
  365. IN LONG BytesAvailable,
  366. OUT LONG *BytesTaken,
  367. IN PVOID Tsdu,
  368. OUT PIRP *Irp
  369. );
  370. #ifndef __SMB_KDEXT__
  371. void
  372. SmbAsyncConnect(
  373. IN PSMB_IP_ADDRESS ipaddr,
  374. IN USHORT port,
  375. IN PSMB_CONNECT_CONTEXT Context
  376. );
  377. NTSTATUS
  378. SmbTcpDisconnect(
  379. PSMB_TCP_CONTEXT TcpContext,
  380. LONG TimeoutMilliseconds,
  381. ULONG Flags
  382. );
  383. NTSTATUS
  384. SmbAsynchTcpDisconnect(
  385. PSMB_TCP_CONTEXT TcpContext,
  386. ULONG Flags
  387. );
  388. NTSTATUS
  389. SmbSetTcpEventHandlers(
  390. PFILE_OBJECT AddressObject,
  391. PVOID Context
  392. );
  393. NTSTATUS
  394. SubmitSynchTdiRequest (
  395. IN PFILE_OBJECT FileObject,
  396. IN PIRP Irp
  397. );
  398. NTSTATUS
  399. SmbSendIoctl(
  400. PFILE_OBJECT FileObject,
  401. ULONG Ioctl,
  402. PVOID InBuf,
  403. ULONG InBufSize,
  404. PVOID OutBuf,
  405. ULONG *OutBufSize
  406. );
  407. NTSTATUS
  408. SmbSetTcpInfo(
  409. IN PFILE_OBJECT FileObject,
  410. IN ULONG Entity,
  411. IN ULONG Class,
  412. IN ULONG ToiId,
  413. IN ULONG ToiType,
  414. IN ULONG InfoBufferValue
  415. );
  416. #define ATTACH_FSP(Attached) \
  417. do { \
  418. if (PsGetCurrentProcess() != SmbCfg.FspProcess) { \
  419. Attached = TRUE; \
  420. KeAttachProcess((PRKPROCESS)SmbCfg.FspProcess); \
  421. } else { \
  422. Attached = FALSE; \
  423. } \
  424. } while(0)
  425. #define DETACH_FSP(Attached) \
  426. do { \
  427. if (Attached) { \
  428. KeDetachProcess(); \
  429. } \
  430. } while(0)
  431. #endif // __SMB_KDEXT__
  432. #endif // __SMBTDI_H__