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.

1153 lines
24 KiB

  1. /*++
  2. Copyright (c) 1998-2000 Microsoft Corporation
  3. Module Name:
  4. DrPRT
  5. Abstract:
  6. This module defines methods for the DrPRT class.
  7. The job of the DrPRT class is to translate IO requests received
  8. from the TS server into communications (serial/parallel) port IO
  9. functions and to handle generic IO port functionality in a
  10. platform-independent way to promote reuse between the various TS
  11. client platforms, with respect to implementing comm port
  12. redirection.
  13. Subclasses of DrPRT will implement the specific comm functions
  14. for their respective platform.
  15. Author:
  16. Tad Brockway 5/26/99
  17. Revision History:
  18. --*/
  19. #include <precom.h>
  20. #define TRC_FILE "DrPRT"
  21. #include <stdarg.h>
  22. #include "drprt.h"
  23. #include "drdbg.h"
  24. #include "utl.h"
  25. ///////////////////////////////////////////////////////////////
  26. //
  27. // DrPRT Methods
  28. //
  29. //
  30. DrPRT::DrPRT(const DRSTRING portName,
  31. ProcObj *processObject) : _isValid(TRUE)
  32. /*++
  33. Routine Description:
  34. Constructor
  35. Arguments:
  36. processObject - Associated Process Object
  37. portName - Name of the port.
  38. deviceID - Device ID for the port.
  39. devicePath - Path that can be opened via CreateFile for port.
  40. Return Value:
  41. NA
  42. --*/
  43. {
  44. ULONG len;
  45. HRESULT hr;
  46. DC_BEGIN_FN("DrPRT::DrPRT");
  47. //
  48. // Initialize data members.
  49. //
  50. _traceFile = NULL;
  51. _procObj = processObject;
  52. //
  53. // Record the port name.
  54. //
  55. ASSERT(portName != NULL);
  56. len = (STRLEN(portName) + 1);
  57. _portName = new TCHAR[len];
  58. if (_portName != NULL) {
  59. hr = StringCchCopy(_portName, len, portName);
  60. TRC_ASSERT(SUCCEEDED(hr),
  61. (TB,_T("Pre-checked str copy failed: 0x%x"), hr));
  62. }
  63. //
  64. // Check and record our status,
  65. //
  66. if (_portName == NULL) {
  67. TRC_ERR((TB, _T("Memory allocation failed.")));
  68. SetValid(FALSE);
  69. }
  70. DC_END_FN();
  71. }
  72. DrPRT::~DrPRT()
  73. /*++
  74. Routine Description:
  75. Destructor
  76. Arguments:
  77. NA
  78. Return Value:
  79. NA
  80. --*/
  81. {
  82. DC_BEGIN_FN("DrPRT::~DrPRT");
  83. //
  84. // Release the port name.
  85. //
  86. if (_portName != NULL) {
  87. delete _portName;
  88. }
  89. //
  90. // Close the trace log.
  91. //
  92. if (_traceFile != NULL) {
  93. fclose(_traceFile);
  94. }
  95. DC_END_FN();
  96. }
  97. VOID DrPRT::GetDevAnnounceData(
  98. IN PRDPDR_DEVICE_ANNOUNCE pDeviceAnnounce,
  99. IN ULONG deviceID,
  100. IN ULONG deviceType
  101. )
  102. /*++
  103. Routine Description:
  104. Add a device announce packet for this device to the input buffer.
  105. Arguments:
  106. pDeviceAnnounce - Device Announce Buf for this Device
  107. deviceID - ID of port device. This is a field in the
  108. Device Announce Buf.
  109. deviceType - Type of port device.
  110. Return Value:
  111. NA
  112. --*/
  113. {
  114. DC_BEGIN_FN("DrPRT::GetDevAnnounceData");
  115. ASSERT(IsValid());
  116. if (!IsValid()) {
  117. DC_END_FN();
  118. return;
  119. }
  120. //
  121. // Record the device ID.
  122. //
  123. pDeviceAnnounce->DeviceType = deviceType;
  124. pDeviceAnnounce->DeviceId = deviceID;
  125. //
  126. // Record the port name in ANSI.
  127. //
  128. #ifdef UNICODE
  129. RDPConvertToAnsi(_portName, (LPSTR)pDeviceAnnounce->PreferredDosName,
  130. sizeof(pDeviceAnnounce->PreferredDosName)
  131. );
  132. #else
  133. STRCPY((char *)pDeviceAnnounce->PreferredDosName, _portName);
  134. #endif
  135. DC_END_FN();
  136. }
  137. ULONG DrPRT::GetDevAnnounceDataSize()
  138. /*++
  139. Routine Description:
  140. Return the size (in bytes) of a device announce packet for
  141. this device.
  142. Arguments:
  143. NA
  144. Return Value:
  145. The size (in bytes) of a device announce packet for this device.
  146. --*/
  147. {
  148. ULONG size;
  149. DC_BEGIN_FN("DrPRT::GetDevAnnounceDataSize");
  150. ASSERT(IsValid());
  151. if (!IsValid()) {
  152. DC_END_FN();
  153. return 0;
  154. }
  155. size = 0;
  156. //
  157. // Add the base announce size.
  158. //
  159. size += sizeof(RDPDR_DEVICE_ANNOUNCE);
  160. DC_END_FN();
  161. return size;
  162. }
  163. BOOL
  164. DrPRT::MsgIrpDeviceControlTranslate(
  165. IN PRDPDR_IOREQUEST_PACKET pIoRequest
  166. )
  167. /*++
  168. Routine Description:
  169. Handle Port IOCTL IRP's from the server and translate to
  170. the appropriate subclass-implemented IO function.
  171. Arguments:
  172. pIoRequestPacket - Request packet received from server.
  173. Return Value:
  174. Returns TRUE if there was a valid translation. Otherwise,
  175. FALSE is returned.
  176. --*/
  177. {
  178. BOOL result = TRUE;
  179. DC_BEGIN_FN("DrPRT::MsgIrpDeviceControlTranslate");
  180. //
  181. // Dispatch the IOCTL to a subclass-implemented function.
  182. // This would be faster if it were table-driven.
  183. //
  184. switch (pIoRequest->IoRequest.Parameters.DeviceIoControl.IoControlCode) {
  185. case IOCTL_SERIAL_SET_BAUD_RATE :
  186. SerialSetBaudRate(pIoRequest);
  187. break;
  188. case IOCTL_SERIAL_GET_BAUD_RATE :
  189. SerialGetBaudRate(pIoRequest);
  190. break;
  191. case IOCTL_SERIAL_SET_LINE_CONTROL :
  192. SerialSetLineControl(pIoRequest);
  193. break;
  194. case IOCTL_SERIAL_GET_LINE_CONTROL :
  195. SerialGetLineControl(pIoRequest);
  196. break;
  197. case IOCTL_SERIAL_SET_TIMEOUTS :
  198. SerialSetTimeouts(pIoRequest);
  199. break;
  200. case IOCTL_SERIAL_GET_TIMEOUTS :
  201. SerialGetTimeouts(pIoRequest);
  202. break;
  203. case IOCTL_SERIAL_SET_CHARS :
  204. SerialSetChars(pIoRequest);
  205. break;
  206. case IOCTL_SERIAL_GET_CHARS :
  207. SerialGetChars(pIoRequest);
  208. break;
  209. case IOCTL_SERIAL_SET_DTR :
  210. SerialSetDTR(pIoRequest);
  211. break;
  212. case IOCTL_SERIAL_CLR_DTR :
  213. SerialClearDTR(pIoRequest);
  214. break;
  215. case IOCTL_SERIAL_RESET_DEVICE :
  216. SerialResetDevice(pIoRequest);
  217. break;
  218. case IOCTL_SERIAL_SET_RTS :
  219. SerialSetRTS(pIoRequest);
  220. break;
  221. case IOCTL_SERIAL_CLR_RTS :
  222. SerialClearRTS(pIoRequest);
  223. break;
  224. case IOCTL_SERIAL_SET_XOFF :
  225. SerialSetXOff(pIoRequest);
  226. break;
  227. case IOCTL_SERIAL_SET_XON :
  228. SerialSetXon(pIoRequest);
  229. break;
  230. case IOCTL_SERIAL_SET_BREAK_ON :
  231. SerialSetBreakOn(pIoRequest);
  232. break;
  233. case IOCTL_SERIAL_SET_BREAK_OFF :
  234. SerialSetBreakOff(pIoRequest);
  235. break;
  236. case IOCTL_SERIAL_SET_QUEUE_SIZE :
  237. SerialSetQueueSize(pIoRequest);
  238. break;
  239. case IOCTL_SERIAL_GET_WAIT_MASK :
  240. SerialGetWaitMask(pIoRequest);
  241. break;
  242. case IOCTL_SERIAL_SET_WAIT_MASK :
  243. SerialSetWaitMask(pIoRequest);
  244. break;
  245. case IOCTL_SERIAL_WAIT_ON_MASK :
  246. SerialWaitOnMask(pIoRequest);
  247. break;
  248. case IOCTL_SERIAL_IMMEDIATE_CHAR :
  249. SerialImmediateChar(pIoRequest);
  250. break;
  251. case IOCTL_SERIAL_PURGE :
  252. SerialPurge(pIoRequest);
  253. break;
  254. case IOCTL_SERIAL_GET_HANDFLOW :
  255. SerialGetHandflow(pIoRequest);
  256. break;
  257. case IOCTL_SERIAL_SET_HANDFLOW :
  258. SerialSetHandflow(pIoRequest);
  259. break;
  260. case IOCTL_SERIAL_GET_MODEMSTATUS :
  261. SerialGetModemStatus(pIoRequest);
  262. break;
  263. case IOCTL_SERIAL_GET_DTRRTS :
  264. SerialGetDTRRTS(pIoRequest);
  265. break;
  266. case IOCTL_SERIAL_GET_COMMSTATUS :
  267. SerialGetCommStatus(pIoRequest);
  268. break;
  269. case IOCTL_SERIAL_GET_PROPERTIES :
  270. SerialGetProperties(pIoRequest);
  271. break;
  272. case IOCTL_SERIAL_XOFF_COUNTER :
  273. SerialXoffCounter(pIoRequest);
  274. break;
  275. case IOCTL_SERIAL_LSRMST_INSERT :
  276. SerialLSRMSTInsert(pIoRequest);
  277. break;
  278. case IOCTL_SERIAL_CONFIG_SIZE :
  279. SerialConfigSize(pIoRequest);
  280. break;
  281. case IOCTL_SERIAL_GET_COMMCONFIG :
  282. SerialGetConfig(pIoRequest);
  283. break;
  284. case IOCTL_SERIAL_GET_STATS :
  285. SerialGetStats(pIoRequest);
  286. break;
  287. case IOCTL_SERIAL_CLEAR_STATS :
  288. SerialClearStats(pIoRequest);
  289. break;
  290. default:
  291. TRC_DBG((TB, _T("Unknown IOCTL %08X"),
  292. pIoRequest->IoRequest.Parameters.DeviceIoControl.IoControlCode));
  293. result = FALSE;
  294. }
  295. DC_END_FN();
  296. return result;
  297. }
  298. void
  299. DrPRT::SerialSetBaudRate(
  300. IN PRDPDR_IOREQUEST_PACKET pIoReq
  301. )
  302. /*++
  303. Routine Description:
  304. Handle Serial Port Set Baud Rate Request from Server.
  305. Arguments:
  306. pIoReq - Request packet received from server.
  307. Return Value:
  308. NA
  309. --*/
  310. {
  311. PBYTE inputBuf;
  312. NTSTATUS status = STATUS_SUCCESS;
  313. DCB dcb;
  314. PRDPDR_DEVICE_IOREQUEST pIoRequest;
  315. DRPORTHANDLE FileHandle;
  316. DC_BEGIN_FN("DrPRT::SerialSetBaudRate");
  317. TRACEREQ(pIoReq);
  318. //
  319. // Get IO request pointer.
  320. //
  321. pIoRequest = &pIoReq->IoRequest;
  322. //
  323. // Get Port Handle
  324. //
  325. FileHandle = GetPortHandle(pIoRequest->FileId);
  326. ASSERT(FileHandle != INVALID_TSPORTHANDLE);
  327. //
  328. // Check the size of the incoming request.
  329. //
  330. status = DrUTL_CheckIOBufInputSize(pIoReq, sizeof(SERIAL_BAUD_RATE));
  331. //
  332. // Get a pointer to the input buffer.
  333. //
  334. inputBuf = (PBYTE)(pIoReq + 1);
  335. //
  336. // Get the current DCB.
  337. //
  338. if (status == STATUS_SUCCESS) {
  339. if (!GetCommState(FileHandle, &dcb)) {
  340. DWORD err = GetLastError();
  341. TRC_ALT((TB, _T("GetCommState failed with %08x"), err));
  342. status = TranslateWinError(err);
  343. }
  344. }
  345. //
  346. // Set the baud rate and update the DCB.
  347. //
  348. if (status == STATUS_SUCCESS) {
  349. dcb.BaudRate = ((PSERIAL_BAUD_RATE)inputBuf)->BaudRate;
  350. if (!SetCommState(FileHandle, &dcb)) {
  351. DWORD err = GetLastError();
  352. TRC_NRM((TB, _T("SetCommState failed with %08x"), err));
  353. status = TranslateWinError(err);
  354. }
  355. }
  356. TRACERESP_WITHPARAMS(pIoReq, NULL, 0, status);
  357. //
  358. // Send the results to the server.
  359. //
  360. DefaultIORequestMsgHandle(pIoReq, status);
  361. DC_END_FN();
  362. }
  363. void
  364. DrPRT::SerialGetBaudRate(
  365. IN PRDPDR_IOREQUEST_PACKET pIoReq
  366. )
  367. /*++
  368. Routine Description:
  369. Handle Serial Port Get Baud Rate Request from Server.
  370. Arguments:
  371. pIoReq - Request packet received from server.
  372. Return Value:
  373. NA
  374. --*/
  375. {
  376. PRDPDR_IOCOMPLETION_PACKET pReplyPacket = NULL;
  377. NTSTATUS status = STATUS_SUCCESS;
  378. DCB dcb;
  379. ULONG replyPacketSize;
  380. PBYTE outputBuf;
  381. PRDPDR_DEVICE_IOREQUEST pIoRequest;
  382. DRPORTHANDLE FileHandle;
  383. DC_BEGIN_FN("DrPRT::SerialGetBaudRate");
  384. TRACEREQ(pIoReq);
  385. //
  386. // Get IO request pointer.
  387. //
  388. pIoRequest = &pIoReq->IoRequest;
  389. //
  390. // Get Port Handle
  391. //
  392. FileHandle = GetPortHandle(pIoRequest->FileId);
  393. ASSERT(FileHandle != INVALID_TSPORTHANDLE);
  394. //
  395. // Check the size of the output buffer.
  396. //
  397. status = DrUTL_CheckIOBufOutputSize(pIoReq, sizeof(SERIAL_BAUD_RATE));
  398. //
  399. // Allocate reply buffer.
  400. //
  401. if (status == STATUS_SUCCESS) {
  402. status = DrUTL_AllocateReplyBuf(pIoReq, &pReplyPacket, &replyPacketSize);
  403. }
  404. //
  405. // Get the current DCB.
  406. //
  407. if (status == STATUS_SUCCESS) {
  408. //
  409. // Get a pointer to the output buffer.
  410. //
  411. outputBuf = pReplyPacket->IoCompletion.Parameters.DeviceIoControl.OutputBuffer;
  412. if (GetCommState(FileHandle, &dcb)) {
  413. ((PSERIAL_BAUD_RATE)outputBuf)->BaudRate = dcb.BaudRate;
  414. pReplyPacket->IoCompletion.Parameters.DeviceIoControl.OutputBufferLength
  415. = sizeof(SERIAL_BAUD_RATE);
  416. }
  417. else {
  418. DWORD err = GetLastError();
  419. TRC_ALT((TB, _T("GetCommState failed with %08x"), err));
  420. status = TranslateWinError(err);
  421. pReplyPacket->IoCompletion.Parameters.DeviceIoControl.OutputBufferLength
  422. = 0;
  423. replyPacketSize = (ULONG)FIELD_OFFSET(
  424. RDPDR_IOCOMPLETION_PACKET,
  425. IoCompletion.Parameters.DeviceIoControl.OutputBuffer);
  426. }
  427. //
  428. // Finish the response and send it.
  429. //
  430. pReplyPacket->IoCompletion.IoStatus = status;
  431. TRACERESP(pIoReq, pReplyPacket);
  432. ProcessObject()->GetVCMgr().ChannelWrite(pReplyPacket, replyPacketSize);
  433. }
  434. else {
  435. //
  436. // Send the results to the server.
  437. //
  438. TRACERESP_WITHPARAMS(pIoReq, NULL, 0, status);
  439. DefaultIORequestMsgHandle(pIoReq, status);
  440. }
  441. DC_END_FN();
  442. }
  443. void
  444. DrPRT::SerialSetLineControl(
  445. IN PRDPDR_IOREQUEST_PACKET pIoReq
  446. )
  447. /*++
  448. Routine Description:
  449. Handle Serial Port Set Set Line Control Request from Server.
  450. Arguments:
  451. pIoReq - Request packet received from server.
  452. Return Value:
  453. NA
  454. --*/
  455. {
  456. PBYTE inputBuf;
  457. NTSTATUS status = STATUS_SUCCESS;
  458. DCB dcb;
  459. PSERIAL_LINE_CONTROL lineControl;
  460. PRDPDR_DEVICE_IOREQUEST pIoRequest;
  461. DRPORTHANDLE FileHandle;
  462. DC_BEGIN_FN("DrPRT::SerialSetLineControl");
  463. TRACEREQ(pIoReq);
  464. //
  465. // Get IO request pointer.
  466. //
  467. pIoRequest = &pIoReq->IoRequest;
  468. //
  469. // Get Port Handle
  470. //
  471. FileHandle = GetPortHandle(pIoRequest->FileId);
  472. ASSERT(FileHandle != INVALID_TSPORTHANDLE);
  473. //
  474. // Check the size of the incoming request.
  475. //
  476. status = DrUTL_CheckIOBufInputSize(pIoReq, sizeof(SERIAL_LINE_CONTROL));
  477. //
  478. // Get a pointer to the input buffer.
  479. //
  480. inputBuf = (PBYTE)(pIoReq + 1);
  481. //
  482. // Get the current DCB.
  483. //
  484. if (status == STATUS_SUCCESS) {
  485. if (!GetCommState(FileHandle, &dcb)) {
  486. DWORD err = GetLastError();
  487. TRC_ALT((TB, _T("GetCommState failed with %08x"), err));
  488. status = TranslateWinError(err);
  489. }
  490. }
  491. //
  492. // Set the line control and update the DCB.
  493. //
  494. if (status == STATUS_SUCCESS) {
  495. lineControl = (PSERIAL_LINE_CONTROL)inputBuf;
  496. dcb.StopBits = lineControl->StopBits;
  497. dcb.Parity = lineControl->Parity;
  498. dcb.ByteSize = lineControl->WordLength;
  499. if (!SetCommState(FileHandle, &dcb)) {
  500. DWORD err = GetLastError();
  501. TRC_ALT((TB, _T("SetCommState failed with %08x"), err));
  502. status = TranslateWinError(err);
  503. }
  504. }
  505. //
  506. // Send the results to the server.
  507. //
  508. TRACERESP_WITHPARAMS(pIoReq, NULL, 0, status);
  509. DefaultIORequestMsgHandle(pIoReq, status);
  510. DC_END_FN();
  511. }
  512. void
  513. DrPRT::SerialGetLineControl(
  514. IN PRDPDR_IOREQUEST_PACKET pIoReq
  515. )
  516. /*++
  517. Routine Description:
  518. Handle Serial Port Get Line Control Rate Request from Server.
  519. Arguments:
  520. pIoReq - Request packet received from server.
  521. Return Value:
  522. NA
  523. --*/
  524. {
  525. PRDPDR_IOCOMPLETION_PACKET pReplyPacket = NULL;
  526. NTSTATUS status = STATUS_SUCCESS;
  527. DCB dcb;
  528. ULONG replyPacketSize;
  529. PBYTE outputBuf;
  530. PSERIAL_LINE_CONTROL lineControl;
  531. PRDPDR_DEVICE_IOREQUEST pIoRequest;
  532. DRPORTHANDLE FileHandle;
  533. DC_BEGIN_FN("DrPRT::SerialGetLineControl");
  534. TRACEREQ(pIoReq);
  535. //
  536. // Get IO request pointer.
  537. //
  538. pIoRequest = &pIoReq->IoRequest;
  539. //
  540. // Get Port Handle
  541. //
  542. FileHandle = GetPortHandle(pIoRequest->FileId);
  543. ASSERT(FileHandle != INVALID_TSPORTHANDLE);
  544. //
  545. // Check the size of the output buffer.
  546. //
  547. status = DrUTL_CheckIOBufOutputSize(pIoReq, sizeof(SERIAL_LINE_CONTROL));
  548. //
  549. // Allocate reply buffer.
  550. //
  551. if (status == STATUS_SUCCESS) {
  552. status = DrUTL_AllocateReplyBuf(pIoReq, &pReplyPacket, &replyPacketSize);
  553. }
  554. //
  555. // Get the current DCB and grab the line control params.
  556. //
  557. if (status == STATUS_SUCCESS) {
  558. //
  559. // Get a pointer to the output buffer and line control params.
  560. //
  561. outputBuf = pReplyPacket->IoCompletion.Parameters.DeviceIoControl.OutputBuffer;
  562. lineControl = (PSERIAL_LINE_CONTROL)outputBuf;
  563. if (GetCommState(FileHandle, &dcb)) {
  564. lineControl->StopBits = dcb.StopBits;
  565. lineControl->Parity = dcb.Parity;
  566. lineControl->WordLength = dcb.ByteSize;
  567. pReplyPacket->IoCompletion.Parameters.DeviceIoControl.OutputBufferLength
  568. = sizeof(SERIAL_LINE_CONTROL);
  569. }
  570. else {
  571. DWORD err = GetLastError();
  572. TRC_ALT((TB, _T("GetCommState failed with %08x"), err));
  573. status = TranslateWinError(err);
  574. pReplyPacket->IoCompletion.Parameters.DeviceIoControl.OutputBufferLength
  575. = 0;
  576. replyPacketSize = (ULONG)FIELD_OFFSET(
  577. RDPDR_IOCOMPLETION_PACKET,
  578. IoCompletion.Parameters.DeviceIoControl.OutputBuffer);
  579. }
  580. //
  581. // Finish the response and send it.
  582. //
  583. pReplyPacket->IoCompletion.IoStatus = status;
  584. TRACERESP(pIoReq, pReplyPacket);
  585. ProcessObject()->GetVCMgr().ChannelWrite(pReplyPacket, replyPacketSize);
  586. }
  587. else {
  588. //
  589. // Send the results to the server.
  590. //
  591. TRACERESP_WITHPARAMS(pIoReq, NULL, 0, status);
  592. DefaultIORequestMsgHandle(pIoReq, status);
  593. }
  594. DC_END_FN();
  595. }
  596. void
  597. DrPRT::SerialSetDTR(
  598. IN PRDPDR_IOREQUEST_PACKET pIoReq
  599. )
  600. /*++
  601. Routine Description:
  602. Handle Serial Port Set DTR Request from Server.
  603. Arguments:
  604. pIoReq - Request packet received from server.
  605. Return Value:
  606. NA
  607. --*/
  608. {
  609. DC_BEGIN_FN("DrPRT::SerialSetDTR");
  610. TRACEREQ(pIoReq);
  611. //
  612. // Send the escape code to the serial port.
  613. //
  614. SerialHandleEscapeCode(pIoReq, SETDTR);
  615. DC_END_FN();
  616. }
  617. void
  618. DrPRT::SerialClearDTR(
  619. IN PRDPDR_IOREQUEST_PACKET pIoReq
  620. )
  621. /*++
  622. Routine Description:
  623. Handle Serial Port Clear DTR Request from Server.
  624. Arguments:
  625. pIoReq - Request packet received from server.
  626. Return Value:
  627. NA
  628. --*/
  629. {
  630. DC_BEGIN_FN("DrPRT::SerialClearDTR");
  631. TRACEREQ(pIoReq);
  632. //
  633. // Send the escape code to the serial port.
  634. //
  635. SerialHandleEscapeCode(pIoReq, CLRDTR);
  636. DC_END_FN();
  637. }
  638. void
  639. DrPRT::SerialSetRTS(
  640. IN PRDPDR_IOREQUEST_PACKET pIoReq
  641. )
  642. /*++
  643. Routine Description:
  644. Handle Serial Port Set RTS Request from Server.
  645. Arguments:
  646. pIoReq - Request packet received from server.
  647. Return Value:
  648. NA
  649. --*/
  650. {
  651. DC_BEGIN_FN("DrPRT::SerialResetDevice");
  652. TRACEREQ(pIoReq);
  653. //
  654. // Send the escape code to the serial port.
  655. //
  656. SerialHandleEscapeCode(pIoReq, SETRTS);
  657. DC_END_FN();
  658. }
  659. void
  660. DrPRT::SerialClearRTS(
  661. IN PRDPDR_IOREQUEST_PACKET pIoReq
  662. )
  663. /*++
  664. Routine Description:
  665. Handle Serial Port Clear RTS Request from Server.
  666. Arguments:
  667. pIoReq - Request packet received from server.
  668. Return Value:
  669. NA
  670. --*/
  671. {
  672. DC_BEGIN_FN("DrPRT::SerialClearRTS");
  673. TRACEREQ(pIoReq);
  674. //
  675. // Send the escape code to the serial port.
  676. //
  677. SerialHandleEscapeCode(pIoReq, CLRRTS);
  678. DC_END_FN();
  679. }
  680. void
  681. DrPRT::SerialSetXOff(
  682. IN PRDPDR_IOREQUEST_PACKET pIoReq
  683. )
  684. /*++
  685. Routine Description:
  686. Handle Serial Port Set XOFF Request from Server.
  687. Arguments:
  688. pIoReq - Request packet received from server.
  689. Return Value:
  690. NA
  691. --*/
  692. {
  693. DC_BEGIN_FN("DrPRT::SerialSetXOff");
  694. //
  695. // Send the escape code to the serial port.
  696. //
  697. SerialHandleEscapeCode(pIoReq, SETXOFF);
  698. DC_END_FN();
  699. }
  700. void
  701. DrPRT::SerialSetXon(
  702. IN PRDPDR_IOREQUEST_PACKET pIoReq
  703. )
  704. /*++
  705. Routine Description:
  706. Handle Serial Port Set XON Request from Server.
  707. Arguments:
  708. pIoReq - Request packet received from server.
  709. Return Value:
  710. NA
  711. --*/
  712. {
  713. DC_BEGIN_FN("DrPRT::SerialSetXon");
  714. TRACEREQ(pIoReq);
  715. //
  716. // Send the escape code to the serial port.
  717. //
  718. SerialHandleEscapeCode(pIoReq, SETXON);
  719. DC_END_FN();
  720. }
  721. void
  722. DrPRT::SerialSetBreakOn(
  723. IN PRDPDR_IOREQUEST_PACKET pIoReq
  724. )
  725. /*++
  726. Routine Description:
  727. Handle Serial Port Set Break On Request from Server.
  728. Arguments:
  729. pIoReq - Request packet received from server.
  730. Return Value:
  731. NA
  732. --*/
  733. {
  734. DC_BEGIN_FN("DrPRT::SerialSetBreakOn");
  735. TRACEREQ(pIoReq);
  736. //
  737. // Send the escape code to the serial port.
  738. //
  739. SerialHandleEscapeCode(pIoReq, SETBREAK);
  740. DC_END_FN();
  741. }
  742. void
  743. DrPRT::SerialSetBreakOff(
  744. IN PRDPDR_IOREQUEST_PACKET pIoReq
  745. )
  746. /*++
  747. Routine Description:
  748. Handle Serial Port Set Break Off Request from Server.
  749. Arguments:
  750. pIoReq - Request packet received from server.
  751. Return Value:
  752. NA
  753. --*/
  754. {
  755. DC_BEGIN_FN("DrPRT::SerialSetBreakOff");
  756. TRACEREQ(pIoReq);
  757. //
  758. // Send the escape code to the serial port.
  759. //
  760. SerialHandleEscapeCode(pIoReq, CLRBREAK);
  761. DC_END_FN();
  762. }
  763. void
  764. DrPRT::SerialImmediateChar(
  765. IN PRDPDR_IOREQUEST_PACKET pIoReq
  766. )
  767. /*++
  768. Routine Description:
  769. Handle Serial Port Immediate Char Request from Server.
  770. Arguments:
  771. pIoReq - Request packet received from server.
  772. Return Value:
  773. NA
  774. --*/
  775. {
  776. PBYTE inputBuf;
  777. NTSTATUS status = STATUS_SUCCESS;
  778. UCHAR *immediateChar;
  779. PRDPDR_DEVICE_IOREQUEST pIoRequest;
  780. DRPORTHANDLE FileHandle;
  781. DC_BEGIN_FN("DrPRT::SerialImmediateChar");
  782. TRACEREQ(pIoReq);
  783. //
  784. // Get IO request pointer.
  785. //
  786. pIoRequest = &pIoReq->IoRequest;
  787. //
  788. // Get Port Handle
  789. //
  790. FileHandle = GetPortHandle(pIoRequest->FileId);
  791. ASSERT(FileHandle != INVALID_TSPORTHANDLE);
  792. //
  793. // Check the size of the incoming request.
  794. //
  795. status = DrUTL_CheckIOBufInputSize(pIoReq, sizeof(UCHAR));
  796. //
  797. // Get a pointer to the input buffer and the immediate character.
  798. //
  799. inputBuf = (PBYTE)(pIoReq + 1);
  800. immediateChar = (UCHAR *)inputBuf;
  801. //
  802. // Transmit the COMM char.
  803. //
  804. if (status == STATUS_SUCCESS) {
  805. if (!TransmitCommChar(FileHandle, *immediateChar)) {
  806. DWORD err = GetLastError();
  807. TRC_ALT((TB, _T("TransmitCommChar failed with %08x"), err));
  808. status = TranslateWinError(err);
  809. }
  810. }
  811. //
  812. // Send the results to the server.
  813. //
  814. TRACERESP_WITHPARAMS(pIoReq, NULL, 0, status);
  815. DefaultIORequestMsgHandle(pIoReq, status);
  816. DC_END_FN();
  817. }
  818. #if DBG
  819. void TraceCOMProtocol(TCHAR *format, ...)
  820. /*++
  821. Routine Description:
  822. Tracing function required by serial IO tracing module, tracecom.c.
  823. Arguments:
  824. format - printf-style format specifie
  825. Return Value:
  826. NA
  827. --*/
  828. {
  829. static TCHAR bigBuf[1024];
  830. va_list vargs;
  831. DC_BEGIN_FN("TraceCOMProtocol");
  832. va_start(vargs, format);
  833. StringCchVPrintf(bigBuf, SIZE_TCHARS(bigBuf), format, vargs);
  834. va_end( vargs );
  835. TRC_DBG((TB, bigBuf));
  836. DC_END_FN();
  837. }
  838. #else
  839. void TraceCOMProtocol(TCHAR *format, ...)
  840. {
  841. }
  842. #endif