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.

711 lines
17 KiB

  1. /*++
  2. Copyright (c) 1998 Microsoft Corporation
  3. Module Name:
  4. nbfcom.c
  5. Abstract:
  6. This file contains the generic routines
  7. for the kernel debugger extensions dll.
  8. Author:
  9. Chaitanya Kodeboyina (Chaitk)
  10. Environment:
  11. User Mode
  12. --*/
  13. #include "precomp.h"
  14. #pragma hdrstop
  15. //
  16. // Misc Helper Routines
  17. //
  18. ULONG
  19. GetLocation (
  20. PCHAR String
  21. )
  22. {
  23. ULONG Location;
  24. Location = GetExpression( String );
  25. if (!Location) {
  26. dprintf("unable to get %s\n",String);
  27. return 0;
  28. }
  29. return Location;
  30. }
  31. ULONG
  32. GetUlongValue (
  33. PCHAR String
  34. )
  35. {
  36. ULONG Location;
  37. ULONG Value;
  38. ULONG result;
  39. Location = GetExpression( String );
  40. if (!Location) {
  41. dprintf("unable to get %s\n",String);
  42. return 0;
  43. }
  44. if ((!ReadMemory((DWORD)Location,&Value,sizeof(ULONG),&result)) ||
  45. (result < sizeof(ULONG))) {
  46. dprintf("unable to get %s\n",String);
  47. return 0;
  48. }
  49. return Value;
  50. }
  51. VOID
  52. dprintSymbolPtr
  53. (
  54. PVOID Pointer,
  55. PCHAR EndOfLine
  56. )
  57. {
  58. UCHAR SymbolName[ 80 ];
  59. ULONG Displacement;
  60. GetSymbol( Pointer, SymbolName, &Displacement );
  61. if ( Displacement == 0 )
  62. {
  63. dprintf( "(%s)%s", SymbolName, EndOfLine );
  64. }
  65. else
  66. {
  67. dprintf( "(%s + 0x%X)%s", SymbolName, Displacement, EndOfLine );
  68. }
  69. }
  70. VOID
  71. dprint_nchar
  72. (
  73. PCHAR pch,
  74. int cch
  75. )
  76. {
  77. CHAR ch;
  78. int index;
  79. for ( index = 0; index < cch; index ++ )
  80. {
  81. ch = pch[ index ];
  82. dprintf( "%c", ( ch >= 32 ) ? ch : '.' );
  83. }
  84. }
  85. VOID
  86. dprint_hardware_address
  87. (
  88. PUCHAR Address
  89. )
  90. {
  91. dprintf( "%02x-%02x-%02x-%02x-%02x-%02x",
  92. Address[ 0 ],
  93. Address[ 1 ],
  94. Address[ 2 ],
  95. Address[ 3 ],
  96. Address[ 4 ],
  97. Address[ 5 ] );
  98. }
  99. BOOL
  100. dprint_enum_name
  101. (
  102. ULONG Value,
  103. PENUM_INFO pEnumInfo
  104. )
  105. {
  106. while ( pEnumInfo->pszDescription != NULL )
  107. {
  108. if ( pEnumInfo->Value == Value )
  109. {
  110. dprintf( "%.40s", pEnumInfo->pszDescription );
  111. return( TRUE );
  112. }
  113. pEnumInfo ++;
  114. }
  115. dprintf( "Unknown enumeration value." );
  116. return( FALSE );
  117. }
  118. BOOL
  119. dprint_flag_names
  120. (
  121. ULONG Value,
  122. PFLAG_INFO pFlagInfo
  123. )
  124. {
  125. BOOL bFoundOne = FALSE;
  126. while ( pFlagInfo->pszDescription != NULL )
  127. {
  128. if ( pFlagInfo->Value & Value )
  129. {
  130. if ( bFoundOne )
  131. {
  132. dprintf( " | " );
  133. }
  134. bFoundOne = TRUE;
  135. dprintf( "%.15s", pFlagInfo->pszDescription );
  136. }
  137. pFlagInfo ++;
  138. }
  139. return( bFoundOne );
  140. }
  141. BOOL
  142. dprint_masked_value
  143. (
  144. ULONG Value,
  145. ULONG Mask
  146. )
  147. {
  148. CHAR Buf[ 9 ];
  149. ULONG nibble;
  150. int index;
  151. for ( index = 0; index < 8; index ++ )
  152. {
  153. nibble = ( Mask & 0xF0000000 );
  154. /*
  155. dprintf( "#%d: nibble == %08X\n"
  156. " Mask == %08X\n"
  157. " Value == %08X\n", index, nibble, Mask, Value );
  158. */
  159. if ( nibble )
  160. {
  161. Buf[ index ] = "0123456789abcdef"[ (( nibble & Value ) >> 28) & 0xF ];
  162. }
  163. else
  164. {
  165. Buf[ index ] = ' ';
  166. }
  167. Mask <<= 4;
  168. Value <<= 4;
  169. }
  170. Buf[ 8 ] = '\0';
  171. dprintf( "%s", Buf );
  172. return( TRUE );
  173. }
  174. VOID dprint_addr_list
  175. (
  176. ULONG FirstAddress,
  177. ULONG OffsetToNextPtr
  178. )
  179. {
  180. ULONG Address;
  181. ULONG result;
  182. int index;
  183. Address = FirstAddress;
  184. if ( Address == (ULONG)NULL )
  185. {
  186. dprintf( "%08X (Empty)\n", Address );
  187. return;
  188. }
  189. dprintf( "{ " );
  190. for ( index = 0; Address != (ULONG)NULL; index ++ )
  191. {
  192. if ( index != 0 )
  193. {
  194. dprintf( ", ");
  195. }
  196. dprintf( "%08X", Address );
  197. if ( !ReadMemory( Address + OffsetToNextPtr,
  198. &Address,
  199. sizeof( Address ),
  200. &result ))
  201. {
  202. dprintf( "ReadMemory() failed." );
  203. Address = (ULONG)NULL;
  204. }
  205. }
  206. dprintf( " }\n" );
  207. }
  208. VOID PrintStringofLenN(PVOID Pointer, ULONG PtrProxy, ULONG printDetail)
  209. {
  210. dprint_nchar((CHAR *)Pointer, 16);
  211. }
  212. VOID PrintClosestSymbol(PVOID Pointer, ULONG PtrProxy, ULONG printDetail)
  213. {
  214. dprintSymbolPtr((PVOID)(*(ULONG *)Pointer), "");
  215. }
  216. VOID PrintFields
  217. (
  218. PVOID pStructure,
  219. ULONG structProxy,
  220. CHAR *fieldPrefix,
  221. ULONG printDetail,
  222. StructAccessInfo *pStructInfo
  223. )
  224. {
  225. FieldAccessInfo *pFieldInfo;
  226. BOOLEAN printAll;
  227. BOOLEAN printField;
  228. UINT i, j, k;
  229. ULONG *pUlong;
  230. ULONG proxyPtr;
  231. ULONG childDetail;
  232. dprintf("\n@@Struct: %s @ %08x\n", pStructInfo->Name, structProxy);
  233. if (printDetail == NULL_INFO)
  234. {
  235. return;
  236. }
  237. if ((fieldPrefix == NULL) || (fieldPrefix[0] == '\0'))
  238. printAll = TRUE;
  239. else
  240. printAll = FALSE;
  241. for (i = 0; i < MAX_FIELD; i++)
  242. {
  243. pFieldInfo = &pStructInfo->fieldInfo[i];
  244. if (pFieldInfo->Name[0] == '\0')
  245. break;
  246. printField = FALSE;
  247. if ((printDetail == FULL_SHAL)
  248. || (printDetail == FULL_DEEP)
  249. || (pFieldInfo->Importance == HIG)
  250. || ((printDetail != SUMM_INFO) &&
  251. (pFieldInfo->Importance > LOW)))
  252. {
  253. printField = TRUE;
  254. }
  255. if (pFieldInfo->Name[0] == '@')
  256. {
  257. if (printField)
  258. {
  259. dprintf("\n");
  260. }
  261. continue;
  262. }
  263. if ((printAll) || strstr(pFieldInfo->Name, fieldPrefix))
  264. {
  265. pUlong = (ULONG *)(((CHAR *)pStructure) + pFieldInfo->Offset);
  266. proxyPtr = (ULONG)(((CHAR *)structProxy) + pFieldInfo->Offset);
  267. if (pFieldInfo->PrintField)
  268. {
  269. switch (printDetail)
  270. {
  271. case FULL_DEEP:
  272. case NORM_DEEP:
  273. childDetail = printDetail;
  274. break;
  275. case NORM_SHAL:
  276. case FULL_SHAL:
  277. childDetail = SUMM_INFO;
  278. break;
  279. case SUMM_INFO:
  280. childDetail = NULL_INFO;
  281. }
  282. if (printField)
  283. {
  284. dprintf("@Field: %40s\t", pFieldInfo->Name);
  285. dprintf("\n%08x ", proxyPtr);
  286. pFieldInfo->PrintField(pUlong,
  287. proxyPtr,
  288. childDetail);
  289. dprintf("\n");
  290. }
  291. }
  292. else
  293. {
  294. if (printField)
  295. {
  296. dprintf("@Field: %40s\t", pFieldInfo->Name);
  297. if (pFieldInfo->Size <= sizeof(ULONG))
  298. {
  299. dprintf("%08x ", proxyPtr);
  300. j = pFieldInfo->Size;
  301. }
  302. else
  303. {
  304. for (k = 0, j = 4; j <= pFieldInfo->Size; j += 4)
  305. {
  306. if (j % 16 == 4)
  307. {
  308. k = (k + 1) % 8;
  309. if (k == 0)
  310. {
  311. dprintf("\n");
  312. }
  313. dprintf("\n%08x ", proxyPtr);
  314. proxyPtr += 0x10;
  315. }
  316. dprintf(" %08x", *pUlong++);
  317. }
  318. j = pFieldInfo->Size - j + 4;
  319. }
  320. switch (j)
  321. {
  322. case 4:
  323. dprintf(" %08x", *pUlong);
  324. break;
  325. case 3:
  326. dprintf(" ....%04x", *(USHORT *)pUlong);
  327. pUlong = (ULONG *)(((UCHAR *)pUlong) + 2);
  328. dprintf(" ......%02x", *(UCHAR *)pUlong);
  329. break;
  330. case 2:
  331. dprintf(" ....%04x", *(USHORT *)pUlong);
  332. break;
  333. case 1:
  334. dprintf(" ......%02x", *(UCHAR *)pUlong);
  335. break;
  336. }
  337. dprintf("\n");
  338. }
  339. }
  340. }
  341. }
  342. }
  343. //
  344. // Misc NBF Specific Helpers
  345. //
  346. #if PKT_LOG
  347. VOID PrintPktLogQue(PVOID pointer, ULONG proxyPtr, ULONG printDetail)
  348. {
  349. UINT i, j;
  350. PKT_LOG_QUE PktLog;
  351. PKT_LOG_QUE *pPktLog;
  352. ULONG bytesRead;
  353. // Get list of logged packets & debug print level
  354. if (pointer == NULL)
  355. {
  356. // Read the packet log queue
  357. if (!ReadMemory(proxyPtr, &PktLog, sizeof(PKT_LOG_QUE), &bytesRead))
  358. {
  359. dprintf("%s @ %08x: Could not read structure\n",
  360. "Packet Log Queue", proxyPtr);
  361. return;
  362. }
  363. pPktLog = &PktLog;
  364. }
  365. else
  366. {
  367. pPktLog = (PKT_LOG_QUE *) pointer;
  368. }
  369. // Print the packet log queue
  370. dprintf("PktNext = %d, PktQue = %08x\n",
  371. pPktLog->PktNext,
  372. &((PKT_LOG_QUE *)proxyPtr)->PktQue);
  373. for (i = 0; i < PKT_QUE_SIZE; i++)
  374. {
  375. j = (pPktLog->PktNext + i) % PKT_QUE_SIZE;
  376. dprintf("P%02d: TS = %05d, BT = %5d, BS = %5d, DH = %08x, PD = %08x\n",
  377. j,
  378. pPktLog->PktQue[j].TimeLogged,
  379. pPktLog->PktQue[j].BytesTotal,
  380. pPktLog->PktQue[j].BytesSaved,
  381. *(ULONG *)pPktLog->PktQue[j].PacketData,
  382. &((PKT_LOG_QUE *)proxyPtr)->PktQue[j].PacketData);
  383. }
  384. }
  385. VOID PrintPktIndQue(PVOID pointer, ULONG proxyPtr, ULONG printDetail)
  386. {
  387. UINT i, j;
  388. PKT_IND_QUE PktLog;
  389. PKT_IND_QUE *pPktLog;
  390. ULONG bytesRead;
  391. // Get list of logged packets & debug print level
  392. if (pointer == NULL)
  393. {
  394. // Read the packet log queue
  395. if (!ReadMemory(proxyPtr, &PktLog, sizeof(PKT_IND_QUE), &bytesRead))
  396. {
  397. dprintf("%s @ %08x: Could not read structure\n",
  398. "Packet Ind Queue", proxyPtr);
  399. return;
  400. }
  401. pPktLog = &PktLog;
  402. }
  403. else
  404. {
  405. pPktLog = (PKT_IND_QUE *) pointer;
  406. }
  407. // Print the packet log queue
  408. dprintf("PktNext = %d, PktQue = %08x\n",
  409. pPktLog->PktNext,
  410. &((PKT_IND_QUE *)proxyPtr)->PktQue);
  411. for (i = 0; i < PKT_QUE_SIZE; i++)
  412. {
  413. j = (pPktLog->PktNext + i) % PKT_QUE_SIZE;
  414. dprintf("P%02d: TS = %05d, BT = %5d, BI = %5d, BK = %5d, PD = %08x, S = %08x\n",
  415. j,
  416. pPktLog->PktQue[j].TimeLogged,
  417. pPktLog->PktQue[j].BytesTotal,
  418. pPktLog->PktQue[j].BytesIndic,
  419. pPktLog->PktQue[j].BytesTaken,
  420. &((PKT_LOG_QUE *)proxyPtr)->PktQue[j].PacketData,
  421. pPktLog->PktQue[j].IndcnStatus);
  422. }
  423. }
  424. #endif
  425. VOID PrintNbfNetbiosAddressFromPtr(PVOID AddressPtrPointer, ULONG AddressPtrProxy, ULONG printDetail)
  426. {
  427. ULONG pNetbiosAddressProxy;
  428. ULONG bytesRead;
  429. if (AddressPtrPointer == NULL)
  430. {
  431. if (!ReadMemory(AddressPtrProxy, &AddressPtrPointer, sizeof(PVOID), &bytesRead))
  432. {
  433. dprintf("%s @ %08x: Could not read structure\n",
  434. "NBF Netbios Address Ptr", AddressPtrProxy);
  435. return;
  436. }
  437. }
  438. pNetbiosAddressProxy = *(ULONG *)AddressPtrPointer;
  439. dprintf("%08x (Ptr)\n", pNetbiosAddressProxy);
  440. if (pNetbiosAddressProxy)
  441. {
  442. PrintNbfNetbiosAddress(NULL, *(ULONG *)AddressPtrPointer, printDetail);
  443. }
  444. }
  445. VOID PrintNbfNetbiosAddress(PVOID AddressPointer, ULONG AddressProxy, ULONG printDetail)
  446. {
  447. PNBF_NETBIOS_ADDRESS pNetbiosAddress;
  448. NBF_NETBIOS_ADDRESS NetbiosAddress;
  449. ULONG bytesRead;
  450. CHAR NetbiosNameTypes[3][10] = { "UNIQUE", "GROUP", "EITHER" };
  451. if (AddressPointer == NULL)
  452. {
  453. if (!ReadMemory(AddressProxy, &NetbiosAddress, sizeof(NBF_NETBIOS_ADDRESS), &bytesRead))
  454. {
  455. dprintf("%s @ %08x: Could not read structure\n",
  456. "NBF Netbios Address", AddressProxy);
  457. return;
  458. }
  459. pNetbiosAddress = &NetbiosAddress;
  460. }
  461. else
  462. {
  463. pNetbiosAddress = (PNBF_NETBIOS_ADDRESS) AddressPointer;
  464. }
  465. dprintf("Name: ");
  466. dprint_nchar(pNetbiosAddress->NetbiosName, 16);
  467. dprintf(", ");
  468. if (pNetbiosAddress->NetbiosNameType > 2)
  469. {
  470. dprintf("Type: %s\n", "UNKNOWN");
  471. }
  472. else
  473. {
  474. dprintf("Type: %s\n",
  475. NetbiosNameTypes[pNetbiosAddress->NetbiosNameType]);
  476. }
  477. }
  478. VOID PrintNbfPacketPoolListFromPtr(PVOID PacketPoolPtrPointer, ULONG PacketPoolPtrProxy, ULONG printDetail)
  479. {
  480. ULONG pPacketPoolProxy;
  481. ULONG bytesRead;
  482. if (PacketPoolPtrPointer == NULL)
  483. {
  484. if (!ReadMemory(PacketPoolPtrProxy, &PacketPoolPtrPointer, sizeof(PVOID), &bytesRead))
  485. {
  486. dprintf("%s @ %08x: Could not read structure\n",
  487. "NBF Packet Pool Ptr", PacketPoolPtrProxy);
  488. return;
  489. }
  490. }
  491. pPacketPoolProxy = *(ULONG *)PacketPoolPtrPointer;
  492. dprintf("%08x (Ptr)\n", pPacketPoolProxy);
  493. if (pPacketPoolProxy)
  494. {
  495. PrintNbfPacketPoolList(NULL, *(ULONG *)PacketPoolPtrPointer, printDetail);
  496. }
  497. }
  498. VOID PrintNbfPacketPoolList(PVOID PacketPoolPointer, ULONG PacketPoolProxy, ULONG printDetail)
  499. {
  500. PNBF_POOL_LIST_DESC pPacketPoolList;
  501. NBF_POOL_LIST_DESC PacketPoolList;
  502. ULONG bytesRead;
  503. if (PacketPoolPointer == NULL)
  504. {
  505. if (!ReadMemory(PacketPoolProxy, &PacketPoolList, sizeof(NBF_POOL_LIST_DESC), &bytesRead))
  506. {
  507. dprintf("%s @ %08x: Could not read structure\n",
  508. "NBF Packet Pool", PacketPoolProxy);
  509. return;
  510. }
  511. pPacketPoolList = &PacketPoolList;
  512. }
  513. else
  514. {
  515. pPacketPoolList = (PNBF_POOL_LIST_DESC) PacketPoolPointer;
  516. }
  517. while (pPacketPoolList)
  518. {
  519. dprintf("PoolHandle: %08x, Num: %08x, Total: %08x\n",
  520. pPacketPoolList->PoolHandle,
  521. pPacketPoolList->NumElements,
  522. pPacketPoolList->TotalElements);
  523. if ((PacketPoolProxy = (ULONG) pPacketPoolList->Next) == (ULONG) NULL)
  524. break;
  525. if (!ReadMemory(PacketPoolProxy, &PacketPoolList, sizeof(NBF_POOL_LIST_DESC), &bytesRead))
  526. {
  527. dprintf("%s @ %08x: Could not read structure\n",
  528. "NBF Packet Pool", PacketPoolProxy);
  529. return;
  530. }
  531. pPacketPoolList = &PacketPoolList;
  532. }
  533. }
  534. VOID PrintListFromListEntryAndOffset(PVOID ListEntryPointer, ULONG ListEntryProxy, ULONG ListEntryOffset)
  535. {
  536. PLIST_ENTRY pListEntry;
  537. LIST_ENTRY ListEntry;
  538. ULONG ListHeadProxy;
  539. ULONG bytesRead;
  540. ULONG numItems;
  541. if (ListEntryPointer == NULL)
  542. {
  543. if (!ReadMemory(ListEntryProxy, &ListEntry, sizeof(LIST_ENTRY), &bytesRead))
  544. {
  545. dprintf("%s @ %08x: Could not read structure\n",
  546. "List Entry", ListEntryProxy);
  547. return;
  548. }
  549. pListEntry = &ListEntry;
  550. }
  551. else
  552. {
  553. pListEntry = (PLIST_ENTRY) ListEntryPointer;
  554. }
  555. dprintf("\n%08x LE : %08x, %08x\n", ListEntryProxy - ListEntryOffset,
  556. pListEntry->Flink,
  557. pListEntry->Blink);
  558. ListHeadProxy = ListEntryProxy; numItems = 0;
  559. while (((ULONG) pListEntry->Flink != ListHeadProxy) && (numItems < 100))
  560. {
  561. ListEntryProxy = (ULONG) pListEntry->Flink;
  562. if (!ReadMemory(ListEntryProxy, &ListEntry, sizeof(LIST_ENTRY), &bytesRead))
  563. {
  564. dprintf("%s @ %08x: Could not read structure\n",
  565. "List Entry", ListEntryProxy);
  566. return;
  567. }
  568. pListEntry = &ListEntry;
  569. dprintf("%08x %02d : %08x, %08x\n", ListEntryProxy - ListEntryOffset,
  570. numItems++,
  571. pListEntry->Flink,
  572. pListEntry->Blink);
  573. }
  574. if (numItems == 100)
  575. {
  576. dprintf("Looks like we have an infinite loop @ %08x\n", ListHeadProxy);
  577. }
  578. }
  579. VOID PrintListFromListEntry(PVOID ListEntryPointer, ULONG ListEntryProxy, ULONG debugDetail)
  580. {
  581. PrintListFromListEntryAndOffset(ListEntryPointer, ListEntryProxy, 0);
  582. }
  583. VOID PrintIRPListFromListEntry(PVOID IRPListEntryPointer, ULONG IRPListEntryProxy, ULONG debugDetail)
  584. {
  585. PrintListFromListEntryAndOffset(IRPListEntryPointer, IRPListEntryProxy,
  586. FIELD_OFFSET(IRP, Tail.Overlay.ListEntry));
  587. }