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.

866 lines
24 KiB

  1. /*-----------------------------------------------------------------------------
  2. Copyright (c) 2000 Microsoft Corporation
  3. Module:
  4. ncext.c
  5. ------------------------------------------------------------------------------*/
  6. #define ENABLETRACE
  7. #define NCDBGEXT
  8. #define IMPORT_NCDBG_FRIENDS \
  9. friend HRESULT HrDumpConnectionListFromAddress(ULONG64 address); \
  10. friend HRESULT HrDumpNode(LPVOID pvHead, LPVOID pvDbgHead, LPVOID pvNil, DWORD dwLevel);
  11. #include "ncext.h"
  12. // #define VERBOSE
  13. #include "ncmem.h"
  14. #include "ncbase.h"
  15. #include "ncdebug.h"
  16. #include "ncdefine.h"
  17. #include "tracetag.h"
  18. #include "naming.h"
  19. #include "foldinc.h"
  20. #include "connlist.h"
  21. #ifdef VERBOSE
  22. #define dprintfVerbose dprintf
  23. #else
  24. #define dprintfVerbose __noop
  25. #endif
  26. HRESULT HrGetAddressOfSymbol(LPCSTR szSymbol, PULONG64 pAddress)
  27. {
  28. HRESULT hr = E_FAIL;
  29. if (pAddress)
  30. {
  31. *pAddress = 0;
  32. }
  33. if (!szSymbol || !*szSymbol || !pAddress)
  34. {
  35. hr = E_INVALIDARG;
  36. }
  37. else
  38. {
  39. *pAddress = GetExpression(szSymbol);
  40. if (!*pAddress)
  41. {
  42. dprintf("\nCould not find symbol: %s. Is your symbols correct?\n", szSymbol);
  43. }
  44. else
  45. {
  46. dprintfVerbose("%s: %I64lx\n", szSymbol, *pAddress);
  47. hr = S_OK;
  48. }
  49. }
  50. return hr;
  51. }
  52. HRESULT HrGetAddressOfSymbol(LPCSTR szModule, LPCSTR szSymbol, PULONG64 pAddress)
  53. {
  54. HRESULT hr = E_FAIL;
  55. if (pAddress)
  56. {
  57. *pAddress = 0;
  58. }
  59. if (!szModule || !*szModule || !szSymbol || !*szSymbol || !pAddress)
  60. {
  61. hr = E_INVALIDARG;
  62. }
  63. else
  64. {
  65. *pAddress = 0;
  66. CHAR szModulueSymbol[MAX_PATH];
  67. wsprintf(szModulueSymbol, "%s!%s", szModule, szSymbol);
  68. dprintfVerbose("%s: ", szModulueSymbol);
  69. hr = HrGetAddressOfSymbol(szModulueSymbol, pAddress);
  70. }
  71. return hr;
  72. }
  73. HRESULT HrReadMemoryFromUlong(ULONG64 Address, DWORD dwSize, OUT LPVOID pBuffer)
  74. {
  75. HRESULT hr = S_OK;
  76. DWORD cb;
  77. dprintfVerbose("from %I64lx, size=%x\n", Address, dwSize);
  78. if (ReadMemory(Address, pBuffer, dwSize, &cb) && cb == dwSize)
  79. {
  80. hr = S_OK;
  81. }
  82. else
  83. {
  84. dprintf("Could not read content of memory at %I64lx. Content might be paged out.\n", Address);
  85. hr = E_FAIL;
  86. }
  87. return hr;
  88. }
  89. HRESULT HrWriteMemoryFromUlong(ULONG64 Address, DWORD dwSize, OUT LPCVOID pBuffer)
  90. {
  91. HRESULT hr = S_OK;
  92. DWORD cb;
  93. dprintfVerbose("to %I64lx, size=%x\n", Address, dwSize);
  94. if (WriteMemory(Address, pBuffer, dwSize, &cb) && cb == dwSize)
  95. {
  96. hr = S_OK;
  97. }
  98. else
  99. {
  100. dprintf("Could not write content of memory to %I64lx. Address might be paged out.\n", Address);
  101. hr = E_FAIL;
  102. }
  103. return hr;
  104. }
  105. HRESULT HrReadMemory(LPVOID pAddress, DWORD dwSize, OUT LPVOID pBuffer)
  106. {
  107. return HrReadMemoryFromUlong((ULONG64)(ULONG_PTR)pAddress, dwSize, pBuffer);
  108. }
  109. HRESULT HrWriteMemory(LPVOID pAddress, DWORD dwSize, OUT LPCVOID pBuffer)
  110. {
  111. return HrWriteMemoryFromUlong((ULONG64)(ULONG_PTR)pAddress, dwSize, pBuffer);
  112. }
  113. HRESULT HrGetTraceTagsForModule(LPCSTR szModuleName, LPDWORD pdwCount, TRACETAGELEMENT** ppTRACETAGELEMENT)
  114. {
  115. HRESULT hr = E_FAIL;
  116. if (szModuleName && *szModuleName)
  117. {
  118. ULONG64 g_TraceTagCountAddress = 0;
  119. ULONG64 g_TraceTagsAddress = 0;
  120. hr = HrGetAddressOfSymbol(szModuleName, "g_nTraceTagCount", &g_TraceTagCountAddress);
  121. if (SUCCEEDED(hr))
  122. {
  123. INT nTraceTagCount = 0;
  124. hr = HrReadMemoryFromUlong(g_TraceTagCountAddress, sizeof(nTraceTagCount), &nTraceTagCount);
  125. if (SUCCEEDED(hr))
  126. {
  127. *pdwCount = nTraceTagCount;
  128. dprintfVerbose("Number of tags: %d\n", nTraceTagCount);
  129. hr = HrGetAddressOfSymbol(szModuleName, "g_TraceTags", &g_TraceTagsAddress);
  130. if (SUCCEEDED(hr))
  131. {
  132. if (nTraceTagCount)
  133. {
  134. DWORD dwSize = nTraceTagCount * sizeof(TRACETAGELEMENT);
  135. *ppTRACETAGELEMENT = reinterpret_cast<TRACETAGELEMENT*>(LocalAlloc(0, dwSize));
  136. if (*ppTRACETAGELEMENT)
  137. {
  138. dprintfVerbose("Reading %d bytes\n", dwSize);
  139. hr = HrReadMemoryFromUlong(g_TraceTagsAddress, dwSize, *ppTRACETAGELEMENT);
  140. }
  141. else
  142. {
  143. dprintf("Out of memory allocating %d trace elements\n", nTraceTagCount);
  144. }
  145. }
  146. else
  147. {
  148. dprintf("Internal error\n");
  149. }
  150. }
  151. }
  152. else
  153. {
  154. dprintf("*ERROR* Could not read content of %s!g_nTraceTagCount. Value might be paged out.\n", szModuleName);
  155. }
  156. }
  157. }
  158. return hr;
  159. }
  160. HRESULT HrPutTraceTagsForModule(LPCSTR szModuleName, DWORD dwCount, const TRACETAGELEMENT* pTRACETAGELEMENT)
  161. {
  162. HRESULT hr = E_FAIL;
  163. if (szModuleName && *szModuleName)
  164. {
  165. CHAR szTraceExport[MAX_PATH];
  166. wsprintf(szTraceExport, "%s!g_TraceTags", szModuleName);
  167. dprintfVerbose("%s: ", szTraceExport);
  168. ULONG64 pnTraceAddress = GetExpression(szTraceExport);
  169. if (!pnTraceAddress)
  170. {
  171. dprintf("\n### Could not find g_TraceTags export on module %s. Is %s loaded, and is your symbols correct? ###\n", szModuleName, szModuleName);
  172. }
  173. dprintfVerbose("%I64lx\n", pnTraceAddress);
  174. CHAR szTraceCount[MAX_PATH];
  175. wsprintf(szTraceCount, "%s!g_nTraceTagCount", szModuleName);
  176. dprintfVerbose("%s: ", szTraceCount);
  177. ULONG64 pnTraceTagCount = GetExpression(szTraceCount);
  178. if (!pnTraceTagCount)
  179. {
  180. dprintf("\n### Could not find g_nTraceTagCount export on module %s. Is %s loaded, and is your symbols correct? ###\n", szModuleName, szModuleName);
  181. }
  182. dprintfVerbose("%I64lx\n", pnTraceTagCount);
  183. if (pnTraceAddress & pnTraceTagCount)
  184. {
  185. INT nTraceTagCount = 0;
  186. DWORD cb;
  187. hr = HrReadMemoryFromUlong(pnTraceTagCount, sizeof(nTraceTagCount), &nTraceTagCount);
  188. if (SUCCEEDED(hr))
  189. {
  190. dwCount = nTraceTagCount;
  191. if (dwCount != nTraceTagCount)
  192. {
  193. dprintf("Internal Error\n");
  194. }
  195. else
  196. {
  197. dprintfVerbose("Number of tags: %d\n", nTraceTagCount);
  198. if (nTraceTagCount)
  199. {
  200. DWORD dwSize = nTraceTagCount * sizeof(TRACETAGELEMENT);
  201. dprintfVerbose("Writing %d bytes\n", dwSize);
  202. hr = HrWriteMemoryFromUlong(pnTraceAddress, dwSize, pTRACETAGELEMENT);
  203. }
  204. else
  205. {
  206. dprintf("Internal error\n");
  207. }
  208. }
  209. }
  210. else
  211. {
  212. dprintf("*ERROR* Could not read content of %s!g_nTraceTagCount. Value might be paged out.\n", szModuleName);
  213. }
  214. }
  215. }
  216. return hr;
  217. }
  218. //
  219. // Extension to read and dump dwords from target
  220. //
  221. DECLARE_API( tracelist )
  222. {
  223. ULONG cb;
  224. ULONG64 Address;
  225. ULONG Buffer[4];
  226. if (!lstrcmpi(args, "all"))
  227. {
  228. for (int x = 0; x < g_nTraceTagCount; x++)
  229. {
  230. dprintf("%-20s - %s\r\n", g_TraceTags[x].szShortName, g_TraceTags[x].szDescription);
  231. }
  232. }
  233. else
  234. {
  235. if (args && *args)
  236. {
  237. DWORD dwCount;
  238. TRACETAGELEMENT *pTRACETAGELEMENT;
  239. HRESULT hr = HrGetTraceTagsForModule(args, &dwCount, &pTRACETAGELEMENT);
  240. if (SUCCEEDED(hr))
  241. {
  242. for (DWORD x = 0; x < dwCount; x++)
  243. {
  244. if (pTRACETAGELEMENT[x].fOutputDebugString)
  245. {
  246. dprintf(" %s\n", pTRACETAGELEMENT[x].szShortName);
  247. }
  248. }
  249. LocalFree(pTRACETAGELEMENT);
  250. }
  251. }
  252. else
  253. {
  254. dprintf("Usage: !tracelist all - dump all tracetags\n");
  255. dprintf(" !tracelist <module> - dump tracetags enable for module <module>\n");
  256. }
  257. }
  258. }
  259. HRESULT HrEnableDisableTraceTag(LPCSTR argstring, BOOL fEnable)
  260. {
  261. HRESULT hr = E_FAIL;
  262. BOOL fShowUsage = FALSE;
  263. DWORD dwArgLen = lstrlen(argstring);
  264. if (dwArgLen)
  265. {
  266. LPSTR szString = new TCHAR[dwArgLen+1];
  267. if (!szString)
  268. {
  269. dprintf("Out of memory\n");
  270. }
  271. else
  272. {
  273. LPSTR Args[2];
  274. DWORD dwCurrentArg = 0;
  275. lstrcpy(szString, argstring);
  276. Args[0] = szString;
  277. for (DWORD x = 0; (x < dwArgLen) && (dwCurrentArg < celems(Args)); x++)
  278. {
  279. if (szString[x] == ' ')
  280. {
  281. dwCurrentArg++;
  282. szString[x] = '\0';
  283. Args[dwCurrentArg] = szString + x + 1;
  284. }
  285. }
  286. dprintfVerbose("Number of arguments: %d\n", dwCurrentArg + 1);
  287. if (dwCurrentArg != 1)
  288. {
  289. hr = E_INVALIDARG;
  290. }
  291. else
  292. {
  293. dprintfVerbose("Arguments: %s, %s\n", Args[0], Args[1]);
  294. if (argstring && *argstring)
  295. {
  296. DWORD dwCount;
  297. TRACETAGELEMENT *pTRACETAGELEMENT;
  298. HRESULT hr = HrGetTraceTagsForModule(Args[0], &dwCount, &pTRACETAGELEMENT);
  299. if (SUCCEEDED(hr))
  300. {
  301. BOOL fFound = FALSE;
  302. for (DWORD x = 0; x < dwCount; x++)
  303. {
  304. if (!lstrcmpi(Args[1], pTRACETAGELEMENT[x].szShortName))
  305. {
  306. fFound = TRUE;
  307. if (pTRACETAGELEMENT[x].fOutputDebugString == fEnable)
  308. {
  309. dprintf(" [%s] is already %s\n", pTRACETAGELEMENT[x].szShortName, fEnable ? "enabled" : "disabled");
  310. hr = S_FALSE;
  311. }
  312. else
  313. {
  314. pTRACETAGELEMENT[x].fOutputDebugString = fEnable;
  315. if (SUCCEEDED(HrPutTraceTagsForModule(Args[0], dwCount, pTRACETAGELEMENT)))
  316. {
  317. dprintf(" [%s] is now %s on module %s\n", pTRACETAGELEMENT[x].szShortName, fEnable ? "enabled" : "disabled", Args[0]);
  318. hr = S_OK;
  319. }
  320. break;
  321. }
  322. }
  323. }
  324. if (!fFound)
  325. {
  326. dprintf("ERROR: No such TraceTag ID found in module %s\n", Args[0]);
  327. }
  328. LocalFree(pTRACETAGELEMENT);
  329. }
  330. }
  331. else
  332. {
  333. }
  334. }
  335. }
  336. delete [] szString;
  337. }
  338. else
  339. {
  340. hr = E_INVALIDARG;
  341. }
  342. return hr;
  343. }
  344. //
  345. // Extension to edit a dword on target
  346. //
  347. // !edit <address> <value>
  348. //
  349. DECLARE_API( traceadd )
  350. {
  351. ULONG cb;
  352. ULONG64 Address;
  353. ULONG Value;
  354. HRESULT hr = HrEnableDisableTraceTag(args, TRUE);
  355. if (E_INVALIDARG == hr)
  356. {
  357. dprintf("Usage: traceadd <module> \"tracetag\" - Starts tracing for a specific tracetag\n");
  358. }
  359. }
  360. //
  361. // Extension to dump stacktrace
  362. //
  363. DECLARE_API ( tracedel )
  364. {
  365. EXTSTACKTRACE64 stk[20];
  366. ULONG frames, i;
  367. CHAR Buffer[256];
  368. ULONG64 displacement;
  369. HRESULT hr = HrEnableDisableTraceTag(args, FALSE);
  370. if (E_INVALIDARG == hr)
  371. {
  372. dprintf("Usage: tracedel <module> \"tracetag\" - Stops tracing for a specific tracetag\n");
  373. }
  374. }
  375. typedef map<ConnListCore::key_type, ConnListCore::referent_type> ConnListCoreMap;
  376. class ConnList_Map : public ConnListCoreMap
  377. {
  378. public:
  379. class ConnList_Tree : public ConnListCoreMap::_Imp
  380. {
  381. public:
  382. _Nodeptr GetHead() { return _Head; }
  383. _Nodepref _Left(_Nodeptr _P)
  384. {
  385. return ((_Nodepref)(*_P)._Left);
  386. }
  387. _Nodepref _Right(_Nodeptr _P)
  388. {
  389. return ((_Nodepref)(*_P)._Right);
  390. }
  391. LPVOID _GetHeadPtr() { return _Head; }
  392. LPVOID _LeftPtr(LPVOID _P)
  393. {
  394. return ((* (_Nodeptr)_P)._Left);
  395. }
  396. LPVOID _RightPtr(LPVOID _P)
  397. {
  398. return ((* (_Nodeptr)_P)._Right);
  399. }
  400. LPVOID _ParentPtr(LPVOID _P)
  401. {
  402. return ((* (_Nodeptr)_P)._Parent);
  403. }
  404. LPVOID GetNil()
  405. {
  406. return _Nil;
  407. }
  408. DWORD _GetNodeSize() { return sizeof(_Node); }
  409. };
  410. public:
  411. ConnList_Tree *GetTree() { return reinterpret_cast<ConnList_Tree *>(&_Tr); }
  412. LPVOID _GetHeadPtr() { return GetTree()->_GetHeadPtr(); }
  413. LPVOID _LeftPtr(LPVOID p) { return GetTree()->_LeftPtr(p); }
  414. LPVOID _RightPtr(LPVOID p) { return GetTree()->_RightPtr(p); }
  415. LPVOID _ParentPtr(LPVOID p) { return GetTree()->_ParentPtr(p); }
  416. LPVOID GetNil() { return GetTree()->GetNil(); }
  417. DWORD _GetNodeSize() { return GetTree()->_GetNodeSize(); }
  418. typedef ConnList_Tree::_Node _NodeType;
  419. };
  420. typedef ConnList_Map::_NodeType NodeType;
  421. LPCSTR DBG_EMNAMES[] =
  422. {
  423. "INVALID_EVENTMGR",
  424. "EVENTMGR_CONMAN",
  425. "EVENTMGR_EAPOLMAN"
  426. };
  427. LPCSTR DBG_CMENAMES[] =
  428. {
  429. "INVALID_TYPE",
  430. "CONNECTION_ADDED",
  431. "CONNECTION_BANDWIDTH_CHANGE",
  432. "CONNECTION_DELETED",
  433. "CONNECTION_MODIFIED",
  434. "CONNECTION_RENAMED",
  435. "CONNECTION_STATUS_CHANGE",
  436. "REFRESH_ALL",
  437. "CONNECTION_ADDRESS_CHANGE"
  438. };
  439. LPCSTR DBG_NCMNAMES[] =
  440. {
  441. "NCM_NONE",
  442. "NCM_DIRECT",
  443. "NCM_ISDN",
  444. "NCM_LAN",
  445. "NCM_PHONE",
  446. "NCM_TUNNEL",
  447. "NCM_PPPOE",
  448. "NCM_BRIDGE",
  449. "NCM_SHAREDACCESSHOST_LAN",
  450. "NCM_SHAREDACCESSHOST_RAS"
  451. };
  452. LPCSTR DBG_NCSMNAMES[] =
  453. {
  454. "NCSM_NONE",
  455. "NCSM_LAN",
  456. "NCSM_WIRELESS",
  457. "NCSM_ATM",
  458. "NCSM_ELAN",
  459. "NCSM_1394",
  460. "NCSM_DIRECT",
  461. "NCSM_IRDA",
  462. "NCSM_CM",
  463. };
  464. LPCSTR DBG_NCSNAMES[] =
  465. {
  466. "NCS_DISCONNECTED",
  467. "NCS_CONNECTING",
  468. "NCS_CONNECTED",
  469. "NCS_DISCONNECTING",
  470. "NCS_HARDWARE_NOT_PRESENT",
  471. "NCS_HARDWARE_DISABLED",
  472. "NCS_HARDWARE_MALFUNCTION",
  473. "NCS_MEDIA_DISCONNECTED",
  474. "NCS_AUTHENTICATING",
  475. "NCS_AUTHENTICATION_SUCCEEDED",
  476. "NCS_AUTHENTICATION_FAILED",
  477. "NCS_INVALID_ADDRESS",
  478. "NCS_CREDENTIALS_REQUIRED"
  479. };
  480. // Shorten these to fit more in.
  481. LPCSTR DBG_NCCSFLAGS[] =
  482. {
  483. "_NONE",
  484. "_ALL_USERS",
  485. "_ALLOW_DUPLICATION",
  486. "_ALLOW_REMOVAL",
  487. "_ALLOW_RENAME",
  488. "_SHOW_ICON",
  489. "_INCOMING_ONLY",
  490. "_OUTGOING_ONLY",
  491. "_BRANDED",
  492. "_SHARED",
  493. "_BRIDGED",
  494. "_FIREWALLED",
  495. "_DEFAULT"
  496. };
  497. LPCSTR DbgEvents(DWORD Event)
  498. {
  499. if (Event < celems(DBG_CMENAMES))
  500. {
  501. return DBG_CMENAMES[Event];
  502. }
  503. else
  504. {
  505. return "UNKNOWN Event: Update DBG_CMENAMES table.";
  506. }
  507. }
  508. LPCSTR DbgEventManager(DWORD EventManager)
  509. {
  510. if (EventManager < celems(DBG_EMNAMES))
  511. {
  512. return DBG_EMNAMES[EventManager];
  513. }
  514. else
  515. {
  516. return "UNKNOWN Event: Update DBG_EMNAMES table.";
  517. }
  518. }
  519. LPCSTR DbgNcm(DWORD ncm)
  520. {
  521. if (ncm < celems(DBG_NCMNAMES))
  522. {
  523. return DBG_NCMNAMES[ncm];
  524. }
  525. else
  526. {
  527. return "UNKNOWN NCM: Update DBG_NCMNAMES table.";
  528. }
  529. }
  530. LPCSTR DbgNcsm(DWORD ncsm)
  531. {
  532. if (ncsm < celems(DBG_NCSMNAMES))
  533. {
  534. return DBG_NCSMNAMES[ncsm];
  535. }
  536. else
  537. {
  538. return "UNKNOWN NCM: Update DBG_NCSMNAMES table.";
  539. }
  540. }
  541. LPCSTR DbgNcs(DWORD ncs)
  542. {
  543. if (ncs < celems(DBG_NCSNAMES))
  544. {
  545. return DBG_NCSNAMES[ncs];
  546. }
  547. else
  548. {
  549. return "UNKNOWN NCS: Update DBG_NCSNAMES table.";
  550. }
  551. }
  552. LPCSTR DbgNccf(DWORD nccf)
  553. {
  554. static CHAR szName[MAX_PATH];
  555. if (nccf >= (1 << celems(DBG_NCCSFLAGS)) )
  556. {
  557. return "UNKNOWN NCCF: Update DBG_NCCSFLAGS table.";
  558. }
  559. if (0 == nccf)
  560. {
  561. strcpy(szName, DBG_NCCSFLAGS[0]);
  562. }
  563. else
  564. {
  565. szName[0] = '\0';
  566. LPSTR szTemp = szName;
  567. BOOL bFirst = TRUE;
  568. for (DWORD x = 0; x < celems(DBG_NCCSFLAGS); x++)
  569. {
  570. if (nccf & (1 << x))
  571. {
  572. if (!bFirst)
  573. {
  574. szTemp += sprintf(szTemp, "+");
  575. }
  576. else
  577. {
  578. szTemp += sprintf(szTemp, "NCCF:");
  579. }
  580. bFirst = FALSE;
  581. szTemp += sprintf(szTemp, "%s", DBG_NCCSFLAGS[x+1]);
  582. }
  583. }
  584. }
  585. return szName;
  586. }
  587. HRESULT HrDumpNode(LPVOID pvHead, LPVOID pvDbgHead, LPVOID pvNil, DWORD dwLevel)
  588. {
  589. NodeType *pHead = reinterpret_cast<NodeType *>(pvHead);
  590. dprintfVerbose("%d: [0x%I64lx], NIL = [0x%I64lx]\n", dwLevel, pvDbgHead, pvNil);
  591. if (pvDbgHead == pvNil)
  592. {
  593. return S_FALSE;
  594. }
  595. if ( (!pHead->_Left) && (!pHead->_Right) ) // aparently with the STL version we are using, this identifies an end node.
  596. {
  597. return S_FALSE;
  598. }
  599. HRESULT hr;
  600. ConnListEntry &cle = pHead->_Value.second;
  601. CConFoldEntry &cfe = cle.ccfe;
  602. WCHAR szNameEntry[MAX_PATH];
  603. dprintfVerbose("%d: Reading szNameEntry", dwLevel);
  604. hr = HrReadMemory(cfe.m_pszName, celems(szNameEntry), szNameEntry);
  605. if (SUCCEEDED(hr))
  606. {
  607. if (*szNameEntry)
  608. {
  609. LPWSTR szGUID;
  610. StringFromCLSID(cfe.m_guidId, &szGUID);
  611. dprintf(" * %S [%s:%s:%s:%s]\n", szNameEntry,
  612. DbgNcs(cfe.m_ncs), DbgNccf(cfe.m_dwCharacteristics), DbgNcm(cfe.m_ncm), DbgNcsm(cfe.m_ncsm) );
  613. dprintf(" guidId : %S\n", szGUID);
  614. CoTaskMemFree(szGUID);
  615. StringFromCLSID(cfe.m_clsid, &szGUID);
  616. dprintf(" clsId : %S\n", szGUID);
  617. CoTaskMemFree(szGUID);
  618. hr = HrReadMemory(cfe.m_pszDeviceName , celems(szNameEntry), szNameEntry);
  619. if (SUCCEEDED(hr))
  620. {
  621. dprintf(" Device Name : %S\n", szNameEntry);
  622. }
  623. hr = HrReadMemory(cfe.m_pszPhoneOrHostAddress, celems(szNameEntry), szNameEntry);
  624. if (SUCCEEDED(hr))
  625. {
  626. dprintf(" Phone # : %S\n", szNameEntry);
  627. }
  628. switch (cfe.m_wizWizard)
  629. {
  630. case WIZARD_NOT_WIZARD:
  631. break;
  632. case WIZARD_HNW:
  633. dprintf(" WIZARD_HNW\n");
  634. break;
  635. case WIZARD_MNC:
  636. dprintf(" WIZARD_MNC\n");
  637. break;
  638. }
  639. }
  640. }
  641. dprintfVerbose("%d: left is : 0x%I64lx\n", dwLevel, pHead->_Left);
  642. dprintfVerbose("%d: right is: 0x%I64lx\n", dwLevel, pHead->_Right);
  643. if (0 != pHead->_Left)
  644. {
  645. NodeType *pNodeLeft = reinterpret_cast<NodeType *>(new BYTE[sizeof(NodeType)]);
  646. ZeroMemory(pNodeLeft, sizeof(NodeType));
  647. dprintfVerbose("%d: Reading left child node ", dwLevel);
  648. hr = HrReadMemory(pHead->_Left, sizeof(NodeType), pNodeLeft);
  649. if (SUCCEEDED(hr))
  650. {
  651. hr = ::HrDumpNode(pNodeLeft, pHead->_Left, pvNil, dwLevel+1);
  652. }
  653. delete [] reinterpret_cast<LPBYTE>(pNodeLeft);
  654. }
  655. if (0 != pHead->_Right)
  656. {
  657. NodeType *pNodeRight = reinterpret_cast<NodeType *>(new BYTE[sizeof(NodeType)]);
  658. ZeroMemory(pNodeRight, sizeof(NodeType));
  659. dprintfVerbose("%d: Reading right child node ", dwLevel);
  660. hr = HrReadMemory(pHead->_Right, sizeof(NodeType), pNodeRight);
  661. if (SUCCEEDED(hr))
  662. {
  663. hr = ::HrDumpNode(pNodeRight, pHead->_Right, pvNil, dwLevel+1);
  664. }
  665. delete [] reinterpret_cast<LPBYTE>(pNodeRight);
  666. }
  667. return S_OK;
  668. }
  669. HRESULT HrDumpConnectionListFromAddress(ULONG64 address)
  670. {
  671. HRESULT hr = E_FAIL;
  672. CConnectionList *pConnectionList = reinterpret_cast<CConnectionList *>(new BYTE[sizeof(CConnectionList)]);
  673. ZeroMemory(pConnectionList, sizeof(CConnectionList));
  674. dprintfVerbose("Reading pConnectionList (g_ccl) ");
  675. hr = HrReadMemoryFromUlong(address, sizeof(CConnectionList), pConnectionList);
  676. if (SUCCEEDED(hr))
  677. {
  678. ConnList_Map *pConnListCore = reinterpret_cast<ConnList_Map *>(new BYTE[sizeof(ConnList_Map)]);
  679. ZeroMemory(pConnListCore, sizeof(ConnList_Map));
  680. dprintfVerbose("Reading pConnListCore (g_ccl.m_pcclc) ");
  681. hr = HrReadMemory(pConnectionList->m_pcclc, sizeof(ConnList_Map), pConnListCore);
  682. if (SUCCEEDED(hr))
  683. {
  684. dprintf("%d entries found:\n", pConnListCore->size());
  685. NodeType *pConnListHead = reinterpret_cast<NodeType *>(new BYTE[sizeof(NodeType)]);
  686. ZeroMemory(pConnListHead, sizeof(NodeType));
  687. dprintfVerbose("Reading pConnListHead (g_ccl.m_pcclc.[_Tr]._Head) ");
  688. hr = HrReadMemory(pConnListCore->_GetHeadPtr(), sizeof(NodeType), pConnListHead);
  689. if (SUCCEEDED(hr))
  690. {
  691. // hr = ::HrDumpNode(pConnListHead, 0);
  692. NodeType *pConnListRoot = reinterpret_cast<NodeType *>(new BYTE[sizeof(NodeType)]);
  693. ZeroMemory(pConnListRoot, sizeof(NodeType));
  694. dprintfVerbose("Reading pConnListRoot (g_ccl.m_pcclc.[_Tr]._Head._Parent) ");
  695. hr = HrReadMemory(pConnListHead->_Parent, sizeof(NodeType), pConnListRoot);
  696. if (SUCCEEDED(hr))
  697. {
  698. hr = ::HrDumpNode(pConnListRoot, pConnListHead->_Parent, pConnListCore->GetNil(), 0);
  699. }
  700. delete [] reinterpret_cast<LPBYTE>(pConnListRoot);
  701. }
  702. delete [] reinterpret_cast<LPBYTE>(pConnListHead);
  703. }
  704. delete reinterpret_cast<LPBYTE>(pConnListCore);
  705. }
  706. delete reinterpret_cast<LPBYTE>(pConnectionList);
  707. if (FAILED(hr))
  708. {
  709. dprintf("Could not dump connection list\n");
  710. }
  711. return hr;
  712. }
  713. //
  714. // Extension to dump stacktrace
  715. //
  716. DECLARE_API ( connlist )
  717. {
  718. EXTSTACKTRACE64 stk[20];
  719. ULONG frames, i;
  720. CHAR Buffer[256];
  721. ULONG64 displacement;
  722. HRESULT hr = E_FAIL;;
  723. ULONG64 g_cclAddress;
  724. if (*args)
  725. {
  726. hr = HrGetAddressOfSymbol(args, &g_cclAddress);
  727. }
  728. else
  729. {
  730. hr = HrGetAddressOfSymbol("netshell!g_ccl", &g_cclAddress);
  731. }
  732. if (SUCCEEDED(hr))
  733. {
  734. hr = ::HrDumpConnectionListFromAddress(g_cclAddress);
  735. }
  736. if (E_INVALIDARG == hr)
  737. {
  738. dprintf("Usage:\n"
  739. " connlist - Dumps out the connection\n"
  740. " connlist <address> - Dumps out the connection list from address\n");
  741. }
  742. }
  743. /*
  744. A built-in help for the extension dll
  745. */
  746. DECLARE_API ( help )
  747. {
  748. dprintf("Help for NetConfig ncext.dll\n"
  749. " tracelist <module> - List all the currently traces enabled for module <module>\n"
  750. " tracelist all - List currently available traces\n"
  751. " traceadd <module> \"tracetag\" - Starts tracing for a specific tracetag\n"
  752. " tracedel <module> \"tracetag\" - Stops tracing for a specific tracetag\n"
  753. " connlist - Dumps out the connection\n"
  754. " connlist <address> - Dumps out the connection list from address\n"
  755. " help - Shows this help\n"
  756. );
  757. }