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.

433 lines
14 KiB

  1. /*++
  2. Copyright (c) 1997-2000 Microsoft Corporation
  3. Module Name:
  4. traceprt.c
  5. Abstract:
  6. Trace formatting library. Converts binary trace file to CSV format,
  7. and other formattted string formats.
  8. Author:
  9. Ian Service (IanServ) 3rd May 2000
  10. Revision History:
  11. Source taken from RtlFormatMessage and adapted for the needs of TraceFmt processing.
  12. Due to the way we pre format strings and get information about 64 and 32 bit strings, the odditties
  13. like %p do not work correctly when handled on a machine of the other type.
  14. This module contains a special version of RtlFormatMessage that does fixups in conjunction
  15. with TracePrt's processing of ItemPtr.
  16. --*/
  17. #ifdef __cplusplus
  18. extern "C"{
  19. #endif
  20. #define UNICODE
  21. #define _UNICODE
  22. #include <stdio.h>
  23. #include <stdlib.h>
  24. #include <nt.h>
  25. #include <ntrtl.h>
  26. #include <nturtl.h>
  27. #include <windows.h>
  28. #include <shellapi.h>
  29. #include <tchar.h>\
  30. #define MAX_INSERTS 200
  31. NTSTATUS
  32. TraceFormatMessage(
  33. IN PWSTR MessageFormat,
  34. IN ULONG MaximumWidth OPTIONAL,
  35. IN BOOLEAN IgnoreInserts,
  36. IN BOOLEAN ArgumentsAreAnsi,
  37. IN BOOLEAN ArgumentsAreAnArray,
  38. IN va_list *Arguments,
  39. OUT PWSTR Buffer,
  40. IN ULONG Length,
  41. OUT PULONG ReturnLength OPTIONAL
  42. )
  43. {
  44. ULONG Column;
  45. int cchRemaining, cchWritten;
  46. PULONG_PTR ArgumentsArray = (PULONG_PTR)Arguments;
  47. ULONG_PTR rgInserts[ MAX_INSERTS ];
  48. ULONG cSpaces;
  49. ULONG MaxInsert, CurInsert;
  50. ULONG PrintParameterCount;
  51. ULONG_PTR PrintParameter1;
  52. ULONG_PTR PrintParameter2;
  53. WCHAR PrintFormatString[ 32 ];
  54. BOOLEAN DefaultedFormatString;
  55. WCHAR c;
  56. PWSTR s, s1;
  57. PWSTR lpDst, lpDstBeg, lpDstLastSpace;
  58. cchRemaining = Length / sizeof( WCHAR );
  59. lpDst = Buffer;
  60. MaxInsert = 0;
  61. lpDstLastSpace = NULL;
  62. Column = 0;
  63. s = MessageFormat;
  64. while (*s != UNICODE_NULL) {
  65. if (*s == L'%') {
  66. s++;
  67. lpDstBeg = lpDst;
  68. if (*s >= L'1' && *s <= L'9') {
  69. CurInsert = *s++ - L'0';
  70. if (*s >= L'0' && *s <= L'9') {
  71. CurInsert = (CurInsert * 10) + (*s++ - L'0');
  72. if (*s >= L'0' && *s <= L'9') {
  73. CurInsert = (CurInsert * 10) + (*s++ - L'0');
  74. if (*s >= L'0' && *s <= L'9') {
  75. return( STATUS_INVALID_PARAMETER );
  76. }
  77. }
  78. }
  79. CurInsert -= 1;
  80. PrintParameterCount = 0;
  81. if (*s == L'!') {
  82. DefaultedFormatString = FALSE;
  83. s1 = PrintFormatString;
  84. *s1++ = L'%';
  85. s++;
  86. while (*s != L'!') {
  87. if (*s != UNICODE_NULL) {
  88. if (s1 >= &PrintFormatString[ 31 ]) {
  89. return( STATUS_INVALID_PARAMETER );
  90. }
  91. if (*s == L'*') {
  92. if (PrintParameterCount++ > 1) {
  93. return( STATUS_INVALID_PARAMETER );
  94. }
  95. }
  96. *s1++ = *s++;
  97. }
  98. else {
  99. return( STATUS_INVALID_PARAMETER );
  100. }
  101. }
  102. s++;
  103. *s1 = UNICODE_NULL;
  104. }
  105. else {
  106. DefaultedFormatString = TRUE;
  107. wcscpy( PrintFormatString, L"%s" );
  108. s1 = PrintFormatString + wcslen( PrintFormatString );
  109. }
  110. if (IgnoreInserts) {
  111. if (!wcscmp( PrintFormatString, L"%s" )) {
  112. cchWritten = _snwprintf( lpDst,
  113. cchRemaining,
  114. L"%%%u",
  115. CurInsert+1
  116. );
  117. }
  118. else {
  119. cchWritten = _snwprintf( lpDst,
  120. cchRemaining,
  121. L"%%%u!%s!",
  122. CurInsert+1,
  123. &PrintFormatString[ 1 ]
  124. );
  125. }
  126. if (cchWritten == -1) {
  127. return(STATUS_BUFFER_OVERFLOW);
  128. }
  129. }
  130. else
  131. if (ARGUMENT_PRESENT( Arguments )) {
  132. if ((CurInsert+PrintParameterCount) >= MAX_INSERTS) {
  133. return( STATUS_INVALID_PARAMETER );
  134. }
  135. if (ArgumentsAreAnsi) {
  136. if (s1[ -1 ] == L'c' && s1[ -2 ] != L'h'
  137. && s1[ -2 ] != L'w' && s1[ -2 ] != L'l') {
  138. wcscpy( &s1[ -1 ], L"hc" );
  139. }
  140. else
  141. if (s1[ -1 ] == L's' && s1[ -2 ] != L'h'
  142. && s1[ -2 ] != L'w' && s1[ -2 ] != L'l') {
  143. wcscpy( &s1[ -1 ], L"hs" );
  144. }
  145. else if (s1[ -1 ] == L'S') {
  146. s1[ -1 ] = L's';
  147. }
  148. else if (s1[ -1 ] == L'C') {
  149. s1[ -1 ] = L'c';
  150. }
  151. }
  152. while (CurInsert >= MaxInsert) {
  153. if (ArgumentsAreAnArray) {
  154. rgInserts[ MaxInsert++ ] = *((PULONG_PTR)Arguments)++;
  155. }
  156. else {
  157. rgInserts[ MaxInsert++ ] = va_arg(*Arguments, ULONG_PTR);
  158. }
  159. }
  160. s1 = (PWSTR)rgInserts[ CurInsert ];
  161. PrintParameter1 = 0;
  162. PrintParameter2 = 0;
  163. if (PrintParameterCount > 0) {
  164. if (ArgumentsAreAnArray) {
  165. PrintParameter1 = rgInserts[ MaxInsert++ ] = *((PULONG_PTR)Arguments)++;
  166. }
  167. else {
  168. PrintParameter1 = rgInserts[ MaxInsert++ ] = va_arg( *Arguments, ULONG_PTR );
  169. }
  170. if (PrintParameterCount > 1) {
  171. if (ArgumentsAreAnArray) {
  172. PrintParameter2 = rgInserts[ MaxInsert++ ] = *((PULONG_PTR)Arguments)++;
  173. }
  174. else {
  175. PrintParameter2 = rgInserts[ MaxInsert++ ] = va_arg( *Arguments, ULONG_PTR );
  176. }
  177. }
  178. }
  179. // Here is where we diverage and fro Trace Formatting we fixup parameters
  180. // %p becomes %s because thats the way we guarantee that its 64/32 compatible
  181. {
  182. SIZE_T len = _tcslen(PrintFormatString);
  183. if (_tcschr(PrintFormatString,L'p') != NULL ||
  184. (len >= 2) && (PrintFormatString[len-2] == 'I') ||
  185. (len >= 4) && (PrintFormatString[len-4] == 'I') &&
  186. (PrintFormatString[len-3] == '6') &&
  187. (PrintFormatString[len-2] == '4') )
  188. {
  189. _stprintf(PrintFormatString,_T("%%s"));
  190. }
  191. }
  192. cchWritten = _snwprintf( lpDst,
  193. cchRemaining,
  194. PrintFormatString,
  195. s1,
  196. PrintParameter1,
  197. PrintParameter2
  198. );
  199. if (cchWritten == -1) {
  200. return(STATUS_BUFFER_OVERFLOW);
  201. }
  202. }
  203. else {
  204. return( STATUS_INVALID_PARAMETER );
  205. }
  206. if ((cchRemaining -= cchWritten) <= 0) {
  207. return STATUS_BUFFER_OVERFLOW;
  208. }
  209. lpDst += cchWritten;
  210. }
  211. else
  212. if (*s == L'0') {
  213. break;
  214. }
  215. else
  216. if (!*s) {
  217. return( STATUS_INVALID_PARAMETER );
  218. }
  219. else
  220. if (*s == L'r') {
  221. if ((cchRemaining -= 1) <= 0) {
  222. return STATUS_BUFFER_OVERFLOW;
  223. }
  224. *lpDst++ = L'\r';
  225. s++;
  226. lpDstBeg = NULL;
  227. }
  228. else
  229. if (*s == L'n') {
  230. if ((cchRemaining -= 2) <= 0) {
  231. return STATUS_BUFFER_OVERFLOW;
  232. }
  233. *lpDst++ = L'\r';
  234. *lpDst++ = L'\n';
  235. s++;
  236. lpDstBeg = NULL;
  237. }
  238. else
  239. if (*s == L't') {
  240. if ((cchRemaining -= 1) <= 0) {
  241. return STATUS_BUFFER_OVERFLOW;
  242. }
  243. if (Column % 8) {
  244. Column = (Column + 7) & ~7;
  245. }
  246. else {
  247. Column += 8;
  248. }
  249. lpDstLastSpace = lpDst;
  250. *lpDst++ = L'\t';
  251. s++;
  252. }
  253. else
  254. if (*s == L'b') {
  255. if ((cchRemaining -= 1) <= 0) {
  256. return STATUS_BUFFER_OVERFLOW;
  257. }
  258. lpDstLastSpace = lpDst;
  259. *lpDst++ = L' ';
  260. s++;
  261. }
  262. else
  263. if (IgnoreInserts) {
  264. if ((cchRemaining -= 2) <= 0) {
  265. return STATUS_BUFFER_OVERFLOW;
  266. }
  267. *lpDst++ = L'%';
  268. *lpDst++ = *s++;
  269. }
  270. else {
  271. if ((cchRemaining -= 1) <= 0) {
  272. return STATUS_BUFFER_OVERFLOW;
  273. }
  274. *lpDst++ = *s++;
  275. }
  276. if (lpDstBeg == NULL) {
  277. lpDstLastSpace = NULL;
  278. Column = 0;
  279. }
  280. else {
  281. Column += (ULONG)(lpDst - lpDstBeg);
  282. }
  283. }
  284. else {
  285. c = *s++;
  286. if (c == L'\r' || c == L'\n') {
  287. if ((c == L'\n' && *s == L'\r') ||
  288. (c == L'\r' && *s == L'\n')
  289. ) {
  290. s++;
  291. }
  292. if (MaximumWidth != 0) {
  293. lpDstLastSpace = lpDst;
  294. c = L' ';
  295. }
  296. else {
  297. c = L'\n';
  298. }
  299. }
  300. if (c == L'\n') {
  301. if ((cchRemaining -= 2) <= 0) {
  302. return STATUS_BUFFER_OVERFLOW;
  303. }
  304. *lpDst++ = L'\r';
  305. *lpDst++ = L'\n';
  306. lpDstLastSpace = NULL;
  307. Column = 0;
  308. }
  309. else {
  310. if ((cchRemaining -= 1) <= 0) {
  311. return STATUS_BUFFER_OVERFLOW;
  312. }
  313. if (c == L' ') {
  314. lpDstLastSpace = lpDst;
  315. }
  316. *lpDst++ = c;
  317. Column += 1;
  318. }
  319. }
  320. if (MaximumWidth != 0 &&
  321. MaximumWidth != 0xFFFFFFFF &&
  322. Column >= MaximumWidth
  323. ) {
  324. if (lpDstLastSpace != NULL) {
  325. lpDstBeg = lpDstLastSpace;
  326. while (*lpDstBeg == L' ' || *lpDstBeg == L'\t') {
  327. lpDstBeg += 1;
  328. if (lpDstBeg == lpDst) {
  329. break;
  330. }
  331. }
  332. while (lpDstLastSpace > Buffer) {
  333. if (lpDstLastSpace[ -1 ] == L' ' || lpDstLastSpace[ -1 ] == L'\t') {
  334. lpDstLastSpace -= 1;
  335. }
  336. else {
  337. break;
  338. }
  339. }
  340. cSpaces = (ULONG)(lpDstBeg - lpDstLastSpace);
  341. if (cSpaces == 1) {
  342. if ((cchRemaining -= 1) <= 0) {
  343. return STATUS_BUFFER_OVERFLOW;
  344. }
  345. }
  346. else
  347. if (cSpaces > 2) {
  348. cchRemaining += (cSpaces - 2);
  349. }
  350. memmove( lpDstLastSpace + 2,
  351. lpDstBeg,
  352. (ULONG) ((lpDst - lpDstBeg) * sizeof( WCHAR ))
  353. );
  354. *lpDstLastSpace++ = L'\r';
  355. *lpDstLastSpace++ = L'\n';
  356. Column = (ULONG)(lpDst - lpDstBeg);
  357. lpDst = lpDstLastSpace + Column;
  358. lpDstLastSpace = NULL;
  359. }
  360. else {
  361. if ((cchRemaining -= 2) <= 0) {
  362. return STATUS_BUFFER_OVERFLOW;
  363. }
  364. *lpDst++ = L'\r';
  365. *lpDst++ = L'\n';
  366. lpDstLastSpace = NULL;
  367. Column = 0;
  368. }
  369. }
  370. }
  371. if ((cchRemaining -= 1) <= 0) {
  372. return STATUS_BUFFER_OVERFLOW;
  373. }
  374. *lpDst++ = '\0';
  375. if ( ARGUMENT_PRESENT(ReturnLength) ) {
  376. *ReturnLength = (ULONG)(lpDst - Buffer) * sizeof( WCHAR );
  377. }
  378. return( STATUS_SUCCESS );
  379. }
  380. #ifdef __cplusplus
  381. }
  382. #endif