Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

3525 lines
97 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. CHAR * NDIS_PACKET_OOB_DATA_NAME = "ndis!_NDIS_PACKET_OOB_DATA";
  45. typedef struct
  46. {
  47. CHAR Name[16];
  48. unsigned int Val;
  49. } DBG_LEVEL;
  50. DBG_LEVEL DbgLevel[] = {
  51. {"INFO", DBG_LEVEL_INFO},
  52. {"LOG", DBG_LEVEL_LOG},
  53. {"WARN", DBG_LEVEL_WARN},
  54. {"ERR", DBG_LEVEL_ERR},
  55. {"FATAL", DBG_LEVEL_FATAL}
  56. };
  57. typedef struct
  58. {
  59. CHAR Name[16];
  60. unsigned int Val;
  61. } DBG_COMP;
  62. DBG_COMP DbgSystems[] = {
  63. {"INIT", DBG_COMP_INIT},
  64. {"CONFIG", DBG_COMP_CONFIG},
  65. {"SEND", DBG_COMP_SEND},
  66. {"RECV", DBG_COMP_RECV},
  67. {"PROTOCOL", DBG_COMP_PROTOCOL},
  68. {"BIND", DBG_COMP_BIND},
  69. {"BUS_QUERY", DBG_COMP_BUSINFO},
  70. {"REGISTRY", DBG_COMP_REG},
  71. {"MEMORY", DBG_COMP_MEMORY},
  72. {"FILTER", DBG_COMP_FILTER},
  73. {"REQUEST", DBG_COMP_REQUEST},
  74. {"WORK_ITEM", DBG_COMP_WORK_ITEM},
  75. {"PNP", DBG_COMP_PNP},
  76. {"PM", DBG_COMP_PM},
  77. {"OPEN", DBG_COMP_OPENREF},
  78. {"LOCKS", DBG_COMP_LOCKS},
  79. {"RESET", DBG_COMP_RESET},
  80. {"WMI", DBG_COMP_WMI},
  81. {"NDIS_CO", DBG_COMP_CO},
  82. {"REFERENCE", DBG_COMP_REF}
  83. };
  84. typedef struct
  85. {
  86. CHAR Name[40];
  87. UINT Val;
  88. } DBG_PER_PACKET_INFO_ID_TYPES;
  89. DBG_PER_PACKET_INFO_ID_TYPES DbgPacketInfoIdTypes[] = {
  90. {"TcpIpChecksumPacketInfo", TcpIpChecksumPacketInfo},
  91. {"IpSecPacketInfo", IpSecPacketInfo},
  92. {"TcpLargeSendPacketInfo", TcpLargeSendPacketInfo},
  93. {"ClassificationHandlePacketInfo", ClassificationHandlePacketInfo},
  94. {"NdisReserved", NdisReserved},
  95. {"ScatterGatherListPacketInfo", ScatterGatherListPacketInfo},
  96. {"Ieee8021pPriority", Ieee8021pPriority},
  97. {"OriginalPacketInfo", OriginalPacketInfo},
  98. {"PacketCancelId", PacketCancelId},
  99. {"MaxPerPacketInfo", MaxPerPacketInfo}
  100. };
  101. typedef struct
  102. {
  103. CHAR Name[20];
  104. unsigned int Val;
  105. } DBG_MEDIA_TYPES;
  106. DBG_MEDIA_TYPES DbgMediaTypes[] = {
  107. {"802.3", NdisMedium802_3},
  108. {"802.5", NdisMedium802_5},
  109. {"FDDI", NdisMediumFddi},
  110. {"WAN", NdisMediumWan},
  111. {"LocalTalk", NdisMediumLocalTalk},
  112. {"Dix", NdisMediumDix},
  113. {"ArcNet Raw", NdisMediumArcnetRaw},
  114. {"ArcNet 878.2", NdisMediumArcnet878_2},
  115. {"ATM", NdisMediumAtm},
  116. {"Wireless WAN", NdisMediumWirelessWan},
  117. {"IRDA", NdisMediumIrda},
  118. {"BPC", NdisMediumBpc},
  119. {"CO-WAN", NdisMediumCoWan},
  120. {"IEEE1394",NdisMedium1394},
  121. {"Illegal", NdisMediumMax}
  122. };
  123. typedef struct
  124. {
  125. CHAR Name[64];
  126. unsigned int Val;
  127. } DBG_MINIPORT_FLAGS;
  128. DBG_MINIPORT_FLAGS DbgMiniportFlags[] = {
  129. {"NORMAL_INTERRUPTS", fMINIPORT_NORMAL_INTERRUPTS},
  130. {"IN_INITIALIZE", fMINIPORT_IN_INITIALIZE},
  131. {"ARCNET_BROADCAST_SET", fMINIPORT_ARCNET_BROADCAST_SET},
  132. {"BUS_MASTER", fMINIPORT_BUS_MASTER},
  133. {"64BIT_DMA", fMINIPORT_64BITS_DMA},
  134. {"DEREGISTERED_INTERRUPT", fMINIPORT_DEREGISTERED_INTERRUPT},
  135. {"SG_LIST", fMINIPORT_SG_LIST},
  136. {"REQUEST_TIMEOUT", fMINIPORT_REQUEST_TIMEOUT},
  137. {"PROCESSING_REQUEST", fMINIPORT_PROCESSING_REQUEST},
  138. {"IGNORE_PACKET_QUEUE", fMINIPORT_IGNORE_PACKET_QUEUE},
  139. {"IGNORE_REQUEST_QUEUE", fMINIPORT_IGNORE_REQUEST_QUEUE},
  140. {"IGNORE_TOKEN_RING_ERRORS", fMINIPORT_IGNORE_TOKEN_RING_ERRORS},
  141. {"CHECK_FOR_LOOPBACK", fMINIPORT_CHECK_FOR_LOOPBACK},
  142. {"INTERMEDIATE_DRIVER", fMINIPORT_INTERMEDIATE_DRIVER},
  143. {"NDIS_5", fMINIPORT_IS_NDIS_5},
  144. {"IS_CO", fMINIPORT_IS_CO},
  145. {"DESERIALIZED", fMINIPORT_DESERIALIZE},
  146. {"CALLING_RESET", fMINIPORT_CALLING_RESET},
  147. {"RESET_REQUESTED", fMINIPORT_RESET_REQUESTED},
  148. {"RESET_IN_PROGRESS", fMINIPORT_RESET_IN_PROGRESS},
  149. {"RESOURCES_AVAILABLE", fMINIPORT_RESOURCES_AVAILABLE},
  150. {"SEND_LOOPBACK_DIRECTED", fMINIPORT_SEND_LOOPBACK_DIRECTED},
  151. {"RESTORING_FILTERS", fMINIPORT_RESTORING_FILTERS},
  152. {"REQUIRES_MEDIA_POLLING", fMINIPORT_REQUIRES_MEDIA_POLLING},
  153. {"SUPPORTS_MEDIA_SENSE", fMINIPORT_SUPPORTS_MEDIA_SENSE},
  154. {"DOES_NOT_DO_LOOPBACK", fMINIPORT_DOES_NOT_DO_LOOPBACK},
  155. {"SECONDARY", fMINIPORT_SECONDARY},
  156. {"MEDIA_CONNECTED", fMINIPORT_MEDIA_CONNECTED},
  157. {"NETBOOT_CARD", fMINIPORT_NETBOOT_CARD},
  158. {"PM_HALTING", fMINIPORT_PM_HALTING}
  159. };
  160. //
  161. // flags that we care more if they are cleared
  162. //
  163. DBG_MINIPORT_FLAGS DbgMiniportClearedFlags[] = {
  164. {"NOT_BUS_MASTER", fMINIPORT_BUS_MASTER},
  165. {"NOT_IGNORE_TOKEN_RING_ERRORS", fMINIPORT_IGNORE_TOKEN_RING_ERRORS},
  166. {"NOT_RESOURCES_AVAILABLE", fMINIPORT_RESOURCES_AVAILABLE},
  167. {"NOT_SUPPORTS_MEDIA_SENSE", fMINIPORT_SUPPORTS_MEDIA_SENSE},
  168. {"DOES_LOOPBACK", fMINIPORT_DOES_NOT_DO_LOOPBACK},
  169. {"NOT_MEDIA_CONNECTED", fMINIPORT_MEDIA_CONNECTED}
  170. };
  171. typedef DBG_MINIPORT_FLAGS DBG_MINIPORT_PNP_FLAGS;
  172. DBG_MINIPORT_PNP_FLAGS DbgMiniportPnPFlags[] = {
  173. {"PM_SUPPORTED", fMINIPORT_PM_SUPPORTED},
  174. {"NO_SHUTDOWN", fMINIPORT_NO_SHUTDOWN},
  175. {"MEDIA_DISCONNECT_WAIT", fMINIPORT_MEDIA_DISCONNECT_WAIT},
  176. {"REMOVE_IN_PROGRESS", fMINIPORT_REMOVE_IN_PROGRESS},
  177. {"DEVICE_POWER_ENABLED", fMINIPORT_DEVICE_POWER_ENABLE},
  178. {"DEVICE_POWER_WAKE_ENABLE", fMINIPORT_DEVICE_POWER_WAKE_ENABLE},
  179. {"DEVICE_FAILED", fMINIPORT_DEVICE_FAILED},
  180. {"MEDIA_DISCONNECT_CANCELLED", fMINIPORT_MEDIA_DISCONNECT_CANCELLED},
  181. {"SEND_WAIT_WAKE", fMINIPORT_SEND_WAIT_WAKE},
  182. {"SYSTEM_SLEEPING", fMINIPORT_SYSTEM_SLEEPING},
  183. {"HIDDEN", fMINIPORT_HIDDEN},
  184. {"SWENUM", fMINIPORT_SWENUM},
  185. {"PM_HALTED", fMINIPORT_PM_HALTED},
  186. {"NO_HALT_ON_SUSPEND", fMINIPORT_NO_HALT_ON_SUSPEND},
  187. {"RECEIVED_START", fMINIPORT_RECEIVED_START},
  188. {"REJECT_REQUESTS", fMINIPORT_REJECT_REQUESTS},
  189. {"PROCESSING", fMINIPORT_PROCESSING},
  190. {"HALTING", fMINIPORT_HALTING},
  191. {"VERIFYING", fMINIPORT_VERIFYING},
  192. {"HARDWARE_DEVICE", fMINIPORT_HARDWARE_DEVICE},
  193. {"NDIS_WDM_DRIVER", fMINIPORT_NDIS_WDM_DRIVER},
  194. {"SHUT_DOWN", fMINIPORT_SHUT_DOWN},
  195. {"SHUTTING_DOWN", fMINIPORT_SHUTTING_DOWN},
  196. {"ORPHANED", fMINIPORT_ORPHANED},
  197. {"QUEUED_BIND_WORKITEM", fMINIPORT_QUEUED_BIND_WORKITEM},
  198. {"FILTER_IM", fMINIPORT_FILTER_IM}
  199. };
  200. typedef DBG_MINIPORT_FLAGS DBG_MINIPORT_PNP_CAPABILITIES;
  201. DBG_MINIPORT_PNP_CAPABILITIES DbgMiniportCapabilities[] = {
  202. {"NOT_STOPPABLE", NDIS_DEVICE_NOT_STOPPABLE},
  203. {"NOT_REMOVEABLE", NDIS_DEVICE_NOT_REMOVEABLE},
  204. {"NOT_SUSPENDABLE", NDIS_DEVICE_NOT_SUSPENDABLE},
  205. {"DISABLE_PM", NDIS_DEVICE_DISABLE_PM},
  206. {"DISABLE_WAKE_UP", NDIS_DEVICE_DISABLE_WAKE_UP},
  207. {"DISABLE_WAKE_ON_RECONNECT", NDIS_DEVICE_DISABLE_WAKE_ON_RECONNECT}
  208. };
  209. typedef DBG_MINIPORT_FLAGS DBG_MINIPORT_VERIFY_FLAGS;
  210. DBG_MINIPORT_VERIFY_FLAGS DbgMiniportVerifyFlags[] = {
  211. {"FAIL_MAP_REG_ALLOC", fMINIPORT_VERIFY_FAIL_MAP_REG_ALLOC},
  212. {"FAIL_INTERRUPT_REGISTER", fMINIPORT_VERIFY_FAIL_INTERRUPT_REGISTER},
  213. {"FAIL_SHARED_MEM_ALLOC", fMINIPORT_VERIFY_FAIL_SHARED_MEM_ALLOC},
  214. {"FAIL_CANCEL_TIMER", fMINIPORT_VERIFY_FAIL_CANCEL_TIMER},
  215. {"FAIL_MAP_IO_SPACE", fMINIPORT_VERIFY_FAIL_MAP_IO_SPACE},
  216. {"FAIL_REGISTER_IO", fMINIPORT_VERIFY_FAIL_REGISTER_IO},
  217. {"FAIL_READ_CONFIG_SPACE", fMINIPORT_VERIFY_FAIL_READ_CONFIG_SPACE},
  218. {"FAIL_WRITE_CONFIG_SPACE", fMINIPORT_VERIFY_FAIL_WRITE_CONFIG_SPACE},
  219. {"FAIL_INIT_SG_DMA", fMINIPORT_VERIFY_FAIL_INIT_SG}
  220. };
  221. typedef struct
  222. {
  223. CHAR Name[32];
  224. unsigned long Val;
  225. } DBG_DEVICE_STATE;
  226. DBG_DEVICE_STATE DbgDeviceState[] = {
  227. {"PowerDeviceUnspecified",PowerDeviceUnspecified},
  228. {"PowerDeviceD0",PowerDeviceD0},
  229. {"PowerDeviceD1",PowerDeviceD1},
  230. {"PowerDeviceD2",PowerDeviceD2},
  231. {"PowerDeviceD3",PowerDeviceD3},
  232. {"PowerDeviceMaximum",PowerDeviceMaximum},
  233. };
  234. typedef struct
  235. {
  236. CHAR Name[32];
  237. unsigned long Val;
  238. } DBG_VC_FLAGS;
  239. DBG_VC_FLAGS DbgVcPtrFlags[] = {
  240. {"VC_CALL_ACTIVE", VC_CALL_ACTIVE},
  241. {"VC_CALL_PENDING", VC_CALL_PENDING},
  242. {"VC_CALL_CLOSE_PENDING", VC_CALL_CLOSE_PENDING},
  243. {"VC_CALL_ABORTED", VC_CALL_ABORTED},
  244. {"VC_PTR_BLOCK_CLOSING", VC_PTR_BLOCK_CLOSING}
  245. };
  246. DBG_VC_FLAGS DbgVcFlags[] = {
  247. {"VC_ACTIVE", VC_ACTIVE},
  248. {"VC_ACTIVATE_PENDING", VC_ACTIVATE_PENDING},
  249. {"VC_DEACTIVATE_PENDING", VC_DEACTIVATE_PENDING},
  250. {"VC_DELETE_PENDING", VC_DELETE_PENDING},
  251. {"VC_HANDOFF_IN_PROGRESS", VC_HANDOFF_IN_PROGRESS}
  252. };
  253. typedef DBG_VC_FLAGS DBG_MINIPORT_PNP_DEVICE_STATE;
  254. DBG_MINIPORT_PNP_DEVICE_STATE DbgMiniportPnPDeviceState[] = {
  255. {"PNP_DEVICE_ADDED", NdisPnPDeviceAdded},
  256. {"PNP_DEVICE_STARTED", NdisPnPDeviceStarted},
  257. {"PNP_DEVICE_QUERY_STOPPED", NdisPnPDeviceQueryStopped},
  258. {"PNP_DEVICE_STOPPED", NdisPnPDeviceStopped},
  259. {"PNP_DEVICE_QUERY_REMOVED", NdisPnPDeviceQueryRemoved},
  260. {"PNP_DEVICE_REMOVED", NdisPnPDeviceRemoved}
  261. };
  262. typedef DBG_MINIPORT_FLAGS DBG_PACKET_FLAGS;
  263. DBG_PACKET_FLAGS DbgPacketFlags[] = {
  264. {"MULTICAST_PACKET", NDIS_FLAGS_MULTICAST_PACKET},
  265. {"RESERVED2", NDIS_FLAGS_RESERVED2},
  266. {"RESERVED3", NDIS_FLAGS_RESERVED3},
  267. {"DONT_LOOPBACK", NDIS_FLAGS_DONT_LOOPBACK},
  268. {"IS_LOOPBACK_PACKET", NDIS_FLAGS_IS_LOOPBACK_PACKET},
  269. {"LOOPBACK_ONLY", NDIS_FLAGS_LOOPBACK_ONLY},
  270. {"RESERVED4", NDIS_FLAGS_RESERVED4},
  271. {"DOUBLE_BUFFERED", NDIS_FLAGS_DOUBLE_BUFFERED}
  272. };
  273. DBG_PACKET_FLAGS DbgNdisPacketFlags[] = {
  274. {"fPACKET_HAS_TIMED_OUT", fPACKET_HAS_TIMED_OUT},
  275. {"fPACKET_IS_LOOPBACK", fPACKET_IS_LOOPBACK},
  276. {"fPACKET_SELF_DIRECTED", fPACKET_SELF_DIRECTED},
  277. {"fPACKET_DONT_COMPLETE", fPACKET_DONT_COMPLETE},
  278. {"fPACKET_PENDING", fPACKET_PENDING},
  279. {"fPACKET_ALREADY_LOOPEDBACK", fPACKET_ALREADY_LOOPEDBACK},
  280. {"fPACKET_CLEAR_ITEMS", fPACKET_CLEAR_ITEMS},
  281. {"fPACKET_CONTAINS_MEDIA_SPECIFIC_INFO", fPACKET_CONTAINS_MEDIA_SPECIFIC_INFO},
  282. {"fPACKET_ALLOCATED_BY_NDIS", fPACKET_ALLOCATED_BY_NDIS}
  283. };
  284. typedef DBG_MINIPORT_FLAGS DBG_PROTOCOL_FLAGS;
  285. DBG_PROTOCOL_FLAGS DbgProtocolFlags[]={
  286. {"NDIS_PROTOCOL_TESTER", NDIS_PROTOCOL_TESTER},
  287. {"NDIS_PROTOCOL_PROXY", NDIS_PROTOCOL_PROXY},
  288. {"NDIS_PROTOCOL_BIND_ALL_CO", NDIS_PROTOCOL_BIND_ALL_CO}
  289. };
  290. typedef DBG_MINIPORT_FLAGS DBG_OPEN_FLAGS;
  291. DBG_OPEN_FLAGS DbgOpenFlags[]={
  292. {"OPEN_USING_ETH_ENCAPSULATION", fMINIPORT_OPEN_USING_ETH_ENCAPSULATION},
  293. {"OPEN_NO_LOOPBACK", fMINIPORT_OPEN_NO_LOOPBACK},
  294. {"OPEN_PMODE", fMINIPORT_OPEN_PMODE},
  295. {"OPEN_NO_PROT_RSVD", fMINIPORT_OPEN_NO_PROT_RSVD},
  296. {"OPEN_PROCESSING", fMINIPORT_OPEN_PROCESSING},
  297. {"PACKET_RECEIVED", fMINIPORT_PACKET_RECEIVED},
  298. {"STATUS_RECEIVED", fMINIPORT_STATUS_RECEIVED},
  299. {"OPEN_CLOSING", fMINIPORT_OPEN_CLOSING},
  300. {"OPEN_UNBINDING", fMINIPORT_OPEN_UNBINDING},
  301. {"OPEN_CALL_MANAGER", fMINIPORT_OPEN_CALL_MANAGER},
  302. {"OPEN_NOTIFY_PROCESSING", fMINIPORT_OPEN_NOTIFY_PROCESSING},
  303. {"OPEN_CLOSE_COMPLETE", fMINIPORT_OPEN_CLOSE_COMPLETE},
  304. {"OPEN_DONT_FREE", fMINIPORT_OPEN_DONT_FREE}
  305. };
  306. /*
  307. * Get 'size' bytes from the debuggee program at 'dwAddress' and place it
  308. * in our address space at 'ptr'. Use 'type' in an error printout if necessary
  309. */
  310. BOOL
  311. GetData( IN LPVOID ptr, IN ULONG64 dwAddress, IN ULONG size, IN PCSTR type )
  312. {
  313. BOOL b;
  314. ULONG BytesRead;
  315. ULONG count = size;
  316. while( size > 0 ) {
  317. if (count >= 3000)
  318. count = 3000;
  319. b = ReadMemory(dwAddress, ptr, count, &BytesRead );
  320. if (!b || BytesRead != count ) {
  321. dprintf( "Unable to read %u bytes at %X, for %s\n", size, dwAddress, type );
  322. return FALSE;
  323. }
  324. dwAddress += count;
  325. size -= count;
  326. ptr = (LPVOID)((ULONG_PTR)ptr + count);
  327. }
  328. return TRUE;
  329. }
  330. /*
  331. * Fetch the null terminated UNICODE string at dwAddress into buf
  332. */
  333. BOOL
  334. GetString( IN ULONG64 dwAddress, IN LPWSTR buf, IN ULONG MaxChars )
  335. {
  336. do {
  337. if( !GetData( buf, dwAddress, sizeof( *buf ), "Character" ) )
  338. return FALSE;
  339. dwAddress += sizeof( *buf );
  340. } while( --MaxChars && *buf++ != '\0' );
  341. return TRUE;
  342. }
  343. char *mystrtok ( char *string, char * control )
  344. {
  345. static unsigned char *str;
  346. CHAR *p, *s;
  347. if( string )
  348. str = string;
  349. if( str == NULL || *str == '\0' )
  350. return NULL;
  351. //
  352. // Skip leading delimiters...
  353. //
  354. for( ; *str; str++ ) {
  355. for( s=control; *s; s++ ) {
  356. if( *str == *s )
  357. break;
  358. }
  359. if( *s == '\0' )
  360. break;
  361. }
  362. //
  363. // Was it was all delimiters?
  364. //
  365. if( *str == '\0' ) {
  366. str = NULL;
  367. return NULL;
  368. }
  369. //
  370. // We've got a string, terminate it at first delimeter
  371. //
  372. for( p = str+1; *p; p++ ) {
  373. for( s = control; *s; s++ ) {
  374. if( *p == *s ) {
  375. s = str;
  376. *p = '\0';
  377. str = p+1;
  378. return s;
  379. }
  380. }
  381. }
  382. //
  383. // We've got a string that ends with the NULL
  384. //
  385. s = str;
  386. str = NULL;
  387. return s;
  388. }
  389. DECLARE_API( help )
  390. {
  391. dprintf("NDIS extensions:\n");
  392. dprintf(" ndis dump ndis information\n");
  393. dprintf(" dbglevel [Level [Level] ...] toggle debug level\n");
  394. dprintf(" dbgsystems [Level [Level] ...] toggle debug systems\n");
  395. dprintf(" miniports <'all'> list all Miniports\n");
  396. dprintf(" gminiports <'all'> list all Miniports, even those not started yet\n");
  397. dprintf(" miniport <Miniport Block> dump Miniport block\n");
  398. dprintf(" mopen <Miniport Open Block> dump Miniport Open block\n");
  399. dprintf(" protocols dump all protocols and their opens\n");
  400. dprintf(" protocol <Protocol Block> dump the protocols block's contents\n");
  401. dprintf(" pkt <Packet> <Verbosity> dump the contents of the packet\n");
  402. dprintf(" pktpools list all allocated packet pools\n");
  403. dprintf(" mem list log of allocated memory if enabled\n");
  404. dprintf(" opens dump all opens\n");
  405. dprintf(" findpacket v <VirtualAddress> finds a packet containing a virtual address\n");
  406. dprintf(" findpacket p <PoolAddress> finds un-returned packets in a pool\n");
  407. }
  408. VOID
  409. ErrorCheckSymbols(
  410. CHAR *symbol
  411. )
  412. {
  413. dprintf("NDISKD: error - could not access %s - check symbols for ndis.sys\n",
  414. symbol);
  415. }
  416. DECLARE_API( dbglevel )
  417. {
  418. INT i;
  419. INT col = 0;
  420. ULONG DbgSettings;
  421. CHAR argbuf[ MAX_PATH ];
  422. CHAR *p;
  423. ULONG64 dwAddress;
  424. DWORD Written;
  425. dwAddress = GetExpression("ndis!ndisDebugLevel");
  426. if (dwAddress == 0)
  427. {
  428. ErrorCheckSymbols("ndis!ndisDebugLevel");
  429. return;
  430. }
  431. DbgSettings = GetUlongFromAddress(dwAddress);
  432. if (!args || !*args)
  433. {
  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!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 = sizeof(ULONG) ; // sizeof(ULONG) is same across all platforms
  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!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 AfFlags;
  1343. ULONG Refs;
  1344. ULONG64 AfOpenAddr;
  1345. ULONG64 AfProtocolAddr;
  1346. if (CheckControlC())
  1347. {
  1348. break;
  1349. }
  1350. GetFieldValue(AfAddr, NDIS_CO_AF_BLOCK_NAME, "Flags", AfFlags);
  1351. GetFieldValue(AfAddr, NDIS_CO_AF_BLOCK_NAME, "References", Refs);
  1352. dprintf(" Af Block %p, Flags %08x, References %d\n", AfAddr, AfFlags, Refs);
  1353. //
  1354. // Client open values:
  1355. //
  1356. GetFieldValue(AfAddr, NDIS_CO_AF_BLOCK_NAME, "ClientOpen", AfOpenAddr);
  1357. dprintf(" Client Open %p : ", AfOpenAddr);
  1358. GetFieldValue(AfOpenAddr, NDIS_COMMON_OPEN_BLOCK_NAME, "ProtocolHandle", AfProtocolAddr);
  1359. if (GetFieldOffset(NDIS_PROTOCOL_BLOCK_NAME, "ProtocolCharacteristics.Name", &Offset) != 0)
  1360. {
  1361. dprintf("Cant get offset of Name in Protocol block!");
  1362. }
  1363. else
  1364. {
  1365. PrintName(AfProtocolAddr + Offset);
  1366. }
  1367. GetFieldValue(AfAddr, NDIS_CO_AF_BLOCK_NAME, "ClientContext", Val);
  1368. dprintf(", CL AFContext %p\n", Val);
  1369. //
  1370. // Call Mgr open values:
  1371. //
  1372. GetFieldValue(AfAddr, NDIS_CO_AF_BLOCK_NAME, "CallMgrOpen", AfOpenAddr);
  1373. dprintf(" CallMgr Open %p : ", AfOpenAddr);
  1374. GetFieldValue(AfOpenAddr, NDIS_COMMON_OPEN_BLOCK_NAME, "ProtocolHandle", AfProtocolAddr);
  1375. PrintName(AfProtocolAddr + Offset);
  1376. GetFieldValue(AfAddr, NDIS_CO_AF_BLOCK_NAME, "CallMgrContext", Val);
  1377. dprintf(", CM AFContext %p\n", Val);
  1378. GetFieldValue(AfAddr, NDIS_CO_AF_BLOCK_NAME, "NextAf", AfAddr);
  1379. }
  1380. //
  1381. // If there are any VCs in the active VC list, display them.
  1382. //
  1383. //
  1384. // First, get some offsets.
  1385. //
  1386. if (GetFieldOffset(NDIS_CO_VC_PTR_BLOCK_NAME, "ClientLink", &ClientLinkOffset) != 0)
  1387. {
  1388. dprintf("Can't get offset of ClientLink in NDIS_CO_VC_PTR_BLOCK!\n");
  1389. return;
  1390. }
  1391. if (GetFieldOffset(NDIS_CO_VC_PTR_BLOCK_NAME, "CallMgrLink", &CallMgrLinkOffset) != 0)
  1392. {
  1393. dprintf("Can't get offset of CallMgrLink in NDIS_CO_VC_PTR_BLOCK!\n");
  1394. return;
  1395. }
  1396. if (GetFieldOffset(NDIS_OPEN_BLOCK_NAME, "ActiveVcHead", &Offset) != 0)
  1397. {
  1398. dprintf("Can't get offset of ActiveVcHead in NDIS_OPEN_BLOCK!\n");
  1399. return;
  1400. }
  1401. VcHeadAddr = OpenAddr + Offset;
  1402. GetFieldValue(OpenAddr, NDIS_OPEN_BLOCK_NAME, "ActiveVcHead.Flink", VcPtrAddr);
  1403. if (VcPtrAddr != VcHeadAddr)
  1404. {
  1405. dprintf("\n Active VC list:\n");
  1406. }
  1407. bPrintingActiveVcs = TRUE;
  1408. Again:
  1409. VcCount = 0;
  1410. while (VcPtrAddr != VcHeadAddr)
  1411. {
  1412. if (CheckControlC())
  1413. {
  1414. break;
  1415. }
  1416. if (VcCount++ == 2000)
  1417. {
  1418. // something wrong?
  1419. dprintf("Too many VCs (%d), bailing out!\n", VcCount);
  1420. break;
  1421. }
  1422. if (bPrintingActiveVcs)
  1423. {
  1424. VcPtrAddr -= ClientLinkOffset;
  1425. }
  1426. else
  1427. {
  1428. if (fClientOpen)
  1429. {
  1430. VcPtrAddr -= ClientLinkOffset;
  1431. }
  1432. else
  1433. {
  1434. VcPtrAddr -= CallMgrLinkOffset;
  1435. }
  1436. }
  1437. PrintVcPtrBlock(VcPtrAddr);
  1438. if (bPrintingActiveVcs)
  1439. {
  1440. GetFieldValue(VcPtrAddr, NDIS_CO_VC_PTR_BLOCK_NAME, "ClientLink.Flink", VcPtrAddr);
  1441. }
  1442. else
  1443. {
  1444. if (fClientOpen)
  1445. GetFieldValue(VcPtrAddr, NDIS_CO_VC_PTR_BLOCK_NAME, "ClientLink.Flink", VcPtrAddr);
  1446. else
  1447. GetFieldValue(VcPtrAddr, NDIS_CO_VC_PTR_BLOCK_NAME, "CallMgrLink.Flink", VcPtrAddr);
  1448. }
  1449. }
  1450. if (bPrintingActiveVcs)
  1451. {
  1452. bPrintingActiveVcs = FALSE;
  1453. //
  1454. // If there are any VCs in the inactive VC list, display them.
  1455. //
  1456. if (GetFieldOffset(NDIS_OPEN_BLOCK_NAME, "InactiveVcHead", &Offset) != 0)
  1457. {
  1458. dprintf("Can't get offset of InActiveVcHead in NDIS_OPEN_BLOCK!\n");
  1459. return;
  1460. }
  1461. VcHeadAddr = OpenAddr + Offset;
  1462. GetFieldValue(OpenAddr, NDIS_OPEN_BLOCK_NAME, "InactiveVcHead.Flink", VcPtrAddr);
  1463. if (VcPtrAddr != VcHeadAddr)
  1464. {
  1465. dprintf("\n Inactive VC list:\n");
  1466. goto Again;
  1467. }
  1468. }
  1469. return;
  1470. }
  1471. DECLARE_API( vc )
  1472. {
  1473. ULONG64 VcPtrAddr;
  1474. ULONG64 ClientOpen, CallMgrOpen, AfBlock, Miniport;
  1475. if (!args || !*args)
  1476. {
  1477. dprintf("Usage: vc <pointer to VC pointer block>\n");
  1478. return;
  1479. }
  1480. VcPtrAddr = GetExpression(args);
  1481. PrintVcPtrBlock(VcPtrAddr);
  1482. //
  1483. // For some reason, InitTypeRead(NDIS_CO_VC_PTR_BLOCK_NAME) followed
  1484. // by ReadField() didn't work - we get all 0's.
  1485. //
  1486. GetFieldValue(VcPtrAddr, NDIS_CO_VC_PTR_BLOCK_NAME, "ClientOpen", ClientOpen);
  1487. GetFieldValue(VcPtrAddr, NDIS_CO_VC_PTR_BLOCK_NAME, "CallMgrOpen", CallMgrOpen);
  1488. GetFieldValue(VcPtrAddr, NDIS_CO_VC_PTR_BLOCK_NAME, "AfBlock", AfBlock);
  1489. GetFieldValue(VcPtrAddr, NDIS_CO_VC_PTR_BLOCK_NAME, "Miniport", Miniport);
  1490. dprintf(" ClientOpen %p CallMgrOpen %p AfBlock %p Miniport %p\n",
  1491. ClientOpen,
  1492. CallMgrOpen,
  1493. AfBlock,
  1494. Miniport);
  1495. }
  1496. VOID
  1497. PrintProtocolOpenQueue(
  1498. ULONG64 ProtocolAddr)
  1499. {
  1500. ULONG64 OpenAddr;
  1501. ULONG64 MiniportHandle;
  1502. ULONG64 MiniportAddr;
  1503. ULONG64 Val;
  1504. GetFieldValue(ProtocolAddr, NDIS_PROTOCOL_BLOCK_NAME, "OpenQueue", OpenAddr);
  1505. while (OpenAddr != 0)
  1506. {
  1507. GetFieldValue(OpenAddr, NDIS_COMMON_OPEN_BLOCK_NAME, "MiniportHandle", MiniportAddr);
  1508. GetFieldValue(OpenAddr, NDIS_COMMON_OPEN_BLOCK_NAME, "ProtocolNextOpen", Val);
  1509. dprintf(" Open %p - ", OpenAddr);
  1510. dprintf("Miniport: %p ", MiniportAddr);
  1511. PrintMiniportName(MiniportAddr);
  1512. dprintf("\n");
  1513. OpenAddr = Val;
  1514. }
  1515. dprintf("\n");
  1516. }
  1517. VOID
  1518. PrintVcPtrBlock(
  1519. IN ULONG64 VcPtrAddr)
  1520. {
  1521. ULONG64 VcBlockAddr;
  1522. ULONG64 ClientContext, CallMgrContext, MiniportContext;
  1523. ULONG Flags;
  1524. ULONG VcFlags;
  1525. INT i, j;
  1526. GetFieldValue(VcPtrAddr, NDIS_CO_VC_PTR_BLOCK_NAME, "CallFlags", Flags);
  1527. GetFieldValue(VcPtrAddr, NDIS_CO_VC_PTR_BLOCK_NAME, "ClientContext", ClientContext);
  1528. GetFieldValue(VcPtrAddr, NDIS_CO_VC_PTR_BLOCK_NAME, "CallMgrContext", CallMgrContext);
  1529. GetFieldValue(VcPtrAddr, NDIS_CO_VC_PTR_BLOCK_NAME, "MiniportContext", MiniportContext);
  1530. dprintf(" VcPtr %p, Contexts: Cl %p, CM %p, MP %p, CallFlags %08x\n",
  1531. VcPtrAddr,
  1532. ClientContext,
  1533. CallMgrContext,
  1534. MiniportContext,
  1535. Flags);
  1536. j = 0;
  1537. for (i = 0; i < sizeof(DbgVcPtrFlags)/sizeof(DBG_VC_FLAGS); i++)
  1538. {
  1539. if (Flags & DbgVcPtrFlags[i].Val)
  1540. {
  1541. if (j == 0)
  1542. {
  1543. dprintf(" ");
  1544. }
  1545. dprintf("%s", DbgVcPtrFlags[i].Name);
  1546. j++;
  1547. if (j != MAX_FLAGS_PER_LINE)
  1548. {
  1549. dprintf(", ");
  1550. }
  1551. else
  1552. {
  1553. dprintf("\n");
  1554. j = 0;
  1555. }
  1556. }
  1557. }
  1558. if (j != 0)
  1559. {
  1560. dprintf("\n");
  1561. }
  1562. GetFieldValue(VcPtrAddr, NDIS_CO_VC_PTR_BLOCK_NAME, "VcBlock", VcBlockAddr);
  1563. if (VcBlockAddr != 0)
  1564. {
  1565. GetFieldValue(VcBlockAddr, NDIS_CO_VC_BLOCK_NAME, "Flags", VcFlags);
  1566. dprintf(" VcBlock %p, Flags %08x\n", VcBlockAddr, VcFlags);
  1567. j = 0;
  1568. for (i = 0; i < sizeof(DbgVcFlags)/sizeof(DBG_VC_FLAGS); i++)
  1569. {
  1570. if (VcFlags & DbgVcFlags[i].Val)
  1571. {
  1572. if (j == 0)
  1573. {
  1574. dprintf(" ");
  1575. }
  1576. dprintf("%s", DbgVcFlags[i].Name);
  1577. j++;
  1578. if (j != MAX_FLAGS_PER_LINE)
  1579. {
  1580. dprintf(", ");
  1581. }
  1582. else
  1583. {
  1584. dprintf("\n");
  1585. j = 0;
  1586. }
  1587. }
  1588. }
  1589. if (j != 0)
  1590. {
  1591. dprintf("\n");
  1592. }
  1593. }
  1594. }
  1595. DECLARE_API( protocols )
  1596. {
  1597. ULONG64 ProtocolListAddr;
  1598. ULONG64 ProtocolAddr;
  1599. ULONG Offset;
  1600. ProtocolListAddr = GetExpression("ndis!ndisProtocolList");
  1601. ProtocolAddr = GetPointerFromAddress(ProtocolListAddr);
  1602. while (ProtocolAddr != 0)
  1603. {
  1604. if (CheckControlC())
  1605. {
  1606. break;
  1607. }
  1608. dprintf(" Protocol %p: ", ProtocolAddr);
  1609. if (GetFieldOffset(NDIS_PROTOCOL_BLOCK_NAME, "ProtocolCharacteristics.Name", &Offset) != 0)
  1610. {
  1611. dprintf("Cant get offset of Name in Protocol block!");
  1612. }
  1613. else
  1614. {
  1615. PrintName(ProtocolAddr + Offset);
  1616. }
  1617. dprintf("\n");
  1618. PrintProtocolOpenQueue(ProtocolAddr);
  1619. GetFieldValue(ProtocolAddr, NDIS_PROTOCOL_BLOCK_NAME, "NextProtocol", ProtocolAddr);
  1620. }
  1621. }
  1622. VOID
  1623. PrintNdisBuffer(
  1624. ULONG64 BufferAddr
  1625. )
  1626. {
  1627. ULONG64 Val1;
  1628. ULONG64 Val2;
  1629. dprintf("NDIS_BUFFER at %p\n", BufferAddr);
  1630. GetFieldValue(BufferAddr, NDIS_BUFFER_NAME, "Next", Val1);
  1631. GetFieldValue(BufferAddr, NDIS_BUFFER_NAME, "Size", Val2);
  1632. dprintf(" Next %p\n Size %x\n", Val1, (ULONG)Val2);
  1633. GetFieldValue(BufferAddr, NDIS_BUFFER_NAME, "MdlFlags", Val1);
  1634. GetFieldValue(BufferAddr, NDIS_BUFFER_NAME, "Process", Val2);
  1635. dprintf(" MdlFlags %x\n Process %p\n", (ULONG)Val1, Val2);
  1636. GetFieldValue(BufferAddr, NDIS_BUFFER_NAME, "MappedSystemVa", Val1);
  1637. GetFieldValue(BufferAddr, NDIS_BUFFER_NAME, "StartVa", Val2);
  1638. dprintf(" MappedSystemVa %p\n Start VA %p\n", Val1, Val2);
  1639. GetFieldValue(BufferAddr, NDIS_BUFFER_NAME, "ByteCount", Val1);
  1640. GetFieldValue(BufferAddr, NDIS_BUFFER_NAME, "ByteOffset", Val2);
  1641. dprintf(" ByteCount %x\n ByteOffset %x\n", (ULONG)Val1, (ULONG)Val2);
  1642. }
  1643. // Verbosity for packet display:
  1644. // 1. Print Packet.Private
  1645. // 2. Print NdisPacketExtension
  1646. // 3. Print NDIS_PACKET_REFERENCE
  1647. // 4. Print NDIS_BUFFER_LIST
  1648. //
  1649. DECLARE_API( pkt )
  1650. {
  1651. ULONG64 PacketAddr;
  1652. INT Verbosity;
  1653. CHAR argbuf[ MAX_PATH ];
  1654. CHAR arglist[10][MAX_PATH];
  1655. CHAR *str;
  1656. INT index=0;
  1657. CHAR *p;
  1658. if (!args || !*args)
  1659. {
  1660. dprintf("Usage: Packet <pointer to packet> <verbosity>\n");
  1661. return;
  1662. }
  1663. PacketAddr = GetExpression(args);
  1664. strcpy(argbuf,args);
  1665. for (p = mystrtok( argbuf, " \t,;" );
  1666. p && *p;
  1667. p = mystrtok(NULL, " \t,;"))
  1668. {
  1669. strcpy(&arglist[index++][0],p);
  1670. }
  1671. Verbosity = atoi(&arglist[1][0]);
  1672. if (index>2 || Verbosity>4)
  1673. {
  1674. dprintf("Usage: pkt <pointer to packet> <verbosity>\n");
  1675. dprintf("1-Packet Private, 2-Packet Extension\n");
  1676. dprintf("3-Ndis Reference, 4-Buffer List\n");
  1677. return;
  1678. }
  1679. dprintf("NDIS_PACKET at %p\n", PacketAddr);
  1680. switch(Verbosity)
  1681. {
  1682. case 4:
  1683. PrintNdisBufferList(PacketAddr);
  1684. // FALLTHRU
  1685. case 3:
  1686. PrintNdisReserved(PacketAddr);
  1687. // FALLTHRU
  1688. case 2:
  1689. PrintNdisPacketExtension(PacketAddr);
  1690. // FALLTHRU
  1691. case 1:
  1692. default:
  1693. PrintNdisPacketPrivate(PacketAddr);
  1694. break;
  1695. }
  1696. }
  1697. VOID
  1698. PrintPacketPrivateFlags(
  1699. ULONG64 PacketAddr
  1700. )
  1701. {
  1702. ULONG NdisPacketFlags;
  1703. ULONG i;
  1704. ULONG j;
  1705. ULONG Flags;
  1706. #define MAX_FLAGS_PER_LINE 3
  1707. GetFieldValue(PacketAddr, NDIS_PACKET_NAME, "Private.Flags", Flags);
  1708. //
  1709. // Prints Flags and NdisPacketFlags
  1710. //
  1711. dprintf("\n ");
  1712. dprintf(" Private.Flags : %08x\n", Flags);
  1713. j = 0;
  1714. for (i = 0; i < sizeof(DbgPacketFlags)/sizeof(DBG_PACKET_FLAGS); i++)
  1715. {
  1716. if (Flags & DbgPacketFlags[i].Val)
  1717. {
  1718. if (j == 0)
  1719. {
  1720. dprintf(" ");
  1721. }
  1722. dprintf("%s", DbgPacketFlags[i].Name);
  1723. j++;
  1724. if (j != MAX_FLAGS_PER_LINE)
  1725. {
  1726. dprintf(", ");
  1727. }
  1728. else
  1729. {
  1730. dprintf("\n");
  1731. j = 0;
  1732. }
  1733. }
  1734. }
  1735. if (j != 0)
  1736. {
  1737. dprintf("\n");
  1738. }
  1739. GetFieldValue(PacketAddr, NDIS_PACKET_NAME, "Private.NdisPacketFlags", NdisPacketFlags);
  1740. dprintf(" ");
  1741. dprintf(" Private.NdisPacketFlags: %01x\n", NdisPacketFlags);
  1742. j = 0;
  1743. for (i = 0; i < sizeof(DbgNdisPacketFlags)/sizeof(DBG_PACKET_FLAGS); i++)
  1744. {
  1745. if (NdisPacketFlags & DbgNdisPacketFlags[i].Val)
  1746. {
  1747. if (j == 0)
  1748. {
  1749. dprintf(" ");
  1750. }
  1751. dprintf("%s", DbgNdisPacketFlags[i].Name);
  1752. j++;
  1753. if (j != MAX_FLAGS_PER_LINE)
  1754. {
  1755. dprintf(", ");
  1756. }
  1757. else
  1758. {
  1759. dprintf("\n");
  1760. j = 0;
  1761. }
  1762. }
  1763. }
  1764. if (j != 0)
  1765. {
  1766. dprintf("\n");
  1767. }
  1768. }
  1769. VOID
  1770. PrintNdisPacketPrivate(
  1771. ULONG64 PacketAddr
  1772. )
  1773. {
  1774. ULONG64 Val1, Val2;
  1775. ULONG64 Addr1, Addr2;
  1776. dprintf("\nPacket.Private\n");
  1777. InitTypeRead(PacketAddr, ndis!NDIS_PACKET);
  1778. Val1 = ReadField(Private.PhysicalCount);
  1779. Val2 = ReadField(Private.TotalLength);
  1780. dprintf(" PhysicalCount %.8d Total Length %.8x\n",
  1781. (ULONG)Val1, (ULONG)Val2);
  1782. Addr1 = ReadField(Private.Head);
  1783. Addr2 = ReadField(Private.Tail);
  1784. dprintf(" Head %p Tail %p\n", Addr1, Addr2);
  1785. Addr1 = ReadField(Private.Pool);
  1786. Val1 = (UINT)ReadField(Private.Count);
  1787. dprintf(" Pool %p Count %p\n", Addr1, Val1);
  1788. Val1 = ReadField(Private.Flags);
  1789. Val2 = (BOOLEAN)ReadField(Private.ValidCounts);
  1790. dprintf(" Flags %08x ValidCounts %.2x\n", (ULONG)Val1, (BOOLEAN)Val2);
  1791. Val1 = (UCHAR)ReadField(Private.NdisPacketFlags);
  1792. Val2 = (USHORT)ReadField(Private.NdisPacketOobOffset);
  1793. dprintf(" NdisPacketFlags %08x NdisPacketOobOffset %.4x\n", (UCHAR)Val1, (USHORT)Val2);
  1794. PrintPacketPrivateFlags (PacketAddr);
  1795. }
  1796. VOID
  1797. PrintNdisPacketExtension(
  1798. ULONG64 PacketAddr
  1799. )
  1800. {
  1801. ULONG64 PacketExtensionAddr;
  1802. ULONG PtrSize;
  1803. UINT i;
  1804. USHORT OobOffset;
  1805. GetFieldValue(PacketAddr, NDIS_PACKET_NAME, "Private.NdisPacketOobOffset", OobOffset);
  1806. PacketExtensionAddr = PacketAddr + OobOffset + GetTypeSize(NDIS_PACKET_OOB_DATA_NAME);
  1807. PtrSize = IsPtr64() ? 8 : 4;
  1808. for (i = 0; i < MaxPerPacketInfo; i++)
  1809. {
  1810. dprintf(" %d. %s = %p\n",
  1811. i, DbgPacketInfoIdTypes[i].Name, GetPointerFromAddress(PacketExtensionAddr));
  1812. PacketExtensionAddr += PtrSize;
  1813. }
  1814. }
  1815. VOID
  1816. PrintNdisBufferList(
  1817. ULONG64 PacketAddr
  1818. )
  1819. {
  1820. ULONG64 BufAddr;
  1821. ULONG64 TailAddr;
  1822. GetFieldValue(PacketAddr, NDIS_PACKET_NAME, "Private.Head", BufAddr);
  1823. GetFieldValue(PacketAddr, NDIS_PACKET_NAME, "Private.Tail", TailAddr);
  1824. while (BufAddr != 0)
  1825. {
  1826. if (CheckControlC())
  1827. {
  1828. break;
  1829. }
  1830. PrintNdisBuffer(BufAddr);
  1831. if (BufAddr == TailAddr)
  1832. {
  1833. break;
  1834. }
  1835. GetFieldValue(BufAddr, NDIS_BUFFER_NAME, "Next", BufAddr);
  1836. }
  1837. }
  1838. VOID
  1839. PrintNdisReserved(
  1840. ULONG64 PacketAddr
  1841. )
  1842. {
  1843. ULONG Offset;
  1844. ULONG Size;
  1845. ULONG64 EntryAddr;
  1846. ULONG64 EntryVal;
  1847. ULONG NumEntries;
  1848. ULONG EntrySize;
  1849. ULONG i;
  1850. if (GetFieldOffsetAndSize(NDIS_PACKET_NAME, "MacReserved", &Offset, &Size) != 0)
  1851. {
  1852. dprintf("Can't get offset of MacReserved in %s!\n", NDIS_PACKET_NAME);
  1853. return;
  1854. }
  1855. EntrySize = IsPtr64() ? 8 : 4;
  1856. NumEntries = Size / EntrySize;
  1857. EntryAddr = PacketAddr + Offset;
  1858. dprintf("MacReserved[]:");
  1859. for (i = 0; i < NumEntries; i++)
  1860. {
  1861. EntryVal = GetPointerFromAddress(EntryAddr);
  1862. dprintf(" %p ", EntryVal);
  1863. EntryAddr += EntrySize;
  1864. }
  1865. dprintf("\n");
  1866. }
  1867. VOID
  1868. PrintProtocolDetails(
  1869. ULONG64 ProtocolAddr
  1870. )
  1871. {
  1872. ULONG64 NameAddr;
  1873. ULONG64 ProtocolCharsAddr;
  1874. ULONG64 Val1, Val2;
  1875. ULONG Val;
  1876. ULONG Offset;
  1877. GetFieldValue(ProtocolAddr, NDIS_PROTOCOL_BLOCK_NAME, "BindDeviceName", NameAddr);
  1878. if (NameAddr != 0)
  1879. {
  1880. dprintf(" BindDeviceName is ");
  1881. PrintName(NameAddr);
  1882. dprintf("\n");
  1883. }
  1884. GetFieldValue(ProtocolAddr, NDIS_PROTOCOL_BLOCK_NAME, "RootDeviceName", NameAddr);
  1885. if (NameAddr != 0)
  1886. {
  1887. dprintf(" RootDeviceName is ");
  1888. PrintName(NameAddr);
  1889. dprintf("\n");
  1890. }
  1891. GetFieldValue(ProtocolAddr, NDIS_PROTOCOL_BLOCK_NAME, "Ref.ReferenceCount", Val);
  1892. dprintf(" RefCount %d\n", Val);
  1893. dprintf("\n");
  1894. //
  1895. // Walk the Open Block Queue
  1896. //
  1897. PrintProtocolOpenQueue(ProtocolAddr);
  1898. if (GetFieldOffset(NDIS_PROTOCOL_BLOCK_NAME, "ProtocolCharacteristics", &Offset) != 0)
  1899. {
  1900. dprintf("Can't get offset of ProtocolCharacteristics in %s\n",
  1901. NDIS_PROTOCOL_BLOCK_NAME);
  1902. return;
  1903. }
  1904. ProtocolCharsAddr = ProtocolAddr + Offset;
  1905. //
  1906. // Addresses of handlers.
  1907. //
  1908. GetFieldValue(ProtocolCharsAddr, NDIS_PROTOCOL_CHARACTERISTICS_NAME,
  1909. "BindAdapterHandler", Val1);
  1910. GetFieldValue(ProtocolCharsAddr, NDIS_PROTOCOL_CHARACTERISTICS_NAME,
  1911. "UnbindAdapterHandler", Val2);
  1912. dprintf(" BindAdapterHandler %p, UnbindAdapterHandler %p\n", Val1, Val2);
  1913. GetFieldValue(ProtocolCharsAddr, NDIS_PROTOCOL_CHARACTERISTICS_NAME,
  1914. "PnPEventHandler", Val1);
  1915. GetFieldValue(ProtocolCharsAddr, NDIS_PROTOCOL_CHARACTERISTICS_NAME,
  1916. "UnloadHandler", Val2);
  1917. dprintf(" PnPEventHandler %p, UnloadHandler %p\n", Val1, Val2);
  1918. GetFieldValue(ProtocolCharsAddr, NDIS_PROTOCOL_CHARACTERISTICS_NAME,
  1919. "OpenAdapterCompleteHandler", Val1);
  1920. GetFieldValue(ProtocolCharsAddr, NDIS_PROTOCOL_CHARACTERISTICS_NAME,
  1921. "CloseAdapterCompleteHandler", Val2);
  1922. dprintf(" OpenAdapterComplete %p, CloseAdapterComplete %p\n", Val1, Val2);
  1923. GetFieldValue(ProtocolCharsAddr, NDIS_PROTOCOL_CHARACTERISTICS_NAME,
  1924. "SendCompleteHandler", Val1);
  1925. GetFieldValue(ProtocolCharsAddr, NDIS_PROTOCOL_CHARACTERISTICS_NAME,
  1926. "TransferDataCompleteHandler", Val2);
  1927. dprintf(" SendCompleteHandler %p, TransferDataComplete %p\n", Val1, Val2);
  1928. GetFieldValue(ProtocolCharsAddr, NDIS_PROTOCOL_CHARACTERISTICS_NAME,
  1929. "ReceiveHandler", Val1);
  1930. GetFieldValue(ProtocolCharsAddr, NDIS_PROTOCOL_CHARACTERISTICS_NAME,
  1931. "ReceivePacketHandler", Val2);
  1932. dprintf(" ReceiveHandler %p, ReceivePacketHandler %p\n", Val1, Val2);
  1933. GetFieldValue(ProtocolCharsAddr, NDIS_PROTOCOL_CHARACTERISTICS_NAME,
  1934. "ReceiveCompleteHandler", Val1);
  1935. GetFieldValue(ProtocolCharsAddr, NDIS_PROTOCOL_CHARACTERISTICS_NAME,
  1936. "StatusHandler", Val2);
  1937. dprintf(" ReceiveComplete %p, StatusHandler %p\n", Val1, Val2);
  1938. GetFieldValue(ProtocolCharsAddr, NDIS_PROTOCOL_CHARACTERISTICS_NAME,
  1939. "StatusCompleteHandler", Val1);
  1940. dprintf(" StatusComplete %p\n", Val1);
  1941. GetFieldValue(ProtocolCharsAddr, NDIS_PROTOCOL_CHARACTERISTICS_NAME,
  1942. "AssociatedMiniDriver", Val1);
  1943. dprintf(" AssociatedMiniDriver %p\n", Val1);
  1944. {
  1945. ULONG i;
  1946. ULONG j;
  1947. ULONG Flags;
  1948. #define MAX_FLAGS_PER_LINE 3
  1949. dprintf("\n ");
  1950. GetFieldValue(ProtocolCharsAddr, NDIS_PROTOCOL_CHARACTERISTICS_NAME,
  1951. "Flags", Val1);
  1952. Flags = (ULONG)Val1;
  1953. dprintf(" Flags : %08x\n", Flags);
  1954. j = 0;
  1955. for (i = 0; i < sizeof(DbgProtocolFlags)/sizeof(DBG_PROTOCOL_FLAGS ); i++)
  1956. {
  1957. if (Flags & DbgProtocolFlags[i].Val)
  1958. {
  1959. if (j == 0)
  1960. {
  1961. dprintf(" ");
  1962. }
  1963. dprintf("%s", DbgProtocolFlags[i].Name);
  1964. j++;
  1965. if (j != MAX_FLAGS_PER_LINE)
  1966. {
  1967. dprintf(", ");
  1968. }
  1969. else
  1970. {
  1971. dprintf("\n");
  1972. j = 0;
  1973. }
  1974. }
  1975. }
  1976. if (j != 0)
  1977. {
  1978. dprintf("\n");
  1979. }
  1980. }
  1981. }
  1982. DECLARE_API( protocol )
  1983. {
  1984. ULONG64 ProtocolAddr;
  1985. ULONG Offset;
  1986. //
  1987. // Verify if any args are present
  1988. //
  1989. if (!args || !*args)
  1990. {
  1991. dprintf("Usage: protocol <pointer to protocol block>\n");
  1992. return;
  1993. }
  1994. ProtocolAddr = GetExpression(args);
  1995. dprintf(" Protocol %p : ", ProtocolAddr);
  1996. if (GetFieldOffset(NDIS_PROTOCOL_BLOCK_NAME, "ProtocolCharacteristics.Name", &Offset) != 0)
  1997. {
  1998. dprintf("Can't get offset of Name in Protocol block!");
  1999. }
  2000. else
  2001. {
  2002. PrintName(ProtocolAddr + Offset);
  2003. }
  2004. dprintf("\n");
  2005. PrintProtocolDetails(ProtocolAddr);
  2006. }
  2007. /**
  2008. Routine to get offset and size of a "Field" of "Type" on a debugee machine. This uses
  2009. Ioctl call for type info.
  2010. Returns 0 on success, Ioctl error value otherwise.
  2011. **/
  2012. ULONG GetFieldOffsetAndSize(
  2013. IN LPSTR Type,
  2014. IN LPSTR Field,
  2015. OUT PULONG pOffset,
  2016. OUT PULONG pSize)
  2017. {
  2018. FIELD_INFO flds = {
  2019. Field, "", 0,
  2020. DBG_DUMP_FIELD_FULL_NAME | DBG_DUMP_FIELD_RETURN_ADDRESS,
  2021. 0, NULL};
  2022. SYM_DUMP_PARAM Sym = {
  2023. sizeof (SYM_DUMP_PARAM), Type, DBG_DUMP_NO_PRINT, 0,
  2024. NULL, NULL, NULL, 1, &flds
  2025. };
  2026. ULONG Err, i=0;
  2027. LPSTR dot, last=Field;
  2028. Sym.nFields = 1;
  2029. Err = Ioctl( IG_DUMP_SYMBOL_INFO, &Sym, Sym.size );
  2030. *pOffset = (ULONG) (flds.address - Sym.addr);
  2031. *pSize = flds.size;
  2032. return Err;
  2033. }
  2034. ULONG GetUlongFromAddress (
  2035. ULONG64 Location)
  2036. {
  2037. ULONG Value;
  2038. ULONG result;
  2039. if ((!ReadMemory(Location,&Value,sizeof(ULONG),&result)) ||
  2040. (result < sizeof(ULONG))) {
  2041. dprintf("unable to read from %08x\n",Location);
  2042. return 0;
  2043. }
  2044. return Value;
  2045. }
  2046. ULONG64 GetPointerFromAddress(
  2047. ULONG64 Location)
  2048. {
  2049. ULONG64 Value;
  2050. ULONG result;
  2051. if (!ReadPointer(Location,&Value))
  2052. {
  2053. dprintf("unable to read from %p\n",Location);
  2054. return 0;
  2055. }
  2056. return Value;
  2057. }
  2058. DECLARE_API(pktpools)
  2059. {
  2060. ULONG64 PoolListAddr;
  2061. ULONG64 LinkAddr;
  2062. ULONG64 Pool;
  2063. ULONG64 Allocator;
  2064. ULONG LinkOffset;
  2065. LONG BlocksAllocated;
  2066. ULONG BlockSize;
  2067. USHORT PacketLength;
  2068. USHORT PktsPerBlock;
  2069. PoolListAddr = GetExpression("ndis!ndisGlobalPacketPoolList");
  2070. if (PoolListAddr == 0)
  2071. {
  2072. ErrorCheckSymbols("ndis!ndisGlobalPacketPoolList");
  2073. return;
  2074. }
  2075. GetFieldValue(PoolListAddr, LIST_ENTRY_NAME, "Flink", LinkAddr);
  2076. //
  2077. // First, get some offsets.
  2078. //
  2079. if (GetFieldOffset(NDIS_PKT_POOL_NAME, "GlobalPacketPoolList", &LinkOffset) != 0)
  2080. {
  2081. dprintf("Can't get offset of GlobalPacketPoolList in NDIS_PKT_POOL!\n");
  2082. return;
  2083. }
  2084. dprintf("Pool Allocator BlocksAllocated BlockSize PktsPerBlock PacketLength\n");
  2085. while (LinkAddr != PoolListAddr)
  2086. {
  2087. if (CheckControlC())
  2088. {
  2089. break;
  2090. }
  2091. Pool = LinkAddr - LinkOffset;
  2092. GetFieldValue(Pool, NDIS_PKT_POOL_NAME, "Allocator", Allocator);
  2093. GetFieldValue(Pool, NDIS_PKT_POOL_NAME, "BlocksAllocated", BlocksAllocated);
  2094. GetFieldValue(Pool, NDIS_PKT_POOL_NAME, "BlockSize", BlockSize);
  2095. GetFieldValue(Pool, NDIS_PKT_POOL_NAME, "PktsPerBlock", PktsPerBlock);
  2096. GetFieldValue(Pool, NDIS_PKT_POOL_NAME, "PacketLength", PacketLength);
  2097. dprintf("%p %p 0x%lx\t 0x%lx\t 0x%lx\t 0x%lx\n", Pool,
  2098. Allocator,
  2099. BlocksAllocated,
  2100. BlockSize,
  2101. PktsPerBlock,
  2102. PacketLength);
  2103. GetFieldValue(Pool, NDIS_PKT_POOL_NAME, "GlobalPacketPoolList.Flink", LinkAddr);
  2104. if (LinkAddr == 0)
  2105. {
  2106. break;
  2107. }
  2108. }
  2109. }
  2110. /*
  2111. DECLARE_API(pktpool)
  2112. {
  2113. ULONG64 PktPoolAddr;
  2114. //
  2115. // Verify if any args are present
  2116. //
  2117. if (!args || !*args)
  2118. {
  2119. dprintf("Usage: pktpool <pointer to a Ndis packet pool>\n");
  2120. return;
  2121. }
  2122. PktPoolAddr = GetExpression(args);
  2123. dprintf(" Packet Pool %p : ", PktPoolAddr);
  2124. }
  2125. */
  2126. DECLARE_API(mem)
  2127. {
  2128. ULONG64 MiniportAddr, MiniBlockAddr;
  2129. ULONG64 Miniport, MiniBlock;
  2130. ULONG64 ListAddr;
  2131. ULONG64 LinkAddr;
  2132. ULONG64 TrackMem, Address, Caller, CallersCaller;
  2133. ULONG LinkOffset;
  2134. ULONG Tag;
  2135. UINT Length;
  2136. BOOLEAN Done;
  2137. do
  2138. {
  2139. MiniBlockAddr = GetExpression("ndis!ndisDriverTrackAlloc");
  2140. if (MiniBlockAddr == 0)
  2141. {
  2142. ErrorCheckSymbols("ndis!ndisDriverTrackAlloc");
  2143. break;
  2144. }
  2145. MiniportAddr = GetExpression("ndis!ndisMiniportTrackAlloc");
  2146. if (MiniportAddr == 0)
  2147. {
  2148. ErrorCheckSymbols("ndis!ndisMiniportTrackAlloc");
  2149. break;
  2150. }
  2151. //
  2152. // First, get some offsets.
  2153. //
  2154. if (GetFieldOffset(NDIS_TRACK_MEM_NAME, "List", &LinkOffset) != 0)
  2155. {
  2156. dprintf("Can't get offset of List in NDIS_TRACK_MEM!\n");
  2157. break;
  2158. }
  2159. ListAddr = GetExpression("ndis!ndisDriverTrackAllocList");
  2160. if (ListAddr == 0)
  2161. {
  2162. ErrorCheckSymbols("ndis!ndisDriverTrackAllocList");
  2163. break;
  2164. }
  2165. Done = FALSE;
  2166. MiniBlock = GetPointerFromAddress(MiniBlockAddr);
  2167. dprintf("Allocations charged to Miniport Driver Block at %p\n", MiniBlock);
  2168. again:
  2169. GetFieldValue(ListAddr, LIST_ENTRY_NAME, "Flink", LinkAddr);
  2170. dprintf("Address Tag Length Caller Caller'sCaller\n");
  2171. while (LinkAddr != ListAddr)
  2172. {
  2173. if (CheckControlC())
  2174. {
  2175. break;
  2176. }
  2177. TrackMem = (ULONG64)((PUCHAR)LinkAddr - LinkOffset);
  2178. Address = TrackMem + sizeof(NDIS_TRACK_MEM);
  2179. GetFieldValue(TrackMem, NDIS_TRACK_MEM_NAME, "Length", Length);
  2180. GetFieldValue(TrackMem, NDIS_TRACK_MEM_NAME, "Tag", Tag);
  2181. GetFieldValue(TrackMem, NDIS_TRACK_MEM_NAME, "Caller", Caller);
  2182. GetFieldValue(TrackMem, NDIS_TRACK_MEM_NAME, "CallersCaller", CallersCaller);
  2183. dprintf("%p %c%c%c%c %8lx %p %p\n",
  2184. Address,
  2185. Tag & 0xff,
  2186. (Tag >> 8) & 0xff,
  2187. (Tag >> 16) & 0xff,
  2188. (Tag >> 24) & 0xff,
  2189. Length, Caller, CallersCaller);
  2190. GetFieldValue(LinkAddr, NDIS_TRACK_MEM_NAME, "List.Flink", LinkAddr);
  2191. if (LinkAddr == 0)
  2192. {
  2193. break;
  2194. }
  2195. }
  2196. if (Done)
  2197. break;
  2198. Done = TRUE;
  2199. ListAddr = GetExpression("ndis!ndisMiniportTrackAllocList");
  2200. if (ListAddr == 0)
  2201. {
  2202. ErrorCheckSymbols("ndis!ndisMiniportTrackAllocList");
  2203. break;
  2204. }
  2205. Miniport = GetPointerFromAddress(MiniportAddr);
  2206. dprintf("\nAllocations charged to Miniport at %p\n", Miniport);
  2207. GetFieldValue(ListAddr, LIST_ENTRY_NAME, "Flink", LinkAddr);
  2208. goto again;
  2209. }while (FALSE);
  2210. }
  2211. DECLARE_API(ndis)
  2212. {
  2213. ULONG64 dwAddress;
  2214. ULONG CheckedVersion;
  2215. //
  2216. // get Ndis build date and time
  2217. //
  2218. dwAddress = GetExpression("ndis!ndisChecked");
  2219. if (dwAddress != 0)
  2220. {
  2221. CheckedVersion = GetUlongFromAddress(dwAddress);
  2222. if (CheckedVersion == 1)
  2223. dprintf("Checked");
  2224. else
  2225. dprintf("Free");
  2226. dprintf(" Ndis built on: ");
  2227. dwAddress = GetExpression("ndis!ndisBuildDate");
  2228. if (dwAddress != 0)
  2229. {
  2230. PrintName(dwAddress);
  2231. }
  2232. dprintf(", ");
  2233. dwAddress = GetExpression("ndis!ndisBuildTime");
  2234. if (dwAddress != 0)
  2235. {
  2236. PrintName(dwAddress);
  2237. }
  2238. dprintf(", by ");
  2239. dwAddress = GetExpression("ndis!ndisBuiltBy");
  2240. if (dwAddress != 0)
  2241. {
  2242. PrintName(dwAddress);
  2243. }
  2244. dprintf(".\n");
  2245. }
  2246. }
  2247. DECLARE_API(opens)
  2248. {
  2249. ULONG64 OpenListAddr;
  2250. ULONG64 OpenAddr;
  2251. ULONG64 ProtocolAddr;
  2252. ULONG64 MiniportAddr;
  2253. ULONG Offset;
  2254. OpenListAddr = GetExpression("ndis!ndisGlobalOpenList");
  2255. if (OpenListAddr == 0)
  2256. {
  2257. ErrorCheckSymbols("ndis!ndisGlobalOpenList");
  2258. return;
  2259. }
  2260. OpenAddr = GetPointerFromAddress(OpenListAddr);
  2261. if (GetFieldOffset(NDIS_PROTOCOL_BLOCK_NAME, "ProtocolCharacteristics.Name", &Offset) != 0)
  2262. {
  2263. dprintf("Cant get offset of Name in Protocol block!");
  2264. return;
  2265. }
  2266. while (OpenAddr != 0)
  2267. {
  2268. if (CheckControlC())
  2269. {
  2270. break;
  2271. }
  2272. GetFieldValue(OpenAddr, NDIS_COMMON_OPEN_BLOCK_NAME, "ProtocolHandle", ProtocolAddr);
  2273. GetFieldValue(OpenAddr, NDIS_COMMON_OPEN_BLOCK_NAME, "MiniportHandle", MiniportAddr);
  2274. dprintf(" Open %p \n", OpenAddr);
  2275. if (MiniportAddr)
  2276. {
  2277. dprintf(" Miniport: %p - ", MiniportAddr);
  2278. PrintMiniportName(MiniportAddr);
  2279. dprintf("\n");
  2280. }
  2281. if (ProtocolAddr)
  2282. {
  2283. dprintf(" Protocol: %p - ", ProtocolAddr);
  2284. PrintName(ProtocolAddr + Offset);
  2285. dprintf("\n");
  2286. }
  2287. dprintf("\n");
  2288. GetFieldValue(OpenAddr, NDIS_COMMON_OPEN_BLOCK_NAME, "NextGlobalOpen", OpenAddr);
  2289. }
  2290. }
  2291. /*++
  2292. Routine Desc:
  2293. This function searches one block for the packet with the
  2294. specified virtual address.
  2295. Argument:
  2296. CurBlock --- The starting of the searched block
  2297. CurPacket --- The first packet inside CurBlock to search
  2298. PktsPerBlock --- Number of packets inside the searched block
  2299. PacketStackSize --- The stack size inside the searched block
  2300. Flags --- 1: Free block to search
  2301. --- 0: Used block to search
  2302. Address --- The virtual address
  2303. PacketLength --- Packet length of the search block
  2304. BlockSize --- The size of the current block
  2305. Return Value:
  2306. True --- Packet found
  2307. False --- Packet not found
  2308. --*/
  2309. BOOL
  2310. SearchVaInOneBlock(
  2311. ULONG64 CurBlock,
  2312. ULONG PktsPerBlock,
  2313. ULONG PacketStackSize,
  2314. UCHAR Flags,
  2315. ULONG64 Address,
  2316. USHORT PacketLength,
  2317. ULONG BlockSize)
  2318. {
  2319. USHORT i;
  2320. UCHAR NdisPacketFlags;
  2321. ULONG64 TmpVal;
  2322. PVOID MappedSystemVa;
  2323. ULONG ByteCount;
  2324. ULONG64 pNdisBuf;
  2325. PUCHAR p;
  2326. ULONG64 CurPacket;
  2327. CurPacket = CurBlock + GetTypeSize(NDIS_PKT_POOL_HDR_NAME);
  2328. p = (PUCHAR)CurPacket;
  2329. for(i = 0; i < PktsPerBlock; i++, p += PacketLength)
  2330. {
  2331. if (CheckControlC())
  2332. {
  2333. break;
  2334. }
  2335. CurPacket = (ULONG64)(p + PacketStackSize);
  2336. //
  2337. // Flags = 1 means free blocks
  2338. //
  2339. if (Flags)
  2340. {
  2341. //
  2342. // skip the packet if it is not allocated, check for the flag
  2343. //
  2344. GetFieldValue(CurPacket, NDIS_PACKET_NAME,
  2345. "Private.NdisPacketFlags", NdisPacketFlags);
  2346. if ((NdisPacketFlags & fPACKET_ALLOCATED_BY_NDIS) == 0)
  2347. {
  2348. continue;
  2349. }
  2350. //
  2351. // For packets in the free list
  2352. //
  2353. GetFieldValue(CurPacket, NDIS_PACKET_NAME,
  2354. "Private.Head", pNdisBuf);
  2355. //
  2356. // PAGE_SIZE may not be BlockSize
  2357. //
  2358. if (pNdisBuf >= CurBlock && pNdisBuf < CurBlock + BlockSize)
  2359. {
  2360. continue;
  2361. }
  2362. }
  2363. //
  2364. // for each allocated packet, walk through all MDLs
  2365. //
  2366. GetFieldValue(CurPacket, NDIS_PACKET_NAME,
  2367. "Private.Head", pNdisBuf);
  2368. while(pNdisBuf)
  2369. {
  2370. GetFieldValue(pNdisBuf, NDIS_BUFFER_NAME,
  2371. "MappedSystemVa", TmpVal);
  2372. MappedSystemVa = (PVOID)TmpVal ;
  2373. GetFieldValue((ULONG64)pNdisBuf, NDIS_BUFFER_NAME,
  2374. "ByteCount", ByteCount);
  2375. if (Address >= (ULONG64)MappedSystemVa
  2376. && Address < (ULONG64)MappedSystemVa + ByteCount)
  2377. {
  2378. //
  2379. // Packet found, and print out the information about the packet
  2380. //
  2381. dprintf("\nPacket found\n");
  2382. dprintf("Packet at 0x%p\n", CurPacket);
  2383. PrintNdisPacketPrivate(CurPacket);
  2384. return TRUE;
  2385. }
  2386. GetFieldValue((ULONG64)pNdisBuf, NDIS_BUFFER_NAME,
  2387. "Next", TmpVal);
  2388. pNdisBuf = TmpVal;
  2389. }
  2390. }
  2391. return FALSE;
  2392. }
  2393. /*++
  2394. Roution Desc:
  2395. This function traverses blocks inside a list to search for the packet
  2396. Arguments:
  2397. CurBlockLink --- The "List" addresss inside one block
  2398. BlocksHeadAddress --- The header address of the block list inside one pool
  2399. BlcokLinkOffset --- The offset of "List" inside one block
  2400. PktsPerBlock --- Number of packets inside the searched block
  2401. PacketStackSize --- The stack size inside the searched block
  2402. Flags --- 1: Free block to search
  2403. --- 0: Used block to search
  2404. Address --- The virtual address
  2405. PacketLength --- Packet length of the search block
  2406. BlockSize --- Size of the block
  2407. Return Value:
  2408. True --- Packet found
  2409. False --- Packet not found
  2410. --*/
  2411. BOOL
  2412. SearchVaInBlocks(
  2413. ULONG64 CurBlockLink,
  2414. ULONG64 BlocksHeadAddr,
  2415. ULONG BlockLinkOffset,
  2416. ULONG PacketStackSize,
  2417. USHORT PktPerBlock,
  2418. UCHAR Flags,
  2419. ULONG64 Address,
  2420. USHORT PacketLength,
  2421. ULONG BlockSize)
  2422. {
  2423. ULONG64 CurBlock;
  2424. BOOL fRet;
  2425. while((ULONG64)CurBlockLink != BlocksHeadAddr)
  2426. {
  2427. if (CheckControlC())
  2428. {
  2429. break;
  2430. }
  2431. //
  2432. // for each free block, walk through all allocated packets
  2433. //
  2434. CurBlock = (ULONG64)CurBlockLink - BlockLinkOffset;
  2435. dprintf("\nSearching %s block <0x%p>\n", (Flags == 1)? "Free":"Used", CurBlock);
  2436. fRet = SearchVaInOneBlock(CurBlock,
  2437. PktPerBlock,
  2438. PacketStackSize,
  2439. Flags,
  2440. Address,
  2441. PacketLength,
  2442. BlockSize);
  2443. if (fRet)
  2444. {
  2445. return fRet;
  2446. }
  2447. GetFieldValue((ULONG64)CurBlockLink, LIST_ENTRY_NAME,
  2448. "Flink", CurBlockLink);
  2449. if (CurBlockLink == 0)
  2450. {
  2451. break;
  2452. }
  2453. }
  2454. return FALSE;
  2455. }
  2456. /*++
  2457. Routine Desc:
  2458. This function searches one block for the packets in use.
  2459. Argument:
  2460. CurBlock --- The starting of the searched block
  2461. PktsPerBlock --- Number of packets inside the searched block
  2462. PacketStackSize --- The stack size inside the searched block
  2463. Flags --- 1: Free block to search
  2464. --- 0: Used block to search
  2465. Address --- The virtual address
  2466. PacketLength --- Packet length of the search block
  2467. Return Value:
  2468. None
  2469. --*/
  2470. void
  2471. SearchPktInOneBlock(
  2472. ULONG64 CurBlock,
  2473. ULONG PktsPerBlock,
  2474. ULONG PacketStackSize,
  2475. UCHAR Flags,
  2476. USHORT PacketLength)
  2477. {
  2478. USHORT i;
  2479. ULONG64 BlockStartAddr;
  2480. PUCHAR p;
  2481. ULONG64 pStackIndex;
  2482. ULONG Index;
  2483. ULONG64 CurPacket;
  2484. CurPacket = CurBlock + GetTypeSize(NDIS_PKT_POOL_HDR_NAME);
  2485. p = (PUCHAR)CurPacket;
  2486. for(i = 0; i < PktsPerBlock; i++, p += PacketLength)
  2487. {
  2488. if (CheckControlC())
  2489. {
  2490. break;
  2491. }
  2492. CurPacket = (ULONG64)(p + PacketStackSize);
  2493. pStackIndex = CurPacket - sizeof(ULONG); // sizeof(ULONG) is same across all platforms
  2494. Index = GetUlongFromAddress((ULONG64)pStackIndex);
  2495. if (Index != (ULONG)-1)
  2496. {
  2497. dprintf("Packet at 0x%p\n", CurPacket);
  2498. }
  2499. }
  2500. }
  2501. /*++
  2502. Roution Desc:
  2503. This function traverses blocks inside a list to search for the packets in use
  2504. Arguments:
  2505. CurBlockLink --- The "List" addresss inside one block
  2506. BlocksHeadAddress --- The header address of the block list inside one pool
  2507. BlcokLinkOffset --- The offset of "List" inside one block
  2508. PktsPerBlock --- Number of packets inside the searched block
  2509. PacketStackSize --- The stack size inside the searched block
  2510. Flags --- 1: Free block to search
  2511. --- 0: Used block to search
  2512. PacketLength --- Packet length of the search block
  2513. Return Value:
  2514. None
  2515. --*/
  2516. void
  2517. SearchPktInBlocks(
  2518. ULONG64 CurBlockLink,
  2519. ULONG64 BlocksHeadAddr,
  2520. ULONG BlockLinkOffset,
  2521. ULONG PacketStackSize,
  2522. USHORT PktPerBlock,
  2523. UCHAR Flags,
  2524. USHORT PacketLength)
  2525. {
  2526. ULONG64 CurBlock;
  2527. ULONG64 TmpVal;
  2528. while(CurBlockLink != BlocksHeadAddr)
  2529. {
  2530. if (CheckControlC())
  2531. {
  2532. break;
  2533. }
  2534. //
  2535. // for each free block, walk through all allocated packets
  2536. //
  2537. CurBlock = (ULONG64)CurBlockLink - BlockLinkOffset;
  2538. dprintf("\nSearching %s block <0x%p>\n", (Flags == 1)? "Free":"Used", CurBlock);
  2539. SearchPktInOneBlock(CurBlock,
  2540. PktPerBlock,
  2541. PacketStackSize,
  2542. Flags,
  2543. PacketLength);
  2544. GetFieldValue((ULONG64)CurBlockLink, LIST_ENTRY_NAME,
  2545. "Flink", TmpVal);
  2546. CurBlockLink = TmpVal;
  2547. if (CurBlockLink == 0)
  2548. {
  2549. break;
  2550. }
  2551. }
  2552. }
  2553. /*++
  2554. Routine Desc:
  2555. This function is to find the packets with the given virtual address.
  2556. It traverses each pool, and inside one pool it traverses freeblockslist
  2557. and usedblockslist, then inside each block in the list, it search for
  2558. the packet with the given virtual address
  2559. --*/
  2560. void
  2561. FindPacketWithVa(ULONG64 Address)
  2562. {
  2563. ULONG64 PoolListAddr;
  2564. ULONG64 LinkAddr;
  2565. ULONG64 Pool;
  2566. ULONG LinkOffset;
  2567. LONG BlocksAllocated;
  2568. ULONG BlockSize;
  2569. USHORT PacketLength;
  2570. USHORT PktsPerBlock;
  2571. ULONG NumberOfStacks;
  2572. ULONG PacketStackSize;
  2573. ULONG FreeBlocksLinkOffset;
  2574. ULONG UsedBlocksLinkOffset;
  2575. ULONG BlockLinkOffset;
  2576. ULONG64 PoolFreeBlocksListAddr;
  2577. ULONG64 PoolUsedBlocksListAddr;
  2578. ULONG64 CurBlockLink;
  2579. ULONG64 BlocksHeadAddr;
  2580. BOOL fRet;
  2581. ULONG64 NumberOfStacksAddr;
  2582. PoolListAddr = GetExpression("ndis!ndisGlobalPacketPoolList");
  2583. if (PoolListAddr == 0)
  2584. {
  2585. ErrorCheckSymbols("ndis!ndisGlobalPacketPoolList");
  2586. return;
  2587. }
  2588. GetFieldValue(PoolListAddr, LIST_ENTRY_NAME, "Flink", LinkAddr);
  2589. if (LinkAddr == 0)
  2590. {
  2591. dprintf("Can't get Flink of PoolListAddr.\n");
  2592. return;
  2593. }
  2594. NumberOfStacksAddr = GetExpression("ndis!ndisPacketStackSize");
  2595. if (NumberOfStacksAddr == 0)
  2596. {
  2597. ErrorCheckSymbols("ndis!ndisPacketStackSize");
  2598. return;
  2599. }
  2600. NumberOfStacks = GetUlongFromAddress(NumberOfStacksAddr);
  2601. PacketStackSize = (ULONG)GetTypeSize(STACK_INDEX_NAME)
  2602. + (ULONG)GetTypeSize(NDIS_PACKET_STACK_NAME) * NumberOfStacks;
  2603. //
  2604. // First, get some offsets.
  2605. //
  2606. if (GetFieldOffset(NDIS_PKT_POOL_NAME, "GlobalPacketPoolList", &LinkOffset) != 0)
  2607. {
  2608. dprintf("Can't get offset of GlobalPacketPoolList in NDIS_PKT_POOL!\n");
  2609. return;
  2610. }
  2611. if (GetFieldOffset(NDIS_PKT_POOL_NAME,
  2612. "FreeBlocks",&FreeBlocksLinkOffset) != 0)
  2613. {
  2614. dprintf("Can't get offset of FreeBlocks in NDIS_PKT_POOL!\n");
  2615. return;
  2616. }
  2617. if (GetFieldOffset(NDIS_PKT_POOL_NAME, "UsedBlocks", &UsedBlocksLinkOffset) != 0)
  2618. {
  2619. dprintf("Can't get offset of UsedBlocks in NDIS_PKT_POOL!\n");
  2620. return;
  2621. }
  2622. if (GetFieldOffset(NDIS_PKT_POOL_HDR_NAME, "List", &BlockLinkOffset) != 0)
  2623. {
  2624. dprintf("Can't get offset of List in NDIS_PKT_POOL_HDR!\n");
  2625. return;
  2626. }
  2627. //
  2628. // walk through all the allocated packet pools
  2629. //
  2630. while (LinkAddr != PoolListAddr)
  2631. {
  2632. //
  2633. // Just safe check, usually this condition never satisfied
  2634. if (LinkAddr == 0)
  2635. {
  2636. break;
  2637. }
  2638. if (CheckControlC())
  2639. {
  2640. break;
  2641. }
  2642. //
  2643. // Get the pool
  2644. //
  2645. Pool = LinkAddr - LinkOffset;
  2646. PoolFreeBlocksListAddr = Pool + FreeBlocksLinkOffset;
  2647. PoolUsedBlocksListAddr = Pool + UsedBlocksLinkOffset;
  2648. GetFieldValue(Pool, NDIS_PKT_POOL_NAME, "BlockSize", BlockSize);
  2649. GetFieldValue(Pool, NDIS_PKT_POOL_NAME, "PktsPerBlock", PktsPerBlock);
  2650. GetFieldValue(Pool, NDIS_PKT_POOL_NAME, "PacketLength", PacketLength);
  2651. //
  2652. // walk through all free and used blocks on this packet pool
  2653. //
  2654. BlocksHeadAddr = PoolFreeBlocksListAddr;
  2655. //
  2656. // Search free blocks
  2657. //
  2658. GetFieldValue(Pool, NDIS_PKT_POOL_NAME,
  2659. "FreeBlocks.Flink", CurBlockLink);
  2660. if (CurBlockLink != 0)
  2661. {
  2662. fRet = SearchVaInBlocks ((ULONG64)CurBlockLink,
  2663. BlocksHeadAddr,
  2664. BlockLinkOffset,
  2665. PacketStackSize,
  2666. PktsPerBlock,
  2667. 1,
  2668. Address,
  2669. PacketLength,
  2670. BlockSize);
  2671. if (fRet)
  2672. {
  2673. return;
  2674. }
  2675. }
  2676. BlocksHeadAddr = PoolUsedBlocksListAddr;
  2677. //
  2678. // Search used blocks
  2679. GetFieldValue(Pool, NDIS_PKT_POOL_NAME,
  2680. "UsedBlocks.Flink", CurBlockLink);
  2681. if (CurBlockLink != 0)
  2682. {
  2683. fRet = SearchVaInBlocks (CurBlockLink,
  2684. BlocksHeadAddr,
  2685. BlockLinkOffset,
  2686. PacketStackSize,
  2687. PktsPerBlock,
  2688. 0,
  2689. Address,
  2690. PacketLength,
  2691. BlockSize);
  2692. if (fRet)
  2693. {
  2694. return;
  2695. }
  2696. }
  2697. //
  2698. // Go to the next pool
  2699. //
  2700. GetFieldValue(LinkAddr, LIST_ENTRY_NAME,
  2701. "Flink", LinkAddr);
  2702. if (LinkAddr == 0)
  2703. {
  2704. break;
  2705. }
  2706. }
  2707. dprintf("\nPACKET with VA 0x%p Not Found\n", Address);
  2708. }
  2709. /*++
  2710. Routine Desc:
  2711. This function is to find the packets in use inside a pool with the
  2712. given pool address. Inside the pool it traverses freeblockslist
  2713. and usedblockslist, then inside each block in the list, it search for
  2714. the packets that are in use
  2715. --*/
  2716. void
  2717. FindPacketInUse(ULONG64 Pool)
  2718. {
  2719. ULONG BlockSize;
  2720. USHORT PacketLength;
  2721. USHORT PktsPerBlock;
  2722. ULONG NumberOfStacks;
  2723. ULONG PacketStackSize;
  2724. ULONG64 TmpVal;
  2725. ULONG FreeBlocksLinkOffset;
  2726. ULONG UsedBlocksLinkOffset;
  2727. ULONG BlockLinkOffset;
  2728. ULONG64 PoolFreeBlocksListAddr;
  2729. ULONG64 PoolUsedBlocksListAddr;
  2730. ULONG64 CurBlockLink;
  2731. ULONG64 BlocksHeadAddr;
  2732. ULONG64 NumberOfStacksAddr;
  2733. NumberOfStacksAddr = GetExpression("ndis!ndisPacketStackSize");
  2734. NumberOfStacks = GetUlongFromAddress(NumberOfStacksAddr);
  2735. PacketStackSize = (ULONG)GetTypeSize(STACK_INDEX_NAME)
  2736. + (ULONG)GetTypeSize(NDIS_PACKET_STACK_NAME) * NumberOfStacks;
  2737. //
  2738. // First, get some offsets.
  2739. //
  2740. if (GetFieldOffset(NDIS_PKT_POOL_NAME,
  2741. "FreeBlocks",&FreeBlocksLinkOffset) != 0)
  2742. {
  2743. dprintf("Can't get offset of FreeBlocks in NDIS_PKT_POOL!\n");
  2744. return;
  2745. }
  2746. if (GetFieldOffset(NDIS_PKT_POOL_NAME, "UsedBlocks", &UsedBlocksLinkOffset) != 0)
  2747. {
  2748. dprintf("Can't get offset of UsedBlocks in NDIS_PKT_POOL!\n");
  2749. return;
  2750. }
  2751. if (GetFieldOffset(NDIS_PKT_POOL_HDR_NAME, "List", &BlockLinkOffset) != 0)
  2752. {
  2753. dprintf("Can't get offset of List in NDIS_PKT_POOL_HDR!\n");
  2754. return;
  2755. }
  2756. //
  2757. // Get the pool
  2758. //
  2759. PoolFreeBlocksListAddr = Pool + FreeBlocksLinkOffset;
  2760. PoolUsedBlocksListAddr = Pool + UsedBlocksLinkOffset;
  2761. GetFieldValue(Pool, NDIS_PKT_POOL_NAME, "BlockSize", BlockSize);
  2762. GetFieldValue(Pool, NDIS_PKT_POOL_NAME, "PktsPerBlock", PktsPerBlock);
  2763. GetFieldValue(Pool, NDIS_PKT_POOL_NAME, "PacketLength", PacketLength);
  2764. //
  2765. // walk through all free and used blocks on this packet pool
  2766. //
  2767. BlocksHeadAddr = PoolFreeBlocksListAddr;
  2768. //
  2769. // Search free blocks
  2770. //
  2771. GetFieldValue(Pool, NDIS_PKT_POOL_NAME,
  2772. "FreeBlocks.Flink", CurBlockLink);
  2773. if (CurBlockLink != 0)
  2774. {
  2775. SearchPktInBlocks ((ULONG64)CurBlockLink,
  2776. BlocksHeadAddr,
  2777. BlockLinkOffset,
  2778. PacketStackSize,
  2779. PktsPerBlock,
  2780. 1,
  2781. PacketLength);
  2782. }
  2783. BlocksHeadAddr = PoolUsedBlocksListAddr;
  2784. //
  2785. // Search used blocks
  2786. GetFieldValue(Pool, NDIS_PKT_POOL_NAME,
  2787. "UsedBlocks.Flink", CurBlockLink);
  2788. if (CurBlockLink != 0)
  2789. {
  2790. SearchPktInBlocks ((ULONG64)CurBlockLink,
  2791. BlocksHeadAddr,
  2792. BlockLinkOffset,
  2793. PacketStackSize,
  2794. PktsPerBlock,
  2795. 0,
  2796. PacketLength);
  2797. }
  2798. }
  2799. /*++
  2800. Routine Desc:
  2801. This function is to find packets with the given selection
  2802. v --- with virtual address
  2803. p --- with pool address
  2804. --*/
  2805. DECLARE_API(findpacket)
  2806. {
  2807. CHAR Verbosity;
  2808. CHAR argbuf[ MAX_PATH ];
  2809. CHAR arglist[10][MAX_PATH];
  2810. CHAR *str;
  2811. INT index=0;
  2812. CHAR *p;
  2813. ULONG64 Address;
  2814. if (!args || !*args)
  2815. {
  2816. dprintf("Usag: findpacket v <virtual address>\n");
  2817. dprintf(" p <pool address>\n");
  2818. return;
  2819. }
  2820. strcpy(argbuf,args);
  2821. for (p = mystrtok( argbuf, " \t,;" );
  2822. p && *p;
  2823. p = mystrtok(NULL, " \t,;"))
  2824. {
  2825. strcpy(&arglist[index++][0], p);
  2826. }
  2827. Verbosity = arglist[0][0];
  2828. if (Verbosity != 'v' && Verbosity != 'p')
  2829. {
  2830. dprintf("Usag: findpacket v <virtual address>\n");
  2831. dprintf(" p <pool address>\n");
  2832. return;
  2833. }
  2834. if (index < 2)
  2835. {
  2836. dprintf("\nAddress is needed \n");
  2837. return;
  2838. }
  2839. Address = GetExpression(&arglist[1][0]);
  2840. switch (Verbosity)
  2841. {
  2842. case 'v':
  2843. FindPacketWithVa(Address);
  2844. break;
  2845. case 'p':
  2846. FindPacketInUse(Address);
  2847. default:
  2848. break;
  2849. }
  2850. }