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.

2110 lines
61 KiB

  1. #include "pch.h"
  2. #pragma hdrstop
  3. #include "adapter.h"
  4. #include "diag.h"
  5. #include "inetcfg.h"
  6. #include "lanamap.h"
  7. #include "ncreg.h"
  8. #include "ncsetup.h"
  9. #include "netcfg.h"
  10. #include "persist.h"
  11. #include "util.h"
  12. #include <conio.h> // _kbhit
  13. //move to classinst.cpp
  14. HRESULT
  15. HrCiDoCompleteSectionInstall(
  16. HINF hinfFile,
  17. HKEY hkeyRelative,
  18. PCWSTR szSection,
  19. HWND hwndParent,
  20. BOOL fEnumerated);
  21. class CNetCfgInternalDiagnostic
  22. {
  23. public:
  24. static VOID
  25. DoCreateReleaseDiagnostic (
  26. IN const DIAG_OPTIONS* pOptions,
  27. BOOL fPrime);
  28. static VOID
  29. DoEnumAllDiagnostic (
  30. IN const DIAG_OPTIONS* pOptions);
  31. static VOID
  32. DoSaveLoadDiagnostic (
  33. IN const DIAG_OPTIONS* pOptions,
  34. IN CNetConfig* pNetConfig);
  35. static VOID
  36. DoWriteLockDiagnostic (
  37. IN const DIAG_OPTIONS* pOptions,
  38. IN CNetConfig* pNetConfig);
  39. static VOID
  40. CmdFullDiagnostic (
  41. IN const DIAG_OPTIONS* pOptions,
  42. IN CNetConfig* pNetConfig);
  43. };
  44. VOID
  45. PromptForLeakCheck (
  46. IN const DIAG_OPTIONS* pOptions,
  47. IN PCSTR psz)
  48. {
  49. if (pOptions->fLeakCheck)
  50. {
  51. g_pDiagCtx->Printf (ttidBeDiag, psz);
  52. while (!_kbhit())
  53. {
  54. Sleep (50);
  55. }
  56. _getch ();
  57. g_pDiagCtx->Printf (ttidBeDiag, "\n");
  58. }
  59. }
  60. HRESULT
  61. HrCreateINetCfg (
  62. IN BOOL fAcquireWriteLock,
  63. OUT CImplINetCfg** ppINetCfg)
  64. {
  65. HRESULT hr;
  66. CImplINetCfg* pINetCfg;
  67. hr = CComCreator<CComObject <CImplINetCfg> >::CreateInstance(
  68. NULL, IID_INetCfg, (VOID**)&pINetCfg);
  69. if (S_OK == hr)
  70. {
  71. if (fAcquireWriteLock)
  72. {
  73. hr = pINetCfg->AcquireWriteLock (100, L"ncdiag", NULL);
  74. if (S_FALSE == hr)
  75. {
  76. g_pDiagCtx->Printf (ttidBeDiag, "The write lock could not be acquired.\n");
  77. }
  78. else if (NETCFG_E_NEED_REBOOT == hr)
  79. {
  80. g_pDiagCtx->Printf (ttidBeDiag, "A reboot is required before any futher "
  81. "changes can be made.\n");
  82. }
  83. }
  84. if (S_OK == hr)
  85. {
  86. hr = pINetCfg->Initialize (NULL);
  87. if (S_OK == hr)
  88. {
  89. *ppINetCfg = pINetCfg;
  90. }
  91. }
  92. if (S_OK != hr)
  93. {
  94. ReleaseObj (pINetCfg->GetUnknown());
  95. }
  96. }
  97. return hr;
  98. }
  99. HRESULT
  100. HrFindBindPath (
  101. IN CImplINetCfg* pINetCfg,
  102. IN PCWSTR pszPathToken,
  103. OUT INetCfgBindingPath** ppIPath,
  104. OUT INetCfgComponentBindings** ppIOwner)
  105. {
  106. HRESULT hr;
  107. const WCHAR szDelim[] = L"->";
  108. WCHAR szBindPath [_MAX_PATH];
  109. PCWSTR pszInfId;
  110. PWSTR pszNext;
  111. INetCfgComponent* pIComp;
  112. *ppIPath = NULL;
  113. if (ppIOwner)
  114. {
  115. *ppIOwner = NULL;
  116. }
  117. wcscpy (szBindPath, pszPathToken);
  118. pszInfId = GetNextStringToken (szBindPath, szDelim, &pszNext);
  119. hr = pINetCfg->FindComponent (pszInfId, &pIComp);
  120. if (S_OK == hr)
  121. {
  122. INetCfgComponentBindings* pIBind;
  123. hr = pIComp->QueryInterface (IID_INetCfgComponentBindings,
  124. (VOID**)&pIBind);
  125. if (S_OK == hr)
  126. {
  127. IEnumNetCfgBindingPath* pIEnumPath;
  128. hr = pIBind->EnumBindingPaths (EBP_BELOW, &pIEnumPath);
  129. if (S_OK == hr)
  130. {
  131. INetCfgBindingPath* rgIPath [256];
  132. ULONG cIPath;
  133. hr = pIEnumPath->Next (celems(rgIPath), rgIPath, &cIPath);
  134. if (SUCCEEDED(hr) && cIPath)
  135. {
  136. for (ULONG iPath = 0;
  137. (iPath < cIPath) && !(*ppIPath);
  138. iPath++)
  139. {
  140. PWSTR pszToken;
  141. hr = rgIPath[iPath]->GetPathToken (&pszToken);
  142. if (S_OK == hr)
  143. {
  144. if (0 == wcscmp (pszPathToken, pszToken))
  145. {
  146. AddRefObj (rgIPath[iPath]);
  147. *ppIPath = rgIPath[iPath];
  148. if (ppIOwner)
  149. {
  150. INetCfgComponent* pICompOwner;
  151. hr = rgIPath[0]->GetOwner(&pICompOwner);
  152. Assert (S_OK == hr);
  153. pICompOwner->QueryInterface (
  154. IID_INetCfgComponentBindings,
  155. (VOID**)ppIOwner);
  156. ReleaseObj (pICompOwner);
  157. }
  158. }
  159. CoTaskMemFree (pszToken);
  160. }
  161. }
  162. ReleaseIUnknownArray(cIPath, (IUnknown**)rgIPath);
  163. hr = S_OK;
  164. }
  165. ReleaseObj (pIEnumPath);
  166. }
  167. ReleaseObj (pIBind);
  168. }
  169. ReleaseObj (pIComp);
  170. }
  171. else if (S_FALSE == hr)
  172. {
  173. hr = S_OK;
  174. }
  175. return hr;
  176. }
  177. // This test ensures proper circular reference behavior between CNetConfig
  178. // and CImplINetCfg.
  179. // The following is performed:
  180. // create a CNetConfig and have it create its INetCfg for the notify objects.
  181. // AddRef its INetCfg
  182. // destroy the CNetConfig
  183. // Try to Uninitialize the INetCfg which should fail because it never
  184. // owned its internal CNetConfig pointer.
  185. // Release the INetCfg and ensure that nothing is leaked.
  186. //
  187. VOID
  188. CNetCfgInternalDiagnostic::DoCreateReleaseDiagnostic (
  189. IN const DIAG_OPTIONS* pOptions,
  190. IN BOOL fPrime)
  191. {
  192. HRESULT hr;
  193. CImplINetCfg* pINetCfg = NULL;
  194. if (!fPrime)
  195. {
  196. PromptForLeakCheck (pOptions,
  197. "Create/Release diagnostic...(dump heap)");
  198. }
  199. // Scoping brackets so that NetConfig will be created and destroyed
  200. // in this scope.
  201. //
  202. {
  203. CNetConfig NetConfig;
  204. hr = HrLoadNetworkConfigurationFromRegistry (KEY_READ, &NetConfig);
  205. if (S_OK == hr)
  206. {
  207. // Shouldn't have internal INetCfg created yet.
  208. //
  209. Assert (!NetConfig.Notify.m_pINetCfg);
  210. hr = NetConfig.Notify.HrEnsureNotifyObjectsInitialized ();
  211. if (S_OK == hr)
  212. {
  213. // Should now have internal INetCfg created.
  214. //
  215. Assert (NetConfig.Notify.m_pINetCfg);
  216. pINetCfg = NetConfig.Notify.m_pINetCfg;
  217. // INetCfg should be pointing back to our CNetConfig object.
  218. //
  219. Assert (&NetConfig == pINetCfg->m_pNetConfig);
  220. // Let's hang on to it and see what happens after we let
  221. // the parent CNetConfig be destroyed.
  222. //
  223. pINetCfg = NetConfig.Notify.m_pINetCfg;
  224. AddRefObj (pINetCfg->GetUnknown());
  225. }
  226. }
  227. }
  228. if ((S_OK == hr) && pINetCfg)
  229. {
  230. // Now that CNetConfig is destroyed, it should not be pointing to
  231. // any CNetConfig object.
  232. //
  233. Assert (!pINetCfg->m_pNetConfig);
  234. hr = pINetCfg->Uninitialize();
  235. Assert (NETCFG_E_NOT_INITIALIZED == hr);
  236. ReleaseObj (pINetCfg->GetUnknown());
  237. }
  238. if (NETCFG_E_NOT_INITIALIZED == hr)
  239. {
  240. g_pDiagCtx->Printf (ttidBeDiag, "Passed Create/Release diagnostic.\n");
  241. }
  242. else
  243. {
  244. g_pDiagCtx->Printf (ttidBeDiag, "FAILED Create/Release diagnostic.\n");
  245. }
  246. if (!fPrime)
  247. {
  248. PromptForLeakCheck (pOptions,
  249. "Create/Release diagnostic...(dump heap and compare)");
  250. }
  251. }
  252. VOID
  253. CNetCfgInternalDiagnostic::DoEnumAllDiagnostic (
  254. IN const DIAG_OPTIONS* pOptions)
  255. {
  256. HRESULT hr;
  257. CImplINetCfg* pINetCfg;
  258. PromptForLeakCheck (pOptions, "Enumerate All diagnostic...(dump heap)");
  259. hr = HrCreateINetCfg (FALSE, &pINetCfg);
  260. if (S_OK == hr)
  261. {
  262. IEnumNetCfgComponent* pIEnum;
  263. hr = pINetCfg->EnumComponents (NULL, &pIEnum);
  264. if (S_OK == hr)
  265. {
  266. INetCfgComponent* rgIComp[128];
  267. ULONG cIComp;
  268. hr = pIEnum->Next (celems(rgIComp), rgIComp, &cIComp);
  269. if (SUCCEEDED(hr) && cIComp)
  270. {
  271. INetCfgComponentBindings* pIBind;
  272. IEnumNetCfgBindingPath* pIEnumPath;
  273. INetCfgBindingPath* rgIPath[256];
  274. PWSTR pszInfId;
  275. ULONG cIPath;
  276. ULONG cIPathTotal = 0;
  277. ULONG cIIntTotal = 0;
  278. for (ULONG iComp = 0; iComp < cIComp; iComp++)
  279. {
  280. hr = rgIComp[iComp]->GetId (&pszInfId);
  281. if (S_OK == hr)
  282. {
  283. hr = (*pszInfId) ? S_OK : E_FAIL;
  284. if (S_OK != hr)
  285. {
  286. break;
  287. }
  288. hr = rgIComp[iComp]->QueryInterface (IID_INetCfgComponentBindings, (VOID**)&pIBind);
  289. if (S_OK == hr)
  290. {
  291. hr = pIBind->EnumBindingPaths (EBP_BELOW, &pIEnumPath);
  292. if (S_OK == hr)
  293. {
  294. hr = pIEnumPath->Next (celems(rgIPath), rgIPath, &cIPath);
  295. if (SUCCEEDED(hr))
  296. {
  297. for (ULONG iPath = 0; iPath < cIPath; iPath++)
  298. {
  299. ULONG ulDepth;
  300. hr = rgIPath[iPath]->GetDepth(&ulDepth);
  301. if (S_OK == hr)
  302. {
  303. IEnumNetCfgBindingInterface* pIEnumInt;
  304. INetCfgBindingInterface* rgIInt[128];
  305. ULONG cIInt;
  306. hr = rgIPath[iPath]->EnumBindingInterfaces (&pIEnumInt);
  307. if (S_OK == hr)
  308. {
  309. hr = pIEnumInt->Next (celems(rgIInt), rgIInt, &cIInt);
  310. if (SUCCEEDED(hr))
  311. {
  312. cIIntTotal += cIInt;
  313. ReleaseIUnknownArray(cIInt, (IUnknown**)rgIInt);
  314. }
  315. else if (S_FALSE == hr)
  316. {
  317. hr = S_OK;
  318. }
  319. ReleaseObj (pIEnumInt);
  320. }
  321. }
  322. }
  323. cIPathTotal += cIPath;
  324. ReleaseIUnknownArray(cIPath, (IUnknown**)rgIPath);
  325. hr = S_OK;
  326. }
  327. ReleaseObj (pIEnumPath);
  328. }
  329. ReleaseObj (pIBind);
  330. }
  331. CoTaskMemFree (pszInfId);
  332. }
  333. if (S_OK != hr)
  334. {
  335. break;
  336. }
  337. }
  338. ReleaseIUnknownArray(cIComp, (IUnknown**)rgIComp);
  339. // Note: Total bindpaths are not total unique bindpaths.
  340. // (A component's bindpaths which end in ms_ipx have
  341. // ms_ipx's lower bindings added. These additional
  342. // bindings are counted for every component which has
  343. // bindpaths that end in ms_ipx.)
  344. //
  345. g_pDiagCtx->Printf (ttidBeDiag, "Passed Enumerate All diagnostic. (%d components, %d (non-unique) bindpaths, %d interfaces)\n", cIComp, cIPathTotal, cIIntTotal);
  346. }
  347. else if (S_FALSE == hr)
  348. {
  349. hr = S_OK;
  350. }
  351. ReleaseObj (pIEnum);
  352. }
  353. HRESULT hrT = pINetCfg->Uninitialize ();
  354. Assert (S_OK == hrT);
  355. ReleaseObj (pINetCfg->GetUnknown());
  356. }
  357. if (S_OK != hr)
  358. {
  359. g_pDiagCtx->Printf (ttidBeDiag, "FAILED Enumerate All diagnostic.\n");
  360. }
  361. PromptForLeakCheck (pOptions, "Enumerate All diagnostic...(dump heap and compare)");
  362. }
  363. VOID
  364. CNetCfgInternalDiagnostic::DoSaveLoadDiagnostic (
  365. IN const DIAG_OPTIONS* pOptions,
  366. IN CNetConfig* pNetConfig)
  367. {
  368. HRESULT hr;
  369. BOOL fClearDisabledBindings = FALSE;
  370. CBindingSet BindingSet;
  371. CComponentList::iterator iter;
  372. CComponent* pComponent;
  373. // Generate a full set of bindings so we test persisting them as
  374. // disabled bindings, but only if we don't already have disabled
  375. // bindings.
  376. //
  377. if (0 == pNetConfig->Core.DisabledBindings.CountBindPaths())
  378. {
  379. fClearDisabledBindings = TRUE;
  380. for (iter = pNetConfig->Core.Components.begin();
  381. iter != pNetConfig->Core.Components.end();
  382. iter++)
  383. {
  384. pComponent = *iter;
  385. Assert (pComponent);
  386. hr = pNetConfig->Core.HrGetComponentBindings (
  387. pComponent,
  388. GBF_ADD_TO_BINDSET,
  389. &pNetConfig->Core.DisabledBindings);
  390. if (S_OK != hr) return;
  391. }
  392. }
  393. PBYTE pbBuf;
  394. ULONG cbBuf;
  395. hr = HrSaveNetworkConfigurationToBufferWithAlloc (
  396. pNetConfig, &pbBuf, &cbBuf);
  397. if (S_OK == hr)
  398. {
  399. CNetConfig NetConfigCopy;
  400. hr = HrLoadNetworkConfigurationFromBuffer (
  401. pbBuf, cbBuf, &NetConfigCopy);
  402. if (S_OK == hr)
  403. {
  404. PBYTE pbBufCopy;
  405. ULONG cbBufCopy;
  406. hr = HrSaveNetworkConfigurationToBufferWithAlloc (
  407. &NetConfigCopy, &pbBufCopy, &cbBufCopy);
  408. if (S_OK == hr)
  409. {
  410. if ((cbBufCopy == cbBuf) && (0 == memcmp(pbBufCopy, pbBuf, cbBuf)))
  411. {
  412. g_pDiagCtx->Printf (ttidBeDiag, "Passed Save/Load diagnostic. (%d bytes)\n", cbBuf);
  413. }
  414. else
  415. {
  416. g_pDiagCtx->Printf (ttidBeDiag, "FAILED compare for Save/Load diagnostic.\n");
  417. }
  418. MemFree (pbBufCopy);
  419. }
  420. }
  421. MemFree (pbBuf);
  422. }
  423. // Leave the disabled bindings as we found them.
  424. //
  425. if (fClearDisabledBindings)
  426. {
  427. pNetConfig->Core.DisabledBindings.Clear();
  428. }
  429. if (S_OK != hr)
  430. {
  431. g_pDiagCtx->Printf (ttidBeDiag, "FAILED Save/Load diagnostic.\n");
  432. }
  433. }
  434. VOID
  435. CNetCfgInternalDiagnostic::DoWriteLockDiagnostic (
  436. IN const DIAG_OPTIONS* pOptions,
  437. IN CNetConfig* pNetConfig)
  438. {
  439. HRESULT hr;
  440. CImplINetCfg* pINetCfg;
  441. BOOL fFailed = FALSE;
  442. PromptForLeakCheck (pOptions, "WriteLock diagnostic...(dump heap)");
  443. hr = CComCreator<CComObject <CImplINetCfg> >::CreateInstance(
  444. NULL, IID_INetCfg, (VOID**)&pINetCfg);
  445. if (S_OK == hr)
  446. {
  447. PWSTR psz;
  448. hr = pINetCfg->IsWriteLocked (&psz);
  449. if (S_FALSE != hr) fFailed = TRUE;
  450. if (psz) fFailed = TRUE;
  451. hr = pINetCfg->AcquireWriteLock (100, L"ncdiag", &psz);
  452. if (S_OK != hr) fFailed = TRUE;
  453. if (psz) fFailed = TRUE;
  454. if (S_OK == hr)
  455. {
  456. hr = pINetCfg->IsWriteLocked (&psz);
  457. if (S_OK != hr) fFailed = TRUE;
  458. if (!psz) fFailed = TRUE;
  459. if (S_OK == hr)
  460. {
  461. if (0 != wcscmp(L"ncdiag", psz))
  462. {
  463. fFailed = TRUE;
  464. }
  465. }
  466. CoTaskMemFree (psz);
  467. hr = pINetCfg->ReleaseWriteLock ();
  468. if (S_OK != hr) fFailed = TRUE;
  469. hr = pINetCfg->IsWriteLocked (&psz);
  470. if (S_FALSE != hr) fFailed = TRUE;
  471. if (psz) fFailed = TRUE;
  472. }
  473. ReleaseObj (pINetCfg->GetUnknown());
  474. }
  475. if (!fFailed)
  476. {
  477. PromptForLeakCheck (pOptions, "WriteLock diagnostic...(dump heap and compare)");
  478. g_pDiagCtx->Printf (ttidBeDiag, "Passed WriteLock diagnostic.\n");
  479. }
  480. else
  481. {
  482. g_pDiagCtx->Printf (ttidBeDiag, "FAILED WriteLock diagnostic.\n");
  483. }
  484. }
  485. VOID
  486. CNetCfgInternalDiagnostic::CmdFullDiagnostic (
  487. IN const DIAG_OPTIONS* pOptions,
  488. IN CNetConfig* pNetConfig)
  489. {
  490. DoCreateReleaseDiagnostic (pOptions, TRUE);
  491. if (pOptions->fLeakCheck)
  492. {
  493. DoCreateReleaseDiagnostic (pOptions, FALSE);
  494. }
  495. DoEnumAllDiagnostic (pOptions);
  496. DoSaveLoadDiagnostic (pOptions, pNetConfig);
  497. DoWriteLockDiagnostic (pOptions, pNetConfig);
  498. }
  499. VOID
  500. CmdAddComponent (
  501. IN const DIAG_OPTIONS* pOptions,
  502. IN CNetConfig* pNetConfig)
  503. {
  504. HRESULT hr;
  505. CImplINetCfg* pINetCfg;
  506. PromptForLeakCheck (pOptions, "Add component...(dump heap)");
  507. hr = HrCreateINetCfg (TRUE, &pINetCfg);
  508. if (S_OK == hr)
  509. {
  510. INetCfgClassSetup* pSetup;
  511. hr = pINetCfg->QueryNetCfgClass (
  512. &pOptions->ClassGuid,
  513. IID_INetCfgClassSetup,
  514. (VOID**)&pSetup);
  515. if (S_OK == hr)
  516. {
  517. OBO_TOKEN OboToken;
  518. INetCfgComponent* pIComp;
  519. ZeroMemory (&OboToken, sizeof(OboToken));
  520. OboToken.Type = OBO_USER;
  521. hr = pSetup->Install (
  522. pOptions->pszInfId,
  523. &OboToken,
  524. 0, 0, NULL, NULL,
  525. &pIComp);
  526. if (SUCCEEDED(hr))
  527. {
  528. ReleaseObj (pIComp);
  529. }
  530. if (NETCFG_S_REBOOT == hr)
  531. {
  532. hr = S_OK;
  533. g_pDiagCtx->Printf (ttidBeDiag, "%S was installed, but a reboot is required.\n",
  534. pOptions->pszInfId);
  535. }
  536. else if (HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) == hr)
  537. {
  538. hr = S_OK;
  539. g_pDiagCtx->Printf (ttidBeDiag, "The INF file for %S could not be found.\n",
  540. pOptions->pszInfId);
  541. }
  542. ReleaseObj (pSetup);
  543. }
  544. HRESULT hrT = pINetCfg->Uninitialize ();
  545. Assert (S_OK == hrT);
  546. ReleaseObj (pINetCfg->GetUnknown());
  547. }
  548. if (S_OK != hr)
  549. {
  550. g_pDiagCtx->Printf (ttidBeDiag, "FAILED Add component.\n");
  551. }
  552. PromptForLeakCheck (pOptions, "Add component...(dump heap and compare)");
  553. }
  554. VOID
  555. CmdAddRemoveStress (
  556. IN const DIAG_OPTIONS* pOptions,
  557. IN CNetConfig* pNetConfig)
  558. {
  559. HRESULT hr;
  560. CImplINetCfg* pINetCfg;
  561. NETCLASS Class;
  562. PCWSTR pszInfId;
  563. PRODUCT_FLAVOR Flavor;
  564. BOOL fPrompted;
  565. static const struct
  566. {
  567. NETCLASS Class;
  568. PCWSTR pszInfId;
  569. BOOL fServerOnly;
  570. } aPassInfo [] =
  571. {
  572. { NC_NETCLIENT, L"ms_msclient", FALSE },
  573. { NC_NETCLIENT, L"ms_nwclient", FALSE },
  574. // { NC_NETSERVICE, L"ms_fpnw", FALSE }, // requries copy files
  575. { NC_NETSERVICE, L"ms_netbios", FALSE },
  576. { NC_NETSERVICE, L"ms_nwsapagent", FALSE },
  577. { NC_NETSERVICE, L"ms_psched", FALSE },
  578. { NC_NETSERVICE, L"ms_server", FALSE },
  579. // { NC_NETSERVICE, L"ms_wlbs", FALSE },
  580. { NC_NETTRANS, L"ms_appletalk", FALSE },
  581. { NC_NETTRANS, L"ms_atmarps", TRUE },
  582. { NC_NETTRANS, L"ms_atmlane", FALSE },
  583. { NC_NETTRANS, L"ms_atmuni", FALSE },
  584. { NC_NETTRANS, L"ms_irda", FALSE },
  585. // { NC_NETTRANS, L"ms_isotpsys", FALSE },
  586. { NC_NETTRANS, L"ms_rawwan", FALSE },
  587. // { NC_NETTRANS, L"ms_streams", FALSE },
  588. // { NC_NETTRANS, L"ms_tcpip", FALSE },
  589. };
  590. GetProductFlavor (NULL, &Flavor);
  591. fPrompted = FALSE;
  592. g_pDiagCtx->SetFlags (
  593. DF_SHOW_CONSOLE_OUTPUT | DF_DONT_START_SERVICES |
  594. DF_DONT_DO_PNP_BINDS | DF_SUPRESS_E_NEED_REBOOT);
  595. hr = HrCreateINetCfg (TRUE, &pINetCfg);
  596. if (S_OK == hr)
  597. {
  598. UINT cSkip = 0;
  599. for (BOOL fInstall = TRUE;
  600. !_kbhit() && (S_OK == hr);
  601. fInstall = !fInstall)
  602. {
  603. for (UINT i = cSkip;
  604. (i < celems(aPassInfo)) && (S_OK == hr);
  605. i += (1 + cSkip))
  606. {
  607. INetCfgClassSetup* pSetup;
  608. INetCfgComponent* pIComp;
  609. if (aPassInfo[i].fServerOnly && (PF_WORKSTATION == Flavor))
  610. {
  611. continue;
  612. }
  613. Class = aPassInfo[i].Class;
  614. pszInfId = aPassInfo[i].pszInfId;
  615. if (fInstall)
  616. {
  617. g_pDiagCtx->Printf (ttidBeDiag, "--------------------\n"
  618. "Installing %S\n", pszInfId);
  619. hr = pINetCfg->QueryNetCfgClass (
  620. MAP_NETCLASS_TO_GUID[Class],
  621. IID_INetCfgClassSetup,
  622. (VOID**)&pSetup);
  623. if (S_OK == hr)
  624. {
  625. OBO_TOKEN OboToken;
  626. ZeroMemory (&OboToken, sizeof(OboToken));
  627. OboToken.Type = OBO_USER;
  628. hr = pSetup->Install (
  629. pszInfId,
  630. &OboToken,
  631. 0, 0, NULL, NULL,
  632. &pIComp);
  633. if (SUCCEEDED(hr))
  634. {
  635. ReleaseObj (pIComp);
  636. }
  637. if (NETCFG_S_REBOOT == hr)
  638. {
  639. hr = S_OK;
  640. g_pDiagCtx->Printf (ttidBeDiag, "%S was installed, but a reboot is required.\n",
  641. pszInfId);
  642. }
  643. ReleaseObj (pSetup);
  644. }
  645. }
  646. else
  647. {
  648. hr = pINetCfg->FindComponent (pszInfId, &pIComp);
  649. if (S_OK == hr)
  650. {
  651. GUID ClassGuid;
  652. g_pDiagCtx->Printf (ttidBeDiag, "--------------------\n"
  653. "Removing %S\n", pszInfId);
  654. hr = pIComp->GetClassGuid (&ClassGuid);
  655. if (S_OK == hr)
  656. {
  657. hr = pINetCfg->QueryNetCfgClass (
  658. &ClassGuid,
  659. IID_INetCfgClassSetup,
  660. (VOID**)&pSetup);
  661. if (S_OK == hr)
  662. {
  663. OBO_TOKEN OboToken;
  664. ZeroMemory (&OboToken, sizeof(OboToken));
  665. OboToken.Type = OBO_USER;
  666. hr = pSetup->DeInstall (
  667. pIComp,
  668. &OboToken,
  669. NULL);
  670. if (NETCFG_S_REBOOT == hr)
  671. {
  672. hr = S_OK;
  673. g_pDiagCtx->Printf (ttidBeDiag, "%S was removed, but a reboot is required.\n",
  674. pszInfId);
  675. }
  676. if (NETCFG_S_STILL_REFERENCED == hr)
  677. {
  678. hr = S_OK;
  679. g_pDiagCtx->Printf (ttidBeDiag, "%S is still referenced\n",
  680. pszInfId);
  681. }
  682. if (E_INVALIDARG == hr)
  683. {
  684. hr = S_OK;
  685. g_pDiagCtx->Printf (ttidBeDiag, "%S is installed, but not on behalf of "
  686. "the user, so we can't remove it. (Proceeding.)\n",
  687. pszInfId);
  688. }
  689. ReleaseObj (pSetup);
  690. }
  691. }
  692. ReleaseObj (pIComp);
  693. }
  694. else if (S_FALSE == hr)
  695. {
  696. hr = S_OK;
  697. }
  698. }
  699. }
  700. cSkip++;
  701. if (cSkip >= celems(aPassInfo))
  702. {
  703. cSkip = 0;
  704. }
  705. g_pDiagCtx->Printf (ttidBeDiag, "\n");
  706. if (!fPrompted)
  707. {
  708. PromptForLeakCheck (pOptions, "Add/Remove stress...(dump heap)");
  709. fPrompted = TRUE;
  710. }
  711. }
  712. if (S_OK == hr)
  713. {
  714. _getch ();
  715. }
  716. HRESULT hrT = pINetCfg->Uninitialize ();
  717. Assert (S_OK == hrT);
  718. ReleaseObj (pINetCfg->GetUnknown());
  719. }
  720. if (S_OK != hr)
  721. {
  722. g_pDiagCtx->Printf (ttidBeDiag, "FAILED Add/Remove stress component.\n");
  723. }
  724. if (fPrompted)
  725. {
  726. PromptForLeakCheck (pOptions, "Add/Remove stress...(dump heap and compare)");
  727. }
  728. }
  729. VOID
  730. CmdCleanup (
  731. IN const DIAG_OPTIONS* pOptions,
  732. IN CNetConfig* pNetConfig)
  733. {
  734. HRESULT hr;
  735. NETCLASS Class;
  736. PCWSTR pszSubtree;
  737. HKEY hkeySubtree;
  738. DWORD dwIndex;
  739. HKEY hkeyInstance;
  740. GUID InstanceGuid;
  741. BOOL fDeleteKey;
  742. WCHAR szInfPath [_MAX_PATH];
  743. WCHAR szInfSection [_MAX_PATH];
  744. DWORD cbData;
  745. static const struct
  746. {
  747. NETCLASS Class;
  748. PCWSTR pszSubtree;
  749. } aPassInfo [] =
  750. {
  751. { NC_NET, NULL },
  752. { NC_INFRARED, NULL },
  753. { NC_NETTRANS, NULL },
  754. { NC_NETCLIENT, NULL },
  755. { NC_NETSERVICE, NULL },
  756. { NC_NET, L"System\\CurrentControlSet\\Control\\Network\\{4d36e972-e325-11ce-bfc1-08002be10318}" },
  757. };
  758. for (UINT i = 0; i < celems(aPassInfo); i++)
  759. {
  760. Class = aPassInfo[i].Class;
  761. pszSubtree = aPassInfo[i].pszSubtree;
  762. Assert (FIsValidNetClass(Class));
  763. if (!pszSubtree)
  764. {
  765. pszSubtree = MAP_NETCLASS_TO_NETWORK_SUBTREE[Class];
  766. }
  767. // Play it safe and assume we don't be deleting anything.
  768. //
  769. fDeleteKey = FALSE;
  770. if (!FIsEnumerated (Class))
  771. {
  772. hr = HrRegOpenKeyEx (HKEY_LOCAL_MACHINE,
  773. pszSubtree,
  774. KEY_READ,
  775. &hkeySubtree);
  776. if (S_OK == hr)
  777. {
  778. DWORD cchGuid;
  779. WCHAR szInstanceGuid [c_cchGuidWithTerm];
  780. FILETIME ftLastWrite;
  781. for (dwIndex = 0; S_OK == hr; dwIndex++)
  782. {
  783. fDeleteKey = FALSE;
  784. cchGuid = celems(szInstanceGuid);
  785. hr = HrRegEnumKeyEx (
  786. hkeySubtree, dwIndex, szInstanceGuid, &cchGuid,
  787. NULL, NULL, &ftLastWrite);
  788. if ((S_OK == hr) && ((c_cchGuidWithTerm-1) == cchGuid))
  789. {
  790. hr = IIDFromString (szInstanceGuid, &InstanceGuid);
  791. if (S_OK == hr)
  792. {
  793. if (!pNetConfig->Core.Components.PFindComponentByInstanceGuid(&InstanceGuid))
  794. {
  795. fDeleteKey = TRUE;
  796. hr = HrRegOpenKeyEx (
  797. hkeySubtree,
  798. szInstanceGuid,
  799. KEY_READ,
  800. &hkeyInstance);
  801. if (S_OK == hr)
  802. {
  803. *szInfPath = 0;
  804. *szInfSection = 0;
  805. cbData = sizeof(szInfPath);
  806. HrRegQuerySzBuffer (hkeyInstance,
  807. REGSTR_VAL_INFPATH,
  808. szInfPath, &cbData);
  809. cbData = sizeof(szInfSection) - sizeof(L".Remove");
  810. HrRegQuerySzBuffer (hkeyInstance,
  811. REGSTR_VAL_INFSECTION,
  812. szInfSection, &cbData);
  813. if (*szInfPath && *szInfSection)
  814. {
  815. HINF hinf;
  816. hr = HrSetupOpenInfFile (
  817. szInfPath,
  818. NULL, INF_STYLE_WIN4, NULL,
  819. &hinf);
  820. if (S_OK == hr)
  821. {
  822. wcscat (szInfSection, L".Remove");
  823. g_pDiagCtx->Printf (ttidBeDiag, "Running %S...\n", szInfSection);
  824. hr = HrCiDoCompleteSectionInstall(
  825. hinf, hkeyInstance,
  826. szInfSection, NULL,
  827. FIsEnumerated(Class));
  828. SetupCloseInfFile (hinf);
  829. }
  830. }
  831. RegCloseKey (hkeyInstance);
  832. }
  833. }
  834. }
  835. if (fDeleteKey)
  836. {
  837. g_pDiagCtx->Printf (ttidBeDiag, "Deleting tree %S...\n", szInstanceGuid);
  838. (VOID) HrRegDeleteKeyTree (hkeySubtree, szInstanceGuid);
  839. fDeleteKey = FALSE;
  840. // Back the index up by one since we just
  841. // delete the current element.
  842. //
  843. dwIndex--;
  844. }
  845. }
  846. }
  847. if (HRESULT_FROM_WIN32(ERROR_NO_MORE_ITEMS) == hr)
  848. {
  849. hr = S_OK;
  850. }
  851. RegCloseKey (hkeySubtree);
  852. }
  853. }
  854. else
  855. {
  856. HDEVINFO hdi;
  857. hr = HrSetupDiGetClassDevs (MAP_NETCLASS_TO_GUID[Class],
  858. NULL, NULL, DIGCF_PROFILE, &hdi);
  859. if (S_OK == hr)
  860. {
  861. SP_DEVINFO_DATA deid;
  862. WCHAR szPnpId [2 * _MAX_PATH];
  863. BOOL fr;
  864. for (dwIndex = 0; S_OK == hr; dwIndex++)
  865. {
  866. hr = HrSetupDiEnumDeviceInfo (hdi, dwIndex, &deid);
  867. if (S_OK == hr)
  868. {
  869. fr = SetupDiGetDeviceInstanceId (
  870. hdi, &deid,
  871. szPnpId, celems(szPnpId), NULL);
  872. if (fr)
  873. {
  874. if (!pNetConfig->Core.Components.PFindComponentByPnpId(szPnpId))
  875. {
  876. g_pDiagCtx->Printf (ttidBeDiag, "Removing %S...\n", szPnpId);
  877. ADAPTER_REMOVE_PARAMS arp = {0};
  878. CiSetReservedField (hdi, &deid, &arp);
  879. hr = HrSetupDiCallClassInstaller (
  880. DIF_REMOVE, hdi, &deid);
  881. CiClearReservedField (hdi, &deid);
  882. }
  883. }
  884. }
  885. }
  886. if (HRESULT_FROM_WIN32(ERROR_NO_MORE_ITEMS) == hr)
  887. {
  888. hr = S_OK;
  889. }
  890. SetupDiDestroyDeviceInfoList (hdi);
  891. }
  892. }
  893. }
  894. }
  895. VOID
  896. CmdRemoveComponent (
  897. IN const DIAG_OPTIONS* pOptions,
  898. IN CNetConfig* pNetConfig)
  899. {
  900. HRESULT hr;
  901. CImplINetCfg* pINetCfg;
  902. PromptForLeakCheck (pOptions, "Remove component...(dump heap)");
  903. hr = HrCreateINetCfg (TRUE, &pINetCfg);
  904. if (S_OK == hr)
  905. {
  906. INetCfgComponent* pIComp;
  907. hr = pINetCfg->FindComponent (pOptions->pszInfId, &pIComp);
  908. if (S_OK == hr)
  909. {
  910. GUID ClassGuid;
  911. hr = pIComp->GetClassGuid (&ClassGuid);
  912. if (S_OK == hr)
  913. {
  914. INetCfgClassSetup* pSetup;
  915. hr = pINetCfg->QueryNetCfgClass (
  916. &ClassGuid,
  917. IID_INetCfgClassSetup,
  918. (VOID**)&pSetup);
  919. if (S_OK == hr)
  920. {
  921. OBO_TOKEN OboToken;
  922. ZeroMemory (&OboToken, sizeof(OboToken));
  923. OboToken.Type = OBO_USER;
  924. hr = pSetup->DeInstall (
  925. pIComp,
  926. &OboToken,
  927. NULL);
  928. if (NETCFG_S_REBOOT == hr)
  929. {
  930. hr = S_OK;
  931. g_pDiagCtx->Printf (ttidBeDiag, "%S was removed, but a reboot is required.\n",
  932. pOptions->pszInfId);
  933. }
  934. if (NETCFG_S_STILL_REFERENCED == hr)
  935. {
  936. hr = S_OK;
  937. g_pDiagCtx->Printf (ttidBeDiag, "%S is still referenced\n",
  938. pOptions->pszInfId);
  939. }
  940. if (E_INVALIDARG == hr)
  941. {
  942. hr = S_OK;
  943. g_pDiagCtx->Printf (ttidBeDiag, "%S is installed, but not on behalf of "
  944. "the user, so it was not removed.\n",
  945. pOptions->pszInfId);
  946. }
  947. ReleaseObj (pSetup);
  948. }
  949. }
  950. ReleaseObj (pIComp);
  951. }
  952. else if (S_FALSE == hr)
  953. {
  954. g_pDiagCtx->Printf (ttidBeDiag, "%S was not found.\n", pOptions->pszInfId);
  955. hr = S_OK;
  956. }
  957. HRESULT hrT = pINetCfg->Uninitialize ();
  958. Assert (S_OK == hrT);
  959. ReleaseObj (pINetCfg->GetUnknown());
  960. }
  961. else if (NETCFG_E_NEED_REBOOT == hr)
  962. {
  963. hr = S_OK;
  964. }
  965. if (S_OK != hr)
  966. {
  967. g_pDiagCtx->Printf (ttidBeDiag, "FAILED Remove component.\n");
  968. }
  969. PromptForLeakCheck (pOptions, "Remove component...(dump heap and compare)");
  970. }
  971. VOID
  972. CmdUpdateComponent (
  973. IN const DIAG_OPTIONS* pOptions,
  974. IN CNetConfig* pNetConfig)
  975. {
  976. HRESULT hr;
  977. CImplINetCfg* pINetCfg;
  978. PromptForLeakCheck (pOptions, "Update component...(dump heap)");
  979. hr = HrCreateINetCfg (TRUE, &pINetCfg);
  980. if (S_OK == hr)
  981. {
  982. INetCfgComponent* pIComp;
  983. hr = pINetCfg->FindComponent (pOptions->pszInfId, &pIComp);
  984. if (S_OK == hr)
  985. {
  986. INetCfgInternalSetup* pSetup;
  987. hr = pINetCfg->GetUnknown()->QueryInterface (
  988. IID_INetCfgInternalSetup,
  989. (VOID**)&pSetup);
  990. if (S_OK == hr)
  991. {
  992. hr = pSetup->UpdateNonEnumeratedComponent (
  993. pIComp,
  994. NSF_POSTSYSINSTALL,
  995. 0);
  996. if (S_OK == hr)
  997. {
  998. hr = pINetCfg->Apply ();
  999. if (NETCFG_S_REBOOT == hr)
  1000. {
  1001. hr = S_OK;
  1002. g_pDiagCtx->Printf (ttidBeDiag, "%S was removed, but a reboot is required.\n",
  1003. pOptions->pszInfId);
  1004. }
  1005. }
  1006. ReleaseObj (pSetup);
  1007. }
  1008. ReleaseObj (pIComp);
  1009. }
  1010. else if (S_FALSE == hr)
  1011. {
  1012. g_pDiagCtx->Printf (ttidBeDiag, "%S was not found.\n", pOptions->pszInfId);
  1013. hr = S_OK;
  1014. }
  1015. HRESULT hrT = pINetCfg->Uninitialize ();
  1016. Assert (S_OK == hrT);
  1017. ReleaseObj (pINetCfg->GetUnknown());
  1018. }
  1019. else if (NETCFG_E_NEED_REBOOT == hr)
  1020. {
  1021. hr = S_OK;
  1022. }
  1023. if (S_OK != hr)
  1024. {
  1025. g_pDiagCtx->Printf (ttidBeDiag, "FAILED Update component.\n");
  1026. }
  1027. PromptForLeakCheck (pOptions, "Update component...(dump heap and compare)");
  1028. }
  1029. VOID
  1030. CmdRemoveReferences (
  1031. IN const DIAG_OPTIONS* pOptions,
  1032. IN CNetConfig* pNetConfig)
  1033. {
  1034. Assert (pOptions->pszInfId);
  1035. CComponent* pComponent;
  1036. pComponent = pNetConfig->Core.Components.PFindComponentByInfId (
  1037. pOptions->pszInfId, NULL);
  1038. if (pComponent)
  1039. {
  1040. pComponent->Refs.RemoveAllReferences();
  1041. HrSaveNetworkConfigurationToRegistry (pNetConfig);
  1042. }
  1043. }
  1044. VOID
  1045. CmdShowBindings (
  1046. IN const DIAG_OPTIONS* pOptions,
  1047. IN CNetConfig* pNetConfig)
  1048. {
  1049. HRESULT hr = S_OK;
  1050. CComponent* pComponent;
  1051. CBindingSet BindingSet;
  1052. tstring strBindingSet;
  1053. if (SHOW_DISABLED == pOptions->ShowBindParam)
  1054. {
  1055. pNetConfig->Core.DisabledBindings.Printf (ttidBeDiag, NULL);
  1056. return;
  1057. }
  1058. else if (CST_BY_NAME == pOptions->CompSpecifier.Type)
  1059. {
  1060. pComponent = pNetConfig->Core.Components.PFindComponentByPnpId (
  1061. pOptions->CompSpecifier.pszInfOrPnpId);
  1062. if (!pComponent)
  1063. {
  1064. pComponent = pNetConfig->Core.Components.PFindComponentByInfId (
  1065. pOptions->CompSpecifier.pszInfOrPnpId, NULL);
  1066. }
  1067. if (!pComponent)
  1068. {
  1069. g_pDiagCtx->Printf (ttidBeDiag, "Component not found.");
  1070. return;
  1071. }
  1072. if (SHOW_BELOW == pOptions->ShowBindParam)
  1073. {
  1074. hr = pNetConfig->Core.HrGetComponentBindings (
  1075. pComponent, GBF_DEFAULT, &BindingSet);
  1076. }
  1077. else if (SHOW_INVOLVING == pOptions->ShowBindParam)
  1078. {
  1079. hr = pNetConfig->Core.HrGetBindingsInvolvingComponent (
  1080. pComponent, GBF_DEFAULT, &BindingSet);
  1081. }
  1082. if ((SHOW_UPPER == pOptions->ShowBindParam) &&
  1083. FIsEnumerated(pComponent->Class()))
  1084. {
  1085. hr = pNetConfig->Core.HrGetComponentUpperBindings (
  1086. pComponent, GBF_DEFAULT, &BindingSet);
  1087. }
  1088. }
  1089. else if (CST_ALL == pOptions->CompSpecifier.Type)
  1090. {
  1091. CComponentList::const_iterator iter;
  1092. for (iter = pNetConfig->Core.Components.begin();
  1093. iter != pNetConfig->Core.Components.end();
  1094. iter++)
  1095. {
  1096. pComponent = *iter;
  1097. Assert (pComponent);
  1098. hr = pNetConfig->Core.HrGetComponentBindings (
  1099. pComponent,
  1100. GBF_ADD_TO_BINDSET,
  1101. &BindingSet);
  1102. if (S_OK != hr) break;
  1103. }
  1104. }
  1105. if ((S_OK == hr) && !BindingSet.FIsEmpty())
  1106. {
  1107. BindingSet.Printf (ttidBeDiag, NULL);
  1108. }
  1109. }
  1110. VOID
  1111. CmdShowComponents (
  1112. IN const DIAG_OPTIONS* pOptions,
  1113. IN CNetConfig* pNetConfig)
  1114. {
  1115. HRESULT hr;
  1116. CComponentList::const_iterator iter;
  1117. const CComponent* pComponent;
  1118. WCHAR szBuffer [256];
  1119. CHAR* pszNetClass;
  1120. UINT CountRefdBy;
  1121. UINT i;
  1122. hr = pNetConfig->HrEnsureExternalDataLoadedForAllComponents ();
  1123. if (S_OK != hr)
  1124. {
  1125. return;
  1126. }
  1127. for (iter = pNetConfig->Core.Components.begin();
  1128. iter != pNetConfig->Core.Components.end();
  1129. iter++)
  1130. {
  1131. pComponent = *iter;
  1132. Assert (pComponent);
  1133. StringFromGUID2 (pComponent->m_InstanceGuid,
  1134. szBuffer, celems(szBuffer));
  1135. switch (pComponent->Class())
  1136. {
  1137. case NC_NET:
  1138. pszNetClass = "NET ";
  1139. break;
  1140. case NC_INFRARED:
  1141. pszNetClass = "INFRARED ";
  1142. break;
  1143. case NC_NETTRANS:
  1144. pszNetClass = "TRANSPORT";
  1145. break;
  1146. case NC_NETCLIENT:
  1147. pszNetClass = "CLIENT ";
  1148. break;
  1149. case NC_NETSERVICE:
  1150. pszNetClass = "SERVICE ";
  1151. break;
  1152. default:
  1153. pszNetClass = "(Invalid)";
  1154. break;
  1155. }
  1156. tstring strChars;
  1157. SzFromCharacteristics(pComponent->m_dwCharacter, &strChars);
  1158. g_pDiagCtx->Printf (ttidBeDiag,
  1159. "\n"
  1160. "%S %S\n" // InfId PnpId
  1161. " Description: %S\n"
  1162. " Class: %s\n"
  1163. " Character: (0x%08x) %S\n"
  1164. " Guid: %S\n"
  1165. " NotifyObject?: %s\n"
  1166. " BindForm: %S\n"
  1167. " BindName: %S\n"
  1168. " Service (CoServices): %S (%S)\n"
  1169. " Ref'd by User?: %s\n",
  1170. pComponent->m_pszInfId,
  1171. (pComponent->m_pszPnpId) ? pComponent->m_pszPnpId : L"",
  1172. (pComponent->Ext.PszDescription()) ? pComponent->Ext.PszDescription() : L"<no description>",
  1173. pszNetClass, pComponent->m_dwCharacter, strChars.c_str(), szBuffer,
  1174. pComponent->Ext.FHasNotifyObject() ? "Yes" : "No",
  1175. (pComponent->Ext.PszBindForm()) ? pComponent->Ext.PszBindForm() : L"<default>",
  1176. pComponent->Ext.PszBindName(),
  1177. (pComponent->Ext.PszService()) ? pComponent->Ext.PszService() : L"(none)",
  1178. (pComponent->Ext.PszCoServices()) ? pComponent->Ext.PszCoServices() : L"none",
  1179. (pComponent->Refs.FIsReferencedByUser()) ? "Yes" : "No");
  1180. CountRefdBy = pComponent->Refs.CountComponentsReferencedBy();
  1181. if (CountRefdBy)
  1182. {
  1183. *szBuffer = 0;
  1184. for (i = 0; i < CountRefdBy; i++)
  1185. {
  1186. CComponent* pRefdBy;
  1187. pRefdBy = pComponent->Refs.PComponentReferencedByAtIndex(i);
  1188. Assert (pRefdBy);
  1189. wcscat (szBuffer, pRefdBy->PszGetPnpIdOrInfId());
  1190. wcscat (szBuffer, L" ");
  1191. }
  1192. }
  1193. else
  1194. {
  1195. wcscpy (szBuffer, L"(none)");
  1196. }
  1197. g_pDiagCtx->Printf (ttidBeDiag,
  1198. " Ref'd by Components: %S\n", szBuffer);
  1199. CountRefdBy = pComponent->Refs.CountSoftwareReferencedBy();
  1200. if (CountRefdBy)
  1201. {
  1202. *szBuffer = 0;
  1203. for (i = 0; i < CountRefdBy; i++)
  1204. {
  1205. const CWideString* pRefdBy;
  1206. pRefdBy = pComponent->Refs.PSoftwareReferencedByAtIndex(i);
  1207. Assert (pRefdBy);
  1208. wcscat (szBuffer, pRefdBy->c_str());
  1209. wcscat (szBuffer, L" ");
  1210. }
  1211. }
  1212. else
  1213. {
  1214. wcscpy (szBuffer, L"(none)");
  1215. }
  1216. g_pDiagCtx->Printf (ttidBeDiag,
  1217. " Ref'd by Software: %S\n", szBuffer);
  1218. }
  1219. g_pDiagCtx->Printf (ttidBeDiag, "\n");
  1220. }
  1221. VOID
  1222. CmdShowStackTable (
  1223. IN const DIAG_OPTIONS* pOptions,
  1224. IN CNetConfig* pNetConfig)
  1225. {
  1226. const CStackEntry* pStackEntry;
  1227. g_pDiagCtx->Printf (ttidBeDiag, "\n%15s | %s\n"
  1228. "---------------------------------\n",
  1229. "Upper",
  1230. "Lower");
  1231. for (pStackEntry = pNetConfig->Core.StackTable.begin();
  1232. pStackEntry != pNetConfig->Core.StackTable.end();
  1233. pStackEntry++)
  1234. {
  1235. g_pDiagCtx->Printf (ttidBeDiag, "%15S | %S\n",
  1236. pStackEntry->pUpper->PszGetPnpIdOrInfId(),
  1237. pStackEntry->pLower->PszGetPnpIdOrInfId());
  1238. }
  1239. g_pDiagCtx->Printf (ttidBeDiag, "\n");
  1240. g_pDiagCtx->Printf (ttidBeDiag, "WAN adapters are ordered %s\n\n",
  1241. (pNetConfig->Core.StackTable.m_fWanAdaptersFirst)
  1242. ? "first" : "last");
  1243. }
  1244. VOID
  1245. CmdShowLanAdapterPnpIds (
  1246. IN const DIAG_OPTIONS* pOptions,
  1247. IN CNetConfig* pNetConfig)
  1248. {
  1249. HRESULT hr;
  1250. CComponentList::const_iterator iter;
  1251. const CComponent* pComponent;
  1252. hr = pNetConfig->HrEnsureExternalDataLoadedForAllComponents ();
  1253. if (S_OK != hr)
  1254. {
  1255. return;
  1256. }
  1257. for (iter = pNetConfig->Core.Components.begin();
  1258. iter != pNetConfig->Core.Components.end();
  1259. iter++)
  1260. {
  1261. pComponent = *iter;
  1262. Assert (pComponent);
  1263. if (!FSubstringMatch (pComponent->Ext.PszUpperRange (), L"ndis5",
  1264. NULL, NULL))
  1265. {
  1266. continue;
  1267. }
  1268. g_pDiagCtx->Printf (ttidBeDiag, "%S\n", pComponent->m_pszPnpId);
  1269. }
  1270. }
  1271. VOID
  1272. CmdEnableOrDisableBinding (
  1273. IN const DIAG_OPTIONS* pOptions,
  1274. IN BOOL fEnable)
  1275. {
  1276. HRESULT hr;
  1277. CImplINetCfg* pINetCfg;
  1278. hr = HrCreateINetCfg (TRUE, &pINetCfg);
  1279. if (S_OK == hr)
  1280. {
  1281. INetCfgBindingPath* pIPath;
  1282. hr = HrFindBindPath (pINetCfg, pOptions->pszBindPath, &pIPath, NULL);
  1283. if ((S_OK == hr) && pIPath)
  1284. {
  1285. pIPath->Enable (fEnable);
  1286. ReleaseObj (pIPath);
  1287. }
  1288. hr = pINetCfg->Apply ();
  1289. if (S_OK != hr)
  1290. {
  1291. g_pDiagCtx->Printf (ttidBeDiag, "FAILED to %s binding\n",
  1292. (fEnable) ? "enable" : "disable");
  1293. }
  1294. HRESULT hrT = pINetCfg->Uninitialize ();
  1295. Assert (S_OK == hrT);
  1296. ReleaseObj (pINetCfg->GetUnknown());
  1297. }
  1298. }
  1299. VOID
  1300. CmdMoveBinding (
  1301. IN const DIAG_OPTIONS* pOptions)
  1302. {
  1303. HRESULT hr;
  1304. CImplINetCfg* pINetCfg;
  1305. hr = HrCreateINetCfg (TRUE, &pINetCfg);
  1306. if (S_OK == hr)
  1307. {
  1308. INetCfgBindingPath* pIPath;
  1309. INetCfgBindingPath* pIOtherPath;
  1310. INetCfgComponentBindings* pIOwner;
  1311. hr = HrFindBindPath (pINetCfg, pOptions->pszBindPath, &pIPath, &pIOwner);
  1312. if ((S_OK == hr) && pIPath)
  1313. {
  1314. if (0 == _wcsicmp(pOptions->pszOtherBindPath, L"null"))
  1315. {
  1316. pIOtherPath = NULL;
  1317. }
  1318. else
  1319. {
  1320. hr = HrFindBindPath (pINetCfg, pOptions->pszOtherBindPath,
  1321. &pIOtherPath, NULL);
  1322. }
  1323. if (S_OK == hr)
  1324. {
  1325. if (pOptions->fMoveBefore)
  1326. {
  1327. hr = pIOwner->MoveBefore (pIPath, pIOtherPath);
  1328. }
  1329. else
  1330. {
  1331. hr = pIOwner->MoveAfter (pIPath, pIOtherPath);
  1332. }
  1333. ReleaseObj (pIOtherPath);
  1334. }
  1335. ReleaseObj (pIPath);
  1336. ReleaseObj (pIOwner);
  1337. }
  1338. hr = pINetCfg->Apply ();
  1339. if (S_OK != hr)
  1340. {
  1341. g_pDiagCtx->Printf (ttidBeDiag, "FAILED to move binding\n");
  1342. }
  1343. HRESULT hrT = pINetCfg->Uninitialize ();
  1344. Assert (S_OK == hrT);
  1345. ReleaseObj (pINetCfg->GetUnknown());
  1346. }
  1347. }
  1348. VOID
  1349. CmdWriteBindings (
  1350. IN const DIAG_OPTIONS* pOptions OPTIONAL,
  1351. IN CNetConfig* pNetConfig)
  1352. {
  1353. HRESULT hr;
  1354. CComponentList::const_iterator iter;
  1355. const CComponent* pComponent;
  1356. CRegistryBindingsContext RegBindCtx;
  1357. hr = RegBindCtx.HrPrepare (pNetConfig);
  1358. if (S_OK != hr)
  1359. {
  1360. return;
  1361. }
  1362. for (iter = pNetConfig->Core.Components.begin();
  1363. iter != pNetConfig->Core.Components.end();
  1364. iter++)
  1365. {
  1366. pComponent = *iter;
  1367. Assert (pComponent);
  1368. hr = RegBindCtx.HrWriteBindingsForComponent (pComponent);
  1369. }
  1370. }
  1371. VOID
  1372. CmdSetWanOrder (
  1373. IN const DIAG_OPTIONS* pOptions)
  1374. {
  1375. HRESULT hr;
  1376. CImplINetCfg* pINetCfg;
  1377. hr = HrCreateINetCfg (TRUE, &pINetCfg);
  1378. if (S_OK == hr)
  1379. {
  1380. INetCfgSpecialCase* pSpecialCase;
  1381. hr = pINetCfg->GetUnknown()->QueryInterface (
  1382. IID_INetCfgSpecialCase,
  1383. (VOID**)&pSpecialCase);
  1384. Assert (S_OK == hr);
  1385. hr = pSpecialCase->SetWanAdaptersFirst (pOptions->fWanAdaptersFirst);
  1386. ReleaseObj (pSpecialCase);
  1387. hr = pINetCfg->Apply ();
  1388. if (S_OK != hr)
  1389. {
  1390. g_pDiagCtx->Printf (ttidBeDiag, "FAILED to move binding\n");
  1391. }
  1392. HRESULT hrT = pINetCfg->Uninitialize ();
  1393. Assert (S_OK == hrT);
  1394. ReleaseObj (pINetCfg->GetUnknown());
  1395. }
  1396. }
  1397. VOID
  1398. CmdShowLanaDiag (
  1399. IN const DIAG_OPTIONS* pOptions)
  1400. {
  1401. CLanaMap LanaMap;
  1402. HRESULT hr;
  1403. hr = LanaMap.HrLoadLanaMap();
  1404. if (S_OK == hr)
  1405. {
  1406. g_pDiagCtx->Printf (ttidBeDiag, "NetBios Bindings and Lana Information\n"
  1407. "-------------------------------------\n");
  1408. CWideString str;
  1409. LanaMap.Dump (&str);
  1410. g_pDiagCtx->Printf (ttidBeDiag, "%S", str.c_str());
  1411. HKEY hkeyNetBios;
  1412. hr = HrRegOpenKeyEx (HKEY_LOCAL_MACHINE,
  1413. L"System\\currentcontrolset\\services\\netbios\\parameters",
  1414. KEY_READ, &hkeyNetBios);
  1415. if (S_OK == hr)
  1416. {
  1417. DWORD MaxLana;
  1418. hr = HrRegQueryDword (hkeyNetBios, L"MaxLana", &MaxLana);
  1419. if (S_OK == hr)
  1420. {
  1421. g_pDiagCtx->Printf (ttidBeDiag, "\nMaximum Lana: %d\n", MaxLana);
  1422. }
  1423. RegCloseKey (hkeyNetBios);
  1424. }
  1425. }
  1426. }
  1427. HRESULT
  1428. HrPrintComponentDescriptionsFromBindPath (
  1429. IN PCWSTR pszBindPath,
  1430. IN CNetConfig* pNetConfig)
  1431. {
  1432. HRESULT hr = S_OK;
  1433. PCWSTR pszBindName;
  1434. PCWSTR pszEnd;
  1435. DWORD cchComponent;
  1436. CComponent* pComponent;
  1437. WCHAR szComponentBindName[_MAX_PATH] = {0};
  1438. Assert (pszBindPath && *pszBindPath);
  1439. GetFirstComponentFromBindPath (pszBindPath, &pszBindName,
  1440. &cchComponent);
  1441. while (pszBindName && *pszBindName)
  1442. {
  1443. wcsncpy (szComponentBindName, pszBindName, cchComponent);
  1444. pComponent = pNetConfig->Core.Components.
  1445. PFindComponentByBindName (NC_INVALID, szComponentBindName);
  1446. if (pComponent)
  1447. {
  1448. g_pDiagCtx->Printf (ttidBeDiag, "-->%S", pComponent->Ext.PszDescription());
  1449. }
  1450. #ifdef ENABLETRACE
  1451. else
  1452. {
  1453. g_pDiagCtx->Printf (ttidBeDiag, "%S", szComponentBindName);
  1454. }
  1455. #endif // ENABLETRACE
  1456. pszBindName = wcschr (pszBindName, L'_');
  1457. if (pszBindName)
  1458. {
  1459. pszBindName++;
  1460. pszEnd = wcschr (pszBindName, L'_');
  1461. if (pszEnd)
  1462. {
  1463. cchComponent = (DWORD)(pszEnd - pszBindName);
  1464. }
  1465. else
  1466. {
  1467. cchComponent = wcslen (pszBindName);
  1468. }
  1469. }
  1470. }
  1471. TraceHr (ttidError, FAL, hr, FALSE,
  1472. "HrPrintComponentDescriptionsFromBindPath");
  1473. return hr;
  1474. }
  1475. VOID
  1476. CmdShowLanaPaths (
  1477. IN const DIAG_OPTIONS* pOptions,
  1478. IN CNetConfig* pNetConfig)
  1479. {
  1480. HRESULT hr;
  1481. CLanaMap LanaMap;
  1482. PCWSTR pszBindPath;
  1483. CLanaEntry* pEntry;
  1484. PromptForLeakCheck (pOptions,
  1485. "Show Lana UI info diagnostic...(dump heap)");
  1486. hr = pNetConfig->HrEnsureExternalDataLoadedForAllComponents();
  1487. if (S_OK != hr)
  1488. {
  1489. return;
  1490. }
  1491. hr = LanaMap.HrLoadLanaMap();
  1492. if (S_OK == hr)
  1493. {
  1494. PCWSTR pszBindName;
  1495. PCWSTR pszEnd;
  1496. DWORD cchComponent;
  1497. CComponent* pComponent;
  1498. WCHAR szComponentBindName[_MAX_PATH] = {0};
  1499. for (pEntry = LanaMap.begin(); pEntry != LanaMap.end();
  1500. pEntry++)
  1501. {
  1502. if (1 == pEntry->RegLanaEntry.Exported)
  1503. {
  1504. g_pDiagCtx->Printf (ttidNcDiag, "Lana: %3d\n",
  1505. pEntry->RegLanaEntry.LanaNumber);
  1506. pszBindPath = pEntry->pszBindPath;
  1507. GetFirstComponentFromBindPath (pszBindPath,
  1508. &pszBindName, &cchComponent);
  1509. while (pszBindName && *pszBindName)
  1510. {
  1511. wcsncpy (szComponentBindName, pszBindName, cchComponent);
  1512. szComponentBindName[cchComponent] = 0;
  1513. pComponent = pNetConfig->Core.Components.
  1514. PFindComponentByBindName (NC_INVALID,
  1515. szComponentBindName);
  1516. if (pComponent)
  1517. {
  1518. g_pDiagCtx->Printf (ttidNcDiag, "-->%S",
  1519. pComponent->Ext.PszDescription());
  1520. }
  1521. #ifdef ENABLETRACE
  1522. else
  1523. {
  1524. g_pDiagCtx->Printf (ttidNcDiag, "-->%S", szComponentBindName);
  1525. }
  1526. #endif // ENABLETRACE
  1527. pszBindName = wcschr (pszBindName, L'_');
  1528. if (pszBindName)
  1529. {
  1530. pszBindName++;
  1531. pszEnd = wcschr (pszBindName, L'_');
  1532. if (pszEnd)
  1533. {
  1534. cchComponent = (DWORD)(pszEnd - pszBindName);
  1535. }
  1536. else
  1537. {
  1538. cchComponent = wcslen (pszBindName);
  1539. }
  1540. }
  1541. }
  1542. if (FAILED(hr))
  1543. {
  1544. break;
  1545. }
  1546. g_pDiagCtx->Printf (ttidNcDiag, "\n\n");
  1547. }
  1548. }
  1549. }
  1550. PromptForLeakCheck (pOptions,
  1551. "Show Lana UI info diagnostic...(dump heap and compare)");
  1552. }
  1553. VOID
  1554. CmdSetLanaNumber (
  1555. IN const DIAG_OPTIONS* pOptions,
  1556. IN CNetConfig* pNetConfig)
  1557. {
  1558. CLanaMap LanaMap;
  1559. HRESULT hr;
  1560. hr = pNetConfig->HrEnsureExternalDataLoadedForAllComponents();
  1561. if (S_OK != hr)
  1562. {
  1563. return;
  1564. }
  1565. hr = LanaMap.HrLoadLanaMap();
  1566. if (S_OK == hr)
  1567. {
  1568. if (pOptions->OldLanaNumber != pOptions->NewLanaNumber)
  1569. {
  1570. hr = LanaMap.HrSetLanaNumber (pOptions->OldLanaNumber,
  1571. pOptions->NewLanaNumber);
  1572. if (S_OK == hr)
  1573. {
  1574. hr = LanaMap.HrWriteLanaConfiguration (
  1575. pNetConfig->Core.Components);
  1576. g_pDiagCtx->Printf (ttidNcDiag, "\nLana changed.\n");
  1577. }
  1578. }
  1579. else
  1580. {
  1581. g_pDiagCtx->Printf (ttidNcDiag, "\nNo change.\n");
  1582. }
  1583. }
  1584. if (S_OK != hr)
  1585. {
  1586. if (HRESULT_FROM_WIN32(ERROR_OBJECT_NOT_FOUND) == hr)
  1587. {
  1588. g_pDiagCtx->Printf (ttidNcDiag, "\nThe old lana number is not currently "
  1589. "assigned to a bind path.\n");
  1590. }
  1591. else if (HRESULT_FROM_WIN32(ERROR_ALREADY_EXISTS) == hr)
  1592. {
  1593. g_pDiagCtx->Printf (ttidNcDiag, "\nThe new lana number is currently assigned "
  1594. "to a bind path.\n");
  1595. }
  1596. else
  1597. {
  1598. g_pDiagCtx->Printf (ttidNcDiag, "\nError %X occurred\n", hr);
  1599. }
  1600. }
  1601. }
  1602. VOID
  1603. CmdRewriteLanaInfo (
  1604. IN const DIAG_OPTIONS* pOptions,
  1605. IN CNetConfig* pNetConfig)
  1606. {
  1607. HRESULT hr;
  1608. const CComponent* pComponent;
  1609. CRegistryBindingsContext RegBindCtx;
  1610. hr = RegBindCtx.HrPrepare (pNetConfig);
  1611. if (S_OK == hr)
  1612. {
  1613. pComponent = pNetConfig->Core.Components.
  1614. PFindComponentByInfId (L"MS_NetBios", NULL);
  1615. if (pComponent)
  1616. {
  1617. hr = RegBindCtx.HrWriteBindingsForComponent (pComponent);
  1618. }
  1619. else
  1620. {
  1621. g_pDiagCtx->Printf (ttidNcDiag, "\nNetBios is not installed.\n");
  1622. }
  1623. }
  1624. }
  1625. EXTERN_C
  1626. VOID
  1627. WINAPI
  1628. NetCfgDiagFromCommandArgs (
  1629. IN DIAG_OPTIONS* pOptions)
  1630. {
  1631. Assert (pOptions);
  1632. Assert (pOptions->pDiagCtx);
  1633. g_pDiagCtx = pOptions->pDiagCtx;
  1634. CNetConfig NetConfig;
  1635. HrLoadNetworkConfigurationFromRegistry (KEY_READ, &NetConfig);
  1636. switch (pOptions->Command)
  1637. {
  1638. case CMD_SHOW_BINDINGS:
  1639. CmdShowBindings (pOptions, &NetConfig);
  1640. break;
  1641. case CMD_SHOW_COMPONENTS:
  1642. CmdShowComponents (pOptions, &NetConfig);
  1643. break;
  1644. case CMD_SHOW_STACK_TABLE:
  1645. CmdShowStackTable (pOptions, &NetConfig);
  1646. break;
  1647. case CMD_SHOW_LAN_ADAPTER_PNPIDS:
  1648. CmdShowLanAdapterPnpIds (pOptions, &NetConfig);
  1649. break;
  1650. case CMD_ADD_COMPONENT:
  1651. CmdAddComponent (pOptions, &NetConfig);
  1652. break;
  1653. case CMD_REMOVE_COMPONENT:
  1654. CmdRemoveComponent (pOptions, &NetConfig);
  1655. break;
  1656. case CMD_UPDATE_COMPONENT:
  1657. CmdUpdateComponent (pOptions, &NetConfig);
  1658. break;
  1659. case CMD_REMOVE_REFS:
  1660. CmdRemoveReferences (pOptions, &NetConfig);
  1661. break;
  1662. case CMD_ENABLE_BINDING:
  1663. CmdEnableOrDisableBinding (pOptions, TRUE);
  1664. break;
  1665. case CMD_DISABLE_BINDING:
  1666. CmdEnableOrDisableBinding (pOptions, FALSE);
  1667. break;
  1668. case CMD_MOVE_BINDING:
  1669. CmdMoveBinding (pOptions);
  1670. break;
  1671. case CMD_WRITE_BINDINGS:
  1672. CmdWriteBindings (pOptions, &NetConfig);
  1673. break;
  1674. case CMD_SET_WANORDER:
  1675. CmdSetWanOrder (pOptions);
  1676. break;
  1677. case CMD_FULL_DIAGNOSTIC:
  1678. CNetCfgInternalDiagnostic::CmdFullDiagnostic (pOptions, &NetConfig);
  1679. break;
  1680. case CMD_CLEANUP:
  1681. CmdCleanup (pOptions, &NetConfig);
  1682. break;
  1683. case CMD_ADD_REMOVE_STRESS:
  1684. CmdAddRemoveStress (pOptions, &NetConfig);
  1685. break;
  1686. default:
  1687. break;
  1688. }
  1689. g_pDiagCtx = NULL;
  1690. }
  1691. EXTERN_C
  1692. VOID
  1693. WINAPI
  1694. NetCfgDiagRepairRegistryBindings (
  1695. IN FILE* pLogFile)
  1696. {
  1697. HRESULT hr;
  1698. BOOL fCoUninitialize = TRUE;
  1699. hr = CoInitializeEx (NULL,
  1700. COINIT_DISABLE_OLE1DDE | COINIT_APARTMENTTHREADED);
  1701. if (FAILED(hr))
  1702. {
  1703. fCoUninitialize = FALSE;
  1704. if (RPC_E_CHANGED_MODE == hr)
  1705. {
  1706. hr = S_OK;
  1707. }
  1708. else
  1709. {
  1710. fprintf(pLogFile, "CoInitializeEx failed. (hr=0x%08x)\n", hr);
  1711. }
  1712. }
  1713. if (SUCCEEDED(hr))
  1714. {
  1715. CDiagContext DiagCtx;
  1716. CNetConfig NetConfig;
  1717. DiagCtx.SetFlags (DF_REPAIR_REGISTRY_BINDINGS);
  1718. DiagCtx.SetLogFile (pLogFile);
  1719. g_pDiagCtx = &DiagCtx;
  1720. hr = HrLoadNetworkConfigurationFromRegistry (KEY_READ, &NetConfig);
  1721. if (S_OK == hr)
  1722. {
  1723. CmdWriteBindings (NULL, &NetConfig);
  1724. }
  1725. else
  1726. {
  1727. fprintf(pLogFile,
  1728. "Failed to load network configuration "
  1729. "from the registry. (hr=0x%08x)\n", hr);
  1730. }
  1731. g_pDiagCtx = NULL;
  1732. if (fCoUninitialize)
  1733. {
  1734. CoUninitialize ();
  1735. }
  1736. }
  1737. }
  1738. EXTERN_C
  1739. VOID
  1740. WINAPI
  1741. LanaCfgFromCommandArgs (
  1742. IN DIAG_OPTIONS* pOptions)
  1743. {
  1744. Assert (pOptions);
  1745. Assert (pOptions->pDiagCtx);
  1746. g_pDiagCtx = pOptions->pDiagCtx;
  1747. CNetConfig NetConfig;
  1748. HrLoadNetworkConfigurationFromRegistry (KEY_READ, &NetConfig);
  1749. switch (pOptions->Command)
  1750. {
  1751. case CMD_SHOW_LANA_DIAG:
  1752. CmdShowLanaDiag (pOptions);
  1753. break;
  1754. case CMD_SHOW_LANA_PATHS:
  1755. CmdShowLanaPaths (pOptions, &NetConfig);
  1756. break;
  1757. case CMD_SET_LANA_NUMBER:
  1758. CmdSetLanaNumber (pOptions, &NetConfig);
  1759. break;
  1760. case CMD_REWRITE_LANA_INFO:
  1761. CmdRewriteLanaInfo (pOptions, &NetConfig);
  1762. break;
  1763. default:
  1764. break;
  1765. }
  1766. g_pDiagCtx = NULL;
  1767. }