Source code of Windows XP (NT5)
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.

530 lines
11 KiB

  1. /*++
  2. Copyright (C) Microsoft Corporation, 1997 - 1999
  3. Module Name:
  4. common.cxx
  5. Abstract:
  6. This file contains some common stuff for SENS project.
  7. Author:
  8. Gopal Parupudi <GopalP>
  9. [Notes:]
  10. optional-notes
  11. Revision History:
  12. GopalP 10/11/1997 Start.
  13. --*/
  14. #include "common.hxx"
  15. #include <windows.h>
  16. #ifdef DBG
  17. extern DWORD gdwDebugOutputLevel;
  18. #endif // DBG
  19. //
  20. // Constants
  21. //
  22. #define MAX_DBGPRINT_LEN 512
  23. #if defined(SENS_CHICAGO)
  24. //
  25. // Macros
  26. //
  27. #define UnicodeStrLen(str) lstrlenW(str)
  28. char *
  29. SensUnicodeStringToAnsi(
  30. unsigned short * StringW
  31. )
  32. /*++
  33. Routine Description:
  34. Converts UNICODE string to it's ANSI equivalent.
  35. Arguments:
  36. StringW - The UNICODE string.
  37. Notes:
  38. a. The returned ANSI string is to be freed using the "delete" operator.
  39. Return Value:
  40. The equivalent ANSI string, if successful.
  41. NULL, otherwise
  42. --*/
  43. {
  44. int retVal;
  45. short Length;
  46. char * StringA;
  47. // Simple check
  48. if (NULL == StringW)
  49. {
  50. return (NULL);
  51. }
  52. // Allocate Multi-byte buffer
  53. Length = UnicodeStrLen(StringW);
  54. StringA = new char [Length * 2 + 2];
  55. if (NULL == StringA)
  56. {
  57. return (NULL);
  58. }
  59. // Perform the conversion
  60. retVal = WideCharToMultiByte(
  61. CP_ACP, // Code Page
  62. 0, // Performance and mapping flags
  63. (LPCWSTR) StringW, // Wide String
  64. -1, // Number of characters in Wide String
  65. (LPSTR) StringA, // Multi-byte string buffer
  66. Length * 2 + 2, // Size of the Multi-byte string buffer
  67. NULL, // Default for unmappable characters
  68. NULL // Flag when default character is used
  69. );
  70. if (0 == retVal)
  71. {
  72. SensPrintToDebugger(SENS_DBG, ("[SENS] WideCharToMultiByte() failed with %d\n",
  73. GetLastError()));
  74. delete StringA;
  75. return (NULL);
  76. }
  77. return (StringA);
  78. }
  79. unsigned short *
  80. SensAnsiStringToUnicode(
  81. char * StringA
  82. )
  83. /*++
  84. Routine Description:
  85. Converts ANSI string to it's UNICODE equivalent.
  86. Arguments:
  87. StringA - The ANSI string.
  88. Notes:
  89. a. The returned UNICODE string is to be freed using the "delete" operator.
  90. Return Value:
  91. The equivalent UNICODE string, if successful.
  92. NULL, otherwise
  93. --*/
  94. {
  95. int retVal;
  96. short Length;
  97. unsigned short * StringW;
  98. // Simple check
  99. if (NULL == StringA)
  100. {
  101. return (NULL);
  102. }
  103. // Allocate UNICODE buffer
  104. Length = strlen((const char *) StringA);
  105. StringW = new unsigned short [Length + 1];
  106. if (NULL == StringW)
  107. {
  108. return (NULL);
  109. }
  110. retVal = MultiByteToWideChar(
  111. CP_ACP, // Code page
  112. 0, // Character type options
  113. (LPCSTR) StringA, // Multi-byte string
  114. -1, // Number of characters in multi-byte string
  115. (LPWSTR) StringW, // UNICODE string buffer
  116. Length * 2 + 2 // Length of the UNICODE string buffer
  117. );
  118. if (0 == retVal)
  119. {
  120. SensPrintToDebugger(SENS_DBG, ("[SENS] MultiByteToWideChar() failed with %d\n",
  121. GetLastError()));
  122. delete StringW;
  123. return (NULL);
  124. }
  125. return (StringW);
  126. }
  127. #endif // SENS_CHICAGO
  128. //
  129. // Available only on Debug builds.
  130. //
  131. #if DBG
  132. ULONG _cdecl
  133. SensDbgPrintA(
  134. CHAR * Format,
  135. ...
  136. )
  137. /*++
  138. Routine Description:
  139. Equivalent of NT's DbgPrint().
  140. Arguments:
  141. Same as for printf()
  142. Return Value:
  143. 0, if successful.
  144. --*/
  145. {
  146. va_list arglist;
  147. CHAR OutputBuffer[MAX_DBGPRINT_LEN];
  148. ULONG length;
  149. static BeginningOfLine = 1;
  150. static LineCount = 0;
  151. // See if we are supposed to print
  152. if (0x0 == gdwDebugOutputLevel)
  153. {
  154. return -1;
  155. }
  156. //
  157. // vsprintf isn't multithreaded + we don't want to intermingle output
  158. // from different threads.
  159. //
  160. length = 0;
  161. //
  162. // Handle the beginning of a new line.
  163. //
  164. //
  165. if (BeginningOfLine)
  166. {
  167. //
  168. // If we're writing to the debug terminal,
  169. // indicate this is a SENS message.
  170. //
  171. length += (ULONG) wsprintfA(&OutputBuffer[length], "[SENS] ");
  172. }
  173. //
  174. // Put the information requested by the caller onto the line
  175. //
  176. va_start(arglist, Format);
  177. length += (ULONG) wvsprintfA(&OutputBuffer[length], Format, arglist);
  178. BeginningOfLine = (length > 0 && OutputBuffer[length-1] == '\n' );
  179. if (OutputBuffer[length-1] == '\n')
  180. {
  181. OutputBuffer[length-1] = '\r';
  182. OutputBuffer[length] = '\n';
  183. OutputBuffer[length+1] = '\0';
  184. }
  185. va_end(arglist);
  186. if (length > MAX_DBGPRINT_LEN)
  187. {
  188. SensBreakPoint();
  189. }
  190. //
  191. // Just output to the debug terminal
  192. //
  193. #ifdef PRINT_TO_CONSOLE
  194. printf("%s\n", OutputBuffer);
  195. #else // PRINT_TO_CONSOLE
  196. #if !defined(SENS_CHICAGO)
  197. DbgPrint(OutputBuffer);
  198. #else
  199. OutputDebugStringA(OutputBuffer);
  200. #endif // SENS_CHICAGO
  201. #endif // PRINT_TO_CONSOLE
  202. return (0);
  203. }
  204. ULONG _cdecl
  205. SensDbgPrintW(
  206. WCHAR * Format,
  207. ...
  208. )
  209. /*++
  210. Routine Description:
  211. Equivalent of NT's DbgPrint().
  212. Arguments:
  213. Same as for printf()
  214. Return Value:
  215. 0, if successful.
  216. --*/
  217. {
  218. va_list arglist;
  219. WCHAR OutputBuffer[MAX_DBGPRINT_LEN];
  220. ULONG length;
  221. static BeginningOfLine = 1;
  222. static LineCount = 0;
  223. // See if we are supposed to print
  224. if (0x0 == gdwDebugOutputLevel)
  225. {
  226. return -1;
  227. }
  228. //
  229. // vsprintf isn't multithreaded + we don't want to intermingle output
  230. // from different threads.
  231. //
  232. length = 0;
  233. //
  234. // Handle the beginning of a new line.
  235. //
  236. //
  237. if (BeginningOfLine)
  238. {
  239. //
  240. // If we're writing to the debug terminal,
  241. // indicate this is a SENS message.
  242. //
  243. length += (ULONG) wsprintfW(&OutputBuffer[length], SENS_BSTR("[SENS] "));
  244. }
  245. //
  246. // Put the information requested by the caller onto the line
  247. //
  248. va_start(arglist, Format);
  249. length += (ULONG) wvsprintfW(&OutputBuffer[length], Format, arglist);
  250. BeginningOfLine = (length > 0 && OutputBuffer[length-1] == (WCHAR)'\n' );
  251. if (OutputBuffer[length-1] == (WCHAR)'\n')
  252. {
  253. OutputBuffer[length-1] = (WCHAR)'\r';
  254. OutputBuffer[length] = (WCHAR)'\n';
  255. OutputBuffer[length+1] = (WCHAR)'\0';
  256. }
  257. va_end(arglist);
  258. if (length > MAX_DBGPRINT_LEN)
  259. {
  260. SensBreakPoint();
  261. }
  262. //
  263. // Just output to the debug terminal
  264. //
  265. #ifdef PRINT_TO_CONSOLE
  266. wprintf(SENS_BSTR("%s\n"), OutputBuffer);
  267. #else
  268. OutputDebugStringW(OutputBuffer);
  269. #endif
  270. return (0);
  271. }
  272. BOOL
  273. ValidateError(
  274. IN int Status,
  275. IN unsigned int Count,
  276. IN const int ErrorList[])
  277. /*++
  278. Routine Description
  279. Tests that 'Status' is one of an expected set of error codes.
  280. Used on debug builds as part of the VALIDATE() macro.
  281. Example:
  282. VALIDATE(EventStatus)
  283. {
  284. RPC_P_CONNECTION_CLOSED,
  285. RPC_P_RECEIVE_FAILED,
  286. RPC_P_CONNECTION_SHUTDOWN
  287. // more error codes here
  288. } END_VALIDATE;
  289. This function is called with the RpcStatus and expected errors codes
  290. as parameters. If RpcStatus is not one of the expected error
  291. codes and it not zero a message will be printed to the debugger
  292. and the function will return false. The VALIDATE macro ASSERT's the
  293. return value.
  294. Arguments:
  295. Status - Status code in question.
  296. Count - number of variable length arguments
  297. ... - One or more expected status codes. Terminated with 0 (RPC_S_OK).
  298. Return Value:
  299. TRUE - Status code is in the list or the status is 0.
  300. FALSE - Status code is not in the list.
  301. --*/
  302. {
  303. unsigned int i;
  304. for (i = 0; i < Count; i++)
  305. {
  306. if (ErrorList[i] == Status)
  307. {
  308. return TRUE;
  309. }
  310. }
  311. SensPrintToDebugger(SENS_DEB, ("[SENS] Assertion: unexpected failure %lu (0x%08x)\n",
  312. (unsigned long)Status, (unsigned long)Status));
  313. return(FALSE);
  314. }
  315. void
  316. EnableDebugOutputIfNecessary(
  317. void
  318. )
  319. /*++
  320. This routine tries to set gdwDebugOuputLevel to the value defined
  321. in the regitry at HKLM\Software\Microsoft\Mobile\SENS\Debug value.
  322. All binaries using this function need to define the following
  323. global value:
  324. DWORD gdwDebugOutputLevel;
  325. --*/
  326. {
  327. HRESULT hr;
  328. HKEY hKeySens;
  329. LONG RegStatus;
  330. BOOL bStatus;
  331. DWORD dwType;
  332. DWORD cbData;
  333. LPBYTE lpbData;
  334. hr = S_OK;
  335. hKeySens = NULL;
  336. RegStatus = ERROR_SUCCESS;
  337. bStatus = FALSE;
  338. dwType = 0x0;
  339. cbData = 0x0;
  340. lpbData = NULL;
  341. RegStatus = RegOpenKeyEx(
  342. HKEY_LOCAL_MACHINE, // Handle of the key
  343. SENS_REGISTRY_KEY, // String which represents the sub-key to open
  344. 0, // Reserved (MBZ)
  345. KEY_QUERY_VALUE, // Security Access mask
  346. &hKeySens // Returned HKEY
  347. );
  348. if (RegStatus != ERROR_SUCCESS)
  349. {
  350. SensPrintToDebugger(SENS_ERR, ("[SENS] RegOpenKeyEx(Sens) returned %d.\n", RegStatus));
  351. goto Cleanup;
  352. }
  353. //
  354. // Query the Configured value
  355. //
  356. lpbData = (LPBYTE) &gdwDebugOutputLevel;
  357. cbData = sizeof(DWORD);
  358. RegStatus = RegQueryValueEx(
  359. hKeySens, // Handle of the sub-key
  360. SENS_DEBUG_LEVEL, // Name of the Value
  361. NULL, // Reserved (MBZ)
  362. &dwType, // Address of the type of the Value
  363. lpbData, // Address of the data of the Value
  364. &cbData // Address of size of data of the Value
  365. );
  366. if (RegStatus != ERROR_SUCCESS)
  367. {
  368. SensPrintToDebugger(SENS_ERR, ("[SENS] RegQueryValueEx(SENS_DEBUG_LEVEL) failed with 0x%x\n", RegStatus));
  369. gdwDebugOutputLevel = 0x0;
  370. goto Cleanup;
  371. }
  372. SensPrintToDebugger(SENS_INFO, ("[SENS] Debug Output is turned %s. The level is 0x%x.\n",
  373. gdwDebugOutputLevel ? "ON" : "OFF", gdwDebugOutputLevel));
  374. Cleanup:
  375. //
  376. // Cleanup
  377. //
  378. if (hKeySens)
  379. {
  380. RegCloseKey(hKeySens);
  381. }
  382. return;
  383. }
  384. #endif // DBG