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.

1326 lines
33 KiB

  1. /*
  2. NOTE: Debugger extensions should be compiled with the headers that match the debugger
  3. you will use.
  4. You can install the latest debugger package from http://www.microsoft.com/ddk/debugging
  5. and the debugger has more up to date samples of various debugger extensions to which you
  6. can refer when you write debugger extensions.
  7. */
  8. // This is a 64 bit aware debugger extension
  9. #define KDEXT_64BIT
  10. #include <windows.h>
  11. #include <wdbgexts.h>
  12. #include <stdio.h>
  13. #include <stdlib.h>
  14. #include <string.h>
  15. #include "e100_equ.h"
  16. #include "e100_557.h"
  17. #include "mp_cmn.h"
  18. #include "e100kd.h"
  19. WINDBG_EXTENSION_APIS ExtensionApis;
  20. EXT_API_VERSION ApiVersion = { 5, 0, EXT_API_VERSION_NUMBER64, 0};
  21. USHORT SavedMajorVersion;
  22. USHORT SavedMinorVersion;
  23. BOOL ChkTarget; // is debuggee a CHK build?
  24. typedef struct
  25. {
  26. char Name[16];
  27. unsigned int Val;
  28. } DBG_LEVEL;
  29. DBG_LEVEL DbgLevel[] = {
  30. {"ERROR", MP_ERROR},
  31. {"WARN", MP_WARN},
  32. {"TRACE", MP_TRACE},
  33. {"INFO", MP_INFO},
  34. {"LOUD", MP_LOUD}
  35. };
  36. typedef struct
  37. {
  38. char Name[32];
  39. unsigned int Val;
  40. } DBG_ADAPTER_FLAGS, DBG_FILTER;
  41. DBG_ADAPTER_FLAGS DbgAdapterFlags[] = {
  42. {"SCATTER_GATHER", fMP_ADAPTER_SCATTER_GATHER},
  43. {"MAP_REGISTER", fMP_ADAPTER_MAP_REGISTER},
  44. {"RECV_LOOKASIDE", fMP_ADAPTER_RECV_LOOKASIDE},
  45. {"INTERRUPT_IN_USE", fMP_ADAPTER_INTERRUPT_IN_USE},
  46. {"RESET_IN_PROGRESS", fMP_ADAPTER_RESET_IN_PROGRESS},
  47. {"NO_CABLE", fMP_ADAPTER_NO_CABLE},
  48. {"HARDWARE_ERROR", fMP_ADAPTER_HARDWARE_ERROR}
  49. };
  50. //
  51. // Ndis Packet Filter Bits (OID_GEN_CURRENT_PACKET_FILTER).
  52. //
  53. #define NDIS_PACKET_TYPE_DIRECTED 0x00000001
  54. #define NDIS_PACKET_TYPE_MULTICAST 0x00000002
  55. #define NDIS_PACKET_TYPE_ALL_MULTICAST 0x00000004
  56. #define NDIS_PACKET_TYPE_BROADCAST 0x00000008
  57. #define NDIS_PACKET_TYPE_SOURCE_ROUTING 0x00000010
  58. #define NDIS_PACKET_TYPE_PROMISCUOUS 0x00000020
  59. #define NDIS_PACKET_TYPE_SMT 0x00000040
  60. #define NDIS_PACKET_TYPE_ALL_LOCAL 0x00000080
  61. #define NDIS_PACKET_TYPE_GROUP 0x00001000
  62. #define NDIS_PACKET_TYPE_ALL_FUNCTIONAL 0x00002000
  63. #define NDIS_PACKET_TYPE_FUNCTIONAL 0x00004000
  64. #define NDIS_PACKET_TYPE_MAC_FRAME 0x00008000
  65. DBG_FILTER DbgFilterTable[] = {
  66. {"DIRECTED", NDIS_PACKET_TYPE_DIRECTED},
  67. {"MULTICAST", NDIS_PACKET_TYPE_MULTICAST},
  68. {"ALL_MULTICAST", NDIS_PACKET_TYPE_ALL_MULTICAST},
  69. {"BROADCAST", NDIS_PACKET_TYPE_BROADCAST},
  70. {"SOURCE_ROUTING", NDIS_PACKET_TYPE_SOURCE_ROUTING},
  71. {"PROMISCUOUS", NDIS_PACKET_TYPE_PROMISCUOUS},
  72. {"SMT", NDIS_PACKET_TYPE_SMT},
  73. {"ALL_LOCAL", NDIS_PACKET_TYPE_ALL_LOCAL},
  74. {"GROUP", NDIS_PACKET_TYPE_GROUP},
  75. {"ALL_FUNCTIONAL", NDIS_PACKET_TYPE_ALL_FUNCTIONAL},
  76. {"FUNCTIONAL", NDIS_PACKET_TYPE_FUNCTIONAL},
  77. {"MAC_FRAME", NDIS_PACKET_TYPE_MAC_FRAME}
  78. };
  79. typedef struct
  80. {
  81. char Name[32];
  82. USHORT Val;
  83. } DBG_RFD_STATUS, DBG_RFD_COMMAND, DBG_USHORT_BITS, DBG_USHORT_VALUE;
  84. typedef struct
  85. {
  86. char Name[32];
  87. UCHAR Val;
  88. } DBG_UCHAR_BITS, DBG_UCHAR_VALUE;
  89. DBG_RFD_STATUS DbgRfdStatus[] = {
  90. {"COMPLETE", RFD_STATUS_COMPLETE},
  91. {"OK", RFD_STATUS_OK},
  92. {"CRC_ERROR", RFD_CRC_ERROR},
  93. {"ALIGNMENT_ERROR", RFD_ALIGNMENT_ERROR},
  94. {"NO_RESOURCES", RFD_NO_RESOURCES},
  95. {"DMA_OVERRUN", RFD_DMA_OVERRUN},
  96. {"FRAME_TOO_SHORT", RFD_FRAME_TOO_SHORT},
  97. {"RX_ERR", RFD_RX_ERR},
  98. {"IA_MATCH", RFD_IA_MATCH},
  99. {"RECEIVE_COLLISION", RFD_RECEIVE_COLLISION},
  100. };
  101. DBG_RFD_COMMAND DbgRfdCommand[] = {
  102. {"EL", RFD_EL_BIT},
  103. {"S", RFD_S_BIT},
  104. {"H", RFD_H_BIT},
  105. {"SF", RFD_SF_BIT}
  106. };
  107. DBG_USHORT_BITS DbgCbCommandBits[] = {
  108. {"EL", CB_EL_BIT},
  109. {"S", CB_S_BIT},
  110. {"I", CB_I_BIT},
  111. {"TX_SF", CB_TX_SF_BIT}
  112. };
  113. DBG_USHORT_VALUE DbgCbCommands[] = {
  114. {"CB_NOP", CB_NOP},
  115. {"CB_IA_ADDRESS", CB_IA_ADDRESS},
  116. {"CB_CONFIGURE", CB_CONFIGURE},
  117. {"CB_MULTICAST", CB_MULTICAST},
  118. {"CB_TRANSMIT", CB_TRANSMIT},
  119. {"CB_LOAD_MICROCODE", CB_LOAD_MICROCODE},
  120. {"CB_DUMP", CB_DUMP},
  121. {"CB_DIAGNOSE", CB_DIAGNOSE}
  122. };
  123. DBG_USHORT_VALUE DbgScbStatusRus[] = {
  124. {"IDLE", SCB_RUS_IDLE},
  125. {"SUSPEND", SCB_RUS_SUSPEND},
  126. {"NO_RESOURCES", SCB_RUS_NO_RESOURCES},
  127. {"READY", SCB_RUS_READY},
  128. {"SUSP_NO_RBDS", SCB_RUS_SUSP_NO_RBDS},
  129. {"NO_RBDS", SCB_RUS_NO_RBDS},
  130. {"READY_NO_RBDS", SCB_RUS_READY_NO_RBDS},
  131. };
  132. DBG_USHORT_BITS DbgScbStatusBits[] = {
  133. {"CX", SCB_STATUS_CX},
  134. {"FR", SCB_STATUS_FR},
  135. {"CNA", SCB_STATUS_CNA},
  136. {"RNR", SCB_STATUS_RNR},
  137. {"MDI", SCB_STATUS_MDI},
  138. {"SWI", SCB_STATUS_SWI}
  139. };
  140. DBG_UCHAR_VALUE DbgScbCommandCuc[] = {
  141. {"START", SCB_CUC_START},
  142. {"RESUME", SCB_CUC_RESUME},
  143. {"DUMP_ADDR", SCB_CUC_DUMP_ADDR},
  144. {"DUMP_STAT", SCB_CUC_DUMP_STAT},
  145. {"LOAD_BASE", SCB_CUC_LOAD_BASE},
  146. {"DUMP_RST_STAT", SCB_CUC_DUMP_RST_STAT},
  147. {"STATIC_RESUME", SCB_CUC_STATIC_RESUME}
  148. };
  149. DBG_UCHAR_VALUE DbgScbCommandRuc[] = {
  150. {"START", SCB_RUC_START},
  151. {"RESUME", SCB_RUC_RESUME},
  152. {"ABORT", SCB_RUC_ABORT},
  153. {"LOAD_HDS", SCB_RUC_LOAD_HDS},
  154. {"LOAD_BASE", SCB_RUC_LOAD_BASE},
  155. {"RBD_RESUME", SCB_RUC_RBD_RESUME}
  156. };
  157. VOID WinDbgExtensionDllInit(
  158. PWINDBG_EXTENSION_APIS64 lpExtensionApis,
  159. USHORT MajorVersion,
  160. USHORT MinorVersion
  161. )
  162. {
  163. ExtensionApis = *lpExtensionApis;
  164. SavedMajorVersion = MajorVersion;
  165. SavedMinorVersion = MinorVersion;
  166. ChkTarget = SavedMajorVersion == 0x0c ? TRUE : FALSE;
  167. }
  168. LPEXT_API_VERSION ExtensionApiVersion(VOID)
  169. {
  170. return &ApiVersion;
  171. }
  172. VOID CheckVersion(VOID)
  173. {
  174. //
  175. // for now don't bother to version check
  176. //
  177. return;
  178. }
  179. DECLARE_API( help )
  180. {
  181. int i;
  182. dprintf("E100 extensions:\n");
  183. dprintf(" dbglevel dump debug level\n");
  184. dprintf(" mpadapter <MP_ADAPTER> <verbosity>> dump MP_ADAPTER block\n");
  185. dprintf(" csr <CSRAddress> dump CSR block\n");
  186. dprintf(" sendlist <CurrSendHead> <verbosity> dump send list\n");
  187. dprintf(" mptcb <MP_TCB> dump MP_TCB block\n");
  188. dprintf(" hwtcb <HW_TCB> dump HW_TCB block\n");
  189. dprintf(" sendqueue <SendWaitQueue> dump queued send packets\n");
  190. dprintf(" recvlist <RecvList> <verbosity> dump receive list\n");
  191. dprintf(" mprfd <MP_RFD> dump MP_RFD block\n");
  192. dprintf(" hwrfd <HW_RFD> dump HW_RFD block\n");
  193. dprintf(" recvpendlist <RecvPendList> dump pending indicated rx packets\n");
  194. }
  195. DECLARE_API(dbglevel)
  196. {
  197. ULONG64 debugLevelPtr;
  198. ULONG debugLevel, NewLevel;
  199. ULONG64 Val;
  200. int i;
  201. ULONG Bytes;
  202. debugLevelPtr = GetExpression("e100bnt5!MPDebugLevel");
  203. if(debugLevelPtr == 0)
  204. {
  205. dprintf("Error retrieving address of MPDebugLevel\n");
  206. dprintf("Target is %s\n", ChkTarget ? "Checked" : "Free");
  207. }
  208. dprintf("MPDebugLevel @ %p\n", debugLevelPtr);
  209. debugLevel = GetUlongFromAddress(debugLevelPtr);
  210. dprintf("Current MPDebugLevel = %d", debugLevel);
  211. for(i = 0; i < sizeof(DbgLevel)/sizeof(DBG_LEVEL); i++)
  212. {
  213. if(debugLevel == DbgLevel[i].Val)
  214. {
  215. dprintf(" - %s", DbgLevel[i].Name);
  216. break;
  217. }
  218. }
  219. dprintf("\n");
  220. dprintf("Available settings: ");
  221. for(i = 0; i < sizeof(DbgLevel)/sizeof(DBG_LEVEL); i++)
  222. {
  223. if(debugLevel != DbgLevel[i].Val)
  224. {
  225. dprintf("%d-%s ", DbgLevel[i].Val, DbgLevel[i].Name);
  226. }
  227. }
  228. dprintf("\n");
  229. if(!*args)
  230. {
  231. return;
  232. }
  233. i = sscanf(args, "%lx", &NewLevel);
  234. if(i == 1)
  235. {
  236. for(i = 0; i < sizeof(DbgLevel)/sizeof(DBG_LEVEL); i++)
  237. {
  238. if(NewLevel == DbgLevel[i].Val)
  239. {
  240. if(NewLevel != debugLevel)
  241. {
  242. dprintf("New MPDebugLevel = %d\n", NewLevel);
  243. WriteMemory(debugLevelPtr, &NewLevel, sizeof(ULONG), &Bytes);
  244. }
  245. break;
  246. }
  247. }
  248. }
  249. }
  250. DECLARE_API(version)
  251. {
  252. #if DBG
  253. PCSTR kind = "Checked";
  254. #else
  255. PCSTR kind = "Free";
  256. #endif
  257. dprintf("%s E100 Extension dll on a %s system\n",
  258. kind, ChkTarget? "Checked" : "Free");
  259. }
  260. #define MAX_FLAGS_PER_LINE 4
  261. #define MAC_ADDRESS_LENGTH 6
  262. DECLARE_API(mpadapter)
  263. {
  264. ULONG64 pAdapter;
  265. int ArgCount = 0;
  266. ULONG i, j;
  267. ULONG Flags;
  268. ULONG PacketFilter;
  269. ULONG Off;
  270. UCHAR MacAddress[MAC_ADDRESS_LENGTH];
  271. UINT MCAddressCount;
  272. PUCHAR pBuffer;
  273. if(*args)
  274. {
  275. ArgCount = sscanf(args,"%I64lx",&pAdapter);
  276. }
  277. //check for arguments
  278. if(ArgCount < 1)
  279. {
  280. dprintf("Usage: mpadapter <pointer to MP_ADAPTER>\n");
  281. return ;
  282. }
  283. dprintf(" pAdapter %p : \n", pAdapter);
  284. InitTypeRead(pAdapter, MP_ADAPTER);
  285. dprintf(" AdapterHandle : %p\n", ReadField(AdapterHandle));
  286. Flags = (ULONG) ReadField(Flags);
  287. dprintf(" Flags : 0x%08x\n", Flags);
  288. j = 0;
  289. for(i = 0; i < sizeof(DbgAdapterFlags)/sizeof(DBG_ADAPTER_FLAGS); i++)
  290. {
  291. if(Flags & DbgAdapterFlags[i].Val)
  292. {
  293. if(j == 0)
  294. {
  295. dprintf(" ");
  296. }
  297. dprintf("%s", DbgAdapterFlags[i].Name);
  298. j++;
  299. if(j != MAX_FLAGS_PER_LINE)
  300. {
  301. dprintf(", ");
  302. }
  303. else
  304. {
  305. dprintf("\n");
  306. j = 0;
  307. }
  308. }
  309. }
  310. if(j != 0)
  311. {
  312. dprintf("\n");
  313. }
  314. if(!GetFieldOffset("MP_ADAPTER", "PermanentAddress", &Off))
  315. {
  316. if(GetData(MacAddress, pAdapter+Off, MAC_ADDRESS_LENGTH, "PermanentAddress[]"))
  317. {
  318. dprintf(" Permanent address : %02x-%02x-%02x-%02x-%02x-%02x\n",
  319. MacAddress[0], MacAddress[1],
  320. MacAddress[2], MacAddress[3],
  321. MacAddress[4], MacAddress[5]);
  322. }
  323. }
  324. if((BOOLEAN) ReadField(OverrideAddress))
  325. {
  326. if(!GetFieldOffset("MP_ADAPTER", "CurrentAddress", &Off))
  327. {
  328. if(GetData(MacAddress, pAdapter+Off, MAC_ADDRESS_LENGTH, "CurrentAddress[]"))
  329. {
  330. dprintf(" Current address : %02x-%02x-%02x-%02x-%02x-%02x\n",
  331. MacAddress[0], MacAddress[1],
  332. MacAddress[2], MacAddress[3],
  333. MacAddress[4], MacAddress[5]);
  334. }
  335. }
  336. }
  337. else
  338. {
  339. dprintf(" Current address : same as above\n");
  340. }
  341. dprintf("\n");
  342. dprintf(" --- SEND ---\n");
  343. dprintf(" CurrSendHead = %p , CurrSendTail = %p , nBusySend = %d\n",
  344. ReadField(CurrSendHead), ReadField(CurrSendTail), (LONG)ReadField(nBusySend));
  345. dprintf(" SendWaitQueue Head = %p, Tail = %p\n",
  346. ReadField(SendWaitQueue.Head), ReadField(SendWaitQueue.Tail));
  347. dprintf(" NumTcb = %d, RegNumTcb = %d, NumBuffers = %d\n",
  348. (LONG)ReadField(NumTcb), (LONG)ReadField(RegNumTcb), (LONG)ReadField(NumBuffers));
  349. dprintf(" MpTcbMem = %p\n", ReadField(MpTcbMem));
  350. if(DBG_TEST_FLAG(Flags, fMP_ADAPTER_MAP_REGISTER))
  351. {
  352. dprintf(" CurrMapRegHead = %d, CurrMapRegTail = %d\n",
  353. (UINT)ReadField(CurrMapRegHead), (UINT)ReadField(CurrMapRegTail));
  354. }
  355. dprintf(" TransmitIdle = %s, ResumeWait = %s\n",
  356. (BOOLEAN)ReadField(TransmitIdle) ? "TRUE" : "FALSE",
  357. (BOOLEAN)ReadField(ResumeWait) ? "TRUE" : "FALSE");
  358. dprintf(" SendBufferPool = %p\n", ReadField(SendBufferPool));
  359. dprintf("\n");
  360. dprintf(" --- RECV ---\n");
  361. if(!GetFieldOffset("MP_ADAPTER", "RecvList", &Off))
  362. {
  363. dprintf(" RecvList @ %p , nReadyRecv = %d\n",
  364. pAdapter+Off, (LONG)ReadField(nReadyRecv));
  365. }
  366. if(!GetFieldOffset("MP_ADAPTER", "RecvPendList", &Off))
  367. {
  368. dprintf(" RecvPendList @ %p , RefCount = %d\n",
  369. pAdapter+Off, (LONG)ReadField(RefCount));
  370. }
  371. dprintf(" NumRfd = %d, CurrNumRfd = %d , HwRfdSize = %d\n",
  372. (LONG)ReadField(NumRfd), (LONG)ReadField(CurrNumRfd), (LONG)ReadField(HwRfdSize));
  373. dprintf(" bAllocNewRfd = %s, RfdShrinkCount = %d\n",
  374. (BOOLEAN)ReadField(bAllocNewRfd) ? "TRUE" : "FALSE",
  375. (LONG)ReadField(RfdShrinkCount));
  376. dprintf(" RecvPacketPool = %p , RecvBufferPool = %p\n",
  377. ReadField(RecvPacketPool), ReadField(RecvBufferPool));
  378. dprintf("\n");
  379. PacketFilter = (ULONG)ReadField(PacketFilter);
  380. dprintf(" PacketFilter : 0x%08x\n", PacketFilter);
  381. j = 0;
  382. for(i = 0; i < sizeof(DbgFilterTable)/sizeof(DBG_FILTER); i++)
  383. {
  384. if(PacketFilter & DbgFilterTable[i].Val)
  385. {
  386. if(j == 0)
  387. {
  388. dprintf(" ");
  389. }
  390. dprintf("%s", DbgFilterTable[i].Name);
  391. j++;
  392. if(j != MAX_FLAGS_PER_LINE)
  393. {
  394. dprintf(", ");
  395. }
  396. else
  397. {
  398. dprintf("\n");
  399. j = 0;
  400. }
  401. }
  402. }
  403. if(j != 0)
  404. {
  405. dprintf("\n");
  406. }
  407. dprintf(" ulLookAhead=%d, usLinkSpeed=%d, usDuplexMode=%d\n",
  408. (ULONG)ReadField(ulLookAhead), (USHORT)ReadField(usLinkSpeed),
  409. (USHORT)ReadField(usDuplexMode));
  410. dprintf("\n");
  411. MCAddressCount = (UINT)ReadField(MCAddressCount);
  412. dprintf(" MCAddressCount = %d\n", MCAddressCount);
  413. pBuffer = malloc(MCAddressCount * MAC_ADDRESS_LENGTH);
  414. if(pBuffer)
  415. {
  416. if(!GetFieldOffset("MP_ADAPTER", "MCList", &Off))
  417. {
  418. if(GetData(pBuffer, pAdapter+Off, MCAddressCount * MAC_ADDRESS_LENGTH, "MCList[]"))
  419. {
  420. for(i=0; i<MCAddressCount; i++)
  421. {
  422. j = i * MAC_ADDRESS_LENGTH;
  423. dprintf(" (%d) = %02x-%02x-%02x-%02x-%02x-%02x\n",
  424. i, pBuffer[j], pBuffer[j+1], pBuffer[j+2],
  425. pBuffer[j+3], pBuffer[j+4], pBuffer[j+5]);
  426. }
  427. }
  428. }
  429. free(pBuffer);
  430. }
  431. else
  432. {
  433. }
  434. dprintf("\n");
  435. dprintf(" IoBaseAddress = 0x%x, IoRange = 0x%x, InterrupLevel = 0x%x, MemPhysAddress = 0x%x\n",
  436. (ULONG)ReadField(IoBaseAddress), (ULONG)ReadField(IoRange),
  437. (ULONG)ReadField(InterruptLevel), (ULONG)ReadField(MemPhysAddress.LowPart));
  438. dprintf(" PortOffset = %p , CSRAddress = %p\n",
  439. ReadField(PortOffset), ReadField(CSRAddress));
  440. dprintf(" RevsionID = %d, SubVendorID = 0x%02x, SubSystemID = 0x%02x\n",
  441. (UCHAR)ReadField(RevsionID), (USHORT)ReadField(SubVendorID),
  442. (USHORT)ReadField(SubSystemID));
  443. }
  444. DECLARE_API(csr)
  445. {
  446. ULONG64 pHwCsr;
  447. int ArgCount = 0;
  448. UCHAR ucVal;
  449. USHORT usVal;
  450. ULONG i;
  451. if(*args)
  452. {
  453. ArgCount = sscanf(args,"%I64lx", &pHwCsr);
  454. }
  455. //check for arguments
  456. if(ArgCount < 1)
  457. {
  458. dprintf("Usage: csr <CSRAddress>\n");
  459. return ;
  460. }
  461. dprintf(" pHwCsr %x : \n", pHwCsr);
  462. InitTypeRead(pHwCsr, HW_CSR);
  463. // ScbStatus
  464. usVal = (USHORT)ReadField(ScbStatus);
  465. dprintf(" ScbStatus - 0x%04x ", usVal);
  466. dprintf("CUS-");
  467. switch(usVal & SCB_CUS_MASK)
  468. {
  469. case SCB_CUS_IDLE:
  470. dprintf("IDLE ");
  471. break;
  472. case SCB_CUS_SUSPEND:
  473. dprintf("SUSPEND ");
  474. break;
  475. case SCB_CUS_ACTIVE:
  476. dprintf("ACTIVE ");
  477. break;
  478. default:
  479. dprintf("Reserved ");
  480. }
  481. for(i = 0; i < sizeof(DbgScbStatusRus)/sizeof(DBG_USHORT_VALUE); i++)
  482. {
  483. if((usVal & SCB_RUS_MASK) == DbgScbStatusRus[i].Val)
  484. {
  485. dprintf("RUS-%s ", DbgScbStatusRus[i].Name);
  486. break;
  487. }
  488. }
  489. dprintf("STAT-");
  490. for(i = 0; i < sizeof(DbgScbStatusBits)/sizeof(DBG_USHORT_BITS); i++)
  491. {
  492. if(usVal & DbgScbStatusBits[i].Val)
  493. {
  494. dprintf("%s ", DbgScbStatusBits[i].Name);
  495. }
  496. }
  497. dprintf("\n");
  498. //ScbCommandLow
  499. ucVal = (UCHAR)ReadField(ScbCommandLow);
  500. dprintf(" ScbCommandLow - 0x%02x ", ucVal);
  501. for(i = 0; i < sizeof(DbgScbCommandCuc)/sizeof(DBG_UCHAR_VALUE); i++)
  502. {
  503. if((ucVal & SCB_CUC_MASK) == DbgScbCommandCuc[i].Val)
  504. {
  505. dprintf("CUC-%s ", DbgScbCommandCuc[i].Name);
  506. break;
  507. }
  508. }
  509. for(i = 0; i < sizeof(DbgScbCommandRuc)/sizeof(DBG_UCHAR_VALUE); i++)
  510. {
  511. if((ucVal & SCB_RUC_MASK) == DbgScbCommandRuc[i].Val)
  512. {
  513. dprintf("RUC-%s ", DbgScbCommandRuc[i].Name);
  514. break;
  515. }
  516. }
  517. //ScbCommandHigh
  518. ucVal = (UCHAR)ReadField(ScbCommandHigh);
  519. dprintf(" ScbCommandHigh - 0x%02x ", ucVal);
  520. if(ucVal & SCB_INT_MASK)
  521. {
  522. dprintf("INT_MASK ");
  523. }
  524. if(ucVal & SCB_SOFT_INT)
  525. {
  526. dprintf("SOFT_INT ");
  527. }
  528. dprintf("\n");
  529. }
  530. DECLARE_API(sendlist)
  531. {
  532. ULONG64 pMpTcb;
  533. ULONG64 pFirstMpTcb;
  534. int ArgCount = 0;
  535. int Verbosity = 0;
  536. int index = 0;
  537. if(*args)
  538. {
  539. ArgCount = sscanf(args,"%I64lx %lx", &pMpTcb, &Verbosity);
  540. }
  541. //check for arguments
  542. if(ArgCount < 1 || Verbosity > 1)
  543. {
  544. dprintf("Usage: sendlist <CurrSendHead> <verbosity>\n");
  545. dprintf("1-Show HW_TCB info\n");
  546. return ;
  547. }
  548. SIGN_EXTEND(pMpTcb);
  549. pFirstMpTcb = pMpTcb;
  550. do
  551. {
  552. dprintf(" (%d) pMpTcb %p : \n", index, pMpTcb);
  553. PrintMpTcbDetails(pMpTcb, Verbosity);
  554. if(GetFieldValue(pMpTcb, "MP_TCB", "Next", pMpTcb))
  555. {
  556. break;
  557. }
  558. index++;
  559. if(CheckControlC())
  560. {
  561. dprintf("***Control-C***\n");
  562. break;
  563. }
  564. } while(pMpTcb != pFirstMpTcb);
  565. }
  566. DECLARE_API(mptcb)
  567. {
  568. ULONG64 pMpTcb;
  569. int ArgCount = 0;
  570. if(*args)
  571. {
  572. ArgCount = sscanf(args,"%I64lx", &pMpTcb);
  573. }
  574. //check for arguments
  575. if(ArgCount < 1)
  576. {
  577. dprintf("Usage: mptcb <MP_TCB>\n");
  578. return ;
  579. }
  580. dprintf(" pMpTcb %p : \n", pMpTcb);
  581. PrintMpTcbDetails(pMpTcb, 1);
  582. }
  583. DECLARE_API(hwtcb)
  584. {
  585. ULONG64 pHwTcb;
  586. int ArgCount = 0;
  587. if(*args)
  588. {
  589. ArgCount = sscanf(args,"%I64lx", &pHwTcb);
  590. }
  591. //check for arguments
  592. if(ArgCount < 1)
  593. {
  594. dprintf("Usage: hwtcb <HW_TCB>\n");
  595. return ;
  596. }
  597. dprintf(" pHwTcb %p : \n", pHwTcb);
  598. PrintHwTcbDetails(pHwTcb);
  599. }
  600. void PrintMpTcbDetails(ULONG64 pMpTcb, int Verbosity)
  601. {
  602. ULONG Flags;
  603. ULONG64 pMpTxBuf;
  604. ULONG64 pHwTcb;
  605. ULONG64 pVal;
  606. ULONG ulVal;
  607. USHORT usVal;
  608. InitTypeRead(pMpTcb, MP_TCB);
  609. dprintf(" Next %p", ReadField(Next));
  610. Flags = (ULONG) ReadField(Flags);
  611. dprintf(" , Flags - 0x%x", Flags);
  612. if(Flags & fMP_TCB_IN_USE)
  613. {
  614. dprintf(" IN_USE");
  615. }
  616. if(Flags & fMP_TCB_USE_LOCAL_BUF)
  617. {
  618. dprintf(" USE_LOCAL_BUF");
  619. }
  620. if(Flags & fMP_TCB_MULTICAST)
  621. {
  622. dprintf(" MULTICAST");
  623. }
  624. dprintf("\n");
  625. if(Flags & fMP_TCB_USE_LOCAL_BUF)
  626. {
  627. pMpTxBuf = ReadField(MpTxBuf);
  628. dprintf(" MpTxBuf = %p", pMpTxBuf);
  629. GetFieldValue(pMpTxBuf, "MP_TXBUF", "NdisBuffer", pVal);
  630. dprintf(" - NdisBuffer = %p", pVal);
  631. GetFieldValue(pMpTxBuf, "MP_TXBUF", "AllocSize", ulVal);
  632. dprintf(" , AllocSize = %d", ulVal);
  633. GetFieldValue(pMpTxBuf, "MP_TXBUF", "AllocVa", pVal);
  634. dprintf(" , AllocVa = %p", pVal);
  635. GetFieldValue(pMpTxBuf, "MP_TXBUF", "pBuffer", pVal);
  636. dprintf(" , pBuffer = %p\n", pVal);
  637. dprintf("\n");
  638. }
  639. if(Flags & fMP_TCB_IN_USE)
  640. {
  641. dprintf(" Packet = %p\n", ReadField(Packet));
  642. pHwTcb = ReadField(HwTcb);
  643. dprintf(" HwTcb = %p , HwTcbPhys = 0x%lx , PrevHwTcb = 0x%x\n",
  644. pHwTcb, (ULONG)ReadField(HwTcbPhys), ReadField(PrevHwTcb));
  645. dprintf(" HwTbd (First) = %p , HwTbdPhys = 0x%x\n",
  646. ReadField(HwTbd), (ULONG)ReadField(HwTbdPhys));
  647. dprintf(" PhysBufCount = %d, BufferCount = %d, FirstBuffer = %p , PacketLength = %d\n",
  648. (ULONG)ReadField(PhysBufCount), (ULONG)ReadField(BufferCount),
  649. ReadField(FirstBuffer), (ULONG)ReadField(PacketLength));
  650. }
  651. dprintf("\n");
  652. if((Flags & fMP_TCB_IN_USE) && Verbosity == 1)
  653. {
  654. PrintHwTcbDetails(pHwTcb);
  655. }
  656. }
  657. void PrintHwTcbDetails(ULONG64 pHwTcb)
  658. {
  659. USHORT HwCbStatus;
  660. USHORT HwCbCommand;
  661. ULONG i;
  662. InitTypeRead(pHwTcb, HW_TCB);
  663. HwCbStatus = (USHORT) ReadField(TxCbHeader.CbStatus);
  664. HwCbCommand = (USHORT) ReadField(TxCbHeader.CbCommand);
  665. dprintf(" TxCbHeader.CbStatus = 0x%04x ,", HwCbStatus);
  666. if(HwCbStatus & CB_STATUS_COMPLETE)
  667. {
  668. dprintf(" COMPLETE");
  669. }
  670. if(HwCbStatus & CB_STATUS_OK)
  671. {
  672. dprintf(" OK");
  673. }
  674. if(HwCbStatus & CB_STATUS_UNDERRUN)
  675. {
  676. dprintf(" UNDERRUN");
  677. }
  678. dprintf("\n");
  679. dprintf(" TxCbHeader.CbCommand = 0x%04x ", HwCbCommand);
  680. for(i = 0; i < sizeof(DbgCbCommandBits)/sizeof(DBG_USHORT_BITS); i++)
  681. {
  682. if(HwCbCommand & DbgCbCommandBits[i].Val)
  683. {
  684. dprintf(", %s", DbgCbCommandBits[i].Name);
  685. }
  686. }
  687. for(i = 0; i < sizeof(DbgCbCommands)/sizeof(DBG_USHORT_VALUE); i++)
  688. {
  689. if((HwCbCommand & CB_CMD_MASK) == DbgCbCommands[i].Val)
  690. {
  691. dprintf(", %s", DbgCbCommands[i].Name);
  692. break;
  693. }
  694. }
  695. if(i == sizeof(DbgCbCommands)/sizeof(DBG_USHORT_VALUE))
  696. {
  697. dprintf(", UNKNOWN COMMAND");
  698. }
  699. dprintf("\n");
  700. dprintf(" TxCbHeader.CbLinkPointer = 0x%x\n", (ULONG)ReadField(TxCbHeader.CbLinkPointer));
  701. if((HwCbCommand & CB_CMD_MASK) == CB_TRANSMIT)
  702. {
  703. dprintf(" TxCbTbdPointer = 0x%08x\n", (ULONG)ReadField(TxCbTbdPointer));
  704. dprintf(" TxCbCount = %d, ", (USHORT)ReadField(TxCbCount));
  705. dprintf("TxCbThreshold = %d, ", (UCHAR)ReadField(TxCbThreshold));
  706. dprintf("TxCbTbdNumber = %d\n", (UCHAR)ReadField(TxCbTbdNumber));
  707. }
  708. }
  709. DECLARE_API(sendqueue)
  710. {
  711. ULONG64 pEntry;
  712. ULONG64 pPacket;
  713. ULONG ulSize;
  714. int ArgCount = 0;
  715. int index = 0;
  716. if(*args)
  717. {
  718. ArgCount = sscanf(args,"%I64lx", &pEntry);
  719. }
  720. //check for arguments
  721. if(ArgCount < 1)
  722. {
  723. dprintf("Usage: sendqueue <SendWaitQueue address>\n");
  724. return ;
  725. }
  726. SIGN_EXTEND(pEntry);
  727. if(!(ulSize = GetTypeSize("NDIS_PACKET_PRIVATE")))
  728. {
  729. dprintf("Failed to get the type size of NDIS_PACKET_PRIVATE\n");
  730. return;
  731. }
  732. dprintf("NDIS_PACKET_PRIVATE size is 0x%x\n", ulSize);
  733. while(pEntry)
  734. {
  735. pPacket = pEntry - ulSize;
  736. if(pPacket > pEntry)
  737. {
  738. dprintf("Invalid pEntry %p\n", pEntry);
  739. break;
  740. }
  741. dprintf(" (%d) pEntry = %p, Pkt = %p\n", index, pEntry, pPacket);
  742. if(ReadPtr(pEntry, &pEntry))
  743. {
  744. break;
  745. }
  746. index++;
  747. if(CheckControlC())
  748. {
  749. dprintf("***Control-C***\n");
  750. break;
  751. }
  752. }
  753. }
  754. DECLARE_API(recvlist)
  755. {
  756. ULONG64 pListHead;
  757. ULONG64 pMpRfd;
  758. ULONG64 pHwRfd;
  759. int ArgCount = 0;
  760. int Verbosity = 0;
  761. int index = 0;
  762. if(*args)
  763. {
  764. ArgCount = sscanf(args,"%I64lx %lx", &pListHead, &Verbosity);
  765. }
  766. //check for arguments
  767. if(ArgCount < 1 || Verbosity > 1)
  768. {
  769. dprintf("Usage: recvlist <RecvList address> <verbosity>\n");
  770. dprintf("1-Show HW_RFD info\n");
  771. return ;
  772. }
  773. SIGN_EXTEND(pListHead);
  774. if(GetFieldValue(pListHead, "LIST_ENTRY", "Flink", pMpRfd))
  775. {
  776. dprintf("Failed to get LIST_ENTRY Flink at %p\n", pListHead);
  777. return;
  778. }
  779. while((pMpRfd != pListHead))
  780. {
  781. dprintf(" (%d) pMpRfd %p :\n", index, pMpRfd);
  782. PrintMpRfdDetails(pMpRfd, Verbosity);
  783. if(GetFieldValue(pMpRfd, "LIST_ENTRY", "Flink", pMpRfd))
  784. {
  785. dprintf("Failed to get LIST_ENTRY Flink at %p\n", pMpRfd);
  786. break;
  787. }
  788. index++;
  789. if(CheckControlC())
  790. {
  791. dprintf("***Control-C***\n");
  792. break;
  793. }
  794. }
  795. dprintf("RecvList has %d RFDs\n", index);
  796. }
  797. DECLARE_API(mprfd)
  798. {
  799. ULONG64 pMpRfd;
  800. int ArgCount = 0;
  801. if(*args)
  802. {
  803. ArgCount = sscanf(args,"%I64lx", &pMpRfd);
  804. }
  805. //check for arguments
  806. if(ArgCount < 1)
  807. {
  808. dprintf("Usage: mprfd <MP_RFD>\n");
  809. return ;
  810. }
  811. dprintf(" pMpRfd %p : \n", pMpRfd);
  812. PrintMpRfdDetails(pMpRfd, 1);
  813. }
  814. DECLARE_API(hwrfd)
  815. {
  816. ULONG64 pHwRfd;
  817. int ArgCount = 0;
  818. if(*args)
  819. {
  820. ArgCount = sscanf(args,"%I64lx", &pHwRfd);
  821. }
  822. //check for arguments
  823. if(ArgCount < 1)
  824. {
  825. dprintf("Usage: hwrfd <HW_RFD>\n");
  826. return ;
  827. }
  828. dprintf(" pHwRfd = %p : \n", pHwRfd);
  829. PrintHwRfdDetails(pHwRfd);
  830. }
  831. void PrintMpRfdDetails(ULONG64 pMpRfd, int Verbosity)
  832. {
  833. ULONG64 pHwRfd;
  834. ULONG Flags;
  835. InitTypeRead(pMpRfd, MP_RFD);
  836. dprintf(" Flink %p", ReadField(List.Flink));
  837. dprintf(" , Blink %p\n", ReadField(List.Blink));
  838. pHwRfd = ReadField(HwRfd);
  839. dprintf(" NdisPacket = %p , NdisBuffer = %p , HwRfd = %p\n",
  840. ReadField(NdisPacket), ReadField(NdisBuffer), pHwRfd);
  841. dprintf(" PacketSize = %d, ", (ULONG) ReadField(PacketSize));
  842. Flags = (ULONG) ReadField(Flags);
  843. dprintf("Flags 0x%x", Flags);
  844. if(Flags & fMP_RFD_RECV_PEND)
  845. {
  846. dprintf(" RECV_PEND ");
  847. }
  848. if(Flags & fMP_RFD_ALLOC_PEND)
  849. {
  850. dprintf(" ALLOC_PEND ");
  851. }
  852. if(Flags & fMP_RFD_RECV_READY)
  853. {
  854. dprintf(" RECV_READY ");
  855. }
  856. if(Flags & fMP_RFD_RESOURCES)
  857. {
  858. dprintf(" RESOURCES ");
  859. }
  860. dprintf("\n");
  861. if(Verbosity == 1)
  862. {
  863. PrintHwRfdDetails(pHwRfd);
  864. }
  865. }
  866. void PrintHwRfdDetails(ULONG64 pHwRfd)
  867. {
  868. USHORT RfdStatus;
  869. USHORT RfdCommand;
  870. ULONG i;
  871. InitTypeRead(pHwRfd, HW_RFD);
  872. RfdStatus = (USHORT) ReadField(RfdCbHeader.CbStatus);
  873. RfdCommand = (USHORT) ReadField(RfdCbHeader.CbCommand);
  874. dprintf(" RfdCbHeader.CbStatus = 0x%04x", RfdStatus);
  875. for(i = 0; i < sizeof(DbgRfdStatus)/sizeof(DBG_RFD_STATUS); i++)
  876. {
  877. if(RfdStatus & DbgRfdStatus[i].Val)
  878. {
  879. dprintf(", %s", DbgRfdStatus[i].Name);
  880. }
  881. }
  882. dprintf("\n");
  883. dprintf(" RfdCbHeader.CbCommand = %04x", RfdCommand);
  884. for(i = 0; i < sizeof(DbgRfdCommand)/sizeof(DBG_RFD_COMMAND); i++)
  885. {
  886. if(RfdCommand & DbgRfdCommand[i].Val)
  887. {
  888. dprintf(", %s", DbgRfdCommand[i].Name);
  889. }
  890. }
  891. dprintf("\n");
  892. dprintf(" RfdCbHeader.CbLinkPointer = 0x%x\n", (ULONG)ReadField(RfdCbHeader.CbLinkPointer));
  893. //dprintf(" RfdRbdPointer = 0x%x\n", (ULONG)ReadField(RfdRbdPointer));
  894. dprintf(" RfdActualCount = %x , %d", (USHORT)ReadField(RfdActualCount), (USHORT)ReadField(RfdActualCount) & 0x3fff);
  895. dprintf(", RfdSize = %d\n", (USHORT)ReadField(RfdSize));
  896. }
  897. DECLARE_API(recvpendlist)
  898. {
  899. ULONG64 pListHead;
  900. ULONG64 pMpRfd;
  901. ULONG64 pPacket;
  902. int ArgCount = 0;
  903. int index = 0;
  904. if(*args)
  905. {
  906. ArgCount = sscanf(args,"%I64lx", &pListHead);
  907. }
  908. //check for arguments
  909. if(ArgCount < 1)
  910. {
  911. dprintf("Usage: recvpendlist <RecvPendList address>\n");
  912. return ;
  913. }
  914. SIGN_EXTEND(pListHead);
  915. if(GetFieldValue(pListHead, "LIST_ENTRY", "Flink", pMpRfd))
  916. {
  917. dprintf("Failed to get LIST_ENTRY Flink at %p\n", pListHead);
  918. return;
  919. }
  920. while(pMpRfd != pListHead)
  921. {
  922. dprintf(" (%d) pMpRfd %x :\n", index, pMpRfd);
  923. PrintMpRfdDetails(pMpRfd, 0);
  924. if(GetFieldValue(pMpRfd, "LIST_ENTRY", "Flink", pMpRfd))
  925. {
  926. dprintf("Failed to get LIST_ENTRY Flink at %p\n", pMpRfd);
  927. break;
  928. }
  929. index++;
  930. if(CheckControlC())
  931. {
  932. dprintf("***Control-C***\n");
  933. break;
  934. }
  935. }
  936. dprintf("RecvPendList has %d RFDs\n", index);
  937. }
  938. /**
  939. Get 'size' bytes from the debuggee program at 'dwAddress' and place it
  940. in our address space at 'ptr'. Use 'type' in an error printout if necessary
  941. **/
  942. BOOL GetData( IN LPVOID ptr, IN ULONG64 AddressPtr, IN ULONG size, IN PCSTR type )
  943. {
  944. BOOL b;
  945. ULONG BytesRead;
  946. ULONG count = size;
  947. while(size > 0)
  948. {
  949. if(count >= 3000)
  950. count = 3000;
  951. b = ReadMemory(AddressPtr, ptr, count, &BytesRead );
  952. if(!b || BytesRead != count)
  953. {
  954. dprintf( "Unable to read %u bytes at %X, for %s\n", size, AddressPtr, type );
  955. return FALSE;
  956. }
  957. AddressPtr += count;
  958. size -= count;
  959. ptr = (LPVOID)((ULONG_PTR)ptr + count);
  960. }
  961. return TRUE;
  962. }
  963. /**
  964. Routine to get offset and size of a "Field" of "Type" on a debugee machine. This uses
  965. Ioctl call for type info.
  966. Returns 0 on success, Ioctl error value otherwise.
  967. **/
  968. ULONG GetFieldOffsetAndSize(
  969. IN LPSTR Type,
  970. IN LPSTR Field,
  971. OUT PULONG pOffset,
  972. OUT PULONG pSize)
  973. {
  974. FIELD_INFO flds = {
  975. Field, "", 0,
  976. DBG_DUMP_FIELD_FULL_NAME | DBG_DUMP_FIELD_RETURN_ADDRESS | DBG_DUMP_FIELD_SIZE_IN_BITS,
  977. 0, NULL};
  978. SYM_DUMP_PARAM Sym = {
  979. sizeof (SYM_DUMP_PARAM), Type, DBG_DUMP_NO_PRINT, 0,
  980. NULL, NULL, NULL, 1, &flds
  981. };
  982. ULONG Err, i=0;
  983. LPSTR dot, last=Field;
  984. Sym.nFields = 1;
  985. Err = Ioctl( IG_DUMP_SYMBOL_INFO, &Sym, Sym.size );
  986. *pOffset = (ULONG) (flds.address - Sym.addr);
  987. *pSize = flds.size;
  988. return Err;
  989. }
  990. ULONG GetUlongFromAddress (
  991. ULONG64 Location)
  992. {
  993. ULONG Value;
  994. ULONG result;
  995. if((!ReadMemory(Location,&Value,sizeof(ULONG),&result)) ||
  996. (result < sizeof(ULONG)))
  997. {
  998. dprintf("unable to read from %08x\n",Location);
  999. return 0;
  1000. }
  1001. return Value;
  1002. }
  1003. ULONG64 GetPointerFromAddress(
  1004. ULONG64 Location)
  1005. {
  1006. ULONG64 Value;
  1007. ULONG result;
  1008. if(ReadPtr(Location,&Value))
  1009. {
  1010. dprintf("unable to read from %p\n",Location);
  1011. return 0;
  1012. }
  1013. return Value;
  1014. }
  1015. ULONG GetUlongValue (
  1016. PCHAR String)
  1017. {
  1018. ULONG64 Location;
  1019. ULONG Value;
  1020. ULONG result;
  1021. Location = GetExpression(String);
  1022. if(!Location)
  1023. {
  1024. dprintf("unable to get %s\n",String);
  1025. return 0;
  1026. }
  1027. return GetUlongFromAddress(Location);
  1028. }
  1029. ULONG64 GetPointerValue (
  1030. PCHAR String)
  1031. {
  1032. ULONG64 Location, Val=0;
  1033. Location = GetExpression(String);
  1034. if(!Location)
  1035. {
  1036. dprintf("unable to get %s\n",String);
  1037. return 0;
  1038. }
  1039. ReadPtr(Location, &Val);
  1040. return Val;
  1041. }