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.

584 lines
12 KiB

  1. /*++
  2. Copyright (c) 1991-3 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. #include "procs.h"
  14. #if NWDBG
  15. //
  16. // Set DebugControl to 1 to open the logfile on the first NW call and close it
  17. // on process exit.
  18. //
  19. int DebugCtrl = 0;
  20. BOOL UseConsole = FALSE;
  21. BOOL UseLogFile = FALSE;
  22. BOOL Verbose = FALSE;
  23. HANDLE LogFile = INVALID_HANDLE_VALUE;
  24. #define LOGNAME (LPTSTR) TEXT("c:\\nwapi16.log")
  25. LONG NwMaxDump = SERVERNAME_LENGTH * MC; //128;
  26. #define ERR_BUF_SIZE 260
  27. #define NAME_BUF_SIZE 260
  28. extern UCHAR CpuInProtectMode;
  29. LPSTR
  30. ConvertFlagsToString(
  31. IN WORD FlagsRegister,
  32. OUT LPSTR Buffer
  33. );
  34. WORD
  35. GetFlags(
  36. VOID
  37. );
  38. VOID
  39. HexDumpLine(
  40. PCHAR pch,
  41. ULONG len,
  42. PCHAR s,
  43. PCHAR t
  44. );
  45. VOID
  46. DebugControl(
  47. int Command
  48. )
  49. /*++
  50. Routine Description:
  51. This routine controls what we output as debug information and where.
  52. Arguments:
  53. IN int Command
  54. Return Value:
  55. none.
  56. --*/
  57. {
  58. switch (Command) {
  59. case 0:
  60. UseLogFile = TRUE;
  61. break;
  62. case 1:
  63. UseConsole = TRUE;
  64. break;
  65. case 2:
  66. if (LogFile != INVALID_HANDLE_VALUE) {
  67. CloseHandle(LogFile);
  68. LogFile = INVALID_HANDLE_VALUE;
  69. }
  70. UseLogFile = FALSE;
  71. UseConsole = FALSE;
  72. break;
  73. case 8:
  74. Verbose = TRUE; // Same as 4 only chatty
  75. DebugCtrl = 4;
  76. case 4:
  77. UseLogFile = TRUE;
  78. break;
  79. }
  80. NwPrint(("DebugControl %x\n", Command ));
  81. }
  82. VOID
  83. NwPrintf(
  84. char *Format,
  85. ...
  86. )
  87. /*++
  88. Routine Description:
  89. This routine is equivalent to printf with the output being directed to
  90. stdout.
  91. Arguments:
  92. IN char *Format - Supplies string to be output and describes following
  93. (optional) parameters.
  94. Return Value:
  95. none.
  96. --*/
  97. {
  98. va_list arglist;
  99. char OutputBuffer[200];
  100. int length;
  101. if (( UseConsole == FALSE ) &&
  102. ( UseLogFile == FALSE )) {
  103. return;
  104. }
  105. va_start( arglist, Format );
  106. length = _vsnprintf( OutputBuffer, sizeof(OutputBuffer)-1, Format, arglist );
  107. if (length < 0) {
  108. return;
  109. }
  110. OutputBuffer[sizeof(OutputBuffer)-1] = '\0'; // in-case length= 199;
  111. va_end( arglist );
  112. if ( UseConsole ) {
  113. DbgPrint( "%s", OutputBuffer );
  114. } else {
  115. if ( LogFile == INVALID_HANDLE_VALUE ) {
  116. if ( UseLogFile ) {
  117. LogFile = CreateFile( LOGNAME,
  118. GENERIC_WRITE,
  119. FILE_SHARE_WRITE | FILE_SHARE_READ,
  120. NULL,
  121. TRUNCATE_EXISTING,
  122. FILE_ATTRIBUTE_NORMAL,
  123. NULL );
  124. if (LogFile == INVALID_HANDLE_VALUE) {
  125. LogFile = CreateFile( LOGNAME,
  126. GENERIC_WRITE,
  127. FILE_SHARE_WRITE | FILE_SHARE_READ,
  128. NULL,
  129. OPEN_ALWAYS,
  130. FILE_ATTRIBUTE_NORMAL,
  131. NULL );
  132. }
  133. if ( LogFile == INVALID_HANDLE_VALUE ) {
  134. UseLogFile = FALSE;
  135. return;
  136. }
  137. }
  138. }
  139. WriteFile( LogFile , (LPVOID )OutputBuffer, length, &length, NULL );
  140. }
  141. } // NwPrintf
  142. void
  143. FormattedDump(
  144. PCHAR far_p,
  145. LONG len
  146. )
  147. /*++
  148. Routine Description:
  149. This routine outputs a buffer in lines of text containing hex and
  150. printable characters.
  151. Arguments:
  152. IN far_p - Supplies buffer to be displayed.
  153. IN len - Supplies the length of the buffer in bytes.
  154. Return Value:
  155. none.
  156. --*/
  157. {
  158. ULONG l;
  159. char s[80], t[80];
  160. if (( UseConsole == FALSE ) &&
  161. ( UseLogFile == FALSE )) {
  162. return;
  163. }
  164. if (( len > NwMaxDump ) ||
  165. ( len < 0 )) {
  166. len = NwMaxDump;
  167. }
  168. while (len) {
  169. l = len < 16 ? len : 16;
  170. NwPrint(("%lx ", far_p));
  171. HexDumpLine (far_p, l, s, t);
  172. NwPrint(("%s%.*s%s\n", s, 1 + ((16 - l) * 3), "", t));
  173. len -= l;
  174. far_p += l;
  175. }
  176. }
  177. VOID
  178. HexDumpLine(
  179. PCHAR pch,
  180. ULONG len,
  181. PCHAR s,
  182. PCHAR t
  183. )
  184. /*++
  185. Routine Description:
  186. This routine builds a line of text containing hex and printable characters.
  187. Arguments:
  188. IN pch - Supplies buffer to be displayed.
  189. IN len - Supplies the length of the buffer in bytes.
  190. IN s - Supplies the start of the buffer to be loaded with the string
  191. of hex characters.
  192. IN t - Supplies the start of the buffer to be loaded with the string
  193. of printable ascii characters.
  194. Return Value:
  195. none.
  196. --*/
  197. {
  198. static UCHAR rghex[] = "0123456789ABCDEF";
  199. UCHAR c;
  200. UCHAR *hex, *asc;
  201. hex = s;
  202. asc = t;
  203. *(asc++) = '*';
  204. while (len--) {
  205. c = *(pch++);
  206. *(hex++) = rghex [c >> 4] ;
  207. *(hex++) = rghex [c & 0x0F];
  208. *(hex++) = ' ';
  209. *(asc++) = (c < ' ' || c > '~') ? (CHAR )'.' : c;
  210. }
  211. *(asc++) = '*';
  212. *asc = 0;
  213. *hex = 0;
  214. }
  215. VOID
  216. DisplayExtendedError(VOID)
  217. {
  218. TCHAR errorBuf[ERR_BUF_SIZE];
  219. TCHAR nameBuf[NAME_BUF_SIZE];
  220. DWORD errorCode;
  221. DWORD status;
  222. status = WNetGetLastError(
  223. &errorCode,
  224. errorBuf,
  225. ERR_BUF_SIZE,
  226. nameBuf,
  227. NAME_BUF_SIZE);
  228. if(status != WN_SUCCESS) {
  229. NwPrint(("nwapi32: WNetGetLastError failed %d\n",status));
  230. return;
  231. }
  232. NwPrint(("nwapi32: EXTENDED ERROR INFORMATION: (from GetLastError)\n"));
  233. NwPrint(("nwapi32: Code: %d\n",errorCode));
  234. NwPrint(("nwapi32: Description: "FORMAT_LPSTR"\n",errorBuf));
  235. NwPrint(("nwapi32: Provider: "FORMAT_LPSTR"\n\n",nameBuf));
  236. return;
  237. }
  238. VOID
  239. VrDumpRealMode16BitRegisters(
  240. IN BOOL DebugStyle
  241. )
  242. /*++
  243. Routine Description:
  244. Displays dump of 16-bit
  245. real-mode 80286 registers - gp registers (8), segment registers (4), flags
  246. register (1) instruction pointer register (1)
  247. Arguments:
  248. DebugStyle - determines look of output:
  249. DebugStyle == TRUE:
  250. ax=1111 bx=2222 cx=3333 dx=4444 sp=5555 bp=6666 si=7777 di=8888
  251. ds=aaaa es=bbbb ss=cccc cs=dddd ip=iiii fl fl fl fl fl fl fl fl
  252. DebugStyle == FALSE:
  253. cs:ip=cccc:iiii ss:sp=ssss:pppp bp=bbbb ax=1111 bx=2222 cx=3333 dx=4444
  254. ds:si=dddd:ssss es:di=eeee:dddd flags[ODIxSZxAxPxC]=fl fl fl fl fl fl fl fl
  255. Return Value:
  256. None.
  257. --*/
  258. {
  259. char flags_string[25];
  260. if (( UseConsole == FALSE ) &&
  261. ( UseLogFile == FALSE )) {
  262. return;
  263. }
  264. if (CpuInProtectMode) {
  265. NwPrint(( "Protect Mode:\n"));
  266. }
  267. if (DebugStyle) {
  268. NwPrint((
  269. "ax=%04x bx=%04x cx=%04x dx=%04x sp=%04x bp=%04x si=%04x di=%04x\n"
  270. "ds=%04x es=%04x ss=%04x cs=%04x ip=%04x %s\n\n",
  271. pNwDosTable->SavedAx, //getAX(),
  272. getBX(),
  273. getCX(),
  274. getDX(),
  275. getSP(),
  276. getBP(),
  277. getSI(),
  278. getDI(),
  279. getDS(),
  280. getES(),
  281. getSS(),
  282. getCS(),
  283. getIP(),
  284. ConvertFlagsToString(GetFlags(), flags_string)
  285. ));
  286. } else {
  287. NwPrint((
  288. "cs:ip=%04x:%04x ss:sp=%04x:%04x bp=%04x ax=%04x bx=%04x cx=%04x dx=%04x\n"
  289. "ds:si=%04x:%04x es:di=%04x:%04x flags[ODITSZxAxPxC]=%s\n\n",
  290. getCS(),
  291. getIP(),
  292. getSS(),
  293. getSP(),
  294. getBP(),
  295. pNwDosTable->SavedAx, //getAX(),
  296. getBX(),
  297. getCX(),
  298. getDX(),
  299. getDS(),
  300. getSI(),
  301. getES(),
  302. getDI(),
  303. ConvertFlagsToString(GetFlags(), flags_string)
  304. ));
  305. }
  306. }
  307. LPSTR
  308. ConvertFlagsToString(
  309. IN WORD FlagsRegister,
  310. OUT LPSTR Buffer
  311. )
  312. /*++
  313. Routine Description:
  314. Given a 16-bit word, interpret bit positions as for x86 Flags register
  315. and produce descriptive string of flags state (as per debug) eg:
  316. NV UP DI PL NZ NA PO NC ODItSZxAxPxC = 000000000000b
  317. OV DN EI NG ZR AC PE CY ODItSZxAxPxC = 111111111111b
  318. Trap Flag (t) is not dumped since this has no interest for programs which
  319. are not debuggers or don't examine program execution (ie virtually none)
  320. Arguments:
  321. FlagsRegister - 16-bit flags
  322. Buffer - place to store string. Requires 25 bytes inc \0
  323. Return Value:
  324. Address of <Buffer>
  325. --*/
  326. {
  327. static char* flags_states[16][2] = {
  328. //0 1
  329. "NC", "CY", // CF (0x0001) - Carry
  330. "", "", // x (0x0002)
  331. "PO", "PE", // PF (0x0004) - Parity
  332. "", "", // x (0x0008)
  333. "NA", "AC", // AF (0x0010) - Aux (half) carry
  334. "", "", // x (0x0020)
  335. "NZ", "ZR", // ZF (0x0040) - Zero
  336. "PL", "NG", // SF (0x0080) - Sign
  337. "", "", // TF (0x0100) - Trap (not dumped)
  338. "DI", "EI", // IF (0x0200) - Interrupt
  339. "UP", "DN", // DF (0x0400) - Direction
  340. "NV", "OV", // OF (0x0800) - Overflow
  341. "", "", // x (0x1000) - (I/O Privilege Level) (not dumped)
  342. "", "", // x (0x2000) - (I/O Privilege Level) (not dumped)
  343. "", "", // x (0x4000) - (Nested Task) (not dumped)
  344. "", "" // x (0x8000)
  345. };
  346. int i;
  347. WORD bit;
  348. BOOL on;
  349. *Buffer = 0;
  350. for (bit=0x0800, i=11; bit; bit >>= 1, --i) {
  351. on = (BOOL)((FlagsRegister & bit) == bit);
  352. if (flags_states[i][on][0]) {
  353. strcat(Buffer, flags_states[i][on]);
  354. strcat(Buffer, " ");
  355. }
  356. }
  357. return Buffer;
  358. }
  359. WORD
  360. GetFlags(
  361. VOID
  362. )
  363. /*++
  364. Routine Description:
  365. Supplies the missing softpc function
  366. Arguments:
  367. None.
  368. Return Value:
  369. Conglomerates softpc flags into x86 flags word
  370. --*/
  371. {
  372. WORD flags;
  373. flags = (WORD)getCF();
  374. flags |= (WORD)getPF() << 2;
  375. flags |= (WORD)getAF() << 4;
  376. flags |= (WORD)getZF() << 6;
  377. flags |= (WORD)getSF() << 7;
  378. flags |= (WORD)getIF() << 9;
  379. flags |= (WORD)getDF() << 10;
  380. flags |= (WORD)getOF() << 11;
  381. return flags;
  382. }
  383. VOID
  384. VrDumpNwData(
  385. VOID
  386. )
  387. /*++
  388. Routine Description:
  389. Dumps out the state of the 16 bit datastructures.
  390. Arguments:
  391. none.
  392. Return Value:
  393. None.
  394. --*/
  395. {
  396. int index;
  397. int Drive;
  398. if (Verbose == FALSE) {
  399. return;
  400. }
  401. NwPrint(( "Preferred = %x, Primary = %x\n",
  402. pNwDosTable->PreferredServer,
  403. pNwDosTable->PrimaryServer));
  404. for (index = 0; index < MC; index++) {
  405. if ((PUCHAR)pNwDosTable->ServerNameTable[index][0] != 0 ) {
  406. if (pNwDosTable->ConnectionIdTable[index].ci_InUse != IN_USE) {
  407. NwPrint(("Warning Connection not in use %x: %x\n",
  408. index,
  409. pNwDosTable->ConnectionIdTable[index].ci_InUse));
  410. }
  411. NwPrint((" Server %d = %s, Connection = %d\n",
  412. index,
  413. (PUCHAR)pNwDosTable-> ServerNameTable[index],
  414. (((pNwDosTable->ConnectionIdTable[index]).ci_ConnectionHi * 256) +
  415. ( pNwDosTable-> ConnectionIdTable[index]).ci_ConnectionLo )));
  416. } else {
  417. if (pNwDosTable->ConnectionIdTable[index].ci_InUse != FREE) {
  418. NwPrint(("Warning Connection in use but name is null %x: %x\n",
  419. index,
  420. pNwDosTable->ConnectionIdTable[index]));
  421. }
  422. }
  423. }
  424. for (Drive = 0; Drive < MD; Drive++ ) {
  425. if (pNwDosTable->DriveFlagTable[Drive] & 3) {
  426. NwPrint(("%c=%x on server %d,",'A' + Drive,
  427. pNwDosTable->DriveFlagTable[Drive],
  428. pNwDosTable->DriveIdTable[ Drive ] ));
  429. }
  430. }
  431. NwPrint(("\n"));
  432. }
  433. #endif