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.

321 lines
7.4 KiB

  1. /*++
  2. Copyright (C) Microsoft Corporation, 1996 - 1999
  3. Module Name:
  4. ComChanl
  5. Abstract:
  6. This module implements the CComChannel Communications Class
  7. Author:
  8. Doug Barlow (dbarlow) 10/30/1996
  9. Environment:
  10. Win32, C++ w/ Exceptions
  11. Notes:
  12. None
  13. --*/
  14. #define __SUBROUTINE__
  15. #ifndef WIN32_LEAN_AND_MEAN
  16. #define WIN32_LEAN_AND_MEAN
  17. #endif
  18. #include <windows.h>
  19. #include <WinSCard.h>
  20. #include <CalMsgs.h>
  21. #include <CalCom.h>
  22. //
  23. //==============================================================================
  24. //
  25. // CComChannel
  26. //
  27. /*++
  28. CComChannel:
  29. This is the standard constructor and destructor for the Comm Channel
  30. class. They just call the clean and clear functions, respectively.
  31. Arguments:
  32. None
  33. Return Value:
  34. None
  35. Throws:
  36. None
  37. Author:
  38. Doug Barlow (dbarlow) 10/30/1996
  39. --*/
  40. #undef __SUBROUTINE__
  41. #define __SUBROUTINE__ DBGT("CComChannel::CComChannel")
  42. CComChannel::CComChannel(
  43. HANDLE hPipe)
  44. : m_hPipe(DBGT("CComChannel connection pipe")),
  45. m_hProc(DBGT("CComChannel process handle")),
  46. m_hOvrWait(DBGT("CComChannel overlapped I/O event"))
  47. {
  48. m_hPipe = hPipe;
  49. ZeroMemory(&m_ovrlp, sizeof(m_ovrlp));
  50. m_ovrlp.hEvent = m_hOvrWait = CreateEvent(NULL, TRUE, FALSE, NULL);
  51. if (!m_hOvrWait.IsValid())
  52. {
  53. DWORD dwErr = m_hOvrWait.GetLastError();
  54. CalaisWarning(
  55. __SUBROUTINE__,
  56. DBGT("Comm Responder failed to create overlapped event: %1"),
  57. dwErr);
  58. throw dwErr;
  59. }
  60. }
  61. #undef __SUBROUTINE__
  62. #define __SUBROUTINE__ DBGT("CComChannel::~CComChannel")
  63. CComChannel::~CComChannel()
  64. {
  65. if (m_hPipe.IsValid())
  66. m_hPipe.Close();
  67. if (m_hProc.IsValid())
  68. m_hProc.Close();
  69. if (m_hOvrWait.IsValid())
  70. m_hOvrWait.Close();
  71. }
  72. /*++
  73. Send:
  74. Send data over the communications channel.
  75. Arguments:
  76. pvData supplies the data to be written.
  77. cbLen supplies the length of the data, in bytes.
  78. Return Value:
  79. A DWORD status code.
  80. Throws:
  81. None.
  82. Author:
  83. Doug Barlow (dbarlow) 11/4/1996
  84. --*/
  85. #undef __SUBROUTINE__
  86. #define __SUBROUTINE__ DBGT("CComChannel::Send")
  87. DWORD
  88. CComChannel::Send(
  89. LPCVOID pvData,
  90. DWORD cbLen)
  91. {
  92. BOOL fSts;
  93. DWORD dwLen, dwOffset = 0;
  94. DWORD dwSts = SCARD_S_SUCCESS;
  95. while (0 < cbLen)
  96. {
  97. fSts = WriteFile(
  98. m_hPipe,
  99. &((LPBYTE)pvData)[dwOffset],
  100. cbLen,
  101. &dwLen,
  102. &m_ovrlp);
  103. if (!fSts)
  104. {
  105. BOOL fErrorProcessed;
  106. dwSts = GetLastError();
  107. do
  108. {
  109. fErrorProcessed = TRUE;
  110. switch (dwSts)
  111. {
  112. //
  113. // Postpone processing
  114. case ERROR_IO_PENDING:
  115. fErrorProcessed = FALSE;
  116. WaitForever(
  117. m_ovrlp.hEvent,
  118. REASONABLE_TIME,
  119. DBGT("Comm Channel response write"),
  120. (DWORD)0);
  121. fSts = GetOverlappedResult(
  122. m_hPipe,
  123. &m_ovrlp,
  124. &dwLen,
  125. TRUE);
  126. dwSts = fSts ? ERROR_SUCCESS : GetLastError();
  127. break;
  128. //
  129. // Success after a wait event.
  130. case ERROR_SUCCESS:
  131. break;
  132. //
  133. // The pipe may have been closed, for instance, the context
  134. // may have been marked invalid as a result of a session
  135. // change.
  136. case ERROR_BROKEN_PIPE:
  137. case ERROR_INVALID_HANDLE:
  138. throw (DWORD)ERROR_BROKEN_PIPE;
  139. break;
  140. //
  141. // Some other error.
  142. default:
  143. CalaisWarning(
  144. __SUBROUTINE__,
  145. DBGT("Comm Channel could not write to pipe: %1"),
  146. dwSts);
  147. goto ErrorExit;
  148. }
  149. } while (!fErrorProcessed);
  150. }
  151. cbLen -= dwLen;
  152. }
  153. ErrorExit:
  154. return dwSts;
  155. }
  156. /*++
  157. Receive:
  158. This method receives a given number of bytes from the communications
  159. channel.
  160. Arguments:
  161. pvData receives the incoming bytes.
  162. cbLen supplies the length of the data expected.
  163. Return Value:
  164. None
  165. Throws:
  166. Transmission errors as a DWORD.
  167. Author:
  168. Doug Barlow (dbarlow) 11/4/1996
  169. --*/
  170. #undef __SUBROUTINE__
  171. #define __SUBROUTINE__ DBGT("CComChannel::Receive")
  172. void
  173. CComChannel::Receive(
  174. LPVOID pvData,
  175. DWORD cbLen)
  176. {
  177. BOOL fSts;
  178. DWORD dwLen, dwOffset = 0;
  179. while (0 < cbLen)
  180. {
  181. fSts = ReadFile(
  182. m_hPipe,
  183. &((LPBYTE)pvData)[dwOffset],
  184. cbLen,
  185. &dwLen,
  186. &m_ovrlp);
  187. if (!fSts)
  188. {
  189. BOOL fErrorProcessed;
  190. DWORD dwSts = GetLastError();
  191. DWORD dwWait;
  192. do
  193. {
  194. fErrorProcessed = TRUE;
  195. switch (dwSts)
  196. {
  197. //
  198. // Postpone processing
  199. case ERROR_IO_PENDING:
  200. dwWait = WaitForAnyObject(
  201. INFINITE,
  202. m_ovrlp.hEvent,
  203. g_hCalaisShutdown, // Make sure this is last
  204. NULL);
  205. switch (dwWait)
  206. {
  207. case 1:
  208. fErrorProcessed = FALSE;
  209. fSts = GetOverlappedResult(
  210. m_hPipe,
  211. &m_ovrlp,
  212. &dwLen,
  213. TRUE);
  214. dwSts = fSts ? ERROR_SUCCESS : GetLastError();
  215. break;
  216. case 2:
  217. throw (DWORD)SCARD_P_SHUTDOWN;
  218. break;
  219. default:
  220. CalaisWarning(
  221. __SUBROUTINE__,
  222. DBGT("Wait for comm pipe receive returned invalid value"));
  223. throw (DWORD)SCARD_F_INTERNAL_ERROR;
  224. }
  225. break;
  226. //
  227. // Success after a wait event.
  228. case ERROR_SUCCESS:
  229. break;
  230. //
  231. // The client exited.
  232. case ERROR_BROKEN_PIPE:
  233. case ERROR_INVALID_HANDLE:
  234. throw (DWORD)ERROR_BROKEN_PIPE;
  235. break;
  236. //
  237. // Some other error.
  238. default:
  239. CalaisWarning(
  240. __SUBROUTINE__,
  241. DBGT("Comm Channel could not read from pipe: %1"),
  242. dwSts);
  243. throw dwSts;
  244. }
  245. } while (!fErrorProcessed);
  246. }
  247. ASSERT(dwLen <= cbLen);
  248. cbLen -= dwLen;
  249. dwOffset += dwLen;
  250. }
  251. }