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.

1047 lines
25 KiB

  1. #include "precomp.h"
  2. #pragma hdrstop
  3. #include "private.h"
  4. #include "engine.h"
  5. #include "resource.h"
  6. #include "Document.h"
  7. #include "Application.h"
  8. #include "MainForm.h"
  9. #include "AboutDialog.h"
  10. #include "application.tmh"
  11. #include <process.h>
  12. Application theApplication;
  13. MUsingCom usingCom;
  14. BOOL CanRunNLB(void);
  15. BEGIN_MESSAGE_MAP( Application, CWinApp )
  16. ON_COMMAND( ID_HELP, OnHelp )
  17. ON_COMMAND( ID_APP_ABOUT, OnAppAbout )
  18. END_MESSAGE_MAP()
  19. // #define szNLBMGRREG_DISABLE_DISCLAIMER L"DisableNlbMgrDisclaimer"
  20. #if DBG
  21. //
  22. // Allow the DEMO cmdline option
  23. //
  24. #define ALLOW_DEMO 1
  25. #endif //DBG
  26. BOOL NoAdminNics(void);
  27. void
  28. CNlbMgrCommandLineInfo::ParseParam(
  29. LPCTSTR lpszParam,
  30. BOOL bFlag,
  31. BOOL bLast
  32. )
  33. //
  34. // -demo
  35. // -hostlist file.txt
  36. // -help -?
  37. // -autoresfresh
  38. // -noping
  39. {
  40. static enum Commands {
  41. None = 0,
  42. Demo,
  43. NoPing,
  44. HostList,
  45. AutoRefresh
  46. };
  47. static UINT LastCommand = None;
  48. TRACE_VERB("-> %!FUNC! (szParm=\"%ws\", bFlag=%lu, bLast=%lu)", lpszParam, bFlag, bLast);
  49. if (m_bUsage)
  50. {
  51. goto end;
  52. }
  53. if (bFlag)
  54. {
  55. /* Throw an error if this is a flag, but the last command was the
  56. HostList command, which REQUIRES a non-flag argument following it. */
  57. if (LastCommand == HostList)
  58. {
  59. /* Turn the host list option off to keep NLB manager
  60. from trying to open NULL filename. */
  61. m_bHostList = FALSE;
  62. m_bUsage = TRUE; // error
  63. goto end;
  64. }
  65. #if ALLOW_DEMO
  66. if (!_wcsicmp(lpszParam, L"demo"))
  67. {
  68. if (m_bDemo)
  69. {
  70. m_bUsage = TRUE; // error
  71. goto end;
  72. }
  73. m_bDemo = TRUE;
  74. LastCommand = Demo;
  75. }
  76. else
  77. #endif // ALLOW_DEMO
  78. if (!_wcsicmp(lpszParam, L"noping"))
  79. {
  80. if (m_bNoPing)
  81. {
  82. m_bUsage = TRUE; // error
  83. goto end;
  84. }
  85. m_bNoPing = TRUE;
  86. LastCommand = NoPing;
  87. }
  88. else if (!_wcsicmp(lpszParam, L"hostlist"))
  89. {
  90. if (m_bHostList || bLast)
  91. {
  92. m_bUsage = TRUE; // error
  93. goto end;
  94. }
  95. m_bHostList = TRUE;
  96. LastCommand = HostList;
  97. }
  98. else if (!_wcsicmp(lpszParam, L"autorefresh"))
  99. {
  100. if (m_bAutoRefresh)
  101. {
  102. m_bUsage = TRUE; // error
  103. goto end;
  104. }
  105. m_bAutoRefresh = TRUE;
  106. LastCommand = AutoRefresh;
  107. }
  108. else
  109. {
  110. m_bUsage = TRUE; // error or help
  111. }
  112. }
  113. else
  114. {
  115. switch (LastCommand) {
  116. case None:
  117. m_bUsage = TRUE; // error
  118. break;
  119. case Demo:
  120. m_bUsage = TRUE; // error
  121. break;
  122. case NoPing:
  123. m_bUsage = TRUE; // error
  124. break;
  125. case HostList:
  126. m_bstrHostListFile = _bstr_t(lpszParam); // read the file name of the host list
  127. break;
  128. case AutoRefresh:
  129. m_refreshInterval = _wtoi(lpszParam); // read the refresh interval
  130. /* If the specified refresh interval is too small to be practical, re-set it. */
  131. if (m_refreshInterval < NLBMGR_AUTOREFRESH_MIN_INTERVAL)
  132. m_refreshInterval = NLBMGR_AUTOREFRESH_MIN_INTERVAL;
  133. break;
  134. default:
  135. m_bUsage = TRUE; // error
  136. break;
  137. }
  138. /* Re-set the last command. */
  139. LastCommand = None;
  140. }
  141. end:
  142. TRACE_VERB("%!FUNC! <-");
  143. }
  144. BOOL
  145. Application::ProcessShellCommand(
  146. CNlbMgrCommandLineInfo& rCmdInfo
  147. )
  148. {
  149. BOOL fRet = FALSE;
  150. LPCWSTR szFile = NULL;
  151. TRACE_CRIT("-> %!FUNC!");
  152. fRet = CWinApp::ProcessShellCommand(rCmdInfo);
  153. if (!fRet)
  154. {
  155. goto end;
  156. }
  157. szFile = (LPCWSTR) rCmdInfo.m_bstrHostListFile;
  158. if (szFile==NULL)
  159. {
  160. szFile = L"<null>";
  161. }
  162. TRACE_VERB("%!FUNC! bUsage=%lu bDemo=%lu bNoPing=%lu bHostList=%lu szFile=\"%ws\"",
  163. rCmdInfo.m_bUsage,
  164. rCmdInfo.m_bDemo,
  165. rCmdInfo.m_bNoPing,
  166. rCmdInfo.m_bHostList,
  167. szFile
  168. );
  169. if (rCmdInfo.m_bUsage)
  170. {
  171. _bstr_t bstrMsg = GETRESOURCEIDSTRING( IDS_USAGE_MESSAGE );
  172. _bstr_t bstrTitle = GETRESOURCEIDSTRING( IDS_USAGE_TITLE );
  173. ::MessageBox(
  174. NULL,
  175. (LPCWSTR) bstrMsg,
  176. (LPCWSTR) bstrTitle,
  177. MB_ICONINFORMATION | MB_OK
  178. );
  179. fRet = FALSE;
  180. }
  181. else
  182. {
  183. if (rCmdInfo.m_bDemo)
  184. {
  185. _bstr_t bstrMsg = GETRESOURCEIDSTRING( IDS_DEMO_MESSAGE );
  186. _bstr_t bstrTitle = GETRESOURCEIDSTRING( IDS_DEMO_TITLE );
  187. ::MessageBox(
  188. NULL,
  189. (LPCWSTR) bstrMsg,
  190. (LPCWSTR) bstrTitle,
  191. MB_ICONINFORMATION | MB_OK
  192. );
  193. }
  194. fRet = TRUE;
  195. }
  196. end:
  197. TRACE_CRIT("<- %!FUNC! returns %lu", fRet);
  198. return fRet;
  199. }
  200. BOOL
  201. Application::InitInstance()
  202. {
  203. BOOL fRet = FALSE;
  204. WPP_INIT_TRACING(L"Microsoft\\NLB\\TPROV");
  205. TRACE_INFO("------------ APPLICATION INITITIALIZATION -------------");
  206. //
  207. // Set the current thread id as the main thread id
  208. //
  209. m_dwMainThreadId = GetCurrentThreadId();
  210. ParseCommandLine(gCmdLineInfo);
  211. m_pSingleDocumentTemplate =
  212. new CSingleDocTemplate( IDR_MAINFRAME,
  213. RUNTIME_CLASS( Document ),
  214. RUNTIME_CLASS( MainForm ),
  215. RUNTIME_CLASS( LeftView) );
  216. AddDocTemplate( m_pSingleDocumentTemplate );
  217. //
  218. // NOTE: ProcessShellCommand is our (Application) own version. It
  219. // calls CWinApp::ProcessShellCommand.
  220. //
  221. fRet = ProcessShellCommand( gCmdLineInfo );
  222. if (!fRet)
  223. {
  224. goto end;
  225. }
  226. fRet = CanRunNLB();
  227. // fall through...
  228. end:
  229. if (!fRet)
  230. {
  231. // Deinit tracing here.
  232. WPP_CLEANUP();
  233. }
  234. return fRet;
  235. }
  236. void
  237. Application::OnAppAbout()
  238. {
  239. AboutDialog aboutDlg;
  240. aboutDlg.DoModal();
  241. }
  242. void
  243. Application::OnHelp()
  244. {
  245. WCHAR wbuf[CVY_STR_SIZE];
  246. /* Spawn the windows help process. */
  247. StringCbPrintf(wbuf, sizeof(wbuf), L"%ls\\help\\%ls", _wgetenv(L"WINDIR"), CVY_HELP_FILE);
  248. _wspawnlp(P_NOWAIT, L"hh.exe", L"hh.exe", wbuf, NULL);
  249. }
  250. BOOL CanRunNLB(void)
  251. /*
  252. Checks if NLB can run on the current machine. The main check is to make sure that there is atleast one active NIC without NLB bound.
  253. */
  254. {
  255. if (NoAdminNics())
  256. {
  257. ::MessageBox(
  258. NULL,
  259. GETRESOURCEIDSTRING( IDS_CANTRUN_NONICS_TEXT), // Contents
  260. GETRESOURCEIDSTRING( IDS_CANTRUN_NONICS_CAPTION), // caption
  261. MB_ICONSTOP | MB_OK );
  262. }
  263. else
  264. {
  265. // ::ShowDisclaimer();
  266. }
  267. return TRUE;
  268. }
  269. //
  270. // This class manages NetCfg interfaces
  271. //
  272. class AppMyNetCfg
  273. {
  274. public:
  275. AppMyNetCfg(VOID)
  276. {
  277. m_pINetCfg = NULL;
  278. m_pLock = NULL;
  279. }
  280. ~AppMyNetCfg()
  281. {
  282. ASSERT(m_pINetCfg==NULL);
  283. ASSERT(m_pLock==NULL);
  284. }
  285. WBEMSTATUS
  286. Initialize(
  287. BOOL fWriteLock
  288. );
  289. VOID
  290. Deinitialize(
  291. VOID
  292. );
  293. WBEMSTATUS
  294. GetNlbCompatibleNics(
  295. OUT LPWSTR **ppszNics,
  296. OUT UINT *pNumNics,
  297. OUT UINT *pNumBoundToNlb // OPTIONAL
  298. );
  299. WBEMSTATUS
  300. GetBindingIF(
  301. IN LPCWSTR szComponent,
  302. OUT INetCfgComponentBindings **ppIBinding
  303. );
  304. private:
  305. INetCfg *m_pINetCfg;
  306. INetCfgLock *m_pLock;
  307. }; // Class AppMyNetCfg
  308. WBEMSTATUS
  309. AppMyNetCfg::Initialize(
  310. BOOL fWriteLock
  311. )
  312. {
  313. HRESULT hr;
  314. INetCfg *pnc = NULL;
  315. INetCfgLock *pncl = NULL;
  316. WBEMSTATUS Status = WBEM_E_CRITICAL_ERROR;
  317. BOOL fLocked = FALSE;
  318. BOOL fInitialized=FALSE;
  319. if (m_pINetCfg != NULL || m_pLock != NULL)
  320. {
  321. ASSERT(FALSE);
  322. goto end;
  323. }
  324. hr = CoCreateInstance( CLSID_CNetCfg,
  325. NULL,
  326. CLSCTX_SERVER,
  327. IID_INetCfg,
  328. (void **) &pnc);
  329. if( !SUCCEEDED( hr ) )
  330. {
  331. // failure to create instance.
  332. //TRACE_CRIT("ERROR: could not get interface to Net Config");
  333. goto end;
  334. }
  335. //
  336. // If require, get the write lock
  337. //
  338. if (fWriteLock)
  339. {
  340. WCHAR *szLockedBy = NULL;
  341. hr = pnc->QueryInterface( IID_INetCfgLock, ( void **) &pncl );
  342. if( !SUCCEEDED( hr ) )
  343. {
  344. //TRACE_CRIT("ERROR: could not get interface to NetCfg Lock");
  345. goto end;
  346. }
  347. hr = pncl->AcquireWriteLock( 1, // One Second
  348. L"NLBManager",
  349. &szLockedBy);
  350. if( hr != S_OK )
  351. {
  352. //TRACE_CRIT("Could not get write lock. Lock held by %ws",
  353. // (szLockedBy!=NULL) ? szLockedBy : L"<null>");
  354. goto end;
  355. }
  356. }
  357. // Initializes network configuration by loading into
  358. // memory all basic networking information
  359. //
  360. hr = pnc->Initialize( NULL );
  361. if( !SUCCEEDED( hr ) )
  362. {
  363. // failure to Initialize
  364. //TRACE_CRIT("INetCfg::Initialize failure ");
  365. goto end;
  366. }
  367. Status = WBEM_NO_ERROR;
  368. end:
  369. if (FAILED(Status))
  370. {
  371. if (pncl!=NULL)
  372. {
  373. if (fLocked)
  374. {
  375. pncl->ReleaseWriteLock();
  376. }
  377. pncl->Release();
  378. pncl=NULL;
  379. }
  380. if( pnc != NULL)
  381. {
  382. if (fInitialized)
  383. {
  384. pnc->Uninitialize();
  385. }
  386. pnc->Release();
  387. pnc= NULL;
  388. }
  389. }
  390. else
  391. {
  392. m_pINetCfg = pnc;
  393. m_pLock = pncl;
  394. }
  395. return Status;
  396. }
  397. VOID
  398. AppMyNetCfg::Deinitialize(
  399. VOID
  400. )
  401. {
  402. if (m_pLock!=NULL)
  403. {
  404. m_pLock->ReleaseWriteLock();
  405. m_pLock->Release();
  406. m_pLock=NULL;
  407. }
  408. if( m_pINetCfg != NULL)
  409. {
  410. m_pINetCfg->Uninitialize();
  411. m_pINetCfg->Release();
  412. m_pINetCfg= NULL;
  413. }
  414. }
  415. WBEMSTATUS
  416. AppMyNetCfg::GetNlbCompatibleNics(
  417. OUT LPWSTR **ppszNics,
  418. OUT UINT *pNumNics,
  419. OUT UINT *pNumBoundToNlb // OPTIONAL
  420. )
  421. /*
  422. Returns an array of pointers to string-version of GUIDS
  423. that represent the set of alive and healthy NICS that are
  424. suitable for NLB to bind to -- basically alive ethernet NICs.
  425. Delete ppNics using the delete WCHAR[] operator. Do not
  426. delete the individual strings.
  427. */
  428. {
  429. #define MY_GUID_LENGTH 38
  430. WBEMSTATUS Status = WBEM_E_CRITICAL_ERROR;
  431. HRESULT hr;
  432. IEnumNetCfgComponent* pencc = NULL;
  433. INetCfgComponent *pncc = NULL;
  434. ULONG countToFetch = 1;
  435. ULONG countFetched;
  436. UINT NumNics = 0;
  437. LPWSTR *pszNics = NULL;
  438. INetCfgComponentBindings *pINlbBinding=NULL;
  439. UINT NumNlbBoundNics = 0;
  440. typedef struct _MYNICNODE MYNICNODE;
  441. typedef struct _MYNICNODE
  442. {
  443. LPWSTR szNicGuid;
  444. MYNICNODE *pNext;
  445. } MYNICNODE;
  446. MYNICNODE *pNicNodeList = NULL;
  447. MYNICNODE *pNicNode = NULL;
  448. *ppszNics = NULL;
  449. *pNumNics = 0;
  450. if (pNumBoundToNlb != NULL)
  451. {
  452. *pNumBoundToNlb = 0;
  453. }
  454. if (m_pINetCfg == NULL)
  455. {
  456. //
  457. // This means we're not initialized
  458. //
  459. ASSERT(FALSE);
  460. goto end;
  461. }
  462. hr = m_pINetCfg->EnumComponents( &GUID_DEVCLASS_NET, &pencc );
  463. if( !SUCCEEDED( hr ) )
  464. {
  465. // failure to Enumerate net components
  466. //TRACE_CRIT("%!FUNC! Could not enum netcfg adapters");
  467. pencc = NULL;
  468. goto end;
  469. }
  470. //
  471. // Check if nlb is bound to the nlb component.
  472. //
  473. //
  474. // If we need to count of NLB-bound nics, get instance of the nlb component
  475. //
  476. if (pNumBoundToNlb != NULL)
  477. {
  478. Status = GetBindingIF(L"ms_wlbs", &pINlbBinding);
  479. if (FAILED(Status))
  480. {
  481. //TRACE_CRIT("%!FUNC! WARNING: NLB doesn't appear to be installed on this machine");
  482. pINlbBinding = NULL;
  483. }
  484. }
  485. while( ( hr = pencc->Next( countToFetch, &pncc, &countFetched ) )== S_OK )
  486. {
  487. LPWSTR szName = NULL;
  488. hr = pncc->GetBindName( &szName );
  489. if (!SUCCEEDED(hr))
  490. {
  491. //TRACE_CRIT("%!FUNC! WARNING: couldn't get bind name for 0x%p, ignoring",
  492. // (PVOID) pncc);
  493. continue;
  494. }
  495. do // while FALSE -- just to allow breaking out
  496. {
  497. UINT Len = wcslen(szName);
  498. if (Len != MY_GUID_LENGTH)
  499. {
  500. //TRACE_CRIT("%!FUNC! WARNING: GUID %ws has unexpected length %ul",
  501. // szName, Len);
  502. break;
  503. }
  504. DWORD characteristics = 0;
  505. hr = pncc->GetCharacteristics( &characteristics );
  506. if(!SUCCEEDED(hr))
  507. {
  508. //TRACE_CRIT("%!FUNC! WARNING: couldn't get characteristics for %ws, ignoring",
  509. // szName);
  510. break;
  511. }
  512. if (((characteristics & NCF_PHYSICAL) || (characteristics & NCF_VIRTUAL)) && !(characteristics & NCF_HIDDEN))
  513. {
  514. ULONG devstat = 0;
  515. // This is a physical or virtual miniport that is NOT hidden. These
  516. // are the same adapters that show up in the "Network Connections"
  517. // dialog. Hidden devices include WAN miniports, RAS miniports and
  518. // NLB miniports - all of which should be excluded here.
  519. // check if the nic is enabled, we are only
  520. // interested in enabled nics.
  521. //
  522. hr = pncc->GetDeviceStatus( &devstat );
  523. if(!SUCCEEDED(hr))
  524. {
  525. //TRACE_CRIT(
  526. // "%!FUNC! WARNING: couldn't get dev status for %ws, ignoring",
  527. // szName
  528. // );
  529. break;
  530. }
  531. // if any of the nics has any of the problem codes
  532. // then it cannot be used.
  533. if( devstat != CM_PROB_NOT_CONFIGURED
  534. &&
  535. devstat != CM_PROB_FAILED_START
  536. &&
  537. devstat != CM_PROB_NORMAL_CONFLICT
  538. &&
  539. devstat != CM_PROB_NEED_RESTART
  540. &&
  541. devstat != CM_PROB_REINSTALL
  542. &&
  543. devstat != CM_PROB_WILL_BE_REMOVED
  544. &&
  545. devstat != CM_PROB_DISABLED
  546. &&
  547. devstat != CM_PROB_FAILED_INSTALL
  548. &&
  549. devstat != CM_PROB_FAILED_ADD
  550. )
  551. {
  552. //
  553. // No problem with this nic and also
  554. // physical device
  555. // thus we want it.
  556. //
  557. if (pINlbBinding != NULL)
  558. {
  559. BOOL fBound = FALSE;
  560. hr = pINlbBinding->IsBoundTo(pncc);
  561. if( !SUCCEEDED( hr ) )
  562. {
  563. //TRACE_CRIT("IsBoundTo method failed for Nic %ws", szName);
  564. goto end;
  565. }
  566. if( hr == S_OK )
  567. {
  568. //TRACE_VERB("BOUND: %ws\n", szName);
  569. NumNlbBoundNics++;
  570. fBound = TRUE;
  571. }
  572. else if (hr == S_FALSE )
  573. {
  574. //TRACE_VERB("NOT BOUND: %ws\n", szName);
  575. fBound = FALSE;
  576. }
  577. }
  578. // We allocate a little node to keep this string
  579. // temporarily and add it to our list of nodes.
  580. //
  581. pNicNode = new MYNICNODE;
  582. if (pNicNode == NULL)
  583. {
  584. Status = WBEM_E_OUT_OF_MEMORY;
  585. goto end;
  586. }
  587. ZeroMemory(pNicNode, sizeof(*pNicNode));
  588. pNicNode->szNicGuid = szName;
  589. szName = NULL; // so we don't delete inside the lopp.
  590. pNicNode->pNext = pNicNodeList;
  591. pNicNodeList = pNicNode;
  592. NumNics++;
  593. }
  594. else
  595. {
  596. // There is a problem...
  597. //TRACE_CRIT(
  598. // "%!FUNC! WARNING: Skipping %ws because DeviceStatus=0x%08lx",
  599. // szName, devstat
  600. // );
  601. break;
  602. }
  603. }
  604. else
  605. {
  606. //TRACE_VERB("%!FUNC! Ignoring non-physical device %ws", szName);
  607. }
  608. } while (FALSE);
  609. if (szName != NULL)
  610. {
  611. CoTaskMemFree( szName );
  612. }
  613. pncc->Release();
  614. pncc=NULL;
  615. }
  616. if (pINlbBinding!=NULL)
  617. {
  618. pINlbBinding->Release();
  619. pINlbBinding = NULL;
  620. }
  621. if (NumNics==0)
  622. {
  623. Status = WBEM_NO_ERROR;
  624. goto end;
  625. }
  626. //
  627. // Now let's allocate space for all the nic strings and:w
  628. // copy them over..
  629. //
  630. #define MY_GUID_LENGTH 38
  631. pszNics = CfgUtilsAllocateStringArray(NumNics, MY_GUID_LENGTH);
  632. if (pszNics == NULL)
  633. {
  634. Status = WBEM_E_OUT_OF_MEMORY;
  635. goto end;
  636. }
  637. pNicNode= pNicNodeList;
  638. for (UINT u=0; u<NumNics; u++, pNicNode=pNicNode->pNext)
  639. {
  640. ASSERT(pNicNode != NULL); // because we just counted NumNics of em.
  641. UINT Len = wcslen(pNicNode->szNicGuid);
  642. if (Len != MY_GUID_LENGTH)
  643. {
  644. //
  645. // We should never get here beause we checked the length earlier.
  646. //
  647. //TRACE_CRIT("%!FUNC! ERROR: GUID %ws has unexpected length %ul",
  648. // pNicNode->szNicGuid, Len);
  649. ASSERT(FALSE);
  650. Status = WBEM_E_CRITICAL_ERROR;
  651. goto end;
  652. }
  653. CopyMemory(
  654. pszNics[u],
  655. pNicNode->szNicGuid,
  656. (MY_GUID_LENGTH+1)*sizeof(WCHAR));
  657. ASSERT(pszNics[u][MY_GUID_LENGTH]==0);
  658. }
  659. Status = WBEM_NO_ERROR;
  660. end:
  661. //
  662. // Now release the temporarly allocated memory.
  663. //
  664. pNicNode= pNicNodeList;
  665. while (pNicNode!=NULL)
  666. {
  667. MYNICNODE *pTmp = pNicNode->pNext;
  668. CoTaskMemFree(pNicNode->szNicGuid);
  669. pNicNode->szNicGuid = NULL;
  670. delete pNicNode;
  671. pNicNode = pTmp;
  672. }
  673. if (FAILED(Status))
  674. {
  675. // TRACE_CRIT("%!FUNC! fails with status 0x%08lx", (UINT) Status);
  676. NumNics = 0;
  677. if (pszNics!=NULL)
  678. {
  679. delete pszNics;
  680. pszNics = NULL;
  681. }
  682. }
  683. else
  684. {
  685. if (pNumBoundToNlb != NULL)
  686. {
  687. *pNumBoundToNlb = NumNlbBoundNics;
  688. }
  689. *ppszNics = pszNics;
  690. *pNumNics = NumNics;
  691. }
  692. if (pencc != NULL)
  693. {
  694. pencc->Release();
  695. }
  696. return Status;
  697. }
  698. WBEMSTATUS
  699. AppMyNetCfg::GetBindingIF(
  700. IN LPCWSTR szComponent,
  701. OUT INetCfgComponentBindings **ppIBinding
  702. )
  703. {
  704. WBEMSTATUS Status = WBEM_E_CRITICAL_ERROR;
  705. INetCfgComponent *pncc = NULL;
  706. INetCfgComponentBindings *pnccb = NULL;
  707. HRESULT hr;
  708. if (m_pINetCfg == NULL)
  709. {
  710. //
  711. // This means we're not initialized
  712. //
  713. ASSERT(FALSE);
  714. goto end;
  715. }
  716. hr = m_pINetCfg->FindComponent(szComponent, &pncc);
  717. if (FAILED(hr))
  718. {
  719. // TRACE_CRIT("Error checking if component %ws does not exist\n", szComponent);
  720. pncc = NULL;
  721. goto end;
  722. }
  723. else if (hr == S_FALSE)
  724. {
  725. Status = WBEM_E_NOT_FOUND;
  726. // TRACE_CRIT("Component %ws does not exist\n", szComponent);
  727. goto end;
  728. }
  729. hr = pncc->QueryInterface( IID_INetCfgComponentBindings, (void **) &pnccb );
  730. if( !SUCCEEDED( hr ) )
  731. {
  732. // TRACE_CRIT("INetCfgComponent::QueryInterface failed ");
  733. pnccb = NULL;
  734. goto end;
  735. }
  736. Status = WBEM_NO_ERROR;
  737. end:
  738. if (pncc)
  739. {
  740. pncc->Release();
  741. pncc=NULL;
  742. }
  743. *ppIBinding = pnccb;
  744. return Status;
  745. }
  746. BOOL NoAdminNics(void)
  747. /*
  748. Return TRUE IFF all NICs on this machine are bound to NLB.
  749. */
  750. {
  751. LPWSTR *pszNics = NULL;
  752. OUT UINT NumNics = 0;
  753. OUT UINT NumBoundToNlb = 0;
  754. WBEMSTATUS Status = WBEM_NO_ERROR;
  755. BOOL fNetCfgInitialized = FALSE;
  756. AppMyNetCfg NetCfg;
  757. BOOL fRet = FALSE;
  758. //
  759. // Get and initialize interface to netcfg
  760. //
  761. Status = NetCfg.Initialize(FALSE); // TRUE == get write lock.
  762. if (FAILED(Status))
  763. {
  764. goto end;
  765. }
  766. fNetCfgInitialized = TRUE;
  767. //
  768. // Get the total list of enabled nics and the list of nics
  769. // bound to NLB. If there are non-zero enabled nics and all are
  770. // bound to NLB, we return TRUE.
  771. //
  772. Status = NetCfg.GetNlbCompatibleNics(
  773. &pszNics,
  774. &NumNics,
  775. &NumBoundToNlb
  776. );
  777. if (!FAILED(Status))
  778. {
  779. fRet = NumNics && (NumNics == NumBoundToNlb);
  780. if (NumNics)
  781. {
  782. delete pszNics;
  783. pszNics = NULL;
  784. }
  785. }
  786. end:
  787. if (fNetCfgInitialized)
  788. {
  789. NetCfg.Deinitialize();
  790. }
  791. return fRet;
  792. }
  793. void
  794. Application::ProcessMsgQueue()
  795. {
  796. MSG msg;
  797. BOOL bDoingBackgroundProcessing = FALSE;
  798. TRACE_INFO(L"-> %!FUNC!");
  799. if (!mfn_IsMainThread()) goto end;
  800. if (InterlockedIncrement(&m_lMsgProcReentrancyCount) > 1)
  801. {
  802. InterlockedDecrement(&m_lMsgProcReentrancyCount);
  803. goto end;
  804. }
  805. while ( ::PeekMessage( &msg, NULL, 0, 0, PM_NOREMOVE ) )
  806. {
  807. #if BUGFIX334243
  808. if (msg.message == MYWM_DEFER_UI_MSG)
  809. {
  810. // DummyAction(L"Hey -- got DEFER_UI_MSG ProcessMsgQueue!");
  811. }
  812. #endif // BUGFIX334243
  813. if ( !this->PumpMessage( ) )
  814. {
  815. bDoingBackgroundProcessing = FALSE;
  816. ::PostQuitMessage(0);
  817. break;
  818. }
  819. }
  820. // let MFC do its idle processing
  821. LONG lIdle = 0;
  822. while ( this->OnIdle(lIdle++ ) )
  823. {
  824. }
  825. // Perform some background processing here
  826. // using another call to OnIdle
  827. this->DoWaitCursor(0); // process_msgqueue() breaks the hour glass cursor, This call restores the hour glass cursor if there was one
  828. InterlockedDecrement(&m_lMsgProcReentrancyCount);
  829. if (m_fQuit)
  830. {
  831. ::PostQuitMessage(0);
  832. }
  833. end:
  834. TRACE_INFO(L"<- %!FUNC!");
  835. return;
  836. }
  837. //
  838. // Get application-wide lock. If main thread, while waiting to get the lock,
  839. // periodically process the msg loop.
  840. //
  841. VOID
  842. Application::Lock()
  843. {
  844. //
  845. // See notes.txt entry
  846. // 01/23/2002 JosephJ DEADLOCK in Leftview::mfn_Lock
  847. // for the reason for this convoluted implementation of mfn_Lock
  848. //
  849. if (mfn_IsMainThread())
  850. {
  851. EnterCriticalSection(&m_crit);
  852. }
  853. else
  854. {
  855. while (!TryEnterCriticalSection(&m_crit))
  856. {
  857. this->ProcessMsgQueue();
  858. Sleep(100);
  859. }
  860. }
  861. }
  862. //
  863. // Get application-wide unlock
  864. //
  865. VOID
  866. Application::Unlock()
  867. {
  868. LeaveCriticalSection(&m_crit);
  869. }