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.

2110 lines
55 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1992-2001.
  5. //
  6. // File: N O T I F Y . C P P
  7. //
  8. // Contents: Sample notify object code
  9. //
  10. // Notes:
  11. //
  12. // Author: Alok Sinha
  13. //----------------------------------------------------------------------------
  14. #include "notify.h"
  15. HRESULT HrCopyMiniportInf (VOID);
  16. //----------------------------------------------------------------------------
  17. //
  18. // Function: CMuxNotify::CMuxNotify
  19. //
  20. // Purpose: Constructor for CMuxNotify
  21. //
  22. // Arguments: None
  23. //
  24. // Returns: None
  25. //
  26. // Notes:
  27. //
  28. CMuxNotify::CMuxNotify (VOID) : m_pncc (NULL),
  29. m_pnc(NULL),
  30. m_eApplyAction(eActUnknown),
  31. m_pUnkContext(NULL)
  32. {
  33. TraceMsg( L"-->CMuxNotify::CMuxNotify(Constructor).\n" );
  34. TraceMsg( L"<--CMuxNotify::CMuxNotify(Constructor).\n" );
  35. }
  36. // ----------------------------------------------------------------------
  37. //
  38. // Function: CMuxNotify::~CMuxNotify
  39. //
  40. // Purpose: Destructor for class CMuxNotify
  41. //
  42. // Arguments: None
  43. //
  44. // Returns: None
  45. //
  46. // Notes:
  47. //
  48. CMuxNotify::~CMuxNotify (VOID)
  49. {
  50. CMuxPhysicalAdapter *pAdapter;
  51. DWORD dwAdapterCount;
  52. DWORD i;
  53. TraceMsg( L"-->CMuxNotify::~CMuxNotify(Destructor).\n" );
  54. // release interfaces if acquired
  55. ReleaseObj( m_pncc );
  56. ReleaseObj( m_pnc );
  57. ReleaseObj( m_pUnkContext );
  58. dwAdapterCount = m_AdaptersList.ListCount();
  59. for (i=0; i < dwAdapterCount; ++i) {
  60. m_AdaptersList.Remove( &pAdapter );
  61. delete pAdapter;
  62. }
  63. dwAdapterCount = m_AdaptersToRemove.ListCount();
  64. for (i=0; i < dwAdapterCount; ++i) {
  65. m_AdaptersToRemove.Remove( &pAdapter );
  66. delete pAdapter;
  67. }
  68. dwAdapterCount = m_AdaptersToAdd.ListCount();
  69. for (i=0; i < dwAdapterCount; ++i) {
  70. m_AdaptersToAdd.Remove( &pAdapter );
  71. delete pAdapter;
  72. }
  73. TraceMsg( L"<--CMuxNotify::~CMuxNotify(Destructor).\n" );
  74. }
  75. //
  76. //---------------------- NOTIFY OBJECT FUNCTIONS -----------------------------
  77. //
  78. //----------------------------------------------------------------------------
  79. // INetCfgComponentControl
  80. //
  81. // The following functions provide the INetCfgComponentControl interface.
  82. //
  83. //----------------------------------------------------------------------------
  84. //
  85. // Function: CMuxNotify::Initialize
  86. //
  87. // Purpose: Initialize the notify object
  88. //
  89. // Arguments:
  90. // IN pnccItem : Pointer to INetCfgComponent object
  91. // IN pnc : Pointer to INetCfg object
  92. // IN fInstalling: TRUE if we are being installed
  93. //
  94. // Returns:
  95. //
  96. // Notes:
  97. //
  98. STDMETHODIMP CMuxNotify::Initialize (INetCfgComponent* pncc,
  99. INetCfg* pnc,
  100. BOOL fInstalling)
  101. {
  102. HRESULT hr = S_OK;
  103. TraceMsg( L"-->CMuxNotify INetCfgControl::Initialize.\n" );
  104. // Save INetCfg & INetCfgComponent and add a refcount
  105. m_pncc = pncc;
  106. m_pnc = pnc;
  107. if (m_pncc) {
  108. m_pncc->AddRef();
  109. }
  110. if (m_pnc) {
  111. m_pnc->AddRef();
  112. }
  113. //
  114. // If this not an installation, then we need to
  115. // initialize all of our data and classes
  116. //
  117. if ( !fInstalling ) {
  118. hr = HrLoadAdapterConfiguration();
  119. }else {
  120. OSVERSIONINFO osvi;
  121. ZeroMemory( &osvi,
  122. sizeof(OSVERSIONINFO) );
  123. osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
  124. if ( GetVersionEx(&osvi) )
  125. {
  126. if ( (osvi.dwPlatformId == VER_PLATFORM_WIN32_NT) &&
  127. (osvi.dwMajorVersion == 5) &&
  128. (osvi.dwMinorVersion == 0) )
  129. {
  130. // On Windows 2000, copy the miniport inf file to %windir%\inf.
  131. TraceMsg(L" Copying miniport inf to system inf directory...\n");
  132. HrCopyMiniportInf();
  133. }
  134. else
  135. {
  136. TraceMsg(L" Skipping copying miniport inf to system inf directory...\n");
  137. }
  138. }
  139. }
  140. TraceMsg( L"<--CMuxNotify INetCfgControl::Initialize(HRESULT = %x).\n",
  141. hr );
  142. return hr;
  143. }
  144. // ----------------------------------------------------------------------
  145. //
  146. // Function: CMuxNotify::CancelChanges
  147. //
  148. // Purpose: Cancel any changes made to internal data
  149. //
  150. // Arguments: None
  151. //
  152. // Returns: S_OK on success, otherwise an error code
  153. //
  154. // Notes:
  155. //
  156. STDMETHODIMP CMuxNotify::CancelChanges (VOID)
  157. {
  158. TraceMsg( L"-->CMuxNotify INetCfgControl::CancelChanges.\n" );
  159. TraceMsg( L"<--CMuxNotify INetCfgControl::CancelChanges(HRESULT = %x).\n",
  160. S_OK );
  161. return S_OK;
  162. }
  163. // ----------------------------------------------------------------------
  164. //
  165. // Function: CMuxNotify::ApplyRegistryChanges
  166. //
  167. // Purpose: Apply changes.
  168. //
  169. // Arguments: None
  170. //
  171. // Returns: S_OK.
  172. //
  173. // Notes: We can make changes to registry etc. here.
  174. STDMETHODIMP CMuxNotify::ApplyRegistryChanges(VOID)
  175. {
  176. CMuxPhysicalAdapter *pAdapter = NULL;
  177. GUID guidAdapter;
  178. DWORD dwAdapterCount;
  179. DWORD i;
  180. TraceMsg( L"-->CMuxNotify INetCfgControl::ApplyRegistryChanges.\n" );
  181. //
  182. // Make registry changes for the adapters added.
  183. //
  184. dwAdapterCount = m_AdaptersToAdd.ListCount();
  185. TraceMsg( L" Adding %d new adapters.\n",
  186. dwAdapterCount );
  187. for (i=0; i < dwAdapterCount; ++i) {
  188. m_AdaptersToAdd.Find( i,
  189. &pAdapter );
  190. pAdapter->ApplyRegistryChanges( eActAdd );
  191. }
  192. //
  193. // Make registry changes for the adapters uninstalled.
  194. //
  195. dwAdapterCount = m_AdaptersToRemove.ListCount();
  196. TraceMsg( L" Removing %d adapters.\n",
  197. dwAdapterCount );
  198. for (i=0; i < dwAdapterCount; ++i) {
  199. m_AdaptersToRemove.Find( i,
  200. &pAdapter );
  201. pAdapter->ApplyRegistryChanges( eActRemove );
  202. }
  203. //
  204. // Make registry changes for the miniports added/removed
  205. // through the property pages.
  206. //
  207. dwAdapterCount = m_AdaptersList.ListCount();
  208. for (i=0; i < dwAdapterCount; ++i) {
  209. m_AdaptersList.Find( i,
  210. &pAdapter );
  211. pAdapter->ApplyRegistryChanges( eActUpdate );
  212. }
  213. TraceMsg( L"<--CMuxNotify INetCfgControl::ApplyRegistryChanges(HRESULT = %x).\n",
  214. S_OK );
  215. return S_OK;
  216. }
  217. // ----------------------------------------------------------------------
  218. //
  219. // Function: CMuxNotify::ApplyPnpChanges
  220. //
  221. // Purpose: Apply changes.
  222. //
  223. // Arguments:
  224. // IN pfCallback: PnPConfigCallback interface.
  225. //
  226. // Returns: S_OK.
  227. //
  228. // Notes:
  229. STDMETHODIMP CMuxNotify::ApplyPnpChanges (
  230. INetCfgPnpReconfigCallback* pfCallback)
  231. {
  232. CMuxPhysicalAdapter *pAdapter = NULL;
  233. GUID guidAdapter;
  234. DWORD dwAdapterCount;
  235. DWORD i;
  236. TraceMsg( L"-->CMuxNotify INetCfgControl::ApplyPnpChanges.\n" );
  237. //
  238. // Apply PnP changes for the adapters added.
  239. //
  240. dwAdapterCount = m_AdaptersToAdd.ListCount();
  241. TraceMsg( L" Applying PnP changes when %d adapters added.\n",
  242. dwAdapterCount );
  243. for (i=0; i < dwAdapterCount; ++i) {
  244. m_AdaptersToAdd.Remove( &pAdapter );
  245. pAdapter->ApplyPnpChanges( pfCallback,
  246. eActAdd );
  247. pAdapter->GetAdapterGUID( &guidAdapter );
  248. m_AdaptersList.Insert( pAdapter,
  249. guidAdapter );
  250. }
  251. //
  252. // Apply PnP changes for the adapters uninstalled.
  253. //
  254. dwAdapterCount = m_AdaptersToRemove.ListCount();
  255. TraceMsg( L" Applying PnP changes when %d adapters removed.\n",
  256. dwAdapterCount );
  257. for (i=0; i < dwAdapterCount; ++i) {
  258. m_AdaptersToRemove.Remove( &pAdapter );
  259. pAdapter->ApplyPnpChanges( pfCallback,
  260. eActRemove );
  261. delete pAdapter;
  262. }
  263. //
  264. // Apply PnP changes for the miniports added/removed through
  265. // the property pages.
  266. //
  267. dwAdapterCount = m_AdaptersList.ListCount();
  268. for (i=0; i < dwAdapterCount; ++i) {
  269. m_AdaptersList.Find( i,
  270. &pAdapter );
  271. pAdapter->ApplyPnpChanges( pfCallback,
  272. eActUpdate );
  273. }
  274. TraceMsg( L"<--CMuxNotify INetCfgControl::ApplyPnpChanges(HRESULT = %x).\n",
  275. S_OK );
  276. return S_OK;
  277. }
  278. //----------------------------------------------------------------------------
  279. // INetCfgComponentSetup
  280. //
  281. // The following functions provide the INetCfgComponentSetup interface.
  282. //
  283. //----------------------------------------------------------------------------
  284. // ----------------------------------------------------------------------
  285. //
  286. // Function: CMuxNotify::Install
  287. //
  288. // Purpose: Do operations necessary during the installation.
  289. //
  290. // Arguments:
  291. // IN dwSetupFlags: Setup flags
  292. //
  293. // Returns: S_OK
  294. //
  295. // Notes: Don't do anything irreversible (like modifying registry) yet
  296. // since the config. actually completes only when Apply is called!
  297. //
  298. STDMETHODIMP CMuxNotify::Install (DWORD dwSetupFlags)
  299. {
  300. TraceMsg( L"-->CMuxNotify INetCfgSetup::Install.\n" );
  301. // Start up the install process
  302. m_eApplyAction = eActInstall;
  303. TraceMsg( L"<--CMuxNotify INetCfgSetup::Install(HRESULT = %x).\n",
  304. S_OK );
  305. return S_OK;
  306. }
  307. // ----------------------------------------------------------------------
  308. //
  309. // Function: CMuxNotify::Upgrade
  310. //
  311. // Purpose: Do operations necessary during the upgrade.
  312. //
  313. // Arguments:
  314. // IN dwSetupFlags: Setup flags
  315. //
  316. // Returns: S_OK
  317. //
  318. // Notes: Don't do anything irreversible (like modifying registry) yet
  319. // since the config. actually completes only when Apply is called!
  320. //
  321. STDMETHODIMP CMuxNotify::Upgrade (IN DWORD dwSetupFlags,
  322. IN DWORD dwUpgradeFromBuildNo)
  323. {
  324. TraceMsg( L"-->CMuxNotify INetCfgSetup::Upgrade.\n" );
  325. TraceMsg( L" DwSetupFlags = %x, dwUpgradeFromBuildNo = %x\n",
  326. dwSetupFlags,
  327. dwUpgradeFromBuildNo );
  328. TraceMsg( L"<--CMuxNotify INetCfgSetup::Upgrade(HRESULT = %x).\n",
  329. S_OK );
  330. return S_OK;
  331. }
  332. // ----------------------------------------------------------------------
  333. //
  334. // Function: CMuxNotify::ReadAnswerFile
  335. //
  336. // Purpose: Read settings from answerfile and configure CMuxNotify
  337. //
  338. // Arguments:
  339. // IN pszAnswerFile : Name of AnswerFile
  340. // IN pszAnswerSection: Name of parameters section
  341. //
  342. // Returns:
  343. //
  344. // Notes: Don't do anything irreversible (like modifying registry) yet
  345. // since the config. actually completes only when Apply is called!
  346. //
  347. STDMETHODIMP CMuxNotify::ReadAnswerFile (PCWSTR pszAnswerFile,
  348. PCWSTR pszAnswerSection)
  349. {
  350. PCWSTR pszParamReadFromAnswerFile = L"ParamFromAnswerFile";
  351. TraceMsg( L"-->CMuxNotify INetCfgSetup::ReadAnswerFile.\n" );
  352. // We will pretend here that szParamReadFromAnswerFile was actually
  353. // read from the AnswerFile using the following steps
  354. //
  355. // - Open file pszAnswerFile using SetupAPI
  356. // - locate section pszAnswerSection
  357. // - locate the required key and get its value
  358. // - store its value in pszParamReadFromAnswerFile
  359. // - close HINF for pszAnswerFile
  360. // Now that we have read pszParamReadFromAnswerFile from the
  361. // AnswerFile, store it in our memory structure.
  362. // Remember we should not be writing it to the registry till
  363. // our Apply is called!!
  364. //
  365. TraceMsg( L"<--CMuxNotify INetCfgSetup::ReadAnswerFile(HRESULT = %x).\n",
  366. S_OK );
  367. return S_OK;
  368. }
  369. // ----------------------------------------------------------------------
  370. //
  371. // Function: CMuxNotify::Removing
  372. //
  373. // Purpose: Do necessary cleanup when being removed
  374. //
  375. // Arguments: None
  376. //
  377. // Returns: S_OK
  378. //
  379. // Notes: Don't do anything irreversible (like modifying registry) yet
  380. // since the removal is actually complete only when Apply is called!
  381. //
  382. STDMETHODIMP CMuxNotify::Removing (VOID)
  383. {
  384. TraceMsg( L"-->CMuxNotify INetCfgSetup::Removing.\n" );
  385. TraceMsg( L"<--CMuxNotify INetCfgSetup::Removing(HRESULT = %x).\n",
  386. S_OK );
  387. return S_OK;
  388. }
  389. //----------------------------------------------------------------------------
  390. // INetCfgComponentNotifyBinding
  391. //
  392. // The following functions provide the INetCfgComponentNotifyBinding interface.
  393. //
  394. //----------------------------------------------------------------------------
  395. //----------------------------------------------------------------------------
  396. //
  397. // Function: CMuxNotify::QueryBindingPath
  398. //
  399. // Purpose: This is specific to the component being installed. This will
  400. // ask us if we want to bind to the Item being passed into
  401. // this routine. We can disable the binding by returning
  402. // NETCFG_S_DISABLE_QUERY
  403. //
  404. //
  405. // Arguments:
  406. // IN dwChangeFlag: Type of binding change
  407. // IN pncbpItem : Pointer to INetCfgBindingPath object
  408. //
  409. // Returns: S_OK on success, otherwise an error code.
  410. //
  411. // Notes:
  412. //
  413. STDMETHODIMP CMuxNotify::QueryBindingPath (IN DWORD dwChangeFlag,
  414. IN INetCfgBindingPath *pncbp)
  415. {
  416. TraceMsg( L"-->CMuxNotify INetCfgNotifyBinding::QueryBindingPath.\n" );
  417. DumpChangeFlag( dwChangeFlag );
  418. DumpBindingPath( pncbp );
  419. TraceMsg( L"<--CMuxNotify INetCfgNotifyBinding::QueryBindingPath(HRESULT = %x).\n",
  420. S_OK );
  421. return S_OK;
  422. }
  423. // ----------------------------------------------------------------------
  424. //
  425. // Function: CMuxNotify::NotifyBindingPath
  426. //
  427. // Purpose: We are now being told to bind to the component passed to us.
  428. //
  429. //
  430. // Arguments:
  431. // IN dwChangeFlag: Type of system change
  432. // IN pncc : Pointer to INetCfgComponent object
  433. //
  434. // Returns: S_OK on success, otherwise an error code
  435. //
  436. // Notes:
  437. //
  438. STDMETHODIMP CMuxNotify::NotifyBindingPath (IN DWORD dwChangeFlag,
  439. IN INetCfgBindingPath *pncbp)
  440. {
  441. INetCfgComponent *pnccLower;
  442. INetCfgComponent *pnccUpper;
  443. LPWSTR pszwInfIdLower;
  444. LPWSTR pszwInfIdUpper;
  445. DWORD dwCharcteristics;
  446. HRESULT hr = S_OK;
  447. TraceMsg( L"-->CMuxNotify INetCfgNotifyBinding::NotifyBindingPath.\n" );
  448. DumpChangeFlag( dwChangeFlag );
  449. DumpBindingPath( pncbp );
  450. //
  451. // We are only interested to know 1) when a component is installed
  452. // and we are binding to it i.e. dwChangeFlag = NCN_ADD | NCN_ENABLE
  453. // and 2) when a component is removed to which we are bound i.e.
  454. // dwChangeFlag = NCN_REMOVE | NCN_ENABLE. dwChangeFlag is never
  455. // set to NCN_ADD or NCN_REMOVE only. So, checking for NCN_ENABLE
  456. // covers the case of NCN_ADD | NCN_ENABLE and checking for NCN_REMOVE
  457. // covers the case of NCN_REMOVE | NCN_ENABLE. We don't care about
  458. // NCN_ADD | NCN_DISABLE (case 1) and NCN_REMOVE | NCN_DISABLE (case 2).
  459. //
  460. if ( dwChangeFlag & (NCN_ENABLE | NCN_REMOVE) ) {
  461. //
  462. // Get the upper and lower components.
  463. //
  464. hr = HrGetUpperAndLower( pncbp,
  465. &pnccUpper,
  466. &pnccLower );
  467. if ( hr == S_OK ) {
  468. hr = pnccLower->GetCharacteristics( &dwCharcteristics );
  469. if ( hr == S_OK ) {
  470. hr = pnccLower->GetId( &pszwInfIdLower );
  471. if ( hr == S_OK ) {
  472. hr = pnccUpper->GetId( &pszwInfIdUpper );
  473. if ( hr == S_OK ) {
  474. //
  475. // We are interested only in binding to a
  476. // physical ethernet adapters.
  477. //
  478. if ( dwCharcteristics & NCF_PHYSICAL ) {
  479. if ( !_wcsicmp( pszwInfIdUpper, c_szMuxProtocol ) ) {
  480. if ( dwChangeFlag & NCN_ADD ) {
  481. hr = HrAddAdapter( pnccLower );
  482. m_eApplyAction = eActAdd;
  483. } else if ( dwChangeFlag & NCN_REMOVE ) {
  484. hr = HrRemoveAdapter( pnccLower );
  485. m_eApplyAction = eActRemove;
  486. }
  487. }
  488. } // Physical Adapters.
  489. else if (dwCharcteristics & NCF_VIRTUAL) {
  490. }
  491. CoTaskMemFree( pszwInfIdUpper );
  492. } // Got the upper component id.
  493. CoTaskMemFree( pszwInfIdLower );
  494. } // Got the lower component id.
  495. } // Got NIC's characteristics
  496. ReleaseObj(pnccLower);
  497. ReleaseObj(pnccUpper);
  498. } // Got the upper and lower components.
  499. }
  500. TraceMsg( L"<--CMuxNotify INetCfgNotifyBinding::NotifyBindingPath(HRESULT = %x).\n",
  501. S_OK );
  502. return S_OK;
  503. }
  504. //----------------------------------------------------------------------------
  505. // INetCfgComponentNotifyGlobal
  506. //
  507. // The following functions provide the INetCfgComponentNotifyGlobal interface.
  508. //
  509. //----------------------------------------------------------------------------
  510. // ----------------------------------------------------------------------
  511. //
  512. // Function: CMuxNotify::GetSupportedNotifications
  513. //
  514. // Purpose: Tell the system which notifications we are interested in
  515. //
  516. // Arguments:
  517. // OUT pdwNotificationFlag: Pointer to NotificationFlag
  518. //
  519. // Returns: S_OK on success, otherwise an error code
  520. //
  521. // Notes:
  522. //
  523. STDMETHODIMP CMuxNotify::GetSupportedNotifications (
  524. OUT DWORD* pdwNotificationFlag)
  525. {
  526. TraceMsg( L"-->CMuxNotify INetCfgNotifyGlobal::GetSupportedNotifications.\n" );
  527. *pdwNotificationFlag = NCN_NET | NCN_NETTRANS | NCN_ADD | NCN_REMOVE |
  528. NCN_BINDING_PATH | NCN_ENABLE | NCN_DISABLE;
  529. TraceMsg( L"<--CMuxNotify INetCfgNotifyGlobal::GetSupportedNotifications(HRESULT = %x).\n",
  530. S_OK );
  531. return S_OK;
  532. }
  533. // ----------------------------------------------------------------------
  534. //
  535. // Function: CMuxNotify::SysQueryBindingPath
  536. //
  537. // Purpose: Enable or Disable a binding path.
  538. //
  539. // Arguments:
  540. // IN dwChangeFlag: Type of binding change
  541. // IN pncbp : Pointer to INetCfgBindingPath object
  542. //
  543. // Returns: S_OK on success, otherwise an error code
  544. //
  545. // Notes:
  546. //
  547. STDMETHODIMP CMuxNotify::SysQueryBindingPath (DWORD dwChangeFlag,
  548. INetCfgBindingPath* pncbp)
  549. {
  550. INetCfgComponent *pnccLower;
  551. INetCfgComponent *pnccUpper;
  552. LPWSTR pszwInfIdLower;
  553. LPWSTR pszwInfIdUpper;
  554. DWORD dwCharcteristics;
  555. HRESULT hr = S_OK;
  556. TraceMsg( L"-->CMuxNotify INetCfgNotifyGlobal::SysQueryBindingPath.\n" );
  557. DumpChangeFlag( dwChangeFlag );
  558. DumpBindingPath( pncbp );
  559. if ( dwChangeFlag & NCN_ENABLE ) {
  560. //
  561. // Get the upper and lower components.
  562. //
  563. hr = HrGetUpperAndLower( pncbp,
  564. &pnccUpper,
  565. &pnccLower );
  566. if ( hr == S_OK ) {
  567. hr = pnccLower->GetCharacteristics( &dwCharcteristics );
  568. if ( hr == S_OK ) {
  569. hr = pnccLower->GetId( &pszwInfIdLower );
  570. if ( hr == S_OK ) {
  571. hr = pnccUpper->GetId( &pszwInfIdUpper );
  572. if ( hr == S_OK ) {
  573. //
  574. // We are interested only in bindings to physical
  575. // ethernet adapters.
  576. //
  577. if ( dwCharcteristics & NCF_PHYSICAL ) {
  578. #ifdef DISABLE_PROTOCOLS_TO_PHYSICAL
  579. //
  580. // If it not our protocol binding to the
  581. // physical adapter then, disable the
  582. // binding.
  583. //
  584. if (_wcsicmp( pszwInfIdUpper, c_szMuxProtocol ) ) {
  585. TraceMsg( L" Disabling the binding between %s "
  586. L"and %s.\n",
  587. pszwInfIdUpper,
  588. pszwInfIdLower );
  589. hr = NETCFG_S_DISABLE_QUERY;
  590. }
  591. #endif
  592. } // Physical Adapters.
  593. else {
  594. if (dwCharcteristics & NCF_VIRTUAL) {
  595. // If the lower component is our miniport
  596. // and the upper component is our protocol
  597. // then also, disable the binding.
  598. if ( !_wcsicmp(pszwInfIdLower, c_szMuxMiniport) &&
  599. !_wcsicmp(pszwInfIdUpper, c_szMuxProtocol) ) {
  600. TraceMsg( L" Disabling the binding between %s "
  601. L"and %s.\n",
  602. pszwInfIdUpper,
  603. pszwInfIdLower );
  604. hr = NETCFG_S_DISABLE_QUERY;
  605. }
  606. } // Virtual Adapters
  607. }
  608. CoTaskMemFree( pszwInfIdUpper );
  609. } // Got the upper component id.
  610. CoTaskMemFree( pszwInfIdLower );
  611. } // Got the lower component id.
  612. } // Got NIC's characteristics
  613. ReleaseObj(pnccLower);
  614. ReleaseObj(pnccUpper);
  615. }
  616. }
  617. TraceMsg( L"<--CMuxNotify INetCfgNotifyGlobal::SysQueryBindingPath(HRESULT = %x).\n",
  618. hr );
  619. return hr;
  620. }
  621. // ----------------------------------------------------------------------
  622. //
  623. // Function: CMuxNotify::SysNotifyBindingPath
  624. //
  625. // Purpose: System tells us by calling this function which
  626. // binding path has just been formed.
  627. //
  628. // Arguments:
  629. // IN dwChangeFlag: Type of binding change
  630. // IN pncbpItem : Pointer to INetCfgBindingPath object
  631. //
  632. // Returns: S_OK on success, otherwise an error code
  633. //
  634. // Notes:
  635. //
  636. STDMETHODIMP CMuxNotify::SysNotifyBindingPath (DWORD dwChangeFlag,
  637. INetCfgBindingPath* pncbp)
  638. {
  639. TraceMsg( L"-->CMuxNotify INetCfgNotifyGlobal::SysNotifyBindingPath.\n" );
  640. DumpChangeFlag( dwChangeFlag );
  641. DumpBindingPath( pncbp );
  642. TraceMsg( L"<--CMuxNotify INetCfgNotifyGlobal::SysNotifyBindingPath(HRESULT = %x).\n",
  643. S_OK );
  644. return S_OK;
  645. }
  646. // ----------------------------------------------------------------------
  647. //
  648. // Function: CMuxNotify::SysNotifyComponent
  649. //
  650. // Purpose: System tells us by calling this function which
  651. // component has undergone a change (installed/removed)
  652. //
  653. // Arguments:
  654. // IN dwChangeFlag: Type of system change
  655. // IN pncc : Pointer to INetCfgComponent object
  656. //
  657. // Returns: S_OK on success, otherwise an error code
  658. //
  659. // Notes:
  660. //
  661. STDMETHODIMP CMuxNotify::SysNotifyComponent (DWORD dwChangeFlag,
  662. INetCfgComponent* pncc)
  663. {
  664. TraceMsg( L"-->CMuxNotify INetCfgNotifyGlobal::SysNotifyComponent.\n" );
  665. DumpChangeFlag( dwChangeFlag );
  666. DumpComponent( pncc );
  667. TraceMsg( L"<--CMuxNotify INetCfgNotifyGlobal::SysNotifyComponent(HRESULT = %x).\n",
  668. S_OK );
  669. return S_OK;
  670. }
  671. //----------------------------------------------------------------------------
  672. // INetCfgComponentPropertyUi
  673. //
  674. // The following functions provide the INetCfgComponentPropertyUi interface.
  675. //
  676. //----------------------------------------------------------------------------
  677. // ----------------------------------------------------------------------
  678. //
  679. // Function: CMuxNotify::MergePropPages
  680. //
  681. // Purpose: Supply our property page to system.
  682. //
  683. // Arguments:
  684. // OUT pdwDefPages : Pointer to num default pages
  685. // OUT pahpspPrivate: Pointer to array of pages
  686. // OUT pcPages : Pointer to num pages
  687. // IN hwndParent : Handle of parent window
  688. // IN szStartPage : Pointer to
  689. //
  690. // Returns: S_OK on success, otherwise an error code
  691. //
  692. // Notes:
  693. //
  694. STDMETHODIMP CMuxNotify::MergePropPages (IN OUT DWORD* pdwDefPages,
  695. OUT LPBYTE* pahpspPrivate,
  696. OUT UINT* pcPages,
  697. IN HWND hwndParent,
  698. OUT PCWSTR* szStartPage)
  699. {
  700. HRESULT hr = S_OK;
  701. HPROPSHEETPAGE *ahpsp;;
  702. INetLanConnectionUiInfo *pLanConnUiInfo;
  703. TraceMsg(L"-->CMuxNotify INetCfgPropertyUi::MergePropPages\n");
  704. //
  705. // We don't want any default pages to be shown
  706. //
  707. *pdwDefPages = 0;
  708. *pcPages = 0;
  709. *pahpspPrivate = NULL;
  710. if ( !m_pUnkContext ) {
  711. return E_UNEXPECTED;
  712. }
  713. hr = m_pUnkContext->QueryInterface(
  714. IID_INetLanConnectionUiInfo,
  715. reinterpret_cast<PVOID *>(&pLanConnUiInfo));
  716. if ( hr == S_OK ) {
  717. ReleaseObj( pLanConnUiInfo );
  718. ahpsp = (HPROPSHEETPAGE*)CoTaskMemAlloc( sizeof(HPROPSHEETPAGE) );
  719. if (ahpsp) {
  720. PROPSHEETPAGE psp = {0};
  721. psp.dwSize = sizeof(PROPSHEETPAGE);
  722. psp.dwFlags = PSP_DEFAULT;
  723. psp.hInstance = _Module.GetModuleInstance();
  724. psp.pszTemplate = MAKEINTRESOURCE(IDD_NOTIFY_GENERAL);
  725. psp.pfnDlgProc = (DLGPROC)NotifyDialogProc;
  726. psp.pfnCallback = NULL; (LPFNPSPCALLBACK)NotifyPropSheetPageProc;
  727. psp.lParam = (LPARAM) this;
  728. psp.pszHeaderTitle = NULL;
  729. psp.pszHeaderSubTitle = NULL;
  730. ahpsp[0] = ::CreatePropertySheetPage(&psp);
  731. *pcPages = 1;
  732. *pahpspPrivate = (LPBYTE)ahpsp;
  733. }
  734. else {
  735. hr = E_OUTOFMEMORY;
  736. }
  737. }
  738. TraceMsg(L"<--CMuxNotify INetCfgPropertyUi::MergePropPages(HRESULT = %x).\n",
  739. hr );
  740. return hr;
  741. }
  742. // ----------------------------------------------------------------------
  743. //
  744. // Function: CMuxNotify::ValidateProperties
  745. //
  746. // Purpose: Validate changes to property page.
  747. //
  748. // Arguments:
  749. // IN hwndSheet: Window handle of property sheet
  750. //
  751. // Returns: S_OK on success, otherwise an error code
  752. //
  753. // Notes:
  754. //
  755. STDMETHODIMP CMuxNotify::ValidateProperties (HWND hwndSheet)
  756. {
  757. TraceMsg( L"-->CMuxNotify INetCfgPropertyUi::ValidateProperties\n" );
  758. TraceMsg(L"<--CMuxNotify INetCfgPropertyUi::ValidateProperties(HRESULT = %x).\n",
  759. S_OK );
  760. return S_OK;
  761. }
  762. // ----------------------------------------------------------------------
  763. //
  764. // Function: CMuxNotify::CancelProperties
  765. //
  766. // Purpose: Cancel changes to property page
  767. //
  768. // Arguments: None
  769. //
  770. // Returns: S_OK on success, otherwise an error code
  771. //
  772. // Notes:
  773. //
  774. STDMETHODIMP CMuxNotify::CancelProperties (VOID)
  775. {
  776. TraceMsg(L"-->CMuxNotify INetCfgPropertyUi::CancelProperties\n");
  777. TraceMsg(L"<--CMuxNotify INetCfgPropertyUi::CancelProperties(HRESULT = %x).\n",
  778. S_OK );
  779. return S_OK;
  780. }
  781. // ----------------------------------------------------------------------
  782. //
  783. // Function: CMuxNotify::ApplyProperties
  784. //
  785. // Purpose: Apply value of controls on property page
  786. // to internal memory structure
  787. //
  788. // Arguments: None
  789. //
  790. // Returns: S_OK on success, otherwise an error code
  791. //
  792. // Notes:
  793. //
  794. STDMETHODIMP CMuxNotify::ApplyProperties (VOID)
  795. {
  796. INetLanConnectionUiInfo *pLanConnUiInfo;
  797. CMuxPhysicalAdapter *pAdapter;
  798. GUID guidAdapter;
  799. INetCfgComponent *pncc;
  800. HRESULT hr = S_OK;
  801. TraceMsg(L"-->CMuxNotify INetCfgPropertyUi::ApplyProperties\n");
  802. if ( m_pUnkContext ) {
  803. hr = m_pUnkContext->QueryInterface(
  804. IID_INetLanConnectionUiInfo,
  805. reinterpret_cast<PVOID *>(&pLanConnUiInfo));
  806. if ( hr == S_OK ) {
  807. hr = pLanConnUiInfo->GetDeviceGuid( &guidAdapter );
  808. if ( hr == S_OK ) {
  809. hr = m_AdaptersList.FindByKey( guidAdapter,
  810. &pAdapter );
  811. if ( hr == S_OK ) {
  812. switch( m_eApplyAction ) {
  813. case eActPropertyUIAdd:
  814. hr = HrAddMiniport( pAdapter,
  815. &guidAdapter );
  816. break;
  817. case eActPropertyUIRemove:
  818. hr = HrRemoveMiniport( pAdapter,
  819. &guidAdapter );
  820. break;
  821. }
  822. }
  823. }
  824. ReleaseObj( pLanConnUiInfo );
  825. }
  826. }
  827. TraceMsg(L"<--CMuxNotify INetCfgPropertyUi::ApplyProperties(HRESULT = %x).\n",
  828. hr );
  829. return hr;
  830. }
  831. // ----------------------------------------------------------------------
  832. //
  833. // Function: CMuxNotify::QueryPropertyUi
  834. //
  835. // Purpose: System is asking if we support property pages.
  836. //
  837. // Arguments:
  838. // IN pUnk: Pointer to IUnknown.
  839. //
  840. // Returns: S_OK on success, otherwise an error code
  841. //
  842. // Notes: We display property pages only in the context of
  843. // a LAN connection.
  844. //
  845. STDMETHODIMP CMuxNotify::QueryPropertyUi (IUnknown * pUnk)
  846. {
  847. INetLanConnectionUiInfo *pLanConnUiInfo;
  848. HRESULT hr=S_FALSE;
  849. TraceMsg(L"-->CMuxNotify INetCfgPropertyUi::QueryPropertyUi\n");
  850. #ifndef PASSTHRU_NOTIFY
  851. if ( pUnk ) {
  852. hr = pUnk->QueryInterface(
  853. IID_INetLanConnectionUiInfo,
  854. reinterpret_cast<PVOID *>(&pLanConnUiInfo));
  855. ReleaseObj( pLanConnUiInfo );
  856. }
  857. #endif
  858. TraceMsg(L"<--CMuxNotify INetCfgPropertyUi::QueryPropertyUi(HRESULT = %x).\n",
  859. hr );
  860. return hr;
  861. }
  862. // ----------------------------------------------------------------------
  863. //
  864. // Function: CMuxNotify::SetContext
  865. //
  866. // Purpose: Save the LAN connection context.
  867. //
  868. // Arguments:
  869. // IN pUnk: Pointer to IUnknown.
  870. //
  871. // Returns: S_OK on success, otherwise an error code
  872. //
  873. // Notes: It is also called to release the current LAN connection context.
  874. //
  875. STDMETHODIMP CMuxNotify::SetContext (IUnknown * pUnk)
  876. {
  877. TraceMsg(L"-->CMuxNotify INetCfgPropertyUi::SetContext\n");
  878. //
  879. // Release previous context, if any
  880. //
  881. ReleaseObj( m_pUnkContext );
  882. m_pUnkContext = NULL;
  883. if ( pUnk ) {
  884. m_pUnkContext = pUnk;
  885. m_pUnkContext->AddRef();
  886. }
  887. TraceMsg(L"<--CMuxNotify INetCfgPropertyUi::SetContext(HRESULT = %x).\n",
  888. S_OK );
  889. return S_OK;
  890. }
  891. //----------------------------------------------------------------------------
  892. //
  893. // Function: CMuxNotify::HrLoadAdapterConfiguration
  894. //
  895. // Purpose: This loads the Miniport and adapters that have already been
  896. // installed into our own data structures
  897. //
  898. // Arguments: None.
  899. //
  900. // Returns: S_OK, or an error.
  901. //
  902. //
  903. // Notes:
  904. //
  905. HRESULT CMuxNotify::HrLoadAdapterConfiguration (VOID)
  906. {
  907. HKEY hkeyAdapterList;
  908. WCHAR szAdapterGuid[MAX_PATH+1];
  909. DWORD dwDisp;
  910. CMuxPhysicalAdapter *pAdapter;
  911. GUID guidAdapter;
  912. DWORD dwIndex;
  913. LONG lResult;
  914. TraceMsg( L"-->CMuxNotify::HrLoadAdapterConfiguration.\n" );
  915. lResult = RegCreateKeyExW( HKEY_LOCAL_MACHINE,
  916. c_szAdapterList,
  917. 0,
  918. NULL,
  919. REG_OPTION_NON_VOLATILE,
  920. KEY_ALL_ACCESS,
  921. NULL,
  922. &hkeyAdapterList,
  923. &dwDisp);
  924. if ( lResult == ERROR_SUCCESS ) {
  925. //
  926. // If dwDisp indicates that a new key is created then, we know there
  927. // is no adapter currently listed underneath and we simply
  928. // return, otherwise, we enumerate the subkeys, each one representing an
  929. // adapter.
  930. //
  931. if ( dwDisp != REG_CREATED_NEW_KEY ) {
  932. lResult = RegEnumKeyW( hkeyAdapterList,
  933. 0,
  934. szAdapterGuid,
  935. MAX_PATH+1 );
  936. for (dwIndex=1; lResult == ERROR_SUCCESS; ++dwIndex) {
  937. TraceMsg( L" Loading configuration for adapter %s...\n",
  938. szAdapterGuid );
  939. //
  940. // Subkeys are actually a guid/bindname of the adapters.
  941. //
  942. CLSIDFromString( szAdapterGuid,
  943. &guidAdapter );
  944. //
  945. // Create an instance representing the adapter.
  946. //
  947. pAdapter = new CMuxPhysicalAdapter( m_pnc,
  948. &guidAdapter );
  949. if ( pAdapter ) {
  950. //
  951. // Load any adapter specific configuration.
  952. //
  953. pAdapter->LoadConfiguration();
  954. //
  955. // Save the adapter instance in a list.
  956. //
  957. m_AdaptersList.Insert( pAdapter,
  958. guidAdapter );
  959. //
  960. // Get next subkey.
  961. //
  962. lResult = RegEnumKeyW( hkeyAdapterList,
  963. dwIndex,
  964. szAdapterGuid,
  965. MAX_PATH+1 );
  966. }
  967. else {
  968. lResult = ERROR_NOT_ENOUGH_MEMORY;
  969. }
  970. }
  971. //
  972. // RegEnumKeyW may have returned error when there are no more
  973. // subkeys to read.
  974. //
  975. lResult = ERROR_SUCCESS;
  976. }
  977. RegCloseKey( hkeyAdapterList );
  978. }
  979. TraceMsg( L"<--CMuxNotify::HrLoadAdapterConfiguration(HRESULT = %x).\n",
  980. HRESULT_FROM_WIN32(lResult) );
  981. return HRESULT_FROM_WIN32(lResult);
  982. }
  983. //----------------------------------------------------------------------------
  984. //
  985. // Function: CMuxNotify::HrGetUpperAndLower
  986. //
  987. // Purpose: Get the upper and lower component of the first interface
  988. // of a binding path.
  989. //
  990. // Arguments:
  991. // IN pncbp : Binding path.
  992. // OUT ppnccUpper: Upper component.
  993. // OUT ppnccLower: Lower component.
  994. //
  995. // Returns: S_OK, or an error.
  996. //
  997. //
  998. // Notes:
  999. //
  1000. HRESULT CMuxNotify::HrGetUpperAndLower (INetCfgBindingPath* pncbp,
  1001. INetCfgComponent **ppnccUpper,
  1002. INetCfgComponent **ppnccLower)
  1003. {
  1004. IEnumNetCfgBindingInterface* pencbi;
  1005. INetCfgBindingInterface* pncbi;
  1006. ULONG ulCount;
  1007. HRESULT hr;
  1008. TraceMsg( L"-->CMuxNotify::HrGetUpperAndLowerComponent.\n" );
  1009. *ppnccUpper = NULL;
  1010. *ppnccLower = NULL;
  1011. hr = pncbp->EnumBindingInterfaces(&pencbi);
  1012. if (S_OK == hr) {
  1013. //
  1014. // get the first binding interface
  1015. //
  1016. hr = pencbi->Next(1, &pncbi, &ulCount);
  1017. if ( hr == S_OK ) {
  1018. hr = pncbi->GetUpperComponent( ppnccUpper );
  1019. if ( hr == S_OK ) {
  1020. hr = pncbi->GetLowerComponent ( ppnccLower );
  1021. }
  1022. else {
  1023. ReleaseObj( *ppnccUpper );
  1024. }
  1025. ReleaseObj( pncbi );
  1026. }
  1027. ReleaseObj( pencbi );
  1028. }
  1029. TraceMsg( L"<--CMuxNotify::HrGetUpperAndLowerComponent(HRESULT = %x).\n",
  1030. hr );
  1031. return hr;
  1032. }
  1033. //----------------------------------------------------------------------------
  1034. //
  1035. // Function: CMuxNotify::HrAddAdapter
  1036. //
  1037. // Purpose: Create an instance representing the physical adapter and install
  1038. // a virtual miniport.
  1039. //
  1040. // Arguments:
  1041. // IN pnccAdapter: Pointer to the physical adapter.
  1042. //
  1043. // Returns: S_OK, or an error.
  1044. //
  1045. //
  1046. // Notes:
  1047. //
  1048. HRESULT CMuxNotify::HrAddAdapter (INetCfgComponent *pnccAdapter)
  1049. {
  1050. GUID guidAdapter;
  1051. CMuxPhysicalAdapter *pAdapter;
  1052. HRESULT hr;
  1053. TraceMsg( L"-->CMuxNotify::HrAddAdapter.\n" );
  1054. hr = pnccAdapter->GetInstanceGuid( &guidAdapter );
  1055. if ( hr == S_OK ) {
  1056. pAdapter = new CMuxPhysicalAdapter( m_pnc,
  1057. &guidAdapter );
  1058. if ( pAdapter ) {
  1059. hr = HrAddMiniport( pAdapter,
  1060. &guidAdapter );
  1061. if ( hr == S_OK ) {
  1062. m_AdaptersToAdd.Insert( pAdapter,
  1063. guidAdapter );
  1064. }
  1065. else {
  1066. delete pAdapter;
  1067. }
  1068. }
  1069. else {
  1070. hr = HRESULT_FROM_WIN32( ERROR_NOT_ENOUGH_MEMORY );
  1071. }
  1072. }
  1073. TraceMsg( L"<--CMuxNotify::HrAddAdapter(HRESULT = %x).\n",
  1074. hr );
  1075. return hr;
  1076. }
  1077. //----------------------------------------------------------------------------
  1078. //
  1079. // Function: CMuxNotify::HrRemoveAdapter
  1080. //
  1081. // Purpose: Deletes the instance representing the physical adapter
  1082. // and uninstalls all the virtual miniports.
  1083. //
  1084. // Arguments:
  1085. // IN pnccAdapter: Pointer to the physical adapter.
  1086. //
  1087. // Returns: S_OK, or an error.
  1088. //
  1089. //
  1090. // Notes: This function is called when the adapter or the protocol
  1091. // is being uninstalled.
  1092. //
  1093. HRESULT CMuxNotify::HrRemoveAdapter (INetCfgComponent *pnccAdapter)
  1094. {
  1095. GUID guidAdapter;
  1096. CMuxPhysicalAdapter *pAdapter;
  1097. HRESULT hr;
  1098. TraceMsg( L"-->CMuxNotify::HrRemoveAdapter.\n" );
  1099. hr = pnccAdapter->GetInstanceGuid( &guidAdapter );
  1100. if ( hr == S_OK ) {
  1101. hr = m_AdaptersList.RemoveByKey( guidAdapter,
  1102. &pAdapter );
  1103. if ( hr == S_OK ) {
  1104. m_AdaptersToRemove.Insert( pAdapter,
  1105. guidAdapter );
  1106. hr = pAdapter->Remove();
  1107. #ifdef DISABLE_PROTOCOLS_TO_PHYSICAL
  1108. //
  1109. // Restore the bindings of other protocols to the physical
  1110. // adapter.
  1111. //
  1112. EnableBindings( pnccAdapter,
  1113. TRUE );
  1114. #endif
  1115. }
  1116. }
  1117. TraceMsg( L"<--CMuxNotify::HrRemoveAdapter(HRESULT = %x).\n",
  1118. hr );
  1119. return hr;
  1120. }
  1121. //----------------------------------------------------------------------------
  1122. //
  1123. // Function: CMuxNotify::HrAddMiniport
  1124. //
  1125. // Purpose: Installs a virtual miniport.
  1126. //
  1127. // Arguments:
  1128. // IN pAdapter : Pointer to the physical adapter class instance.
  1129. // IN pguidAdapter: Pointer to the GUID of the adapter.
  1130. //
  1131. // Returns: S_OK, or an error.
  1132. //
  1133. //
  1134. // Notes:
  1135. //
  1136. HRESULT CMuxNotify::HrAddMiniport (CMuxPhysicalAdapter *pAdapter,
  1137. GUID *pguidAdapter)
  1138. {
  1139. CMuxVirtualMiniport *pMiniport;
  1140. INetCfgComponent *pnccAdapter;
  1141. HRESULT hr;
  1142. TraceMsg( L"-->CMuxNotify::HrAddMiniport.\n" );
  1143. pMiniport = new CMuxVirtualMiniport( m_pnc,
  1144. NULL,
  1145. pguidAdapter );
  1146. if ( pMiniport ) {
  1147. hr = pMiniport->Install();
  1148. if ( hr == S_OK ) {
  1149. hr = pAdapter->AddMiniport( pMiniport );
  1150. if ( hr != S_OK ) {
  1151. pMiniport->DeInstall();
  1152. delete pMiniport;
  1153. }
  1154. }
  1155. }
  1156. else {
  1157. hr = HRESULT_FROM_WIN32( ERROR_NOT_ENOUGH_MEMORY );
  1158. }
  1159. #ifdef DISABLE_PROTOCOLS_TO_PHYSICAL
  1160. if ( hr == S_OK ) {
  1161. //
  1162. // If this is the first virtual miniport then, disable the bindings
  1163. // of other protocols to the physical adapter.
  1164. //
  1165. if ( pAdapter->MiniportCount() == 0 ) {
  1166. hr = HrFindInstance( m_pnc,
  1167. *pguidAdapter,
  1168. &pnccAdapter );
  1169. if ( hr == S_OK ) {
  1170. EnableBindings( pnccAdapter,
  1171. FALSE );
  1172. ReleaseObj( pnccAdapter );
  1173. }
  1174. }
  1175. }
  1176. #endif
  1177. TraceMsg( L"<--CMuxNotify::HrAddMiniport(HRESULT = %x).\n",
  1178. hr );
  1179. return hr;
  1180. }
  1181. //----------------------------------------------------------------------------
  1182. //
  1183. // Function: CMuxNotify::HrRemoveMiniport
  1184. //
  1185. // Purpose: Uninstalls a virtual miniport.
  1186. //
  1187. // Arguments:
  1188. // IN pAdapter : Pointer to the physical adapter class instance.
  1189. // IN pguidAdapter: Pointer to the GUID of the adapter.
  1190. //
  1191. // Returns: S_OK, or an error.
  1192. //
  1193. //
  1194. // Notes:
  1195. //
  1196. HRESULT CMuxNotify::HrRemoveMiniport (CMuxPhysicalAdapter *pAdapter,
  1197. GUID *pguidAdapter)
  1198. {
  1199. INetCfgComponent *pnccAdapter;
  1200. HRESULT hr;
  1201. TraceMsg( L"-->CMuxNotify::HrRemoveMiniport.\n" );
  1202. hr = pAdapter->RemoveMiniport( NULL );
  1203. #ifdef DISABLE_PROTOCOLS_TO_PHYSICAL
  1204. if ( hr == S_OK ) {
  1205. //
  1206. // If this was the last miniport that was removed then, restore the
  1207. // bindings of other protocols to the physical adapter.
  1208. //
  1209. if ( pAdapter->AllMiniportsRemoved() ) {
  1210. hr = HrFindInstance( m_pnc,
  1211. *pguidAdapter,
  1212. &pnccAdapter );
  1213. if ( hr == S_OK ) {
  1214. EnableBindings( pnccAdapter,
  1215. TRUE );
  1216. ReleaseObj( pnccAdapter );
  1217. }
  1218. }
  1219. }
  1220. #endif
  1221. TraceMsg( L"<--CMuxNotify::HrRemoveMiniport(HRESULT = %x).\n",
  1222. hr );
  1223. return hr;
  1224. }
  1225. // ----------------------------------------------------------------------
  1226. //
  1227. // Function: CMuxNotify::OnInitDialog
  1228. //
  1229. // Purpose: Initialize controls
  1230. //
  1231. // Arguments:
  1232. // IN hWnd: Window handle to the property page.
  1233. //
  1234. // Returns: TRUE.
  1235. //
  1236. // Notes:
  1237. //
  1238. LRESULT CMuxNotify::OnInitDialog (IN HWND hWndPage)
  1239. {
  1240. m_eApplyAction = eActUnknown;
  1241. ::SendMessage(GetDlgItem(hWndPage, IDC_ADD), BM_SETCHECK, BST_CHECKED, 0);
  1242. ::SendMessage(GetDlgItem(hWndPage, IDC_REMOVE), BM_SETCHECK, BST_UNCHECKED, 0);
  1243. return TRUE;
  1244. }
  1245. // ----------------------------------------------------------------------
  1246. //
  1247. // Function: CMuxNotify::OnOk
  1248. //
  1249. // Purpose: Do actions when OK is pressed
  1250. //
  1251. // Arguments:
  1252. // IN hWnd: Window handle to the property page.
  1253. //
  1254. // Returns: PSNRET_NOERROR
  1255. //
  1256. // Notes:
  1257. //
  1258. LRESULT CMuxNotify::OnOk (IN HWND hWndPage)
  1259. {
  1260. TraceMsg(L"-->CMuxNotify::OnOk\n");
  1261. if ( ::SendMessage(GetDlgItem(hWndPage, IDC_ADD),
  1262. BM_GETCHECK, 0, 0) == BST_CHECKED ) {
  1263. m_eApplyAction = eActPropertyUIAdd;
  1264. }
  1265. else {
  1266. m_eApplyAction = eActPropertyUIRemove;
  1267. }
  1268. //
  1269. // Set the property sheet changed flag if any of our controls
  1270. // get changed. This is important so that we get called to
  1271. // apply our property changes.
  1272. //
  1273. PropSheet_Changed( GetParent(hWndPage), hWndPage);
  1274. TraceMsg(L"<--CMuxNotify::OnOk(Action = %s).\n",
  1275. (m_eApplyAction == eActPropertyUIAdd) ? L"Add" : L"Remove" );
  1276. return PSNRET_NOERROR;
  1277. }
  1278. // ----------------------------------------------------------------------
  1279. //
  1280. // Function: CMuxNotify::OnCancel
  1281. //
  1282. // Purpose: Do actions when CANCEL is pressed
  1283. //
  1284. // Arguments:
  1285. // IN hWnd: Window handle to the property page.
  1286. //
  1287. // Returns: FALSE
  1288. //
  1289. // Notes:
  1290. //
  1291. LRESULT CMuxNotify::OnCancel (IN HWND hWndPage)
  1292. {
  1293. TraceMsg(L"-->CMuxNotify::OnCancel\n");
  1294. m_eApplyAction = eActUnknown;
  1295. TraceMsg(L"<--CMuxNotify::OnCancel\n");
  1296. return FALSE;
  1297. }
  1298. // ----------------------------------------------------------------------
  1299. //
  1300. // Function: CMuxNotifyDialogProc
  1301. //
  1302. // Purpose: Dialog proc
  1303. //
  1304. // Arguments:
  1305. // IN hWnd : See win32 documentation.
  1306. // IN uMsg : See win32 documentation.
  1307. // IN wParam: See win32 documentation.
  1308. // IN lParam: See win32 documentation.
  1309. //
  1310. // Returns: See win32 documentation.
  1311. //
  1312. // Notes:
  1313. //
  1314. LRESULT CALLBACK NotifyDialogProc (HWND hWnd,
  1315. UINT uMsg,
  1316. WPARAM wParam,
  1317. LPARAM lParam)
  1318. {
  1319. CMuxNotify *psf;
  1320. LRESULT lRes=FALSE;
  1321. if ( uMsg != WM_INITDIALOG ) {
  1322. psf = (CMuxNotify *)::GetWindowLongPtr( hWnd,
  1323. DWLP_USER );
  1324. // Until we get WM_INITDIALOG, just return FALSE
  1325. if ( !psf ) {
  1326. return lRes;
  1327. }
  1328. }
  1329. switch( uMsg ) {
  1330. case WM_INITDIALOG:
  1331. {
  1332. PROPSHEETPAGE* ppsp;
  1333. ppsp = (PROPSHEETPAGE *)lParam;
  1334. psf = (CMuxNotify *)ppsp->lParam;
  1335. SetWindowLongPtr( hWnd,
  1336. DWLP_USER,
  1337. (LONG_PTR)psf);
  1338. lRes = psf->OnInitDialog( hWnd );
  1339. }
  1340. break;
  1341. case WM_COMMAND:
  1342. break;
  1343. case WM_NOTIFY:
  1344. {
  1345. LPNMHDR pnmh = (LPNMHDR)lParam;
  1346. switch (pnmh->code) {
  1347. case PSN_KILLACTIVE:
  1348. //
  1349. // ok to loose focus.
  1350. //
  1351. SetWindowLongPtr( hWnd, DWLP_MSGRESULT, FALSE);
  1352. lRes = TRUE;
  1353. break;
  1354. case PSN_APPLY:
  1355. psf = (CMuxNotify *)::GetWindowLongPtr( hWnd, DWLP_USER);
  1356. lRes = psf->OnOk( hWnd );
  1357. SetWindowLongPtr( hWnd, DWLP_MSGRESULT, lRes);
  1358. lRes = TRUE;
  1359. break;
  1360. case PSN_RESET:
  1361. psf = (CMuxNotify *)::GetWindowLongPtr( hWnd, DWLP_USER);
  1362. psf->OnCancel( hWnd );
  1363. }
  1364. }
  1365. }
  1366. return lRes;
  1367. }
  1368. // ----------------------------------------------------------------------
  1369. //
  1370. // Function: CMuxNotifyPropSheetPageProc
  1371. //
  1372. // Purpose: Prop sheet proc
  1373. //
  1374. // Arguments:
  1375. // IN hWnd: See win32 documentation
  1376. // IN uMsg: See win32 documentation
  1377. // IN ppsp: See win32 documentation
  1378. //
  1379. // Returns: See win32 documentation
  1380. //
  1381. // Notes:
  1382. //
  1383. UINT CALLBACK NotifyPropSheetPageProc(HWND hWnd,
  1384. UINT uMsg,
  1385. LPPROPSHEETPAGE ppsp)
  1386. {
  1387. return TRUE;
  1388. }
  1389. #ifdef DISABLE_PROTOCOLS_TO_PHYSICAL
  1390. // ----------------------------------------------------------------------
  1391. //
  1392. // Function: CMuxNotify::EnableBindings
  1393. //
  1394. // Purpose: Enable/Disable the bindings of other protocols to
  1395. // the physical adapter.
  1396. //
  1397. // Arguments:
  1398. // IN pnccAdapter: Pointer to the physical adapter.
  1399. // IN bEnable: TRUE/FALSE to enable/disable respectively.
  1400. //
  1401. // Returns: None.
  1402. //
  1403. // Notes:
  1404. //
  1405. VOID CMuxNotify::EnableBindings (INetCfgComponent *pnccAdapter,
  1406. BOOL bEnable)
  1407. {
  1408. IEnumNetCfgBindingPath *pencbp;
  1409. INetCfgBindingPath *pncbp;
  1410. HRESULT hr;
  1411. TraceMsg( L"-->CMuxNotify::EnableBindings.\n" );
  1412. //
  1413. // Get the binding path enumerator.
  1414. //
  1415. hr = HrGetBindingPathEnum( pnccAdapter,
  1416. EBP_ABOVE,
  1417. &pencbp );
  1418. if ( hr == S_OK ) {
  1419. hr = HrGetBindingPath( pencbp,
  1420. &pncbp );
  1421. //
  1422. // Traverse each binding path.
  1423. //
  1424. while( hr == S_OK ) {
  1425. //
  1426. // If our protocol does exist in the binding path then,
  1427. // disable it.
  1428. //
  1429. if ( !IfExistMux(pncbp) ) {
  1430. pncbp->Enable( bEnable );
  1431. }
  1432. ReleaseObj( pncbp );
  1433. hr = HrGetBindingPath( pencbp,
  1434. &pncbp );
  1435. }
  1436. ReleaseObj( pencbp );
  1437. }
  1438. else {
  1439. TraceMsg( L" Couldn't get the binding path enumerator, "
  1440. L"bindings will not be %s.\n",
  1441. bEnable ? L"enabled" : L"disabled" );
  1442. }
  1443. TraceMsg( L"<--CMuxNotify::EnableBindings.\n" );
  1444. return;
  1445. }
  1446. // ----------------------------------------------------------------------
  1447. //
  1448. // Function: CMuxNotify::IfExistMux
  1449. //
  1450. // Purpose: Determine if a given binding path contains our protocol.
  1451. //
  1452. // Arguments:
  1453. // IN pncbp: Pointer to the binding path.
  1454. //
  1455. // Returns: TRUE if our protocol exists, otherwise FALSE.
  1456. //
  1457. // Notes:
  1458. //
  1459. BOOL CMuxNotify::IfExistMux (INetCfgBindingPath *pncbp)
  1460. {
  1461. IEnumNetCfgBindingInterface *pencbi;
  1462. INetCfgBindingInterface *pncbi;
  1463. INetCfgComponent *pnccUpper;
  1464. LPWSTR lpszIdUpper;
  1465. HRESULT hr;
  1466. BOOL bExist = FALSE;
  1467. TraceMsg( L"-->CMuxNotify::IfExistMux.\n" );
  1468. //
  1469. // Get the binding interface enumerator.
  1470. //
  1471. hr = HrGetBindingInterfaceEnum( pncbp,
  1472. &pencbi );
  1473. if ( hr == S_OK ) {
  1474. //
  1475. // Traverse each binding interface.
  1476. //
  1477. hr = HrGetBindingInterface( pencbi,
  1478. &pncbi );
  1479. while( !bExist && (hr == S_OK) ) {
  1480. //
  1481. // Is the upper component our protocol?
  1482. //
  1483. hr = pncbi->GetUpperComponent( &pnccUpper );
  1484. if ( hr == S_OK ) {
  1485. hr = pnccUpper->GetId( &lpszIdUpper );
  1486. if ( hr == S_OK ) {
  1487. bExist = !_wcsicmp( lpszIdUpper, c_szMuxProtocol );
  1488. CoTaskMemFree( lpszIdUpper );
  1489. }
  1490. else {
  1491. TraceMsg( L" Failed to get the upper component of the interface.\n" );
  1492. }
  1493. ReleaseObj( pnccUpper );
  1494. }
  1495. else {
  1496. TraceMsg( L" Failed to get the upper component of the interface.\n" );
  1497. }
  1498. ReleaseObj( pncbi );
  1499. if ( !bExist ) {
  1500. hr = HrGetBindingInterface( pencbi,
  1501. &pncbi );
  1502. }
  1503. }
  1504. ReleaseObj( pencbi );
  1505. }
  1506. else {
  1507. TraceMsg( L" Couldn't get the binding interface enumerator.\n" );
  1508. }
  1509. TraceMsg( L"<--CMuxNotify::IfExistMux(BOOL = %x).\n",
  1510. bExist );
  1511. return bExist;
  1512. }
  1513. // ----------------------------------------------------------------------
  1514. //
  1515. // Function: CMuxNotify::HrGetBindingPathEnum
  1516. //
  1517. // Purpose: Returns the binding path enumerator.
  1518. //
  1519. // Arguments:
  1520. // IN pnccAdapter : Pointer to the physical adapter.
  1521. // IN dwBindingType: Type of binding path enumerator.
  1522. // OUT ppencbp : Pointer to the binding path enumerator.
  1523. //
  1524. // Returns: S_OK on success, otherwise an error code.
  1525. //
  1526. // Notes:
  1527. //
  1528. HRESULT CMuxNotify::HrGetBindingPathEnum (
  1529. INetCfgComponent *pnccAdapter,
  1530. DWORD dwBindingType,
  1531. IEnumNetCfgBindingPath **ppencbp)
  1532. {
  1533. INetCfgComponentBindings *pnccb = NULL;
  1534. HRESULT hr;
  1535. *ppencbp = NULL;
  1536. hr = pnccAdapter->QueryInterface( IID_INetCfgComponentBindings,
  1537. (PVOID *)&pnccb );
  1538. if ( hr == S_OK ) {
  1539. hr = pnccb->EnumBindingPaths( dwBindingType,
  1540. ppencbp );
  1541. ReleaseObj( pnccb );
  1542. }
  1543. return hr;
  1544. }
  1545. // ----------------------------------------------------------------------
  1546. //
  1547. // Function: CMuxNotify::HrGetBindingPath
  1548. //
  1549. // Purpose: Returns a binding path.
  1550. //
  1551. // Arguments:
  1552. // IN pencbp : Pointer to the binding path enumerator.
  1553. // OUT ppncbp : Pointer to the binding path.
  1554. //
  1555. // Returns: S_OK on success, otherwise an error code.
  1556. //
  1557. // Notes:
  1558. //
  1559. HRESULT CMuxNotify::HrGetBindingPath (IEnumNetCfgBindingPath *pencbp,
  1560. INetCfgBindingPath **ppncbp)
  1561. {
  1562. ULONG ulCount;
  1563. HRESULT hr;
  1564. *ppncbp = NULL;
  1565. hr = pencbp->Next( 1,
  1566. ppncbp,
  1567. &ulCount );
  1568. return hr;
  1569. }
  1570. // ----------------------------------------------------------------------
  1571. //
  1572. // Function: CMuxNotify::HrGetBindingInterfaceEnum
  1573. //
  1574. // Purpose: Returns the binding interface enumerator.
  1575. //
  1576. // Arguments:
  1577. // IN pncbp : Pointer to the binding path.
  1578. // OUT ppencbi: Pointer to the binding path enumerator.
  1579. //
  1580. // Returns: S_OK on success, otherwise an error code.
  1581. //
  1582. // Notes:
  1583. //
  1584. HRESULT CMuxNotify::HrGetBindingInterfaceEnum (
  1585. INetCfgBindingPath *pncbp,
  1586. IEnumNetCfgBindingInterface **ppencbi)
  1587. {
  1588. HRESULT hr;
  1589. *ppencbi = NULL;
  1590. hr = pncbp->EnumBindingInterfaces( ppencbi );
  1591. return hr;
  1592. }
  1593. // ----------------------------------------------------------------------
  1594. //
  1595. // Function: CMuxNotify::HrGetBindingInterface
  1596. //
  1597. // Purpose: Returns a binding interface.
  1598. //
  1599. // Arguments:
  1600. // IN pencbi : Pointer to the binding interface enumerator.
  1601. // OUT ppncbi : Pointer to the binding interface.
  1602. //
  1603. // Returns: S_OK on success, otherwise an error code.
  1604. //
  1605. // Notes:
  1606. //
  1607. HRESULT CMuxNotify::HrGetBindingInterface (
  1608. IEnumNetCfgBindingInterface *pencbi,
  1609. INetCfgBindingInterface **ppncbi)
  1610. {
  1611. ULONG ulCount;
  1612. HRESULT hr;
  1613. *ppncbi = NULL;
  1614. hr = pencbi->Next( 1,
  1615. ppncbi,
  1616. &ulCount );
  1617. return hr;
  1618. }
  1619. #endif