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.

938 lines
27 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1992-2001.
  5. //
  6. // File: A D A P T E R . C P P
  7. //
  8. // Contents: Physical adapter class definition.
  9. //
  10. // Notes:
  11. //
  12. // Author: Alok Sinha
  13. //
  14. //----------------------------------------------------------------------------
  15. #include "adapter.h"
  16. #include "common.h"
  17. #ifdef CUSTOM_EVENTS
  18. #include "public.h"
  19. #endif
  20. //+---------------------------------------------------------------------------
  21. //
  22. // Function: CMuxPhysicalAdapter::CMuxPhysicalAdapter
  23. //
  24. // Purpose: Constructor for class CMuxPhysicalAdapter
  25. //
  26. // Arguments: None
  27. //
  28. // Returns:
  29. //
  30. // Notes:
  31. //
  32. CMuxPhysicalAdapter::CMuxPhysicalAdapter (INetCfg *pnc,
  33. GUID *pguidAdapter)
  34. {
  35. TraceMsg( L"-->CMuxPhysicalAdapter::CMuxPhysicalAdapter(Constructor).\n" );
  36. m_pnc = pnc;
  37. m_pnc->AddRef();
  38. CopyMemory( &m_guidAdapter,
  39. pguidAdapter,
  40. sizeof(GUID) );
  41. TraceMsg( L"<--CMuxPhysicalAdapter::CMuxPhysicalAdapter(Constructor).\n" );
  42. }
  43. //+---------------------------------------------------------------------------
  44. //
  45. // Function: CMuxPhysicalAdapter::~CMuxPhysicalAdapter
  46. //
  47. // Purpose: Destructor for class CMuxPhysicalAdapter
  48. //
  49. // Arguments: None
  50. //
  51. // Returns:
  52. //
  53. // Notes:
  54. //
  55. CMuxPhysicalAdapter::~CMuxPhysicalAdapter (VOID)
  56. {
  57. CMuxVirtualMiniport *pMiniport;
  58. DWORD dwMiniportCount;
  59. DWORD i;
  60. TraceMsg( L"-->CMuxPhysicalAdapter::~CMuxPhysicalAdapter(Destructor).\n" );
  61. //
  62. // Delete all the instances representing the virtual miniports.
  63. // We are only deleting the class instances, not uninstalling the
  64. // the virtual miniports.
  65. //
  66. dwMiniportCount = m_MiniportList.ListCount();
  67. for (i=0; i < dwMiniportCount; ++i) {
  68. m_MiniportList.Remove( &pMiniport );
  69. delete pMiniport;
  70. }
  71. dwMiniportCount = m_MiniportsToAdd.ListCount();
  72. for (i=0; i < dwMiniportCount; ++i) {
  73. m_MiniportsToAdd.Remove( &pMiniport );
  74. delete pMiniport;
  75. }
  76. dwMiniportCount = m_MiniportsToRemove.ListCount();
  77. for (i=0; i < dwMiniportCount; ++i) {
  78. m_MiniportsToRemove.Remove( &pMiniport );
  79. delete pMiniport;
  80. }
  81. ReleaseObj( m_pnc );
  82. TraceMsg( L"<--CMuxPhysicalAdapter::~CMuxPhysicalAdapter(Destructor).\n" );
  83. }
  84. //+---------------------------------------------------------------------------
  85. //
  86. // Function: CMuxPhysicalAdapter::LoadConfiguration
  87. //
  88. // Purpose: Read the registry to get the device IDs of the
  89. // virtual miniports installed on the adapter and
  90. // crate an instance to represent each virtual miniport.
  91. //
  92. // Arguments: None
  93. //
  94. // Returns: S_OK on success, otherwise an error code.
  95. //
  96. // Notes:
  97. //
  98. HRESULT CMuxPhysicalAdapter::LoadConfiguration (VOID)
  99. {
  100. HKEY hkeyAdapterGuid;
  101. WCHAR szAdapterGuidKey[MAX_PATH+1];
  102. WCHAR szAdapterGuid[MAX_PATH+1];
  103. LPWSTR lpMiniportList;
  104. LPWSTR lpMiniport;
  105. LPWSTR lpMiniportGuid;
  106. DWORD dwDisp;
  107. CMuxVirtualMiniport *pMiniport;
  108. GUID guidMiniport;
  109. DWORD dwBytes;
  110. LONG lResult;
  111. TraceMsg( L"-->CMuxPhysicalAdapter::LoadConfiguration.\n" );
  112. //
  113. // Build the registry key using the adapter guid under which
  114. // device IDs of the virtual miniports are stored.
  115. //
  116. StringFromGUID2( m_guidAdapter,
  117. szAdapterGuid,
  118. MAX_PATH+1 );
  119. swprintf( szAdapterGuidKey,
  120. L"%s\\%s",
  121. c_szAdapterList,
  122. szAdapterGuid );
  123. lResult = RegCreateKeyExW( HKEY_LOCAL_MACHINE,
  124. szAdapterGuidKey,
  125. 0,
  126. NULL,
  127. REG_OPTION_NON_VOLATILE,
  128. KEY_ALL_ACCESS,
  129. NULL,
  130. &hkeyAdapterGuid,
  131. &dwDisp);
  132. if ( lResult == ERROR_SUCCESS ) {
  133. //
  134. // If dwDisp indicates that a new key is created then, we know there
  135. // is no virtual miniport currently listed underneath and we simply
  136. // return.
  137. //
  138. if ( dwDisp != REG_CREATED_NEW_KEY ) {
  139. dwBytes = 0;
  140. lResult = RegQueryValueExW(
  141. hkeyAdapterGuid,
  142. c_szUpperBindings,
  143. NULL,
  144. NULL,
  145. NULL,
  146. &dwBytes );
  147. lpMiniportList = (LPWSTR)calloc( dwBytes, 1 );
  148. if ( lpMiniportList ) {
  149. lResult = RegQueryValueExW(
  150. hkeyAdapterGuid,
  151. c_szUpperBindings,
  152. NULL,
  153. NULL,
  154. (LPBYTE)lpMiniportList,
  155. &dwBytes );
  156. if ( lResult == ERROR_SUCCESS ) {
  157. lpMiniport = lpMiniportList;
  158. #ifndef PASSTHRU_NOTIFY
  159. //
  160. // In case of mux, c_szUpperBindings is a multi_sz string.
  161. //
  162. while ( wcslen(lpMiniport) ) {
  163. lpMiniportGuid = RemoveDevicePrefix( lpMiniport );
  164. TraceMsg( L" Loading configuration for miniport %s...\n",
  165. lpMiniportGuid );
  166. if ( lpMiniportGuid ) {
  167. CLSIDFromString( lpMiniportGuid,
  168. &guidMiniport );
  169. //
  170. // Create an instance representing the virtual miniport.
  171. //
  172. pMiniport = new CMuxVirtualMiniport( m_pnc,
  173. &guidMiniport,
  174. &m_guidAdapter );
  175. if ( pMiniport ) {
  176. //
  177. // Load any miniport specific configuration.
  178. //
  179. pMiniport->LoadConfiguration();
  180. //
  181. // Save the miniport instance in a list.
  182. //
  183. m_MiniportList.Insert( pMiniport,
  184. guidMiniport );
  185. }
  186. free( lpMiniportGuid );
  187. }
  188. //
  189. // Get next miniport guid.
  190. //
  191. lpMiniport += wcslen(lpMiniport) + 1;
  192. }
  193. #else
  194. //
  195. // In case of the passthru driver, c_szUpperBindings is
  196. // a reg_sz string.
  197. //
  198. lpMiniportGuid = RemoveDevicePrefix( lpMiniport );
  199. TraceMsg( L" Loading configuration for miniport %s...\n",
  200. lpMiniportGuid );
  201. if ( lpMiniportGuid ) {
  202. CLSIDFromString( lpMiniportGuid,
  203. &guidMiniport );
  204. //
  205. // Create an instance representing the virtual miniport.
  206. //
  207. pMiniport = new CMuxVirtualMiniport( m_pnc,
  208. &guidMiniport,
  209. &m_guidAdapter );
  210. if ( pMiniport ) {
  211. //
  212. // Load any miniport specific configuration.
  213. //
  214. pMiniport->LoadConfiguration();
  215. //
  216. // Save the miniport instance in a list.
  217. //
  218. m_MiniportList.Insert( pMiniport,
  219. guidMiniport );
  220. }
  221. free( lpMiniportGuid );
  222. }
  223. #endif
  224. }
  225. else {
  226. TraceMsg( L" Failed to read the registry value: %s.\n",
  227. c_szUpperBindings );
  228. }
  229. free( lpMiniportList );
  230. }
  231. else {
  232. lResult = ERROR_NOT_ENOUGH_MEMORY;
  233. }
  234. }
  235. RegCloseKey( hkeyAdapterGuid );
  236. }
  237. else {
  238. TraceMsg( L" Failed to open the registry key: %s.\n",
  239. szAdapterGuidKey );
  240. }
  241. TraceMsg( L"<--CMuxPhysicalAdapter::LoadConfiguration(HRESULT = %x).\n",
  242. HRESULT_FROM_WIN32(lResult) );
  243. return HRESULT_FROM_WIN32(lResult);
  244. }
  245. //+---------------------------------------------------------------------------
  246. //
  247. // Function: CMuxPhysicalAdapter::GetAdapterGUID
  248. //
  249. // Purpose: Returns the adapter GUID.
  250. //
  251. // Arguments:
  252. // OUT pguidAdapter: GUID of the adapter returned.
  253. //
  254. // Returns: None.
  255. //
  256. // Notes:
  257. //
  258. VOID CMuxPhysicalAdapter::GetAdapterGUID (GUID *pguidAdapter)
  259. {
  260. TraceMsg( L"-->CMuxPhysicalAdapter::GetAdapterGUID.\n" );
  261. CopyMemory( pguidAdapter,
  262. &m_guidAdapter,
  263. sizeof(GUID) );
  264. TraceMsg( L"<--CMuxPhysicalAdapter::GetAdapterGUID.\n" );
  265. }
  266. //+---------------------------------------------------------------------------
  267. //
  268. // Function: CMuxPhysicalAdapter::AddMiniport
  269. //
  270. // Purpose: Puts the miniport instance into the list of newly added miniports.
  271. //
  272. // Arguments:
  273. // IN pMiniport: A newly create miniport instance.
  274. //
  275. // Returns: S_OK on success, otherwize and error code.
  276. //
  277. // Notes:
  278. //
  279. HRESULT CMuxPhysicalAdapter::AddMiniport (CMuxVirtualMiniport *pMiniport)
  280. {
  281. GUID guidMiniport;
  282. HRESULT hr;
  283. TraceMsg( L"-->CMuxPhysicalAdapter::AddMiniport.\n" );
  284. pMiniport->GetMiniportGUID( &guidMiniport );
  285. hr = m_MiniportsToAdd.Insert( pMiniport,
  286. guidMiniport );
  287. TraceMsg( L"<--CMuxPhysicalAdapter::AddMiniport(HRESULT = %x).\n",
  288. hr );
  289. return hr;
  290. }
  291. //+---------------------------------------------------------------------------
  292. //
  293. // Function: CMuxPhysicalAdapter::RemoveMiniport
  294. //
  295. // Purpose: Remove a specified miniport instance from the list and
  296. // uninstalls the corresponding virtual miniport.
  297. //
  298. // Arguments:
  299. // IN pguidMiniportToRemove: GUID of the miniport to be removed
  300. // and uninstalled. If it is NULL then,
  301. // the first miniport instance is removed.
  302. //
  303. // Returns: S_OK on success, otherwize and error code.
  304. //
  305. // Notes:
  306. //
  307. HRESULT CMuxPhysicalAdapter::RemoveMiniport (GUID *pguidMiniportToRemove)
  308. {
  309. CMuxVirtualMiniport *pMiniport;
  310. GUID guidMiniport;
  311. HRESULT hr;
  312. TraceMsg( L"-->CMuxPhysicalAdapter::RemoveMiniport.\n" );
  313. //
  314. // If miniport GUID specified then, delete that one.
  315. //
  316. if ( pguidMiniportToRemove ) {
  317. hr = m_MiniportList.RemoveByKey( *pguidMiniportToRemove,
  318. &pMiniport );
  319. }
  320. else {
  321. //
  322. // No GUID specified, so we just delete the first one.
  323. //
  324. hr = m_MiniportList.Remove( &pMiniport );
  325. }
  326. if ( hr == S_OK ) {
  327. pMiniport->GetMiniportGUID( &guidMiniport );
  328. m_MiniportsToRemove.Insert( pMiniport,
  329. guidMiniport );
  330. pMiniport->DeInstall();
  331. }
  332. TraceMsg( L"<--CMuxPhysicalAdapter::RemoveMiniport(HRESULT = %x).\n",
  333. hr );
  334. return hr;
  335. }
  336. //+---------------------------------------------------------------------------
  337. //
  338. // Function: CMuxPhysicalAdapter::Remove
  339. //
  340. // Purpose: Uninstall all the instances of virtual miniports.
  341. //
  342. // Arguments: None
  343. //
  344. // Returns: S_OK.
  345. //
  346. // Notes:
  347. //
  348. HRESULT CMuxPhysicalAdapter::Remove (VOID)
  349. {
  350. CMuxVirtualMiniport *pMiniport;
  351. GUID guidMiniport;
  352. DWORD dwMiniportCount;
  353. DWORD i;
  354. TraceMsg( L"-->CMuxPhysicalAdapter::Remove.\n" );
  355. dwMiniportCount = m_MiniportList.ListCount();
  356. TraceMsg ( L" Removing %d miniports.\n",
  357. dwMiniportCount );
  358. for (i=0; i < dwMiniportCount; ++i) {
  359. m_MiniportList.Remove( &pMiniport );
  360. pMiniport->GetMiniportGUID( &guidMiniport );
  361. m_MiniportsToRemove.Insert( pMiniport,
  362. guidMiniport );
  363. pMiniport->DeInstall();
  364. }
  365. TraceMsg( L"<--CMuxPhysicalAdapter::Remove(HRESULT = %x).\n",
  366. S_OK );
  367. return S_OK;
  368. }
  369. //+---------------------------------------------------------------------------
  370. //
  371. // Function: CMuxPhysicalAdapter::ApplyRegistryChanges
  372. //
  373. // Purpose: Update the registry depending on the actions performed.
  374. //
  375. // Arguments:
  376. // IN eApplyAction: Action that was last performed.
  377. //
  378. //
  379. // Returns: S_OK.
  380. //
  381. // Notes:
  382. // More than one action could have been performed by the user
  383. // but this function is called only once at the end. So, the argument
  384. // only denotes the very last action performed. For example, if the
  385. // user deletes one miniport and adds two miniports then, the argument
  386. // will denote an add action.
  387. //
  388. HRESULT CMuxPhysicalAdapter::ApplyRegistryChanges (ConfigAction eApplyAction)
  389. {
  390. HKEY hkeyAdapterList;
  391. HKEY hkeyAdapterGuid;
  392. WCHAR szAdapterGuid[MAX_PATH+1];
  393. CMuxVirtualMiniport *pMiniport = NULL;
  394. DWORD dwMiniportCount;
  395. DWORD dwDisp;
  396. DWORD i;
  397. LONG lResult;
  398. HRESULT hr;
  399. TraceMsg( L"-->CMuxPhysicalAdapter::ApplyRegistryChanges.\n" );
  400. //
  401. // Open/create and then close the registry key to ensure that it does exist.
  402. //
  403. StringFromGUID2( m_guidAdapter,
  404. szAdapterGuid,
  405. MAX_PATH+1 );
  406. lResult = RegCreateKeyExW( HKEY_LOCAL_MACHINE,
  407. c_szAdapterList,
  408. 0,
  409. NULL,
  410. REG_OPTION_NON_VOLATILE,
  411. KEY_ALL_ACCESS,
  412. NULL,
  413. &hkeyAdapterList,
  414. &dwDisp);
  415. if ( lResult == ERROR_SUCCESS ) {
  416. lResult = RegCreateKeyExW( hkeyAdapterList,
  417. szAdapterGuid,
  418. 0,
  419. NULL,
  420. REG_OPTION_NON_VOLATILE,
  421. KEY_ALL_ACCESS,
  422. NULL,
  423. &hkeyAdapterGuid,
  424. &dwDisp);
  425. if ( lResult == ERROR_SUCCESS ) {
  426. RegCloseKey( hkeyAdapterGuid );
  427. }
  428. else {
  429. TraceMsg( L" Failed to create/open the registry key: %s\\%s.\n",
  430. c_szAdapterList, szAdapterGuid );
  431. }
  432. RegCloseKey( hkeyAdapterList );
  433. }
  434. else {
  435. TraceMsg( L" Failed to open the registry key: %s.\n",
  436. c_szAdapterList );
  437. }
  438. //
  439. // Update the registry in case there were new miniports installed.
  440. //
  441. hr = HRESULT_FROM_WIN32( lResult );
  442. dwMiniportCount = m_MiniportsToAdd.ListCount();
  443. TraceMsg( L" Applying registry changes when %d miniports added.\n",
  444. dwMiniportCount );
  445. for (i=0; i < dwMiniportCount; ++i) {
  446. m_MiniportsToAdd.Find( i,
  447. &pMiniport );
  448. //
  449. // Do virtual miniport specific registry changes.
  450. //
  451. // We need to tell the miniport instance explicitly what the action
  452. // is.
  453. //
  454. hr = pMiniport->ApplyRegistryChanges( eActAdd );
  455. if ( hr != S_OK ) {
  456. TraceMsg( L" Failed to apply registry changes to miniport(%d).\n",
  457. i );
  458. }
  459. }
  460. //
  461. // Update the registry in case one or more miniports were uninstalled.
  462. //
  463. dwMiniportCount = m_MiniportsToRemove.ListCount();
  464. TraceMsg( L" Applying registry changes when %d miniports removed.\n",
  465. dwMiniportCount );
  466. for (i=0; i < dwMiniportCount; ++i) {
  467. m_MiniportsToRemove.Find( i,
  468. &pMiniport );
  469. //
  470. // Do virtual miniport specific registry changes.
  471. //
  472. // We need to tell the miniport instance explicitly what the action
  473. // is.
  474. //
  475. hr = pMiniport->ApplyRegistryChanges( eActRemove );
  476. if ( hr != S_OK ) {
  477. TraceMsg( L" Failed to apply registry changes to miniport(%d).\n",
  478. i );
  479. }
  480. }
  481. //
  482. // If the adapter is being removed or the protocol is being uninstalled,
  483. // delete the adatper registry key.
  484. //
  485. if ( eApplyAction == eActRemove ) {
  486. //
  487. // Delete the adapter key.
  488. //
  489. lResult = RegCreateKeyExW( HKEY_LOCAL_MACHINE,
  490. c_szAdapterList,
  491. 0,
  492. NULL,
  493. REG_OPTION_NON_VOLATILE,
  494. KEY_ALL_ACCESS,
  495. NULL,
  496. &hkeyAdapterList,
  497. &dwDisp);
  498. if ( lResult == ERROR_SUCCESS ) {
  499. TraceMsg( L" Deleting the registry key: %s.\n", szAdapterGuid );
  500. RegDeleteKeyW( hkeyAdapterList,
  501. szAdapterGuid );
  502. }
  503. }
  504. TraceMsg( L"<--CMuxPhysicalAdapter::ApplyRegistryChanges(HRESULT = %x).\n",
  505. S_OK );
  506. return S_OK;
  507. }
  508. //+---------------------------------------------------------------------------
  509. //
  510. // Function: CMuxPhysicalAdapter::ApplyPnpChanges
  511. //
  512. // Purpose: Apply the PnP changes depending on the actions performed.
  513. //
  514. // Arguments:
  515. // IN pfCallback : SendPnpConfig Callback interface.
  516. // IN eApplyAction: Action that was last performed.
  517. //
  518. //
  519. // Returns: S_OK.
  520. //
  521. // Notes:
  522. // More than one action could have been performed by the user
  523. // but this function is called only once at the end. So, the argument
  524. // only denotes the very last action performed. For example, if the
  525. // user deletes one miniport and adds two miniports then, the argument
  526. // will denote an add action.
  527. //
  528. HRESULT CMuxPhysicalAdapter::ApplyPnpChanges(
  529. INetCfgPnpReconfigCallback *pfCallback,
  530. ConfigAction eApplyAction)
  531. {
  532. CMuxVirtualMiniport *pMiniport;
  533. GUID guidMiniport;
  534. WCHAR szMiniportGuid[MAX_PATH+1];
  535. LPWSTR lpDevice;
  536. DWORD dwMiniportCount;
  537. DWORD i;
  538. DWORD dwBytes;
  539. INetCfgComponent *pncc;
  540. HRESULT hr;
  541. #ifdef CUSTOM_EVENTS
  542. LPWSTR lpszBindName;
  543. PNOTIFY_CUSTOM_EVENT lppnpEvent;
  544. #endif
  545. TraceMsg( L"-->CMuxPhysicalAdapter::ApplyPnpChanges.\n" );
  546. #ifdef CUSTOM_EVENTS
  547. //
  548. // Find the instance of the adapter to get its bindname.
  549. //
  550. hr = HrFindInstance( m_pnc,
  551. m_guidAdapter,
  552. &pncc );
  553. if ( hr == S_OK ) {
  554. hr = pncc->GetBindName( &lpszBindName );
  555. if ( hr != S_OK ) {
  556. TraceMsg( L" GetBindName failed.(HRESULT = %x). PnP changes will not "
  557. L"be applied and the driver will not be notified.\n",
  558. hr );
  559. }
  560. ReleaseObj( pncc );
  561. }
  562. else {
  563. TraceMsg( L" PnP changes will not "
  564. L"be applied and the driver will not be notified.\n",
  565. hr );
  566. }
  567. #endif
  568. dwMiniportCount = m_MiniportsToAdd.ListCount();
  569. TraceMsg( L" Applying PnP changes to %d new miniports.\n",
  570. dwMiniportCount );
  571. for (i=0; i < dwMiniportCount; ++i) {
  572. m_MiniportsToAdd.Remove( &pMiniport );
  573. pMiniport->GetMiniportGUID( &guidMiniport );
  574. m_MiniportList.Insert( pMiniport,
  575. guidMiniport );
  576. //
  577. // Do miniport specific Pnp Changes when they are added.
  578. //
  579. hr = pMiniport->ApplyPnpChanges( pfCallback,
  580. eActAdd );
  581. #ifdef CUSTOM_EVENTS
  582. //
  583. // Notify the driver that one or more virtual miniports have been added.
  584. //
  585. StringFromGUID2( guidMiniport,
  586. szMiniportGuid,
  587. MAX_PATH+1 );
  588. lpDevice = AddDevicePrefix( szMiniportGuid );
  589. if ( lpDevice ) {
  590. dwBytes = sizeof(NOTIFY_CUSTOM_EVENT) +
  591. ((wcslen(lpDevice) + 1) * sizeof(WCHAR));
  592. lppnpEvent = (PNOTIFY_CUSTOM_EVENT)malloc( dwBytes );
  593. if ( lppnpEvent ) {
  594. lppnpEvent->uSignature = NOTIFY_SIGNATURE;
  595. lppnpEvent->uEvent = MUX_CUSTOM_EVENT;
  596. wcscpy( lppnpEvent->szMiniport,
  597. lpDevice );
  598. hr = pfCallback->SendPnpReconfig( NCRL_NDIS,
  599. c_szMuxService,
  600. lpszBindName,
  601. (PVOID)lppnpEvent,
  602. dwBytes );
  603. TraceMsg( L" INetCfgPnpReconfigCallback->SendPnpReconfig returned "
  604. L"%#x.\n",
  605. hr );
  606. if ( hr != S_OK ) {
  607. TraceMsg( L" Failed to apply Pnp changes, miniport(%d).\n",
  608. i );
  609. }
  610. free( lppnpEvent );
  611. }
  612. free( lpDevice );
  613. }
  614. #endif
  615. }
  616. dwMiniportCount = m_MiniportsToRemove.ListCount();
  617. TraceMsg( L" Applying PnP changes to %d removed miniports.\n",
  618. dwMiniportCount );
  619. for (i=0; i < dwMiniportCount; ++i) {
  620. m_MiniportsToRemove.Remove( &pMiniport );
  621. pMiniport->GetMiniportGUID( &guidMiniport );
  622. //
  623. // Do miniport specific Pnp Changes when they are uninstalled.
  624. //
  625. hr = pMiniport->ApplyPnpChanges( pfCallback,
  626. eActRemove );
  627. delete pMiniport;
  628. #ifdef CUSTOM_EVENTS
  629. //
  630. // Notify the driver that one or more virtual miniports have been
  631. // uninstalled.
  632. //
  633. // We can't notify the driver in case the adapter or the protocol is
  634. // being uninstalled because the binding handle doesn't exist.
  635. //
  636. if ( eApplyAction != eActRemove ) {
  637. StringFromGUID2( guidMiniport,
  638. szMiniportGuid,
  639. MAX_PATH+1 );
  640. lpDevice = AddDevicePrefix( szMiniportGuid );
  641. if ( lpDevice ) {
  642. dwBytes = sizeof(NOTIFY_CUSTOM_EVENT) +
  643. ((wcslen(lpDevice) + 1) * sizeof(WCHAR));
  644. lppnpEvent = (PNOTIFY_CUSTOM_EVENT)malloc( dwBytes );
  645. if ( lppnpEvent ) {
  646. lppnpEvent->uSignature = NOTIFY_SIGNATURE;
  647. lppnpEvent->uEvent = MUX_CUSTOM_EVENT;
  648. wcscpy( lppnpEvent->szMiniport,
  649. lpDevice );
  650. hr = pfCallback->SendPnpReconfig( NCRL_NDIS,
  651. c_szMuxService,
  652. lpszBindName,
  653. (PVOID)lppnpEvent,
  654. dwBytes );
  655. TraceMsg( L" INetCfgPnpReconfigCallback->SendPnpReconfig returned "
  656. L"%#x.\n",
  657. hr );
  658. if ( hr != S_OK ) {
  659. TraceMsg( L" Failed to apply Pnp changes, miniport(%d).\n",
  660. i );
  661. }
  662. free( lppnpEvent );
  663. }
  664. free( lpDevice );
  665. }
  666. }
  667. #endif
  668. }
  669. #ifdef CUSTOM_EVENTS
  670. CoTaskMemFree( lpszBindName );
  671. #endif
  672. TraceMsg( L"<--CMuxPhysicalAdapter::ApplyPnpChanges(HRESULT = %x).\n",
  673. S_OK );
  674. return S_OK;
  675. }
  676. //+---------------------------------------------------------------------------
  677. //
  678. // Function: CMuxPhysicalAdapter::CancelChanges
  679. //
  680. // Purpose: Cancel any changes made.
  681. //
  682. // Arguments: None
  683. //
  684. //
  685. // Returns: S_OK.
  686. //
  687. // Notes:
  688. //
  689. HRESULT CMuxPhysicalAdapter::CancelChanges (VOID)
  690. {
  691. TraceMsg( L"-->CMuxPhysicalAdapter::CancelChanges.\n" );
  692. TraceMsg( L"<--CMuxPhysicalAdapter::CancelChanges(HRESULT = %x).\n",
  693. S_OK );
  694. return S_OK;
  695. }
  696. //+---------------------------------------------------------------------------
  697. //
  698. // Function: CMuxPhysicalAdapter::AllMiniportsRemoved
  699. //
  700. // Purpose: Find out if there is no miniport installed on the adapter.
  701. //
  702. // Arguments: None
  703. //
  704. //
  705. // Returns: TRUE if all the miniports associated with this adapter have been
  706. // uninstalled and there is none pending to be added, otherwise FALSE.
  707. //
  708. // Notes:
  709. //
  710. BOOL CMuxPhysicalAdapter::AllMiniportsRemoved (VOID)
  711. {
  712. return (m_MiniportList.ListCount() + m_MiniportsToAdd.ListCount()) == 0;
  713. }