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.

195 lines
5.2 KiB

  1. // SacCommunicator.cpp: implementation of the CSacCommunicator class.
  2. //
  3. //////////////////////////////////////////////////////////////////////
  4. #include "inclfile.h"
  5. #include "..\SacCommunicator\SacCommunicator.h"
  6. //#include "Debug.cpp"
  7. //////////////////////////////////////////////////////////////////////
  8. // Construction/Destruction
  9. //////////////////////////////////////////////////////////////////////
  10. LPTSTR CSacCommunicator::s_vctrCommPorts[]= {_T("COM1"), _T("COM2"), NULL};
  11. SacString CSacCommunicator::s_strDummyReponse;
  12. BOOL CSacCommunicator::XReadFile(
  13. HANDLE hFile, // handle to file
  14. LPVOID lpBuffer, // data buffer
  15. DWORD nNumberOfBytesToRead, // number of bytes to read
  16. LPDWORD lpNumberOfBytesRead, // number of bytes read
  17. LPOVERLAPPED lpOverlapped, // overlapped buffer
  18. time_t tmTimeout // time-out
  19. )
  20. {
  21. time_t tmInitReadTime, tmCurrTime;
  22. time(&tmInitReadTime); // stamp
  23. BOOL bLastRead;
  24. while (!(bLastRead= ReadFile(hFile, lpBuffer, nNumberOfBytesToRead, lpNumberOfBytesRead, lpOverlapped)) || !*lpNumberOfBytesRead)
  25. {
  26. time(&tmCurrTime); // stamp
  27. if (tmCurrTime-tmInitReadTime>tmTimeout)
  28. break;
  29. }
  30. return bLastRead;
  31. }
  32. CSacCommunicator::CSacCommunicator(int nCommPort, DCB dcb)
  33. {
  34. _Construct(nCommPort, dcb);
  35. }
  36. CSacCommunicator::~CSacCommunicator()
  37. {
  38. _Clean();
  39. }
  40. void CSacCommunicator::_Construct(int nCommPort, DCB dcb)
  41. {
  42. m_nCommPort= nCommPort;
  43. m_dcb= dcb;
  44. m_hCommPort= INVALID_HANDLE_VALUE;
  45. }
  46. void CSacCommunicator::_Clean()
  47. {
  48. if (IsConnected())
  49. Disconnect();
  50. }
  51. BOOL CSacCommunicator::Connect()
  52. {
  53. m_hCommPort= CreateFile(s_vctrCommPorts[m_nCommPort], GENERIC_READ|GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
  54. // open handle
  55. if (m_hCommPort!=INVALID_HANDLE_VALUE)
  56. {
  57. if (!SetCommMask(m_hCommPort, EV_RXCHAR)) // masking all events but the char. read event
  58. return FALSE; // init call has to succeed
  59. COMMTIMEOUTS tmouts;
  60. ZeroMemory(&tmouts,sizeof(COMMTIMEOUTS));
  61. tmouts.ReadIntervalTimeout= MAXDWORD; // no blocking
  62. if (!SetCommTimeouts(m_hCommPort, &tmouts)) // non-blocking read
  63. return FALSE; // has to succeed as well
  64. }
  65. return m_hCommPort!=INVALID_HANDLE_VALUE; // check if succeeded
  66. }
  67. BOOL CSacCommunicator::Disconnect()
  68. {
  69. CloseHandle(m_hCommPort); // close the handle
  70. m_hCommPort= INVALID_HANDLE_VALUE;
  71. return m_hCommPort==INVALID_HANDLE_VALUE; // has to succeed
  72. }
  73. BOOL CSacCommunicator::IsConnected()
  74. {
  75. return m_hCommPort!=INVALID_HANDLE_VALUE;
  76. }
  77. BOOL CSacCommunicator::PokeSac() // currently disabled
  78. {
  79. return FALSE;
  80. }
  81. BOOL CSacCommunicator::SacCommand(SAC_STR szRequest, SacString& strResponse, BOOL bPoke, time_t tmTimeout)
  82. {
  83. time_t tmInitTime, tmCurrTime;
  84. time(&tmInitTime);
  85. strResponse= ""; // init response
  86. if (bPoke) // if asked:
  87. /* if (!PokeSac()) // poke sac
  88. return FALSE; // make sure to get response*/
  89. 0; // disabled
  90. DWORD nBytesWritten, nBytesRead;
  91. SAC_CHAR szReturned[BUF_LEN]; // whatever is written by sac
  92. for (int i= 0; i<SAC_STRLEN(szRequest); i++) // baby-feeding sac
  93. {
  94. if (!WriteFile( m_hCommPort, szRequest+i, sizeof(SAC_CHAR), &nBytesWritten, NULL)) // feed sac
  95. return FALSE; // io must succeed
  96. time(&tmCurrTime);
  97. tmTimeout-= tmCurrTime-tmInitTime;
  98. if (!XReadFile( m_hCommPort, szReturned, sizeof(SAC_CHAR), &nBytesRead, NULL, tmTimeout)||!nBytesRead) // feed sac
  99. return FALSE; // io must succeed && must receive echo back
  100. }
  101. time(&tmCurrTime);
  102. tmTimeout-= tmCurrTime-tmInitTime;
  103. if (!XReadFile( m_hCommPort, szReturned, sizeof(SAC_CHAR), &nBytesRead, NULL, tmTimeout)||!nBytesRead) // feed sac
  104. return FALSE; // io must succeed && must receive echo back
  105. // DWORD dwEvtMask;
  106. DWORD dwErrors; // port errors
  107. COMSTAT stat; // io status
  108. time(&tmInitTime);
  109. do
  110. {
  111. //dwEvtMask= 0;
  112. //while (!(dwEvtMask & EV_RXCHAR)
  113. // if (!WaitCommEvent(m_hCommPort, &dwEvtMask, NULL))
  114. // return FALSE;
  115. ClearCommError(m_hCommPort, &dwErrors, &stat); // peek into buffer
  116. if (!ReadFile(m_hCommPort, szReturned, stat.cbInQue, &nBytesRead, NULL)) // receive echo-back
  117. return FALSE; // io must succeed
  118. if (!nBytesRead)
  119. continue; // save some worthless instructions then
  120. szReturned[nBytesRead]= '\0'; // fix it
  121. strResponse.append(szReturned); // add to response
  122. time(&tmCurrTime);
  123. } while ((strResponse.rfind(SAC_TEXT("SAC>"))==SacString::npos)&&(tmCurrTime-tmInitTime<tmTimeout));
  124. int nPosSacPrompt= strResponse.rfind(SAC_TEXT("SAC>"));
  125. if (!nPosSacPrompt)
  126. return FALSE; // no prompt back
  127. strResponse.erase(nPosSacPrompt, SAC_STRLEN(SAC_TEXT("SAC>")));
  128. return TRUE; // at last sac echoed back!!!
  129. }
  130. BOOL CSacCommunicator::PagingOff(SacString& strResponse)
  131. {
  132. if (!SacCommand(SAC_STR("p\r"), strResponse, FALSE)) // toggle paging
  133. return FALSE;
  134. if (strResponse.find(SAC_STR("OFF"))!=SacString::npos) // check state
  135. return TRUE;
  136. // if we r here then supposedly it's on, need to toggle once more
  137. if (!SacCommand(SAC_STR("p\r"), strResponse, FALSE)) // toggle paging
  138. return FALSE;
  139. if (strResponse.find(SAC_STR("OFF"))!=SacString::npos) // re-check
  140. return TRUE;
  141. return FALSE; // desperate
  142. }