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.

3526 lines
93 KiB

  1. #include <nt.h>
  2. #include <ntrtl.h>
  3. #include <nturtl.h>
  4. #include <ntverp.h>
  5. #include <windef.h>
  6. #include <winbase.h>
  7. #include <wdbgexts.h>
  8. #include <stdlib.h> // needed for atoi function
  9. #include "wrapper.h"
  10. #include "mini.h"
  11. #include "ndiskd.h"
  12. WINDBG_EXTENSION_APIS ExtensionApis;
  13. EXT_API_VERSION ApiVersion = { 5, 0, EXT_API_VERSION_NUMBER64, 0 };
  14. #define NL 1
  15. #define NONL 0
  16. USHORT SavedMajorVersion;
  17. USHORT SavedMinorVersion;
  18. BOOL ChkTarget; // is debuggee a CHK build?
  19. //
  20. // Names of interesting structures
  21. //
  22. CHAR * NDIS_PROTOCOL_CHARACTERISTICS_NAME = "ndis!_NDIS50_PROTOCOL_CHARACTERISTICS";
  23. CHAR * NDIS_PROTOCOL_BLOCK_NAME = "ndis!_NDIS_PROTOCOL_BLOCK";
  24. CHAR * NDIS_OPEN_BLOCK_NAME = "ndis!_NDIS_OPEN_BLOCK";
  25. CHAR * NDIS_COMMON_OPEN_BLOCK_NAME = "ndis!_NDIS_COMMON_OPEN_BLOCK";
  26. CHAR * NDIS_MINIPORT_BLOCK_NAME = "ndis!_NDIS_MINIPORT_BLOCK";
  27. CHAR * NDIS_M_DRIVER_BLOCK_NAME = "ndis!_NDIS_M_DRIVER_BLOCK";
  28. CHAR * NDIS_CO_VC_PTR_BLOCK_NAME = "ndis!_NDIS_CO_VC_PTR_BLOCK";
  29. CHAR * NDIS_CO_VC_BLOCK_NAME = "ndis!_NDIS_CO_VC_BLOCK";
  30. CHAR * NDIS_CO_AF_BLOCK_NAME = "ndis!_NDIS_CO_AF_BLOCK";
  31. CHAR * NDIS_PACKET_NAME = "ndis!_NDIS_PACKET";
  32. CHAR * NDIS_BUFFER_NAME = "ndis!_MDL";
  33. CHAR * NDIS_STRING_NAME = "ndis!_UNICODE_STRING";
  34. CHAR * LIST_ENTRY_NAME = "ndis!_LIST_ENTRY";
  35. CHAR * NDIS_PKT_POOL_NAME = "ndis!_NDIS_PKT_POOL";
  36. CHAR * NDIS_TRACK_MEM_NAME = "ndis!_NDIS_TRACK_MEM";
  37. CHAR * NDIS_PKT_POOL_HDR_NAME = "ndis!_NDIS_PKT_POOL_HDR";
  38. CHAR * STACK_INDEX_NAME = "ndis!_STACK_INDEX";
  39. CHAR * NDIS_PACKET_STACK_NAME = "ndis!_NDIS_PACKET_STACK";
  40. CHAR * CPRD_NAME = "ndis!_CM_PARTIAL_RESOURCE_DESCRIPTOR";
  41. CHAR * CFRD_NAME = "ndis!_CM_FULL_RESOURCE_DESCRIPTOR";
  42. CHAR * CRL_NAME = "ndis!_CM_RESOURCE_LIST";
  43. CHAR * DEVICE_CAPS_NAME = "ndis!_DEVICE_CAPABILITIES";
  44. typedef struct
  45. {
  46. CHAR Name[16];
  47. unsigned int Val;
  48. } DBG_LEVEL;
  49. DBG_LEVEL DbgLevel[] = {
  50. {"INFO", DBG_LEVEL_INFO},
  51. {"LOG", DBG_LEVEL_LOG},
  52. {"WARN", DBG_LEVEL_WARN},
  53. {"ERR", DBG_LEVEL_ERR},
  54. {"FATAL", DBG_LEVEL_FATAL}
  55. };
  56. typedef struct
  57. {
  58. CHAR Name[16];
  59. unsigned int Val;
  60. } DBG_COMP;
  61. DBG_COMP DbgSystems[] = {
  62. {"INIT", DBG_COMP_INIT},
  63. {"CONFIG", DBG_COMP_CONFIG},
  64. {"SEND", DBG_COMP_SEND},
  65. {"RECV", DBG_COMP_RECV},
  66. {"PROTOCOL", DBG_COMP_PROTOCOL},
  67. {"BIND", DBG_COMP_BIND},
  68. {"BUS_QUERY", DBG_COMP_BUSINFO},
  69. {"REGISTRY", DBG_COMP_REG},
  70. {"MEMORY", DBG_COMP_MEMORY},
  71. {"FILTER", DBG_COMP_FILTER},
  72. {"REQUEST", DBG_COMP_REQUEST},
  73. {"WORK_ITEM", DBG_COMP_WORK_ITEM},
  74. {"PNP", DBG_COMP_PNP},
  75. {"PM", DBG_COMP_PM},
  76. {"OPEN", DBG_COMP_OPENREF},
  77. {"LOCKS", DBG_COMP_LOCKS},
  78. {"RESET", DBG_COMP_RESET},
  79. {"WMI", DBG_COMP_WMI},
  80. {"NDIS_CO", DBG_COMP_CO},
  81. {"REFERENCE", DBG_COMP_REF}
  82. };
  83. typedef struct
  84. {
  85. CHAR Name[40];
  86. UINT Val;
  87. } DBG_PER_PACKET_INFO_ID_TYPES;
  88. DBG_PER_PACKET_INFO_ID_TYPES DbgPacketInfoIdTypes[] = {
  89. {"TcpIpChecksumPacketInfo", TcpIpChecksumPacketInfo},
  90. {"IpSecPacketInfo", IpSecPacketInfo},
  91. {"TcpLargeSendPacketInfo", TcpLargeSendPacketInfo},
  92. {"ClassificationHandlePacketInfo", ClassificationHandlePacketInfo},
  93. {"NdisReserved", NdisReserved},
  94. {"ScatterGatherListPacketInfo", ScatterGatherListPacketInfo},
  95. {"Ieee8021pPriority", Ieee8021pPriority},
  96. {"OriginalPacketInfo", OriginalPacketInfo},
  97. {"PacketCancelId", PacketCancelId},
  98. {"MaxPerPacketInfo", MaxPerPacketInfo}
  99. };
  100. typedef struct
  101. {
  102. CHAR Name[20];
  103. unsigned int Val;
  104. } DBG_MEDIA_TYPES;
  105. DBG_MEDIA_TYPES DbgMediaTypes[] = {
  106. {"802.3", NdisMedium802_3},
  107. {"802.5", NdisMedium802_5},
  108. {"FDDI", NdisMediumFddi},
  109. {"WAN", NdisMediumWan},
  110. {"LocalTalk", NdisMediumLocalTalk},
  111. {"Dix", NdisMediumDix},
  112. {"ArcNet Raw", NdisMediumArcnetRaw},
  113. {"ArcNet 878.2", NdisMediumArcnet878_2},
  114. {"ATM", NdisMediumAtm},
  115. {"Wireless WAN", NdisMediumWirelessWan},
  116. {"IRDA", NdisMediumIrda},
  117. {"BPC", NdisMediumBpc},
  118. {"CO-WAN", NdisMediumCoWan},
  119. {"IEEE1394",NdisMedium1394},
  120. {"Illegal", NdisMediumMax}
  121. };
  122. typedef struct
  123. {
  124. CHAR Name[64];
  125. unsigned int Val;
  126. } DBG_MINIPORT_FLAGS;
  127. DBG_MINIPORT_FLAGS DbgMiniportFlags[] = {
  128. {"NORMAL_INTERRUPTS", fMINIPORT_NORMAL_INTERRUPTS},
  129. {"IN_INITIALIZE", fMINIPORT_IN_INITIALIZE},
  130. {"ARCNET_BROADCAST_SET", fMINIPORT_ARCNET_BROADCAST_SET},
  131. {"BUS_MASTER", fMINIPORT_BUS_MASTER},
  132. {"64BIT_DMA", fMINIPORT_64BITS_DMA},
  133. {"DEREGISTERED_INTERRUPT", fMINIPORT_DEREGISTERED_INTERRUPT},
  134. {"SG_LIST", fMINIPORT_SG_LIST},
  135. {"REQUEST_TIMEOUT", fMINIPORT_REQUEST_TIMEOUT},
  136. {"PROCESSING_REQUEST", fMINIPORT_PROCESSING_REQUEST},
  137. {"IGNORE_PACKET_QUEUE", fMINIPORT_IGNORE_PACKET_QUEUE},
  138. {"IGNORE_REQUEST_QUEUE", fMINIPORT_IGNORE_REQUEST_QUEUE},
  139. {"IGNORE_TOKEN_RING_ERRORS", fMINIPORT_IGNORE_TOKEN_RING_ERRORS},
  140. {"CHECK_FOR_LOOPBACK", fMINIPORT_CHECK_FOR_LOOPBACK},
  141. {"INTERMEDIATE_DRIVER", fMINIPORT_INTERMEDIATE_DRIVER},
  142. {"NDIS_5", fMINIPORT_IS_NDIS_5},
  143. {"IS_CO", fMINIPORT_IS_CO},
  144. {"DESERIALIZED", fMINIPORT_DESERIALIZE},
  145. {"CALLING_RESET", fMINIPORT_CALLING_RESET},
  146. {"RESET_REQUESTED", fMINIPORT_RESET_REQUESTED},
  147. {"RESET_IN_PROGRESS", fMINIPORT_RESET_IN_PROGRESS},
  148. {"RESOURCES_AVAILABLE", fMINIPORT_RESOURCES_AVAILABLE},
  149. {"SEND_LOOPBACK_DIRECTED", fMINIPORT_SEND_LOOPBACK_DIRECTED},
  150. {"RESTORING_FILTERS", fMINIPORT_RESTORING_FILTERS},
  151. {"REQUIRES_MEDIA_POLLING", fMINIPORT_REQUIRES_MEDIA_POLLING},
  152. {"SUPPORTS_MEDIA_SENSE", fMINIPORT_SUPPORTS_MEDIA_SENSE},
  153. {"DOES_NOT_DO_LOOPBACK", fMINIPORT_DOES_NOT_DO_LOOPBACK},
  154. {"SECONDARY", fMINIPORT_SECONDARY},
  155. {"MEDIA_CONNECTED", fMINIPORT_MEDIA_CONNECTED},
  156. {"NETBOOT_CARD", fMINIPORT_NETBOOT_CARD},
  157. {"PM_HALTING", fMINIPORT_PM_HALTING}
  158. };
  159. //
  160. // flags that we care more if they are cleared
  161. //
  162. DBG_MINIPORT_FLAGS DbgMiniportClearedFlags[] = {
  163. {"NOT_BUS_MASTER", fMINIPORT_BUS_MASTER},
  164. {"NOT_IGNORE_TOKEN_RING_ERRORS", fMINIPORT_IGNORE_TOKEN_RING_ERRORS},
  165. {"NOT_RESOURCES_AVAILABLE", fMINIPORT_RESOURCES_AVAILABLE},
  166. {"NOT_SUPPORTS_MEDIA_SENSE", fMINIPORT_SUPPORTS_MEDIA_SENSE},
  167. {"DOES_LOOPBACK", fMINIPORT_DOES_NOT_DO_LOOPBACK},
  168. {"NOT_MEDIA_CONNECTED", fMINIPORT_MEDIA_CONNECTED}
  169. };
  170. typedef DBG_MINIPORT_FLAGS DBG_MINIPORT_PNP_FLAGS;
  171. DBG_MINIPORT_PNP_FLAGS DbgMiniportPnPFlags[] = {
  172. {"PM_SUPPORTED", fMINIPORT_PM_SUPPORTED},
  173. {"NO_SHUTDOWN", fMINIPORT_NO_SHUTDOWN},
  174. {"MEDIA_DISCONNECT_WAIT", fMINIPORT_MEDIA_DISCONNECT_WAIT},
  175. {"REMOVE_IN_PROGRESS", fMINIPORT_REMOVE_IN_PROGRESS},
  176. {"DEVICE_POWER_ENABLED", fMINIPORT_DEVICE_POWER_ENABLE},
  177. {"DEVICE_POWER_WAKE_ENABLE", fMINIPORT_DEVICE_POWER_WAKE_ENABLE},
  178. {"DEVICE_FAILED", fMINIPORT_DEVICE_FAILED},
  179. {"MEDIA_DISCONNECT_CANCELLED", fMINIPORT_MEDIA_DISCONNECT_CANCELLED},
  180. {"SEND_WAIT_WAKE", fMINIPORT_SEND_WAIT_WAKE},
  181. {"SYSTEM_SLEEPING", fMINIPORT_SYSTEM_SLEEPING},
  182. {"HIDDEN", fMINIPORT_HIDDEN},
  183. {"SWENUM", fMINIPORT_SWENUM},
  184. {"PM_HALTED", fMINIPORT_PM_HALTED},
  185. {"NO_HALT_ON_SUSPEND", fMINIPORT_NO_HALT_ON_SUSPEND},
  186. {"RECEIVED_START", fMINIPORT_RECEIVED_START},
  187. {"REJECT_REQUESTS", fMINIPORT_REJECT_REQUESTS},
  188. {"PROCESSING", fMINIPORT_PROCESSING},
  189. {"HALTING", fMINIPORT_HALTING},
  190. {"VERIFYING", fMINIPORT_VERIFYING},
  191. {"HARDWARE_DEVICE", fMINIPORT_HARDWARE_DEVICE},
  192. {"NDIS_WDM_DRIVER", fMINIPORT_NDIS_WDM_DRIVER},
  193. {"SHUT_DOWN", fMINIPORT_SHUT_DOWN},
  194. {"SHUTTING_DOWN", fMINIPORT_SHUTTING_DOWN},
  195. {"ORPHANED", fMINIPORT_ORPHANED},
  196. {"QUEUED_BIND_WORKITEM", fMINIPORT_QUEUED_BIND_WORKITEM},
  197. {"FILTER_IM", fMINIPORT_FILTER_IM}
  198. };
  199. typedef DBG_MINIPORT_FLAGS DBG_MINIPORT_PNP_CAPABILITIES;
  200. DBG_MINIPORT_PNP_CAPABILITIES DbgMiniportCapabilities[] = {
  201. {"NOT_STOPPABLE", NDIS_DEVICE_NOT_STOPPABLE},
  202. {"NOT_REMOVEABLE", NDIS_DEVICE_NOT_REMOVEABLE},
  203. {"NOT_SUSPENDABLE", NDIS_DEVICE_NOT_SUSPENDABLE},
  204. {"DISABLE_PM", NDIS_DEVICE_DISABLE_PM},
  205. {"DISABLE_WAKE_UP", NDIS_DEVICE_DISABLE_WAKE_UP},
  206. {"DISABLE_WAKE_ON_RECONNECT", NDIS_DEVICE_DISABLE_WAKE_ON_RECONNECT}
  207. };
  208. typedef DBG_MINIPORT_FLAGS DBG_MINIPORT_VERIFY_FLAGS;
  209. DBG_MINIPORT_VERIFY_FLAGS DbgMiniportVerifyFlags[] = {
  210. {"FAIL_MAP_REG_ALLOC", fMINIPORT_VERIFY_FAIL_MAP_REG_ALLOC},
  211. {"FAIL_INTERRUPT_REGISTER", fMINIPORT_VERIFY_FAIL_INTERRUPT_REGISTER},
  212. {"FAIL_SHARED_MEM_ALLOC", fMINIPORT_VERIFY_FAIL_SHARED_MEM_ALLOC},
  213. {"FAIL_CANCEL_TIMER", fMINIPORT_VERIFY_FAIL_CANCEL_TIMER},
  214. {"FAIL_MAP_IO_SPACE", fMINIPORT_VERIFY_FAIL_MAP_IO_SPACE},
  215. {"FAIL_REGISTER_IO", fMINIPORT_VERIFY_FAIL_REGISTER_IO},
  216. {"FAIL_READ_CONFIG_SPACE", fMINIPORT_VERIFY_FAIL_READ_CONFIG_SPACE},
  217. {"FAIL_WRITE_CONFIG_SPACE", fMINIPORT_VERIFY_FAIL_WRITE_CONFIG_SPACE},
  218. {"FAIL_INIT_SG_DMA", fMINIPORT_VERIFY_FAIL_INIT_SG}
  219. };
  220. typedef struct
  221. {
  222. CHAR Name[32];
  223. unsigned long Val;
  224. } DBG_DEVICE_STATE;
  225. DBG_DEVICE_STATE DbgDeviceState[] = {
  226. {"PowerDeviceUnspecified",PowerDeviceUnspecified},
  227. {"PowerDeviceD0",PowerDeviceD0},
  228. {"PowerDeviceD1",PowerDeviceD1},
  229. {"PowerDeviceD2",PowerDeviceD2},
  230. {"PowerDeviceD3",PowerDeviceD3},
  231. {"PowerDeviceMaximum",PowerDeviceMaximum},
  232. };
  233. typedef struct
  234. {
  235. CHAR Name[32];
  236. unsigned long Val;
  237. } DBG_VC_FLAGS;
  238. DBG_VC_FLAGS DbgVcPtrFlags[] = {
  239. {"VC_CALL_ACTIVE", VC_CALL_ACTIVE},
  240. {"VC_CALL_PENDING", VC_CALL_PENDING},
  241. {"VC_CALL_CLOSE_PENDING", VC_CALL_CLOSE_PENDING},
  242. {"VC_CALL_ABORTED", VC_CALL_ABORTED},
  243. {"VC_PTR_BLOCK_CLOSING", VC_PTR_BLOCK_CLOSING}
  244. };
  245. DBG_VC_FLAGS DbgVcFlags[] = {
  246. {"VC_ACTIVE", VC_ACTIVE},
  247. {"VC_ACTIVATE_PENDING", VC_ACTIVATE_PENDING},
  248. {"VC_DEACTIVATE_PENDING", VC_DEACTIVATE_PENDING},
  249. {"VC_DELETE_PENDING", VC_DELETE_PENDING},
  250. {"VC_HANDOFF_IN_PROGRESS", VC_HANDOFF_IN_PROGRESS}
  251. };
  252. typedef DBG_VC_FLAGS DBG_MINIPORT_PNP_DEVICE_STATE;
  253. DBG_MINIPORT_PNP_DEVICE_STATE DbgMiniportPnPDeviceState[] = {
  254. {"PNP_DEVICE_ADDED", NdisPnPDeviceAdded},
  255. {"PNP_DEVICE_STARTED", NdisPnPDeviceStarted},
  256. {"PNP_DEVICE_QUERY_STOPPED", NdisPnPDeviceQueryStopped},
  257. {"PNP_DEVICE_STOPPED", NdisPnPDeviceStopped},
  258. {"PNP_DEVICE_QUERY_REMOVED", NdisPnPDeviceQueryRemoved},
  259. {"PNP_DEVICE_REMOVED", NdisPnPDeviceRemoved}
  260. };
  261. typedef DBG_MINIPORT_FLAGS DBG_PACKET_FLAGS;
  262. DBG_PACKET_FLAGS DbgPacketFlags[] = {
  263. {"MULTICAST_PACKET", NDIS_FLAGS_MULTICAST_PACKET},
  264. {"RESERVED2", NDIS_FLAGS_RESERVED2},
  265. {"RESERVED3", NDIS_FLAGS_RESERVED3},
  266. {"DONT_LOOPBACK", NDIS_FLAGS_DONT_LOOPBACK},
  267. {"IS_LOOPBACK_PACKET", NDIS_FLAGS_IS_LOOPBACK_PACKET},
  268. {"LOOPBACK_ONLY", NDIS_FLAGS_LOOPBACK_ONLY},
  269. {"RESERVED4", NDIS_FLAGS_RESERVED4},
  270. {"DOUBLE_BUFFERED", NDIS_FLAGS_DOUBLE_BUFFERED}
  271. };
  272. DBG_PACKET_FLAGS DbgNdisPacketFlags[] = {
  273. {"fPACKET_HAS_TIMED_OUT", fPACKET_HAS_TIMED_OUT},
  274. {"fPACKET_IS_LOOPBACK", fPACKET_IS_LOOPBACK},
  275. {"fPACKET_SELF_DIRECTED", fPACKET_SELF_DIRECTED},
  276. {"fPACKET_DONT_COMPLETE", fPACKET_DONT_COMPLETE},
  277. {"fPACKET_PENDING", fPACKET_PENDING},
  278. {"fPACKET_ALREADY_LOOPEDBACK", fPACKET_ALREADY_LOOPEDBACK},
  279. {"fPACKET_CLEAR_ITEMS", fPACKET_CLEAR_ITEMS},
  280. {"fPACKET_CONTAINS_MEDIA_SPECIFIC_INFO", fPACKET_CONTAINS_MEDIA_SPECIFIC_INFO},
  281. {"fPACKET_ALLOCATED_BY_NDIS", fPACKET_ALLOCATED_BY_NDIS}
  282. };
  283. typedef DBG_MINIPORT_FLAGS DBG_PROTOCOL_FLAGS;
  284. DBG_PROTOCOL_FLAGS DbgProtocolFlags[]={
  285. {"NDIS_PROTOCOL_TESTER", NDIS_PROTOCOL_TESTER},
  286. {"NDIS_PROTOCOL_PROXY", NDIS_PROTOCOL_PROXY},
  287. {"NDIS_PROTOCOL_BIND_ALL_CO", NDIS_PROTOCOL_BIND_ALL_CO}
  288. };
  289. typedef DBG_MINIPORT_FLAGS DBG_OPEN_FLAGS;
  290. DBG_OPEN_FLAGS DbgOpenFlags[]={
  291. {"OPEN_USING_ETH_ENCAPSULATION", fMINIPORT_OPEN_USING_ETH_ENCAPSULATION},
  292. {"OPEN_NO_LOOPBACK", fMINIPORT_OPEN_NO_LOOPBACK},
  293. {"OPEN_PMODE", fMINIPORT_OPEN_PMODE},
  294. {"OPEN_NO_PROT_RSVD", fMINIPORT_OPEN_NO_PROT_RSVD},
  295. {"OPEN_PROCESSING", fMINIPORT_OPEN_PROCESSING},
  296. {"PACKET_RECEIVED", fMINIPORT_PACKET_RECEIVED},
  297. {"STATUS_RECEIVED", fMINIPORT_STATUS_RECEIVED},
  298. {"OPEN_CLOSING", fMINIPORT_OPEN_CLOSING},
  299. {"OPEN_UNBINDING", fMINIPORT_OPEN_UNBINDING},
  300. {"OPEN_CALL_MANAGER", fMINIPORT_OPEN_CALL_MANAGER},
  301. {"OPEN_NOTIFY_PROCESSING", fMINIPORT_OPEN_NOTIFY_PROCESSING},
  302. {"OPEN_CLOSE_COMPLETE", fMINIPORT_OPEN_CLOSE_COMPLETE},
  303. {"OPEN_DONT_FREE", fMINIPORT_OPEN_DONT_FREE}
  304. };
  305. /*
  306. * Get 'size' bytes from the debuggee program at 'dwAddress' and place it
  307. * in our address space at 'ptr'. Use 'type' in an error printout if necessary
  308. */
  309. BOOL
  310. GetData( IN LPVOID ptr, IN ULONG64 dwAddress, IN ULONG size, IN PCSTR type )
  311. {
  312. BOOL b;
  313. ULONG BytesRead;
  314. ULONG count = size;
  315. while( size > 0 ) {
  316. if (count >= 3000)
  317. count = 3000;
  318. b = ReadMemory(dwAddress, ptr, count, &BytesRead );
  319. if (!b || BytesRead != count ) {
  320. dprintf( "Unable to read %u bytes at %X, for %s\n", size, dwAddress, type );
  321. return FALSE;
  322. }
  323. dwAddress += count;
  324. size -= count;
  325. ptr = (LPVOID)((ULONG_PTR)ptr + count);
  326. }
  327. return TRUE;
  328. }
  329. /*
  330. * Fetch the null terminated UNICODE string at dwAddress into buf
  331. */
  332. BOOL
  333. GetString( IN ULONG64 dwAddress, IN LPWSTR buf, IN ULONG MaxChars )
  334. {
  335. do {
  336. if( !GetData( buf, dwAddress, sizeof( *buf ), "Character" ) )
  337. return FALSE;
  338. dwAddress += sizeof( *buf );
  339. } while( --MaxChars && *buf++ != '\0' );
  340. return TRUE;
  341. }
  342. char *mystrtok ( char *string, char * control )
  343. {
  344. static unsigned char *str;
  345. CHAR *p, *s;
  346. if( string )
  347. str = string;
  348. if( str == NULL || *str == '\0' )
  349. return NULL;
  350. //
  351. // Skip leading delimiters...
  352. //
  353. for( ; *str; str++ ) {
  354. for( s=control; *s; s++ ) {
  355. if( *str == *s )
  356. break;
  357. }
  358. if( *s == '\0' )
  359. break;
  360. }
  361. //
  362. // Was it was all delimiters?
  363. //
  364. if( *str == '\0' ) {
  365. str = NULL;
  366. return NULL;
  367. }
  368. //
  369. // We've got a string, terminate it at first delimeter
  370. //
  371. for( p = str+1; *p; p++ ) {
  372. for( s = control; *s; s++ ) {
  373. if( *p == *s ) {
  374. s = str;
  375. *p = '\0';
  376. str = p+1;
  377. return s;
  378. }
  379. }
  380. }
  381. //
  382. // We've got a string that ends with the NULL
  383. //
  384. s = str;
  385. str = NULL;
  386. return s;
  387. }
  388. DECLARE_API( help )
  389. {
  390. dprintf("NDIS extensions:\n");
  391. dprintf(" ndis dump ndis information\n");
  392. dprintf(" dbglevel [Level [Level] ...] toggle debug level\n");
  393. dprintf(" dbgsystems [Level [Level] ...] toggle debug systems\n");
  394. dprintf(" miniports <'all'> list all Miniports\n");
  395. dprintf(" gminiports <'all'> list all Miniports, even those not started yet\n");
  396. dprintf(" miniport <Miniport Block> dump Miniport block\n");
  397. dprintf(" mopen <Miniport Open Block> dump Miniport Open block\n");
  398. dprintf(" protocols dump all protocols and their opens\n");
  399. dprintf(" protocol <Protocol Block> dump the protocols block's contents\n");
  400. dprintf(" pkt <Packet> <Verbosity> dump the contents of the packet\n");
  401. dprintf(" pktpools list all allocated packet pools\n");
  402. dprintf(" mem list log of allocated memory if enabled\n");
  403. dprintf(" opens dump all opens\n");
  404. dprintf(" findpacket v <VirtualAddress> finds a packet containing a virtual address\n");
  405. dprintf(" findpacket p <PoolAddress> finds un-returned packets in a pool\n");
  406. }
  407. VOID
  408. ErrorCheckSymbols(
  409. CHAR *symbol
  410. )
  411. {
  412. dprintf("NDISKD: error - could not access %s - check symbols for ndis.sys\n",
  413. symbol);
  414. }
  415. DECLARE_API( dbglevel )
  416. {
  417. INT i;
  418. INT col = 0;
  419. ULONG DbgSettings;
  420. CHAR argbuf[ MAX_PATH ];
  421. CHAR *p;
  422. ULONG64 dwAddress;
  423. DWORD Written;
  424. dwAddress = GetExpression("ndis!ndisDebugLevel");
  425. if (dwAddress == 0)
  426. {
  427. ErrorCheckSymbols("ndis!ndisDebugLevel");
  428. return;
  429. }
  430. DbgSettings = GetUlongFromAddress(dwAddress);
  431. if (!args || !*args)
  432. {
  433. INT col = 0;
  434. dprintf("Current setting: ");
  435. for (i = 0; i < sizeof(DbgLevel)/sizeof(DBG_LEVEL); i++)
  436. {
  437. if (DbgSettings == DbgLevel[i].Val)
  438. {
  439. dprintf(" %s\n", DbgLevel[i].Name);
  440. if (col == 4)
  441. {
  442. col = 0;
  443. dprintf("\n");
  444. }
  445. else
  446. {
  447. col++;
  448. }
  449. break;
  450. }
  451. }
  452. if (col != 0)
  453. dprintf("\n");
  454. dprintf("Available settings: \n");
  455. for (i = 0; i < sizeof(DbgLevel)/sizeof(DBG_LEVEL); i++)
  456. {
  457. if (!(DbgSettings == DbgLevel[i].Val))
  458. {
  459. dprintf(" %s", DbgLevel[i].Name);
  460. if (col == 4)
  461. {
  462. col = 0;
  463. dprintf("\n");
  464. }
  465. else
  466. {
  467. col++;
  468. }
  469. }
  470. }
  471. if (col != 0)
  472. dprintf("\n");
  473. return;
  474. }
  475. strcpy( argbuf, args );
  476. for (p = mystrtok( argbuf, " \t,;" );
  477. p && *p;
  478. p = mystrtok(NULL, " \t,;"))
  479. {
  480. for (i = 0; i < sizeof(DbgLevel)/sizeof(DBG_LEVEL); i++)
  481. {
  482. if (strcmp(p, DbgLevel[i].Name) == 0)
  483. {
  484. DbgSettings = DbgLevel[i].Val;
  485. }
  486. }
  487. }
  488. WriteMemory(dwAddress, &DbgSettings, sizeof(DWORD), &Written);
  489. }
  490. DECLARE_API( dbgsystems )
  491. {
  492. INT i;
  493. INT col = 0;
  494. DWORD DbgSettings;
  495. CHAR argbuf[ MAX_PATH ];
  496. char *p;
  497. ULONG64 dwAddress;
  498. DWORD Written;
  499. dwAddress = GetExpression("ndis!ndisDebugSystems");
  500. if (dwAddress == 0)
  501. {
  502. ErrorCheckSymbols("ndis!ndisDebugSystems");
  503. return;
  504. }
  505. DbgSettings = GetUlongFromAddress(dwAddress);
  506. if (!args || !*args)
  507. {
  508. dprintf("Current settings:\n");
  509. for (i = 0; i < sizeof(DbgSystems)/sizeof(DBG_COMP); i++)
  510. {
  511. if (DbgSettings & DbgSystems[i].Val)
  512. {
  513. dprintf(" %s", DbgSystems[i].Name);
  514. if (col == 4)
  515. {
  516. col = 0;
  517. dprintf("\n");
  518. }
  519. else
  520. {
  521. col ++;
  522. }
  523. }
  524. }
  525. if (col != 0)
  526. dprintf("\n");
  527. col = 0;
  528. dprintf("Available settings:\n");
  529. for (i = 0; i < sizeof(DbgSystems)/sizeof(DBG_COMP); i++)
  530. {
  531. if (!(DbgSettings & DbgSystems[i].Val))
  532. {
  533. dprintf(" %s", DbgSystems[i].Name);
  534. if (col == 4)
  535. {
  536. col = 0;
  537. dprintf("\n");
  538. }
  539. else
  540. {
  541. col++;
  542. }
  543. }
  544. }
  545. if (col != 0)
  546. dprintf("\n");
  547. return;
  548. }
  549. strcpy( argbuf, args );
  550. for (p = mystrtok( argbuf, " \t,;" );
  551. p && *p;
  552. p = mystrtok(NULL, " \t,;"))
  553. {
  554. dprintf("\nArg = %s\n",p);
  555. for (i = 0; i < sizeof(DbgSystems)/sizeof(DBG_COMP); i++)
  556. {
  557. if (strcmp(p, DbgSystems[i].Name) == 0)
  558. {
  559. if (DbgSettings & DbgSystems[i].Val)
  560. {
  561. DbgSettings &= ~DbgSystems[i].Val;
  562. }
  563. else
  564. {
  565. DbgSettings |= DbgSystems[i].Val;
  566. }
  567. }
  568. }
  569. }
  570. WriteMemory(dwAddress, &DbgSettings, sizeof(DWORD), &Written);
  571. }
  572. DECLARE_API( miniports )
  573. {
  574. ULONG64 Addr;
  575. ULONG Val;
  576. ULONG64 DriverBlockAddr;
  577. ULONG64 MiniportAddr;
  578. CHAR argbuf[ MAX_PATH ];
  579. BOOLEAN fAll = FALSE;
  580. //
  581. // The flag fALL is used to dump all the miniport blocks in the minidriver list
  582. //
  583. if (args)
  584. {
  585. strcpy (argbuf,args);
  586. if ( strcmp ("all",argbuf )== 0 )
  587. {
  588. fAll = TRUE;
  589. }
  590. }
  591. Addr = GetExpression("ndis!ndisVerifierLevel");
  592. if (Addr != 0)
  593. {
  594. Val = GetUlongFromAddress(Addr);
  595. dprintf("NDIS Driver verifier level: %lx\n", Val);
  596. }
  597. else
  598. {
  599. ErrorCheckSymbols("ndis!ndisVerifierLevel");
  600. }
  601. Addr = GetExpression("ndis!ndisVeriferFailedAllocations");
  602. if (Addr != 0)
  603. {
  604. Val = GetUlongFromAddress(Addr);
  605. dprintf("NDIS Failed allocations : %lx\n", Val);
  606. }
  607. else
  608. {
  609. ErrorCheckSymbols("ndis!ndisVeriferFailedAllocations");
  610. }
  611. DriverBlockAddr = GetExpression("ndis!ndisMiniDriverList");
  612. if (DriverBlockAddr == 0)
  613. {
  614. ErrorCheckSymbols("ndis!ndisMiniDriverList");
  615. return;
  616. }
  617. DriverBlockAddr = GetPointerFromAddress(DriverBlockAddr);
  618. while (DriverBlockAddr != 0)
  619. {
  620. GetFieldValue(DriverBlockAddr, NDIS_M_DRIVER_BLOCK_NAME, "DriverVersion", Val);
  621. dprintf("Miniport Driver Block: %p, Version %u.%u\n", DriverBlockAddr,
  622. (USHORT)((Val & 0xffff0000)>>16),
  623. (USHORT)(Val & 0x0000ffff));
  624. GetFieldValue(DriverBlockAddr, NDIS_M_DRIVER_BLOCK_NAME, "MiniportQueue", MiniportAddr);
  625. while (MiniportAddr != 0)
  626. {
  627. if (CheckControlC())
  628. {
  629. break;
  630. }
  631. dprintf(" Miniport: %p ", MiniportAddr);
  632. PrintMiniportName(MiniportAddr);
  633. dprintf("\n");
  634. if (fAll == TRUE)
  635. {
  636. PrintMiniportDetails(MiniportAddr);
  637. dprintf("\n");
  638. }
  639. GetFieldValue(MiniportAddr, NDIS_MINIPORT_BLOCK_NAME, "NextMiniport", MiniportAddr);
  640. }
  641. if (CheckControlC())
  642. {
  643. break;
  644. }
  645. GetFieldValue(DriverBlockAddr, NDIS_M_DRIVER_BLOCK_NAME, "NextDriver", DriverBlockAddr);
  646. }
  647. }
  648. DECLARE_API(gminiports)
  649. {
  650. ULONG64 MiniportListAddr;
  651. ULONG64 MiniportAddr;
  652. ULONG64 MiniBlockAddr;
  653. BOOLEAN fAll = FALSE;
  654. CHAR argbuf[ MAX_PATH ];
  655. if (args)
  656. {
  657. strcpy (argbuf,args);
  658. if ( strcmp ("all",argbuf )== 0 )
  659. {
  660. fAll = TRUE;
  661. }
  662. }
  663. MiniportListAddr = GetExpression("ndis!ndisMiniportList");
  664. if (MiniportListAddr == 0)
  665. {
  666. ErrorCheckSymbols("ndis!ndisMiniportList");
  667. return;
  668. }
  669. MiniportAddr = GetPointerFromAddress(MiniportListAddr);
  670. while (MiniportAddr != 0)
  671. {
  672. if (CheckControlC())
  673. {
  674. break;
  675. }
  676. GetFieldValue(MiniportAddr, NDIS_MINIPORT_BLOCK_NAME, "DriverHandle", MiniBlockAddr);
  677. dprintf(" MiniBlock: %p, Miniport: %p ", MiniBlockAddr, MiniportAddr);
  678. PrintMiniportName(MiniportAddr);
  679. dprintf("\n");
  680. if (fAll == TRUE)
  681. {
  682. PrintMiniportDetails(MiniportAddr);
  683. dprintf("\n");
  684. }
  685. GetFieldValue(MiniportAddr, NDIS_MINIPORT_BLOCK_NAME, "NextGlobalMiniport", MiniportAddr);
  686. }
  687. }
  688. VOID
  689. WinDbgExtensionDllInit(
  690. PWINDBG_EXTENSION_APIS64 lpExtensionApis,
  691. USHORT MajorVersion,
  692. USHORT MinorVersion
  693. )
  694. {
  695. ExtensionApis = *lpExtensionApis;
  696. SavedMajorVersion = MajorVersion;
  697. SavedMinorVersion = MinorVersion;
  698. ChkTarget = SavedMajorVersion == 0x0c ? TRUE : FALSE;
  699. }
  700. DECLARE_API( version )
  701. {
  702. #if DBG
  703. PCSTR kind = "Checked";
  704. #else
  705. PCSTR kind = "Free";
  706. #endif
  707. dprintf(
  708. "%s NDIS Extension dll for Build %d debugging %s kernel for Build %d\n",
  709. kind,
  710. VER_PRODUCTBUILD,
  711. SavedMajorVersion == 0x0c ? "Checked" : "Free",
  712. SavedMinorVersion
  713. );
  714. }
  715. VOID
  716. CheckVersion(
  717. VOID
  718. )
  719. {
  720. //
  721. // for now don't bother to version check
  722. //
  723. return;
  724. #if DBG
  725. if ((SavedMajorVersion != 0x0c) || (SavedMinorVersion != VER_PRODUCTBUILD)) {
  726. dprintf("\r\n*** Extension DLL(%d Checked) does not match target system(%d %s)\r\n\r\n",
  727. VER_PRODUCTBUILD, SavedMinorVersion, (SavedMajorVersion==0x0f) ? "Free" : "Checked" );
  728. }
  729. #else
  730. if ((SavedMajorVersion != 0x0f) || (SavedMinorVersion != VER_PRODUCTBUILD)) {
  731. dprintf("\r\n*** Extension DLL(%d Free) does not match target system(%d %s)\r\n\r\n",
  732. VER_PRODUCTBUILD, SavedMinorVersion, (SavedMajorVersion==0x0f) ? "Free" : "Checked" );
  733. }
  734. #endif
  735. }
  736. LPEXT_API_VERSION
  737. ExtensionApiVersion(
  738. VOID
  739. )
  740. {
  741. return &ApiVersion;
  742. }
  743. //
  744. // VOID
  745. // PrintName(
  746. // ULONG64 UnicodeStringAddr
  747. // );
  748. // print a unicode string
  749. //
  750. VOID
  751. PrintName(
  752. ULONG64 UnicodeStringAddr
  753. )
  754. {
  755. USHORT i;
  756. #define MAX_STRING_LENGTH 256
  757. WCHAR ubuf[MAX_STRING_LENGTH];
  758. UCHAR abuf[MAX_STRING_LENGTH+1];
  759. ULONG MaxChars;
  760. ULONG64 BufAddr;
  761. USHORT Length;
  762. USHORT MaximumLength;
  763. ULONG64 Val;
  764. GetFieldValue(UnicodeStringAddr, NDIS_STRING_NAME, "Buffer", Val);
  765. BufAddr = Val;
  766. GetFieldValue(UnicodeStringAddr, NDIS_STRING_NAME, "Length", Val);
  767. Length = (USHORT)Val;
  768. GetFieldValue(UnicodeStringAddr, NDIS_STRING_NAME, "MaximumLength", Val);
  769. MaximumLength = (USHORT)Val;
  770. //
  771. // Truncate so that we don't crash with bad data.
  772. //
  773. MaxChars = (Length > MAX_STRING_LENGTH)? MAX_STRING_LENGTH: Length;
  774. if (!GetData(ubuf, BufAddr, MaxChars, "STRING"))
  775. {
  776. return;
  777. }
  778. for (i = 0; i < Length/2; i++)
  779. {
  780. abuf[i] = (UCHAR)ubuf[i];
  781. }
  782. abuf[i] = 0;
  783. dprintf("%s",abuf);
  784. }
  785. VOID
  786. PrintMiniportName(
  787. ULONG64 MiniportAddr
  788. )
  789. {
  790. ULONG64 Val;
  791. GetFieldValue(MiniportAddr, NDIS_MINIPORT_BLOCK_NAME, "pAdapterInstanceName", Val);
  792. PrintName(Val);
  793. }
  794. VOID
  795. PrintMiniportDetails(
  796. ULONG64 MiniportAddr
  797. )
  798. {
  799. ULONG i;
  800. ULONG j;
  801. ULONG Flags;
  802. ULONG64 Val;
  803. ULONG Offset;
  804. ULONG64 DeviceCapsAddr;
  805. ULONG64 DeviceStateAddr;
  806. ULONG64 ResourcesAddr;
  807. ULONG DeviceState;
  808. ULONG SizeOfDeviceState;
  809. ULONG SystemWake, DeviceWake;
  810. ULONG SizeOfPvoid;
  811. ULONG64 VarAddr;
  812. #define MAX_FLAGS_PER_LINE 3
  813. InitTypeRead(MiniportAddr, NDIS_MINIPORT_BLOCK);
  814. Val = ReadField(MiniportAdapterContext);
  815. dprintf(" AdapterContext : %p\n", Val);
  816. Flags = (ULONG)ReadField(Flags);
  817. dprintf(" Flags : %08x\n", Flags);
  818. j = 0;
  819. for (i = 0; i < sizeof(DbgMiniportFlags)/sizeof(DBG_MINIPORT_FLAGS); i++)
  820. {
  821. if (Flags & DbgMiniportFlags[i].Val)
  822. {
  823. if (j == 0)
  824. {
  825. dprintf(" ");
  826. }
  827. dprintf("%s", DbgMiniportFlags[i].Name);
  828. j++;
  829. if (j != MAX_FLAGS_PER_LINE)
  830. {
  831. dprintf(", ");
  832. }
  833. else
  834. {
  835. dprintf("\n");
  836. j = 0;
  837. }
  838. }
  839. }
  840. if (j != 0)
  841. {
  842. dprintf("\n");
  843. }
  844. j = 0;
  845. for (i = 0; i < sizeof(DbgMiniportClearedFlags)/sizeof(DBG_MINIPORT_FLAGS); i++)
  846. {
  847. if (!(Flags & DbgMiniportClearedFlags[i].Val))
  848. {
  849. if (j == 0)
  850. {
  851. dprintf(" ");
  852. }
  853. dprintf("%s", DbgMiniportClearedFlags[i].Name);
  854. j++;
  855. if (j != MAX_FLAGS_PER_LINE)
  856. {
  857. dprintf(", ");
  858. }
  859. else
  860. {
  861. dprintf("\n");
  862. j = 0;
  863. }
  864. }
  865. }
  866. if (j != 0)
  867. {
  868. dprintf("\n");
  869. }
  870. Flags = (ULONG)ReadField(PnPFlags);
  871. dprintf(" PnPFlags : %08x\n", Flags);
  872. j = 0;
  873. for (i = 0; i < sizeof(DbgMiniportPnPFlags)/sizeof(DBG_MINIPORT_PNP_FLAGS); i++)
  874. {
  875. if (Flags & DbgMiniportPnPFlags[i].Val)
  876. {
  877. if (j == 0)
  878. {
  879. dprintf(" ");
  880. }
  881. dprintf("%s", DbgMiniportPnPFlags[i].Name);
  882. j++;
  883. if (j != MAX_FLAGS_PER_LINE)
  884. {
  885. dprintf(", ");
  886. }
  887. else
  888. {
  889. dprintf("\n");
  890. j = 0;
  891. }
  892. }
  893. }
  894. if (j != 0)
  895. {
  896. dprintf("\n");
  897. }
  898. // dprintf(" CheckforHang interval : %ld seconds\n", ReadField(CheckForHangSeconds));
  899. // dprintf(" CurrentTick : %04u\n", ReadField(CFHangCurrentTick));
  900. // dprintf(" IntervalTicks : %04u\n", ReadField(CFHangTicks));
  901. dprintf(" InternalResetCount : %04u\n", (USHORT)ReadField(InternalResetCount));
  902. dprintf(" MiniportResetCount : %04u\n", (USHORT)ReadField(MiniportResetCount));
  903. dprintf(" References : %u\n", (USHORT)ReadField(Ref.ReferenceCount));
  904. dprintf(" UserModeOpenReferences: %ld\n", (ULONG)ReadField(UserModeOpenReferences));
  905. dprintf(" PnPDeviceState : ");
  906. Val = (ULONG)ReadField(PnPDeviceState);
  907. if (Val <= NdisPnPDeviceRemoved)
  908. {
  909. dprintf("%s\n", DbgMiniportPnPDeviceState[Val].Name);
  910. }
  911. dprintf(" CurrentDevicePowerState : ");
  912. Val = (ULONG)ReadField(CurrentDevicePowerState);
  913. if (Val < PowerDeviceMaximum)
  914. {
  915. dprintf("%s\n", DbgDeviceState[Val].Name);
  916. }
  917. else
  918. {
  919. dprintf("Illegal Value\n");
  920. }
  921. dprintf(" Bus PM capabilities\n");
  922. //
  923. // Use GetFieldValue() rather than ReadField() for bit fields.
  924. //
  925. GetFieldValue(MiniportAddr, NDIS_MINIPORT_BLOCK_NAME, "DeviceCaps.DeviceD1", Val);
  926. dprintf("\tDeviceD1:\t\t%lu\n", (ULONG)Val);
  927. GetFieldValue(MiniportAddr, NDIS_MINIPORT_BLOCK_NAME, "DeviceCaps.DeviceD2", Val);
  928. dprintf("\tDeviceD2:\t\t%lu\n", (ULONG)Val);
  929. GetFieldValue(MiniportAddr, NDIS_MINIPORT_BLOCK_NAME, "DeviceCaps.WakeFromD0", Val);
  930. dprintf("\tWakeFromD0:\t\t%lu\n", (ULONG)Val);
  931. GetFieldValue(MiniportAddr, NDIS_MINIPORT_BLOCK_NAME, "DeviceCaps.WakeFromD1", Val);
  932. dprintf("\tWakeFromD1:\t\t%lu\n", (ULONG)Val);
  933. GetFieldValue(MiniportAddr, NDIS_MINIPORT_BLOCK_NAME, "DeviceCaps.WakeFromD2", Val);
  934. dprintf("\tWakeFromD2:\t\t%lu\n", (ULONG)Val);
  935. GetFieldValue(MiniportAddr, NDIS_MINIPORT_BLOCK_NAME, "DeviceCaps.WakeFromD3", Val);
  936. dprintf("\tWakeFromD3:\t\t%lu\n\n", (ULONG)Val);
  937. dprintf("\tSystemState\t\tDeviceState\n");
  938. do
  939. {
  940. if (GetFieldOffset(NDIS_MINIPORT_BLOCK_NAME, "DeviceCaps.DeviceState", &Offset) != 0)
  941. {
  942. dprintf("Can't get offset of DeviceCaps.DeviceState in %s\n", NDIS_MINIPORT_BLOCK_NAME);
  943. break;
  944. }
  945. SizeOfDeviceState = GetTypeSize("ULONG");
  946. DeviceStateAddr = MiniportAddr + (ULONG)Offset;
  947. DeviceState = GetUlongFromAddress(DeviceStateAddr);
  948. DeviceStateAddr += SizeOfDeviceState;
  949. if (DeviceState == PowerDeviceUnspecified)
  950. {
  951. dprintf("\tPowerSystemUnspecified\tPowerDeviceUnspecified\n");
  952. }
  953. else
  954. {
  955. dprintf("\tPowerSystemUnspecified\t\tD%ld\n", (ULONG)(DeviceState - 1));
  956. }
  957. for (i = 1; i < PowerSystemMaximum; i++)
  958. {
  959. DeviceState = GetUlongFromAddress(DeviceStateAddr);
  960. DeviceStateAddr += SizeOfDeviceState;
  961. if (DeviceState == PowerDeviceUnspecified)
  962. {
  963. dprintf("\tS%lu\t\t\tPowerDeviceUnspecified\n",(i-1));
  964. }
  965. else
  966. {
  967. dprintf("\tS%lu\t\t\tD%lu\n",(ULONG)(i-1), (ULONG)(DeviceState - 1));
  968. }
  969. }
  970. }
  971. while (FALSE);
  972. GetFieldValue(MiniportAddr, NDIS_MINIPORT_BLOCK_NAME, "DeviceCaps.SystemWake", SystemWake);
  973. if (SystemWake == PowerSystemUnspecified)
  974. dprintf("\tSystemWake: PowerSystemUnspecified\n");
  975. else
  976. dprintf("\tSystemWake: S%lu\n", (ULONG)(SystemWake - 1));
  977. GetFieldValue(MiniportAddr, NDIS_MINIPORT_BLOCK_NAME, "DeviceCaps.DeviceWake", DeviceWake);
  978. if (DeviceWake == PowerDeviceUnspecified)
  979. {
  980. dprintf("\tDeviceWake: PowerDeviceUnspecified\n");
  981. }
  982. else
  983. {
  984. dprintf("\tDeviceWake: D%lu\n", (ULONG)(DeviceWake - 1));
  985. }
  986. Flags = (ULONG)ReadField(PnPFlags);
  987. if ((DeviceWake != PowerDeviceUnspecified) &&
  988. (SystemWake != PowerSystemUnspecified) &&
  989. (Flags & fMINIPORT_PM_SUPPORTED))
  990. {
  991. ULONG WakeUpEnable;
  992. WakeUpEnable = (ULONG)ReadField(WakeUpEnable);
  993. dprintf("\n WakeupMethods Enabled %lx:\n\t", WakeUpEnable);
  994. if (WakeUpEnable & NDIS_PNP_WAKE_UP_MAGIC_PACKET)
  995. dprintf("WAKE_UP_MAGIC_PACKET ");
  996. if (WakeUpEnable & NDIS_PNP_WAKE_UP_PATTERN_MATCH)
  997. dprintf("WAKE_UP_PATTERN_MATCH ");
  998. if (WakeUpEnable & NDIS_PNP_WAKE_UP_LINK_CHANGE)
  999. dprintf("WAKE_UP_LINK_CHANGE ");
  1000. dprintf("\n WakeUpCapabilities:\n");
  1001. dprintf("\tMinMagicPacketWakeUp: %lu\n",(ULONG)ReadField(PMCapabilities.WakeUpCapabilities.MinMagicPacketWakeUp));
  1002. dprintf("\tMinPatternWakeUp: %lu\n", (ULONG)ReadField(PMCapabilities.WakeUpCapabilities.MinPatternWakeUp));
  1003. dprintf("\tMinLinkChangeWakeUp: %lu\n", (ULONG)ReadField(PMCapabilities.WakeUpCapabilities.MinLinkChangeWakeUp));
  1004. }
  1005. Flags = (ULONG)ReadField(PnPCapabilities);
  1006. dprintf(" Current PnP and PM Settings: : %08x\n", Flags);
  1007. j = 0;
  1008. for (i = 0; i < sizeof(DbgMiniportCapabilities)/sizeof(DBG_MINIPORT_PNP_CAPABILITIES); i++)
  1009. {
  1010. if (Flags & DbgMiniportCapabilities[i].Val)
  1011. {
  1012. if (j == 0)
  1013. {
  1014. dprintf(" ");
  1015. }
  1016. dprintf("%s", DbgMiniportCapabilities[i].Name);
  1017. j++;
  1018. if (j != MAX_FLAGS_PER_LINE)
  1019. {
  1020. dprintf(", ");
  1021. }
  1022. else
  1023. {
  1024. dprintf("\n");
  1025. j = 0;
  1026. }
  1027. }
  1028. }
  1029. if (j != 0)
  1030. {
  1031. dprintf("\n");
  1032. }
  1033. ResourcesAddr = ReadField(AllocatedResources);
  1034. if (ResourcesAddr)
  1035. {
  1036. dprintf(" Allocated Resources:\n");
  1037. PrintResources(ResourcesAddr);
  1038. dprintf(" Translated Allocated Resources:\n");
  1039. ResourcesAddr = ReadField(AllocatedResourcesTranslated);
  1040. PrintResources(ResourcesAddr);
  1041. }
  1042. else
  1043. {
  1044. dprintf(" No Resources Allocated\n");
  1045. }
  1046. dprintf(" MediaType : ");
  1047. Val = ReadField(MediaType);
  1048. if (Val < NdisMediumMax)
  1049. {
  1050. dprintf("%s\n", DbgMediaTypes[Val].Name);
  1051. }
  1052. else
  1053. {
  1054. dprintf("Illegal value: %d\n", Val);
  1055. }
  1056. dprintf(" DeviceObject : %p, PhysDO : %p Next DO: %p\n",
  1057. ReadField(DeviceObject),
  1058. ReadField(PhysicalDeviceObject),
  1059. ReadField(NextDeviceObject));
  1060. dprintf(" MapRegisters : %p\n", ReadField(MapRegisters));
  1061. dprintf(" FirstPendingPkt: %p\n", ReadField(FirstPendingPacket));
  1062. /*
  1063. SizeOfPvoid = GetTypeSize("SINGLE_LIST_ENTRY");
  1064. if (GetFieldOffset(NDIS_MINIPORT_BLOCK_NAME, "SingleWorkItems", &Offset) != 0)
  1065. {
  1066. dprintf("Can't get offset of SingleWorkItems in %s\n", NDIS_MINIPORT_BLOCK_NAME);
  1067. }
  1068. else
  1069. {
  1070. VarAddr = MiniportAddr + Offset;
  1071. dprintf(" SingleWorkItems:\n");
  1072. for (i = 0, j = 1; i < NUMBER_OF_SINGLE_WORK_ITEMS; i++)
  1073. {
  1074. if (j == 1)
  1075. {
  1076. dprintf(" ");
  1077. }
  1078. dprintf("[%d]: %p ", i, GetPointerFromAddress(VarAddr));
  1079. VarAddr += SizeOfPvoid;
  1080. if (j == 4)
  1081. {
  1082. dprintf("\n");
  1083. j = 1;
  1084. }
  1085. else
  1086. {
  1087. j++;
  1088. }
  1089. }
  1090. if (j != 1)
  1091. {
  1092. dprintf("\n");
  1093. }
  1094. }
  1095. */
  1096. Flags = (ULONG)ReadField(DriverVerifyFlags);
  1097. dprintf(" DriverVerifyFlags : %08x\n", Flags);
  1098. j = 0;
  1099. for (i = 0; i < sizeof(DbgMiniportVerifyFlags)/sizeof(DBG_MINIPORT_VERIFY_FLAGS); i++)
  1100. {
  1101. if (Flags & DbgMiniportVerifyFlags[i].Val)
  1102. {
  1103. if (j == 0)
  1104. {
  1105. dprintf(" ");
  1106. }
  1107. dprintf("%s", DbgMiniportVerifyFlags[i].Name);
  1108. j++;
  1109. if (j != MAX_FLAGS_PER_LINE)
  1110. {
  1111. dprintf(", ");
  1112. }
  1113. else
  1114. {
  1115. dprintf("\n");
  1116. j = 0;
  1117. }
  1118. }
  1119. }
  1120. if (j != 0)
  1121. {
  1122. dprintf("\n");
  1123. }
  1124. dprintf(" Miniport Interrupt : %p\n", ReadField(Interrupt));
  1125. PrintMiniportOpenList(MiniportAddr);
  1126. }
  1127. VOID
  1128. PrintMiniportOpenList(
  1129. ULONG64 MiniportAddr
  1130. )
  1131. {
  1132. ULONG64 OpenAddr;
  1133. ULONG64 ProtocolAddr;
  1134. ULONG64 ProtocolContext;
  1135. ULONG Offset;
  1136. InitTypeRead(MiniportAddr, NDIS_MINIPORT_BLOCK);
  1137. dprintf(" Miniport Open Block Queue:\n");
  1138. OpenAddr = ReadField(OpenQueue);
  1139. if (GetFieldOffset(NDIS_PROTOCOL_BLOCK_NAME, "ProtocolCharacteristics.Name", &Offset) != 0)
  1140. {
  1141. dprintf("Cant get offset of Name in Protocol block!");
  1142. Offset = (ULONG)-1;
  1143. }
  1144. while (OpenAddr != 0)
  1145. {
  1146. if (CheckControlC())
  1147. {
  1148. break;
  1149. }
  1150. GetFieldValue(OpenAddr, NDIS_COMMON_OPEN_BLOCK_NAME, "ProtocolHandle", ProtocolAddr);
  1151. dprintf(" %p: Protocol %p = ", OpenAddr, ProtocolAddr);
  1152. if (Offset != (ULONG)-1)
  1153. {
  1154. PrintName(ProtocolAddr + Offset);
  1155. }
  1156. GetFieldValue(OpenAddr, NDIS_COMMON_OPEN_BLOCK_NAME, "ProtocolBindingContext", ProtocolContext);
  1157. dprintf(", ProtocolBindingContext %p\n", ProtocolContext);
  1158. GetFieldValue(OpenAddr, NDIS_COMMON_OPEN_BLOCK_NAME, "MiniportNextOpen", OpenAddr);
  1159. }
  1160. }
  1161. //
  1162. // PrintResources: ResourceListAddr is addr of CM_RESOURCE_LIST
  1163. //
  1164. VOID
  1165. PrintResources(
  1166. ULONG64 ResourceListAddr
  1167. )
  1168. {
  1169. ULONG64 FullResourceDescrAddr;
  1170. ULONG64 PartialResourceDescrAddr;
  1171. ULONG SizeOfFullDescr;
  1172. ULONG SizeOfPartialDescr;
  1173. ULONG Offset;
  1174. ULONG CountVal;
  1175. ULONG64 Val1;
  1176. ULONG Val2, Val3, TypeVal;
  1177. ULONG j;
  1178. SizeOfFullDescr = GetTypeSize(CFRD_NAME);
  1179. SizeOfPartialDescr = GetTypeSize(CPRD_NAME);
  1180. if (GetFieldOffset(CRL_NAME, "List", &Offset) != 0)
  1181. {
  1182. dprintf("Can't get offset of List in CM_RESOURCE_LIST\n");
  1183. return;
  1184. }
  1185. FullResourceDescrAddr = ResourceListAddr + Offset;
  1186. GetFieldValue(FullResourceDescrAddr, CFRD_NAME, "PartialResourceList.Count", CountVal);
  1187. if (GetFieldOffset(CFRD_NAME, "PartialResourceList.PartialDescriptors", &Offset) != 0)
  1188. {
  1189. dprintf("Can't get offset of PartialResourceList.PartialDescriptors in %s\n",
  1190. CFRD_NAME);
  1191. return;
  1192. }
  1193. PartialResourceDescrAddr = FullResourceDescrAddr + Offset;
  1194. for (j = 0; j < CountVal; j++)
  1195. {
  1196. if (CheckControlC())
  1197. {
  1198. break;
  1199. }
  1200. GetFieldValue(PartialResourceDescrAddr, CPRD_NAME, "Type", TypeVal);
  1201. switch (TypeVal)
  1202. {
  1203. case CmResourceTypePort:
  1204. GetFieldValue(PartialResourceDescrAddr, CPRD_NAME, "u.Port.Start", Val1);
  1205. GetFieldValue(PartialResourceDescrAddr, CPRD_NAME, "u.Port.Length", Val2);
  1206. dprintf(" IO Port: %p, Length: %lx\n", Val1, Val2);
  1207. break;
  1208. case CmResourceTypeMemory:
  1209. GetFieldValue(PartialResourceDescrAddr, CPRD_NAME, "u.Memory.Start", Val1);
  1210. GetFieldValue(PartialResourceDescrAddr, CPRD_NAME, "u.Memory.Length", Val2);
  1211. dprintf(" Memory: %p, Length: %lx\n", Val1, Val2);
  1212. break;
  1213. case CmResourceTypeInterrupt:
  1214. GetFieldValue(PartialResourceDescrAddr, CPRD_NAME, "u.Interrupt.Level", Val3);
  1215. GetFieldValue(PartialResourceDescrAddr, CPRD_NAME, "u.Interrupt.Vector", Val2);
  1216. dprintf(" Interrupt Level: %lx, Vector: %lx\n", Val3, Val2);
  1217. break;
  1218. case CmResourceTypeDma:
  1219. GetFieldValue(PartialResourceDescrAddr, CPRD_NAME, "u.Dma.Channel", Val3);
  1220. dprintf(" DMA Channel: %lx\n", Val3);
  1221. break;
  1222. default:
  1223. break;
  1224. }
  1225. PartialResourceDescrAddr += SizeOfPartialDescr;
  1226. }
  1227. }
  1228. DECLARE_API( miniport )
  1229. {
  1230. ULONG64 pMiniport;
  1231. if (!args || !*args)
  1232. {
  1233. dprintf("Usage: miniport <pointer to miniport block>\n");
  1234. return;
  1235. }
  1236. pMiniport = (ULONG64)GetExpression(args);
  1237. dprintf(" Miniport %p : ", pMiniport);
  1238. PrintMiniportName(pMiniport);
  1239. dprintf("\n");
  1240. PrintMiniportDetails(pMiniport);
  1241. }
  1242. DECLARE_API( mopen )
  1243. {
  1244. ULONG64 OpenAddr;
  1245. ULONG64 ProtocolAddr;
  1246. ULONG64 MiniportAddr;
  1247. ULONG64 AfAddr;
  1248. ULONG64 Val;
  1249. ULONG64 VcHeadAddr;
  1250. ULONG64 VcPtrAddr;
  1251. ULONG ClientLinkOffset;
  1252. ULONG CallMgrLinkOffset;
  1253. ULONG Offset;
  1254. ULONG Flags;
  1255. ULONG VcCount;
  1256. UINT i, j;
  1257. BOOLEAN bPrintingActiveVcs;
  1258. BOOLEAN fCoOpen = FALSE;
  1259. BOOLEAN fClientOpen;
  1260. if (!args || !*args)
  1261. {
  1262. dprintf("Usage: mopen <pointer to miniport open block>\n");
  1263. return;
  1264. }
  1265. OpenAddr = GetExpression(args);
  1266. if (OpenAddr == 0)
  1267. {
  1268. dprintf("Invalid open block address\n");
  1269. return;
  1270. }
  1271. dprintf(" Miniport Open Block %p\n", OpenAddr);
  1272. //
  1273. // Get and print the protocol's name
  1274. //
  1275. GetFieldValue(OpenAddr, NDIS_COMMON_OPEN_BLOCK_NAME, "ProtocolHandle", ProtocolAddr);
  1276. dprintf(" Protocol %p = ", ProtocolAddr);
  1277. if (GetFieldOffset(NDIS_PROTOCOL_BLOCK_NAME, "ProtocolCharacteristics.Name", &Offset) != 0)
  1278. {
  1279. dprintf("Cant get offset of Name in Protocol block!");
  1280. }
  1281. else
  1282. {
  1283. PrintName(ProtocolAddr + Offset);
  1284. }
  1285. GetFieldValue(OpenAddr, NDIS_COMMON_OPEN_BLOCK_NAME, "ProtocolBindingContext", Val);
  1286. dprintf(", ProtocolContext %p\n", Val);
  1287. //
  1288. // Get and print the miniport's name
  1289. //
  1290. GetFieldValue(OpenAddr, NDIS_COMMON_OPEN_BLOCK_NAME, "MiniportHandle", MiniportAddr);
  1291. dprintf(" Miniport %p = ", MiniportAddr);
  1292. PrintMiniportName(MiniportAddr);
  1293. dprintf("\n");
  1294. GetFieldValue(OpenAddr, NDIS_COMMON_OPEN_BLOCK_NAME, "MiniportAdapterContext", Val);
  1295. dprintf(" MiniportAdapterContext: %p\n", Val);
  1296. GetFieldValue(OpenAddr, NDIS_COMMON_OPEN_BLOCK_NAME, "Flags", Val);
  1297. dprintf(" Flags : %08x\n", Val);
  1298. j = 0;
  1299. for (i = 0; i < sizeof(DbgOpenFlags)/sizeof(DBG_OPEN_FLAGS ); i++)
  1300. {
  1301. if (Val & DbgOpenFlags[i].Val)
  1302. {
  1303. if (j == 0)
  1304. {
  1305. dprintf(" ");
  1306. }
  1307. dprintf("%s", DbgOpenFlags[i].Name);
  1308. j++;
  1309. if (j != MAX_FLAGS_PER_LINE)
  1310. {
  1311. dprintf(", ");
  1312. }
  1313. else
  1314. {
  1315. dprintf("\n");
  1316. j = 0;
  1317. }
  1318. }
  1319. }
  1320. if (j != 0)
  1321. {
  1322. dprintf("\n");
  1323. }
  1324. fClientOpen = (Val & fMINIPORT_OPEN_CLIENT) ? TRUE : FALSE;
  1325. GetFieldValue(OpenAddr, NDIS_COMMON_OPEN_BLOCK_NAME, "References", (ULONG)Val);
  1326. dprintf(" References : %d\n", (ULONG)Val);
  1327. //
  1328. // Check if this is a CONDIS miniport. If not, we are done.
  1329. //
  1330. GetFieldValue(MiniportAddr, NDIS_MINIPORT_BLOCK_NAME, "Flags", Flags);
  1331. fCoOpen = ((Flags & fMINIPORT_IS_CO) != 0);
  1332. if (!fCoOpen)
  1333. {
  1334. return;
  1335. }
  1336. //
  1337. // If there are open AFs on this Open, display them.
  1338. //
  1339. GetFieldValue(OpenAddr, NDIS_OPEN_BLOCK_NAME, "NextAf", AfAddr);
  1340. while (AfAddr != 0)
  1341. {
  1342. ULONG Flags;
  1343. ULONG Refs;
  1344. ULONG64 AfOpenAddr;
  1345. ULONG64 ProtocolAddr;
  1346. ULONG Offset;
  1347. if (CheckControlC())
  1348. {
  1349. break;
  1350. }
  1351. GetFieldValue(AfAddr, NDIS_CO_AF_BLOCK_NAME, "Flags", Flags);
  1352. GetFieldValue(AfAddr, NDIS_CO_AF_BLOCK_NAME, "References", Refs);
  1353. dprintf(" Af Block %p, Flags %08x, References %d\n", AfAddr, Flags, Refs);
  1354. //
  1355. // Client open values:
  1356. //
  1357. GetFieldValue(AfAddr, NDIS_CO_AF_BLOCK_NAME, "ClientOpen", AfOpenAddr);
  1358. dprintf(" Client Open %p : ", AfOpenAddr);
  1359. GetFieldValue(AfOpenAddr, NDIS_COMMON_OPEN_BLOCK_NAME, "ProtocolHandle", ProtocolAddr);
  1360. if (GetFieldOffset(NDIS_PROTOCOL_BLOCK_NAME, "ProtocolCharacteristics.Name", &Offset) != 0)
  1361. {
  1362. dprintf("Cant get offset of Name in Protocol block!");
  1363. }
  1364. else
  1365. {
  1366. PrintName(ProtocolAddr + Offset);
  1367. }
  1368. GetFieldValue(AfAddr, NDIS_CO_AF_BLOCK_NAME, "ClientContext", Val);
  1369. dprintf(", CL AFContext %p\n", Val);
  1370. //
  1371. // Call Mgr open values:
  1372. //
  1373. GetFieldValue(AfAddr, NDIS_CO_AF_BLOCK_NAME, "CallMgrOpen", AfOpenAddr);
  1374. dprintf(" CallMgr Open %p : ", AfOpenAddr);
  1375. GetFieldValue(AfOpenAddr, NDIS_COMMON_OPEN_BLOCK_NAME, "ProtocolHandle", ProtocolAddr);
  1376. PrintName(ProtocolAddr + Offset);
  1377. GetFieldValue(AfAddr, NDIS_CO_AF_BLOCK_NAME, "ClientContext", Val);
  1378. dprintf(", CM AFContext %p\n", Val);
  1379. GetFieldValue(AfAddr, NDIS_CO_AF_BLOCK_NAME, "NextAf", AfAddr);
  1380. }
  1381. //
  1382. // If there are any VCs in the active VC list, display them.
  1383. //
  1384. //
  1385. // First, get some offsets.
  1386. //
  1387. if (GetFieldOffset(NDIS_CO_VC_PTR_BLOCK_NAME, "ClientLink", &ClientLinkOffset) != 0)
  1388. {
  1389. dprintf("Can't get offset of ClientLink in NDIS_CO_VC_PTR_BLOCK!\n");
  1390. return;
  1391. }
  1392. if (GetFieldOffset(NDIS_CO_VC_PTR_BLOCK_NAME, "CallMgrLink", &CallMgrLinkOffset) != 0)
  1393. {
  1394. dprintf("Can't get offset of CallMgrLink in NDIS_CO_VC_PTR_BLOCK!\n");
  1395. return;
  1396. }
  1397. if (GetFieldOffset(NDIS_OPEN_BLOCK_NAME, "ActiveVcHead", &Offset) != 0)
  1398. {
  1399. dprintf("Can't get offset of ActiveVcHead in NDIS_OPEN_BLOCK!\n");
  1400. return;
  1401. }
  1402. VcHeadAddr = OpenAddr + Offset;
  1403. GetFieldValue(OpenAddr, NDIS_OPEN_BLOCK_NAME, "ActiveVcHead.Flink", VcPtrAddr);
  1404. if (VcPtrAddr != VcHeadAddr)
  1405. {
  1406. dprintf("\n Active VC list:\n");
  1407. }
  1408. bPrintingActiveVcs = TRUE;
  1409. Again:
  1410. VcCount = 0;
  1411. while (VcPtrAddr != VcHeadAddr)
  1412. {
  1413. if (CheckControlC())
  1414. {
  1415. break;
  1416. }
  1417. if (VcCount++ == 2000)
  1418. {
  1419. // something wrong?
  1420. dprintf("Too many VCs (%d), bailing out!\n", VcCount);
  1421. break;
  1422. }
  1423. if (bPrintingActiveVcs)
  1424. {
  1425. VcPtrAddr -= ClientLinkOffset;
  1426. }
  1427. else
  1428. {
  1429. if (fClientOpen)
  1430. {
  1431. VcPtrAddr -= ClientLinkOffset;
  1432. }
  1433. else
  1434. {
  1435. VcPtrAddr -= CallMgrLinkOffset;
  1436. }
  1437. }
  1438. PrintVcPtrBlock(VcPtrAddr);
  1439. if (bPrintingActiveVcs)
  1440. {
  1441. GetFieldValue(VcPtrAddr, NDIS_CO_VC_PTR_BLOCK_NAME, "ClientLink.Flink", VcPtrAddr);
  1442. }
  1443. else
  1444. {
  1445. if (fClientOpen)
  1446. GetFieldValue(VcPtrAddr, NDIS_CO_VC_PTR_BLOCK_NAME, "ClientLink.Flink", VcPtrAddr);
  1447. else
  1448. GetFieldValue(VcPtrAddr, NDIS_CO_VC_PTR_BLOCK_NAME, "CallMgrLink.Flink", VcPtrAddr);
  1449. }
  1450. }
  1451. if (bPrintingActiveVcs)
  1452. {
  1453. bPrintingActiveVcs = FALSE;
  1454. //
  1455. // If there are any VCs in the inactive VC list, display them.
  1456. //
  1457. if (GetFieldOffset(NDIS_OPEN_BLOCK_NAME, "InactiveVcHead", &Offset) != 0)
  1458. {
  1459. dprintf("Can't get offset of InActiveVcHead in NDIS_OPEN_BLOCK!\n");
  1460. return;
  1461. }
  1462. VcHeadAddr = OpenAddr + Offset;
  1463. GetFieldValue(OpenAddr, NDIS_OPEN_BLOCK_NAME, "InactiveVcHead.Flink", VcPtrAddr);
  1464. if (VcPtrAddr != VcHeadAddr)
  1465. {
  1466. dprintf("\n Inactive VC list:\n");
  1467. goto Again;
  1468. }
  1469. }
  1470. return;
  1471. }
  1472. DECLARE_API( vc )
  1473. {
  1474. ULONG64 VcPtrAddr;
  1475. ULONG64 ClientOpen, CallMgrOpen, AfBlock, Miniport;
  1476. if (!args || !*args)
  1477. {
  1478. dprintf("Usage: vc <pointer to VC pointer block>\n");
  1479. return;
  1480. }
  1481. VcPtrAddr = GetExpression(args);
  1482. PrintVcPtrBlock(VcPtrAddr);
  1483. //
  1484. // For some reason, InitTypeRead(NDIS_CO_VC_PTR_BLOCK_NAME) followed
  1485. // by ReadField() didn't work - we get all 0's.
  1486. //
  1487. GetFieldValue(VcPtrAddr, NDIS_CO_VC_PTR_BLOCK_NAME, "ClientOpen", ClientOpen);
  1488. GetFieldValue(VcPtrAddr, NDIS_CO_VC_PTR_BLOCK_NAME, "CallMgrOpen", CallMgrOpen);
  1489. GetFieldValue(VcPtrAddr, NDIS_CO_VC_PTR_BLOCK_NAME, "AfBlock", AfBlock);
  1490. GetFieldValue(VcPtrAddr, NDIS_CO_VC_PTR_BLOCK_NAME, "Miniport", Miniport);
  1491. dprintf(" ClientOpen %p CallMgrOpen %p AfBlock %p Miniport %p\n",
  1492. ClientOpen,
  1493. CallMgrOpen,
  1494. AfBlock,
  1495. Miniport);
  1496. }
  1497. VOID
  1498. PrintProtocolOpenQueue(
  1499. ULONG64 ProtocolAddr)
  1500. {
  1501. ULONG64 OpenAddr;
  1502. ULONG64 MiniportHandle;
  1503. ULONG64 MiniportAddr;
  1504. ULONG64 Val;
  1505. GetFieldValue(ProtocolAddr, NDIS_PROTOCOL_BLOCK_NAME, "OpenQueue", OpenAddr);
  1506. while (OpenAddr != 0)
  1507. {
  1508. GetFieldValue(OpenAddr, NDIS_COMMON_OPEN_BLOCK_NAME, "MiniportHandle", MiniportAddr);
  1509. GetFieldValue(OpenAddr, NDIS_COMMON_OPEN_BLOCK_NAME, "ProtocolNextOpen", Val);
  1510. dprintf(" Open %p - ", OpenAddr);
  1511. dprintf("Miniport: %p ", MiniportAddr);
  1512. PrintMiniportName(MiniportAddr);
  1513. dprintf("\n");
  1514. OpenAddr = Val;
  1515. }
  1516. dprintf("\n");
  1517. }
  1518. VOID
  1519. PrintVcPtrBlock(
  1520. IN ULONG64 VcPtrAddr)
  1521. {
  1522. ULONG64 VcBlockAddr;
  1523. ULONG64 ClientContext, CallMgrContext, MiniportContext;
  1524. ULONG Flags;
  1525. ULONG VcFlags;
  1526. INT i, j;
  1527. GetFieldValue(VcPtrAddr, NDIS_CO_VC_PTR_BLOCK_NAME, "CallFlags", Flags);
  1528. GetFieldValue(VcPtrAddr, NDIS_CO_VC_PTR_BLOCK_NAME, "ClientContext", ClientContext);
  1529. GetFieldValue(VcPtrAddr, NDIS_CO_VC_PTR_BLOCK_NAME, "CallMgrContext", CallMgrContext);
  1530. GetFieldValue(VcPtrAddr, NDIS_CO_VC_PTR_BLOCK_NAME, "MiniportContext", MiniportContext);
  1531. dprintf(" VcPtr %p, Contexts: Cl %p, CM %p, MP %p, CallFlags %08x\n",
  1532. VcPtrAddr,
  1533. ClientContext,
  1534. CallMgrContext,
  1535. MiniportContext,
  1536. Flags);
  1537. j = 0;
  1538. for (i = 0; i < sizeof(DbgVcPtrFlags)/sizeof(DBG_VC_FLAGS); i++)
  1539. {
  1540. if (Flags & DbgVcPtrFlags[i].Val)
  1541. {
  1542. if (j == 0)
  1543. {
  1544. dprintf(" ");
  1545. }
  1546. dprintf("%s", DbgVcPtrFlags[i].Name);
  1547. j++;
  1548. if (j != MAX_FLAGS_PER_LINE)
  1549. {
  1550. dprintf(", ");
  1551. }
  1552. else
  1553. {
  1554. dprintf("\n");
  1555. j = 0;
  1556. }
  1557. }
  1558. }
  1559. if (j != 0)
  1560. {
  1561. dprintf("\n");
  1562. }
  1563. GetFieldValue(VcPtrAddr, NDIS_CO_VC_PTR_BLOCK_NAME, "VcBlock", VcBlockAddr);
  1564. if (VcBlockAddr != 0)
  1565. {
  1566. GetFieldValue(VcBlockAddr, NDIS_CO_VC_BLOCK_NAME, "Flags", VcFlags);
  1567. dprintf(" VcBlock %p, Flags %08x\n", VcBlockAddr, VcFlags);
  1568. j = 0;
  1569. for (i = 0; i < sizeof(DbgVcFlags)/sizeof(DBG_VC_FLAGS); i++)
  1570. {
  1571. if (VcFlags & DbgVcFlags[i].Val)
  1572. {
  1573. if (j == 0)
  1574. {
  1575. dprintf(" ");
  1576. }
  1577. dprintf("%s", DbgVcFlags[i].Name);
  1578. j++;
  1579. if (j != MAX_FLAGS_PER_LINE)
  1580. {
  1581. dprintf(", ");
  1582. }
  1583. else
  1584. {
  1585. dprintf("\n");
  1586. j = 0;
  1587. }
  1588. }
  1589. }
  1590. if (j != 0)
  1591. {
  1592. dprintf("\n");
  1593. }
  1594. }
  1595. }
  1596. DECLARE_API( protocols )
  1597. {
  1598. ULONG64 ProtocolListAddr;
  1599. ULONG64 ProtocolAddr;
  1600. ULONG Offset;
  1601. ProtocolListAddr = GetExpression("ndis!ndisProtocolList");
  1602. ProtocolAddr = GetPointerFromAddress(ProtocolListAddr);
  1603. while (ProtocolAddr != 0)
  1604. {
  1605. if (CheckControlC())
  1606. {
  1607. break;
  1608. }
  1609. dprintf(" Protocol %p: ", ProtocolAddr);
  1610. if (GetFieldOffset(NDIS_PROTOCOL_BLOCK_NAME, "ProtocolCharacteristics.Name", &Offset) != 0)
  1611. {
  1612. dprintf("Cant get offset of Name in Protocol block!");
  1613. }
  1614. else
  1615. {
  1616. PrintName(ProtocolAddr + Offset);
  1617. }
  1618. dprintf("\n");
  1619. PrintProtocolOpenQueue(ProtocolAddr);
  1620. GetFieldValue(ProtocolAddr, NDIS_PROTOCOL_BLOCK_NAME, "NextProtocol", ProtocolAddr);
  1621. }
  1622. }
  1623. VOID
  1624. PrintNdisBuffer(
  1625. ULONG64 BufferAddr
  1626. )
  1627. {
  1628. ULONG64 Val1;
  1629. ULONG64 Val2;
  1630. dprintf("NDIS_BUFFER at %p\n", BufferAddr);
  1631. GetFieldValue(BufferAddr, NDIS_BUFFER_NAME, "Next", Val1);
  1632. GetFieldValue(BufferAddr, NDIS_BUFFER_NAME, "Size", Val2);
  1633. dprintf(" Next %p\n Size %x\n", Val1, (ULONG)Val2);
  1634. GetFieldValue(BufferAddr, NDIS_BUFFER_NAME, "MdlFlags", Val1);
  1635. GetFieldValue(BufferAddr, NDIS_BUFFER_NAME, "Process", Val2);
  1636. dprintf(" MdlFlags %x\n Process %p\n", (ULONG)Val1, Val2);
  1637. GetFieldValue(BufferAddr, NDIS_BUFFER_NAME, "MappedSystemVa", Val1);
  1638. GetFieldValue(BufferAddr, NDIS_BUFFER_NAME, "StartVa", Val2);
  1639. dprintf(" MappedSystemVa %p\n Start VA %p\n", Val1, Val2);
  1640. GetFieldValue(BufferAddr, NDIS_BUFFER_NAME, "ByteCount", Val1);
  1641. GetFieldValue(BufferAddr, NDIS_BUFFER_NAME, "ByteOffset", Val2);
  1642. dprintf(" ByteCount %x\n ByteOffset %x\n", (ULONG)Val1, (ULONG)Val2);
  1643. }
  1644. // Verbosity for packet display:
  1645. // 1. Print Packet.Private
  1646. // 2. Print NdisPacketExtension
  1647. // 3. Print NDIS_PACKET_REFERENCE
  1648. // 4. Print NDIS_BUFFER_LIST
  1649. //
  1650. DECLARE_API( pkt )
  1651. {
  1652. ULONG64 PacketAddr;
  1653. INT Verbosity;
  1654. CHAR argbuf[ MAX_PATH ];
  1655. CHAR arglist[10][MAX_PATH];
  1656. CHAR *str;
  1657. INT index=0;
  1658. CHAR *p;
  1659. if (!args || !*args)
  1660. {
  1661. dprintf("Usage: Packet <pointer to packet> <verbosity>\n");
  1662. return;
  1663. }
  1664. PacketAddr = GetExpression(args);
  1665. strcpy(argbuf,args);
  1666. for (p = mystrtok( argbuf, " \t,;" );
  1667. p && *p;
  1668. p = mystrtok(NULL, " \t,;"))
  1669. {
  1670. strcpy(&arglist[index++][0],p);
  1671. }
  1672. Verbosity = atoi(&arglist[1][0]);
  1673. if (index>2 || Verbosity>4)
  1674. {
  1675. dprintf("Usage: pkt <pointer to packet> <verbosity>\n");
  1676. dprintf("1-Packet Private, 2-Packet Extension\n");
  1677. dprintf("3-Ndis Reference, 4-Buffer List\n");
  1678. return;
  1679. }
  1680. dprintf("NDIS_PACKET at %p\n", PacketAddr);
  1681. switch(Verbosity)
  1682. {
  1683. case 4:
  1684. PrintNdisBufferList(PacketAddr);
  1685. // FALLTHRU
  1686. case 3:
  1687. PrintNdisReserved(PacketAddr);
  1688. // FALLTHRU
  1689. case 2:
  1690. PrintNdisPacketExtension(PacketAddr);
  1691. // FALLTHRU
  1692. case 1:
  1693. default:
  1694. PrintNdisPacketPrivate(PacketAddr);
  1695. break;
  1696. }
  1697. }
  1698. VOID
  1699. PrintPacketPrivateFlags(
  1700. ULONG64 PacketAddr
  1701. )
  1702. {
  1703. ULONG NdisPacketFlags;
  1704. ULONG i;
  1705. ULONG j;
  1706. ULONG Flags;
  1707. #define MAX_FLAGS_PER_LINE 3
  1708. GetFieldValue(PacketAddr, NDIS_PACKET_NAME, "Private.Flags", Flags);
  1709. //
  1710. // Prints Flags and NdisPacketFlags
  1711. //
  1712. dprintf("\n ");
  1713. dprintf(" Private.Flags : %08x\n", Flags);
  1714. j = 0;
  1715. for (i = 0; i < sizeof(DbgPacketFlags)/sizeof(DBG_PACKET_FLAGS); i++)
  1716. {
  1717. if (Flags & DbgPacketFlags[i].Val)
  1718. {
  1719. if (j == 0)
  1720. {
  1721. dprintf(" ");
  1722. }
  1723. dprintf("%s", DbgPacketFlags[i].Name);
  1724. j++;
  1725. if (j != MAX_FLAGS_PER_LINE)
  1726. {
  1727. dprintf(", ");
  1728. }
  1729. else
  1730. {
  1731. dprintf("\n");
  1732. j = 0;
  1733. }
  1734. }
  1735. }
  1736. if (j != 0)
  1737. {
  1738. dprintf("\n");
  1739. }
  1740. GetFieldValue(PacketAddr, NDIS_PACKET_NAME, "Private.NdisPacketFlags", NdisPacketFlags);
  1741. dprintf(" ");
  1742. dprintf(" Private.NdisPacketFlags: %01x\n", NdisPacketFlags);
  1743. j = 0;
  1744. for (i = 0; i < sizeof(DbgNdisPacketFlags)/sizeof(DBG_PACKET_FLAGS); i++)
  1745. {
  1746. if (NdisPacketFlags & DbgNdisPacketFlags[i].Val)
  1747. {
  1748. if (j == 0)
  1749. {
  1750. dprintf(" ");
  1751. }
  1752. dprintf("%s", DbgNdisPacketFlags[i].Name);
  1753. j++;
  1754. if (j != MAX_FLAGS_PER_LINE)
  1755. {
  1756. dprintf(", ");
  1757. }
  1758. else
  1759. {
  1760. dprintf("\n");
  1761. j = 0;
  1762. }
  1763. }
  1764. }
  1765. if (j != 0)
  1766. {
  1767. dprintf("\n");
  1768. }
  1769. }
  1770. VOID
  1771. PrintNdisPacketPrivate(
  1772. ULONG64 PacketAddr
  1773. )
  1774. {
  1775. ULONG64 Val1, Val2;
  1776. ULONG64 Addr1, Addr2;
  1777. dprintf("\nPacket.Private\n");
  1778. InitTypeRead(PacketAddr, NDIS_PACKET);
  1779. Val1 = ReadField(Private.PhysicalCount);
  1780. Val2 = ReadField(Private.TotalLength);
  1781. dprintf(" PhysicalCount %.8d Total Length %.8x\n",
  1782. (ULONG)Val1, (ULONG)Val2);
  1783. Addr1 = ReadField(Private.Head);
  1784. Addr2 = ReadField(Private.Tail);
  1785. dprintf(" Head %p Tail %p\n", Addr1, Addr2);
  1786. Addr1 = ReadField(Private.Pool);
  1787. Val1 = (UINT)ReadField(Private.Count);
  1788. dprintf(" Pool %p Count %p\n", Addr1, Val1);
  1789. Val1 = ReadField(Private.Flags);
  1790. Val2 = (BOOLEAN)ReadField(Private.ValidCounts);
  1791. dprintf(" Flags %08x ValidCounts %.2x\n", (ULONG)Val1, (BOOLEAN)Val2);
  1792. Val1 = (UCHAR)ReadField(Private.NdisPacketFlags);
  1793. Val2 = (USHORT)ReadField(Private.NdisPacketOobOffset);
  1794. dprintf(" NdisPacketFlags %08x NdisPacketOobOffset %.4x\n", (UCHAR)Val1, (USHORT)Val2);
  1795. PrintPacketPrivateFlags (PacketAddr);
  1796. }
  1797. VOID
  1798. PrintNdisPacketExtension(
  1799. ULONG64 PacketAddr
  1800. )
  1801. {
  1802. ULONG64 PacketExtensionAddr;
  1803. ULONG PtrSize;
  1804. UINT i;
  1805. USHORT OobOffset;
  1806. GetFieldValue(PacketAddr, NDIS_PACKET_NAME, "Private.NdisPacketOobOffset", OobOffset);
  1807. PacketExtensionAddr = PacketAddr + OobOffset + GetTypeSize("NDIS_PACKET_OOB_DATA");
  1808. PtrSize = GetTypeSize("PVOID");
  1809. for (i = 0; i < MaxPerPacketInfo; i++)
  1810. {
  1811. dprintf(" %d. %s = %p\n",
  1812. i, DbgPacketInfoIdTypes[i].Name, GetPointerFromAddress(PacketExtensionAddr));
  1813. PacketExtensionAddr += PtrSize;
  1814. }
  1815. }
  1816. VOID
  1817. PrintNdisBufferList(
  1818. ULONG64 PacketAddr
  1819. )
  1820. {
  1821. ULONG64 BufAddr;
  1822. ULONG64 TailAddr;
  1823. GetFieldValue(PacketAddr, NDIS_PACKET_NAME, "Private.Head", BufAddr);
  1824. GetFieldValue(PacketAddr, NDIS_PACKET_NAME, "Private.Tail", TailAddr);
  1825. while (BufAddr != 0)
  1826. {
  1827. if (CheckControlC())
  1828. {
  1829. break;
  1830. }
  1831. PrintNdisBuffer(BufAddr);
  1832. if (BufAddr == TailAddr)
  1833. {
  1834. break;
  1835. }
  1836. GetFieldValue(BufAddr, NDIS_BUFFER_NAME, "Next", BufAddr);
  1837. }
  1838. }
  1839. VOID
  1840. PrintNdisReserved(
  1841. ULONG64 PacketAddr
  1842. )
  1843. {
  1844. ULONG Offset;
  1845. ULONG Size;
  1846. ULONG64 EntryAddr;
  1847. ULONG64 EntryVal;
  1848. ULONG NumEntries;
  1849. ULONG EntrySize;
  1850. ULONG i;
  1851. if (GetFieldOffsetAndSize(NDIS_PACKET_NAME, "MacReserved", &Offset, &Size) != 0)
  1852. {
  1853. dprintf("Can't get offset of MacReserved in %s!\n", NDIS_PACKET_NAME);
  1854. return;
  1855. }
  1856. EntrySize = GetTypeSize("PVOID");
  1857. NumEntries = Size / EntrySize;
  1858. EntryAddr = PacketAddr + Offset;
  1859. dprintf("MacReserved[]:");
  1860. for (i = 0; i < NumEntries; i++)
  1861. {
  1862. EntryVal = GetPointerFromAddress(EntryAddr);
  1863. dprintf(" %p ", EntryVal);
  1864. EntryAddr += EntrySize;
  1865. }
  1866. dprintf("\n");
  1867. }
  1868. VOID
  1869. PrintProtocolDetails(
  1870. ULONG64 ProtocolAddr
  1871. )
  1872. {
  1873. ULONG64 NameAddr;
  1874. ULONG64 ProtocolCharsAddr;
  1875. ULONG64 Val1, Val2;
  1876. ULONG Val;
  1877. ULONG Offset;
  1878. GetFieldValue(ProtocolAddr, NDIS_PROTOCOL_BLOCK_NAME, "BindDeviceName", NameAddr);
  1879. if (NameAddr != 0)
  1880. {
  1881. dprintf(" BindDeviceName is ");
  1882. PrintName(NameAddr);
  1883. dprintf("\n");
  1884. }
  1885. GetFieldValue(ProtocolAddr, NDIS_PROTOCOL_BLOCK_NAME, "RootDeviceName", NameAddr);
  1886. if (NameAddr != 0)
  1887. {
  1888. dprintf(" RootDeviceName is ");
  1889. PrintName(NameAddr);
  1890. dprintf("\n");
  1891. }
  1892. GetFieldValue(ProtocolAddr, NDIS_PROTOCOL_BLOCK_NAME, "Ref.ReferenceCount", Val);
  1893. dprintf(" RefCount %d\n", Val);
  1894. dprintf("\n");
  1895. //
  1896. // Walk the Open Block Queue
  1897. //
  1898. PrintProtocolOpenQueue(ProtocolAddr);
  1899. if (GetFieldOffset(NDIS_PROTOCOL_BLOCK_NAME, "ProtocolCharacteristics", &Offset) != 0)
  1900. {
  1901. dprintf("Can't get offset of ProtocolCharacteristics in %s\n",
  1902. NDIS_PROTOCOL_BLOCK_NAME);
  1903. return;
  1904. }
  1905. ProtocolCharsAddr = ProtocolAddr + Offset;
  1906. //
  1907. // Addresses of handlers.
  1908. //
  1909. GetFieldValue(ProtocolCharsAddr, NDIS_PROTOCOL_CHARACTERISTICS_NAME,
  1910. "BindAdapterHandler", Val1);
  1911. GetFieldValue(ProtocolCharsAddr, NDIS_PROTOCOL_CHARACTERISTICS_NAME,
  1912. "UnbindAdapterHandler", Val2);
  1913. dprintf(" BindAdapterHandler %p, UnbindAdapterHandler %p\n", Val1, Val2);
  1914. GetFieldValue(ProtocolCharsAddr, NDIS_PROTOCOL_CHARACTERISTICS_NAME,
  1915. "PnPEventHandler", Val1);
  1916. GetFieldValue(ProtocolCharsAddr, NDIS_PROTOCOL_CHARACTERISTICS_NAME,
  1917. "UnloadHandler", Val2);
  1918. dprintf(" PnPEventHandler %p, UnloadHandler %p\n", Val1, Val2);
  1919. GetFieldValue(ProtocolCharsAddr, NDIS_PROTOCOL_CHARACTERISTICS_NAME,
  1920. "OpenAdapterCompleteHandler", Val1);
  1921. GetFieldValue(ProtocolCharsAddr, NDIS_PROTOCOL_CHARACTERISTICS_NAME,
  1922. "CloseAdapterCompleteHandler", Val2);
  1923. dprintf(" OpenAdapterComplete %p, CloseAdapterComplete %p\n", Val1, Val2);
  1924. GetFieldValue(ProtocolCharsAddr, NDIS_PROTOCOL_CHARACTERISTICS_NAME,
  1925. "SendCompleteHandler", Val1);
  1926. GetFieldValue(ProtocolCharsAddr, NDIS_PROTOCOL_CHARACTERISTICS_NAME,
  1927. "TransferDataCompleteHandler", Val2);
  1928. dprintf(" SendCompleteHandler %p, TransferDataComplete %p\n", Val1, Val2);
  1929. GetFieldValue(ProtocolCharsAddr, NDIS_PROTOCOL_CHARACTERISTICS_NAME,
  1930. "ReceiveHandler", Val1);
  1931. GetFieldValue(ProtocolCharsAddr, NDIS_PROTOCOL_CHARACTERISTICS_NAME,
  1932. "ReceivePacketHandler", Val2);
  1933. dprintf(" ReceiveHandler %p, ReceivePacketHandler %p\n", Val1, Val2);
  1934. GetFieldValue(ProtocolCharsAddr, NDIS_PROTOCOL_CHARACTERISTICS_NAME,
  1935. "ReceiveCompleteHandler", Val1);
  1936. GetFieldValue(ProtocolCharsAddr, NDIS_PROTOCOL_CHARACTERISTICS_NAME,
  1937. "StatusHandler", Val2);
  1938. dprintf(" ReceiveComplete %p, StatusHandler %p\n", Val1, Val2);
  1939. GetFieldValue(ProtocolCharsAddr, NDIS_PROTOCOL_CHARACTERISTICS_NAME,
  1940. "StatusCompleteHandler", Val1);
  1941. dprintf(" StatusComplete %p\n", Val1);
  1942. GetFieldValue(ProtocolCharsAddr, NDIS_PROTOCOL_CHARACTERISTICS_NAME,
  1943. "AssociatedMiniDriver", Val1);
  1944. dprintf(" AssociatedMiniDriver %p\n", Val1);
  1945. {
  1946. ULONG i;
  1947. ULONG j;
  1948. ULONG Flags;
  1949. #define MAX_FLAGS_PER_LINE 3
  1950. dprintf("\n ");
  1951. GetFieldValue(ProtocolCharsAddr, NDIS_PROTOCOL_CHARACTERISTICS_NAME,
  1952. "Flags", Val1);
  1953. Flags = (ULONG)Val1;
  1954. dprintf(" Flags : %08x\n", Flags);
  1955. j = 0;
  1956. for (i = 0; i < sizeof(DbgProtocolFlags)/sizeof(DBG_PROTOCOL_FLAGS ); i++)
  1957. {
  1958. if (Flags & DbgProtocolFlags[i].Val)
  1959. {
  1960. if (j == 0)
  1961. {
  1962. dprintf(" ");
  1963. }
  1964. dprintf("%s", DbgProtocolFlags[i].Name);
  1965. j++;
  1966. if (j != MAX_FLAGS_PER_LINE)
  1967. {
  1968. dprintf(", ");
  1969. }
  1970. else
  1971. {
  1972. dprintf("\n");
  1973. j = 0;
  1974. }
  1975. }
  1976. }
  1977. if (j != 0)
  1978. {
  1979. dprintf("\n");
  1980. }
  1981. }
  1982. }
  1983. DECLARE_API( protocol )
  1984. {
  1985. ULONG64 ProtocolAddr;
  1986. ULONG Offset;
  1987. //
  1988. // Verify if any args are present
  1989. //
  1990. if (!args || !*args)
  1991. {
  1992. dprintf("Usage: protocol <pointer to protocol block>\n");
  1993. return;
  1994. }
  1995. ProtocolAddr = GetExpression(args);
  1996. dprintf(" Protocol %p : ", ProtocolAddr);
  1997. if (GetFieldOffset(NDIS_PROTOCOL_BLOCK_NAME, "ProtocolCharacteristics.Name", &Offset) != 0)
  1998. {
  1999. dprintf("Can't get offset of Name in Protocol block!");
  2000. }
  2001. else
  2002. {
  2003. PrintName(ProtocolAddr + Offset);
  2004. }
  2005. dprintf("\n");
  2006. PrintProtocolDetails(ProtocolAddr);
  2007. }
  2008. /**
  2009. Routine to get offset and size of a "Field" of "Type" on a debugee machine. This uses
  2010. Ioctl call for type info.
  2011. Returns 0 on success, Ioctl error value otherwise.
  2012. **/
  2013. ULONG GetFieldOffsetAndSize(
  2014. IN LPSTR Type,
  2015. IN LPSTR Field,
  2016. OUT PULONG pOffset,
  2017. OUT PULONG pSize)
  2018. {
  2019. FIELD_INFO flds = {
  2020. Field, "", 0,
  2021. DBG_DUMP_FIELD_FULL_NAME | DBG_DUMP_FIELD_RETURN_ADDRESS,
  2022. 0, NULL};
  2023. SYM_DUMP_PARAM Sym = {
  2024. sizeof (SYM_DUMP_PARAM), Type, DBG_DUMP_NO_PRINT, 0,
  2025. NULL, NULL, NULL, 1, &flds
  2026. };
  2027. ULONG Err, i=0;
  2028. LPSTR dot, last=Field;
  2029. Sym.nFields = 1;
  2030. Err = Ioctl( IG_DUMP_SYMBOL_INFO, &Sym, Sym.size );
  2031. *pOffset = (ULONG) (flds.address - Sym.addr);
  2032. *pSize = flds.size;
  2033. return Err;
  2034. }
  2035. ULONG GetUlongFromAddress (
  2036. ULONG64 Location)
  2037. {
  2038. ULONG Value;
  2039. ULONG result;
  2040. if ((!ReadMemory(Location,&Value,sizeof(ULONG),&result)) ||
  2041. (result < sizeof(ULONG))) {
  2042. dprintf("unable to read from %08x\n",Location);
  2043. return 0;
  2044. }
  2045. return Value;
  2046. }
  2047. ULONG64 GetPointerFromAddress(
  2048. ULONG64 Location)
  2049. {
  2050. ULONG64 Value;
  2051. ULONG result;
  2052. if (ReadPtr(Location,&Value))
  2053. {
  2054. dprintf("unable to read from %p\n",Location);
  2055. return 0;
  2056. }
  2057. return Value;
  2058. }
  2059. DECLARE_API(pktpools)
  2060. {
  2061. ULONG64 PoolListAddr;
  2062. ULONG64 LinkAddr;
  2063. ULONG64 Pool;
  2064. ULONG64 Allocator;
  2065. ULONG LinkOffset;
  2066. LONG BlocksAllocated;
  2067. ULONG BlockSize;
  2068. USHORT PacketLength;
  2069. USHORT PktsPerBlock;
  2070. PoolListAddr = GetExpression("ndis!ndisGlobalPacketPoolList");
  2071. if (PoolListAddr == 0)
  2072. {
  2073. ErrorCheckSymbols("ndis!ndisGlobalPacketPoolList");
  2074. return;
  2075. }
  2076. GetFieldValue(PoolListAddr, LIST_ENTRY_NAME, "Flink", LinkAddr);
  2077. //
  2078. // First, get some offsets.
  2079. //
  2080. if (GetFieldOffset(NDIS_PKT_POOL_NAME, "GlobalPacketPoolList", &LinkOffset) != 0)
  2081. {
  2082. dprintf("Can't get offset of GlobalPacketPoolList in NDIS_PKT_POOL!\n");
  2083. return;
  2084. }
  2085. dprintf("Pool Allocator BlocksAllocated BlockSize PktsPerBlock PacketLength\n");
  2086. while (LinkAddr != PoolListAddr)
  2087. {
  2088. if (CheckControlC())
  2089. {
  2090. break;
  2091. }
  2092. Pool = LinkAddr - LinkOffset;
  2093. GetFieldValue(Pool, NDIS_PKT_POOL_NAME, "Allocator", Allocator);
  2094. GetFieldValue(Pool, NDIS_PKT_POOL_NAME, "BlocksAllocated", BlocksAllocated);
  2095. GetFieldValue(Pool, NDIS_PKT_POOL_NAME, "BlockSize", BlockSize);
  2096. GetFieldValue(Pool, NDIS_PKT_POOL_NAME, "PktsPerBlock", PktsPerBlock);
  2097. GetFieldValue(Pool, NDIS_PKT_POOL_NAME, "PacketLength", PacketLength);
  2098. dprintf("%p %p 0x%lx\t 0x%lx\t 0x%lx\t 0x%lx\n", Pool,
  2099. Allocator,
  2100. BlocksAllocated,
  2101. BlockSize,
  2102. PktsPerBlock,
  2103. PacketLength);
  2104. GetFieldValue(Pool, NDIS_PKT_POOL_NAME, "GlobalPacketPoolList.Flink", LinkAddr);
  2105. if (LinkAddr == 0)
  2106. {
  2107. break;
  2108. }
  2109. }
  2110. }
  2111. /*
  2112. DECLARE_API(pktpool)
  2113. {
  2114. ULONG64 PktPoolAddr;
  2115. //
  2116. // Verify if any args are present
  2117. //
  2118. if (!args || !*args)
  2119. {
  2120. dprintf("Usage: pktpool <pointer to a Ndis packet pool>\n");
  2121. return;
  2122. }
  2123. PktPoolAddr = GetExpression(args);
  2124. dprintf(" Packet Pool %p : ", PktPoolAddr);
  2125. }
  2126. */
  2127. DECLARE_API(mem)
  2128. {
  2129. ULONG64 MiniportAddr, MiniBlockAddr;
  2130. ULONG64 Miniport, MiniBlock;
  2131. ULONG64 ListAddr;
  2132. ULONG64 LinkAddr;
  2133. ULONG64 TrackMem, Address, Caller, CallersCaller;
  2134. ULONG LinkOffset;
  2135. ULONG Tag;
  2136. UINT Length;
  2137. BOOLEAN Done;
  2138. do
  2139. {
  2140. MiniBlockAddr = GetExpression("ndis!ndisDriverTrackAlloc");
  2141. if (MiniBlockAddr == 0)
  2142. {
  2143. ErrorCheckSymbols("ndis!ndisDriverTrackAlloc");
  2144. break;
  2145. }
  2146. MiniportAddr = GetExpression("ndis!ndisMiniportTrackAlloc");
  2147. if (MiniportAddr == 0)
  2148. {
  2149. ErrorCheckSymbols("ndis!ndisMiniportTrackAlloc");
  2150. break;
  2151. }
  2152. //
  2153. // First, get some offsets.
  2154. //
  2155. if (GetFieldOffset(NDIS_TRACK_MEM_NAME, "List", &LinkOffset) != 0)
  2156. {
  2157. dprintf("Can't get offset of List in NDIS_TRACK_MEM!\n");
  2158. break;
  2159. }
  2160. ListAddr = GetExpression("ndis!ndisDriverTrackAllocList");
  2161. if (ListAddr == 0)
  2162. {
  2163. ErrorCheckSymbols("ndis!ndisDriverTrackAllocList");
  2164. break;
  2165. }
  2166. Done = FALSE;
  2167. MiniBlock = GetPointerFromAddress(MiniBlockAddr);
  2168. dprintf("Allocations charged to Miniport Driver Block at %p\n", MiniBlock);
  2169. again:
  2170. GetFieldValue(ListAddr, LIST_ENTRY_NAME, "Flink", LinkAddr);
  2171. dprintf("Address Tag Length Caller Caller'sCaller\n");
  2172. while (LinkAddr != ListAddr)
  2173. {
  2174. if (CheckControlC())
  2175. {
  2176. break;
  2177. }
  2178. TrackMem = (ULONG64)((PUCHAR)LinkAddr - LinkOffset);
  2179. Address = TrackMem + sizeof(NDIS_TRACK_MEM);
  2180. GetFieldValue(TrackMem, NDIS_TRACK_MEM_NAME, "Length", Length);
  2181. GetFieldValue(TrackMem, NDIS_TRACK_MEM_NAME, "Tag", Tag);
  2182. GetFieldValue(TrackMem, NDIS_TRACK_MEM_NAME, "Caller", Caller);
  2183. GetFieldValue(TrackMem, NDIS_TRACK_MEM_NAME, "CallersCaller", CallersCaller);
  2184. dprintf("%p %c%c%c%c %8lx %p %p\n",
  2185. Address,
  2186. Tag & 0xff,
  2187. (Tag >> 8) & 0xff,
  2188. (Tag >> 16) & 0xff,
  2189. (Tag >> 24) & 0xff,
  2190. Length, Caller, CallersCaller);
  2191. GetFieldValue(LinkAddr, NDIS_TRACK_MEM_NAME, "List.Flink", LinkAddr);
  2192. if (LinkAddr == 0)
  2193. {
  2194. break;
  2195. }
  2196. }
  2197. if (Done)
  2198. break;
  2199. Done = TRUE;
  2200. ListAddr = GetExpression("ndis!ndisMiniportTrackAllocList");
  2201. if (ListAddr == 0)
  2202. {
  2203. ErrorCheckSymbols("ndis!ndisMiniportTrackAllocList");
  2204. break;
  2205. }
  2206. Miniport = GetPointerFromAddress(MiniportAddr);
  2207. dprintf("\nAllocations charged to Miniport at %p\n", Miniport);
  2208. GetFieldValue(ListAddr, LIST_ENTRY_NAME, "Flink", LinkAddr);
  2209. goto again;
  2210. }while (FALSE);
  2211. }
  2212. DECLARE_API(ndis)
  2213. {
  2214. ULONG64 dwAddress;
  2215. ULONG CheckedVersion;
  2216. //
  2217. // get Ndis build date and time
  2218. //
  2219. dwAddress = GetExpression("ndis!ndisChecked");
  2220. if (dwAddress != 0)
  2221. {
  2222. CheckedVersion = GetUlongFromAddress(dwAddress);
  2223. if (CheckedVersion == 1)
  2224. dprintf("Checked");
  2225. else
  2226. dprintf("Free");
  2227. dprintf(" Ndis built on: ");
  2228. dwAddress = GetExpression("ndis!ndisBuildDate");
  2229. if (dwAddress != 0)
  2230. {
  2231. PrintName(dwAddress);
  2232. }
  2233. dprintf(", ");
  2234. dwAddress = GetExpression("ndis!ndisBuildTime");
  2235. if (dwAddress != 0)
  2236. {
  2237. PrintName(dwAddress);
  2238. }
  2239. dprintf(", by ");
  2240. dwAddress = GetExpression("ndis!ndisBuiltBy");
  2241. if (dwAddress != 0)
  2242. {
  2243. PrintName(dwAddress);
  2244. }
  2245. dprintf(".\n");
  2246. }
  2247. }
  2248. DECLARE_API(opens)
  2249. {
  2250. ULONG64 OpenListAddr;
  2251. ULONG64 OpenAddr;
  2252. ULONG64 ProtocolAddr;
  2253. ULONG64 MiniportAddr;
  2254. ULONG Offset;
  2255. OpenListAddr = GetExpression("ndis!ndisGlobalOpenList");
  2256. if (OpenListAddr == 0)
  2257. {
  2258. ErrorCheckSymbols("ndis!ndisGlobalOpenList");
  2259. return;
  2260. }
  2261. OpenAddr = GetPointerFromAddress(OpenListAddr);
  2262. if (GetFieldOffset(NDIS_PROTOCOL_BLOCK_NAME, "ProtocolCharacteristics.Name", &Offset) != 0)
  2263. {
  2264. dprintf("Cant get offset of Name in Protocol block!");
  2265. return;
  2266. }
  2267. while (OpenAddr != 0)
  2268. {
  2269. if (CheckControlC())
  2270. {
  2271. break;
  2272. }
  2273. GetFieldValue(OpenAddr, NDIS_COMMON_OPEN_BLOCK_NAME, "ProtocolHandle", ProtocolAddr);
  2274. GetFieldValue(OpenAddr, NDIS_COMMON_OPEN_BLOCK_NAME, "MiniportHandle", MiniportAddr);
  2275. dprintf(" Open %p \n", OpenAddr);
  2276. if (MiniportAddr)
  2277. {
  2278. dprintf(" Miniport: %p - ", MiniportAddr);
  2279. PrintMiniportName(MiniportAddr);
  2280. dprintf("\n");
  2281. }
  2282. if (ProtocolAddr)
  2283. {
  2284. dprintf(" Protocol: %p - ", ProtocolAddr);
  2285. PrintName(ProtocolAddr + Offset);
  2286. dprintf("\n");
  2287. }
  2288. dprintf("\n");
  2289. GetFieldValue(OpenAddr, NDIS_COMMON_OPEN_BLOCK_NAME, "NextGlobalOpen", OpenAddr);
  2290. }
  2291. }
  2292. /*++
  2293. Routine Desc:
  2294. This function searches one block for the packet with the
  2295. specified virtual address.
  2296. Argument:
  2297. CurBlock --- The starting of the searched block
  2298. CurPacket --- The first packet inside CurBlock to search
  2299. PktsPerBlock --- Number of packets inside the searched block
  2300. PacketStackSize --- The stack size inside the searched block
  2301. Flags --- 1: Free block to search
  2302. --- 0: Used block to search
  2303. Address --- The virtual address
  2304. PacketLength --- Packet length of the search block
  2305. BlockSize --- The size of the current block
  2306. Return Value:
  2307. True --- Packet found
  2308. False --- Packet not found
  2309. --*/
  2310. BOOL
  2311. SearchVaInOneBlock(
  2312. ULONG64 CurBlock,
  2313. ULONG PktsPerBlock,
  2314. ULONG PacketStackSize,
  2315. UCHAR Flags,
  2316. ULONG64 Address,
  2317. USHORT PacketLength,
  2318. ULONG BlockSize)
  2319. {
  2320. USHORT i;
  2321. UCHAR NdisPacketFlags;
  2322. ULONG64 TmpVal;
  2323. PVOID MappedSystemVa;
  2324. ULONG ByteCount;
  2325. ULONG64 pNdisBuf;
  2326. PUCHAR p;
  2327. ULONG64 CurPacket;
  2328. CurPacket = CurBlock + GetTypeSize(NDIS_PKT_POOL_HDR_NAME);
  2329. p = (PUCHAR)CurPacket;
  2330. for(i = 0; i < PktsPerBlock; i++, p += PacketLength)
  2331. {
  2332. if (CheckControlC())
  2333. {
  2334. break;
  2335. }
  2336. CurPacket = (ULONG64)(p + PacketStackSize);
  2337. //
  2338. // Flags = 1 means free blocks
  2339. //
  2340. if (Flags)
  2341. {
  2342. //
  2343. // skip the packet if it is not allocated, check for the flag
  2344. //
  2345. GetFieldValue(CurPacket, NDIS_PACKET_NAME,
  2346. "Private.NdisPacketFlags", NdisPacketFlags);
  2347. if ((NdisPacketFlags & fPACKET_ALLOCATED_BY_NDIS) == 0)
  2348. {
  2349. continue;
  2350. }
  2351. //
  2352. // For packets in the free list
  2353. //
  2354. GetFieldValue(CurPacket, NDIS_PACKET_NAME,
  2355. "Private.Head", pNdisBuf);
  2356. //
  2357. // PAGE_SIZE may not be BlockSize
  2358. //
  2359. if (pNdisBuf >= CurBlock && pNdisBuf < CurBlock + BlockSize)
  2360. {
  2361. continue;
  2362. }
  2363. }
  2364. //
  2365. // for each allocated packet, walk through all MDLs
  2366. //
  2367. GetFieldValue(CurPacket, NDIS_PACKET_NAME,
  2368. "Private.Head", pNdisBuf);
  2369. while(pNdisBuf)
  2370. {
  2371. GetFieldValue(pNdisBuf, NDIS_BUFFER_NAME,
  2372. "MappedSystemVa", TmpVal);
  2373. MappedSystemVa = (PVOID)TmpVal ;
  2374. GetFieldValue((ULONG64)pNdisBuf, NDIS_BUFFER_NAME,
  2375. "ByteCount", ByteCount);
  2376. if (Address >= (ULONG64)MappedSystemVa
  2377. && Address < (ULONG64)MappedSystemVa + ByteCount)
  2378. {
  2379. //
  2380. // Packet found, and print out the information about the packet
  2381. //
  2382. dprintf("\nPacket found\n");
  2383. dprintf("Packet at 0x%p\n", CurPacket);
  2384. PrintNdisPacketPrivate(CurPacket);
  2385. return TRUE;
  2386. }
  2387. GetFieldValue((ULONG64)pNdisBuf, NDIS_BUFFER_NAME,
  2388. "Next", TmpVal);
  2389. pNdisBuf = TmpVal;
  2390. }
  2391. }
  2392. return FALSE;
  2393. }
  2394. /*++
  2395. Roution Desc:
  2396. This function traverses blocks inside a list to search for the packet
  2397. Arguments:
  2398. CurBlockLink --- The "List" addresss inside one block
  2399. BlocksHeadAddress --- The header address of the block list inside one pool
  2400. BlcokLinkOffset --- The offset of "List" inside one block
  2401. PktsPerBlock --- Number of packets inside the searched block
  2402. PacketStackSize --- The stack size inside the searched block
  2403. Flags --- 1: Free block to search
  2404. --- 0: Used block to search
  2405. Address --- The virtual address
  2406. PacketLength --- Packet length of the search block
  2407. BlockSize --- Size of the block
  2408. Return Value:
  2409. True --- Packet found
  2410. False --- Packet not found
  2411. --*/
  2412. BOOL
  2413. SearchVaInBlocks(
  2414. ULONG64 CurBlockLink,
  2415. ULONG64 BlocksHeadAddr,
  2416. ULONG BlockLinkOffset,
  2417. ULONG PacketStackSize,
  2418. USHORT PktPerBlock,
  2419. UCHAR Flags,
  2420. ULONG64 Address,
  2421. USHORT PacketLength,
  2422. ULONG BlockSize)
  2423. {
  2424. ULONG64 CurBlock;
  2425. BOOL fRet;
  2426. while((ULONG64)CurBlockLink != BlocksHeadAddr)
  2427. {
  2428. if (CheckControlC())
  2429. {
  2430. break;
  2431. }
  2432. //
  2433. // for each free block, walk through all allocated packets
  2434. //
  2435. CurBlock = (ULONG64)CurBlockLink - BlockLinkOffset;
  2436. dprintf("\nSearching %s block <0x%p>\n", (Flags == 1)? "Free":"Used", CurBlock);
  2437. fRet = SearchVaInOneBlock(CurBlock,
  2438. PktPerBlock,
  2439. PacketStackSize,
  2440. Flags,
  2441. Address,
  2442. PacketLength,
  2443. BlockSize);
  2444. if (fRet)
  2445. {
  2446. return fRet;
  2447. }
  2448. GetFieldValue((ULONG64)CurBlockLink, LIST_ENTRY_NAME,
  2449. "Flink", CurBlockLink);
  2450. if (CurBlockLink == 0)
  2451. {
  2452. break;
  2453. }
  2454. }
  2455. return FALSE;
  2456. }
  2457. /*++
  2458. Routine Desc:
  2459. This function searches one block for the packets in use.
  2460. Argument:
  2461. CurBlock --- The starting of the searched block
  2462. PktsPerBlock --- Number of packets inside the searched block
  2463. PacketStackSize --- The stack size inside the searched block
  2464. Flags --- 1: Free block to search
  2465. --- 0: Used block to search
  2466. Address --- The virtual address
  2467. PacketLength --- Packet length of the search block
  2468. Return Value:
  2469. None
  2470. --*/
  2471. void
  2472. SearchPktInOneBlock(
  2473. ULONG64 CurBlock,
  2474. ULONG PktsPerBlock,
  2475. ULONG PacketStackSize,
  2476. UCHAR Flags,
  2477. USHORT PacketLength)
  2478. {
  2479. USHORT i;
  2480. ULONG64 BlockStartAddr;
  2481. PUCHAR p;
  2482. ULONG64 pStackIndex;
  2483. ULONG Index;
  2484. ULONG64 CurPacket;
  2485. CurPacket = CurBlock + GetTypeSize(NDIS_PKT_POOL_HDR_NAME);
  2486. p = (PUCHAR)CurPacket;
  2487. for(i = 0; i < PktsPerBlock; i++, p += PacketLength)
  2488. {
  2489. if (CheckControlC())
  2490. {
  2491. break;
  2492. }
  2493. CurPacket = (ULONG64)(p + PacketStackSize);
  2494. pStackIndex = CurPacket - GetTypeSize("ULONG");
  2495. Index = GetUlongFromAddress((ULONG64)pStackIndex);
  2496. if (Index != (ULONG)-1)
  2497. {
  2498. dprintf("Packet at 0x%p\n", CurPacket);
  2499. }
  2500. }
  2501. }
  2502. /*++
  2503. Roution Desc:
  2504. This function traverses blocks inside a list to search for the packets in use
  2505. Arguments:
  2506. CurBlockLink --- The "List" addresss inside one block
  2507. BlocksHeadAddress --- The header address of the block list inside one pool
  2508. BlcokLinkOffset --- The offset of "List" inside one block
  2509. PktsPerBlock --- Number of packets inside the searched block
  2510. PacketStackSize --- The stack size inside the searched block
  2511. Flags --- 1: Free block to search
  2512. --- 0: Used block to search
  2513. PacketLength --- Packet length of the search block
  2514. Return Value:
  2515. None
  2516. --*/
  2517. void
  2518. SearchPktInBlocks(
  2519. ULONG64 CurBlockLink,
  2520. ULONG64 BlocksHeadAddr,
  2521. ULONG BlockLinkOffset,
  2522. ULONG PacketStackSize,
  2523. USHORT PktPerBlock,
  2524. UCHAR Flags,
  2525. USHORT PacketLength)
  2526. {
  2527. ULONG64 CurBlock;
  2528. ULONG64 TmpVal;
  2529. while(CurBlockLink != BlocksHeadAddr)
  2530. {
  2531. if (CheckControlC())
  2532. {
  2533. break;
  2534. }
  2535. //
  2536. // for each free block, walk through all allocated packets
  2537. //
  2538. CurBlock = (ULONG64)CurBlockLink - BlockLinkOffset;
  2539. dprintf("\nSearching %s block <0x%p>\n", (Flags == 1)? "Free":"Used", CurBlock);
  2540. SearchPktInOneBlock(CurBlock,
  2541. PktPerBlock,
  2542. PacketStackSize,
  2543. Flags,
  2544. PacketLength);
  2545. GetFieldValue((ULONG64)CurBlockLink, LIST_ENTRY_NAME,
  2546. "Flink", TmpVal);
  2547. CurBlockLink = TmpVal;
  2548. if (CurBlockLink == 0)
  2549. {
  2550. break;
  2551. }
  2552. }
  2553. }
  2554. /*++
  2555. Routine Desc:
  2556. This function is to find the packets with the given virtual address.
  2557. It traverses each pool, and inside one pool it traverses freeblockslist
  2558. and usedblockslist, then inside each block in the list, it search for
  2559. the packet with the given virtual address
  2560. --*/
  2561. void
  2562. FindPacketWithVa(ULONG64 Address)
  2563. {
  2564. ULONG64 PoolListAddr;
  2565. ULONG64 LinkAddr;
  2566. ULONG64 Pool;
  2567. ULONG LinkOffset;
  2568. LONG BlocksAllocated;
  2569. USHORT BlockSize;
  2570. USHORT PacketLength;
  2571. USHORT PktsPerBlock;
  2572. ULONG NumberOfStacks;
  2573. ULONG PacketStackSize;
  2574. ULONG FreeBlocksLinkOffset;
  2575. ULONG UsedBlocksLinkOffset;
  2576. ULONG BlockLinkOffset;
  2577. ULONG64 PoolFreeBlocksListAddr;
  2578. ULONG64 PoolUsedBlocksListAddr;
  2579. ULONG64 CurBlockLink;
  2580. ULONG64 BlocksHeadAddr;
  2581. BOOL fRet;
  2582. ULONG64 NumberOfStacksAddr;
  2583. PoolListAddr = GetExpression("ndis!ndisGlobalPacketPoolList");
  2584. if (PoolListAddr == 0)
  2585. {
  2586. ErrorCheckSymbols("ndis!ndisGlobalPacketPoolList");
  2587. return;
  2588. }
  2589. GetFieldValue(PoolListAddr, LIST_ENTRY_NAME, "Flink", LinkAddr);
  2590. if (LinkAddr == 0)
  2591. {
  2592. dprintf("Can't get Flink of PoolListAddr.\n");
  2593. return;
  2594. }
  2595. NumberOfStacksAddr = GetExpression("ndis!ndisPacketStackSize");
  2596. if (NumberOfStacksAddr == 0)
  2597. {
  2598. ErrorCheckSymbols("ndis!ndisPacketStackSize");
  2599. return;
  2600. }
  2601. NumberOfStacks = GetUlongFromAddress(NumberOfStacksAddr);
  2602. PacketStackSize = (ULONG)GetTypeSize(STACK_INDEX_NAME)
  2603. + (ULONG)GetTypeSize(NDIS_PACKET_STACK_NAME) * NumberOfStacks;
  2604. //
  2605. // First, get some offsets.
  2606. //
  2607. if (GetFieldOffset(NDIS_PKT_POOL_NAME, "GlobalPacketPoolList", &LinkOffset) != 0)
  2608. {
  2609. dprintf("Can't get offset of GlobalPacketPoolList in NDIS_PKT_POOL!\n");
  2610. return;
  2611. }
  2612. if (GetFieldOffset(NDIS_PKT_POOL_NAME,
  2613. "FreeBlocks",&FreeBlocksLinkOffset) != 0)
  2614. {
  2615. dprintf("Can't get offset of FreeBlocks in NDIS_PKT_POOL!\n");
  2616. return;
  2617. }
  2618. if (GetFieldOffset(NDIS_PKT_POOL_NAME, "UsedBlocks", &UsedBlocksLinkOffset) != 0)
  2619. {
  2620. dprintf("Can't get offset of UsedBlocks in NDIS_PKT_POOL!\n");
  2621. return;
  2622. }
  2623. if (GetFieldOffset(NDIS_PKT_POOL_HDR_NAME, "List", &BlockLinkOffset) != 0)
  2624. {
  2625. dprintf("Can't get offset of List in NDIS_PKT_POOL_HDR!\n");
  2626. return;
  2627. }
  2628. //
  2629. // walk through all the allocated packet pools
  2630. //
  2631. while (LinkAddr != PoolListAddr)
  2632. {
  2633. //
  2634. // Just safe check, usually this condition never satisfied
  2635. if (LinkAddr == 0)
  2636. {
  2637. break;
  2638. }
  2639. if (CheckControlC())
  2640. {
  2641. break;
  2642. }
  2643. //
  2644. // Get the pool
  2645. //
  2646. Pool = LinkAddr - LinkOffset;
  2647. PoolFreeBlocksListAddr = Pool + FreeBlocksLinkOffset;
  2648. PoolUsedBlocksListAddr = Pool + UsedBlocksLinkOffset;
  2649. GetFieldValue(Pool, NDIS_PKT_POOL_NAME, "BlockSize", BlockSize);
  2650. GetFieldValue(Pool, NDIS_PKT_POOL_NAME, "PktsPerBlock", PktsPerBlock);
  2651. GetFieldValue(Pool, NDIS_PKT_POOL_NAME, "PacketLength", PacketLength);
  2652. //
  2653. // walk through all free and used blocks on this packet pool
  2654. //
  2655. BlocksHeadAddr = PoolFreeBlocksListAddr;
  2656. //
  2657. // Search free blocks
  2658. //
  2659. GetFieldValue(Pool, NDIS_PKT_POOL_NAME,
  2660. "FreeBlocks.Flink", CurBlockLink);
  2661. if (CurBlockLink != 0)
  2662. {
  2663. fRet = SearchVaInBlocks ((ULONG64)CurBlockLink,
  2664. BlocksHeadAddr,
  2665. BlockLinkOffset,
  2666. PacketStackSize,
  2667. PktsPerBlock,
  2668. 1,
  2669. Address,
  2670. PacketLength,
  2671. BlockSize);
  2672. if (fRet)
  2673. {
  2674. return;
  2675. }
  2676. }
  2677. BlocksHeadAddr = PoolUsedBlocksListAddr;
  2678. //
  2679. // Search used blocks
  2680. GetFieldValue(Pool, NDIS_PKT_POOL_NAME,
  2681. "UsedBlocks.Flink", CurBlockLink);
  2682. if (CurBlockLink != 0)
  2683. {
  2684. fRet = SearchVaInBlocks (CurBlockLink,
  2685. BlocksHeadAddr,
  2686. BlockLinkOffset,
  2687. PacketStackSize,
  2688. PktsPerBlock,
  2689. 0,
  2690. Address,
  2691. PacketLength,
  2692. BlockSize);
  2693. if (fRet)
  2694. {
  2695. return;
  2696. }
  2697. }
  2698. //
  2699. // Go to the next pool
  2700. //
  2701. GetFieldValue(LinkAddr, LIST_ENTRY_NAME,
  2702. "Flink", LinkAddr);
  2703. if (LinkAddr == 0)
  2704. {
  2705. break;
  2706. }
  2707. }
  2708. dprintf("\nPACKET with VA 0x%p Not Found\n", Address);
  2709. }
  2710. /*++
  2711. Routine Desc:
  2712. This function is to find the packets in use inside a pool with the
  2713. given pool address. Inside the pool it traverses freeblockslist
  2714. and usedblockslist, then inside each block in the list, it search for
  2715. the packets that are in use
  2716. --*/
  2717. void
  2718. FindPacketInUse(ULONG64 Pool)
  2719. {
  2720. ULONG BlockSize;
  2721. USHORT PacketLength;
  2722. USHORT PktsPerBlock;
  2723. ULONG NumberOfStacks;
  2724. ULONG PacketStackSize;
  2725. ULONG64 TmpVal;
  2726. ULONG FreeBlocksLinkOffset;
  2727. ULONG UsedBlocksLinkOffset;
  2728. ULONG BlockLinkOffset;
  2729. ULONG64 PoolFreeBlocksListAddr;
  2730. ULONG64 PoolUsedBlocksListAddr;
  2731. ULONG64 CurBlockLink;
  2732. ULONG64 BlocksHeadAddr;
  2733. ULONG64 NumberOfStacksAddr;
  2734. NumberOfStacksAddr = GetExpression("ndis!ndisPacketStackSize");
  2735. NumberOfStacks = GetUlongFromAddress(NumberOfStacksAddr);
  2736. PacketStackSize = (ULONG)GetTypeSize(STACK_INDEX_NAME)
  2737. + (ULONG)GetTypeSize(NDIS_PACKET_STACK_NAME) * NumberOfStacks;
  2738. //
  2739. // First, get some offsets.
  2740. //
  2741. if (GetFieldOffset(NDIS_PKT_POOL_NAME,
  2742. "FreeBlocks",&FreeBlocksLinkOffset) != 0)
  2743. {
  2744. dprintf("Can't get offset of FreeBlocks in NDIS_PKT_POOL!\n");
  2745. return;
  2746. }
  2747. if (GetFieldOffset(NDIS_PKT_POOL_NAME, "UsedBlocks", &UsedBlocksLinkOffset) != 0)
  2748. {
  2749. dprintf("Can't get offset of UsedBlocks in NDIS_PKT_POOL!\n");
  2750. return;
  2751. }
  2752. if (GetFieldOffset(NDIS_PKT_POOL_HDR_NAME, "List", &BlockLinkOffset) != 0)
  2753. {
  2754. dprintf("Can't get offset of List in NDIS_PKT_POOL_HDR!\n");
  2755. return;
  2756. }
  2757. //
  2758. // Get the pool
  2759. //
  2760. PoolFreeBlocksListAddr = Pool + FreeBlocksLinkOffset;
  2761. PoolUsedBlocksListAddr = Pool + UsedBlocksLinkOffset;
  2762. GetFieldValue(Pool, NDIS_PKT_POOL_NAME, "BlockSize", BlockSize);
  2763. GetFieldValue(Pool, NDIS_PKT_POOL_NAME, "PktsPerBlock", PktsPerBlock);
  2764. GetFieldValue(Pool, NDIS_PKT_POOL_NAME, "PacketLength", PacketLength);
  2765. //
  2766. // walk through all free and used blocks on this packet pool
  2767. //
  2768. BlocksHeadAddr = PoolFreeBlocksListAddr;
  2769. //
  2770. // Search free blocks
  2771. //
  2772. GetFieldValue(Pool, NDIS_PKT_POOL_NAME,
  2773. "FreeBlocks.Flink", CurBlockLink);
  2774. if (CurBlockLink != 0)
  2775. {
  2776. SearchPktInBlocks ((ULONG64)CurBlockLink,
  2777. BlocksHeadAddr,
  2778. BlockLinkOffset,
  2779. PacketStackSize,
  2780. PktsPerBlock,
  2781. 1,
  2782. PacketLength);
  2783. }
  2784. BlocksHeadAddr = PoolUsedBlocksListAddr;
  2785. //
  2786. // Search used blocks
  2787. GetFieldValue(Pool, NDIS_PKT_POOL_NAME,
  2788. "UsedBlocks.Flink", CurBlockLink);
  2789. if (CurBlockLink != 0)
  2790. {
  2791. SearchPktInBlocks ((ULONG64)CurBlockLink,
  2792. BlocksHeadAddr,
  2793. BlockLinkOffset,
  2794. PacketStackSize,
  2795. PktsPerBlock,
  2796. 0,
  2797. PacketLength);
  2798. }
  2799. }
  2800. /*++
  2801. Routine Desc:
  2802. This function is to find packets with the given selection
  2803. v --- with virtual address
  2804. p --- with pool address
  2805. --*/
  2806. DECLARE_API(findpacket)
  2807. {
  2808. CHAR Verbosity;
  2809. CHAR argbuf[ MAX_PATH ];
  2810. CHAR arglist[10][MAX_PATH];
  2811. CHAR *str;
  2812. INT index=0;
  2813. CHAR *p;
  2814. ULONG64 Address;
  2815. if (!args || !*args)
  2816. {
  2817. dprintf("Usag: findpacket v <virtual address>\n");
  2818. dprintf(" p <pool address>\n");
  2819. return;
  2820. }
  2821. strcpy(argbuf,args);
  2822. for (p = mystrtok( argbuf, " \t,;" );
  2823. p && *p;
  2824. p = mystrtok(NULL, " \t,;"))
  2825. {
  2826. strcpy(&arglist[index++][0], p);
  2827. }
  2828. Verbosity = arglist[0][0];
  2829. if (Verbosity != 'v' && Verbosity != 'p')
  2830. {
  2831. dprintf("Usag: findpacket v <virtual address>\n");
  2832. dprintf(" p <pool address>\n");
  2833. return;
  2834. }
  2835. if (index < 2)
  2836. {
  2837. dprintf("\nAddress is needed \n");
  2838. return;
  2839. }
  2840. Address = GetExpression(&arglist[1][0]);
  2841. switch (Verbosity)
  2842. {
  2843. case 'v':
  2844. FindPacketWithVa(Address);
  2845. break;
  2846. case 'p':
  2847. FindPacketInUse(Address);
  2848. default:
  2849. break;
  2850. }
  2851. }