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.

1922 lines
51 KiB

  1. //----------------------------------------------------------------------------
  2. //
  3. // Copyright (c) 1997-1999 Microsoft Corporation
  4. // All rights reserved.
  5. //
  6. // File Name:
  7. // netreg.cpp
  8. //
  9. // Description:
  10. // This file contains the calls to the Network Component Object interfaces
  11. // to find out what network clients, services and protocols are installed
  12. // on the current machine and what their settings are.
  13. //
  14. //----------------------------------------------------------------------------
  15. #include "pch.h"
  16. #include "netreg.h"
  17. //
  18. // Constants
  19. //
  20. const static INT MAX_GUID_STRING = 40;
  21. const static INT MAX_NUM_NET_COMPONENTS = 128;
  22. const static INT BUFFER_SIZE = 4096;
  23. //
  24. // Registry fields used to read settings for network components
  25. //
  26. const static TCHAR REGVAL_DOMAIN[] = _T("Domain");
  27. const static TCHAR REGVAL_INTERFACES[] = _T("Interfaces");
  28. const static TCHAR REGVAL_ENABLE_DHCP[] = _T("EnableDHCP");
  29. const static TCHAR REGVAL_IPADDRESS[] = _T("IPAddress");
  30. const static TCHAR REGVAL_SUBNETMASK[] = _T("SubnetMask");
  31. const static TCHAR REGVAL_DEFAULTGATEWAY[] = _T("DefaultGateway");
  32. const static TCHAR REGVAL_NAMESERVER[] = _T("NameServer");
  33. const static TCHAR REGVAL_WINS[] = _T("SYSTEM\\CurrentControlSet\\Services\\NetBT\\Parameters\\Interfaces\\Tcpip_");
  34. const static TCHAR REGVAL_NAMESERVERLIST[] = _T("NameServerList");
  35. const static TCHAR REGKEY_MSCLIENT_LOCATION[] = _T("SOFTWARE\\Microsoft\\Rpc\\NameService");
  36. const static TCHAR REGVAL_NAME_SERVICE_PROVIDER[] = _T("Protocol");
  37. const static TCHAR REGVAL_NETWORK_ADDRESS[] = _T("NetworkAddress");
  38. const static TCHAR REGVAL_ADAPTERS[] = _T("Adapters");
  39. const static TCHAR REGVAL_PKT_TYPE[] = _T("PktType");
  40. const static TCHAR REGVAL_NETWORK_NUMBER[] = _T("NetworkNumber");
  41. const static TCHAR REGVAL_VIRTUAL_NETWORK_NUMBER[] = _T("VirtualNetworkNumber");
  42. //----------------------------------------------------------------------------
  43. //
  44. // Function: ReadNetworkRegistrySettings
  45. //
  46. // Purpose: In general, this function reads in all the necessary networking
  47. // settings and sets the internal variables appropriately. This includes
  48. // determining how many network adapters there are, what
  49. // client/services/protocols are installed and loading their individual
  50. // settings.
  51. //
  52. // When reads from the registry fail, it just moves on to try and get the
  53. // next setting. The failed one is just left with its default. In this
  54. // way if just one registry entry is broken all the other data will be
  55. // obtained rather than just quiting the function.
  56. //
  57. // Arguments: VOID
  58. //
  59. // Returns: HRESULT returns status of success or failure of the function
  60. //
  61. //----------------------------------------------------------------------------
  62. EXTERN_C HRESULT
  63. ReadNetworkRegistrySettings( VOID )
  64. {
  65. HRESULT hr = S_OK;
  66. INetCfg* pNetCfg = NULL;
  67. //
  68. // Always force a Custom net setting if they are reading from the registry
  69. // because I don't want to write the code to see if their current net
  70. // configuration is a typical one (when 99.9% of the time it won't be)
  71. //
  72. NetSettings.iNetworkingMethod = CUSTOM_NETWORKING;
  73. hr = InitializeInterfaces( &pNetCfg );
  74. if( FAILED( hr ) )
  75. {
  76. return( E_FAIL );
  77. }
  78. hr = GetNetworkAdapterSettings( pNetCfg );
  79. if( FAILED( hr ) )
  80. {
  81. ReleaseInterfaces( pNetCfg );
  82. return( E_FAIL );
  83. }
  84. //
  85. // Purposely not catching return values here. Call each one to try and
  86. // grab as many parameters as we can. If we hit an error just move on
  87. // and try to grab the next value.
  88. //
  89. GetClientsInstalled( pNetCfg );
  90. GetServicesInstalled( pNetCfg );
  91. GetProtocolsInstalled( pNetCfg );
  92. ReleaseInterfaces( pNetCfg );
  93. GetDomainOrWorkgroup();
  94. return( S_OK );
  95. }
  96. //----------------------------------------------------------------------------
  97. //
  98. // Function: GetNetworkAdapterSettings
  99. //
  100. // Purpose: Determines how many network cards are installed and gets there
  101. // PnP Ids. It then stores these in the appropriate global variables.
  102. //
  103. // Arguments: INetCfg *pNetCfg - pointer to a NetCfg object that is already
  104. // created and initialized
  105. //
  106. // Returns: HRESULT returns status of success or failure of the function
  107. //
  108. //----------------------------------------------------------------------------
  109. static HRESULT
  110. GetNetworkAdapterSettings( INetCfg *pNetCfg )
  111. {
  112. UINT i;
  113. INetCfgComponent* arrayComp[MAX_NUM_NET_COMPONENTS];
  114. IEnumNetCfgComponent* pEnum = NULL;
  115. INetCfgClass* pNetCfgClass = NULL;
  116. INetCfgComponent* pNetCfgComp = NULL;
  117. NETWORK_ADAPTER_NODE* pPreviousNode = NULL;
  118. NETWORK_ADAPTER_NODE* pCurrentNode = NULL;
  119. HRESULT hr = S_OK;
  120. DWORD dwCharacteristics = 0;
  121. ULONG iCount = 0;
  122. hr = InitializeComInterface( &GUID_DEVCLASS_NET,
  123. pNetCfg,
  124. pNetCfgClass,
  125. pEnum,
  126. arrayComp,
  127. &iCount );
  128. if( FAILED( hr ) )
  129. {
  130. return( hr );
  131. }
  132. //
  133. // delete the entire list of Network Adapters so we can start fresh
  134. //
  135. DeleteList( NetSettings.NetworkAdapterHead );
  136. NetSettings.NetworkAdapterHead = NULL;
  137. NetSettings.iNumberOfNetworkCards = 0;
  138. AssertMsg( iCount <= MAX_NUM_NET_COMPONENTS,
  139. "Too many network components to work with" );
  140. for( i = 0; i < iCount; i++ )
  141. {
  142. pNetCfgComp = arrayComp[i];
  143. hr = ChkInterfacePointer( pNetCfgComp, IID_INetCfgComponent );
  144. if( FAILED( hr ) )
  145. {
  146. UninitializeComInterface( pNetCfgClass,
  147. pEnum );
  148. return( hr );
  149. }
  150. hr = pNetCfgComp->GetCharacteristics( &dwCharacteristics );
  151. if( FAILED( hr ) )
  152. {
  153. UninitializeComInterface( pNetCfgClass,
  154. pEnum );
  155. return( hr );
  156. }
  157. //
  158. // If this is a physical adapter
  159. //
  160. if( dwCharacteristics & NCF_PHYSICAL )
  161. {
  162. NetSettings.iNumberOfNetworkCards++;
  163. hr = SetupAdapter( &pCurrentNode,
  164. pNetCfgComp );
  165. if( FAILED( hr ) )
  166. {
  167. UninitializeComInterface( pNetCfgClass,
  168. pEnum );
  169. return( hr );
  170. }
  171. //
  172. // Adjust pointers to maintain the doubly linked-list
  173. //
  174. pCurrentNode->previous = pPreviousNode;
  175. if( pPreviousNode != NULL )
  176. {
  177. pPreviousNode->next = pCurrentNode;
  178. }
  179. pPreviousNode = pCurrentNode;
  180. }
  181. if( pNetCfgComp )
  182. {
  183. pNetCfgComp->Release();
  184. }
  185. }
  186. //
  187. // if there is a network card in this machine, set the current network card
  188. // to be the first one, else zero out the values
  189. //
  190. if( NetSettings.iNumberOfNetworkCards > 0 )
  191. {
  192. NetSettings.iCurrentNetworkCard = 1;
  193. NetSettings.pCurrentAdapter = NetSettings.NetworkAdapterHead;
  194. }
  195. else
  196. {
  197. NetSettings.iCurrentNetworkCard = 0;
  198. NetSettings.NetworkAdapterHead = NULL;
  199. NetSettings.pCurrentAdapter = NULL;
  200. }
  201. UninitializeComInterface( pNetCfgClass,
  202. pEnum );
  203. return( S_OK );
  204. }
  205. //----------------------------------------------------------------------------
  206. //
  207. // Function: GetClientsInstalled
  208. //
  209. // Purpose: For each client, it finds out if it is installed on the current
  210. // system and if it is then it reads its settings from the registry
  211. //
  212. // Arguments: INetCfg *pNetCfg - pointer to a NetCfg object that is already
  213. // created and initialized
  214. //
  215. // Returns: HRESULT returns status of success or failure of the function
  216. //
  217. //----------------------------------------------------------------------------
  218. static HRESULT
  219. GetClientsInstalled( INetCfg *pNetCfg )
  220. {
  221. INetCfgComponent* arrayComp[MAX_NUM_NET_COMPONENTS];
  222. IEnumNetCfgComponent* pEnum = NULL;
  223. INetCfgClass* pNetCfgClass = NULL;
  224. INetCfgComponent* pNetCfgComp = NULL;
  225. HRESULT hr = S_OK;
  226. ULONG iCount = 0;
  227. LPWSTR pszwDisplayName = NULL;
  228. HKEY hKey;
  229. UINT i;
  230. NETWORK_COMPONENT* pMsClientComponent = NULL;
  231. NETWORK_COMPONENT* pNetwareComponent = NULL;
  232. //
  233. // Initialize each of the pointers to point into its proper place in the
  234. // global network component list
  235. //
  236. pMsClientComponent = FindNode( MS_CLIENT_POSITION );
  237. pNetwareComponent = FindNode( NETWARE_CLIENT_POSITION );
  238. hr = InitializeComInterface( &GUID_DEVCLASS_NETCLIENT,
  239. pNetCfg,
  240. pNetCfgClass,
  241. pEnum,
  242. arrayComp,
  243. &iCount );
  244. if( FAILED( hr ) )
  245. {
  246. return( hr );
  247. }
  248. for( i = 0; i < iCount; i++ )
  249. {
  250. pNetCfgComp = arrayComp[i];
  251. hr = ChkInterfacePointer( pNetCfgComp,
  252. IID_INetCfgComponent );
  253. if( FAILED( hr ) )
  254. {
  255. UninitializeComInterface( pNetCfgClass,
  256. pEnum );
  257. return( hr );
  258. }
  259. hr = pNetCfgComp->GetDisplayName( &pszwDisplayName );
  260. if( FAILED( hr ) )
  261. {
  262. UninitializeComInterface( pNetCfgClass,
  263. pEnum );
  264. return( hr );
  265. }
  266. if( lstrcmpi( pMsClientComponent->StrComponentName, pszwDisplayName ) == 0 )
  267. {
  268. //
  269. // set the component to Installed
  270. //
  271. pMsClientComponent->bInstalled = TRUE;
  272. hr = pNetCfgComp->OpenParamKey( &hKey );
  273. if( FAILED( hr ) )
  274. {
  275. UninitializeComInterface( pNetCfgClass,
  276. pEnum );
  277. return( hr );
  278. }
  279. //
  280. // grab Ms Client settings from the registry
  281. //
  282. ReadMsClientSettingsFromRegistry( &hKey );
  283. RegCloseKey( hKey );
  284. }
  285. else if( lstrcmpi( pNetwareComponent->StrComponentName, pszwDisplayName ) == 0 )
  286. {
  287. //
  288. // set the component to Installed
  289. //
  290. pNetwareComponent->bInstalled = TRUE;
  291. hr = pNetCfgComp->OpenParamKey( &hKey );
  292. if( FAILED( hr ) )
  293. {
  294. UninitializeComInterface( pNetCfgClass,
  295. pEnum );
  296. return( hr );
  297. }
  298. //
  299. // grab Netware settings from the registry
  300. //
  301. ReadNetwareSettingsFromRegistry( &hKey );
  302. RegCloseKey( hKey );
  303. }
  304. CoTaskMemFree( pszwDisplayName );
  305. if( pNetCfgComp ) {
  306. pNetCfgComp->Release();
  307. }
  308. }
  309. UninitializeComInterface( pNetCfgClass,
  310. pEnum );
  311. return( S_OK );
  312. }
  313. //----------------------------------------------------------------------------
  314. //
  315. // Function: GetServicesInstalled
  316. //
  317. // Purpose: For each service, it finds out if it is installed on the current
  318. // system and if it is then it sets its component to Installed = TRUE
  319. //
  320. // Arguments: INetCfg *pNetCfg - pointer to a NetCfg object that is already
  321. // created and initialized
  322. //
  323. // Returns: HRESULT returns status of success or failure of the function
  324. //
  325. //----------------------------------------------------------------------------
  326. static HRESULT
  327. GetServicesInstalled( INetCfg *pNetCfg )
  328. {
  329. INetCfgComponent* arrayComp[MAX_NUM_NET_COMPONENTS];
  330. IEnumNetCfgComponent* pEnum = NULL;
  331. INetCfgClass* pNetCfgClass = NULL;
  332. INetCfgComponent* pNetCfgComp = NULL;
  333. LPWSTR pszwDisplayName = NULL;
  334. HRESULT hr = S_OK;
  335. ULONG iCount = 0;
  336. UINT i;
  337. NETWORK_COMPONENT* pFilePrintSharingComponent = NULL;
  338. NETWORK_COMPONENT* pPacketSchedulingComponent = NULL;
  339. //
  340. // Initialize each of the pointers to point into its proper place in the
  341. // global network component list
  342. //
  343. pFilePrintSharingComponent = FindNode( FILE_AND_PRINT_SHARING_POSITION );
  344. pPacketSchedulingComponent = FindNode( PACKET_SCHEDULING_POSITION );
  345. hr = InitializeComInterface( &GUID_DEVCLASS_NETCLIENT,
  346. pNetCfg,
  347. pNetCfgClass,
  348. pEnum,
  349. arrayComp,
  350. &iCount );
  351. if( FAILED( hr ) )
  352. {
  353. return( hr );
  354. }
  355. for( i = 0; i < iCount; i++ )
  356. {
  357. pNetCfgComp = arrayComp[i];
  358. hr = ChkInterfacePointer( pNetCfgComp,
  359. IID_INetCfgComponent );
  360. if( FAILED( hr ) )
  361. {
  362. UninitializeComInterface( pNetCfgClass,
  363. pEnum );
  364. return( hr );
  365. }
  366. hr = pNetCfgComp->GetDisplayName( &pszwDisplayName );
  367. if( FAILED( hr ) )
  368. {
  369. UninitializeComInterface( pNetCfgClass,
  370. pEnum );
  371. return( hr );
  372. }
  373. if( lstrcmpi( pFilePrintSharingComponent->StrComponentName, pszwDisplayName ) == 0 )
  374. {
  375. //
  376. // only have to set the component to Installed, no settings to read
  377. //
  378. pFilePrintSharingComponent->bInstalled = TRUE;
  379. }
  380. else if( lstrcmpi( pPacketSchedulingComponent->StrComponentName, pszwDisplayName ) == 0 )
  381. {
  382. //
  383. // only have to set the component to Installed, no settings to read
  384. //
  385. pPacketSchedulingComponent->bInstalled = TRUE;
  386. }
  387. CoTaskMemFree( pszwDisplayName );
  388. if( pNetCfgComp ) {
  389. pNetCfgComp->Release();
  390. }
  391. }
  392. UninitializeComInterface( pNetCfgClass,
  393. pEnum );
  394. return( S_OK );
  395. }
  396. //----------------------------------------------------------------------------
  397. //
  398. // Function: GetProtocolsInstalled
  399. //
  400. // Purpose: For each protocol, it finds out if it is installed on the current
  401. // system and if it is then it reads its settings from the registry
  402. //
  403. // Arguments: INetCfg *pNetCfg - pointer to a NetCfg object that is already
  404. // created and initialized
  405. //
  406. // Returns: HRESULT returns status of success or failure of the function
  407. //
  408. //----------------------------------------------------------------------------
  409. static HRESULT
  410. GetProtocolsInstalled( INetCfg *pNetCfg )
  411. {
  412. INetCfgComponent* arrayComp[MAX_NUM_NET_COMPONENTS];
  413. IEnumNetCfgComponent* pEnum = NULL;
  414. INetCfgClass* pNetCfgClass = NULL;
  415. INetCfgComponent* pNetCfgComp = NULL;
  416. LPWSTR pszwDisplayName = NULL;
  417. HKEY hKey = NULL;
  418. HRESULT hr = S_OK;
  419. ULONG iCount = 0;
  420. UINT i;
  421. NETWORK_COMPONENT* pTcpipComponent = NULL;
  422. NETWORK_COMPONENT* pIpxComponent = NULL;
  423. NETWORK_COMPONENT* pNetBeuiComponent = NULL;
  424. NETWORK_COMPONENT* pDlcComponent = NULL;
  425. NETWORK_COMPONENT* pNetworkMonitorComponent = NULL;
  426. NETWORK_COMPONENT* pAppletalkComponent = NULL;
  427. //
  428. // Initialize each of the pointers to point into its proper place in the
  429. // global network component list
  430. //
  431. pTcpipComponent = FindNode( TCPIP_POSITION );
  432. pIpxComponent = FindNode( IPX_POSITION );
  433. pNetBeuiComponent = FindNode( NETBEUI_POSITION );
  434. pDlcComponent = FindNode( DLC_POSITION );
  435. pNetworkMonitorComponent = FindNode( NETWORK_MONITOR_AGENT_POSITION );
  436. pAppletalkComponent = FindNode( APPLETALK_POSITION );
  437. hr = InitializeComInterface( &GUID_DEVCLASS_NETTRANS,
  438. pNetCfg,
  439. pNetCfgClass,
  440. pEnum,
  441. arrayComp,
  442. &iCount );
  443. if( FAILED( hr ) )
  444. {
  445. return( hr );
  446. }
  447. for( i = 0; i < iCount; i++ )
  448. {
  449. pNetCfgComp = arrayComp[i];
  450. hr = ChkInterfacePointer( pNetCfgComp,
  451. IID_INetCfgComponent );
  452. if( FAILED( hr ) )
  453. {
  454. UninitializeComInterface( pNetCfgClass,
  455. pEnum );
  456. return( hr );
  457. }
  458. hr = pNetCfgComp->GetDisplayName( &pszwDisplayName );
  459. if( FAILED( hr ) )
  460. {
  461. UninitializeComInterface( pNetCfgClass,
  462. pEnum );
  463. return( hr );
  464. }
  465. if( lstrcmpi( pTcpipComponent->StrComponentName, pszwDisplayName ) == 0 )
  466. {
  467. //
  468. // set the component to Installed
  469. //
  470. pTcpipComponent->bInstalled = TRUE;
  471. hr = pNetCfgComp->OpenParamKey( &hKey );
  472. if( SUCCEEDED( hr ) )
  473. {
  474. //
  475. // grab TCP/IP settings from the registry
  476. //
  477. ReadTcpipSettingsFromRegistry( &hKey );
  478. }
  479. RegCloseKey( hKey );
  480. }
  481. else if( lstrcmpi( pIpxComponent->StrComponentName, pszwDisplayName ) == 0 )
  482. {
  483. //
  484. // set the component to Installed
  485. //
  486. pIpxComponent->bInstalled = TRUE;
  487. hr = pNetCfgComp->OpenParamKey( &hKey );
  488. if( SUCCEEDED( hr ) )
  489. {
  490. // grab IPX settings from the registry
  491. ReadIpxSettingsFromRegistry( &hKey );
  492. }
  493. RegCloseKey( hKey );
  494. }
  495. else if( lstrcmpi( pNetBeuiComponent->StrComponentName, pszwDisplayName ) == 0 )
  496. {
  497. //
  498. // only have to set the component to Installed, no settings to read
  499. //
  500. pNetBeuiComponent->bInstalled = TRUE;
  501. }
  502. else if( lstrcmpi( pDlcComponent->StrComponentName, pszwDisplayName ) == 0 )
  503. {
  504. //
  505. // only have to set the component to Installed, no settings to read
  506. //
  507. pDlcComponent->bInstalled = TRUE;
  508. }
  509. else if( lstrcmpi( pNetworkMonitorComponent->StrComponentName, pszwDisplayName ) == 0 )
  510. {
  511. //
  512. // only have to set the component to Installed, no settings to read
  513. //
  514. pNetworkMonitorComponent->bInstalled = TRUE;
  515. }
  516. else if( lstrcmpi( pAppletalkComponent->StrComponentName, pszwDisplayName ) == 0 )
  517. {
  518. //
  519. // set the component to Installed
  520. //
  521. pAppletalkComponent->bInstalled = TRUE;
  522. hr = pNetCfgComp->OpenParamKey( &hKey );
  523. if( SUCCEEDED( hr ) )
  524. {
  525. // grab Appletalk settings from the registry
  526. ReadAppletalkSettingsFromRegistry( &hKey );
  527. }
  528. RegCloseKey( hKey );
  529. }
  530. CoTaskMemFree( pszwDisplayName );
  531. if( pNetCfgComp ) {
  532. pNetCfgComp->Release();
  533. }
  534. }
  535. UninitializeComInterface( pNetCfgClass,
  536. pEnum );
  537. return( S_OK );
  538. }
  539. //----------------------------------------------------------------------------
  540. //
  541. // Function: GetDomainOrWorkgroup
  542. //
  543. // Purpose: Find out if this machine is a member of a workgroup or domain and
  544. // then fill the global structs with the proper name.
  545. //
  546. // Arguments: VOID
  547. //
  548. // Returns: VOID
  549. //
  550. //----------------------------------------------------------------------------
  551. static VOID
  552. GetDomainOrWorkgroup( VOID )
  553. {
  554. BOOL bDomain = FALSE;
  555. TCHAR szDomainOrWorkgroup[MAX_WORKGROUP_LENGTH + 1] = _T("");
  556. //
  557. // Get the domain/workgoup
  558. //
  559. if( LSA_SUCCESS( GetDomainMembershipInfo( &bDomain, szDomainOrWorkgroup ) ) )
  560. {
  561. if( bDomain )
  562. {
  563. lstrcpyn( NetSettings.DomainName, szDomainOrWorkgroup, AS(NetSettings.DomainName) );
  564. NetSettings.bWorkgroup = FALSE;
  565. }
  566. else
  567. {
  568. lstrcpyn( NetSettings.WorkGroupName, szDomainOrWorkgroup, AS(NetSettings.WorkGroupName) );
  569. NetSettings.bWorkgroup = TRUE;
  570. }
  571. }
  572. }
  573. //----------------------------------------------------------------------------
  574. //
  575. // Function: SetupAdapter
  576. //
  577. // Purpose: Allocates and initializes a new Network adapter struct, then reads
  578. // the adapter's PnP Id and it's GUID.
  579. //
  580. // Arguments:
  581. //
  582. // Returns: HRESULT returns status of success or failure of the function
  583. // On failure, the caller of this function is responsible for calling
  584. // UninitializeComInterface()
  585. //----------------------------------------------------------------------------
  586. static HRESULT
  587. SetupAdapter( NETWORK_ADAPTER_NODE **ppCurrentNode,
  588. INetCfgComponent *pNetCfgComp )
  589. {
  590. HRESULT hr = S_OK;
  591. LPWSTR pszwPnPID = NULL;
  592. *ppCurrentNode = (NETWORK_ADAPTER_NODE *)malloc( sizeof( NETWORK_ADAPTER_NODE ) );
  593. if (*ppCurrentNode == NULL)
  594. return (E_FAIL);
  595. //
  596. // Initialize all the Network namelists to 0s
  597. //
  598. ZeroOut( *ppCurrentNode );
  599. //
  600. // Set all network card settings to their default values
  601. //
  602. ResetNetworkAdapter( *ppCurrentNode );
  603. if( NetSettings.iNumberOfNetworkCards == 1 )
  604. {
  605. NetSettings.NetworkAdapterHead = *ppCurrentNode;
  606. }
  607. //
  608. // Get the Plug and Play Id
  609. //
  610. hr = pNetCfgComp->GetId( &pszwPnPID );
  611. if( SUCCEEDED( hr ) )
  612. {
  613. hr=StringCchCopy( (*ppCurrentNode)->szPlugAndPlayID, AS((*ppCurrentNode)->szPlugAndPlayID), pszwPnPID );
  614. CoTaskMemFree( pszwPnPID );
  615. }
  616. //
  617. // Get the Guid for this network adapter
  618. //
  619. hr = pNetCfgComp->GetInstanceGuid( &((*ppCurrentNode)->guid) );
  620. if( FAILED( hr ) )
  621. {
  622. //
  623. // this call failed so any call to the registry will fail since it
  624. // needs this guid
  625. //
  626. return( hr );
  627. }
  628. return( S_OK );
  629. }
  630. //----------------------------------------------------------------------------
  631. //
  632. // Function: ReadNetwareSettingsFromRegistry
  633. //
  634. // Purpose: Read in registry settings on Netware and fill the global structs
  635. // with the appropriate values
  636. //
  637. // Arguments: HKEY *hKey
  638. //
  639. // Returns: HRESULT returns status of success or failure of the function
  640. //
  641. //----------------------------------------------------------------------------
  642. static VOID
  643. ReadNetwareSettingsFromRegistry( IN HKEY *hKey )
  644. {
  645. REGSAM SecurityAccess = KEY_QUERY_VALUE;
  646. // ISSUE-2002/02/28-stelo- write this function
  647. }
  648. //----------------------------------------------------------------------------
  649. //
  650. // Function: ReadMsClientSettingsFromRegistry
  651. //
  652. // Purpose: Read in registry settings on MS Client and fill the global structs
  653. // with the appropriate values
  654. //
  655. // Arguments: HKEY *hKey
  656. //
  657. // Returns: HRESULT returns status of success or failure of the function
  658. //
  659. //----------------------------------------------------------------------------
  660. static VOID
  661. ReadMsClientSettingsFromRegistry( IN HKEY *hKey )
  662. {
  663. HKEY hNameServiceKey = NULL;
  664. REGSAM SecurityAccess = KEY_QUERY_VALUE;
  665. DWORD dwSize = 0;
  666. TCHAR szBuffer[BUFFER_SIZE];
  667. // ISSUE-2002/02/28-stelo- I don't use the hKey passed in. For some reason, the Network
  668. // component objects don't point to the section of the registry I need
  669. // to read from. Is this a bug with Network Component Objects?
  670. dwSize = sizeof( szBuffer );
  671. if( RegOpenKeyEx( HKEY_LOCAL_MACHINE,
  672. REGKEY_MSCLIENT_LOCATION,
  673. 0,
  674. SecurityAccess,
  675. &hNameServiceKey ) != ERROR_SUCCESS )
  676. {
  677. //
  678. // need this key to read in other MS Client values so bail if we
  679. // can't get it
  680. //
  681. return;
  682. }
  683. if( RegQueryValueEx( hNameServiceKey,
  684. REGVAL_NAME_SERVICE_PROVIDER,
  685. NULL,
  686. NULL,
  687. (LPBYTE) szBuffer,
  688. &dwSize ) == ERROR_SUCCESS )
  689. {
  690. if ( LSTRCMPI(szBuffer, _T("ncacn_ip_tcp")) == 0 )
  691. {
  692. NetSettings.NameServiceProvider = MS_CLIENT_DCE_CELL_DIR_SERVICE;
  693. dwSize = sizeof( szBuffer );
  694. if( RegQueryValueEx( hNameServiceKey,
  695. REGVAL_NETWORK_ADDRESS,
  696. 0,
  697. NULL,
  698. (LPBYTE) szBuffer,
  699. &dwSize) == ERROR_SUCCESS )
  700. {
  701. lstrcpyn( NetSettings.szNetworkAddress,
  702. szBuffer,
  703. MAX_NETWORK_ADDRESS_LENGTH + 1 );
  704. }
  705. }
  706. else
  707. {
  708. NetSettings.NameServiceProvider = MS_CLIENT_WINDOWS_LOCATOR;
  709. }
  710. }
  711. RegCloseKey( hNameServiceKey );
  712. }
  713. //----------------------------------------------------------------------------
  714. //
  715. // Function: ReadAppletalkSettingsFromRegistry
  716. //
  717. // Purpose: Read in registry settings on Appletalk and fill the global structs
  718. // with the appropriate values
  719. //
  720. // Arguments: HKEY *hKey
  721. //
  722. // Returns: HRESULT returns status of success or failure of the function
  723. //
  724. //----------------------------------------------------------------------------
  725. static VOID
  726. ReadAppletalkSettingsFromRegistry( IN HKEY *hKey )
  727. {
  728. REGSAM SecurityAccess = KEY_QUERY_VALUE;
  729. // ISSUE-2002/02/28-stelo- write this function
  730. }
  731. //----------------------------------------------------------------------------
  732. //
  733. // Function: ReadIpxSettingsFromRegistry
  734. //
  735. // Purpose: Read in registry settings on IPX and fill the global structs
  736. // with the appropriate values
  737. //
  738. // Arguments: HKEY *hKey
  739. //
  740. // Returns: HRESULT returns status of success or failure of the function
  741. //
  742. //----------------------------------------------------------------------------
  743. static VOID
  744. ReadIpxSettingsFromRegistry( IN HKEY *hKey )
  745. {
  746. REGSAM SecurityAccess = KEY_QUERY_VALUE;
  747. HKEY hIpxAdaptersKey = NULL;
  748. HKEY hNetworkAdapterKey = NULL;
  749. DWORD dwSize = 0;
  750. NETWORK_ADAPTER_NODE *pNetAdapter = NULL;
  751. WCHAR szStringGuid[MAX_GUID_STRING];
  752. TCHAR szBuffer[BUFFER_SIZE];
  753. if( RegOpenKeyEx( *hKey,
  754. REGVAL_ADAPTERS,
  755. 0,
  756. SecurityAccess,
  757. &hIpxAdaptersKey ) != ERROR_SUCCESS )
  758. {
  759. //
  760. // need this key to read in other IPX values so bail if we can't get it
  761. //
  762. return;
  763. }
  764. dwSize = sizeof( szBuffer );
  765. if( RegQueryValueEx( *hKey,
  766. REGVAL_VIRTUAL_NETWORK_NUMBER,
  767. 0,
  768. NULL,
  769. (LPBYTE) szBuffer,
  770. &dwSize ) == ERROR_SUCCESS )
  771. {
  772. lstrcpyn( NetSettings.szInternalNetworkNumber,
  773. szBuffer,
  774. MAX_INTERNAL_NET_NUMBER_LEN + 1 );
  775. }
  776. //
  777. // For each Network Adapter, load its IPX settings
  778. //
  779. for( pNetAdapter = NetSettings.NetworkAdapterHead;
  780. pNetAdapter;
  781. pNetAdapter = pNetAdapter->next )
  782. {
  783. StringFromGUID2( pNetAdapter->guid,
  784. szStringGuid,
  785. StrBuffSize( szStringGuid ) );
  786. if( RegOpenKeyEx( hIpxAdaptersKey,
  787. szStringGuid,
  788. 0,
  789. SecurityAccess,
  790. &hNetworkAdapterKey ) == ERROR_SUCCESS )
  791. {
  792. dwSize = sizeof( szBuffer );
  793. if( RegQueryValueEx( hNetworkAdapterKey,
  794. REGVAL_PKT_TYPE,
  795. 0,
  796. NULL,
  797. (LPBYTE) szBuffer,
  798. &dwSize) == ERROR_SUCCESS )
  799. {
  800. lstrcpyn( pNetAdapter->szFrameType, _T("0x"), AS(pNetAdapter->szFrameType) );
  801. lstrcatn( pNetAdapter->szFrameType, szBuffer, MAX_FRAMETYPE_LEN );
  802. }
  803. dwSize = sizeof( szBuffer );
  804. if( RegQueryValueEx( hNetworkAdapterKey,
  805. REGVAL_NETWORK_NUMBER,
  806. 0,
  807. NULL,
  808. (LPBYTE) szBuffer,
  809. &dwSize) == ERROR_SUCCESS )
  810. {
  811. lstrcpyn( pNetAdapter->szNetworkNumber,
  812. szBuffer,
  813. MAX_NET_NUMBER_LEN + 1 );
  814. }
  815. }
  816. }
  817. }
  818. //----------------------------------------------------------------------------
  819. //
  820. // Function: ReadTcpipSettingsFromRegistry
  821. //
  822. // Purpose: Read in registry settings on TCP/IP and fill the global structs
  823. // with the appropriate values
  824. //
  825. // Arguments: HKEY *hKey -
  826. //
  827. // Returns: HRESULT returns status of success or failure of the function
  828. //
  829. //----------------------------------------------------------------------------
  830. static VOID
  831. ReadTcpipSettingsFromRegistry( IN HKEY *hKey )
  832. {
  833. HKEY hTcpipInterfaceKey = NULL;
  834. REGSAM SecurityAccess = KEY_QUERY_VALUE;
  835. NETWORK_ADAPTER_NODE *pNetAdapter = NULL;
  836. if( RegOpenKeyEx( *hKey,
  837. REGVAL_INTERFACES,
  838. 0,
  839. SecurityAccess,
  840. &hTcpipInterfaceKey ) != ERROR_SUCCESS )
  841. {
  842. //
  843. // need this key to read in all other TCP/IP values so bail if we can't get it
  844. //
  845. return;
  846. }
  847. //
  848. // For each Network Adapter, load its TCP/IP settings
  849. //
  850. for( pNetAdapter = NetSettings.NetworkAdapterHead;
  851. pNetAdapter;
  852. pNetAdapter = pNetAdapter->next )
  853. {
  854. ReadAdapterSpecificTcpipSettings( hTcpipInterfaceKey, pNetAdapter );
  855. }
  856. // ISSUE-2002/20/28-stelo -not reading in LM Hosts setting
  857. }
  858. //----------------------------------------------------------------------------
  859. //
  860. // Function: ReadAdapterSpecificTcpipSettings
  861. //
  862. // Purpose: Reads network adapter specific TCP/IP settings and populates the
  863. // pNetAdapter structure with their values.
  864. //
  865. // Arguments:
  866. // IN HKEY hTcpipInterfaceKey - handle to the TCP/IP settings portion of
  867. // the registry
  868. // IN OUT NETWORK_ADAPTER_NODE *pNetAdapter - ptr to structure to load the
  869. // TCP/IP values into
  870. //
  871. // Returns: VOID
  872. //
  873. //----------------------------------------------------------------------------
  874. static VOID
  875. ReadAdapterSpecificTcpipSettings( IN HKEY hTcpipInterfaceKey,
  876. IN OUT NETWORK_ADAPTER_NODE *pNetAdapter )
  877. {
  878. DWORD dwDHCP = 0;
  879. DWORD dwSize = 0;
  880. DWORD dwSize2 = 0;
  881. REGSAM SecurityAccess = KEY_QUERY_VALUE;
  882. HKEY hNetworkAdapterKey = NULL;
  883. LPTSTR lpszBuffer = NULL;
  884. LPTSTR lpszBuffer2 = NULL;
  885. TCHAR szStringGuid[MAX_GUID_STRING];
  886. //
  887. // Make sure we can allocate big enough buffers...
  888. //
  889. lpszBuffer = (LPTSTR) MALLOC( BUFFER_SIZE * sizeof(TCHAR) );
  890. if ( !lpszBuffer )
  891. {
  892. // Unable to allocate memory... bail!
  893. return;
  894. }
  895. lpszBuffer2 = (LPTSTR) MALLOC( BUFFER_SIZE * sizeof(TCHAR) );
  896. if ( !lpszBuffer2 )
  897. {
  898. // Unable to allocate memory... bail!
  899. FREE( lpszBuffer );
  900. return;
  901. }
  902. StringFromGUID2( pNetAdapter->guid,
  903. szStringGuid,
  904. StrBuffSize( szStringGuid ) );
  905. if( RegOpenKeyEx( hTcpipInterfaceKey,
  906. szStringGuid,
  907. 0,
  908. SecurityAccess,
  909. &hNetworkAdapterKey ) == ERROR_SUCCESS )
  910. {
  911. dwSize = sizeof( dwDHCP );
  912. if( RegQueryValueEx( hNetworkAdapterKey,
  913. REGVAL_ENABLE_DHCP,
  914. 0,
  915. NULL,
  916. (LPBYTE) &dwDHCP,
  917. &dwSize ) == ERROR_SUCCESS )
  918. {
  919. if( dwDHCP == 1 )
  920. {
  921. pNetAdapter->bObtainIPAddressAutomatically = TRUE;
  922. }
  923. else
  924. {
  925. pNetAdapter->bObtainIPAddressAutomatically = FALSE;
  926. }
  927. }
  928. if( ! pNetAdapter->bObtainIPAddressAutomatically )
  929. {
  930. TCHAR *pszIpAddresses;
  931. TCHAR *pszSubnetAddresses;
  932. TCHAR *pszGatewayAddresses;
  933. TCHAR *pszDnsAddresses;
  934. TCHAR *pszWinsAddresses;
  935. TCHAR szWinsRegPath[MAX_INILINE_LEN + 1] = _T("");
  936. HKEY hWinsKey = NULL;
  937. HRESULT hrCat;
  938. dwSize = BUFFER_SIZE * sizeof(TCHAR);
  939. dwSize2 = BUFFER_SIZE * sizeof(TCHAR);
  940. if( (RegQueryValueEx( hNetworkAdapterKey,
  941. REGVAL_IPADDRESS,
  942. 0,
  943. NULL,
  944. (LPBYTE) lpszBuffer,
  945. &dwSize ) == ERROR_SUCCESS)
  946. &&
  947. (RegQueryValueEx( hNetworkAdapterKey,
  948. REGVAL_SUBNETMASK,
  949. 0,
  950. NULL,
  951. (LPBYTE) lpszBuffer2,
  952. &dwSize2 ) == ERROR_SUCCESS ) )
  953. {
  954. pszIpAddresses = lpszBuffer; // contains the IP Addresses
  955. pszSubnetAddresses = lpszBuffer2; // contains the Subnet Masks
  956. if( *pszIpAddresses != _T('\0') && *pszSubnetAddresses != _T('\0') ) {
  957. //
  958. // Add the IP and Subnet masks to their namelists
  959. //
  960. do
  961. {
  962. TcpipAddNameToNameList( &pNetAdapter->Tcpip_IpAddresses,
  963. pszIpAddresses );
  964. TcpipAddNameToNameList( &pNetAdapter->Tcpip_SubnetMaskAddresses,
  965. pszSubnetAddresses );
  966. } while( GetNextIp( &pszIpAddresses ) && GetNextIp( &pszSubnetAddresses ) );
  967. }
  968. }
  969. dwSize = BUFFER_SIZE * sizeof(TCHAR);
  970. if( RegQueryValueEx( hNetworkAdapterKey,
  971. REGVAL_DEFAULTGATEWAY,
  972. 0,
  973. NULL,
  974. (LPBYTE) lpszBuffer,
  975. &dwSize ) == ERROR_SUCCESS )
  976. {
  977. pszGatewayAddresses = lpszBuffer; // contains the Gateway Addresses
  978. if( *pszGatewayAddresses != _T('\0') )
  979. {
  980. //
  981. // Add the Gateways to its namelist
  982. //
  983. do
  984. {
  985. AddNameToNameList( &pNetAdapter->Tcpip_GatewayAddresses,
  986. pszGatewayAddresses );
  987. } while( GetNextIp( &pszGatewayAddresses ) );
  988. }
  989. }
  990. //
  991. // Get the DNS IPs
  992. //
  993. dwSize = BUFFER_SIZE * sizeof(TCHAR);
  994. if( RegQueryValueEx( hNetworkAdapterKey,
  995. REGVAL_NAMESERVER,
  996. 0,
  997. NULL,
  998. (LPBYTE) lpszBuffer,
  999. &dwSize ) == ERROR_SUCCESS )
  1000. {
  1001. pszDnsAddresses = lpszBuffer; // Contains the DNS addresses
  1002. if( *pszDnsAddresses != _T('\0') )
  1003. {
  1004. TCHAR szDnsBuffer[MAX_INILINE_LEN + 1];
  1005. NetSettings.bObtainDNSServerAutomatically = FALSE;
  1006. //
  1007. // Loop grabbing the DNS IPs and inserting them into
  1008. // its namelist
  1009. //
  1010. while( GetCommaDelimitedEntry( szDnsBuffer, &pszDnsAddresses ) )
  1011. {
  1012. TcpipAddNameToNameList( &pNetAdapter->Tcpip_DnsAddresses,
  1013. szDnsBuffer );
  1014. }
  1015. }
  1016. }
  1017. //
  1018. // Get the WINS server list
  1019. //
  1020. // Have to jump to different location in the registry to read
  1021. // the WINS data
  1022. //
  1023. //
  1024. // Build up the WINS registry path
  1025. //
  1026. lstrcpyn( szWinsRegPath, REGVAL_WINS, AS(szWinsRegPath) );
  1027. hrCat=StringCchCat( szWinsRegPath, AS(szWinsRegPath), szStringGuid );
  1028. //
  1029. // Grab all the WINS values from the registry
  1030. //
  1031. if( RegOpenKeyEx( HKEY_LOCAL_MACHINE,
  1032. szWinsRegPath,
  1033. 0,
  1034. SecurityAccess,
  1035. &hWinsKey ) != ERROR_SUCCESS )
  1036. {
  1037. //
  1038. // need this key to read in the WINS values so bail if we
  1039. // can't get it
  1040. //
  1041. return;
  1042. }
  1043. dwSize = BUFFER_SIZE * sizeof(TCHAR);
  1044. if( RegQueryValueEx( hWinsKey,
  1045. REGVAL_NAMESERVERLIST,
  1046. NULL,
  1047. NULL,
  1048. (LPBYTE) lpszBuffer,
  1049. &dwSize ) == ERROR_SUCCESS )
  1050. {
  1051. pszWinsAddresses = lpszBuffer;
  1052. if( *pszWinsAddresses != _T('\0') )
  1053. {
  1054. //
  1055. // Add the WINS IPs to the namelist
  1056. //
  1057. do
  1058. {
  1059. AddNameToNameList( &pNetAdapter->Tcpip_WinsAddresses,
  1060. pszWinsAddresses );
  1061. } while( GetNextIp( &pszWinsAddresses ) );
  1062. }
  1063. }
  1064. //
  1065. // Get the Domain
  1066. //
  1067. dwSize = BUFFER_SIZE * sizeof(TCHAR);
  1068. if( RegQueryValueEx( hNetworkAdapterKey,
  1069. REGVAL_DOMAIN,
  1070. 0,
  1071. NULL,
  1072. (LPBYTE) lpszBuffer,
  1073. &dwSize ) == ERROR_SUCCESS )
  1074. {
  1075. lstrcpyn( pNetAdapter->szDNSDomainName,
  1076. lpszBuffer,
  1077. MAX_DNS_DOMAIN_LENGTH + 1 );
  1078. }
  1079. // ISSUE-2002/20/28-stelo- not reading the NetBiosOption
  1080. }
  1081. }
  1082. }
  1083. //----------------------------------------------------------------------------
  1084. //
  1085. // Function: GetNextIp
  1086. //
  1087. // Purpose: Gets the next string in a multi-NULL terminated string
  1088. //
  1089. // Arguments: TCHAR *ppszString - pointer to the current string
  1090. //
  1091. // Returns: BOOL - TRUE if ppszString points to the IP string
  1092. // FALSE if there are no more IP strings left
  1093. // TCHAR *ppszString - on TRUE, points to the next IP string
  1094. // - on FALSE, points to NULL
  1095. //
  1096. //----------------------------------------------------------------------------
  1097. static BOOL
  1098. GetNextIp( IN OUT TCHAR **ppszString )
  1099. {
  1100. while( **ppszString != _T('\0') )
  1101. {
  1102. (*ppszString)++;
  1103. }
  1104. //
  1105. // check that Char after the one we are currently looking at to see if it
  1106. // is the true end of the string(s)
  1107. //
  1108. if( *( (*ppszString) + 1 ) == _T('\0') )
  1109. {
  1110. //
  1111. // 2 NULLs in a row signify there are no more IPs to read
  1112. //
  1113. return( FALSE );
  1114. }
  1115. else
  1116. {
  1117. //
  1118. // Advance one more so we go past the \0 and point to the first char
  1119. // of the new IP address
  1120. //
  1121. (*ppszString)++;
  1122. return( TRUE );
  1123. }
  1124. }
  1125. //----------------------------------------------------------------------------
  1126. //
  1127. // Function: GetDomainMembershipInfo
  1128. //
  1129. // Purpose: Gets the domain/workgroup for the machine it is running on.
  1130. // Assumes enough space is already allocated in szName for the copy.
  1131. //
  1132. // Arguments: BOOL* bDomainMember - if TRUE, then the contents of szName is a Domain
  1133. // if FALSE, then the contents of szName is a Workgroup
  1134. //
  1135. // Returns: NTSTATUS - returns success or failure of the function
  1136. //
  1137. //----------------------------------------------------------------------------
  1138. static NTSTATUS
  1139. GetDomainMembershipInfo( OUT BOOL* bDomainMember, OUT TCHAR *szName )
  1140. {
  1141. NTSTATUS ntstatus;
  1142. POLICY_PRIMARY_DOMAIN_INFO* ppdi;
  1143. LSA_OBJECT_ATTRIBUTES loa;
  1144. LSA_HANDLE hLsa = 0;
  1145. loa.Length = sizeof(LSA_OBJECT_ATTRIBUTES);
  1146. loa.RootDirectory = NULL;
  1147. loa.ObjectName = NULL;
  1148. loa.Attributes = 0;
  1149. loa.SecurityDescriptor = NULL;
  1150. loa.SecurityQualityOfService = NULL;
  1151. ntstatus = LsaOpenPolicy( NULL, &loa, POLICY_VIEW_LOCAL_INFORMATION, &hLsa );
  1152. if( LSA_SUCCESS( ntstatus ) )
  1153. {
  1154. ntstatus = LsaQueryInformationPolicy( hLsa,
  1155. PolicyPrimaryDomainInformation,
  1156. (VOID **) &ppdi );
  1157. if( LSA_SUCCESS( ntstatus ) )
  1158. {
  1159. if( ppdi->Sid > 0 )
  1160. {
  1161. *bDomainMember = TRUE;
  1162. }
  1163. else
  1164. {
  1165. *bDomainMember = FALSE;
  1166. }
  1167. lstrcpyn( szName, ppdi->Name.Buffer, AS(szName) );
  1168. }
  1169. LsaClose( hLsa );
  1170. }
  1171. return( ntstatus );
  1172. }
  1173. //----------------------------------------------------------------------------
  1174. //
  1175. // Function: InitializeComInterface
  1176. //
  1177. // Purpose: Obtains the INetCfgClass interface and enumerates all the
  1178. // components. Handles cleanup of all interfaces if failure
  1179. // returned.
  1180. //
  1181. // Arguments:
  1182. // const GUID* pGuid - pointer to GUID representing the class of
  1183. // components represented by the returned pointer
  1184. // INetCfg* pNetCfg - pointer to initialized INetCfg interface
  1185. // INetCfgClass** ppNetCfgClass - output parameter pointing to
  1186. // the interface requested by the GUID
  1187. // IEnumNetCfgComponent *pEnum - output param that points to an
  1188. // IEnumNetCfgComponent to get to each individual INetCfgComponent
  1189. // INetCfgComponent *arrayComp[MAX_NUM_NET_COMPONENTS] - array of all
  1190. // the INetCfgComponents that correspond to the the given GUID
  1191. // ULONG* pCount - the number of INetCfgComponents in the array
  1192. //
  1193. // Returns: HRESULT - returns status of success or failure of the function
  1194. //
  1195. //----------------------------------------------------------------------------
  1196. static HRESULT
  1197. InitializeComInterface( const GUID *pGuid,
  1198. INetCfg *pNetCfg,
  1199. INetCfgClass *pNetCfgClass,
  1200. IEnumNetCfgComponent *pEnum,
  1201. INetCfgComponent *arrayComp[MAX_NUM_NET_COMPONENTS],
  1202. ULONG* pCount )
  1203. {
  1204. HRESULT hr;
  1205. HRESULT TempHr;
  1206. //
  1207. // Obtain the INetCfgClass interface pointer
  1208. //
  1209. hr = GetClass( pGuid,
  1210. pNetCfg,
  1211. &pNetCfgClass );
  1212. //
  1213. // Check validity of the pointer we got back from GetClass
  1214. //
  1215. TempHr = ChkInterfacePointer( pNetCfgClass, IID_INetCfgClass );
  1216. if( FAILED( hr ) || FAILED( TempHr ) )
  1217. {
  1218. ReleaseInterfaces( pNetCfg );
  1219. return( E_FAIL );
  1220. }
  1221. //
  1222. // Retrieve the enumerator interface
  1223. //
  1224. hr = pNetCfgClass->EnumComponents( &pEnum );
  1225. if( FAILED( hr ) ||
  1226. FAILED( ChkInterfacePointer( pEnum, IID_IEnumNetCfgComponent ) ) )
  1227. {
  1228. if( pNetCfgClass )
  1229. {
  1230. pNetCfgClass->Release();
  1231. }
  1232. ReleaseInterfaces( pNetCfg );
  1233. return( E_FAIL );
  1234. }
  1235. hr = pEnum->Next( MAX_NUM_NET_COMPONENTS, &arrayComp[0], pCount );
  1236. if( FAILED( hr ) )
  1237. {
  1238. if( pEnum )
  1239. {
  1240. pEnum->Release();
  1241. }
  1242. if( pNetCfgClass )
  1243. {
  1244. pNetCfgClass->Release();
  1245. }
  1246. ReleaseInterfaces( pNetCfg );
  1247. return( E_FAIL );
  1248. }
  1249. return( S_OK );
  1250. }
  1251. //----------------------------------------------------------------------------
  1252. //
  1253. // Function: UninitializeComInterface
  1254. //
  1255. // Purpose: To release the Net Config object interfaces.
  1256. //
  1257. // Arguments: INetCfgClass *pNetCfgClass - the INetCfgClass to be released
  1258. // IEnumNetCfgComponent *pEnum - the IEnumNetCfgComponent to be released
  1259. //
  1260. // Returns: VOID
  1261. //
  1262. //----------------------------------------------------------------------------
  1263. static VOID
  1264. UninitializeComInterface( INetCfgClass *pNetCfgClass,
  1265. IEnumNetCfgComponent *pEnum )
  1266. {
  1267. if( pNetCfgClass )
  1268. {
  1269. pNetCfgClass->Release();
  1270. }
  1271. if( pEnum )
  1272. {
  1273. pEnum->Release();
  1274. }
  1275. }
  1276. //----------------------------------------------------------------------------
  1277. //
  1278. // Function: InitializeInterfaces
  1279. //
  1280. // Purpose: Initializes COM, creates, and initializes the NetCfg
  1281. //
  1282. // Arguments: INetCfg** ppNetCfg - output param that is the created and
  1283. // initialized INetCfg interface
  1284. //
  1285. // Returns: HRESULT - returns status of success or failure of the function
  1286. //
  1287. //----------------------------------------------------------------------------
  1288. static HRESULT
  1289. InitializeInterfaces( INetCfg** ppNetCfg )
  1290. {
  1291. HRESULT hr = S_OK;
  1292. hr = CoInitializeEx( NULL, COINIT_MULTITHREADED | COINIT_DISABLE_OLE1DDE );
  1293. if( FAILED( hr ) )
  1294. {
  1295. return( hr );
  1296. }
  1297. hr = CreateAndInitNetCfg( ppNetCfg );
  1298. return( hr );
  1299. }
  1300. //----------------------------------------------------------------------------
  1301. //
  1302. // Function: CreateAndInitNetCfg
  1303. //
  1304. // Purpose: Instantiate and initalize an INetCfg interface
  1305. //
  1306. // Arguments: INetCfg** ppNetCfg - output parameter that is the initialized
  1307. // INetCfg interface
  1308. //
  1309. // Returns: HRESULT - returns status of success or failure of the function
  1310. //
  1311. //----------------------------------------------------------------------------
  1312. static HRESULT
  1313. CreateAndInitNetCfg( INetCfg** ppNetCfg )
  1314. {
  1315. HRESULT hr = S_OK;
  1316. INetCfg* pNetCfg = NULL;
  1317. if( ( ppNetCfg == NULL ) ||
  1318. IsBadWritePtr( ppNetCfg, sizeof(ppNetCfg) ) )
  1319. {
  1320. return( E_INVALIDARG );
  1321. }
  1322. *ppNetCfg = NULL;
  1323. hr = CoCreateInstance( CLSID_CNetCfg,
  1324. NULL,
  1325. CLSCTX_INPROC_SERVER,
  1326. IID_INetCfg,
  1327. reinterpret_cast<LPVOID*>(&pNetCfg) );
  1328. if( FAILED( hr ) )
  1329. {
  1330. return( hr );
  1331. }
  1332. *ppNetCfg = pNetCfg;
  1333. //
  1334. // Initialize the INetCfg object.
  1335. //
  1336. hr = (*ppNetCfg)->Initialize( NULL );
  1337. if( FAILED( hr ) )
  1338. {
  1339. (*ppNetCfg)->Release();
  1340. CoUninitialize();
  1341. return( hr );
  1342. }
  1343. return( hr );
  1344. }
  1345. //----------------------------------------------------------------------------
  1346. //
  1347. // Function: ReleaseInterfaces
  1348. //
  1349. // Purpose: Uninitializes the NetCfg object and releases the interfaces
  1350. //
  1351. // Arguments: INetCfg* pNetCfg - the INetCfg interface to be released
  1352. //
  1353. // Returns: VOID
  1354. //
  1355. //----------------------------------------------------------------------------
  1356. static VOID
  1357. ReleaseInterfaces( INetCfg* pNetCfg )
  1358. {
  1359. HRESULT hr = S_OK;
  1360. //
  1361. // Check validity of the pNetCfg interface pointer
  1362. //
  1363. hr = ChkInterfacePointer( pNetCfg, IID_INetCfg );
  1364. if( FAILED( hr ) )
  1365. {
  1366. return;
  1367. }
  1368. if( pNetCfg != NULL )
  1369. {
  1370. pNetCfg->Uninitialize();
  1371. pNetCfg->Release();
  1372. }
  1373. CoUninitialize();
  1374. return;
  1375. }
  1376. //----------------------------------------------------------------------------
  1377. //
  1378. // Function: ChkInterfacePointer
  1379. //
  1380. // Purpose: Checks if an interface pointer is valid and if it can query itself
  1381. //
  1382. // Arguments: IUnknown* pInterface - interface pointer to check
  1383. // REFIID IID_IInterface - the IID of parameter 1
  1384. //
  1385. // Returns: HRESULT - returns status of success or failure of the function
  1386. //
  1387. //----------------------------------------------------------------------------
  1388. static HRESULT
  1389. ChkInterfacePointer( IUnknown* pInterface, REFIID IID_IInterface )
  1390. {
  1391. HRESULT hr = S_OK;
  1392. IUnknown* pResInterface = NULL;
  1393. if( (pInterface == NULL) || IsBadReadPtr( pInterface, sizeof(pInterface) ) )
  1394. {
  1395. hr = E_INVALIDARG;
  1396. return( hr );
  1397. }
  1398. hr = pInterface->QueryInterface( IID_IInterface, (void**)&pResInterface );
  1399. if( FAILED( hr ) )
  1400. {
  1401. return( hr );
  1402. }
  1403. if( pInterface != pResInterface )
  1404. {
  1405. hr = E_FAIL;
  1406. pResInterface->Release();
  1407. return( hr );
  1408. }
  1409. pResInterface->Release();
  1410. return( S_OK );
  1411. }
  1412. //----------------------------------------------------------------------------
  1413. //
  1414. // Function: GetClass
  1415. //
  1416. // Purpose: Retrieves INetCfgClass for the specified pGuid
  1417. //
  1418. // Arguments: const GUID* pGuid - pointer to GUID representing the class of
  1419. // components represented by the returned pointer
  1420. // INetCfg* pNetCfg - pointer to initialized INetCfg interface
  1421. // INetCfgClass** ppNetCfgClass - output parameter pointing to
  1422. // the interface requested by the GUID
  1423. //
  1424. // Returns: HRESULT - returns status of success or failure of the function
  1425. //
  1426. //----------------------------------------------------------------------------
  1427. static HRESULT
  1428. GetClass( const GUID* pGuid, INetCfg* pNetCfg, INetCfgClass** ppNetCfgClass )
  1429. {
  1430. HRESULT hr = S_OK;
  1431. INetCfgClass* pNetCfgClass = NULL;
  1432. hr = ChkInterfacePointer( pNetCfg, IID_INetCfg );
  1433. if( FAILED( hr ) )
  1434. {
  1435. return( E_INVALIDARG );
  1436. }
  1437. if( IsBadWritePtr( ppNetCfgClass, sizeof(ppNetCfgClass) ) )
  1438. {
  1439. return( E_INVALIDARG );
  1440. }
  1441. hr = pNetCfg->QueryNetCfgClass( pGuid,
  1442. IID_INetCfgClass,
  1443. (void**)&pNetCfgClass );
  1444. if( FAILED( hr ) )
  1445. {
  1446. return( hr );
  1447. }
  1448. *ppNetCfgClass = pNetCfgClass;
  1449. return( hr );
  1450. }