Windows NT 4.0 source code leak
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.

407 lines
7.7 KiB

4 years ago
  1. /*++
  2. Copyright (c) 1990 Microsoft Corporation
  3. Module Name:
  4. halvprnt.c
  5. Author:
  6. John Vert (jvert) 13-Aug-1991
  7. based on TomP's video.c
  8. Abstract:
  9. Video support routines.
  10. The vprintf function here outputs to the console via HalDisplayString.
  11. All the global variables have been made local, so multiple processors
  12. can execute it simultaneously. If this is the case, it relies on
  13. HalDisplayString to sort the output to avoid interleaving the text from
  14. the processors.
  15. History:
  16. --*/
  17. #include <ntos.h>
  18. typedef unsigned char BYTE, *PBYTE;
  19. //
  20. // Internal routines
  21. //
  22. static
  23. int
  24. xatoi(char c);
  25. static
  26. int
  27. fields(
  28. char *cp,
  29. int *zerofill,
  30. int *fieldwidth
  31. );
  32. static
  33. VOID
  34. putx(
  35. ULONG x,
  36. int digits,
  37. int zerofill,
  38. int *fieldwidth
  39. );
  40. static
  41. VOID
  42. puti(
  43. LONG i,
  44. int digits,
  45. int zerofill,
  46. int *fieldwidth
  47. );
  48. static
  49. VOID
  50. putu(
  51. ULONG u,
  52. int digits,
  53. int zerofill,
  54. int *fieldwidth
  55. );
  56. static
  57. VOID
  58. putc(
  59. CHAR c
  60. );
  61. /*++
  62. Name
  63. vprintf - DbgPrint function on standard video
  64. Currently handles
  65. %i, %li - signed short, signed long (same as d)
  66. %d, %ld - signed short, signed long
  67. %u, %lu - unsigned short, unsigned long
  68. %c, %s, %.*s - character, string
  69. %Z - PSTRING data type
  70. %x, %lx - unsigned print in hex, unsigned long print in hex
  71. %X, %lX, %X, %X, %X, %X - same as %x and %lx
  72. field widths
  73. leading 0 fills
  74. Does not do yet:
  75. No floating point.
  76. --*/
  77. void
  78. vprintf(PCHAR cp,USHORT a1)
  79. {
  80. ULONG cb;
  81. USHORT b,c;
  82. PBYTE ap;
  83. PCHAR s;
  84. PSTRING str;
  85. ULONG Flags;
  86. int zerofill, fieldwidth;
  87. //
  88. // Cast a pointer to the first word on the stack
  89. //
  90. ap = (PBYTE)&a1;
  91. // Save flags in automatic variable on stack, turn off ints.
  92. _asm {
  93. pushfd
  94. pop Flags
  95. cli
  96. }
  97. //
  98. // Process the argements using the descriptor string
  99. //
  100. while (b = *cp++) {
  101. if (b == '%') {
  102. cp += fields(cp, &zerofill, &fieldwidth);
  103. c = *cp++;
  104. switch (c) {
  105. case '.':
  106. if (*cp != '*' || cp[1] != 's') {
  107. putc((char)b);
  108. putc((char)c);
  109. break;
  110. }
  111. cp += 2;
  112. cb = *((ULONG *)ap);
  113. ap += sizeof( ULONG );
  114. s = *((PCHAR *)ap);
  115. ap += sizeof( PCHAR );
  116. if (s == NULL) {
  117. s = "(null)";
  118. cb = 6;
  119. }
  120. if (cb > 0xFFF) {
  121. s = "(overflow)";
  122. cb = 10;
  123. }
  124. while (cb--) {
  125. if (*s) {
  126. putc(*s++);
  127. } else {
  128. putc(' ');
  129. }
  130. }
  131. break;
  132. case 'i':
  133. case 'd':
  134. puti((long)*((int *)ap), 1, zerofill, &fieldwidth);
  135. ap += sizeof(int);
  136. break;
  137. case 'S':
  138. str = *((PSTRING *)ap);
  139. ap += sizeof (STRING *);
  140. b = str->Length;
  141. s = str->Buffer;
  142. if (s == NULL)
  143. s = "(null)";
  144. while (b--)
  145. putc(*s++);
  146. break;
  147. case 's':
  148. s = *((PCHAR *)ap);
  149. ap += sizeof( PCHAR );
  150. if (s == NULL)
  151. s = "(null)";
  152. while (*s)
  153. putc(*s++);
  154. break;
  155. case 'c':
  156. putc(*((char *)ap));
  157. ap += sizeof(int);
  158. break;
  159. //
  160. // If we cannot find the status value in the table, print it in
  161. // hex.
  162. //
  163. case 'C':
  164. case 'B':
  165. //
  166. // Should search bugcodes.h to display bug code
  167. // symbolically. For now just show as hex
  168. //
  169. case 'X':
  170. case 'x':
  171. putx((ULONG)*((USHORT *)ap), 1, zerofill, &fieldwidth);
  172. ap += sizeof(int);
  173. break;
  174. case 'u':
  175. putu((ULONG)*((USHORT *)ap), 1, zerofill, &fieldwidth);
  176. ap += sizeof(int);
  177. break;
  178. case 'l':
  179. c = *cp++;
  180. switch(c) {
  181. case 'u':
  182. putu(*((ULONG *)ap), 1, zerofill, &fieldwidth);
  183. ap += sizeof(long);
  184. break;
  185. case 'C':
  186. case 'B':
  187. //
  188. // Should search bugcodes.h to display bug code
  189. // symbolically. For now just show as hex
  190. //
  191. case 'X':
  192. case 'x':
  193. putx(*((ULONG *)ap), 1, zerofill, &fieldwidth);
  194. ap += sizeof(long);
  195. break;
  196. case 'i':
  197. case 'd':
  198. puti(*((ULONG *)ap), 1, zerofill, &fieldwidth);
  199. ap += sizeof(long);
  200. break;
  201. } // inner switch
  202. break;
  203. default :
  204. putc((char)b);
  205. putc((char)c);
  206. } // outer switch
  207. } // if
  208. else
  209. putc((char)b);
  210. } // while
  211. // Restore flags from automatic variable on stack
  212. _asm {
  213. push Flags
  214. popfd
  215. }
  216. return;
  217. }
  218. //
  219. // Fields computation
  220. //
  221. static int fields(char *cp, int *zerofill, int *fieldwidth)
  222. {
  223. int incval = 0;
  224. *zerofill = 0;
  225. *fieldwidth = 0;
  226. if (*cp == '0') {
  227. *zerofill = 1;
  228. cp++;
  229. incval++;
  230. }
  231. while ((*cp >= '0') && (*cp <= '9')) {
  232. *fieldwidth = (*fieldwidth * 10) + xatoi(*cp);
  233. cp++;
  234. incval++;
  235. }
  236. return incval;
  237. }
  238. //
  239. // Write a hex short to display
  240. //
  241. static void putx(ULONG x, int digits, int zerofill, int *fieldwidth)
  242. {
  243. ULONG j;
  244. if (x/16)
  245. putx(x/16, digits+1, zerofill, fieldwidth);
  246. if (*fieldwidth > digits) {
  247. while (*fieldwidth > digits) {
  248. if (zerofill)
  249. putc('0');
  250. else
  251. putc(' ');
  252. *fieldwidth--;
  253. }
  254. }
  255. *fieldwidth = 0;
  256. if((j=x%16) > 9)
  257. putc((char)(j+'A'- 10));
  258. else
  259. putc((char)(j+'0'));
  260. }
  261. //
  262. // Write a short integer to display
  263. //
  264. static void puti(long i, int digits, int zerofill, int *fieldwidth)
  265. {
  266. if (i<0) {
  267. i = -i;
  268. putc((char)'-');
  269. }
  270. if (i/10)
  271. puti(i/10, digits+1, zerofill, fieldwidth);
  272. if (*fieldwidth > digits) {
  273. while (*fieldwidth > digits) {
  274. if (zerofill)
  275. putc('0');
  276. else
  277. putc(' ');
  278. *fieldwidth--;
  279. }
  280. }
  281. *fieldwidth = 0;
  282. putc((char)((i%10)+'0'));
  283. }
  284. //
  285. // Write an unsigned short to display
  286. //
  287. static void putu(ULONG u, int digits, int zerofill, int *fieldwidth)
  288. {
  289. if (u/10)
  290. putu(u/10, digits+1, zerofill, fieldwidth);
  291. if (*fieldwidth > digits) {
  292. while (*fieldwidth > digits) {
  293. if (zerofill)
  294. putc('0');
  295. else
  296. putc(' ');
  297. *fieldwidth--;
  298. }
  299. }
  300. *fieldwidth = 0;
  301. putc((char)((u%10)+'0'));
  302. }
  303. //
  304. // Write a character to display
  305. //
  306. VOID putc(
  307. CHAR c
  308. )
  309. {
  310. static UCHAR OneCharacter[2];
  311. OneCharacter[1] = '\0';
  312. OneCharacter[0] = c;
  313. HalDisplayString(OneCharacter);
  314. }
  315. //
  316. // Return the integer value of numeral represented by ascii char
  317. //
  318. int xatoi(char c)
  319. {
  320. return c - '0';
  321. }