Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1932 lines
53 KiB

  1. /*++
  2. Copyright (c) 1990 Microsoft Corporation
  3. Module Name:
  4. kdcn.c
  5. Abstract:
  6. Clustner Xport KD extension - based on Vert's skeleton
  7. Author:
  8. John Vert (jvert) 6-Aug-1992
  9. Revision History:
  10. --*/
  11. #include "precomp.h"
  12. #pragma hdrstop
  13. //
  14. // globals
  15. //
  16. EXT_API_VERSION ApiVersion = { 5, 0, EXT_API_VERSION_NUMBER, 0 };
  17. WINDBG_EXTENSION_APIS ExtensionApis;
  18. USHORT SavedMajorVersion;
  19. USHORT SavedMinorVersion;
  20. CHAR igrepLastPattern[256];
  21. DWORD igrepSearchStartAddress;
  22. DWORD igrepLastPc;
  23. PCHAR EventTypes[] = {
  24. "", // used if the number is out of range
  25. "Node Up",
  26. "Node Down",
  27. "Poison Packet Received",
  28. "Halt",
  29. "Net IF Up",
  30. "Net IF Unreachable",
  31. "Net IF Failed",
  32. "(not used)",
  33. "Add Address",
  34. "Delete Address"
  35. };
  36. PCHAR NetObjState[] = {
  37. "Offline",
  38. "OfflinePending",
  39. "Partitioned",
  40. "OnlinePending",
  41. "Online"
  42. };
  43. PCHAR NodeObjCommState[] = {
  44. "Offline",
  45. "OfflinePending",
  46. "Unreachable",
  47. "OnlinePending",
  48. "Online"
  49. };
  50. PCHAR NodeObjMemberState[] = {
  51. "Alive",
  52. "Joining",
  53. "Dead",
  54. "Not Configured"
  55. };
  56. PCHAR InterfaceState[] = {
  57. "Offline",
  58. "OfflinePending",
  59. "Unreachable",
  60. "OnlinePending",
  61. "Online"
  62. };
  63. PCHAR CcmpMessageTypes[] = {
  64. "Invalid",
  65. "Heartbeat",
  66. "Poison",
  67. "Membership"
  68. };
  69. #define TrueOrFalse( _x ) ( _x ? "True" : "False" )
  70. /* forwards */
  71. VOID
  72. DumpEventData(
  73. PCLUSNET_EVENT_ENTRY EventAddress,
  74. PCLUSNET_EVENT_ENTRY EventEntry
  75. );
  76. VOID
  77. DumpInterfaceObj(
  78. PCNP_INTERFACE TargetIfObj,
  79. PCNP_INTERFACE LocalIfObj
  80. );
  81. BOOL
  82. ReadNodeTable(
  83. PCNP_NODE **LocalNodeTable,
  84. CL_NODE_ID *MaxNodeId,
  85. CL_NODE_ID *MinNodeId
  86. );
  87. VOID
  88. DumpNodeObjFlags(
  89. ULONG Flags
  90. );
  91. VOID
  92. DumpNetObjFlags(
  93. ULONG Flag
  94. );
  95. BOOL
  96. ReadTargetMemory(
  97. PVOID TargetAddress,
  98. PVOID LocalBuffer,
  99. ULONG BytesToRead
  100. );
  101. __inline PCHAR
  102. ListInUse(
  103. PLIST_ENTRY ListHead,
  104. PLIST_ENTRY ListToCheck
  105. );
  106. __inline PCHAR
  107. TrueFalse(
  108. BOOLEAN Value
  109. );
  110. VOID
  111. DprintUnicodeString(
  112. PUNICODE_STRING String,
  113. DWORD_PTR AddrString,
  114. PCHAR Symbol OPTIONAL,
  115. DWORD_PTR Displacement OPTIONAL
  116. );
  117. #if 0
  118. VOID
  119. DumpRGPCounters(
  120. rgp_counter_t *counters
  121. );
  122. VOID
  123. DumpClusterMask(
  124. PCHAR Title,
  125. cluster_t *
  126. );
  127. VOID
  128. DumpRGPOSSpecific(
  129. OS_specific_rgp_control_t *Target_rgpos,
  130. OS_specific_rgp_control_t *Local_rgpos
  131. );
  132. #endif
  133. /* end forwards */
  134. DllInit(
  135. HANDLE hModule,
  136. DWORD dwReason,
  137. DWORD dwReserved
  138. )
  139. {
  140. switch (dwReason) {
  141. case DLL_THREAD_ATTACH:
  142. break;
  143. case DLL_THREAD_DETACH:
  144. break;
  145. case DLL_PROCESS_DETACH:
  146. break;
  147. case DLL_PROCESS_ATTACH:
  148. break;
  149. }
  150. return TRUE;
  151. }
  152. VOID
  153. WinDbgExtensionDllInit(
  154. PWINDBG_EXTENSION_APIS lpExtensionApis,
  155. USHORT MajorVersion,
  156. USHORT MinorVersion
  157. )
  158. {
  159. ExtensionApis = *lpExtensionApis;
  160. SavedMajorVersion = MajorVersion;
  161. SavedMinorVersion = MinorVersion;
  162. return;
  163. }
  164. DECLARE_API( version )
  165. {
  166. #if DBG
  167. PCHAR DebuggerType = "Checked";
  168. #else
  169. PCHAR DebuggerType = "Free";
  170. #endif
  171. dprintf("%s Extension dll for Build %d debugging %s clusnet for Build %d\n",
  172. DebuggerType,
  173. VER_PRODUCTBUILD,
  174. SavedMajorVersion == 0x0c ? "Checked" : "Free",
  175. SavedMinorVersion
  176. );
  177. }
  178. VOID
  179. CheckVersion(
  180. VOID
  181. )
  182. {
  183. PVOID cnDebugAddr;
  184. cnDebugAddr = (PVOID)GetExpression( "clusnet!cndebug" );
  185. #if DBG
  186. if ( cnDebugAddr == NULL ) {
  187. dprintf("\r\nYou MUST use the checked built KDCN with the checked built driver!!!\n\n");
  188. }
  189. if ((SavedMajorVersion != 0x0c) || (SavedMinorVersion != VER_PRODUCTBUILD)) {
  190. dprintf("\r\n*** Extension DLL(%d Checked) does not match target system(%d %s)\r\n\r\n",
  191. VER_PRODUCTBUILD, SavedMinorVersion, (SavedMajorVersion==0x0f) ? "Free" : "Checked" );
  192. }
  193. #else
  194. if ( cnDebugAddr != NULL ) {
  195. dprintf("\r\nYou MUST use the free built KDCN with the free built driver!!!\n\n");
  196. }
  197. if ((SavedMajorVersion != 0x0f) || (SavedMinorVersion != VER_PRODUCTBUILD)) {
  198. dprintf("\r\n*** Extension DLL(%d Free) does not match target system(%d %s)\r\n\r\n",
  199. VER_PRODUCTBUILD, SavedMinorVersion, (SavedMajorVersion==0x0f) ? "Free" : "Checked" );
  200. }
  201. #endif
  202. }
  203. LPEXT_API_VERSION
  204. ExtensionApiVersion(
  205. VOID
  206. )
  207. {
  208. return &ApiVersion;
  209. }
  210. DECLARE_API( ustr )
  211. /*++
  212. Routine Description:
  213. This function is called as a KD extension to format and dump
  214. counted unicode string.
  215. Arguments:
  216. see wdbgexts.h
  217. Return Value:
  218. None.
  219. --*/
  220. {
  221. UNICODE_STRING UnicodeString;
  222. DWORD_PTR dwAddrString;
  223. CHAR Symbol[64];
  224. DWORD_PTR Displacement;
  225. BOOL b;
  226. //
  227. // Evaluate the argument string to get the address of
  228. // the string to dump.
  229. //
  230. dwAddrString = GetExpression(args);
  231. if ( !dwAddrString ) {
  232. return;
  233. }
  234. //
  235. // Get the symbolic name of the string
  236. //
  237. GetSymbol((LPVOID)dwAddrString,Symbol,&Displacement);
  238. //
  239. // Read the string from the debuggees address space into our
  240. // own.
  241. b = ReadMemory(dwAddrString, &UnicodeString, sizeof(UnicodeString), NULL);
  242. if ( !b ) {
  243. return;
  244. }
  245. DprintUnicodeString(&UnicodeString, dwAddrString, Symbol, Displacement);
  246. } // ustr
  247. DECLARE_API( netobj )
  248. /*
  249. * dump the specified clusnet network object structure or all if no
  250. * arg is specified
  251. */
  252. {
  253. PCNP_NETWORK TargetNetObj;
  254. CNP_NETWORK LocalNetObj;
  255. PCNP_NETWORK LastNetObj;
  256. LIST_ENTRY LocalListHead;
  257. PLIST_ENTRY TargetListHead;
  258. BOOLEAN DumpAllNetObjs = FALSE;
  259. if ( *args == '\0' ) {
  260. //
  261. // run down the network object list, dumping the contents of each one
  262. //
  263. TargetListHead = (PLIST_ENTRY)GetExpression( "clusnet!cnpnetworklist" );
  264. if ( !TargetListHead ) {
  265. dprintf("Can't convert clusnet!cnpnetworklist symbol\n");
  266. return;
  267. }
  268. //
  269. // read network object listhead out of target's memory
  270. //
  271. if ( !ReadTargetMemory( TargetListHead, &LocalListHead, sizeof(LIST_ENTRY))) {
  272. dprintf("Can't get CnpNetworkList data\n");
  273. return;
  274. }
  275. TargetNetObj = (PCNP_NETWORK)LocalListHead.Flink;
  276. LastNetObj = (PCNP_NETWORK)TargetListHead;
  277. DumpAllNetObjs = TRUE;
  278. } else {
  279. TargetNetObj = (PCNP_NETWORK)GetExpression( args );
  280. if ( !TargetNetObj ) {
  281. dprintf("bad string conversion (%s) \n", args );
  282. return;
  283. }
  284. LastNetObj = 0;
  285. }
  286. while ( TargetNetObj != LastNetObj ) {
  287. if (CheckControlC()) {
  288. return;
  289. }
  290. //
  291. // read network object struct out of target's memory
  292. //
  293. TargetNetObj = CONTAINING_RECORD( TargetNetObj, CNP_NETWORK, Linkage );
  294. if ( !ReadTargetMemory( TargetNetObj, &LocalNetObj, sizeof( CNP_NETWORK ))) {
  295. dprintf("Problem reading net obj at %p\n", TargetNetObj );
  296. return;
  297. }
  298. #if DBG
  299. if ( LocalNetObj.Signature != CNP_NETWORK_SIG ) {
  300. dprintf( "CNP_NETWORK @ %p has the wrong signature\n", TargetNetObj );
  301. }
  302. #endif
  303. dprintf( "\nNetObj @ %p\n\n", TargetNetObj );
  304. dprintf( " Next NetObj @ %p\n", LocalNetObj.Linkage.Flink );
  305. dprintf( " ID = %d\n", LocalNetObj.Id );
  306. dprintf( " Lock @ %p\n", &TargetNetObj->Lock );
  307. dprintf( " Irql = %d\n", LocalNetObj.Irql );
  308. dprintf( " RefCount = %d\n", LocalNetObj.RefCount );
  309. dprintf( " Active RefCount = %d\n", LocalNetObj.ActiveRefCount );
  310. dprintf( " State = %s\n", NetObjState [ LocalNetObj.State ]);
  311. DumpNetObjFlags( LocalNetObj.Flags );
  312. dprintf( " Priority = %d\n", LocalNetObj.Priority );
  313. dprintf( " DatagramHandle @ %p\n", LocalNetObj.DatagramHandle );
  314. dprintf( " Datagram File Obj @ %p\n", LocalNetObj.DatagramFileObject );
  315. dprintf( " Datagram Device Obj @ %p\n", LocalNetObj.DatagramDeviceObject );
  316. dprintf( " TDI provider info @ %p\n", &TargetNetObj->ProviderInfo );
  317. dprintf( " Current mcast group @ %p\n", LocalNetObj.CurrentMcastGroup );
  318. dprintf( " Previous mcast group @ %p\n", LocalNetObj.PreviousMcastGroup );
  319. dprintf( " Multicast reachable node set = %lx\n", LocalNetObj.McastReachableNodes);
  320. dprintf( " Multicast reachable node count = %d\n", LocalNetObj.McastReachableCount);
  321. dprintf( " Pending Delete IRP @ %p\n", LocalNetObj.PendingDeleteIrp );
  322. dprintf( " Pending Offline IRP @ %p\n", LocalNetObj.PendingOfflineIrp );
  323. dprintf( " Work Q Item @ %p\n", &TargetNetObj->ExWorkItem );
  324. if ( !DumpAllNetObjs ) {
  325. break;
  326. } else {
  327. TargetNetObj = (PCNP_NETWORK)LocalNetObj.Linkage.Flink;
  328. }
  329. }
  330. } // netobj
  331. VOID
  332. DumpNetObjFlags(
  333. ULONG Flags
  334. )
  335. {
  336. dprintf(" Flags = %08X (", Flags );
  337. if ( Flags & CNP_NET_FLAG_DELETING )
  338. dprintf(" Deleting" );
  339. if ( Flags & CNP_NET_FLAG_PARTITIONED )
  340. dprintf(" Partitioned" );
  341. if ( Flags & CNP_NET_FLAG_RESTRICTED )
  342. dprintf(" Restricted" );
  343. if ( Flags & CNP_NET_FLAG_LOCALDISCONN ) {
  344. dprintf(" Local-Disconnect" );
  345. }
  346. if ( Flags & CNP_NET_FLAG_MULTICAST ) {
  347. dprintf(" Multicast-Enabled" );
  348. }
  349. dprintf(")\n");
  350. }
  351. DECLARE_API( nodeobj )
  352. /*
  353. * if no arg, run down the node table, dumping each clusnet node object
  354. * structure. otherwise, dump the indicated node obj
  355. */
  356. {
  357. PCNP_NODE TargetNodeObj;
  358. CNP_NODE LocalNodeObj;
  359. PCNP_NODE *LocalNodeTable = NULL;
  360. CL_NODE_ID MaxNodeId, MinNodeId;
  361. ULONG StartNode, EndNode, Node;
  362. //
  363. // read in the node table
  364. //
  365. if ( !ReadNodeTable( &LocalNodeTable, &MaxNodeId, &MinNodeId )) {
  366. if ( LocalNodeTable )
  367. free( LocalNodeTable );
  368. return;
  369. }
  370. if ( *args == '\0' ) {
  371. StartNode = MinNodeId;
  372. EndNode = MaxNodeId;
  373. } else {
  374. StartNode = EndNode = (ULONG)GetExpression( args );
  375. if ( StartNode > MaxNodeId ) {
  376. dprintf("Node ID out of Range: 0 to %d\n", MaxNodeId );
  377. if ( LocalNodeTable )
  378. free( LocalNodeTable );
  379. return;
  380. }
  381. }
  382. dprintf("Min, Max Node ID = ( %u, %d )\n", MinNodeId, MaxNodeId );
  383. for ( Node = StartNode; Node <= EndNode; ++Node ) {
  384. if (CheckControlC()) {
  385. break;
  386. }
  387. //
  388. // read node object struct out of target's memory
  389. //
  390. TargetNodeObj = *(LocalNodeTable + Node);
  391. if ( TargetNodeObj == NULL ) {
  392. continue;
  393. } else if ( !ReadTargetMemory( TargetNodeObj, &LocalNodeObj, sizeof( CNP_NODE ))) {
  394. dprintf("Problem reading node obj at %p (Node %d)\n", TargetNodeObj, Node );
  395. break;
  396. }
  397. #if DBG
  398. if ( LocalNodeObj.Signature != CNP_NODE_SIG ) {
  399. dprintf( "CNP_NODE @ %p has the wrong signature\n", TargetNodeObj );
  400. }
  401. #endif
  402. dprintf( "\nNodeObj @ %p\n\n", TargetNodeObj );
  403. dprintf( " Linkage.Flink @ %p\n", LocalNodeObj.Linkage.Flink );
  404. dprintf( " ID = %d\n", LocalNodeObj.Id );
  405. dprintf( " Lock @ %p\n", &TargetNodeObj->Lock );
  406. dprintf( " Irql = %d\n", LocalNodeObj.Irql );
  407. dprintf( " RefCount = %d\n", LocalNodeObj.RefCount );
  408. dprintf( " Comm State = %s\n", NodeObjCommState [ LocalNodeObj.CommState ]);
  409. dprintf( " MMState = %s\n", NodeObjMemberState [ LocalNodeObj.MMState ]);
  410. DumpNodeObjFlags( LocalNodeObj.Flags );
  411. dprintf( " Interface List @ %p", &TargetNodeObj->InterfaceList );
  412. if ( &TargetNodeObj->InterfaceList == LocalNodeObj.InterfaceList.Flink ) {
  413. dprintf( " (empty)" );
  414. }
  415. dprintf( "\n" );
  416. dprintf( " Current Interface @ %p\n", LocalNodeObj.CurrentInterface );
  417. dprintf( " Pending Delete IRP @ %p\n", LocalNodeObj.PendingDeleteIrp );
  418. dprintf( " HBWasMissed = %s\n", TrueOrFalse( LocalNodeObj.HBWasMissed ));
  419. dprintf( " Node Down Issued = %s\n", TrueOrFalse( LocalNodeObj.NodeDownIssued ));
  420. dprintf( " MissedHBs = %u\n", LocalNodeObj.MissedHBs );
  421. }
  422. if ( LocalNodeTable ) {
  423. free( LocalNodeTable );
  424. }
  425. } // nodeobj
  426. VOID
  427. DumpNodeObjFlags(
  428. ULONG Flags
  429. )
  430. {
  431. dprintf(" Flags = %08X (", Flags );
  432. if ( Flags & CNP_NODE_FLAG_DELETING )
  433. dprintf(" Deleting" );
  434. if ( Flags & CNP_NODE_FLAG_UNREACHABLE )
  435. dprintf(" Unreachable" );
  436. if ( Flags & CNP_NODE_FLAG_LOCAL )
  437. dprintf(" Local" );
  438. dprintf(")\n");
  439. }
  440. DECLARE_API( nodeifs )
  441. /*
  442. * dump the interface list for the indicated node obj
  443. */
  444. {
  445. PCNP_NODE TargetNodeObj;
  446. CNP_NODE LocalNodeObj;
  447. PCNP_NODE *LocalNodeTable = NULL;
  448. PCNP_INTERFACE NextTargetIfObj;
  449. CNP_INTERFACE LocalIfObj;
  450. CL_NODE_ID MaxNodeId, MinNodeId;
  451. ULONG Node;
  452. if ( *args == '\0' ) {
  453. dprintf("Node ID must be specified\n");
  454. return;
  455. }
  456. if ( !ReadNodeTable( &LocalNodeTable, &MaxNodeId, &MinNodeId )) {
  457. if ( LocalNodeTable )
  458. free( LocalNodeTable );
  459. return;
  460. }
  461. Node = (ULONG)GetExpression( args );
  462. if ( Node > MaxNodeId || Node < MinNodeId ) {
  463. dprintf("Node ID is out of range: %u to %u\n", MinNodeId, MaxNodeId );
  464. if ( LocalNodeTable )
  465. free( LocalNodeTable );
  466. return;
  467. }
  468. //
  469. // read node object struct out of target's memory
  470. //
  471. TargetNodeObj = *(LocalNodeTable + Node);
  472. if ( !ReadTargetMemory( TargetNodeObj, &LocalNodeObj, sizeof( CNP_NODE ))) {
  473. dprintf("Problem reading node obj at %p (Node %d)\n", TargetNodeObj, Node );
  474. if ( LocalNodeTable )
  475. free( LocalNodeTable );
  476. return;
  477. }
  478. #if DBG
  479. if ( LocalNodeObj.Signature != CNP_NODE_SIG ) {
  480. dprintf( "CNP_NODE @ %p has the wrong signature\n", TargetNodeObj );
  481. }
  482. #endif
  483. dprintf( "\nNodeObj @ %p Interface List @ %p", TargetNodeObj, &TargetNodeObj->InterfaceList );
  484. if ( &TargetNodeObj->InterfaceList == LocalNodeObj.InterfaceList.Flink ) {
  485. dprintf( " (empty)" );
  486. }
  487. dprintf( "\n\n" );
  488. NextTargetIfObj = (PCNP_INTERFACE)LocalNodeObj.InterfaceList.Flink;
  489. while ( &TargetNodeObj->InterfaceList != (PLIST_ENTRY)NextTargetIfObj ) {
  490. if (CheckControlC()) {
  491. break;
  492. }
  493. NextTargetIfObj = CONTAINING_RECORD( NextTargetIfObj, CNP_INTERFACE, NodeLinkage );
  494. if ( !ReadTargetMemory(
  495. NextTargetIfObj,
  496. &LocalIfObj,
  497. FIELD_OFFSET( CNP_INTERFACE, TdiAddress ) + sizeof(TA_IP_ADDRESS)
  498. )
  499. ) {
  500. break;
  501. }
  502. DumpInterfaceObj( NextTargetIfObj, &LocalIfObj );
  503. NextTargetIfObj = (PCNP_INTERFACE)LocalIfObj.NodeLinkage.Flink;
  504. }
  505. if ( LocalNodeTable ) {
  506. free( LocalNodeTable );
  507. }
  508. } // nodeifs
  509. DECLARE_API( currif )
  510. /*
  511. * for the specified node, dump the current interface obj
  512. */
  513. {
  514. PCNP_NODE TargetNodeObj;
  515. CNP_NODE LocalNodeObj;
  516. PCNP_NODE *LocalNodeTable = NULL;
  517. CL_NODE_ID MaxNodeId, MinNodeId;
  518. CNP_INTERFACE LocalIfObj;
  519. ULONG Node;
  520. if ( *args == '\0' ) {
  521. dprintf("Node ID must be specified\n");
  522. return;
  523. }
  524. //
  525. // read in the node table
  526. //
  527. if ( !ReadNodeTable( &LocalNodeTable, &MaxNodeId, &MinNodeId )) {
  528. if ( LocalNodeTable )
  529. free( LocalNodeTable );
  530. return;
  531. }
  532. Node = (ULONG)GetExpression( args );
  533. if ( Node > MaxNodeId || Node < MinNodeId ) {
  534. dprintf("Node ID is out of range: %u to %u\n", MinNodeId, MaxNodeId );
  535. if ( LocalNodeTable )
  536. free( LocalNodeTable );
  537. return;
  538. }
  539. //
  540. // read node object struct out of target's memory
  541. //
  542. TargetNodeObj = *(LocalNodeTable + Node);
  543. if ( !ReadTargetMemory( TargetNodeObj, &LocalNodeObj, sizeof( CNP_NODE ))) {
  544. dprintf("Problem reading node obj at %p (Node %d)\n", TargetNodeObj, Node );
  545. if ( LocalNodeTable )
  546. free( LocalNodeTable );
  547. return;
  548. }
  549. #if DBG
  550. if ( LocalNodeObj.Signature != CNP_NODE_SIG ) {
  551. dprintf( "CNP_NODE @ %p has the wrong signature\n", TargetNodeObj );
  552. }
  553. #endif
  554. dprintf( "\nNodeObj @ %p Current Interface @ %p\n\n", TargetNodeObj, LocalNodeObj.CurrentInterface );
  555. if ( LocalNodeObj.CurrentInterface ) {
  556. if ( ReadTargetMemory( LocalNodeObj.CurrentInterface, &LocalIfObj, sizeof( CNP_INTERFACE ))) {
  557. DumpInterfaceObj( LocalNodeObj.CurrentInterface, &LocalIfObj );
  558. }
  559. }
  560. if ( LocalNodeTable ) {
  561. free( LocalNodeTable );
  562. }
  563. } // currif
  564. VOID
  565. DumpInterfaceObj(
  566. PCNP_INTERFACE TargetIfObj,
  567. PCNP_INTERFACE IfObj
  568. )
  569. {
  570. LONG i, j;
  571. TA_ADDRESS *TA;
  572. TDI_ADDRESS_IP UNALIGNED *TAIp;
  573. #if DBG
  574. if ( IfObj->Signature != CNP_INTERFACE_SIG ) {
  575. dprintf( "CNP_INTERFACE @ %p has the wrong signature\n", TargetIfObj );
  576. }
  577. #endif
  578. dprintf("Interface Obj @ %p\n", TargetIfObj );
  579. dprintf(" Node Obj @ %p\n", IfObj->Node );
  580. dprintf(" Net Obj @ %p\n", IfObj->Network );
  581. dprintf(" State = %s\n", InterfaceState[ IfObj->State ]);
  582. dprintf(" Priority = %d\n", IfObj->Priority );
  583. dprintf(" Flags = %08X\n", IfObj->Flags );
  584. dprintf(" MissedHBs = %u\n", IfObj->MissedHBs );
  585. dprintf(" Seq to send = %u\n", IfObj->SequenceToSend );
  586. dprintf(" Last Seq Recv'd = %u\n", IfObj->LastSequenceReceived );
  587. dprintf(" Multicast discovery count = %u\n", IfObj->McastDiscoverCount );
  588. dprintf(" AdapterWMIProviderId = %08X\n", IfObj->AdapterWMIProviderId );
  589. dprintf(" TDI Addr Len = %d\n", IfObj->TdiAddressLength );
  590. dprintf(" TDI Addr Count = %d\n", IfObj->TdiAddress.TAAddressCount );
  591. TA = IfObj->TdiAddress.Address;
  592. for (i=0; i < IfObj->TdiAddress.TAAddressCount; ++i ) {
  593. dprintf(" [%d] Addr Length = %d\n", i, TA->AddressLength );
  594. dprintf(" [%d] Addr Type = %d", i, TA->AddressType );
  595. switch ( TA->AddressType ) {
  596. case TDI_ADDRESS_TYPE_IP:
  597. TAIp = (TDI_ADDRESS_IP UNALIGNED *)TA->Address;
  598. // dprintf("%08X %08X\n", TAIp->in_addr,ntohl(TAIp->in_addr));
  599. dprintf(" (IP)\n [%d] Port: %d Addr: %d.%d.%d.%d\n",
  600. i, ntohs(TAIp->sin_port), (ntohl(TAIp->in_addr) >> 24 ) & 0xFF,
  601. (ntohl(TAIp->in_addr) >> 16 ) & 0xFF,
  602. (ntohl(TAIp->in_addr) >> 8 ) & 0xFF,
  603. ntohl(TAIp->in_addr) & 0xFF);
  604. break;
  605. default:
  606. dprintf("\n [%d] Addr:", i );
  607. for( j = 0; j < TA->AddressLength; ++j )
  608. dprintf(" %02X", TA->Address[j]);
  609. dprintf("\n");
  610. }
  611. TA = (TA_ADDRESS *)((CHAR UNALIGNED *)TA + TA->AddressLength);
  612. }
  613. }
  614. DECLARE_API( memlog )
  615. /*
  616. * dump the heart beat log. can optionally specify starting entry number
  617. */
  618. {
  619. PMEMLOG_ENTRY TargetMemLog;
  620. PMEMLOG_ENTRY TargetLogEntry;
  621. MEMLOG_ENTRY LogEntry;
  622. PULONG TargetLogEntries;
  623. ULONG LogEntries;
  624. PULONG TargetNextLogEntry;
  625. ULONG NextLogEntry;
  626. LONG NumEntries;
  627. ULONG Pass;
  628. ULONG LineCount = 0;
  629. ULONG StartingEntry;
  630. LARGE_INTEGER LastSysTime;
  631. DOUBLE LastTimeDelta;
  632. DOUBLE FirstTimeDelta;
  633. BOOLEAN PrintTime = TRUE;
  634. LARGE_INTEGER FirstEntryTime;
  635. //
  636. // get address of MemLog and read its contents to get the real start
  637. // of the log
  638. //
  639. TargetMemLog = (PMEMLOG_ENTRY)GetExpression( "clusnet!memlog" );
  640. if ( !TargetMemLog ) {
  641. dprintf( "Can't find symbol clusnet!memlog\n" );
  642. return;
  643. }
  644. if ( !ReadTargetMemory( TargetMemLog, &TargetMemLog, sizeof( PMEMLOG_ENTRY ))) {
  645. return;
  646. }
  647. //
  648. // repeat this process, getting the size of the log and the next entry index
  649. //
  650. TargetLogEntries = (PULONG)GetExpression( "clusnet!memlogentries" );
  651. if ( !TargetLogEntries ) {
  652. dprintf( "Can't find symbol clusnet!memlogentries\n" );
  653. return;
  654. }
  655. if ( !ReadTargetMemory( TargetLogEntries, &LogEntries, sizeof( ULONG ))) {
  656. return;
  657. }
  658. TargetNextLogEntry = (PULONG)GetExpression( "clusnet!memlognextlogentry" );
  659. if ( !TargetNextLogEntry ) {
  660. dprintf( "Can't find symbol clusnet!memlognextlogentry\n" );
  661. return;
  662. }
  663. if ( !ReadTargetMemory( TargetNextLogEntry, &NextLogEntry, sizeof( ULONG ))) {
  664. return;
  665. }
  666. //
  667. // get optional starting entry number
  668. //
  669. if ( *args != '\0' ) {
  670. StartingEntry = (ULONG)GetExpression( args );
  671. if ( StartingEntry >= LogEntries ) {
  672. dprintf("Starting entry out of range (0 to %d)\n", LogEntries - 1);
  673. return;
  674. }
  675. if ( StartingEntry <= NextLogEntry ) {
  676. //
  677. // adjust starting number if on significant boundry
  678. //
  679. if ( StartingEntry == NextLogEntry ) {
  680. if ( NextLogEntry == 0 )
  681. StartingEntry = LogEntries - 1;
  682. else
  683. StartingEntry = NextLogEntry - 1;
  684. }
  685. Pass = 0;
  686. NumEntries = StartingEntry + 1;
  687. } else {
  688. Pass = 1;
  689. NumEntries = StartingEntry - NextLogEntry;
  690. }
  691. TargetLogEntry = TargetMemLog + StartingEntry;
  692. } else {
  693. Pass = 0;
  694. if ( NextLogEntry == 0 )
  695. NumEntries = LogEntries - 1;
  696. else
  697. NumEntries = NextLogEntry - 1;
  698. TargetLogEntry = TargetMemLog + NumEntries;
  699. }
  700. //
  701. // read in the most current entry to get its time. We calc the first time
  702. // delta from this value
  703. //
  704. if ( !ReadTargetMemory(TargetMemLog + NextLogEntry - 1, &LogEntry, sizeof( MEMLOG_ENTRY ))) {
  705. dprintf("can't read current log entry (%p) from memory\n\n", TargetLogEntry);
  706. return;
  707. }
  708. LastSysTime.QuadPart = LogEntry.SysTime.QuadPart;
  709. FirstEntryTime.QuadPart = LogEntry.SysTime.QuadPart;
  710. dprintf("MemLog @ %p, Log Entries = %d, Next Entry = %d (%p)\n\n",
  711. TargetMemLog, LogEntries, NextLogEntry, TargetMemLog + NextLogEntry);
  712. //
  713. // depending on our starting entry, look through the log twice.
  714. // next entry might have wrapped so first time we
  715. // dump all the entries down to the base. Next time we start at the end and
  716. // dump out the remaining entries
  717. dprintf("First Last\n");
  718. dprintf("Entry Entry Line Log\n");
  719. dprintf("Delta Delta No Type Desc\n");
  720. while ( Pass < 2 ) {
  721. while ( NumEntries-- ) {
  722. if (CheckControlC()) {
  723. return;
  724. }
  725. if ( !ReadTargetMemory(TargetLogEntry, &LogEntry, sizeof( MEMLOG_ENTRY ))) {
  726. dprintf("can't read log entry (%p) from memory\n\n", TargetLogEntry);
  727. return;
  728. }
  729. if ( LogEntry.Type == 0 )
  730. break;
  731. LastTimeDelta = ( LastSysTime.QuadPart - LogEntry.SysTime.QuadPart ) / 10000000.0;
  732. FirstTimeDelta = ( FirstEntryTime.QuadPart - LogEntry.SysTime.QuadPart ) / 10000000.0;
  733. if ( PrintTime ) {
  734. dprintf("%8.3f %6.3f: (%4hu, 0x%02X) ", FirstTimeDelta, LastTimeDelta,
  735. LogEntry.LineNo, LogEntry.Type );
  736. }
  737. PrintTime = TRUE;
  738. switch ( LogEntry.Type ) {
  739. case MemLogInitLog:
  740. dprintf("Memory Log Init'ed\n");
  741. break;
  742. case MemLogInitHB:
  743. dprintf("Heartbeats Init'ed\n");
  744. break;
  745. case MemLogHBStarted:
  746. dprintf("START: Period = %u ms\n", LogEntry.Arg1);
  747. break;
  748. case MemLogHBStopped:
  749. dprintf("STOPPED\n");
  750. break;
  751. case MemLogHBDpcRunning:
  752. dprintf("DPC not removed. HeartBeatDpcRunning = %s\n",
  753. TrueOrFalse( LogEntry.Arg1 ));
  754. break;
  755. case MemLogWaitForDpcFinish:
  756. dprintf("DPC: Waiting to finish running\n");
  757. break;
  758. case MemLogMissedIfHB:
  759. dprintf("HB MISSED on interface. Node = %u net = %u",
  760. LogEntry.Arg1, LogEntry.Arg2);
  761. PrintTime = FALSE;
  762. break;
  763. case MemLogMissedIfHB1:
  764. dprintf(" (IF @ %p) MissedHBCount = %d\n", LogEntry.Arg1, LogEntry.Arg2);
  765. break;
  766. case MemLogFailingIf:
  767. dprintf("IF FAILED. Node = %d, net = %d",
  768. LogEntry.Arg1, LogEntry.Arg2);
  769. PrintTime = FALSE;
  770. break;
  771. case MemLogFailingIf1:
  772. dprintf(" (IF @ %p) IF State = %s\n", LogEntry.Arg1, InterfaceState[LogEntry.Arg2]);
  773. break;
  774. case MemLogSendHBWalkNode:
  775. dprintf("Walking node %d to send HB. MMState = %s\n",
  776. LogEntry.Arg1, NodeObjMemberState[LogEntry.Arg2]);
  777. break;
  778. case MemLogCheckHBWalkNode:
  779. dprintf("Walking node %d to check for HB. MMState = %s.\n",
  780. LogEntry.Arg1, NodeObjMemberState[LogEntry.Arg2]);
  781. break;
  782. case MemLogCheckHBNodeReachable:
  783. dprintf("Node %d is currently %sreachable\n", LogEntry.Arg1,
  784. (LogEntry.Arg2 ? "" : "NOT "));
  785. break;
  786. case MemLogCheckHBMissedHB:
  787. dprintf("NODE MISSED HB on all IFs. MissedHBCount = %u MMState = %s\n",
  788. LogEntry.Arg1, NodeObjMemberState[LogEntry.Arg2]);
  789. break;
  790. case MemLogSendingHB:
  791. dprintf("Sending HB to Node %d on net %d\n", LogEntry.Arg1, LogEntry.Arg2);
  792. break;
  793. case MemLogNodeDown:
  794. dprintf("NODE DOWN EVENT for node %d\n", LogEntry.Arg1);
  795. break;
  796. case MemLogSetDpcEvent:
  797. dprintf("DPC: setting finished event\n");
  798. break;
  799. case MemLogNoNetID:
  800. dprintf("BAD NET POINTER: Recv'd packet from node %d (%p)\n",
  801. LogEntry.Arg1, LogEntry.Arg2);
  802. break;
  803. case MemLogOnlineIf:
  804. dprintf("NODE %d ONLINE. IF State = %s\n", LogEntry.Arg1,
  805. InterfaceState[LogEntry.Arg2]);
  806. break;
  807. case MemLogSeqAckMismatch:
  808. dprintf("Recv'ed ack off with seq on IF %p. IF State = %s\n",
  809. LogEntry.Arg1, InterfaceState[LogEntry.Arg2]);
  810. break;
  811. case MemLogNodeUp:
  812. dprintf("NODE UP EVENT for node %d\n", LogEntry.Arg1);
  813. break;
  814. case MemLogReceivedPacket:
  815. dprintf("Recv'ed HB from Node %d, net %d", LogEntry.Arg1, LogEntry.Arg2);
  816. PrintTime = FALSE;
  817. break;
  818. case MemLogReceivedPacket1:
  819. dprintf(" (S: %u A: %u)\n", LogEntry.Arg1, LogEntry.Arg2);
  820. break;
  821. case MemLogDpcTimeSkew:
  822. dprintf("HB DPC fired %8.3f ms late\n", (double)(LogEntry.Arg1/10000.0));
  823. break;
  824. case MemLogHBPacketSend:
  825. dprintf("%s Packet handed to CNP", CcmpMessageTypes[ LogEntry.Arg1 ]);
  826. if ( LogEntry.Arg1 == CcmpHeartbeatMsgType )
  827. dprintf(" (S:%u)", LogEntry.Arg2);
  828. else if ( LogEntry.Arg1 == CcmpPoisonMsgType )
  829. dprintf(" by %s", LogEntry.Arg2 == 1 ? "Heartbeat DPC" : "clussvc" );
  830. dprintf("\n");
  831. break;
  832. case MemLogHBPacketSendComplete:
  833. dprintf("%s Packet Send completed", CcmpMessageTypes[ LogEntry.Arg1 ]);
  834. if ( LogEntry.Arg1 == CcmpHeartbeatMsgType )
  835. dprintf(" (S:%u)", LogEntry.Arg2);
  836. else if ( LogEntry.Arg1 == CcmpPoisonMsgType )
  837. dprintf(" by %s", LogEntry.Arg2 == 1 ? "Heartbeat DPC" : "clussvc" );
  838. dprintf("\n");
  839. break;
  840. case MemLogPoisonPktReceived:
  841. dprintf("Poison Packet received from node %u\n", LogEntry.Arg1);
  842. break;
  843. case MemLogOuterscreen:
  844. dprintf("Outerscreen changed to %04X\n",
  845. ((LogEntry.Arg1 & 0xFF ) << 8) | ((LogEntry.Arg1 >> 8 ) & 0xFF ));
  846. break;
  847. case MemLogNodeDownIssued:
  848. dprintf("Node %u NodeDownIssued set to %s\n",
  849. LogEntry.Arg1, TrueOrFalse( LogEntry.Arg2 ));
  850. break;
  851. case MemLogRegroupFinished:
  852. dprintf("REGROUP FINISHED. New Epoch = %u\n", LogEntry.Arg1 );
  853. break;
  854. case MemLogInconsistentStates:
  855. dprintf("INCONSISTENT STATES. STARTING NEW REGROUP. Node = %u, MMState = %s\n",
  856. LogEntry.Arg1, NodeObjMemberState[ LogEntry.Arg2 ]);
  857. break;
  858. case MemLogOutOfSequence:
  859. dprintf("Out Of Sequence Packet from Node = %u, SeqNo = %u\n",
  860. LogEntry.Arg1, LogEntry.Arg2 );
  861. break;
  862. case MemLogInvalidSignature:
  863. dprintf("Packet with bad Signature from Node = %u, type = %s\n",
  864. LogEntry.Arg1, CcmpMessageTypes[ LogEntry.Arg2 ]);
  865. break;
  866. case MemLogSignatureSize:
  867. dprintf("Invalid Signature buffer size from Node = %u, size = %u\n",
  868. LogEntry.Arg1, LogEntry.Arg2 );
  869. break;
  870. case MemLogNoSecurityContext:
  871. dprintf("No context to verify signature for Node = %u\n",
  872. LogEntry.Arg1 );
  873. break;
  874. case MemLogPacketSendFailed:
  875. dprintf("Packet not sent to Node %d, status = %08X\n",
  876. LogEntry.Arg1, LogEntry.Arg2 );
  877. break;
  878. default:
  879. dprintf(" unknown event, Arg1 = %p Arg2 = %p\n",
  880. LogEntry.Arg1, LogEntry.Arg2);
  881. }
  882. LastSysTime.QuadPart = LogEntry.SysTime.QuadPart;
  883. --TargetLogEntry;
  884. }
  885. if ( ++Pass < 2 ) {
  886. NumEntries = LogEntries - NextLogEntry - 1;
  887. TargetLogEntry = TargetMemLog + LogEntries - 1;
  888. }
  889. }
  890. } // memlog
  891. DECLARE_API( mlfind )
  892. /*
  893. * list the entry nums of the specified events in the memory log
  894. */
  895. {
  896. PMEMLOG_ENTRY TargetMemLog;
  897. PMEMLOG_ENTRY TargetLogEntry;
  898. MEMLOG_ENTRY LogEntry;
  899. PULONG TargetLogEntries;
  900. ULONG LogEntries;
  901. PULONG TargetNextLogEntry;
  902. ULONG NextLogEntry;
  903. LONG NumEntries;
  904. ULONG i;
  905. DOUBLE FirstTimeDelta;
  906. LARGE_INTEGER FirstEntryTime;
  907. MEMLOG_TYPES LogType;
  908. ULONG EntryDelta;
  909. if ( *args == '\0' ) {
  910. dprintf("Event type must be specified\n");
  911. return;
  912. }
  913. LogType = (MEMLOG_TYPES)GetExpression( args );
  914. //
  915. // get address of MemLog and read its contents to get the real start
  916. // of the log
  917. //
  918. TargetMemLog = (PMEMLOG_ENTRY)GetExpression( "clusnet!memlog" );
  919. if ( !TargetMemLog ) {
  920. dprintf( "Can't find symbol clusnet!memlog\n" );
  921. return;
  922. }
  923. if ( !ReadTargetMemory( TargetMemLog, &TargetMemLog, sizeof( PMEMLOG_ENTRY ))) {
  924. return;
  925. }
  926. //
  927. // repeat this process, getting the size of the log and the next entry index
  928. //
  929. TargetLogEntries = (PULONG)GetExpression( "clusnet!memlogentries" );
  930. if ( !TargetLogEntries ) {
  931. dprintf( "Can't find symbol clusnet!memlogentries\n" );
  932. return;
  933. }
  934. if ( !ReadTargetMemory( TargetLogEntries, &LogEntries, sizeof( ULONG ))) {
  935. return;
  936. }
  937. TargetNextLogEntry = (PULONG)GetExpression( "clusnet!memlognextlogentry" );
  938. if ( !TargetNextLogEntry ) {
  939. dprintf( "Can't find symbol clusnet!memlognextlogentry\n" );
  940. return;
  941. }
  942. if ( !ReadTargetMemory( TargetNextLogEntry, &NextLogEntry, sizeof( ULONG ))) {
  943. return;
  944. }
  945. dprintf("MemLog @ %p, Log Entries = %d, Next Entry = %d (%p)\n",
  946. TargetMemLog, LogEntries, NextLogEntry, TargetMemLog + NextLogEntry);
  947. FirstEntryTime.QuadPart = 0;
  948. //
  949. // look through the log twice. next entry might have wrapped so first time we
  950. // dump all the entries down to the base. Next time we start at the end and
  951. // dump out the remaining entries
  952. for ( i = 0; i < 2; ++i ) {
  953. if ( i == 0 ) {
  954. NumEntries = NextLogEntry;
  955. TargetLogEntry = TargetMemLog + NumEntries;
  956. } else {
  957. NumEntries = LogEntries - NextLogEntry - 1;
  958. TargetLogEntry = TargetMemLog + LogEntries;
  959. }
  960. while ( --TargetLogEntry, NumEntries-- ) {
  961. if (CheckControlC()) {
  962. return;
  963. }
  964. if ( !ReadTargetMemory(TargetLogEntry, &LogEntry, sizeof( MEMLOG_ENTRY ))) {
  965. dprintf("can't read log entry (%p) from memory\n\n", TargetLogEntry);
  966. return;
  967. }
  968. if ( LogEntry.Type == 0 )
  969. break;
  970. if ( FirstEntryTime.QuadPart == 0 ) {
  971. FirstEntryTime.QuadPart = LogEntry.SysTime.QuadPart;
  972. }
  973. if ( LogEntry.Type != LogType )
  974. continue;
  975. FirstTimeDelta = ( FirstEntryTime.QuadPart - LogEntry.SysTime.QuadPart ) / 10000000.0;
  976. EntryDelta = (DWORD)(TargetLogEntry - TargetMemLog);
  977. dprintf("%8.3f: (%5hu) Entry at %d (0x%X)\n", FirstTimeDelta, LogEntry.LineNo,
  978. EntryDelta, EntryDelta);
  979. }
  980. }
  981. } // mlfind
  982. DECLARE_API( events )
  983. //
  984. // run down the event file handle list, dumping interesting info for each one
  985. //
  986. {
  987. PCN_FSCONTEXT targetFSContext;
  988. PCN_FSCONTEXT lastFSContext;
  989. CN_FSCONTEXT localFSContext;
  990. LIST_ENTRY localListHead;
  991. PLIST_ENTRY targetListHead;
  992. PCLUSNET_EVENT_ENTRY nextEvent;
  993. CLUSNET_EVENT_ENTRY localEvent;
  994. //
  995. // get the event file handle list head
  996. //
  997. targetListHead = (PLIST_ENTRY)GetExpression( "clusnet!eventfilehandles" );
  998. if ( !targetListHead ) {
  999. dprintf("Can't convert clusnet!eventfilehandles symbol\n");
  1000. return;
  1001. }
  1002. //
  1003. // read CN FS context object listhead out of target's memory
  1004. //
  1005. if ( !ReadTargetMemory( targetListHead, &localListHead, sizeof(LIST_ENTRY))) {
  1006. dprintf("Can't get EventFileHandles data\n");
  1007. return;
  1008. }
  1009. targetFSContext = (PCN_FSCONTEXT)localListHead.Flink;
  1010. lastFSContext = (PCN_FSCONTEXT)targetListHead;
  1011. if ( targetFSContext == lastFSContext ) {
  1012. dprintf("No file objects in EventFileHandles\n");
  1013. return;
  1014. }
  1015. while ( targetFSContext != lastFSContext ) {
  1016. if (CheckControlC()) {
  1017. return;
  1018. }
  1019. //
  1020. // read FS context struct out of target's memory
  1021. //
  1022. targetFSContext = CONTAINING_RECORD( targetFSContext, CN_FSCONTEXT, Linkage );
  1023. if ( !ReadTargetMemory( targetFSContext, &localFSContext, sizeof( CN_FSCONTEXT ))) {
  1024. dprintf("Problem reading FS context at %p\n", targetFSContext );
  1025. return;
  1026. }
  1027. #if DBG
  1028. if ( localFSContext.Signature != CN_CONTROL_CHANNEL_SIG ) {
  1029. dprintf( "CN_FSCONTEXT @ %p has the wrong signature\n", targetFSContext );
  1030. }
  1031. #endif
  1032. dprintf( "\nFSContext @ %p\n\n", targetFSContext );
  1033. dprintf( " Next FSContext @ %p\n", localFSContext.Linkage.Flink );
  1034. dprintf( " Event Mask %08X\n", localFSContext.EventMask );
  1035. dprintf( " Event IRP @ %p\n", localFSContext.EventIrp );
  1036. dprintf( " Event list @ %p %s\n", &targetFSContext->EventList,
  1037. ListInUse( &targetFSContext->EventList, &localFSContext.EventList ));
  1038. nextEvent = (PCLUSNET_EVENT_ENTRY)localFSContext.EventList.Flink;
  1039. while ( &targetFSContext->EventList != (PLIST_ENTRY)nextEvent ) {
  1040. if (CheckControlC()) {
  1041. break;
  1042. }
  1043. nextEvent = CONTAINING_RECORD( nextEvent, CLUSNET_EVENT_ENTRY, Linkage );
  1044. if ( !ReadTargetMemory( nextEvent, &localEvent, sizeof( CLUSNET_EVENT_ENTRY ))) {
  1045. break;
  1046. }
  1047. DumpEventData( nextEvent, &localEvent );
  1048. nextEvent = (PCLUSNET_EVENT_ENTRY)localEvent.Linkage.Flink;
  1049. }
  1050. targetFSContext = (PCN_FSCONTEXT)localFSContext.Linkage.Flink;
  1051. }
  1052. } // events
  1053. DWORD
  1054. GetEventTypeIndex(
  1055. CLUSNET_EVENT_TYPE EventType
  1056. )
  1057. /*++
  1058. Routine Description:
  1059. Description
  1060. Arguments:
  1061. None
  1062. Return Value:
  1063. None
  1064. --*/
  1065. {
  1066. DWORD index;
  1067. for ( index = 0; index < 10; ++index ) {
  1068. if ( ( 1 << index ) & EventType ) {
  1069. return index + 1;
  1070. }
  1071. }
  1072. return 0;
  1073. }
  1074. VOID
  1075. DumpEventData(
  1076. PCLUSNET_EVENT_ENTRY EventAddress,
  1077. PCLUSNET_EVENT_ENTRY EventEntry
  1078. )
  1079. /*++
  1080. Routine Description:
  1081. Description
  1082. Arguments:
  1083. None
  1084. Return Value:
  1085. None
  1086. --*/
  1087. {
  1088. dprintf(" Event @ %p\n", EventAddress );
  1089. dprintf(" Epoch %u\n", EventEntry->EventData.Epoch );
  1090. dprintf(" Type 0x%03X (%s)\n",
  1091. EventEntry->EventData.EventType,
  1092. EventTypes[ GetEventTypeIndex( EventEntry->EventData.EventType )]);
  1093. dprintf(" NodeId %u\n", EventEntry->EventData.NodeId );
  1094. dprintf(" NetId %u (%08X)\n", EventEntry->EventData.NetworkId,
  1095. EventEntry->EventData.NetworkId);
  1096. }
  1097. DECLARE_API( fsctxt )
  1098. /*
  1099. * dump the specified clusnet file object context struct
  1100. */
  1101. {
  1102. PCN_FSCONTEXT targetFSContext;
  1103. CN_FSCONTEXT localFSContext;
  1104. if ( *args == '\0' ) {
  1105. dprintf("Address must be specified\n");
  1106. return;
  1107. }
  1108. targetFSContext = (PCN_FSCONTEXT)GetExpression( args );
  1109. if ( !targetFSContext ) {
  1110. dprintf("bad string conversion (%s) \n", args );
  1111. return;
  1112. }
  1113. //
  1114. // read network object struct out of target's memory
  1115. //
  1116. if ( !ReadTargetMemory( targetFSContext, &localFSContext, sizeof( CN_FSCONTEXT ))) {
  1117. dprintf("Problem reading FS Context obj at %p\n", targetFSContext );
  1118. return;
  1119. }
  1120. #if DBG
  1121. if ( localFSContext.Signature != CN_CONTROL_CHANNEL_SIG ) {
  1122. dprintf( "CN_FSCONTEXT @ %p has the wrong signature\n", targetFSContext );
  1123. }
  1124. #endif
  1125. dprintf( "\nFS Context @ %p\n\n", targetFSContext );
  1126. dprintf( " Next FS Ctxt on EventFileHandles @ %p\n", localFSContext.Linkage.Flink );
  1127. dprintf( " File Obj @ %p\n", localFSContext.FileObject );
  1128. dprintf( " RefCount = %d\n", localFSContext.ReferenceCount );
  1129. dprintf( " CancelIrps = %s\n", TrueOrFalse( localFSContext.CancelIrps ));
  1130. dprintf( " ShutdownOnClose = %s\n", TrueOrFalse( localFSContext.ShutdownOnClose ));
  1131. dprintf( " CleanupEvent @ %p\n", &targetFSContext->CleanupEvent );
  1132. dprintf( " Event List @ %p %s\n",
  1133. &targetFSContext->EventList,
  1134. ListInUse( &targetFSContext->EventList, &localFSContext.EventList ));
  1135. dprintf( " EventIrp @ %p\n", localFSContext.EventIrp );
  1136. dprintf( " EventMask = %08X\n", localFSContext.EventMask );
  1137. dprintf( " Krn Event Callback @ %p\n", localFSContext.KmodeEventCallback );
  1138. } // fsctxt
  1139. DECLARE_API( sendreq )
  1140. /*
  1141. * dump the specified CNP send request struct
  1142. */
  1143. {
  1144. PCNP_SEND_REQUEST targetCnpSendReq;
  1145. CNP_SEND_REQUEST localCnpSendReq;
  1146. if ( *args == '\0' ) {
  1147. dprintf("Address must be specified\n");
  1148. return;
  1149. }
  1150. targetCnpSendReq = (PCNP_SEND_REQUEST)GetExpression( args );
  1151. if ( !targetCnpSendReq ) {
  1152. dprintf("bad string conversion (%s) \n", args );
  1153. return;
  1154. }
  1155. //
  1156. // read send request struct out of target's memory
  1157. //
  1158. if ( !ReadTargetMemory( targetCnpSendReq, &localCnpSendReq, sizeof( CNP_SEND_REQUEST ))) {
  1159. dprintf("Problem reading CNP send request at %p\n", targetCnpSendReq );
  1160. return;
  1161. }
  1162. dprintf( "\nCNP Send Request @ %p\n\n", targetCnpSendReq );
  1163. dprintf( " CnResource @ %p\n", &targetCnpSendReq->CnResource );
  1164. dprintf( " HeaderMdl @ %p\n", localCnpSendReq.HeaderMdl );
  1165. dprintf( " CnpHeader @ %p\n", localCnpSendReq.CnpHeader );
  1166. dprintf( " UpperProtocolIrp @ %p\n", localCnpSendReq.UpperProtocolIrp );
  1167. dprintf( " UpperProtocolHeader @ %p\n", localCnpSendReq.UpperProtocolHeader );
  1168. dprintf( " UpperProtocolHeaderLength %d\n", localCnpSendReq.UpperProtocolHeaderLength );
  1169. dprintf( " UpperProtocolIrpMode %d\n", localCnpSendReq.UpperProtocolIrpMode );
  1170. dprintf( " UpperProtocolMdl @ %p\n", localCnpSendReq.UpperProtocolMdl );
  1171. dprintf( " UpperProtocolContext @ %p\n", localCnpSendReq.UpperProtocolContext );
  1172. dprintf( " CompletionRoutine @ %p\n", localCnpSendReq.CompletionRoutine );
  1173. dprintf( " Network @ %p\n", localCnpSendReq.Network );
  1174. dprintf( " DestAddress @ %p\n", localCnpSendReq.TdiSendDatagramInfo.RemoteAddress );
  1175. dprintf( " Multicast Group @ %p\n", localCnpSendReq.McastGroup );
  1176. } // fsctxt
  1177. #if 0
  1178. // from when regroup was in the kernel
  1179. DECLARE_API( rgpdump )
  1180. /*
  1181. * dump the regroup struct
  1182. */
  1183. {
  1184. rgp_control_t **TargetRGPAddress;
  1185. rgp_control_t *TargetRGP;
  1186. rgp_control_t LocalRGP;
  1187. OS_specific_rgp_control_t *Local_rgpos; // points to local memory
  1188. OS_specific_rgp_control_t *Target_rgpos; // points to target memory
  1189. BOOL success;
  1190. LONG BytesRead;
  1191. //
  1192. // get address of RGP symbol
  1193. //
  1194. TargetRGPAddress = (rgp_control_t **)GetExpression( "Clusnet!rgp" );
  1195. if ( !TargetRGPAddress ) {
  1196. dprintf("Can't convert Clusnet!rgp symbol\n");
  1197. return;
  1198. }
  1199. //
  1200. // read address of RGP block
  1201. //
  1202. if ( !ReadTargetMemory((PVOID)TargetRGPAddress,
  1203. (PVOID)&TargetRGP,
  1204. sizeof(rgp_control_t *))) {
  1205. return;
  1206. }
  1207. //
  1208. // read actual RGP block into our local buffer
  1209. //
  1210. if ( !ReadTargetMemory((PVOID)TargetRGP,
  1211. (PVOID)&LocalRGP,
  1212. sizeof( rgp_control_t ))) {
  1213. return;
  1214. }
  1215. Target_rgpos = &TargetRGP->OS_specific_control;
  1216. Local_rgpos = &LocalRGP.OS_specific_control;
  1217. dprintf( "RGP @ %p\n\n", TargetRGP );
  1218. dprintf( "info:\n" );
  1219. dprintf( " Version = %u\n", LocalRGP.rgpinfo.version );
  1220. dprintf( " Seq number = %u\n", LocalRGP.rgpinfo.seqnum );
  1221. dprintf( " Clock Period = %hu ms\n", LocalRGP.rgpinfo.a_tick );
  1222. dprintf( " I Am Alive ticks = %hu\n", LocalRGP.rgpinfo.iamalive_ticks );
  1223. dprintf( " Check ticks = %hu\n", LocalRGP.rgpinfo.check_ticks );
  1224. dprintf( " Min stage1 ticks = %hu\n", LocalRGP.rgpinfo.Min_Stage1_ticks );
  1225. DumpClusterMask( " Cluster mask = ", &LocalRGP.rgpinfo.cluster );
  1226. dprintf( " My node = %hu\n", LocalRGP.mynode );
  1227. dprintf( " Tiebreaker node = %hu\n", LocalRGP.tiebreaker );
  1228. dprintf( " Number of nodes in cluster = %u\n", LocalRGP.num_nodes );
  1229. dprintf( " Clock tick counter = %hu\n", LocalRGP.clock_ticks );
  1230. dprintf( " RGP counter = %hu\n", LocalRGP.rgpcounter );
  1231. dprintf( " Restart counter = %hu\n", LocalRGP.restartcount );
  1232. dprintf( " Pruning ticks = %hu\n", LocalRGP.pruning_ticks );
  1233. dprintf( " PFail State = %hu\n", LocalRGP.pfail_state );
  1234. dprintf( " Cautious Mode = %u\n", LocalRGP.cautiousmode );
  1235. dprintf( " Send Stage = %u\n", LocalRGP.sendstage );
  1236. dprintf( " Tie Breaker Selected = %u\n", LocalRGP.tiebreaker_selected );
  1237. dprintf( " Has Unreachable Nodes = %u\n", LocalRGP.has_unreachable_nodes );
  1238. DumpClusterMask( " Outer Screen = ", &LocalRGP.outerscreen );
  1239. DumpClusterMask( " Inner Screen = ", &LocalRGP.innerscreen );
  1240. DumpClusterMask( " Status Targets = ", &LocalRGP.status_targets );
  1241. DumpClusterMask( " Poison Targets = ", &LocalRGP.poison_targets );
  1242. DumpClusterMask( " Init Nodes = ", &LocalRGP.initnodes );
  1243. DumpClusterMask( " End Nodes = ", &LocalRGP.endnodes );
  1244. DumpClusterMask( " Unreachable Nodes = ", &LocalRGP.unreachable_nodes );
  1245. DumpRGPOSSpecific( &TargetRGP->OS_specific_control, &LocalRGP.OS_specific_control );
  1246. }
  1247. DECLARE_API( rgposdump )
  1248. /*
  1249. * dump just the OS specific portion of the regroup struct
  1250. */
  1251. {
  1252. rgp_control_t **TargetRGPAddress;
  1253. rgp_control_t *TargetRGP;
  1254. rgp_control_t LocalRGP;
  1255. OS_specific_rgp_control_t *Local_rgpos; // points to local memory
  1256. OS_specific_rgp_control_t *Target_rgpos; // points to target memory
  1257. BOOL success;
  1258. LONG BytesRead;
  1259. //
  1260. // get address of RGP symbol
  1261. //
  1262. TargetRGPAddress = (rgp_control_t **)GetExpression( "Clusnet!rgp" );
  1263. if ( !TargetRGPAddress ) {
  1264. dprintf("Can't convert Clusnet!rgp symbol\n");
  1265. return;
  1266. }
  1267. //
  1268. // read address of RGP block
  1269. //
  1270. if ( !ReadTargetMemory((PVOID)TargetRGPAddress,
  1271. (PVOID)&TargetRGP,
  1272. sizeof(rgp_control_t *))) {
  1273. return;
  1274. }
  1275. //
  1276. // read actual RGP block into our local buffer
  1277. //
  1278. if ( !ReadTargetMemory((PVOID)TargetRGP,
  1279. (PVOID)&LocalRGP,
  1280. sizeof( rgp_control_t ))) {
  1281. return;
  1282. }
  1283. Target_rgpos = &TargetRGP->OS_specific_control;
  1284. Local_rgpos = &LocalRGP.OS_specific_control;
  1285. dprintf( "RGP @ %p\n\n", TargetRGP );
  1286. DumpRGPOSSpecific( &TargetRGP->OS_specific_control, &LocalRGP.OS_specific_control );
  1287. }
  1288. VOID
  1289. DumpRGPOSSpecific(
  1290. OS_specific_rgp_control_t *Target_rgpos,
  1291. OS_specific_rgp_control_t *Local_rgpos
  1292. )
  1293. {
  1294. dprintf( "OS specific\n" );
  1295. dprintf( "RGP Counters:\n" );
  1296. DumpRGPCounters( &Local_rgpos->counter );
  1297. DumpClusterMask( " CPUUPMASK = ", &Local_rgpos->CPUUPMASK );
  1298. dprintf( " RgpLock @ %p\n", &Target_rgpos->RgpLock );
  1299. dprintf( " RGPTimer @ %p\n", &Target_rgpos->RGPTimer );
  1300. dprintf( " PeriodicCheckDPC @ %p\n", &Target_rgpos->PeriodicCheckDPC );
  1301. dprintf( " TimerDPCFinished @ %p\n", &Target_rgpos->TimerDPCFinished );
  1302. dprintf( " CallbackLock @ %p\n", &Target_rgpos->CallbackLock );
  1303. dprintf( " CallbackIRP @ %p\n", &Target_rgpos->CallbackIrp );
  1304. dprintf( " CallbackEvents @ %p %s\n", &Target_rgpos->CallbackEvents,
  1305. ListInUse( &Local_rgpos->CallbackEvents ));
  1306. dprintf( " SendMsgQLock @ %p\n", &Target_rgpos->SendMsgQLock );
  1307. dprintf( " SendMsgQDPC @ %p\n", &Target_rgpos->SendMsgQDPC );
  1308. dprintf( " SendMsgQ @ %p %s\n", &Target_rgpos->SendMsgQ,
  1309. ListInUse( &Local_rgpos->SendMsgQ ));
  1310. dprintf( " MsgShutdown: %s\n", TrueFalse( Local_rgpos->MsgShutdown ));
  1311. dprintf( " MsgDPCQueued: %s\n", TrueFalse( Local_rgpos->MsgDPCQueued ));
  1312. dprintf( " MsgDPCFinished @ %p\n", &Target_rgpos->MsgDPCFinished );
  1313. DumpClusterMask( " NeedsNodeDownCallback = ", &Local_rgpos->NeedsNodeDownCallback );
  1314. } // rgpdump
  1315. VOID
  1316. DumpRGPCounters(
  1317. rgp_counter_t *counters
  1318. )
  1319. {
  1320. dprintf( " QueuedIAmAlive = %u\n", counters->QueuedIAmAlive );
  1321. dprintf( " RcvdLocalIAmAlive = %u\n", counters->RcvdLocalIAmAlive );
  1322. dprintf( " RcvdRemoteIAmAlive = %u\n", counters->RcvdRemoteIAmAlive );
  1323. dprintf( " RcvdRegroup = %u\n", counters->RcvdRegroup );
  1324. }
  1325. VOID
  1326. DumpClusterMask(
  1327. PCHAR Title,
  1328. cluster_t *nodemask
  1329. )
  1330. {
  1331. UINT i;
  1332. dprintf( Title );
  1333. for ( i = 0; i < BYTES_IN_CLUSTER; ++i ) {
  1334. dprintf("%02X", (ULONG)(*nodemask[i]) );
  1335. }
  1336. dprintf("\n");
  1337. }
  1338. #endif
  1339. BOOL
  1340. ReadNodeTable(
  1341. PCNP_NODE **LocalNodeTable,
  1342. CL_NODE_ID *MaxNodeId,
  1343. CL_NODE_ID *MinNodeId
  1344. )
  1345. /*++
  1346. Routine Description:
  1347. Description
  1348. Arguments:
  1349. None
  1350. Return Value:
  1351. None
  1352. --*/
  1353. {
  1354. PCNP_NODE TargetNodeTable;
  1355. CL_NODE_ID *TargetMaxNodeId;
  1356. CL_NODE_ID *TargetMinNodeId;
  1357. ULONG NumberOfValidNodes;
  1358. //
  1359. // get the address of the node table symbol on the target machine
  1360. //
  1361. TargetNodeTable = (PCNP_NODE)GetExpression( "clusnet!cnpnodetable" );
  1362. if ( !TargetNodeTable ) {
  1363. dprintf("Can't convert clusnet!cnpnnodetable symbol\n");
  1364. return FALSE;
  1365. }
  1366. if ( !ReadTargetMemory( TargetNodeTable, &TargetNodeTable, sizeof(PCNP_NODE))) {
  1367. dprintf("Can't get pointer to target node table\n");
  1368. return FALSE;
  1369. }
  1370. if ( TargetNodeTable == NULL ) {
  1371. dprintf("Node Table hasn't been allocated.\n");
  1372. return FALSE;
  1373. }
  1374. //
  1375. // get lowest and highest valid node in the cluster
  1376. //
  1377. TargetMaxNodeId = (CL_NODE_ID *)GetExpression( "clusnet!cnmaxvalidnodeid" );
  1378. if ( !TargetMaxNodeId ) {
  1379. dprintf("Can't convert clusnet!cnmaxvalidnodeid symbol\n");
  1380. return FALSE;
  1381. }
  1382. if ( !ReadTargetMemory( TargetMaxNodeId, MaxNodeId, sizeof(CL_NODE_ID))) {
  1383. dprintf("Can't get Max Node ID data\n");
  1384. return FALSE;
  1385. }
  1386. TargetMinNodeId = (CL_NODE_ID *)GetExpression( "clusnet!cnminvalidnodeid" );
  1387. if ( !TargetMinNodeId ) {
  1388. dprintf("Can't convert clusnet!cnMinvalidnodeid symbol\n");
  1389. return FALSE;
  1390. }
  1391. if ( !ReadTargetMemory( TargetMinNodeId, MinNodeId, sizeof(CL_NODE_ID))) {
  1392. dprintf("Can't get Min Node ID data\n");
  1393. return FALSE;
  1394. }
  1395. //
  1396. // allocate space for local copy of node table. The max and min are added
  1397. // together since Node Ids may not be zero based while the node table is
  1398. // zero based.
  1399. //
  1400. NumberOfValidNodes = *MaxNodeId + *MinNodeId;
  1401. *LocalNodeTable = malloc( NumberOfValidNodes * sizeof( PCNP_NODE ));
  1402. if ( !*LocalNodeTable ) {
  1403. dprintf("Can't get local mem for node table\n");
  1404. return FALSE;
  1405. }
  1406. //
  1407. // read node table from target memory
  1408. //
  1409. if ( !ReadTargetMemory(TargetNodeTable,
  1410. *LocalNodeTable,
  1411. ClusterDefaultMaxNodes * sizeof(PCNP_NODE))) {
  1412. dprintf("Can't get local copy of node table data\n");
  1413. return FALSE;
  1414. }
  1415. return TRUE;
  1416. }
  1417. BOOL
  1418. ReadTargetMemory(
  1419. PVOID TargetAddress,
  1420. PVOID LocalBuffer,
  1421. ULONG BytesToRead
  1422. )
  1423. {
  1424. BOOL success;
  1425. ULONG BytesRead;
  1426. success = ReadMemory((ULONG_PTR)TargetAddress, LocalBuffer, BytesToRead, &BytesRead);
  1427. if (success) {
  1428. if (BytesRead != BytesToRead) {
  1429. dprintf("wrong byte count. expected=%d, read =%d\n", BytesToRead, BytesRead);
  1430. }
  1431. } else {
  1432. dprintf("Problem reading memory at %p for %u bytes\n",
  1433. TargetAddress, BytesToRead);
  1434. success = FALSE;
  1435. }
  1436. return success;
  1437. }
  1438. __inline PCHAR
  1439. ListInUse(
  1440. PLIST_ENTRY ListHead,
  1441. PLIST_ENTRY ListToCheck
  1442. )
  1443. {
  1444. return ListToCheck->Flink == ListHead ? "(empty)" : "";
  1445. }
  1446. __inline PCHAR
  1447. TrueFalse(
  1448. BOOLEAN Value
  1449. )
  1450. {
  1451. return Value ? "TRUE" : "FALSE";
  1452. }
  1453. VOID
  1454. DprintUnicodeString(
  1455. PUNICODE_STRING UnicodeString,
  1456. DWORD_PTR AddrString,
  1457. PCHAR Symbol OPTIONAL,
  1458. DWORD_PTR Displacement OPTIONAL
  1459. )
  1460. {
  1461. ANSI_STRING AnsiString;
  1462. LPSTR StringData;
  1463. BOOL b;
  1464. StringData = malloc(UnicodeString->Length+sizeof(UNICODE_NULL));
  1465. if ( StringData == NULL ) {
  1466. dprintf("Unable to allocate memory for string buffer\n");
  1467. return;
  1468. }
  1469. b = ReadMemory((ULONG_PTR)UnicodeString->Buffer,
  1470. StringData,
  1471. UnicodeString->Length,
  1472. NULL);
  1473. if ( !b ) {
  1474. free(StringData);
  1475. return;
  1476. }
  1477. UnicodeString->Buffer = (PWSTR)StringData;
  1478. UnicodeString->MaximumLength = UnicodeString->Length+(USHORT)sizeof(UNICODE_NULL);
  1479. RtlUnicodeStringToAnsiString(&AnsiString,UnicodeString,TRUE);
  1480. free(StringData);
  1481. if (Symbol == NULL || Displacement == (DWORD_PTR) NULL) {
  1482. dprintf("String(%d,%d) at %p: %s\n",
  1483. UnicodeString->Length,
  1484. UnicodeString->MaximumLength,
  1485. AddrString,
  1486. AnsiString.Buffer
  1487. );
  1488. }
  1489. else {
  1490. dprintf("String(%d,%d) %s+%p at %p: %s\n",
  1491. UnicodeString->Length,
  1492. UnicodeString->MaximumLength,
  1493. Symbol,
  1494. Displacement,
  1495. AddrString,
  1496. AnsiString.Buffer
  1497. );
  1498. }
  1499. RtlFreeAnsiString(&AnsiString);
  1500. } // DprintUnicodeString
  1501. DECLARE_API( help )
  1502. {
  1503. dprintf("Clusnet kd extensions\n\n");
  1504. dprintf("netobj [address] - dump a network object\n");
  1505. dprintf("nodeobj [node ID] - dump a node object\n");
  1506. dprintf("nodeifs <node ID> - dump the interface objects of a node object\n");
  1507. dprintf("currif <node ID> - dump the current interface object of a node object\n");
  1508. dprintf("memlog [starting entry number] - dump the in-memory log\n");
  1509. dprintf("mlfind <entry type> - find all specified entry types in the memory log\n");
  1510. dprintf("events - dump the FS context structs on the EventFileHandles list\n");
  1511. dprintf("fsctxt <address> - dump a CN_FSCONTEXT struct\n");
  1512. dprintf("sendreq <address> - dump a CNP send request struct\n");
  1513. }