Leaked source code of windows server 2003

1000 lines
28 KiB

  1. /*************************************************************************
  2. *
  3. * stack.c
  4. *
  5. * ICA STACK IOCTLS
  6. *
  7. * Copyright Microsoft, 1998
  8. *
  9. *
  10. *************************************************************************/
  11. /*
  12. * Includes
  13. */
  14. #include <ntddk.h>
  15. #include <ntddvdeo.h>
  16. #include <ntddkbd.h>
  17. #include <ntddmou.h>
  18. #include <ntddbeep.h>
  19. #include <winstaw.h>
  20. #include <icadd.h>
  21. #include <sdapi.h>
  22. #include <td.h>
  23. /*=============================================================================
  24. == External procedures defined
  25. =============================================================================*/
  26. NTSTATUS StackCreateEndpoint( PTD, PSD_IOCTL );
  27. NTSTATUS StackCdCreateEndpoint( PTD, PSD_IOCTL );
  28. NTSTATUS StackCallbackInitiate( PTD, PSD_IOCTL );
  29. NTSTATUS StackCallbackComplete( PTD, PSD_IOCTL );
  30. NTSTATUS StackOpenEndpoint( PTD, PSD_IOCTL );
  31. NTSTATUS StackCloseEndpoint( PTD, PSD_IOCTL );
  32. NTSTATUS StackConnectionWait( PTD, PSD_IOCTL );
  33. NTSTATUS StackConnectionSend( PTD, PSD_IOCTL );
  34. NTSTATUS StackConnectionRequest( PTD, PSD_IOCTL );
  35. NTSTATUS StackQueryParams( PTD, PSD_IOCTL );
  36. NTSTATUS StackSetParams( PTD, PSD_IOCTL );
  37. NTSTATUS StackQueryLastError( PTD, PSD_IOCTL );
  38. NTSTATUS StackWaitForStatus( PTD, PSD_IOCTL );
  39. NTSTATUS StackCancelIo( PTD, PSD_IOCTL );
  40. NTSTATUS StackQueryRemoteAddress( PTD, PSD_IOCTL );
  41. NTSTATUS StackQueryLocalAddress( PTD, PSD_IOCTL );
  42. /*=============================================================================
  43. == Internal procedures defined
  44. =============================================================================*/
  45. NTSTATUS _TdCreateInputThread( PTD );
  46. /*=============================================================================
  47. == Procedures used
  48. =============================================================================*/
  49. NTSTATUS DeviceCreateEndpoint( PTD, PICA_STACK_ADDRESS, PICA_STACK_ADDRESS );
  50. NTSTATUS DeviceOpenEndpoint( PTD, PVOID, ULONG );
  51. NTSTATUS DeviceCloseEndpoint( PTD );
  52. NTSTATUS DeviceConnectionWait( PTD, PVOID, ULONG, PULONG );
  53. NTSTATUS DeviceConnectionSend( PTD );
  54. NTSTATUS DeviceConnectionRequest( PTD, PICA_STACK_ADDRESS, PVOID, ULONG, PULONG );
  55. NTSTATUS DeviceGetLastError( PTD, PICA_STACK_LAST_ERROR );
  56. NTSTATUS DeviceWaitForStatus( PTD );
  57. NTSTATUS DeviceCancelIo( PTD );
  58. NTSTATUS DeviceSetParams( PTD );
  59. NTSTATUS DeviceIoctl( PTD, PSD_IOCTL );
  60. NTSTATUS DeviceQueryRemoteAddress( PTD, PVOID, ULONG, PVOID, ULONG, PULONG );
  61. NTSTATUS DeviceQueryLocalAddress( PTD, PVOID, ULONG, PULONG );
  62. NTSTATUS TdInputThread( PTD );
  63. NTSTATUS TdSyncWrite( PTD, PSD_SYNCWRITE );
  64. /*******************************************************************************
  65. *
  66. * StackCreateEndpoint IOCTL_ICA_STACK_CREATE_ENDPOINT
  67. *
  68. * Create new transport endpoint
  69. *
  70. * The endpoint structure contains everything necessary to preserve
  71. * a client connection across a transport driver unload and reload.
  72. *
  73. * This routine creates a new endpoint, using the optional local address.
  74. * In the case of a network connection, the actual endpoint cannot be
  75. * created until the client connection is established. What this routine
  76. * creates is an endpoint to listen on.
  77. *
  78. * DeviceConnectionWait and DeviceConnectionRequest return the endpoint.
  79. *
  80. * NOTE: The endpoint structure is an opaque, variable length data
  81. * structure whose length and contents are determined by the
  82. * transport driver.
  83. *
  84. *
  85. * ENTRY:
  86. * pTd (input)
  87. * Pointer to td data structure
  88. * pSdIoctl (input/output)
  89. * input - ICA_STACK_ADDRESS (or NULL)
  90. * output - nothing
  91. *
  92. * EXIT:
  93. * STATUS_SUCCESS - no error
  94. *
  95. ******************************************************************************/
  96. NTSTATUS
  97. StackCreateEndpoint( PTD pTd, PSD_IOCTL pSdIoctl )
  98. {
  99. PICA_STACK_ADDRESS pAddressIn;
  100. PICA_STACK_ADDRESS pAddressOut;
  101. NTSTATUS Status;
  102. if ( pSdIoctl->InputBufferLength < sizeof(ICA_STACK_ADDRESS) ) {
  103. /*
  104. * No address specified
  105. */
  106. pAddressIn = NULL;
  107. } else {
  108. /*
  109. * Get local address to use, if any
  110. */
  111. pAddressIn = pSdIoctl->InputBuffer;
  112. }
  113. if ( pSdIoctl->OutputBufferLength < sizeof(ICA_STACK_ADDRESS) ) {
  114. /*
  115. * No address specified
  116. */
  117. pAddressOut = NULL;
  118. } else {
  119. /*
  120. * Get local address to use, if any
  121. */
  122. pAddressOut = pSdIoctl->OutputBuffer;
  123. }
  124. /*
  125. * Initialize transport driver endpoint
  126. */
  127. Status = DeviceCreateEndpoint( pTd, pAddressIn, pAddressOut );
  128. if ( !NT_SUCCESS(Status) )
  129. goto badcreate;
  130. TRACE(( pTd->pContext, TC_TD, TT_API1, "TD: StackCreateEndpoint: %x, success\n", pAddressIn ));
  131. return( STATUS_SUCCESS );
  132. /*=============================================================================
  133. == Error returns
  134. =============================================================================*/
  135. /*
  136. * endpoint create failed
  137. */
  138. badcreate:
  139. TRACE(( pTd->pContext, TC_TD, TT_ERROR, "TD: StackCreateEndpoint: %x, Status=0x%x\n", pAddressIn, Status ));
  140. return( Status );
  141. }
  142. /*******************************************************************************
  143. *
  144. * StackCdCreateEndpoint IOCTL_ICA_STACK_CD_CREATE_ENDPOINT
  145. *
  146. * Create an endpoint based on a data provided by a connection driver.
  147. *
  148. * NOTE: The endpoint structure is an opaque, variable length data
  149. * structure whose length and contents are determined by the
  150. * transport driver.
  151. *
  152. * ENTRY:
  153. * pTd (input)
  154. * Pointer to td data structure
  155. * pSdIoctl (input/output)
  156. * input - <endpoint data)
  157. * output - <endpoint data>
  158. *
  159. * EXIT:
  160. * STATUS_SUCCESS - no error
  161. *
  162. ******************************************************************************/
  163. NTSTATUS
  164. StackCdCreateEndpoint( PTD pTd, PSD_IOCTL pSdIoctl )
  165. {
  166. NTSTATUS Status;
  167. TRACE(( pTd->pContext, TC_TD, TT_API1,
  168. "TD: StackCdCreateEndpoint: entry\n" ));
  169. pTd->fClosing = FALSE;
  170. /*
  171. * Initialize transport driver endpoint
  172. */
  173. Status = DeviceIoctl( pTd, pSdIoctl );
  174. if ( !NT_SUCCESS(Status) )
  175. goto badopen;
  176. TRACE(( pTd->pContext, TC_TD, TT_API1,
  177. "TD: StackCdCreateEndpoint: success\n" ));
  178. return( STATUS_SUCCESS );
  179. /*=============================================================================
  180. == Error returns
  181. =============================================================================*/
  182. /*
  183. * endpoint open failed
  184. */
  185. badopen:
  186. TRACE(( pTd->pContext, TC_TD, TT_ERROR,
  187. "TD: StackCdCreateEndpoint: Status=0x%x\n",
  188. Status ));
  189. return( Status );
  190. }
  191. /*******************************************************************************
  192. *
  193. * StackCallbackInitiate IOCTL_ICA_STACK_CALLBACK_INITIATE
  194. *
  195. *
  196. * ENTRY:
  197. * pTd (input)
  198. * Pointer to td data structure
  199. * pSdIoctl (input/output)
  200. * input - ICA_STACK_CALLBACK
  201. * output - nothing
  202. *
  203. * EXIT:
  204. * STATUS_SUCCESS - no error
  205. *
  206. ******************************************************************************/
  207. NTSTATUS
  208. StackCallbackInitiate( PTD pTd, PSD_IOCTL pSdIoctl )
  209. {
  210. NTSTATUS Status;
  211. TRACE(( pTd->pContext, TC_TD, TT_API1,
  212. "TD: StackCallbackInitiate: entry\n" ));
  213. pTd->fCallbackInProgress = TRUE;
  214. return( STATUS_SUCCESS );
  215. }
  216. /*******************************************************************************
  217. *
  218. * StackCallbackComplete IOCTL_ICA_STACK_CALLBACK_COMPLETE
  219. *
  220. *
  221. * ENTRY:
  222. * pTd (input)
  223. * Pointer to td data structure
  224. * pSdIoctl (input/output)
  225. * input - nothing
  226. * output - nothing
  227. *
  228. * EXIT:
  229. * STATUS_SUCCESS - no error
  230. *
  231. ******************************************************************************/
  232. NTSTATUS
  233. StackCallbackComplete( PTD pTd, PSD_IOCTL pSdIoctl )
  234. {
  235. NTSTATUS Status;
  236. TRACE(( pTd->pContext, TC_TD, TT_API1,
  237. "TD: StackCallbackComplete: entry\n" ));
  238. pTd->fCallbackInProgress = FALSE;
  239. /*
  240. * Create the input thread if one is not running.
  241. */
  242. if ( pTd->pInputThread ) {
  243. Status = IcaWaitForSingleObject( pTd->pContext,
  244. pTd->pInputThread, 0 );
  245. if ( Status != STATUS_TIMEOUT) { // if input thread not running
  246. /*
  247. * The old input thread has gone away, but hasn't
  248. * been cleaned up. Clean it up now.
  249. */
  250. ObDereferenceObject( pTd->pInputThread );
  251. pTd->pInputThread = NULL;
  252. }
  253. }
  254. if ( !pTd->pInputThread ) {
  255. Status = _TdCreateInputThread( pTd );
  256. if ( !NT_SUCCESS(Status) )
  257. goto badthreadcreate;
  258. }
  259. return( STATUS_SUCCESS );
  260. badthreadcreate:
  261. return( Status );
  262. }
  263. /*******************************************************************************
  264. *
  265. * StackOpenEndpoint IOCTL_ICA_STACK_OPEN_ENDPOINT
  266. *
  267. * Open an existing transport endpoint
  268. *
  269. * The endpoint structure contains everything necessary to preserve
  270. * a client connection across a transport driver unload and reload.
  271. *
  272. * This routine will bind to an existing endpoint which is passed as
  273. * the input parameter.
  274. *
  275. * NOTE: The endpoint structure is an opaque, variable length data
  276. * structure whose length and contents are determined by the
  277. * transport driver.
  278. *
  279. *
  280. * ENTRY:
  281. * pTd (input)
  282. * Pointer to td data structure
  283. * pSdIoctl (input/output)
  284. * input - <endpoint data>
  285. * output - nothing
  286. *
  287. * EXIT:
  288. * STATUS_SUCCESS - no error
  289. *
  290. ******************************************************************************/
  291. NTSTATUS
  292. StackOpenEndpoint( PTD pTd, PSD_IOCTL pSdIoctl )
  293. {
  294. NTSTATUS Status;
  295. /*
  296. * Initialize transport driver endpoint
  297. */
  298. Status = DeviceOpenEndpoint( pTd,
  299. pSdIoctl->InputBuffer,
  300. pSdIoctl->InputBufferLength );
  301. if ( !NT_SUCCESS(Status) )
  302. goto badopen;
  303. /*
  304. * Create the input thread now.
  305. */
  306. Status = _TdCreateInputThread( pTd );
  307. if ( !NT_SUCCESS(Status) )
  308. goto badthreadcreate;
  309. TRACE(( pTd->pContext, TC_TD, TT_API1, "TD: StackOpenEndpoint, success\n" ));
  310. return( STATUS_SUCCESS );
  311. /*=============================================================================
  312. == Error returns
  313. =============================================================================*/
  314. /*
  315. * thread create failed - we used to close the endpoint, however TermSrv
  316. * does not expect this and would do a double free. Now we just rely on
  317. * TermSrv to turn around and close the endpoint.
  318. */
  319. badthreadcreate:
  320. // (void) DeviceCloseEndpoint( pTd );
  321. /*
  322. * endpoint open failed
  323. */
  324. badopen:
  325. TRACE(( pTd->pContext, TC_TD, TT_ERROR, "TD: StackOpenEndpoint, Status=0x%x\n", Status ));
  326. return( Status );
  327. }
  328. /*******************************************************************************
  329. *
  330. * StackCloseEndpoint IOCTL_ICA_STACK_CLOSE_ENDPOINT
  331. *
  332. * Close transport endpoint
  333. *
  334. * This will terminate any client connection
  335. *
  336. *
  337. * ENTRY:
  338. * pTd (input)
  339. * Pointer to td data structure
  340. * pSdIoctl (input/output)
  341. * input - nothing
  342. * output - nothing
  343. *
  344. * EXIT:
  345. * STATUS_SUCCESS - no error
  346. *
  347. ******************************************************************************/
  348. NTSTATUS
  349. StackCloseEndpoint( PTD pTd, PSD_IOCTL pSdIoctl )
  350. {
  351. NTSTATUS Status;
  352. /*
  353. * Close transport driver endpoint
  354. */
  355. Status = DeviceCloseEndpoint( pTd );
  356. if ( !NT_SUCCESS(Status) )
  357. goto badclose;
  358. TRACE(( pTd->pContext, TC_TD, TT_API1, "TD: StackCloseEndpoint: success\n" ));
  359. return( STATUS_SUCCESS );
  360. /*=============================================================================
  361. == Error returns
  362. =============================================================================*/
  363. /*
  364. * endpoint close failed
  365. */
  366. badclose:
  367. TRACE(( pTd->pContext, TC_TD, TT_ERROR, "TD: StackCloseEndpoint: 0x%x\n", Status ));
  368. return( Status );
  369. }
  370. /*******************************************************************************
  371. *
  372. * StackConnectionWait IOCTL_ICA_STACK_CONNECTION_WAIT
  373. *
  374. * Waits for a new client connection
  375. *
  376. * After the transport driver is loaded and StackCreateEndpoint is called
  377. * this routine is called to wait for a new client connection.
  378. *
  379. * If an endpoint does not yet exist, DeviceConnectionWait will create one
  380. * when the client connects.
  381. *
  382. * Changed 02/18/97 JohnR:
  383. *
  384. * This routine returns an opaque 32 bit handle to a data structure that
  385. * is maintained by ICADD.SYS. This data structure allows the transport
  386. * driver to maintain specific state information in a secure manner.
  387. *
  388. * This state information is only known to the transport driver.
  389. *
  390. * ENTRY:
  391. * pTd (input)
  392. * Pointer to td data structure
  393. * pSdIoctl (input/output)
  394. * input - nothing
  395. * output - <endpoint data>
  396. *
  397. * EXIT:
  398. * STATUS_SUCCESS - no error
  399. *
  400. ******************************************************************************/
  401. NTSTATUS
  402. StackConnectionWait( PTD pTd, PSD_IOCTL pSdIoctl )
  403. {
  404. NTSTATUS Status;
  405. TRACE(( pTd->pContext, TC_TD, TT_API1, "TD: StackConnectionWait: enter\n" ));
  406. /*
  407. * Initialize return byte count
  408. * - size of returned endpoint structure
  409. */
  410. pSdIoctl->BytesReturned = 0;
  411. /*
  412. * Wait for physical connection
  413. *
  414. * - DeviceConnectionWait should check OutputBufferLength to make
  415. * sure it's long enough to return an endpoint structure before
  416. * blocking.
  417. */
  418. Status = DeviceConnectionWait( pTd,
  419. pSdIoctl->OutputBuffer,
  420. pSdIoctl->OutputBufferLength,
  421. &pSdIoctl->BytesReturned );
  422. if ( !NT_SUCCESS(Status) )
  423. goto badwait;
  424. TRACE(( pTd->pContext, TC_TD, TT_API1, "TD: StackConnectionWait: success\n" ));
  425. return( STATUS_SUCCESS );
  426. /*=============================================================================
  427. == Error returns
  428. =============================================================================*/
  429. /*
  430. * thread create failed
  431. * Wait failed
  432. */
  433. badwait:
  434. TRACE(( pTd->pContext, TC_TD, TT_ERROR, "TD: StackConnectionWait: Status=0x%x\n", Status ));
  435. return( Status );
  436. }
  437. /*******************************************************************************
  438. *
  439. * StackConnectionSend IOCTL_ICA_STACK_CONNECTION_SEND
  440. *
  441. * Initialize transport driver module data to send to the client
  442. *
  443. *
  444. * ENTRY:
  445. * pTd (input)
  446. * Pointer to td data structure
  447. * pSdIoctl (input/output)
  448. * input - nothing
  449. * output - nothing
  450. *
  451. * EXIT:
  452. * STATUS_SUCCESS - no error
  453. *
  454. ******************************************************************************/
  455. NTSTATUS
  456. StackConnectionSend( PTD pTd, PSD_IOCTL pSdIoctl )
  457. {
  458. return( DeviceConnectionSend( pTd ) );
  459. }
  460. /*******************************************************************************
  461. *
  462. * StackConnectionRequest IOCTL_ICA_STACK_CONNECTION_REQUEST
  463. *
  464. * Initiate a connection to the specified remote address
  465. *
  466. * - this routine is only used by shadow
  467. *
  468. * DeviceConnectionRequest will create a new endpoint after establishing
  469. * a connection.
  470. *
  471. * This routine returns the endpoint data structure. The endpoint structure
  472. * contains everything necessary to preserve a connection across a transport
  473. * driver unload and reload.
  474. *
  475. * NOTE: The endpoint structure is an opaque, variable length data
  476. * structure whose length and contents are determined by the
  477. * transport driver.
  478. *
  479. *
  480. * typedef struct _ICA_STACK_ADDRESS {
  481. * BYTE Address[MAX_BR_ADDRESS]; // bytes 0,1 family, 2-n address
  482. * } ICA_STACK_ADDRESS, *PICA_STACK_ADDRESS;
  483. *
  484. *
  485. * ENTRY:
  486. * pTd (input)
  487. * Pointer to td data structure
  488. * pSdIoctl (input/output)
  489. * input - ICA_STACK_ADDRESS (remote address)
  490. * output - <endpoint data>
  491. *
  492. * EXIT:
  493. * STATUS_SUCCESS - no error
  494. *
  495. ******************************************************************************/
  496. NTSTATUS
  497. StackConnectionRequest( PTD pTd, PSD_IOCTL pSdIoctl )
  498. {
  499. NTSTATUS Status;
  500. if ( pSdIoctl->InputBufferLength < sizeof(ICA_STACK_ADDRESS) ) {
  501. Status = STATUS_BUFFER_TOO_SMALL;
  502. goto badbuffer;
  503. }
  504. /*
  505. * Establish physical connection
  506. *
  507. * - DeviceConnectionRequest should check OutputBufferLength to make
  508. * sure it is long enough to return an endpoint structure before
  509. * making a connection.
  510. */
  511. Status = DeviceConnectionRequest( pTd,
  512. pSdIoctl->InputBuffer,
  513. pSdIoctl->OutputBuffer,
  514. pSdIoctl->OutputBufferLength,
  515. &pSdIoctl->BytesReturned );
  516. if ( !NT_SUCCESS(Status) )
  517. goto badrequest;
  518. /*
  519. * Create input thread
  520. */
  521. Status = _TdCreateInputThread( pTd );
  522. if ( !NT_SUCCESS(Status) )
  523. goto badthreadcreate;
  524. TRACE(( pTd->pContext, TC_TD, TT_API1, "TD: StackConnectionRequest: success\n" ));
  525. return( STATUS_SUCCESS );
  526. /*=============================================================================
  527. == Error returns
  528. =============================================================================*/
  529. /*
  530. * thread create failed
  531. * connection request failed
  532. * buffer too small
  533. */
  534. badthreadcreate:
  535. badrequest:
  536. badbuffer:
  537. TRACE(( pTd->pContext, TC_TD, TT_ERROR, "TD: StackConnectionRequest: Status=0x%x\n", Status ));
  538. return( Status );
  539. }
  540. /*******************************************************************************
  541. *
  542. * StackQueryParams IOCTL_ICA_STACK_QUERY_PARAMS
  543. *
  544. * query transport driver parameters
  545. *
  546. *
  547. * ENTRY:
  548. * pTd (input)
  549. * Pointer to td data structure
  550. * pSdIoctl (input/output)
  551. * input - SDCLASS
  552. * output - PDPARAMS
  553. *
  554. * EXIT:
  555. * STATUS_SUCCESS - no error
  556. *
  557. ******************************************************************************/
  558. NTSTATUS
  559. StackQueryParams( PTD pTd, PSD_IOCTL pSdIoctl )
  560. {
  561. PPDPARAMS pParams;
  562. if ( pSdIoctl->InputBufferLength < sizeof(SDCLASS) ||
  563. pSdIoctl->OutputBufferLength < sizeof(PDPARAMS) ) {
  564. return( STATUS_BUFFER_TOO_SMALL );
  565. }
  566. pParams = pSdIoctl->OutputBuffer;
  567. *pParams = pTd->Params;
  568. pSdIoctl->BytesReturned = sizeof(PDPARAMS);
  569. return( STATUS_SUCCESS );
  570. }
  571. /*******************************************************************************
  572. *
  573. * StackQueryRemoteAddress IOCTL_TS_STACK_QUERY_REMOTEADDRESS
  574. *
  575. * query for the remote address
  576. *
  577. *
  578. * ENTRY:
  579. * pTd (input)
  580. * Pointer to td data structure
  581. * pSdIoctl (input/output)
  582. * input - endpoint data
  583. * output - sockaddr
  584. *
  585. * EXIT:
  586. * STATUS_SUCCESS - no error
  587. *
  588. ******************************************************************************/
  589. NTSTATUS
  590. StackQueryRemoteAddress( PTD pTd, PSD_IOCTL pSdIoctl )
  591. {
  592. NTSTATUS Status;
  593. Status = DeviceQueryRemoteAddress( pTd,
  594. pSdIoctl->InputBuffer,
  595. pSdIoctl->InputBufferLength,
  596. pSdIoctl->OutputBuffer,
  597. pSdIoctl->OutputBufferLength,
  598. &pSdIoctl->BytesReturned );
  599. if ( !NT_SUCCESS(Status) )
  600. {
  601. TRACE(( pTd->pContext, TC_TD, TT_ERROR, "TD: StackQueryRemoteAddress: 0x%\n", Status ));
  602. }
  603. return Status;
  604. }
  605. /*******************************************************************************
  606. *
  607. * StackQueryLocalIPAddress IOCTL_ICA_STACK_QUERY_LOCALIPADDRESS
  608. *
  609. * query for the RDP-Enabled IP Address
  610. *
  611. *
  612. * ENTRY:
  613. * pTd (input)
  614. * Pointer to td data structure
  615. * pSdIoctl (output)
  616. * input - no
  617. * output - ULONG (IP Address)
  618. *
  619. * EXIT:
  620. * STATUS_SUCCESS - no error
  621. *
  622. ******************************************************************************/
  623. NTSTATUS
  624. StackQueryLocalAddress( PTD pTd, PSD_IOCTL pSdIoctl )
  625. {
  626. NTSTATUS Status;
  627. Status = DeviceQueryLocalAddress( pTd,
  628. pSdIoctl->OutputBuffer,
  629. pSdIoctl->OutputBufferLength,
  630. &pSdIoctl->BytesReturned );
  631. if ( !NT_SUCCESS(Status) )
  632. {
  633. TRACE(( pTd->pContext, TC_TD, TT_ERROR, "TD: StackQueryLocalIP: 0x%\n", Status ));
  634. }
  635. return Status;
  636. }
  637. /*******************************************************************************
  638. *
  639. * StackSetParams IOCTL_ICA_STACK_SET_PARAMS
  640. *
  641. * set transport driver parameters
  642. *
  643. *
  644. * ENTRY:
  645. * pTd (input)
  646. * Pointer to td data structure
  647. * pSdIoctl (input/output)
  648. * input - PDPARAMS
  649. * output - nothing
  650. *
  651. * EXIT:
  652. * STATUS_SUCCESS - no error
  653. *
  654. ******************************************************************************/
  655. NTSTATUS
  656. StackSetParams( PTD pTd, PSD_IOCTL pSdIoctl )
  657. {
  658. PPDPARAMS pParams;
  659. if ( pSdIoctl->InputBufferLength < sizeof(PDPARAMS) ) {
  660. return( STATUS_BUFFER_TOO_SMALL );
  661. }
  662. pParams = pSdIoctl->InputBuffer;
  663. pTd->Params = *pParams;
  664. return( DeviceSetParams( pTd ) );
  665. }
  666. /*******************************************************************************
  667. *
  668. * StackQueryLastError IOCTL_ICA_STACK_QUERY_LAST_ERROR
  669. *
  670. * Query transport driver error code and message
  671. *
  672. * typedef struct _ICA_STACK_LAST_ERROR {
  673. * ULONG Error;
  674. * CHAR Message[ MAX_ERRORMESSAGE ];
  675. * } ICA_STACK_LAST_ERROR, *PICA_STACK_LAST_ERROR;
  676. *
  677. *
  678. * ENTRY:
  679. * pTd (input)
  680. * Pointer to td data structure
  681. * pSdIoctl (input/output)
  682. * input - nothing
  683. * output - ICA_STACK_LAST_ERROR
  684. *
  685. * EXIT:
  686. * STATUS_SUCCESS - no error
  687. *
  688. ******************************************************************************/
  689. NTSTATUS
  690. StackQueryLastError( PTD pTd, PSD_IOCTL pSdIoctl )
  691. {
  692. if ( pSdIoctl->OutputBufferLength < sizeof(ICA_STACK_LAST_ERROR) ) {
  693. return( STATUS_BUFFER_TOO_SMALL );
  694. }
  695. pSdIoctl->BytesReturned = sizeof(ICA_STACK_LAST_ERROR);
  696. return( DeviceGetLastError( pTd, pSdIoctl->OutputBuffer ) );
  697. }
  698. /*******************************************************************************
  699. *
  700. * StackWaitForStatus IOCTL_ICA_STACK_WAIT_FOR_STATUS
  701. *
  702. * Wait for transport driver status to change
  703. * - only supported by async transport driver to wait for rs232 signal change
  704. *
  705. *
  706. * ENTRY:
  707. * pTd (input)
  708. * Pointer to td data structure
  709. * pSdIoctl (input/output)
  710. * input - nothing
  711. * output - nothing
  712. *
  713. * EXIT:
  714. * STATUS_SUCCESS - no error
  715. *
  716. ******************************************************************************/
  717. NTSTATUS
  718. StackWaitForStatus( PTD pTd, PSD_IOCTL pSdIoctl )
  719. {
  720. /*
  721. * Check if driver is being closed
  722. */
  723. if ( pTd->fClosing )
  724. return( STATUS_CTX_CLOSE_PENDING );
  725. return( DeviceWaitForStatus( pTd ) );
  726. }
  727. /*******************************************************************************
  728. *
  729. * StackCancelIo IOCTL_ICA_STACK_CANCEL_IO
  730. *
  731. * cancel all current and future transport driver i/o
  732. *
  733. * NOTE: no more i/o can be done after StackCancelIo is called.
  734. * The transport driver must be unloaded and reloaded to
  735. * re-enable i/o.
  736. *
  737. *
  738. * ENTRY:
  739. * pTd (input)
  740. * Pointer to td data structure
  741. * pSdIoctl (input/output)
  742. * input - nothing
  743. * output - nothing
  744. *
  745. * EXIT:
  746. * STATUS_SUCCESS - no error
  747. *
  748. ******************************************************************************/
  749. NTSTATUS
  750. StackCancelIo( PTD pTd, PSD_IOCTL pSdIoctl )
  751. {
  752. PLIST_ENTRY Head, Next;
  753. NTSTATUS Status;
  754. TRACE(( pTd->pContext, TC_TD, TT_API1, "TD: StackCancelIo (enter)\n" ));
  755. /*
  756. * Set stack closing flag
  757. */
  758. pTd->fClosing = TRUE;
  759. /*
  760. * Clear error thresholds now
  761. */
  762. pTd->ReadErrorThreshold = 0;
  763. pTd->WriteErrorThreshold = 0;
  764. /*
  765. * Call device specific cancel I/O routine
  766. */
  767. Status = DeviceCancelIo( pTd );
  768. ASSERT( Status == STATUS_SUCCESS );
  769. /*
  770. * Wait for all writes to complete
  771. */
  772. Status = TdSyncWrite( pTd, NULL );
  773. ASSERT( Status == STATUS_SUCCESS );
  774. TRACE(( pTd->pContext, TC_TD, TT_API1, "TD: StackCancelIo, %u (exit)\n", Status ));
  775. return( Status );
  776. }
  777. /*******************************************************************************
  778. *
  779. * StackSetBrokenReason IOCTL_ICA_STACK_SET_BROKENREASON
  780. *
  781. * Store a broken reason for later use (when reporting back up the stack)
  782. *
  783. * NOTE: Does not break the connection
  784. *
  785. *
  786. * ENTRY:
  787. * pTd (input)
  788. * Pointer to td data structure
  789. * pSdIoctl (input/output)
  790. * input - ICA_STACK_BROKENREASON
  791. * output - nothing
  792. *
  793. * EXIT:
  794. * STATUS_SUCCESS - no error
  795. *
  796. ******************************************************************************/
  797. NTSTATUS
  798. StackSetBrokenReason( PTD pTd, PSD_IOCTL pSdIoctl )
  799. {
  800. PICA_STACK_BROKENREASON pBrkReason;
  801. TRACE(( pTd->pContext, TC_TD, TT_API1,
  802. "TD: StackSetBrokenReason (enter)\n" ));
  803. if ( pSdIoctl->InputBufferLength < sizeof(ICA_STACK_BROKENREASON) ) {
  804. return( STATUS_BUFFER_TOO_SMALL );
  805. }
  806. pBrkReason = pSdIoctl->InputBuffer;
  807. pTd->UserBrokenReason = pBrkReason->BrokenReason;
  808. TRACE(( pTd->pContext, TC_TD, TT_API1,
  809. "TD: StackSetBrokenReason, %u (exit)\n", STATUS_SUCCESS ));
  810. return STATUS_SUCCESS;
  811. }
  812. /*******************************************************************************
  813. *
  814. * _TdCreateInputThread
  815. *
  816. * Start the input thread running.
  817. *
  818. *
  819. * ENTRY:
  820. * pTd (input)
  821. * Pointer to td data structure
  822. *
  823. * EXIT:
  824. * STATUS_SUCCESS - no error
  825. *
  826. ******************************************************************************/
  827. NTSTATUS
  828. _TdCreateInputThread( PTD pTd )
  829. {
  830. HANDLE hInputThread;
  831. NTSTATUS Status;
  832. /*
  833. * Create input thread
  834. */
  835. Status = IcaCreateThread( pTd->pContext,
  836. TdInputThread,
  837. pTd,
  838. ICALOCK_DRIVER,
  839. &hInputThread );
  840. if ( !NT_SUCCESS(Status) )
  841. return( Status );
  842. /*
  843. * Convert thread handle to pointer reference
  844. */
  845. Status = ObReferenceObjectByHandle( hInputThread,
  846. THREAD_ALL_ACCESS,
  847. NULL,
  848. KernelMode,
  849. &pTd->pInputThread,
  850. NULL );
  851. (VOID) ZwClose( hInputThread );
  852. if ( !NT_SUCCESS( Status ) ) {
  853. (VOID) StackCancelIo( pTd, NULL );
  854. }
  855. return( Status );
  856. }