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.

369 lines
8.8 KiB

  1. /*++
  2. Copyright (c) 1991 Microsoft Corporation
  3. Module Name:
  4. debug.c
  5. Abstract:
  6. This component of netbios runs in the user process and can ( when
  7. built in a debug kernel) will log to either the console or through the
  8. kernel debugger.
  9. Author:
  10. Colin Watson (ColinW) 24-Jun-91
  11. Revision History:
  12. --*/
  13. #if DBG
  14. #include <netb.h>
  15. #include <stdarg.h>
  16. #include <stdio.h>
  17. ULONG NbDllDebug = 0x0;
  18. #define NB_DLL_DEBUG_NCB 0x00000001 // print all NCB's submitted
  19. #define NB_DLL_DEBUG_NCB_BUFF 0x00000002 // print buffers for NCB's submitted
  20. BOOL UseConsole = FALSE;
  21. BOOL UseLogFile = TRUE;
  22. HANDLE LogFile = INVALID_HANDLE_VALUE;
  23. #define LOGNAME (LPTSTR) TEXT("netbios.log")
  24. LONG NbMaxDump = 128;
  25. // Macro used in DisplayNcb
  26. #define DISPLAY_COMMAND( cmd ) \
  27. case cmd: NbPrintf(( #cmd )); break;
  28. VOID
  29. FormattedDump(
  30. PCHAR far_p,
  31. LONG len
  32. );
  33. VOID
  34. HexDumpLine(
  35. PCHAR pch,
  36. ULONG len,
  37. PCHAR s,
  38. PCHAR t
  39. );
  40. VOID
  41. DisplayNcb(
  42. IN PNCBI pncbi
  43. )
  44. /*++
  45. Routine Description:
  46. This routine displays on the standard output stream the contents
  47. of the Ncb.
  48. Arguments:
  49. IN PNCBI - Supplies the NCB to be displayed.
  50. Return Value:
  51. none.
  52. --*/
  53. {
  54. if ( (NbDllDebug & NB_DLL_DEBUG_NCB) == 0 ) {
  55. return;
  56. }
  57. NbPrintf(( "PNCB %#010lx\n", pncbi));
  58. NbPrintf(( "ncb_command %#04x ", pncbi->ncb_command));
  59. switch ( pncbi->ncb_command & ~ASYNCH ) {
  60. DISPLAY_COMMAND( NCBCALL );
  61. DISPLAY_COMMAND( NCBLISTEN );
  62. DISPLAY_COMMAND( NCBHANGUP );
  63. DISPLAY_COMMAND( NCBSEND );
  64. DISPLAY_COMMAND( NCBRECV );
  65. DISPLAY_COMMAND( NCBRECVANY );
  66. DISPLAY_COMMAND( NCBCHAINSEND );
  67. DISPLAY_COMMAND( NCBDGSEND );
  68. DISPLAY_COMMAND( NCBDGRECV );
  69. DISPLAY_COMMAND( NCBDGSENDBC );
  70. DISPLAY_COMMAND( NCBDGRECVBC );
  71. DISPLAY_COMMAND( NCBADDNAME );
  72. DISPLAY_COMMAND( NCBDELNAME );
  73. DISPLAY_COMMAND( NCBRESET );
  74. DISPLAY_COMMAND( NCBASTAT );
  75. DISPLAY_COMMAND( NCBSSTAT );
  76. DISPLAY_COMMAND( NCBCANCEL );
  77. DISPLAY_COMMAND( NCBADDGRNAME );
  78. DISPLAY_COMMAND( NCBENUM );
  79. DISPLAY_COMMAND( NCBUNLINK );
  80. DISPLAY_COMMAND( NCBSENDNA );
  81. DISPLAY_COMMAND( NCBCHAINSENDNA );
  82. DISPLAY_COMMAND( NCBLANSTALERT );
  83. DISPLAY_COMMAND( NCBFINDNAME );
  84. // Extensions
  85. DISPLAY_COMMAND( NCALLNIU );
  86. DISPLAY_COMMAND( NCBQUICKADDNAME );
  87. DISPLAY_COMMAND( NCBQUICKADDGRNAME );
  88. DISPLAY_COMMAND( NCBACTION );
  89. default: NbPrintf(( " Unknown type")); break;
  90. }
  91. if ( pncbi->ncb_command & ASYNCH ) {
  92. NbPrintf(( " | ASYNCH"));
  93. }
  94. NbPrintf(( "\nncb_retcode %#04x\n", pncbi->ncb_retcode));
  95. NbPrintf(( "ncb_lsn %#04x\n", pncbi->ncb_lsn));
  96. NbPrintf(( "ncb_num %#04x\n", pncbi->ncb_num));
  97. NbPrintf(( "ncb_buffer %#010lx\n",pncbi->ncb_buffer));
  98. NbPrintf(( "ncb_length %#06x\n", pncbi->ncb_length));
  99. NbPrintf(( "\nncb_callname and ncb->name\n"));
  100. FormattedDump( pncbi->cu.ncb_callname, NCBNAMSZ );
  101. FormattedDump( pncbi->ncb_name, NCBNAMSZ );
  102. if (((pncbi->ncb_command & ~ASYNCH) == NCBCHAINSEND) ||
  103. ((pncbi->ncb_command & ~ASYNCH) == NCBCHAINSENDNA)) {
  104. NbPrintf(( "ncb_length2 %#06x\n", pncbi->cu.ncb_chain.ncb_length2));
  105. NbPrintf(( "ncb_buffer2 %#010lx\n",pncbi->cu.ncb_chain.ncb_buffer2));
  106. }
  107. NbPrintf(( "ncb_rto %#04x\n", pncbi->ncb_rto));
  108. NbPrintf(( "ncb_sto %#04x\n", pncbi->ncb_sto));
  109. NbPrintf(( "ncb_post %lx\n", pncbi->ncb_post));
  110. NbPrintf(( "ncb_lana_num %#04x\n", pncbi->ncb_lana_num));
  111. NbPrintf(( "ncb_cmd_cplt %#04x\n", pncbi->ncb_cmd_cplt));
  112. NbPrintf(( "ncb_reserve\n"));
  113. FormattedDump( ((PNCB)pncbi)->ncb_reserve, 14 );
  114. NbPrintf(( "ncb_next\n"));
  115. FormattedDump( (PCHAR)&pncbi->u.ncb_next, sizeof( LIST_ENTRY) );
  116. NbPrintf(( "ncb_iosb\n"));
  117. FormattedDump( (PCHAR)&pncbi->u.ncb_iosb, sizeof( IO_STATUS_BLOCK ) );
  118. NbPrintf(( "ncb_event %#04x\n", pncbi->ncb_event));
  119. if ( (NbDllDebug & NB_DLL_DEBUG_NCB_BUFF) == 0 ) {
  120. NbPrintf(( "\n\n" ));
  121. return;
  122. }
  123. switch ( pncbi->ncb_command & ~ASYNCH ) {
  124. case NCBSEND:
  125. case NCBCHAINSEND:
  126. case NCBDGSEND:
  127. case NCBSENDNA:
  128. case NCBCHAINSENDNA:
  129. if ( pncbi->ncb_retcode == NRC_PENDING ) {
  130. //
  131. // If pending then presumably we have not displayed the ncb
  132. // before. After its been sent there isn't much point in displaying
  133. // the buffer again.
  134. //
  135. NbPrintf(( "ncb_buffer contents:\n"));
  136. FormattedDump( pncbi->ncb_buffer, pncbi->ncb_length );
  137. }
  138. break;
  139. case NCBRECV:
  140. case NCBRECVANY:
  141. case NCBDGRECV:
  142. case NCBDGSENDBC:
  143. case NCBDGRECVBC:
  144. case NCBENUM:
  145. case NCBASTAT:
  146. case NCBSSTAT:
  147. case NCBFINDNAME:
  148. if ( pncbi->ncb_retcode != NRC_PENDING ) {
  149. // Buffer has been loaded with data
  150. NbPrintf(( "ncb_buffer contents:\n"));
  151. FormattedDump( pncbi->ncb_buffer, pncbi->ncb_length );
  152. }
  153. break;
  154. case NCBCANCEL:
  155. // Buffer has been loaded with the NCB to be cancelled
  156. NbPrintf(( "ncb_buffer contents:\n"));
  157. FormattedDump( pncbi->ncb_buffer, sizeof(NCB));
  158. break;
  159. }
  160. NbPrintf(( "\n\n" ));
  161. }
  162. VOID
  163. NbPrint(
  164. char *Format,
  165. ...
  166. )
  167. /*++
  168. Routine Description:
  169. This routine is equivalent to printf with the output being directed to
  170. stdout.
  171. Arguments:
  172. IN char *Format - Supplies string to be output and describes following
  173. (optional) parameters.
  174. Return Value:
  175. none.
  176. --*/
  177. {
  178. va_list arglist;
  179. char OutputBuffer[1024];
  180. ULONG length;
  181. if ( NbDllDebug == 0 ) {
  182. return;
  183. }
  184. va_start( arglist, Format );
  185. vsprintf( OutputBuffer, Format, arglist );
  186. va_end( arglist );
  187. if ( UseConsole ) {
  188. DbgPrint( "%s", OutputBuffer );
  189. } else {
  190. length = strlen( OutputBuffer );
  191. if ( LogFile == INVALID_HANDLE_VALUE ) {
  192. if ( UseLogFile ) {
  193. LogFile = CreateFile( LOGNAME,
  194. GENERIC_WRITE,
  195. FILE_SHARE_WRITE,
  196. NULL,
  197. OPEN_ALWAYS,
  198. FILE_ATTRIBUTE_NORMAL,
  199. NULL );
  200. if ( LogFile == INVALID_HANDLE_VALUE ) {
  201. // Could not access logfile so use stdout instead
  202. UseLogFile = FALSE;
  203. LogFile = GetStdHandle(STD_OUTPUT_HANDLE);
  204. }
  205. } else {
  206. // Use the applications stdout file.
  207. LogFile = GetStdHandle(STD_OUTPUT_HANDLE);
  208. }
  209. }
  210. WriteFile( LogFile , (LPVOID )OutputBuffer, length, &length, NULL );
  211. }
  212. } // NbPrint
  213. void
  214. FormattedDump(
  215. PCHAR far_p,
  216. LONG len
  217. )
  218. /*++
  219. Routine Description:
  220. This routine outputs a buffer in lines of text containing hex and
  221. printable characters.
  222. Arguments:
  223. IN far_p - Supplies buffer to be displayed.
  224. IN len - Supplies the length of the buffer in bytes.
  225. Return Value:
  226. none.
  227. --*/
  228. {
  229. ULONG l;
  230. char s[80], t[80];
  231. if ( len > NbMaxDump ) {
  232. len = NbMaxDump;
  233. }
  234. while (len) {
  235. l = len < 16 ? len : 16;
  236. NbPrintf (("%lx ", far_p));
  237. HexDumpLine (far_p, l, s, t);
  238. NbPrintf (("%s%.*s%s\n", s, 1 + ((16 - l) * 3), "", t));
  239. len -= l;
  240. far_p += l;
  241. }
  242. }
  243. VOID
  244. HexDumpLine(
  245. PCHAR pch,
  246. ULONG len,
  247. PCHAR s,
  248. PCHAR t
  249. )
  250. /*++
  251. Routine Description:
  252. This routine builds a line of text containing hex and printable characters.
  253. Arguments:
  254. IN pch - Supplies buffer to be displayed.
  255. IN len - Supplies the length of the buffer in bytes.
  256. IN s - Supplies the start of the buffer to be loaded with the string
  257. of hex characters.
  258. IN t - Supplies the start of the buffer to be loaded with the string
  259. of printable ascii characters.
  260. Return Value:
  261. none.
  262. --*/
  263. {
  264. static UCHAR rghex[] = "0123456789ABCDEF";
  265. UCHAR c;
  266. UCHAR *hex, *asc;
  267. hex = s;
  268. asc = t;
  269. *(asc++) = '*';
  270. while (len--) {
  271. c = *(pch++);
  272. *(hex++) = rghex [c >> 4] ;
  273. *(hex++) = rghex [c & 0x0F];
  274. *(hex++) = ' ';
  275. *(asc++) = (c < ' ' || c > '~') ? (CHAR )'.' : c;
  276. }
  277. *(asc++) = '*';
  278. *asc = 0;
  279. *hex = 0;
  280. }
  281. #endif
  282.