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.

1044 lines
31 KiB

  1. /////////////////////////////////////////////////////////
  2. //
  3. // Copyright (c) 2001 Microsoft Corporation
  4. //
  5. // Module Name:
  6. // connect.cpp
  7. //
  8. // Abstract:
  9. // This module contains code which deals with making and breaking
  10. // connections
  11. //
  12. //////////////////////////////////////////////////////////
  13. #include "sysvars.h"
  14. //////////////////////////////////////////////////////////////
  15. // private constants, types, and prototypes
  16. //////////////////////////////////////////////////////////////
  17. const PCHAR strFunc1 = "TSConnect";
  18. const PCHAR strFunc2 = "TSDisconnect";
  19. // const PCHAR strFunc3 = "TSIsConnected";
  20. const PCHAR strFunc4 = "TSConnectHandler";
  21. const PCHAR strFunc5 = "TSDisconnectHandler";
  22. const PCHAR strFunc6 = "TSListen";
  23. // const PCHAR strFuncP1 = "TSGenAcceptComplete";
  24. const PCHAR strFuncP2 = "TSGenConnectComplete";
  25. //
  26. // this context structure stores information needed to complete
  27. // the request in the completion handler
  28. //
  29. struct CONNECT_CONTEXT
  30. {
  31. PIRP pUpperIrp; // irp from dll to complete
  32. ULONG ulWhichCommand; // command that is being completed
  33. ULONG ulListenFlag; // 0 or TDI_QUERY_ACCEPT
  34. PENDPOINT_OBJECT pEndpoint; // connection endpoint
  35. PIRP_POOL pIrpPool;
  36. PTDI_CONNECTION_INFORMATION
  37. pTdiConnectInfo;
  38. };
  39. typedef CONNECT_CONTEXT *PCONNECT_CONTEXT;
  40. //
  41. // completion functions
  42. //
  43. TDI_STATUS
  44. TSGenConnectComplete(
  45. PDEVICE_OBJECT DeviceObject,
  46. PIRP Irp,
  47. PVOID Context
  48. );
  49. TDI_STATUS
  50. TSGenAcceptComplete(
  51. PDEVICE_OBJECT DeviceObject,
  52. PIRP Irp,
  53. PVOID Context
  54. );
  55. /////////////////////////////////////////////////////////////
  56. // public functions
  57. //////////////////////////////////////////////////////////////
  58. // -----------------------------------------------------------------
  59. //
  60. // Function: TSConnect
  61. //
  62. // Arguments: pEndpoint -- connection endpoint structure
  63. // pSendBuffer -- arguments from user dll
  64. // pIrp -- completion information
  65. //
  66. // Returns: NTSTATUS (normally pending)
  67. //
  68. // Descript: This function attempts to connect the local endpoint object
  69. // with a remote endpoint
  70. //
  71. // -----------------------------------------------------------------
  72. NTSTATUS
  73. TSConnect(PENDPOINT_OBJECT pEndpoint,
  74. PSEND_BUFFER pSendBuffer,
  75. PIRP pUpperIrp)
  76. {
  77. PTRANSPORT_ADDRESS pTransportAddress
  78. = (PTRANSPORT_ADDRESS)&pSendBuffer->COMMAND_ARGS.ConnectArgs.TransAddr;
  79. ULONG ulTimeout
  80. = pSendBuffer->COMMAND_ARGS.ConnectArgs.ulTimeout;
  81. //
  82. // show debug, if it is turned on
  83. //
  84. if (ulDebugLevel & ulDebugShowCommand)
  85. {
  86. DebugPrint2("\nCommand = ulCONNECT\n"
  87. "FileObject = %p\n"
  88. "Timeout = %u\n",
  89. pEndpoint,
  90. ulTimeout);
  91. TSPrintTaAddress(pTransportAddress->Address);
  92. }
  93. //
  94. // make sure all is kosher
  95. //
  96. if (pEndpoint->fIsConnected)
  97. {
  98. DebugPrint1("%s: endpoint already connected\n", strFunc1);
  99. return STATUS_UNSUCCESSFUL;
  100. }
  101. if (!pEndpoint->pAddressObject)
  102. {
  103. DebugPrint1("%s: endpoint not associated with transport address\n",
  104. strFunc1);
  105. return STATUS_UNSUCCESSFUL;
  106. }
  107. //
  108. // allocate all the necessary structures
  109. //
  110. PCONNECT_CONTEXT pConnectContext;
  111. PTDI_CONNECTION_INFORMATION pTdiConnectInfo = NULL;
  112. //
  113. // our context
  114. //
  115. if ((TSAllocateMemory((PVOID *)&pConnectContext,
  116. sizeof(CONNECT_CONTEXT),
  117. strFunc1,
  118. "ConnectContext")) != STATUS_SUCCESS)
  119. {
  120. goto cleanup;
  121. }
  122. //
  123. // the connection information structure
  124. //
  125. if ((TSAllocateMemory((PVOID *)&pTdiConnectInfo,
  126. sizeof(TDI_CONNECTION_INFORMATION)
  127. + sizeof(TRANSADDR),
  128. strFunc1,
  129. "TdiConnectionInformation")) == STATUS_SUCCESS)
  130. //
  131. // set up the TdiConnectionInformation
  132. //
  133. {
  134. PUCHAR pucTemp = (PUCHAR)pTdiConnectInfo;
  135. ULONG ulAddrLength
  136. = FIELD_OFFSET(TRANSPORT_ADDRESS, Address)
  137. + FIELD_OFFSET(TA_ADDRESS, Address)
  138. + pTransportAddress->Address[0].AddressLength;
  139. pucTemp += sizeof(TDI_CONNECTION_INFORMATION);
  140. pTdiConnectInfo->RemoteAddress = pucTemp;
  141. pTdiConnectInfo->RemoteAddressLength = ulAddrLength;
  142. RtlCopyMemory(pucTemp,
  143. pTransportAddress,
  144. ulAddrLength);
  145. }
  146. else
  147. {
  148. goto cleanup;
  149. }
  150. //
  151. // set up the completion context
  152. //
  153. pConnectContext->pUpperIrp = pUpperIrp;
  154. pConnectContext->pTdiConnectInfo = pTdiConnectInfo;
  155. pConnectContext->pEndpoint = pEndpoint;
  156. pConnectContext->ulWhichCommand = TDI_CONNECT;
  157. //
  158. // finally, the irp itself
  159. //
  160. PIRP pLowerIrp = TSAllocateIrp(pEndpoint->GenHead.pDeviceObject,
  161. NULL);
  162. if (pLowerIrp)
  163. {
  164. LONGLONG llTimeout;
  165. PLONGLONG pllTimeout = NULL;
  166. if (ulTimeout)
  167. {
  168. llTimeout = Int32x32To64(ulTimeout, -10000);
  169. pllTimeout = &llTimeout;
  170. }
  171. //
  172. // if made it to here, everything is correctly allocated
  173. // set up irp and and call the tdi provider
  174. //
  175. #pragma warning(disable: CONSTANT_CONDITIONAL)
  176. TdiBuildConnect(pLowerIrp,
  177. pEndpoint->GenHead.pDeviceObject,
  178. pEndpoint->GenHead.pFileObject,
  179. TSGenConnectComplete,
  180. pConnectContext,
  181. pllTimeout,
  182. pTdiConnectInfo,
  183. NULL); // ReturnConnectionInfo
  184. #pragma warning(default: CONSTANT_CONDITIONAL)
  185. //
  186. // make the call to the tdi provider
  187. //
  188. pSendBuffer->pvLowerIrp = pLowerIrp; // so command can be cancelled
  189. NTSTATUS lStatus = IoCallDriver(pEndpoint->GenHead.pDeviceObject,
  190. pLowerIrp);
  191. if ((!NT_SUCCESS(lStatus)) && (ulDebugLevel & ulDebugShowCommand))
  192. {
  193. DebugPrint2("%s: unexpected status for IoCallDriver [0x%08x]\n",
  194. strFunc1,
  195. lStatus);
  196. }
  197. return STATUS_PENDING;
  198. }
  199. //
  200. // get here if there was an allocation failure
  201. // need to clean up everything else...
  202. //
  203. cleanup:
  204. if (pConnectContext)
  205. {
  206. TSFreeMemory(pConnectContext);
  207. }
  208. if (pTdiConnectInfo)
  209. {
  210. TSFreeMemory(pTdiConnectInfo);
  211. }
  212. return STATUS_INSUFFICIENT_RESOURCES;
  213. }
  214. // -----------------------------------------------------------------
  215. //
  216. // Function: TSDisconnect
  217. //
  218. // Arguments: pEndpoint -- connection endpoint structure
  219. // pIrp -- completion information
  220. //
  221. // Returns: NTSTATUS (normally pending)
  222. //
  223. // Descript: This function attempts to disconnect a local endpoint from
  224. // a remote endpoint
  225. //
  226. // -----------------------------------------------------------------
  227. NTSTATUS
  228. TSDisconnect(PENDPOINT_OBJECT pEndpoint,
  229. PSEND_BUFFER pSendBuffer,
  230. PIRP pUpperIrp)
  231. {
  232. ULONG ulFlags = pSendBuffer->COMMAND_ARGS.ulFlags;
  233. if (ulFlags != TDI_DISCONNECT_RELEASE)
  234. {
  235. ulFlags = TDI_DISCONNECT_ABORT;
  236. }
  237. //
  238. // show debug, if it is turned on
  239. //
  240. if (ulDebugLevel & ulDebugShowCommand)
  241. {
  242. DebugPrint2("\nCommand = ulDISCONNECT\n"
  243. "EndpointObject = %p\n"
  244. "Flags = 0x%x\n",
  245. pEndpoint,
  246. ulFlags);
  247. }
  248. //
  249. // make sure all is kosher
  250. //
  251. if (!pEndpoint->fIsConnected)
  252. {
  253. DebugPrint1("%s: endpoint not currently connected\n", strFunc2);
  254. return STATUS_SUCCESS;
  255. }
  256. //
  257. // allocate all the necessary structures
  258. //
  259. PCONNECT_CONTEXT pConnectContext;
  260. //
  261. // first, our context
  262. //
  263. if ((TSAllocateMemory((PVOID *)&pConnectContext,
  264. sizeof(CONNECT_CONTEXT),
  265. strFunc2,
  266. "ConnectContext")) == STATUS_SUCCESS)
  267. {
  268. pConnectContext->pUpperIrp = pUpperIrp;
  269. pConnectContext->ulWhichCommand = TDI_DISCONNECT;
  270. pConnectContext->pEndpoint = pEndpoint;
  271. //
  272. // then the irp itself
  273. //
  274. PIRP pLowerIrp = TSAllocateIrp(pEndpoint->GenHead.pDeviceObject,
  275. NULL);
  276. if (pLowerIrp)
  277. {
  278. //
  279. // if made it to here, everything is correctly allocated
  280. // set up everything and call the tdi provider
  281. //
  282. #pragma warning(disable: CONSTANT_CONDITIONAL)
  283. TdiBuildDisconnect(pLowerIrp,
  284. pEndpoint->GenHead.pDeviceObject,
  285. pEndpoint->GenHead.pFileObject,
  286. TSGenConnectComplete,
  287. pConnectContext,
  288. NULL, // pLargeInteger Time
  289. ulFlags, // TDI_DISCONNECT _ABORT or _RELEASE
  290. NULL, // RequestConnectionInfo
  291. NULL); // ReturnConnectionInfo
  292. #pragma warning(default: CONSTANT_CONDITIONAL)
  293. //
  294. // make the call to the tdi provider
  295. //
  296. pSendBuffer->pvLowerIrp = pLowerIrp; // so command can be cancelled
  297. pEndpoint->fStartedDisconnect = TRUE;
  298. NTSTATUS lStatus = IoCallDriver(pEndpoint->GenHead.pDeviceObject,
  299. pLowerIrp);
  300. if ((!NT_SUCCESS(lStatus)) && (ulDebugLevel & ulDebugShowCommand))
  301. {
  302. DebugPrint2("%s: unexpected status for IoCallDriver [0x%08x]\n",
  303. strFunc2,
  304. lStatus);
  305. }
  306. return STATUS_PENDING;
  307. }
  308. TSFreeMemory(pConnectContext);
  309. }
  310. return STATUS_INSUFFICIENT_RESOURCES;
  311. }
  312. // --------------------------------------------------
  313. //
  314. // Function: TSListen
  315. //
  316. // Arguments: pEndpoint -- connection endpoint structure
  317. //
  318. // Returns: status of operation (usually success)
  319. //
  320. // Descript: Wait for an incoming call request
  321. //
  322. // --------------------------------------------------
  323. NTSTATUS
  324. TSListen(PENDPOINT_OBJECT pEndpoint)
  325. {
  326. ULONG ulListenFlag = 0;
  327. //
  328. // show debug, if it is turned on
  329. //
  330. if (ulDebugLevel & ulDebugShowCommand)
  331. {
  332. DebugPrint1("\nCommand = ulLISTEN\n"
  333. "FileObject = %p\n",
  334. pEndpoint);
  335. }
  336. //
  337. // make sure all is kosher
  338. //
  339. if (pEndpoint->fIsConnected)
  340. {
  341. DebugPrint1("%s: endpoint already connected\n", strFunc6);
  342. return STATUS_UNSUCCESSFUL;
  343. }
  344. if (!pEndpoint->pAddressObject)
  345. {
  346. DebugPrint1("%s: endpoint not associated with transport address\n",
  347. strFunc6);
  348. return STATUS_UNSUCCESSFUL;
  349. }
  350. //
  351. // allocate all the necessary structures
  352. //
  353. PCONNECT_CONTEXT pConnectContext;
  354. PTDI_CONNECTION_INFORMATION pTdiConnectInfo = NULL;
  355. //
  356. // our context
  357. //
  358. if ((TSAllocateMemory((PVOID *)&pConnectContext,
  359. sizeof(CONNECT_CONTEXT),
  360. strFunc6,
  361. "ConnectContext")) != STATUS_SUCCESS)
  362. {
  363. goto cleanup;
  364. }
  365. //
  366. // the connection information structure
  367. //
  368. if ((TSAllocateMemory((PVOID *)&pTdiConnectInfo,
  369. sizeof(TDI_CONNECTION_INFORMATION),
  370. strFunc6,
  371. "TdiConnectionInformation")) == STATUS_SUCCESS)
  372. //
  373. // set up the TdiConnectionInformation
  374. //
  375. {
  376. pTdiConnectInfo->UserData = NULL;
  377. pTdiConnectInfo->UserDataLength = 0;
  378. pTdiConnectInfo->RemoteAddress = NULL;
  379. pTdiConnectInfo->RemoteAddressLength = 0;
  380. pTdiConnectInfo->Options = &pConnectContext->ulListenFlag;
  381. pTdiConnectInfo->OptionsLength = sizeof(ULONG);
  382. //
  383. // set up the completion context
  384. // note that the upper irp is NOT passed!
  385. //
  386. pConnectContext->pUpperIrp = NULL;
  387. pConnectContext->pTdiConnectInfo = pTdiConnectInfo;
  388. pConnectContext->pEndpoint = pEndpoint;
  389. pConnectContext->ulWhichCommand = TDI_LISTEN;
  390. pConnectContext->ulListenFlag = ulListenFlag;
  391. if (!pEndpoint->pAddressObject->pIrpPool)
  392. {
  393. pEndpoint->pAddressObject->pIrpPool
  394. = TSAllocateIrpPool(pEndpoint->pAddressObject->GenHead.pDeviceObject,
  395. ulIrpPoolSize);
  396. pConnectContext->pIrpPool = pEndpoint->pAddressObject->pIrpPool;
  397. }
  398. //
  399. // finally, the irp itself
  400. //
  401. PIRP pLowerIrp = TSAllocateIrp(pEndpoint->GenHead.pDeviceObject,
  402. pEndpoint->pAddressObject->pIrpPool);
  403. if (pLowerIrp)
  404. {
  405. //
  406. // if made it to here, everything is correctly allocated
  407. // set up irp and call the tdi provider
  408. //
  409. #pragma warning(disable: CONSTANT_CONDITIONAL)
  410. TdiBuildListen(pLowerIrp,
  411. pEndpoint->GenHead.pDeviceObject,
  412. pEndpoint->GenHead.pFileObject,
  413. TSGenAcceptComplete,
  414. pConnectContext,
  415. ulListenFlag,
  416. pTdiConnectInfo,
  417. NULL); // ReturnConnectionInfo
  418. #pragma warning(default: CONSTANT_CONDITIONAL)
  419. NTSTATUS lStatus = IoCallDriver(pEndpoint->GenHead.pDeviceObject,
  420. pLowerIrp);
  421. if ((!NT_SUCCESS(lStatus)) && (ulDebugLevel & ulDebugShowCommand))
  422. {
  423. DebugPrint2("%s: unexpected status for IoCallDriver [0x%08x]\n",
  424. strFunc6,
  425. lStatus);
  426. }
  427. return STATUS_SUCCESS;
  428. }
  429. }
  430. //
  431. // get here if there was an allocation failure
  432. // need to clean up everything else...
  433. //
  434. cleanup:
  435. if (pConnectContext)
  436. {
  437. TSFreeMemory(pConnectContext);
  438. }
  439. if (pTdiConnectInfo)
  440. {
  441. TSFreeMemory(pTdiConnectInfo);
  442. }
  443. return STATUS_INSUFFICIENT_RESOURCES;
  444. }
  445. // --------------------------------------------------
  446. //
  447. // Function: TSIsConnected
  448. //
  449. // Arguments: pEndpoint -- connection endpoint structure
  450. // pReceiveBuffer -- put results in here
  451. //
  452. // Returns: STATUS_SUCCESS
  453. //
  454. // Descript: Checks to see if endpoint is currently connected
  455. //
  456. // --------------------------------------------------
  457. NTSTATUS
  458. TSIsConnected(PENDPOINT_OBJECT pEndpoint,
  459. PRECEIVE_BUFFER pReceiveBuffer)
  460. {
  461. pReceiveBuffer->RESULTS.ulReturnValue = pEndpoint->fIsConnected;
  462. return STATUS_SUCCESS;
  463. }
  464. // --------------------------------------------------
  465. //
  466. // Function: TSConnectHandler
  467. //
  468. // Arguments: pvTdiEventContext -- here, ptr to address object
  469. // lRemoteAddressLength -- # bytes in remote address
  470. // pvRemoteAddress -- pTransportAddress of remote
  471. // lUserDataLength -- length of data at pvUserData
  472. // pvUserData -- connect data from remote
  473. // lOptionsLength -- length of data in pvOptions
  474. // pvOptions -- transport-specific connect options
  475. // pConnectionContext -- return ptr to connection context
  476. // ppAcceptIrp -- return ptr to TdiBuildAccept irp
  477. //
  478. // Returns: STATUS_CONNECTION_REFUSED if are rejecting connection
  479. // STATUS_MORE_PROCESSING_REQUIRED is accepting and have supplied
  480. // a ppAcceptIrp
  481. //
  482. // Descript: listens for an offerred connection, then
  483. // accepts it or rejects it
  484. //
  485. // --------------------------------------------------
  486. TDI_STATUS
  487. TSConnectHandler(PVOID pvTdiEventContext,
  488. LONG lRemoteAddressLength,
  489. PVOID pvRemoteAddress,
  490. LONG lUserDataLength,
  491. PVOID pvUserData,
  492. LONG lOptionsLength,
  493. PVOID pvOptions,
  494. CONNECTION_CONTEXT *pConnectionContext,
  495. PIRP *ppAcceptIrp)
  496. {
  497. PADDRESS_OBJECT pAddressObject = (PADDRESS_OBJECT)pvTdiEventContext;
  498. PENDPOINT_OBJECT pEndpoint = pAddressObject->pEndpoint;
  499. //
  500. // show the information passed in.
  501. // Note that we actually use very little of it..
  502. //
  503. if (ulDebugLevel & ulDebugShowHandlers)
  504. {
  505. DebugPrint1("\n >>>> %s\n", strFunc4);
  506. DebugPrint2("pAddressObject = %p\n"
  507. "RemoteAddressLength = %d\n",
  508. pAddressObject,
  509. lRemoteAddressLength);
  510. if (lRemoteAddressLength)
  511. {
  512. PTRANSPORT_ADDRESS pTransportAddress = (PTRANSPORT_ADDRESS)pvRemoteAddress;
  513. DebugPrint0("RemoteAddress: ");
  514. TSPrintTaAddress(&pTransportAddress->Address[0]);
  515. }
  516. DebugPrint1("UserDataLength = %d\n", lUserDataLength);
  517. if (lUserDataLength)
  518. {
  519. PUCHAR pucTemp = (PUCHAR)pvUserData;
  520. DebugPrint0("UserData: ");
  521. for (LONG lCount = 0; lCount < lUserDataLength; lCount++)
  522. {
  523. DebugPrint1("%02x ", *pucTemp);
  524. ++pucTemp;
  525. }
  526. DebugPrint0("\n");
  527. }
  528. DebugPrint1("OptionsLength = %d\n", lOptionsLength);
  529. if (lOptionsLength)
  530. {
  531. PUCHAR pucTemp = (PUCHAR)pvOptions;
  532. DebugPrint0("Options: ");
  533. for (LONG lCount = 0; lCount < (LONG)lOptionsLength; lCount++)
  534. {
  535. DebugPrint1("%02x ", *pucTemp);
  536. ++pucTemp;
  537. }
  538. DebugPrint0("\n");
  539. }
  540. }
  541. //
  542. // now do the work
  543. //
  544. if (pEndpoint->fIsConnected || pEndpoint->fAcceptInProgress)
  545. {
  546. return TDI_CONN_REFUSED;
  547. }
  548. pEndpoint->fAcceptInProgress = TRUE;
  549. //
  550. // allocate all the necessary structures
  551. //
  552. PCONNECT_CONTEXT pConnectContext;
  553. //
  554. // first, our context
  555. //
  556. if ((TSAllocateMemory((PVOID *)&pConnectContext,
  557. sizeof(CONNECT_CONTEXT),
  558. strFunc4,
  559. "ConnectContext")) == STATUS_SUCCESS)
  560. {
  561. pConnectContext->pUpperIrp = NULL;
  562. pConnectContext->ulWhichCommand = TDI_ACCEPT;
  563. pConnectContext->pEndpoint = pEndpoint;
  564. //
  565. // then the irp itself
  566. //
  567. PIRP pLowerIrp = TSAllocateIrp(pEndpoint->GenHead.pDeviceObject,
  568. pAddressObject->pIrpPool);
  569. pConnectContext->pIrpPool = pAddressObject->pIrpPool;
  570. if (pLowerIrp)
  571. {
  572. //
  573. // if made it to here, everything is correctly allocated
  574. // set up irp and call the tdi provider
  575. //
  576. #pragma warning(disable: CONSTANT_CONDITIONAL)
  577. TdiBuildAccept(pLowerIrp,
  578. pEndpoint->GenHead.pDeviceObject,
  579. pEndpoint->GenHead.pFileObject,
  580. TSGenAcceptComplete,
  581. pConnectContext,
  582. NULL, // RequestConnectionInfo
  583. NULL); // ReturnConnectionInfo
  584. #pragma warning(default: CONSTANT_CONDITIONAL)
  585. //
  586. // need to do this since we are not calling IoCallDriver
  587. //
  588. IoSetNextIrpStackLocation(pLowerIrp);
  589. *pConnectionContext = pEndpoint;
  590. *ppAcceptIrp = pLowerIrp;
  591. return TDI_MORE_PROCESSING;
  592. }
  593. TSFreeMemory(pConnectContext);
  594. }
  595. pEndpoint->fAcceptInProgress = FALSE;
  596. return TDI_CONN_REFUSED;
  597. }
  598. // --------------------------------------------------
  599. //
  600. // Function: TdiDisconnectHandler
  601. //
  602. // Arguments: pvTdiEventContext -- here, our address object
  603. // ConnectionContext -- here, our connection object
  604. // lDisconnectDataLength -- length of data in pvDisconnectData
  605. // pvDisconnectData -- data sent by remote as part of disconnect
  606. // lDisconnectInformationLength -- length of pvDisconnectInformation
  607. // pvDisconnectInformation -- transport-specific sidconnect info
  608. // ulDisconnectFlags -- nature of disconnect
  609. //
  610. // Returns: STATUS_SUCCESS
  611. //
  612. // Descript: deals with an incoming disconnect. Note that the disconnect
  613. // is really complete at this point, as far as the protocol
  614. // is concerned. We just need to clean up our stuff
  615. //
  616. // --------------------------------------------------
  617. TDI_STATUS
  618. TSDisconnectHandler(PVOID pvTdiEventContext,
  619. CONNECTION_CONTEXT ConnectionContext,
  620. LONG lDisconnectDataLength,
  621. PVOID pvDisconnectData,
  622. LONG lDisconnectInformationLength,
  623. PVOID pvDisconnectInformation,
  624. ULONG ulDisconnectFlags)
  625. {
  626. PENDPOINT_OBJECT pEndpoint = (PENDPOINT_OBJECT)ConnectionContext;
  627. //
  628. // show info in arguments
  629. //
  630. if (ulDebugLevel & ulDebugShowHandlers)
  631. {
  632. DebugPrint1("\n >>>> %s\n", strFunc5);
  633. DebugPrint3("pAddressObject = %p\n"
  634. "pEndpoint = %p\n"
  635. "DisconnectDataLength = %d\n",
  636. pvTdiEventContext,
  637. pEndpoint,
  638. lDisconnectDataLength);
  639. if (lDisconnectDataLength)
  640. {
  641. PUCHAR pucTemp = (PUCHAR)pvDisconnectData;
  642. DebugPrint0("DisconnectData: ");
  643. for (LONG lCount = 0; lCount < (LONG)lDisconnectDataLength; lCount++)
  644. {
  645. DebugPrint1("%02x ", *pucTemp);
  646. ++pucTemp;
  647. }
  648. DebugPrint0("\n");
  649. }
  650. DebugPrint1("DisconnectInformationLength = %d\n",
  651. lDisconnectInformationLength);
  652. if (lDisconnectInformationLength)
  653. {
  654. PUCHAR pucTemp = (PUCHAR)pvDisconnectInformation;
  655. DebugPrint0("DisconnectInformation: ");
  656. for (LONG lCount = 0; lCount < (LONG)lDisconnectInformationLength; lCount++)
  657. {
  658. DebugPrint1("%02x ", *pucTemp);
  659. ++pucTemp;
  660. }
  661. DebugPrint0("\n");
  662. }
  663. DebugPrint1("DisconnectFlags = 0x%08x\n", ulDisconnectFlags);
  664. if (ulDisconnectFlags & TDI_DISCONNECT_ABORT)
  665. {
  666. DebugPrint0(" TDI_DISCONNECT_ABORT\n");
  667. }
  668. if (ulDisconnectFlags & TDI_DISCONNECT_RELEASE)
  669. {
  670. DebugPrint0(" TDI_DISCONNECT_RELEASE\n");
  671. }
  672. }
  673. //
  674. // do our cleanup..
  675. //
  676. pEndpoint->fIsConnected = FALSE;
  677. if ((ulDisconnectFlags & TDI_DISCONNECT_RELEASE) &&
  678. (!pEndpoint->fStartedDisconnect))
  679. {
  680. //
  681. // allocate all the necessary structures
  682. //
  683. PCONNECT_CONTEXT pConnectContext;
  684. //
  685. // first, our context
  686. //
  687. if ((TSAllocateMemory((PVOID *)&pConnectContext,
  688. sizeof(CONNECT_CONTEXT),
  689. strFunc5,
  690. "ConnectContext")) == STATUS_SUCCESS)
  691. {
  692. pConnectContext->pUpperIrp = NULL;
  693. pConnectContext->ulWhichCommand = TDI_DISCONNECT;
  694. pConnectContext->pEndpoint = pEndpoint;
  695. //
  696. // then the irp itself
  697. //
  698. PIRP pLowerIrp = TSAllocateIrp(pEndpoint->GenHead.pDeviceObject,
  699. pEndpoint->pAddressObject->pIrpPool);
  700. pConnectContext->pIrpPool = pEndpoint->pAddressObject->pIrpPool;
  701. if (pLowerIrp)
  702. {
  703. //
  704. // if made it to here, everything is correctly allocated
  705. // set up irp and call the tdi provider
  706. //
  707. #pragma warning(disable: CONSTANT_CONDITIONAL)
  708. TdiBuildDisconnect(pLowerIrp,
  709. pEndpoint->GenHead.pDeviceObject,
  710. pEndpoint->GenHead.pFileObject,
  711. TSGenAcceptComplete,
  712. pConnectContext,
  713. NULL, // pLargeInteger Time
  714. TDI_DISCONNECT_RELEASE,
  715. NULL, // RequestConnectionInfo
  716. NULL); // ReturnConnectionInfo
  717. #pragma warning(default: CONSTANT_CONDITIONAL)
  718. //
  719. // make the call to the tdi provider
  720. //
  721. NTSTATUS lStatus = IoCallDriver(pEndpoint->GenHead.pDeviceObject,
  722. pLowerIrp);
  723. if ((!NT_SUCCESS(lStatus)) && (ulDebugLevel & ulDebugShowCommand))
  724. {
  725. DebugPrint2("%s: unexpected status for IoCallDriver [0x%08x]\n",
  726. strFunc5,
  727. lStatus);
  728. }
  729. }
  730. else
  731. {
  732. TSFreeMemory(pConnectContext);
  733. }
  734. }
  735. }
  736. //
  737. // get here if do NOT need to send TDI_DISCONNECT_RELEASE message back
  738. // to other end of connection
  739. //
  740. else
  741. {
  742. pEndpoint->fAcceptInProgress = FALSE;
  743. pEndpoint->fIsConnected = FALSE;
  744. }
  745. return TDI_SUCCESS;
  746. }
  747. /////////////////////////////////////////////////////////////
  748. // private functions
  749. /////////////////////////////////////////////////////////////
  750. // ---------------------------------------------------------
  751. //
  752. // Function: TSGenAcceptComplete
  753. //
  754. // Arguments: pDeviceObject -- device object on which call was made
  755. // pIrp -- IRP used in the call
  756. // pContext -- context used for the call
  757. //
  758. // Returns: status of operation (STATUS_MORE_PROCESSING_REQUIRED)
  759. //
  760. // Descript: Gets the result of the command, stuffs results into
  761. // receive buffer, cleans up the Irp and associated data
  762. // structures, etc
  763. // This is used to complete cases where this no IRP from the
  764. // dll to complete (ie, connect handler, listen, listen-accept,
  765. // listen-disconnect)
  766. //
  767. // ---------------------------------------------------------
  768. #pragma warning(disable: UNREFERENCED_PARAM)
  769. TDI_STATUS
  770. TSGenAcceptComplete(PDEVICE_OBJECT pDeviceObject,
  771. PIRP pLowerIrp,
  772. PVOID pvContext)
  773. {
  774. PCONNECT_CONTEXT pConnectContext = (PCONNECT_CONTEXT)pvContext;
  775. NTSTATUS lStatus = pLowerIrp->IoStatus.Status;
  776. //
  777. // dealing with completions where there is no DLL irp associated
  778. //
  779. switch (pConnectContext->ulWhichCommand)
  780. {
  781. case TDI_ACCEPT:
  782. if (NT_SUCCESS(lStatus))
  783. {
  784. pConnectContext->pEndpoint->fIsConnected = TRUE;
  785. }
  786. pConnectContext->pEndpoint->fAcceptInProgress = FALSE;
  787. break;
  788. case TDI_LISTEN:
  789. if (NT_SUCCESS(lStatus))
  790. {
  791. pConnectContext->pEndpoint->fIsConnected = TRUE;
  792. }
  793. else
  794. {
  795. DebugPrint1("Failure in TSListen: status = 0x%08x\n", lStatus);
  796. }
  797. break;
  798. case TDI_DISCONNECT:
  799. pConnectContext->pEndpoint->fAcceptInProgress = FALSE;
  800. pConnectContext->pEndpoint->fIsConnected = FALSE;
  801. pConnectContext->pEndpoint->fStartedDisconnect = FALSE;
  802. break;
  803. }
  804. TSFreeIrp(pLowerIrp, pConnectContext->pIrpPool);
  805. //
  806. // generic cleanup
  807. //
  808. if (pConnectContext->pTdiConnectInfo)
  809. {
  810. TSFreeMemory(pConnectContext->pTdiConnectInfo);
  811. }
  812. TSFreeMemory(pConnectContext);
  813. return TDI_MORE_PROCESSING;
  814. }
  815. #pragma warning(default: UNREFERENCED_PARAM)
  816. // ---------------------------------------------------------
  817. //
  818. // Function: TSGenConnectComplete
  819. //
  820. // Arguments: pDeviceObject -- device object on which call was made
  821. // pIrp -- IRP used in the call
  822. // pContext -- context used for the call
  823. //
  824. // Returns: status of operation (STATUS_MORE_PROCESSING_REQUIRED)
  825. //
  826. // Descript: Gets the result of the command, stuffs results into
  827. // receive buffer, completes the IRP from the dll,
  828. // cleans up the Irp and associated data structures, etc
  829. // Deals only with commands that carry an IRP from the dll
  830. //
  831. // ---------------------------------------------------------
  832. #pragma warning(disable: UNREFERENCED_PARAM)
  833. TDI_STATUS
  834. TSGenConnectComplete(PDEVICE_OBJECT pDeviceObject,
  835. PIRP pLowerIrp,
  836. PVOID pvContext)
  837. {
  838. PCONNECT_CONTEXT pConnectContext = (PCONNECT_CONTEXT)pvContext;
  839. NTSTATUS lStatus = pLowerIrp->IoStatus.Status;
  840. //
  841. // this is completing a command from the dll
  842. //
  843. PRECEIVE_BUFFER pReceiveBuffer = TSGetReceiveBuffer(pConnectContext->pUpperIrp);
  844. pReceiveBuffer->lStatus = lStatus;
  845. if (NT_SUCCESS(lStatus))
  846. {
  847. if (ulDebugLevel & ulDebugShowCommand)
  848. {
  849. if (pLowerIrp->IoStatus.Information)
  850. {
  851. DebugPrint2("%s: Information = 0x%08x\n",
  852. strFuncP2,
  853. pLowerIrp->IoStatus.Information);
  854. }
  855. }
  856. switch (pConnectContext->ulWhichCommand)
  857. {
  858. case TDI_CONNECT:
  859. pConnectContext->pEndpoint->fIsConnected = TRUE;
  860. break;
  861. case TDI_DISCONNECT:
  862. pConnectContext->pEndpoint->fIsConnected = FALSE;
  863. break;
  864. default:
  865. DebugPrint2("%s: invalid command value [0x%08x]\n",
  866. strFuncP2,
  867. pConnectContext->ulWhichCommand);
  868. DbgBreakPoint();
  869. break;
  870. }
  871. }
  872. else
  873. {
  874. if (ulDebugLevel & ulDebugShowCommand)
  875. {
  876. DebugPrint2("%s: Completed with status 0x%08x\n",
  877. strFuncP2,
  878. lStatus);
  879. }
  880. }
  881. TSCompleteIrp(pConnectContext->pUpperIrp);
  882. TSFreeIrp(pLowerIrp, NULL);
  883. //
  884. // generic cleanup
  885. //
  886. if (pConnectContext->pTdiConnectInfo)
  887. {
  888. TSFreeMemory(pConnectContext->pTdiConnectInfo);
  889. }
  890. TSFreeMemory(pConnectContext);
  891. return TDI_MORE_PROCESSING;
  892. }
  893. #pragma warning(default: UNREFERENCED_PARAM)
  894. ///////////////////////////////////////////////////////////////////////////////
  895. // end of file connect.cpp
  896. ///////////////////////////////////////////////////////////////////////////////