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.

353 lines
7.4 KiB

  1. /*++
  2. Copyright (c) 2000-2001 Microsoft Corporation
  3. Module Name:
  4. vststmsgclient.cxx
  5. Abstract:
  6. Implementation of test message classes for the client and holder of
  7. shared methods and variables shared between client and server.
  8. Brian Berkowitz [brianb] 05/22/2000
  9. TBD:
  10. Revision History:
  11. Name Date Comments
  12. brianb 05/22/2000 Created
  13. ssteiner 06/07/2000 Split client and server portions into
  14. two files. vststmsg.cxx contains
  15. the server portion.
  16. --*/
  17. #include "stdafx.h"
  18. #include "vststmsgclient.hxx"
  19. void LogUnexpectedFailure(LPCWSTR wsz, ...);
  20. VSTST_MSG_TYPE_TABLE g_msgTypes[VSTST_MT_MAXMSGTYPE];
  21. void AddMessageType
  22. (
  23. VSTST_MSG_TYPE type,
  24. UINT cbFixed,
  25. UINT cVarPtr,
  26. VSTST_MSG_PRIORITY priority,
  27. VSTST_MSG_HANDLER pfnHandler,
  28. VSTST_VARPTR_TYPE ptype1 = VSTST_VPT_UNDEFINED,
  29. VSTST_VARPTR_TYPE ptype2 = VSTST_VPT_UNDEFINED,
  30. VSTST_VARPTR_TYPE ptype3 = VSTST_VPT_UNDEFINED,
  31. VSTST_VARPTR_TYPE ptype4 = VSTST_VPT_UNDEFINED,
  32. VSTST_VARPTR_TYPE ptype5 = VSTST_VPT_UNDEFINED,
  33. VSTST_VARPTR_TYPE ptype6 = VSTST_VPT_UNDEFINED,
  34. VSTST_VARPTR_TYPE ptype7 = VSTST_VPT_UNDEFINED,
  35. VSTST_VARPTR_TYPE ptype8 = VSTST_VPT_UNDEFINED
  36. )
  37. {
  38. VSTST_MSG_TYPE_TABLE *pEntry = &g_msgTypes[type];
  39. pEntry->cbFixed = cbFixed;
  40. pEntry->cVarPtr = cVarPtr;
  41. pEntry->priority = priority;
  42. pEntry->pfnHandler = pfnHandler;
  43. pEntry->pointerTypes[0] = (BYTE) ptype1;
  44. pEntry->pointerTypes[1] = (BYTE) ptype2;
  45. pEntry->pointerTypes[2] = (BYTE) ptype3;
  46. pEntry->pointerTypes[3] = (BYTE) ptype4;
  47. pEntry->pointerTypes[4] = (BYTE) ptype5;
  48. pEntry->pointerTypes[5] = (BYTE) ptype6;
  49. pEntry->pointerTypes[6] = (BYTE) ptype7;
  50. pEntry->pointerTypes[7] = (BYTE) ptype8;
  51. };
  52. void InitMsgTypes()
  53. {
  54. AddMessageType
  55. (
  56. VSTST_MT_TEXT,
  57. FIELD_OFFSET(VSTST_TEXTMSG, pch),
  58. 1,
  59. VSTST_MP_QUEUED,
  60. NULL, // Not needed by client, server will fill in
  61. VSTST_VPT_ANSI
  62. );
  63. AddMessageType
  64. (
  65. VSTST_MT_IMMEDIATETEXT,
  66. FIELD_OFFSET(VSTST_TEXTMSG, pch),
  67. 1,
  68. VSTST_MP_IMMEDIATE,
  69. NULL,
  70. VSTST_VPT_ANSI
  71. );
  72. AddMessageType
  73. (
  74. VSTST_MT_FAILURE,
  75. FIELD_OFFSET(VSTST_FAILUREMSG, szFailure),
  76. 1,
  77. VSTST_MP_QUEUED,
  78. NULL,
  79. VSTST_VPT_ANSI
  80. );
  81. AddMessageType
  82. (
  83. VSTST_MT_OPERATIONFAILURE,
  84. FIELD_OFFSET(VSTST_OPERATIONFAILUREMSG, szFailedOperation),
  85. 1,
  86. VSTST_MP_QUEUED,
  87. NULL,
  88. VSTST_VPT_ANSI
  89. );
  90. AddMessageType
  91. (
  92. VSTST_MT_UNEXPECTEDEXCEPTION,
  93. FIELD_OFFSET(VSTST_UNEXPECTEDEXCEPTIONMSG, szFailedRoutine),
  94. 1,
  95. VSTST_MP_QUEUED,
  96. NULL,
  97. VSTST_VPT_ANSI
  98. );
  99. AddMessageType
  100. (
  101. VSTST_MT_SUCCESS,
  102. FIELD_OFFSET(VSTST_SUCCESSMSG, szMsg),
  103. 1,
  104. VSTST_MP_QUEUED,
  105. NULL,
  106. VSTST_VPT_ANSI
  107. );
  108. }
  109. CVsTstClientMsg::CVsTstClientMsg() :
  110. m_bcsInitialized(false),
  111. m_rgbMsg(NULL),
  112. m_hPipe(INVALID_HANDLE_VALUE),
  113. m_bSkipWrites(false),
  114. m_seqQueued(0),
  115. m_seqImmediate(0)
  116. {
  117. }
  118. CVsTstClientMsg::~CVsTstClientMsg()
  119. {
  120. delete m_rgbMsg;
  121. if (m_bcsInitialized)
  122. m_cs.Term();
  123. if (m_hPipe != INVALID_HANDLE_VALUE)
  124. CloseHandle(m_hPipe);
  125. }
  126. // initialize messaging to test controller
  127. HRESULT CVsTstClientMsg::Init
  128. (
  129. LONGLONG processId,
  130. UINT cbMaxMsg,
  131. bool bIgnorePipeCreationFailure
  132. )
  133. {
  134. m_processId = processId;
  135. try
  136. {
  137. m_cs.Init();
  138. m_bcsInitialized = true;
  139. }
  140. catch(...)
  141. {
  142. return E_UNEXPECTED;
  143. }
  144. m_hPipe = CreateFile
  145. (
  146. s_wszPipeName,
  147. GENERIC_WRITE,
  148. FILE_SHARE_READ|FILE_SHARE_WRITE,
  149. NULL,
  150. OPEN_EXISTING,
  151. FILE_ATTRIBUTE_NORMAL,
  152. NULL
  153. );
  154. if (m_hPipe == INVALID_HANDLE_VALUE)
  155. {
  156. if (bIgnorePipeCreationFailure)
  157. m_bSkipWrites = true;
  158. else
  159. return HRESULT_FROM_WIN32(GetLastError());
  160. }
  161. else
  162. {
  163. m_cbMaxMsgLength = cbMaxMsg;
  164. m_rgbMsg = new BYTE[cbMaxMsg];
  165. if (m_rgbMsg == NULL)
  166. {
  167. CloseHandle(m_hPipe);
  168. m_hPipe = INVALID_HANDLE_VALUE;
  169. return E_OUTOFMEMORY;
  170. }
  171. }
  172. return S_OK;
  173. }
  174. // send a message to the test controller
  175. HRESULT CVsTstClientMsg::SendMessage(VSTST_MSG_TYPE type, void *pv)
  176. {
  177. m_cs.Lock();
  178. VSTST_ASSERT(type < VSTST_MT_MAXMSGTYPE);
  179. VSTST_MSG_TYPE_TABLE *pType = &g_msgTypes[type];
  180. VSTST_MSG_HDR *phdr = (VSTST_MSG_HDR *) m_rgbMsg;
  181. phdr->processId = m_processId;
  182. phdr->type = type;
  183. time(&phdr->time);
  184. if (pType->priority == VSTST_MP_IMMEDIATE)
  185. phdr->sequence = ++m_seqImmediate;
  186. else
  187. phdr->sequence = ++m_seqQueued;
  188. BYTE *pbMsg = phdr->rgb;
  189. size_t cbUsed = pType->cbFixed + FIELD_OFFSET(VSTST_MSG_HDR, rgb) +
  190. pType->cVarPtr * sizeof(PVOID);
  191. if (cbUsed >= m_cbMaxMsgLength)
  192. {
  193. m_cs.Unlock();
  194. return HRESULT_FROM_WIN32(ERROR_BUFFER_OVERFLOW);
  195. }
  196. // copy in fixed portion of data structure
  197. memcpy(pbMsg, pv, pType->cbFixed);
  198. pbMsg += pType->cbFixed;
  199. // reserve room for pointers
  200. memset(pbMsg, 0, pType->cVarPtr * sizeof(PVOID));
  201. pbMsg += pType->cVarPtr * sizeof(PVOID);
  202. // walk and write out pointer data
  203. VOID **ppv = (VOID **) ((BYTE *) pv + pType->cbFixed);
  204. for(UINT iPtr = 0; iPtr < pType->cVarPtr; iPtr++, ppv++)
  205. {
  206. VSTST_VARPTR_TYPE type = (VSTST_VARPTR_TYPE) pType->pointerTypes[iPtr];
  207. BYTE *pb = NULL;
  208. size_t cb = 0;
  209. switch(type)
  210. {
  211. default:
  212. VSTST_ASSERT(FALSE);
  213. break;
  214. case VSTST_VPT_BYTE:
  215. pb = *(BYTE **) ppv;
  216. cb = *(UINT *) *pb;
  217. break;
  218. case VSTST_VPT_ANSI:
  219. pb = *(BYTE **) ppv;
  220. cb = strlen((char *) pb) + 1;
  221. break;
  222. case VSTST_VPT_UNICODE:
  223. pb = *(BYTE **) ppv;
  224. cb = (wcslen((WCHAR *) pb) + 1) * sizeof(WCHAR);
  225. break;
  226. }
  227. // round up to alignment boundary
  228. size_t cbAlign = (cb + sizeof(PVOID) - 1) & ~(sizeof(PVOID)-1);
  229. // check for buffer overflow
  230. if (cbAlign + cbUsed >= m_cbMaxMsgLength)
  231. {
  232. m_cs.Unlock();
  233. return HRESULT_FROM_WIN32(ERROR_BUFFER_OVERFLOW);
  234. }
  235. memcpy(pbMsg, pb, cb);
  236. // adjust pointer to alignment boundary
  237. pb += cbAlign;
  238. // adjust amount used
  239. cbUsed += cbAlign;
  240. }
  241. phdr->cbMsg = cbUsed;
  242. phdr->pmsgNext = NULL;
  243. DWORD cbWritten;
  244. if (!WriteFile(m_hPipe, m_rgbMsg, (UINT) cbUsed, &cbWritten, NULL) || cbUsed != cbWritten)
  245. {
  246. m_cs.Unlock();
  247. return HRESULT_FROM_WIN32(GetLastError());
  248. }
  249. VSTST_ASSERT(cbUsed == cbWritten);
  250. m_cs.Unlock();
  251. return S_OK;
  252. }
  253. void CVsTstClientLogger::LogFailure(LPCSTR szFailure)
  254. {
  255. VSTST_ASSERT(m_pClient);
  256. VSTST_FAILUREMSG msg;
  257. msg.szFailure = szFailure;
  258. m_pClient->SendMessage(VSTST_MT_FAILURE, &msg);
  259. }
  260. void CVsTstClientLogger::LogUnexpectedException(LPCSTR szRoutine)
  261. {
  262. VSTST_ASSERT(m_pClient);
  263. VSTST_UNEXPECTEDEXCEPTIONMSG msg;
  264. msg.szFailedRoutine = szRoutine;
  265. m_pClient->SendMessage(VSTST_MT_UNEXPECTEDEXCEPTION, &msg);
  266. }
  267. void CVsTstClientLogger::ValidateResult(HRESULT hr, LPCSTR szOperation)
  268. {
  269. VSTST_ASSERT(m_pClient);
  270. if (FAILED(hr))
  271. {
  272. VSTST_OPERATIONFAILUREMSG msg;
  273. msg.hr = hr;
  274. msg.szFailedOperation = szOperation;
  275. m_pClient->SendMessage(VSTST_MT_OPERATIONFAILURE, &msg);
  276. throw hr;
  277. }
  278. }
  279. void CVsTstClientLogger::LogSuccess(LPCSTR sz)
  280. {
  281. VSTST_ASSERT(m_pClient);
  282. VSTST_SUCCESSMSG msg;
  283. msg.szMsg = sz;
  284. m_pClient->SendMessage(VSTST_MT_SUCCESS, &msg);
  285. }
  286. void CVsTstClientLogger::LogMessage(LPCSTR sz)
  287. {
  288. VSTST_ASSERT(m_pClient);
  289. VSTST_TEXTMSG msg;
  290. msg.pch = sz;
  291. m_pClient->SendMessage(VSTST_MT_TEXT, &msg);
  292. }