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.

2795 lines
71 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1997 - 2000
  5. //
  6. // File: H N C A P I . C P P
  7. //
  8. // Contents: Routines exported from HNetCfg.dll
  9. //
  10. // Notes:
  11. //
  12. // Author: jonburs 20 June 2000
  13. //
  14. // History: billi 09 July 2000 - added HNet[Get|Set]ShareAndBridgeSettings
  15. // and supporting static functions
  16. // billi 14 Sep 2000 - added timeout work around for bridge creation
  17. // and SharePrivate. This work to be removed
  18. // by Whistler Beta 2 due to DHCP fix.
  19. // billi 27 Dec 2000 - added HNW logging strings
  20. //
  21. //----------------------------------------------------------------------------
  22. #include "pch.h"
  23. #pragma hdrstop
  24. #include <lmcons.h>
  25. #include <lmapibuf.h>
  26. #include <ndispnp.h>
  27. #include <raserror.h>
  28. #include <winsock2.h>
  29. #include <iphlpapi.h> // ip helper
  30. #include <netconp.h>
  31. extern "C" { // make it work in C++
  32. #include <dhcpcsdk.h> // dhcp client options api
  33. #include "powrprof.h"
  34. }
  35. const DWORD MAX_DISABLE_EVENT_TIMEOUT = 0xFFFF;
  36. #define SECONDS_TO_WAIT_FOR_BRIDGE 20
  37. #define SECONDS_TO_WAIT_FOR_DHCP 20
  38. #define INITIAL_BUFFER_SIZE 256
  39. extern HINSTANCE g_hOemInstance;
  40. typedef struct _HNET_DELETE_RAS_PARAMS
  41. {
  42. GUID Guid;
  43. HMODULE hModule;
  44. } HNET_DELETE_RAS_PARAMS, *PHNET_DELETE_RAS_PARAMS;
  45. VOID
  46. HNetFreeFirewallLoggingSettings(
  47. HNET_FW_LOGGING_SETTINGS *pSettings
  48. )
  49. /*++
  50. Routine Description:
  51. Frees the memory used by a an HNET_FW_LOGGING_SETTINGS structure. This
  52. routine should only be used for structures obtained from
  53. IHNetFirewallSettings::GetFirewallLoggingSettings.
  54. Arguments:
  55. pSettings - pointer to the structure to free. This pointer should not be
  56. NULL.
  57. Return Value:
  58. None.
  59. --*/
  60. {
  61. if (NULL != pSettings)
  62. {
  63. if (NULL != pSettings->pszwPath)
  64. {
  65. CoTaskMemFree(pSettings->pszwPath);
  66. }
  67. CoTaskMemFree(pSettings);
  68. }
  69. else
  70. {
  71. _ASSERT(FALSE);
  72. }
  73. }
  74. DWORD
  75. WINAPI
  76. HNetDeleteRasConnectionWorker(
  77. VOID *pVoid
  78. )
  79. /*++
  80. Routine Description:
  81. Work item to perform the actual cleanup of a deleted
  82. RAS connection.
  83. Arguments:
  84. pVoid - HNET_DELETE_RAS_PARAMS
  85. Return Value:
  86. DWORD
  87. --*/
  88. {
  89. BOOL fComInitialized = FALSE;
  90. HRESULT hr;
  91. IHNetCfgMgr *pHNetCfgMgr;
  92. IHNetConnection *pHNetConnection;
  93. PHNET_DELETE_RAS_PARAMS pParams;
  94. _ASSERT(NULL != pVoid);
  95. pParams = reinterpret_cast<PHNET_DELETE_RAS_PARAMS>(pVoid);
  96. //
  97. // Make sure COM is initialized on this thread
  98. //
  99. hr = CoInitializeEx(NULL, COINIT_MULTITHREADED);
  100. if (SUCCEEDED(hr))
  101. {
  102. fComInitialized = TRUE;
  103. }
  104. else if (RPC_E_CHANGED_MODE == hr)
  105. {
  106. hr = S_OK;
  107. }
  108. //
  109. // Create the config manager
  110. //
  111. if (SUCCEEDED(hr))
  112. {
  113. hr = CoCreateInstance(
  114. CLSID_HNetCfgMgr,
  115. NULL,
  116. CLSCTX_SERVER,
  117. IID_PPV_ARG(IHNetCfgMgr, &pHNetCfgMgr)
  118. );
  119. }
  120. //
  121. // Try to obtain the IHNetConnection for the guid
  122. //
  123. if (SUCCEEDED(hr))
  124. {
  125. hr = pHNetCfgMgr->GetIHNetConnectionForGuid(
  126. &pParams->Guid,
  127. FALSE,
  128. FALSE,
  129. &pHNetConnection
  130. );
  131. if (SUCCEEDED(hr))
  132. {
  133. //
  134. // Ask the connection to delete itself
  135. //
  136. hr = pHNetConnection->DeleteRasConnectionEntry();
  137. pHNetConnection->Release();
  138. }
  139. pHNetCfgMgr->Release();
  140. }
  141. //
  142. // Uninitialize COM, if necessary
  143. //
  144. if (TRUE == fComInitialized)
  145. {
  146. CoUninitialize();
  147. }
  148. //
  149. // Free the params and exit thread.
  150. //
  151. HMODULE hModule = pParams->hModule;
  152. HeapFree(GetProcessHeap(), 0, pParams);
  153. FreeLibraryAndExitThread(hModule, ERROR_SUCCESS);
  154. return ERROR_SUCCESS;
  155. } // HNetDeleteRasConnectionWorker
  156. VOID
  157. WINAPI
  158. HNetDeleteRasConnection(
  159. GUID *pGuid
  160. )
  161. /*++
  162. Routine Description:
  163. Called by rasapi32 when a RAS connection is being deleted. The
  164. actual work is performed on a separate thread.
  165. Arguments:
  166. pGuid - the GUID of the connection to delete
  167. Return Value:
  168. None.
  169. --*/
  170. {
  171. HANDLE hThread;
  172. PHNET_DELETE_RAS_PARAMS pParams = NULL;
  173. do
  174. {
  175. if (NULL == pGuid)
  176. {
  177. break;
  178. }
  179. //
  180. // Setup the work item paramters
  181. //
  182. pParams =
  183. reinterpret_cast<PHNET_DELETE_RAS_PARAMS>(
  184. HeapAlloc(GetProcessHeap(), 0, sizeof(*pParams))
  185. );
  186. if (NULL == pParams)
  187. {
  188. break;
  189. }
  190. //
  191. // We need to add a reference to hnetcfg to guarantee that the
  192. // dll won't be unloaded before the worker finishes execution.
  193. //
  194. pParams->hModule = LoadLibraryW(L"hnetcfg");
  195. if (NULL == pParams->hModule)
  196. {
  197. break;
  198. }
  199. CopyMemory(&pParams->Guid, pGuid, sizeof(*pGuid));
  200. //
  201. // Create the worker thread. (We can't use QueueUserWorkItem
  202. // due to a possible race condition w/r/t unloading the
  203. // library and returning from the work item).
  204. //
  205. hThread =
  206. CreateThread(
  207. NULL,
  208. 0,
  209. HNetDeleteRasConnectionWorker,
  210. pParams,
  211. 0,
  212. NULL
  213. );
  214. if (NULL == hThread)
  215. {
  216. break;
  217. }
  218. CloseHandle(hThread);
  219. return;
  220. } while (FALSE);
  221. //
  222. // Failure path cleanup
  223. //
  224. if (NULL != pParams)
  225. {
  226. if (NULL != pParams->hModule)
  227. {
  228. FreeLibrary(pParams->hModule);
  229. }
  230. HeapFree(GetProcessHeap(), 0, pParams);
  231. }
  232. } // HNetDeleteRasConnection
  233. #if DBG
  234. WCHAR tcDbgPrtBuf[ BUF_SIZE + 1 ] = _T("");
  235. void inline rawdebugprintf( wchar_t *buf )
  236. {
  237. _sntprintf( tcDbgPrtBuf, BUF_SIZE, buf );
  238. tcDbgPrtBuf[BUF_SIZE] = _T('\0');
  239. OutputDebugString(tcDbgPrtBuf);
  240. return;
  241. }
  242. void inline debugprintf( wchar_t *preamble, wchar_t *buf )
  243. {
  244. OutputDebugString( _T("HNET: ") );
  245. OutputDebugString( preamble );
  246. OutputDebugString( buf );
  247. OutputDebugString( _T("\r\n") );
  248. return;
  249. }
  250. void inline debugretprintf( wchar_t *msg, HRESULT hResult )
  251. {
  252. _sntprintf( tcDbgPrtBuf, BUF_SIZE, _T("HNET: %s = %x\r\n"), msg, hResult );
  253. tcDbgPrtBuf[BUF_SIZE] = _T('\0');
  254. OutputDebugString( tcDbgPrtBuf );
  255. return;
  256. }
  257. #define TRACE_ENTER(x) debugprintf( _T("==> "), _T(x) );
  258. #define TRACE_LEAVE(x,y) debugretprintf( _T("<== ")_T(x), y );
  259. #else
  260. #define rawdebugprintf(x)
  261. #define debugprintf(x,y)
  262. #define debugretprintf(x,y)
  263. #define TRACE_ENTER(x)
  264. #define TRACE_LEAVE(x,y)
  265. #endif
  266. HRESULT
  267. UpdateHnwLog(
  268. IN LPHNWCALLBACK lpHnwCallback,
  269. IN LPARAM lpContext,
  270. IN UINT uID,
  271. IN LPCWSTR lpczwValue
  272. )
  273. /*++
  274. Routine Description:
  275. Arguments:
  276. Return Value:
  277. hResult
  278. --*/
  279. {
  280. HRESULT hr = S_OK;
  281. if ( NULL == lpHnwCallback )
  282. {
  283. hr = E_INVALIDARG;
  284. }
  285. else
  286. {
  287. LPWSTR lpFormat = new WCHAR[ NOTIFYFORMATBUFFERSIZE ];
  288. if ( NULL != lpFormat )
  289. {
  290. if ( LoadString( g_hOemInstance, // handle to resource module
  291. uID, // resource identifier
  292. lpFormat, // resource buffer
  293. NOTIFYFORMATBUFFERSIZE-1 ) // size of buffer
  294. == 0 )
  295. {
  296. hr = HrFromLastWin32Error();
  297. }
  298. else
  299. {
  300. if ( NULL != lpczwValue )
  301. {
  302. LPWSTR lpBuffer = new WCHAR[ HNWCALLBACKBUFFERSIZE ];
  303. if ( NULL != lpBuffer )
  304. {
  305. _snwprintf( lpBuffer, HNWCALLBACKBUFFERSIZE-1, lpFormat, lpczwValue );
  306. (*lpHnwCallback)( lpBuffer, lpContext );
  307. delete [] lpBuffer;
  308. }
  309. else
  310. {
  311. (*lpHnwCallback)( lpFormat, lpContext );
  312. hr = E_OUTOFMEMORY;
  313. }
  314. }
  315. else
  316. {
  317. (*lpHnwCallback)( lpFormat, lpContext );
  318. }
  319. }
  320. delete [] lpFormat;
  321. }
  322. else
  323. {
  324. hr = E_OUTOFMEMORY;
  325. }
  326. }
  327. return hr;
  328. }
  329. HRESULT
  330. UpdateHnwLog(
  331. IN LPHNWCALLBACK lpHnwCallback,
  332. IN LPARAM lpContext,
  333. IN UINT uID,
  334. IN DWORD dwValue
  335. )
  336. /*++
  337. Routine Description:
  338. Arguments:
  339. Return Value:
  340. hResult
  341. --*/
  342. {
  343. WCHAR pzwValue[ 32 ];
  344. _snwprintf( pzwValue, 32, L"%lx", dwValue );
  345. return UpdateHnwLog( lpHnwCallback, lpContext, uID, pzwValue );
  346. }
  347. HRESULT
  348. UpdateHnwLog(
  349. IN LPHNWCALLBACK lpHnwCallback,
  350. IN LPARAM lpContext,
  351. IN UINT uID,
  352. IN int iValue
  353. )
  354. /*++
  355. Routine Description:
  356. Arguments:
  357. Return Value:
  358. hResult
  359. --*/
  360. {
  361. WCHAR pzwValue[ 32 ];
  362. _snwprintf( pzwValue, 32, L"%x", iValue );
  363. return UpdateHnwLog( lpHnwCallback, lpContext, uID, pzwValue );
  364. }
  365. HRESULT
  366. UpdateHnwLog(
  367. IN LPHNWCALLBACK lpHnwCallback,
  368. IN LPARAM lpContext,
  369. IN UINT uID
  370. )
  371. /*++
  372. Routine Description:
  373. Arguments:
  374. Return Value:
  375. hResult
  376. --*/
  377. {
  378. return UpdateHnwLog( lpHnwCallback, lpContext, uID, NULL );
  379. }
  380. HRESULT
  381. UpdateHnwLog(
  382. IN LPHNWCALLBACK lpHnwCallback,
  383. IN LPARAM lpContext,
  384. IN UINT uID,
  385. IN LPCSTR lpczValue
  386. )
  387. /*++
  388. Routine Description:
  389. Arguments:
  390. Return Value:
  391. hResult
  392. --*/
  393. {
  394. HRESULT hr = E_FAIL;
  395. int iChars = 0;
  396. iChars = MultiByteToWideChar( CP_THREAD_ACP, 0, lpczValue, -1, NULL, 0 );
  397. if ( 0 != iChars )
  398. {
  399. LPWSTR lpWideStr = new WCHAR[ iChars + 1 ];
  400. if ( NULL != lpWideStr )
  401. {
  402. if ( !MultiByteToWideChar( CP_THREAD_ACP, 0, lpczValue, -1, lpWideStr, iChars ) )
  403. {
  404. hr = UpdateHnwLog( lpHnwCallback, lpContext, uID, lpWideStr );
  405. }
  406. else
  407. {
  408. hr = HrFromLastWin32Error();
  409. }
  410. }
  411. }
  412. else
  413. {
  414. hr = HrFromLastWin32Error();
  415. }
  416. return hr;
  417. }
  418. HRESULT
  419. CheckNetCfgWriteLock(
  420. IN LPHNWCALLBACK lpHnwCallback,
  421. IN LPARAM lpContext
  422. )
  423. /*++
  424. Routine Description:
  425. Arguments:
  426. Return Value:
  427. hResult
  428. --*/
  429. {
  430. HRESULT hr;
  431. INetCfg *pnetcfg = NULL;
  432. TRACE_ENTER("CheckNetCfgWriteLock");
  433. hr = CoCreateInstance( CLSID_CNetCfg, NULL, CLSCTX_SERVER, IID_PPV_ARG(INetCfg, &pnetcfg ) );
  434. if ( SUCCEEDED(hr) )
  435. {
  436. INetCfgLock *pncfglock = NULL;
  437. // Get the lock interface
  438. hr = pnetcfg->QueryInterface( IID_PPV_ARG(INetCfgLock, &pncfglock) );
  439. if ( SUCCEEDED(hr) )
  440. {
  441. // Get the NetCfg lock
  442. hr = pncfglock->AcquireWriteLock( 5, L"HNetCfg", NULL );
  443. if ( SUCCEEDED(hr) )
  444. {
  445. pncfglock->ReleaseWriteLock();
  446. }
  447. else
  448. {
  449. }
  450. pncfglock->Release();
  451. }
  452. else
  453. {
  454. }
  455. pnetcfg->Release();
  456. }
  457. else
  458. {
  459. }
  460. TRACE_LEAVE("CheckNetCfgWriteLock", hr);
  461. return hr;
  462. }
  463. HRESULT
  464. ArpForConflictingDhcpAddress(
  465. IN LPHNWCALLBACK lpHnwCallback,
  466. IN LPARAM lpContext
  467. )
  468. /*++
  469. Routine Description:
  470. Arguments:
  471. Return Value:
  472. hResult
  473. --*/
  474. {
  475. HRESULT hr = S_OK;
  476. WSADATA wsaData;
  477. int iWsaErr;
  478. TRACE_ENTER("ArpForConflictingDhcpAddress");
  479. iWsaErr = WSAStartup( 0x202, &wsaData );
  480. if ( 0 != iWsaErr )
  481. {
  482. hr = MAKE_HRESULT( SEVERITY_ERROR, FACILITY_INTERNET, iWsaErr );
  483. UpdateHnwLog( lpHnwCallback, lpContext, IDS_WSAERRORDURINGDETECTION, iWsaErr );
  484. }
  485. else
  486. {
  487. // Obtain required ICS server address
  488. ULONG TargetAddress, TargetMask;
  489. hr = ReadDhcpScopeSettings( &TargetAddress, &TargetMask );
  490. if ( SUCCEEDED(hr) )
  491. {
  492. // Retrieve the best interface for the target IP address,
  493. // and also perform a UDP-connect to determine the 'closest'
  494. // local IP address to the target IP address.
  495. ULONG InterfaceIndex;
  496. if ( GetBestInterface( TargetAddress, &InterfaceIndex ) != NO_ERROR )
  497. {
  498. int Length;
  499. SOCKADDR_IN SockAddrIn;
  500. SOCKET Socket;
  501. SockAddrIn.sin_family = AF_INET;
  502. SockAddrIn.sin_port = 0;
  503. SockAddrIn.sin_addr.s_addr = TargetAddress;
  504. Socket = socket( AF_INET, SOCK_DGRAM, IPPROTO_UDP );
  505. if ( INVALID_SOCKET != Socket )
  506. {
  507. iWsaErr = connect( Socket, (PSOCKADDR)&SockAddrIn, sizeof(SockAddrIn) );
  508. if ( NO_ERROR == iWsaErr )
  509. {
  510. iWsaErr = getsockname( Socket, ( PSOCKADDR)&SockAddrIn, &Length );
  511. }
  512. }
  513. else
  514. {
  515. iWsaErr = SOCKET_ERROR;
  516. }
  517. if ( NO_ERROR != iWsaErr )
  518. {
  519. hr = MAKE_SCODE( SEVERITY_ERROR, FACILITY_INTERNET, iWsaErr );
  520. UpdateHnwLog( lpHnwCallback, lpContext, IDS_WSAERRORDURINGDETECTION, iWsaErr );
  521. }
  522. else
  523. {
  524. // Make sure the target IP address isn't already cached,
  525. // by removing it from the ARP cache if present using the interface index
  526. // determined above.
  527. MIB_IPNETROW IpNetRow;
  528. DWORD dwError;
  529. CHAR HardwareAddress[6];
  530. ULONG HardwareAddressLength;
  531. ULONG SourceAddress;
  532. SourceAddress = SockAddrIn.sin_addr.s_addr;
  533. ZeroMemory( &IpNetRow, sizeof(IpNetRow) );
  534. IpNetRow.dwIndex = InterfaceIndex;
  535. IpNetRow.dwPhysAddrLen = 6;
  536. IpNetRow.dwAddr = TargetAddress;
  537. IpNetRow.dwType = MIB_IPNET_TYPE_INVALID;
  538. DeleteIpNetEntry( &IpNetRow );
  539. dwError = SendARP( TargetAddress, // destination IP address
  540. SourceAddress, // IP address of sender
  541. (PULONG)HardwareAddress, // returned physical address
  542. &HardwareAddressLength // length of returned physical addr.
  543. );
  544. if ( NO_ERROR == dwError )
  545. {
  546. TargetAddress = inet_addr( HardwareAddress );
  547. if ( TargetAddress != SourceAddress )
  548. {
  549. hr = E_ICSADDRESSCONFLICT;
  550. UpdateHnwLog( lpHnwCallback,
  551. lpContext,
  552. IDS_ICSADDRESSCONFLICTDETECTED,
  553. HardwareAddress );
  554. }
  555. else
  556. {
  557. hr = S_OK;
  558. }
  559. }
  560. else
  561. {
  562. hr = MAKE_SCODE( SEVERITY_ERROR, FACILITY_INTERNET, dwError );
  563. UpdateHnwLog( lpHnwCallback, lpContext, IDS_SENDARPERRORDURINGDETECTION, dwError );
  564. }
  565. }
  566. }
  567. }
  568. }
  569. TRACE_LEAVE("ArpForConflictingDhcpAddress", hr);
  570. return hr;
  571. }
  572. HRESULT
  573. ObtainIcsErrorConditions(
  574. IN LPHNWCALLBACK lpHnwCallback,
  575. IN LPARAM lpContext
  576. )
  577. /*++
  578. Routine Description:
  579. Arguments:
  580. Return Value:
  581. hResult
  582. --*/
  583. {
  584. HRESULT hr;
  585. TRACE_ENTER("ObtainIcsErrorConditions");
  586. hr = ArpForConflictingDhcpAddress( lpHnwCallback, lpContext );
  587. if ( SUCCEEDED(hr) )
  588. {
  589. hr = CheckNetCfgWriteLock( lpHnwCallback, lpContext );
  590. if ( SUCCEEDED(hr) )
  591. {
  592. // Create Homenet Configuration Manager COM Instance
  593. IHNetCfgMgr* pCfgMgr;
  594. hr = CoCreateInstance( CLSID_HNetCfgMgr,
  595. NULL,
  596. CLSCTX_INPROC_SERVER,
  597. IID_PPV_ARG(IHNetCfgMgr, &pCfgMgr) );
  598. if ( SUCCEEDED(hr) )
  599. {
  600. pCfgMgr->Release();
  601. }
  602. else
  603. {
  604. UpdateHnwLog( lpHnwCallback, lpContext, IDS_SHARINGCONFIGURATIONUNAVAIL );
  605. }
  606. }
  607. }
  608. TRACE_LEAVE("ObtainIcsErrorConditions", hr);
  609. return hr;
  610. }
  611. HRESULT
  612. HRGetConnectionAdapterName(
  613. INetConnection *pNetConnection,
  614. LPWSTR *ppzwAdapterName
  615. )
  616. /*++
  617. Routine Description:
  618. Arguments:
  619. Return Value:
  620. hResult
  621. --*/
  622. {
  623. HRESULT hr;
  624. TRACE_ENTER("HRGetConnectionAdapterName");
  625. if ( NULL == pNetConnection )
  626. {
  627. hr = E_INVALIDARG;
  628. }
  629. else if ( NULL == ppzwAdapterName )
  630. {
  631. hr = E_POINTER;
  632. }
  633. else
  634. {
  635. NETCON_PROPERTIES* pProps;
  636. *ppzwAdapterName = NULL;
  637. hr = pNetConnection->GetProperties(&pProps);
  638. if ( SUCCEEDED( hr ) )
  639. {
  640. *ppzwAdapterName = new WCHAR[ wcslen( pProps->pszwDeviceName ) + 1 ];
  641. if ( NULL != *ppzwAdapterName )
  642. {
  643. wcscpy( *ppzwAdapterName, pProps->pszwDeviceName );
  644. debugprintf( _T("\t"), *ppzwAdapterName );
  645. }
  646. else
  647. {
  648. hr = E_OUTOFMEMORY;
  649. }
  650. NcFreeNetconProperties( pProps );
  651. }
  652. }
  653. TRACE_LEAVE("HRGetConnectionAdapterName", hr);
  654. return hr;
  655. }
  656. HRESULT
  657. GetIcsPublicConnection(
  658. IN CComPtr<IHNetCfgMgr> spIHNetCfgMgr,
  659. OUT INetConnection **ppNetPublicConnection,
  660. OUT BOOLEAN *pbSharePublicConnection OPTIONAL,
  661. OUT BOOLEAN *pbFirewallPublicConnection OPTIONAL
  662. )
  663. /*++
  664. Routine Description:
  665. Arguments:
  666. Return Value:
  667. hResult
  668. --*/
  669. {
  670. HRESULT hr;
  671. TRACE_ENTER("GetIcsPublicConnection");
  672. CComPtr<IHNetIcsSettings> spIHNetIcsSettings;
  673. _ASSERT( spIHNetCfgMgr != NULL );
  674. _ASSERT( NULL != ppNetPublicConnection );
  675. if ( NULL == ppNetPublicConnection )
  676. {
  677. hr = E_POINTER;
  678. }
  679. else if ( spIHNetCfgMgr == NULL )
  680. {
  681. hr = E_INVALIDARG;
  682. *ppNetPublicConnection = NULL;
  683. }
  684. else
  685. {
  686. // initialize arguments
  687. *ppNetPublicConnection = NULL;
  688. if ( NULL != pbSharePublicConnection )
  689. *pbSharePublicConnection = FALSE;
  690. if ( NULL != pbFirewallPublicConnection )
  691. *pbFirewallPublicConnection = FALSE;
  692. // Obtain interface pointer
  693. hr = spIHNetCfgMgr->QueryInterface( IID_PPV_ARG( IHNetIcsSettings, &spIHNetIcsSettings ) );
  694. if ( SUCCEEDED(hr) )
  695. {
  696. hr = S_OK;
  697. }
  698. }
  699. if ( S_OK == hr )
  700. {
  701. CComPtr<IEnumHNetIcsPublicConnections> spehiPublic;
  702. if ( ( hr = spIHNetIcsSettings->EnumIcsPublicConnections( &spehiPublic ) ) == S_OK )
  703. {
  704. CComPtr<IHNetIcsPublicConnection> spIHNetIcsPublic;
  705. // obtain only the first IHNetIcsPublicConnetion
  706. if ( ( hr = spehiPublic->Next( 1, &spIHNetIcsPublic, NULL ) ) == S_OK )
  707. {
  708. // obtain pointer to IID_IHNetConnection interface of object
  709. CComPtr<IHNetConnection> spIHNetPublic;
  710. hr = spIHNetIcsPublic->QueryInterface( IID_PPV_ARG( IHNetConnection, &spIHNetPublic ) );
  711. _ASSERT( SUCCEEDED(hr) );
  712. if ( SUCCEEDED(hr) )
  713. {
  714. // The reference count will be decremented by the caller
  715. // if necessary. Notice we are using the caller's pointer
  716. // variable.
  717. hr = spIHNetPublic->GetINetConnection( ppNetPublicConnection );
  718. if ( SUCCEEDED(hr) )
  719. {
  720. HNET_CONN_PROPERTIES *phncProperties;
  721. hr = spIHNetPublic->GetProperties( &phncProperties );
  722. if ( SUCCEEDED(hr) && ( NULL != phncProperties ) )
  723. {
  724. if ( NULL != pbSharePublicConnection )
  725. *pbSharePublicConnection = phncProperties->fIcsPublic;
  726. if ( NULL != pbFirewallPublicConnection )
  727. *pbFirewallPublicConnection = phncProperties->fFirewalled;
  728. CoTaskMemFree( phncProperties );
  729. } //if ( SUCCEEDED(hr) && ( NULL != phncProperties ) )
  730. if ( FAILED(hr) )
  731. {
  732. (*ppNetPublicConnection)->Release();
  733. *ppNetPublicConnection = NULL;
  734. }
  735. } // if ( SUCCEEDED(hr) )
  736. } // if ( SUCCEEDED(hr) )
  737. } // if ( ( hr = pehiPublic->Next( 1, &sphicPublic, NULL ) ) == S_OK )
  738. } // if ( ( hr = pIHNetCfgMgr->EnumIcsPublicConnections( &pehiPublic ) ) == S_OK )
  739. }
  740. TRACE_LEAVE("GetIcsPublicConnection", hr);
  741. return hr;
  742. }
  743. HRESULT
  744. GetIcsPrivateConnections(
  745. IN CComPtr<IHNetCfgMgr> spIHNetCfgMgr,
  746. OUT INetConnection ***ppNetPrivateConnection
  747. )
  748. /*++
  749. Routine Description:
  750. Obtain the private connections enumerator and loop
  751. through enumeration twice. Set the required array
  752. length during the first enumeration. If the parameter
  753. array is big enough initialize it during the second
  754. enumeration.
  755. Arguments:
  756. Return Value:
  757. hResult
  758. --*/
  759. {
  760. HRESULT hr;
  761. ULONG ulArrayLength, ulListLength, uIndex;
  762. BOOLEAN bBufferAllocated;
  763. CComPtr<IHNetIcsSettings> spIHNetIcsSettings;
  764. IHNetIcsPrivateConnection *pIHNetIcsPrivate;
  765. IHNetIcsPrivateConnection **ppIHNetIPList;
  766. CComPtr<IEnumHNetIcsPrivateConnections> spehiPrivate;
  767. TRACE_ENTER("GetIcsPrivateConnections");
  768. _ASSERT( spIHNetCfgMgr != NULL );
  769. _ASSERT( NULL != ppNetPrivateConnection );
  770. if ( spIHNetCfgMgr == NULL )
  771. {
  772. hr = E_POINTER;
  773. }
  774. else if ( NULL == ppNetPrivateConnection )
  775. {
  776. hr = E_INVALIDARG;
  777. }
  778. else
  779. {
  780. // initialize local vars
  781. ulArrayLength = 0L;
  782. ulListLength = 0L;
  783. bBufferAllocated = FALSE;
  784. // Obtain interface pointer
  785. hr = spIHNetCfgMgr->QueryInterface( IID_PPV_ARG( IHNetIcsSettings, &spIHNetIcsSettings ) );
  786. if ( SUCCEEDED(hr) )
  787. {
  788. hr = S_OK;
  789. }
  790. } // else
  791. if ( S_OK == hr )
  792. {
  793. if ( ( hr = spIHNetIcsSettings->EnumIcsPrivateConnections( &spehiPrivate ) ) == S_OK )
  794. {
  795. while ( spehiPrivate->Next( 1, &pIHNetIcsPrivate, NULL ) == S_OK )
  796. {
  797. ulArrayLength++;
  798. pIHNetIcsPrivate->Release();
  799. }
  800. // releasing the enumeration interface now so we can re-initialize it later
  801. spehiPrivate = NULL;
  802. } // if ( ( hr = spIHNetIcsSettings->EnumIcsPublicConnections( &pehiPublic ) ) == S_OK )
  803. } // if ( S_OK == hr )
  804. if ( S_OK == hr )
  805. {
  806. if ( ( hr = spIHNetIcsSettings->EnumIcsPrivateConnections( &spehiPrivate ) ) == S_OK )
  807. {
  808. hr = spehiPrivate->Next( ulArrayLength, &pIHNetIcsPrivate, &ulListLength );
  809. if ( S_OK == hr )
  810. {
  811. // Allocate array of INetConnection pointers. There will
  812. // be on extra pointer element for the NULL pointer at the
  813. // end of the array. We allocate this buffer with
  814. // NetApiBufferAllocate so the buffer must be released using
  815. // NetApiBufferFree.
  816. NET_API_STATUS nErr;
  817. LPVOID lpvBuffer;
  818. ++ulArrayLength;
  819. nErr = NetApiBufferAllocate( ulArrayLength * sizeof(INetConnection *),
  820. (LPVOID *)ppNetPrivateConnection );
  821. if ( NERR_Success == nErr )
  822. {
  823. bBufferAllocated = TRUE;
  824. for ( uIndex = 0L; uIndex < ulArrayLength; uIndex++ )
  825. {
  826. (*ppNetPrivateConnection)[uIndex] = NULL;
  827. }
  828. }
  829. else
  830. {
  831. hr = E_OUTOFMEMORY;
  832. // must release IHNetIcsPrivateConnection instances
  833. ppIHNetIPList = &pIHNetIcsPrivate;
  834. for ( uIndex = 0L; uIndex < ulListLength; uIndex++ )
  835. {
  836. ppIHNetIPList[uIndex]->Release();
  837. }
  838. }
  839. } // if ( S_OK == hr )
  840. // done with enumeration interface pointer so we explicitly release it
  841. spehiPrivate = NULL;
  842. } // if ( ( hr = spIHNetIcsSettings->EnumIcsPublicConnections( &pehiPublic ) ) == S_OK )
  843. } // if ( S_OK == hr )
  844. if ( S_OK == hr )
  845. {
  846. ppIHNetIPList = &pIHNetIcsPrivate;
  847. for ( uIndex = 0L; uIndex < ulListLength; uIndex++ )
  848. {
  849. if ( uIndex < ulArrayLength - 1 )
  850. {
  851. CComPtr<IHNetConnection> spIHNetPrivate;
  852. hr = ppIHNetIPList[uIndex]->QueryInterface( IID_PPV_ARG( IHNetConnection, &spIHNetPrivate ) );
  853. _ASSERT( SUCCEEDED(hr) );
  854. if ( SUCCEEDED(hr) )
  855. {
  856. // We allow the caller to invoke Release for (*ppNetPrivateConnection)[uIndex]
  857. hr = spIHNetPrivate->GetINetConnection( &((*ppNetPrivateConnection)[uIndex]) );
  858. _ASSERT( SUCCEEDED(hr) );
  859. }
  860. } // if ( uIndex < uiArrayLength - 1 )
  861. ppIHNetIPList[uIndex]->Release();
  862. } // for ( uIndex = 0L; ...
  863. } // if ( S_OK == hr )
  864. if ( !SUCCEEDED(hr) )
  865. {
  866. // If we fail after allocating the buffer then we need release
  867. // references and buffer
  868. if ( bBufferAllocated )
  869. {
  870. for ( uIndex = 0L; uIndex < ulArrayLength; uIndex++ )
  871. {
  872. if ( NULL != (*ppNetPrivateConnection)[uIndex] )
  873. {
  874. (*ppNetPrivateConnection)[uIndex]->Release();
  875. }
  876. }
  877. NetApiBufferFree( *ppNetPrivateConnection );
  878. }
  879. }
  880. TRACE_LEAVE("GetIcsPrivateConnections", hr);
  881. return hr;
  882. }
  883. HRESULT
  884. GetBridge(
  885. IN CComPtr<IHNetCfgMgr> spIHNetCfgMgr,
  886. OUT IHNetBridge **ppBridge
  887. )
  888. /*++
  889. Routine Description:
  890. Obtain the bridge enumerator and loop through enumeration.
  891. Arguments:
  892. Return Value:
  893. --*/
  894. {
  895. HRESULT hr = E_INVALIDARG;
  896. TRACE_ENTER("GetBridge");
  897. _ASSERT( spIHNetCfgMgr != NULL );
  898. _ASSERT( NULL != ppBridge );
  899. if ( spIHNetCfgMgr == NULL )
  900. {
  901. hr = E_POINTER;
  902. }
  903. else if ( NULL == ppBridge )
  904. {
  905. hr = E_INVALIDARG;
  906. }
  907. else
  908. {
  909. CComPtr<IHNetBridgeSettings> spIHNetBridgeSettings;
  910. hr = spIHNetCfgMgr->QueryInterface( IID_PPV_ARG( IHNetBridgeSettings, &spIHNetBridgeSettings ) );
  911. if ( SUCCEEDED(hr) )
  912. {
  913. CComPtr<IEnumHNetBridges> spBridgeEnum;
  914. hr = spIHNetBridgeSettings->EnumBridges( &spBridgeEnum );
  915. if ( SUCCEEDED(hr) )
  916. {
  917. hr = spBridgeEnum->Next( 1, ppBridge, NULL );
  918. if ( S_FALSE == hr )
  919. {
  920. hr = E_FAIL;
  921. }
  922. // We allow the caller to invoke Release for *ppBridge
  923. }
  924. } // if ( SUCCEEDED(hr) )
  925. } // else
  926. TRACE_LEAVE("GetBridge", hr);
  927. return hr;
  928. }
  929. HRESULT
  930. GetBridgedConnections(
  931. IN CComPtr<IHNetCfgMgr> spIHNetCfgMgr,
  932. OUT INetConnection ***ppNetPrivateConnection
  933. )
  934. /*++
  935. Routine Description:
  936. Obtain the bridge connections enumerator and loop
  937. through enumeration twice. Set the required array
  938. length during the first enumeration. If the parameter
  939. array is big enough initialize it during the second
  940. enumeration.
  941. Arguments:
  942. Return Value:
  943. hResult
  944. --*/
  945. {
  946. HRESULT hr;
  947. ULONG ulArrayLength, ulListLength, uIndex;
  948. CComPtr<IHNetBridge> spBridge;
  949. CComPtr<IEnumHNetBridgedConnections> spEnum;
  950. IHNetBridgedConnection *pIHNetBridged;
  951. IHNetBridgedConnection **ppIHNetBridgeList;
  952. TRACE_ENTER("GetBridgedConnections");
  953. _ASSERT( spIHNetCfgMgr != NULL );
  954. _ASSERT( NULL != ppNetPrivateConnection );
  955. if ( NULL == ppNetPrivateConnection )
  956. {
  957. hr = E_POINTER;
  958. }
  959. else if ( spIHNetCfgMgr == NULL )
  960. {
  961. hr = E_INVALIDARG;
  962. *ppNetPrivateConnection = NULL;
  963. }
  964. else
  965. {
  966. // initialize arguments
  967. *ppNetPrivateConnection = NULL;
  968. ulArrayLength = 0L;
  969. ulListLength = 0L;
  970. // Obtain bridge interface pointer
  971. hr = GetBridge( spIHNetCfgMgr, &spBridge );
  972. } // else
  973. if ( S_OK == hr )
  974. {
  975. if ( ( hr = spBridge->EnumMembers( &spEnum ) ) == S_OK )
  976. {
  977. while ( spEnum->Next( 1, &pIHNetBridged, NULL ) == S_OK )
  978. {
  979. ulArrayLength++;
  980. pIHNetBridged->Release();
  981. }
  982. // releasing the enumeration interface instance so we can re-initialize it later
  983. spEnum = NULL;
  984. } // if ( ( hr = spBridge->EnumMembers( &spEnum ) ) == S_OK )
  985. } // if ( S_OK == hr )
  986. if ( S_OK == hr )
  987. {
  988. if ( ( hr = spBridge->EnumMembers( &spEnum ) ) == S_OK )
  989. {
  990. hr = spEnum->Next( ulArrayLength, &pIHNetBridged, &ulListLength );
  991. if ( S_OK == hr )
  992. {
  993. // Allocate array of INetConnection pointers. There will
  994. // be on extra pointer element for the NULL pointer at the
  995. // end of the array. We allocate this buffer with
  996. // NetApiBufferAllocate so the buffer must be released using
  997. // NetApiBufferFree.
  998. NET_API_STATUS nErr;
  999. ++ulArrayLength;
  1000. nErr = NetApiBufferAllocate( ulArrayLength*sizeof(INetConnection *),
  1001. (LPVOID *)ppNetPrivateConnection );
  1002. if ( NERR_Success == nErr )
  1003. {
  1004. for ( uIndex = 0L; uIndex < ulArrayLength; uIndex++ )
  1005. {
  1006. (*ppNetPrivateConnection)[uIndex] = NULL;
  1007. }
  1008. }
  1009. else
  1010. {
  1011. hr = E_OUTOFMEMORY;
  1012. // must release IHNetIcsPrivateConnection instances
  1013. ppIHNetBridgeList = &pIHNetBridged;
  1014. for ( uIndex = 0L; uIndex < ulListLength; uIndex++ )
  1015. {
  1016. ppIHNetBridgeList[uIndex]->Release();
  1017. }
  1018. } // else
  1019. } // if ( S_OK == hr )
  1020. // releasing enumeration interface instance
  1021. spEnum = NULL;
  1022. } // if ( ( hr = pBridge->EnumMembers( &spEnum ) ) == S_OK )
  1023. } // if ( S_OK == hr )
  1024. if ( S_OK == hr )
  1025. {
  1026. ppIHNetBridgeList = &pIHNetBridged;
  1027. for ( uIndex = 0L; uIndex < ulListLength; uIndex++ )
  1028. {
  1029. if ( uIndex < ulArrayLength - 1 )
  1030. {
  1031. CComPtr<IHNetConnection> spIHNetPrivate;
  1032. hr = ppIHNetBridgeList[uIndex]->QueryInterface( IID_PPV_ARG( IHNetConnection, &spIHNetPrivate ) );
  1033. _ASSERT( SUCCEEDED(hr) );
  1034. if ( SUCCEEDED(hr) )
  1035. {
  1036. // We allow the caller to invoke Release for (*ppNetPrivateConnection)[uIndex]
  1037. hr = spIHNetPrivate->GetINetConnection( &((*ppNetPrivateConnection)[uIndex]) );
  1038. _ASSERT( SUCCEEDED(hr) );
  1039. }
  1040. } // if ( uIndex < uiArrayLength - 1 )
  1041. ppIHNetBridgeList[uIndex]->Release();
  1042. } // for ( uIndex = 0L; ...
  1043. } // if ( S_OK == hr )
  1044. TRACE_LEAVE("GetBridgedConnections", hr);
  1045. return hr;
  1046. }
  1047. HRESULT
  1048. SetIcsPublicConnection(
  1049. IN CComPtr<IHNetCfgMgr> spIHNetCfgMgr,
  1050. IN INetConnection *pNetPublicConnection,
  1051. IN BOOLEAN bSharePublicConnection,
  1052. IN BOOLEAN bFirewallPublicConnection,
  1053. IN LPHNWCALLBACK lpHnwCallback,
  1054. IN LPARAM lpContext
  1055. )
  1056. /*++
  1057. Routine Description:
  1058. Arguments:
  1059. Return Value:
  1060. hResult
  1061. --*/
  1062. {
  1063. HRESULT hr;
  1064. TRACE_ENTER("SetIcsPublicConnection");
  1065. _ASSERT( spIHNetCfgMgr != NULL );
  1066. _ASSERT( NULL != pNetPublicConnection );
  1067. if ( spIHNetCfgMgr == NULL )
  1068. {
  1069. hr = E_POINTER;
  1070. }
  1071. else if ( NULL == pNetPublicConnection )
  1072. {
  1073. hr = E_INVALIDARG;
  1074. }
  1075. else
  1076. {
  1077. INetConnectionRefresh* pNetConnectionRefresh;
  1078. hr = CoCreateInstance(CLSID_ConnectionManager, NULL, CLSCTX_SERVER, IID_INetConnectionRefresh, reinterpret_cast<void**>(&pNetConnectionRefresh));
  1079. if( SUCCEEDED(hr) )
  1080. {
  1081. _ASSERT( pNetConnectionRefresh );
  1082. pNetConnectionRefresh->DisableEvents( TRUE, MAX_DISABLE_EVENT_TIMEOUT );
  1083. OLECHAR *strAdapter = L"Adapter";
  1084. OLECHAR *strName = strAdapter;
  1085. CComPtr<IHNetConnection> spHNetConnection;
  1086. hr = spIHNetCfgMgr->GetIHNetConnectionForINetConnection( pNetPublicConnection,
  1087. &spHNetConnection );
  1088. if ( S_OK == hr )
  1089. {
  1090. if ( HRGetConnectionAdapterName( pNetPublicConnection, &strName ) != S_OK )
  1091. {
  1092. strName = strAdapter;
  1093. }
  1094. if ( bSharePublicConnection )
  1095. {
  1096. CComPtr<IHNetIcsPublicConnection> spIcsPublicConn;
  1097. hr = spHNetConnection->SharePublic( &spIcsPublicConn );
  1098. if ( SUCCEEDED(hr) )
  1099. {
  1100. // Instantiating the IHNetIcsPublicConnection pointer with
  1101. // SharePublic results in updating our WMI store with
  1102. // the new sharing properties for this connection. This
  1103. // is our only goal at this time.
  1104. //
  1105. // set the power scheme!
  1106. //
  1107. if (!SetActivePwrScheme(3, NULL, NULL)) {
  1108. debugprintf( _T("Unable to set power scheme to always on\n"), strName);
  1109. }
  1110. UpdateHnwLog( lpHnwCallback, lpContext, IDS_NEWPUBLICCONNECTIONCREATED, strName );
  1111. spIcsPublicConn.Release();
  1112. debugprintf( _T("\t"), strName );
  1113. }
  1114. else
  1115. {
  1116. UpdateHnwLog( lpHnwCallback, lpContext, IDS_NEWPUBLICCONNECTIONFAILED, strName );
  1117. }
  1118. } // if ( bSharePublicConnection )
  1119. if ( SUCCEEDED(hr) && bFirewallPublicConnection )
  1120. {
  1121. CComPtr<IHNetFirewalledConnection> spFirewalledConn;
  1122. hr = spHNetConnection->Firewall( &spFirewalledConn );
  1123. if ( SUCCEEDED(hr) )
  1124. {
  1125. // Instantiating the IHNetFirewalledConnection pointer with
  1126. // SharePublic results in updating our WMI store with
  1127. // the new firewall properties for this connection. This
  1128. // is our only goal at this time.
  1129. UpdateHnwLog( lpHnwCallback, lpContext, IDS_FIREWALLCONNECTION, strName );
  1130. spFirewalledConn.Release();
  1131. }
  1132. else
  1133. {
  1134. UpdateHnwLog( lpHnwCallback, lpContext, IDS_FIREWALLCONNECTIONFAILED, strName );
  1135. }
  1136. } // if ( SUCCEEDED(hr) && bFirewallPublicConnection )
  1137. } // if ( S_OK == hr )
  1138. else
  1139. {
  1140. UpdateHnwLog( lpHnwCallback, lpContext, IDS_SHARINGCFGFORADAPTERUNAVAIL, strName );
  1141. }
  1142. if ( strName != strAdapter )
  1143. {
  1144. delete strName;
  1145. }
  1146. pNetConnectionRefresh->DisableEvents( FALSE, 0L );
  1147. pNetConnectionRefresh->Release();
  1148. } // if( SUCCEEDED(hr) )
  1149. } // else
  1150. TRACE_LEAVE("SetIcsPublicConnection", hr);
  1151. return hr;
  1152. }
  1153. HRESULT WaitForConnectionToInitialize(
  1154. IN CComPtr<IHNetConnection> spIHNC,
  1155. IN ULONG ulSeconds,
  1156. IN BOOLEAN bIsBridge
  1157. )
  1158. {
  1159. HRESULT hr;
  1160. GUID *pGuid;
  1161. UNICODE_STRING UnicodeString;
  1162. TRACE_ENTER("WaitForConnectionToInitialize");
  1163. ZeroMemory( &UnicodeString, sizeof(UnicodeString) );
  1164. hr = spIHNC->GetGuid( &pGuid );
  1165. if ( SUCCEEDED(hr) )
  1166. {
  1167. NTSTATUS Status = RtlStringFromGUID( *pGuid, &UnicodeString );
  1168. hr = ( STATUS_SUCCESS == Status ) ? S_OK : E_FAIL;
  1169. CoTaskMemFree( pGuid );
  1170. }
  1171. pGuid = NULL;
  1172. #ifdef WAIT_FOR_MEDIA_STATUS_CONNECTED
  1173. if ( SUCCEEDED(hr) && bIsBridge )
  1174. {
  1175. // Query the state of the connection. Try to wait for the
  1176. // bridge to build the spanning tree and report media state connected.
  1177. LPWSTR pwsz;
  1178. // Build a buffer large enough for the device string
  1179. pwsz = new WCHAR[ sizeof(c_wszDevice)/sizeof(WCHAR) + UnicodeString.Length/sizeof(WCHAR) + 1 ];
  1180. if ( NULL != pwsz )
  1181. {
  1182. UNICODE_STRING DeviceString;
  1183. NIC_STATISTICS NdisStatistics;
  1184. ULONG ulTimeout;
  1185. swprintf( pwsz, L"%s%s", c_wszDevice, UnicodeString.Buffer );
  1186. ulTimeout = SECONDS_TO_WAIT_FOR_BRIDGE;
  1187. RtlInitUnicodeString( &DeviceString, pwsz );
  1188. do
  1189. {
  1190. ZeroMemory( &NdisStatistics, sizeof(NdisStatistics) );
  1191. NdisStatistics.Size = sizeof(NdisStatistics);
  1192. NdisQueryStatistics( &DeviceString, &NdisStatistics );
  1193. if ( NdisStatistics.MediaState == MEDIA_STATE_UNKNOWN )
  1194. {
  1195. hr = HRESULT_FROM_WIN32(ERROR_SHARING_HOST_ADDRESS_CONFLICT);
  1196. }
  1197. else if ( NdisStatistics.DeviceState != DEVICE_STATE_CONNECTED ||
  1198. NdisStatistics.MediaState != MEDIA_STATE_CONNECTED )
  1199. {
  1200. hr = HRESULT_FROM_WIN32(ERROR_SHARING_NO_PRIVATE_LAN);
  1201. }
  1202. else
  1203. {
  1204. // AHA! Bridge initialized!
  1205. hr = S_OK;
  1206. break;
  1207. }
  1208. debugretprintf( pwsz, hr );
  1209. Sleep( 1000 );
  1210. }
  1211. while ( ulTimeout-- );
  1212. delete [] pwsz;
  1213. } // if ( NULL != pwsz )
  1214. } // if ( SUCCEEDED(hr) && bIsBridge )
  1215. #endif
  1216. if ( SUCCEEDED(hr) )
  1217. {
  1218. DWORD dwResult;
  1219. DWORD dwVersion; // version of the DHCP Client Options API reported
  1220. hr = HRESULT_FROM_WIN32(ERROR_SHARING_NO_PRIVATE_LAN);
  1221. dwResult = DhcpCApiInitialize( &dwVersion );
  1222. if ( ERROR_SUCCESS == dwResult )
  1223. {
  1224. DHCPCAPI_PARAMS requests[1] = { {0, OPTION_SUBNET_MASK, FALSE, NULL, 0} }; // subnet mask
  1225. DHCPCAPI_PARAMS_ARRAY sendarray = { 0, NULL }; // we aren't sending anything
  1226. DHCPCAPI_PARAMS_ARRAY requestarray = { 1, requests }; // we are requesting 2 items
  1227. while ( --ulSeconds )
  1228. {
  1229. DWORD dwSize = INITIAL_BUFFER_SIZE; // size of buffer for options
  1230. LPBYTE buffer = NULL; // buffer for options
  1231. IN_ADDR addr; // address in return code
  1232. do
  1233. {
  1234. if ( NULL != buffer )
  1235. {
  1236. LocalFree( buffer );
  1237. }
  1238. buffer = (LPBYTE) LocalAlloc( LPTR, dwSize ); // allocate the buffer
  1239. if ( NULL == buffer )
  1240. {
  1241. break;
  1242. }
  1243. // make the request on the adapter
  1244. dwResult = DhcpRequestParams( DHCPCAPI_REQUEST_SYNCHRONOUS,
  1245. NULL,
  1246. UnicodeString.Buffer,
  1247. NULL,
  1248. sendarray,
  1249. requestarray,
  1250. buffer,
  1251. &dwSize,
  1252. NULL );
  1253. }
  1254. while ( ERROR_MORE_DATA == dwResult );
  1255. if ( NULL != buffer )
  1256. {
  1257. LocalFree( buffer );
  1258. }
  1259. if ( ERROR_SUCCESS == dwResult )
  1260. {
  1261. hr = S_OK;
  1262. break;
  1263. }
  1264. // wait for dhcp to pick up connection
  1265. debugretprintf( UnicodeString.Buffer, hr );
  1266. Sleep( 1000 );
  1267. } // while ( --ulSeconds )
  1268. DhcpCApiCleanup();
  1269. } // if ( 0 == dwResult )
  1270. } // if ( SUCCEEDED(hr) )
  1271. RtlFreeUnicodeString( &UnicodeString );
  1272. TRACE_LEAVE("WaitForConnectionToInitialize", hr);
  1273. return hr;
  1274. }
  1275. HRESULT
  1276. SetIcsPrivateConnections(
  1277. IN CComPtr<IHNetCfgMgr> spIHNetCfgMgr,
  1278. IN INetConnection *pNetPrivateConnection[],
  1279. IN BOOLEAN bSharePublicConnection,
  1280. IN LPHNWCALLBACK lpHnwCallback,
  1281. IN LPARAM lpContext,
  1282. OUT INetConnection **pNetPrivateInterface
  1283. )
  1284. /*++
  1285. Routine Description:
  1286. Arguments:
  1287. Return Value:
  1288. hResult
  1289. --*/
  1290. {
  1291. HRESULT hr;
  1292. TRACE_ENTER("SetIcsPrivateConnections");
  1293. CComPtr<IHNetBridgeSettings> spIHNetBridgeSettings;
  1294. INetConnectionRefresh* pNetConnectionRefresh = NULL;
  1295. _ASSERT( spIHNetCfgMgr != NULL );
  1296. _ASSERT( NULL != pNetPrivateConnection );
  1297. if ( spIHNetCfgMgr == NULL )
  1298. {
  1299. hr = E_POINTER;
  1300. }
  1301. else if ( NULL == pNetPrivateConnection )
  1302. {
  1303. hr = E_INVALIDARG;
  1304. }
  1305. else
  1306. {
  1307. hr = spIHNetCfgMgr->QueryInterface( IID_PPV_ARG( IHNetBridgeSettings, &spIHNetBridgeSettings ) );
  1308. }
  1309. if ( SUCCEEDED(hr) )
  1310. {
  1311. hr = CoCreateInstance(CLSID_ConnectionManager, NULL, CLSCTX_SERVER, IID_INetConnectionRefresh, reinterpret_cast<void**>(&pNetConnectionRefresh));
  1312. if( SUCCEEDED(hr) )
  1313. {
  1314. _ASSERT( pNetConnectionRefresh );
  1315. pNetConnectionRefresh->DisableEvents( TRUE, MAX_DISABLE_EVENT_TIMEOUT );
  1316. }
  1317. else
  1318. {
  1319. pNetConnectionRefresh = NULL;
  1320. }
  1321. }
  1322. if ( SUCCEEDED(hr) )
  1323. {
  1324. CComPtr<IHNetConnection> spIHNC;
  1325. INetConnection **ppNC;
  1326. ULONG uIndex;
  1327. BOOLEAN bIsBridge;
  1328. INetCfg *pnetcfg = NULL;
  1329. INetCfgLock *pncfglock = NULL;
  1330. ppNC = pNetPrivateConnection;
  1331. bIsBridge = FALSE;
  1332. for ( uIndex=0L; NULL != *ppNC; ppNC++ )
  1333. {
  1334. _ASSERT( !IsBadReadPtr( *ppNC, sizeof( *ppNC ) ) );
  1335. if ( IsBadReadPtr( *ppNC, sizeof( *ppNC ) ) )
  1336. {
  1337. hr = E_POINTER;
  1338. break;
  1339. }
  1340. else
  1341. {
  1342. #if DBG
  1343. LPWSTR lpzwAdapterName;
  1344. HRESULT hrGetName;
  1345. hrGetName = HRGetConnectionAdapterName( *ppNC, &lpzwAdapterName );
  1346. if ( SUCCEEDED( hrGetName ) )
  1347. {
  1348. debugprintf( _T("\t"), lpzwAdapterName );
  1349. delete lpzwAdapterName;
  1350. }
  1351. #endif
  1352. // We only count this as a valid connection for valid pointers
  1353. uIndex++;
  1354. }
  1355. } // if ( SUCCEEDED(hr) )
  1356. if ( SUCCEEDED(hr) )
  1357. {
  1358. HRESULT hrWrite;
  1359. hrWrite = InitializeNetCfgForWrite( &pnetcfg, &pncfglock );
  1360. if ( 1 < uIndex )
  1361. {
  1362. CComPtr<IHNetBridge> spHNetBridge;
  1363. pNetConnectionRefresh->DisableEvents( TRUE, MAX_DISABLE_EVENT_TIMEOUT );
  1364. hr = spIHNetBridgeSettings->CreateBridge( &spHNetBridge, pnetcfg );
  1365. if ( S_OK == hr )
  1366. {
  1367. ULONG uCount;
  1368. ppNC = pNetPrivateConnection;
  1369. for ( uCount=0L; (NULL != *ppNC) && (uCount < uIndex); uCount++, ppNC++ )
  1370. {
  1371. pNetConnectionRefresh->DisableEvents( TRUE, MAX_DISABLE_EVENT_TIMEOUT );
  1372. hr = spIHNetCfgMgr->GetIHNetConnectionForINetConnection( *ppNC, &spIHNC );
  1373. if ( SUCCEEDED(hr) )
  1374. {
  1375. CComPtr<IHNetBridgedConnection> spBridgedConn;
  1376. hr = spHNetBridge->AddMember( spIHNC, &spBridgedConn, pnetcfg );
  1377. if ( S_OK == hr )
  1378. {
  1379. // Instantiating the IHNetBridgeConnection pointer with
  1380. // SharePublic results in updating our WMI store with
  1381. // the new bridge properties for this connection. This
  1382. // is our only goal at this time.
  1383. spBridgedConn.Release();
  1384. }
  1385. else
  1386. {
  1387. debugretprintf( _T("AddMember FAILED with "), hr );
  1388. }
  1389. // We no longer need this IHNetConnection reference
  1390. // so we NULL the smart pointer to release it.
  1391. spIHNC = NULL;
  1392. }
  1393. } // for ( uCount=0L; ...
  1394. hr = spHNetBridge->QueryInterface( IID_PPV_ARG( IHNetConnection, &spIHNC ) );
  1395. _ASSERT( SUCCEEDED(hr) );
  1396. if ( SUCCEEDED(hr) )
  1397. {
  1398. bIsBridge = TRUE;
  1399. UpdateHnwLog( lpHnwCallback, lpContext, IDS_NEWBRIDGECREATED );
  1400. }
  1401. else
  1402. {
  1403. UpdateHnwLog( lpHnwCallback, lpContext, IDS_NEWBRIDGEFAILED );
  1404. }
  1405. } // if ( SUCCEEDED(hr) )
  1406. } // if ( 1 < uIndex )
  1407. else if ( 1 == uIndex )
  1408. {
  1409. pNetConnectionRefresh->DisableEvents( TRUE, MAX_DISABLE_EVENT_TIMEOUT );
  1410. hr = spIHNetCfgMgr->GetIHNetConnectionForINetConnection( pNetPrivateConnection[0], &spIHNC );
  1411. _ASSERT( SUCCEEDED(hr) );
  1412. }
  1413. else
  1414. {
  1415. // We don't have ANY private connections so we null out
  1416. // this pointer to make sure we don't try to use it.
  1417. spIHNC = NULL;
  1418. }
  1419. if ( SUCCEEDED(hrWrite) )
  1420. {
  1421. UninitializeNetCfgForWrite( pnetcfg, pncfglock );
  1422. }
  1423. } // if ( SUCCEEDED(hr) )
  1424. else
  1425. {
  1426. // Some previous error condition occurred and we need to
  1427. // null out this pointer to make sure we don't try to use it.
  1428. spIHNC = NULL;
  1429. }
  1430. if ( bSharePublicConnection && SUCCEEDED(hr) && ( spIHNC != NULL ) )
  1431. {
  1432. OLECHAR *strAdapter = _T("Adapter");
  1433. OLECHAR *strName = strAdapter;
  1434. CComPtr<IHNetIcsPrivateConnection> spIcsPrivateConn;
  1435. // Get name of private connection candidate
  1436. if ( spIHNC != NULL )
  1437. {
  1438. if ( S_OK != spIHNC->GetName( &strName ) )
  1439. {
  1440. strName = strAdapter;
  1441. }
  1442. }
  1443. // Wait for connection to finish initialization and share it
  1444. if ( SUCCEEDED(hr) )
  1445. {
  1446. // if we are in ICS Upgrade, don't wait for dhcp
  1447. // service because it won't be running during GUI Mode Setup.
  1448. HANDLE hIcsUpgradeEvent = OpenEvent( EVENT_MODIFY_STATE, FALSE, c_wszIcsUpgradeEventName );
  1449. if ( NULL != hIcsUpgradeEvent )
  1450. {
  1451. CloseHandle( hIcsUpgradeEvent );
  1452. }
  1453. else
  1454. {
  1455. // We are running normally with dhcp so we must wait
  1456. // for dhcp to pick up the new bridge interface
  1457. pNetConnectionRefresh->DisableEvents( TRUE, MAX_DISABLE_EVENT_TIMEOUT );
  1458. hr = WaitForConnectionToInitialize( spIHNC, SECONDS_TO_WAIT_FOR_DHCP, bIsBridge );
  1459. if ( HRESULT_FROM_WIN32(ERROR_SHARING_NO_PRIVATE_LAN) == hr )
  1460. {
  1461. // If WaitForConnectionToInitialize can't get statistics then try
  1462. // SharePrivate anyway.
  1463. hr = S_OK;
  1464. }
  1465. }
  1466. if ( SUCCEEDED(hr) )
  1467. {
  1468. pNetConnectionRefresh->DisableEvents( TRUE, MAX_DISABLE_EVENT_TIMEOUT );
  1469. hr = spIHNC->SharePrivate( &spIcsPrivateConn );
  1470. }
  1471. }
  1472. if ( SUCCEEDED(hr) )
  1473. {
  1474. // We are only configuring the connection
  1475. // Instantiating the IHNetIcsPrivateConnection pointer with
  1476. // SharePublic results in updating our WMI store with
  1477. // the new private connection properties for this connection.
  1478. // Obtain Interface pointer to private connection if requested
  1479. if ( NULL != pNetPrivateInterface )
  1480. {
  1481. spIHNC->GetINetConnection( pNetPrivateInterface );
  1482. }
  1483. UpdateHnwLog( lpHnwCallback, lpContext, IDS_NEWPRIVATECONNECTIONCREATED, strName );
  1484. spIcsPrivateConn.Release();
  1485. debugprintf( _T("SharePrivate: "), strName );
  1486. }
  1487. else
  1488. {
  1489. UpdateHnwLog( lpHnwCallback, lpContext, IDS_NEWPRIVATECONNECTIONFAILED, strName );
  1490. debugretprintf( _T("SharePrivate FAILED with "), hr );
  1491. }
  1492. if ( strName != strAdapter )
  1493. {
  1494. CoTaskMemFree( strName );
  1495. }
  1496. } // if ( SUCCEEDED(hr) && ( spIHNC != NULL ) )
  1497. // We no longer need this IHNetConnection reference so we NULL the smart
  1498. // pointer to release it. If the smart pointer is all ready NULL then
  1499. // no release or AV will occur. We do this here because the smart pointer
  1500. // may be valid even though we did not enter the preceeding block.
  1501. spIHNC = NULL;
  1502. } // if ( SUCCEEDED(hr) )
  1503. if ( pNetConnectionRefresh )
  1504. {
  1505. pNetConnectionRefresh->DisableEvents( FALSE, 0L );
  1506. pNetConnectionRefresh->Release();
  1507. }
  1508. TRACE_LEAVE("SetIcsPrivateConnections", hr);
  1509. return hr;
  1510. }
  1511. HRESULT
  1512. DisableEverything(
  1513. IN CComPtr<IHNetCfgMgr> spIHNetCfgMgr,
  1514. IN INetConnection *pNetPublicConnection,
  1515. IN INetConnection *pNetPrivateConnection[],
  1516. IN LPHNWCALLBACK lpHnwCallback,
  1517. IN LPARAM lpContext
  1518. )
  1519. /*++
  1520. Routine Description:
  1521. Arguments:
  1522. Return Value:
  1523. hResult
  1524. --*/
  1525. {
  1526. HRESULT hr;
  1527. INetConnectionRefresh* pNetConnectionRefresh;
  1528. TRACE_ENTER("DisableEverything");
  1529. hr = CoCreateInstance(CLSID_ConnectionManager, NULL, CLSCTX_SERVER, IID_INetConnectionRefresh, reinterpret_cast<void**>(&pNetConnectionRefresh));
  1530. if( SUCCEEDED(hr) )
  1531. {
  1532. ULONG ulConnections;
  1533. pNetConnectionRefresh->DisableEvents( TRUE, MAX_DISABLE_EVENT_TIMEOUT );
  1534. if ( pNetPublicConnection )
  1535. {
  1536. IHNetConnection* pHNetPublicConnection;
  1537. hr = spIHNetCfgMgr->GetIHNetConnectionForINetConnection( pNetPublicConnection,
  1538. &pHNetPublicConnection );
  1539. if ( S_OK == hr )
  1540. {
  1541. IHNetFirewalledConnection* pPublicConnectionFirewall;
  1542. hr = pHNetPublicConnection->GetControlInterface( IID_IHNetFirewalledConnection,
  1543. (void**)&pPublicConnectionFirewall );
  1544. if ( SUCCEEDED(hr) )
  1545. {
  1546. hr = pPublicConnectionFirewall->Unfirewall();
  1547. pPublicConnectionFirewall->Release();
  1548. pPublicConnectionFirewall = NULL;
  1549. if ( FAILED(hr) )
  1550. {
  1551. UpdateHnwLog( lpHnwCallback, lpContext, IDS_DISABLEFIREWALLFAIL, hr );
  1552. }
  1553. }
  1554. pHNetPublicConnection->Release();
  1555. pHNetPublicConnection = NULL;
  1556. }
  1557. }
  1558. if ( pNetPrivateConnection && pNetPrivateConnection[0] )
  1559. {
  1560. INetConnection** ppNC = pNetPrivateConnection;
  1561. while ( *ppNC )
  1562. {
  1563. IHNetConnection* pHNetPrivateConnection;
  1564. _ASSERT( !IsBadReadPtr( *ppNC, sizeof( *ppNC ) ) );
  1565. if ( IsBadReadPtr( *ppNC, sizeof( *ppNC ) ) )
  1566. {
  1567. hr = E_POINTER;
  1568. break;
  1569. }
  1570. hr = spIHNetCfgMgr->GetIHNetConnectionForINetConnection( *ppNC,
  1571. &pHNetPrivateConnection );
  1572. if ( S_OK == hr )
  1573. {
  1574. IHNetFirewalledConnection* pPrivateConnectionFirewall;
  1575. hr = pHNetPrivateConnection->GetControlInterface( IID_IHNetFirewalledConnection,
  1576. (void**)&pPrivateConnectionFirewall );
  1577. if ( SUCCEEDED(hr) )
  1578. {
  1579. pNetConnectionRefresh->DisableEvents( TRUE, MAX_DISABLE_EVENT_TIMEOUT );
  1580. hr = pPrivateConnectionFirewall->Unfirewall();
  1581. pPrivateConnectionFirewall->Release();
  1582. pPrivateConnectionFirewall = NULL;
  1583. if ( FAILED(hr) )
  1584. {
  1585. UpdateHnwLog( lpHnwCallback, lpContext, IDS_DISABLEFIREWALLFAIL, hr );
  1586. }
  1587. }
  1588. pHNetPrivateConnection->Release();
  1589. pHNetPrivateConnection = NULL;
  1590. } // if ( S_OK == hr )
  1591. ppNC++;
  1592. } // while ( ppNC )
  1593. } // if ( pNetPrivateConnection && pNetPrivateConnection[0] )
  1594. {
  1595. CComQIPtr<IHNetBridgeSettings> spIHNetBridge = spIHNetCfgMgr;
  1596. if ( spIHNetBridge != NULL )
  1597. {
  1598. pNetConnectionRefresh->DisableEvents( TRUE, MAX_DISABLE_EVENT_TIMEOUT );
  1599. hr = spIHNetBridge->DestroyAllBridges( &ulConnections );
  1600. if ( FAILED(hr) )
  1601. {
  1602. UpdateHnwLog( lpHnwCallback, lpContext, IDS_DESTROYBRIDGEFAIL, hr );
  1603. }
  1604. }
  1605. }
  1606. {
  1607. CComQIPtr<IHNetIcsSettings> spIHNetIcs = spIHNetCfgMgr;
  1608. if ( spIHNetIcs != NULL )
  1609. {
  1610. ULONG ulPrivateConnections;
  1611. pNetConnectionRefresh->DisableEvents( TRUE, MAX_DISABLE_EVENT_TIMEOUT );
  1612. hr = spIHNetIcs->DisableIcs( &ulConnections, &ulPrivateConnections );
  1613. if ( FAILED(hr) )
  1614. {
  1615. UpdateHnwLog( lpHnwCallback, lpContext, IDS_DISABLEICS, hr );
  1616. }
  1617. }
  1618. }
  1619. pNetConnectionRefresh->DisableEvents( FALSE, 0L );
  1620. pNetConnectionRefresh->Release();
  1621. }
  1622. TRACE_LEAVE("DisableEverything", hr);
  1623. return hr;
  1624. }
  1625. extern
  1626. HRESULT APIENTRY
  1627. HNetSetShareAndBridgeSettings(
  1628. IN INetConnection *pNetPublicConnection,
  1629. IN INetConnection *pNetPrivateConnection[],
  1630. IN BOOLEAN bSharePublicConnection,
  1631. IN BOOLEAN bFirewallPublicConnection,
  1632. IN LPHNWCALLBACK lpHnwCallback,
  1633. IN LPARAM lpContext,
  1634. OUT INetConnection **pNetPrivateInterface
  1635. )
  1636. /*++
  1637. Routine Description:
  1638. Arguments:
  1639. Return Value:
  1640. hResult
  1641. --*/
  1642. {
  1643. TRACE_ENTER("HNetSetShareAndBridgeSettings");
  1644. HRESULT hr;
  1645. // Initialize returned interface pointer if necessary
  1646. if ( NULL != pNetPrivateInterface )
  1647. {
  1648. *pNetPrivateInterface = NULL;
  1649. }
  1650. // Create Homenet Configuration Manager COM Instance
  1651. // and obtain connection settings.
  1652. CComPtr<IHNetCfgMgr> spIHNetCfgMgr;
  1653. hr = spIHNetCfgMgr.CoCreateInstance( CLSID_HNetCfgMgr );
  1654. if ( SUCCEEDED(hr) )
  1655. {
  1656. DisableEverything( spIHNetCfgMgr,
  1657. pNetPublicConnection,
  1658. pNetPrivateConnection,
  1659. lpHnwCallback,
  1660. lpContext );
  1661. if ( NULL != pNetPublicConnection )
  1662. {
  1663. hr = SetIcsPublicConnection( spIHNetCfgMgr,
  1664. pNetPublicConnection,
  1665. bSharePublicConnection,
  1666. bFirewallPublicConnection,
  1667. lpHnwCallback,
  1668. lpContext );
  1669. }
  1670. if ( ( NULL != pNetPrivateConnection ) && ( NULL != pNetPrivateConnection[0] ) && SUCCEEDED(hr) )
  1671. {
  1672. hr = SetIcsPrivateConnections( spIHNetCfgMgr,
  1673. pNetPrivateConnection,
  1674. bSharePublicConnection,
  1675. lpHnwCallback,
  1676. lpContext,
  1677. pNetPrivateInterface );
  1678. }
  1679. if ( FAILED(hr) )
  1680. {
  1681. DisableEverything( spIHNetCfgMgr,
  1682. pNetPublicConnection,
  1683. pNetPrivateConnection,
  1684. lpHnwCallback,
  1685. lpContext );
  1686. }
  1687. }
  1688. else
  1689. {
  1690. UpdateHnwLog( lpHnwCallback, lpContext, IDS_SHARINGCONFIGURATIONUNAVAIL );
  1691. }
  1692. TRACE_LEAVE("HNetSetShareAndBridgeSettings", hr);
  1693. return hr;
  1694. }
  1695. extern
  1696. HRESULT APIENTRY
  1697. HNetGetShareAndBridgeSettings(
  1698. OUT INetConnection **ppNetPublicConnection,
  1699. OUT INetConnection ***ppNetPrivateConnection,
  1700. OUT BOOLEAN *pbSharePublicConnection,
  1701. OUT BOOLEAN *pbFirewallPublicConnection
  1702. )
  1703. /*++
  1704. Routine Description:
  1705. Arguments:
  1706. Return Value:
  1707. hResult
  1708. --*/
  1709. {
  1710. HRESULT hr;
  1711. TRACE_ENTER("HNetGetShareAndBridgeSettings");
  1712. // Create Homenet Configuration Manager COM Instance
  1713. // and obtain connection settings.
  1714. CComPtr<IHNetCfgMgr> spIHNetCfgMgr;
  1715. *ppNetPublicConnection = NULL;
  1716. *ppNetPrivateConnection = NULL;
  1717. *pbSharePublicConnection = FALSE;
  1718. *pbFirewallPublicConnection = FALSE;
  1719. hr = spIHNetCfgMgr.CoCreateInstance( CLSID_HNetCfgMgr );
  1720. if ( SUCCEEDED(hr) )
  1721. {
  1722. if ( NULL != ppNetPublicConnection )
  1723. {
  1724. hr = GetIcsPublicConnection( spIHNetCfgMgr,
  1725. ppNetPublicConnection,
  1726. pbSharePublicConnection,
  1727. pbFirewallPublicConnection );
  1728. }
  1729. if ( NULL != ppNetPrivateConnection )
  1730. {
  1731. hr = GetIcsPrivateConnections( spIHNetCfgMgr, ppNetPrivateConnection );
  1732. if ( S_OK == hr )
  1733. {
  1734. CComPtr<IHNetConnection> spIHNetConnection;
  1735. INetConnection **ppINetCon;
  1736. // Check first private connection to see if it is the bridge
  1737. hr = spIHNetCfgMgr->GetIHNetConnectionForINetConnection( (*ppNetPrivateConnection)[0],
  1738. &spIHNetConnection );
  1739. _ASSERT( SUCCEEDED(hr) );
  1740. if ( SUCCEEDED(hr) )
  1741. {
  1742. HNET_CONN_PROPERTIES *phncProperties;
  1743. hr = spIHNetConnection->GetProperties( &phncProperties );
  1744. if ( SUCCEEDED(hr) && ( NULL != phncProperties ) )
  1745. {
  1746. if ( phncProperties->fBridge )
  1747. {
  1748. // If Bridge, then release the private connection instances
  1749. // and get the list of bridged connections
  1750. for ( ppINetCon = *ppNetPrivateConnection; NULL != *ppINetCon; ppINetCon++ )
  1751. {
  1752. (*ppINetCon)->Release();
  1753. *ppINetCon = NULL;
  1754. }
  1755. NetApiBufferFree( *ppNetPrivateConnection );
  1756. *ppNetPrivateConnection = NULL;
  1757. hr = GetBridgedConnections( spIHNetCfgMgr, ppNetPrivateConnection );
  1758. } // if ( phncProperties->fBridge )
  1759. CoTaskMemFree( phncProperties );
  1760. } // if ( SUCCEEDED(hr) && ( NULL != phncProperties ) )
  1761. } // if ( SUCCEEDED(hr)
  1762. // What if we fail along this path? Then we need to release
  1763. // any private connection interface pointer held.
  1764. if ( FAILED(hr) && ( NULL != ppNetPrivateConnection ) )
  1765. {
  1766. for ( ppINetCon = *ppNetPrivateConnection; NULL != *ppINetCon; ppINetCon++ )
  1767. {
  1768. (*ppINetCon)->Release();
  1769. }
  1770. NetApiBufferFree( *ppNetPrivateConnection );
  1771. *ppNetPrivateConnection = NULL;
  1772. }
  1773. } // if ( S_OK == hr )
  1774. } // if ( NULL != ppNetPrivateConnection )
  1775. // If we fail along the way then we need to release the public interface
  1776. // and NULL the pointer so that it won't be used.
  1777. if ( FAILED(hr) && ( NULL != ppNetPublicConnection ) )
  1778. {
  1779. (*ppNetPublicConnection)->Release();
  1780. *ppNetPublicConnection = NULL;
  1781. }
  1782. } // if ( SUCCEEDED(hr) )
  1783. TRACE_LEAVE("HNetGetShareAndBridgeSettings", hr);
  1784. return hr;
  1785. }
  1786. HRESULT DisablePersonalFirewallOnAll()
  1787. /*++
  1788. Routine Description:
  1789. Disable firewall on all connections
  1790. Arguments:
  1791. Return Value:
  1792. hResult
  1793. --*/
  1794. {
  1795. HRESULT hr = S_OK;
  1796. CComPtr<IHNetCfgMgr> spIHNetCfgMgr;
  1797. TRACE_ENTER("DisablePersonalFirewallOnAll");
  1798. hr = CoCreateInstance(CLSID_HNetCfgMgr,
  1799. NULL,
  1800. CLSCTX_ALL,
  1801. IID_PPV_ARG(IHNetCfgMgr, &spIHNetCfgMgr));
  1802. if (SUCCEEDED(hr))
  1803. {
  1804. CComQIPtr<IHNetFirewallSettings> spIHNetFirewall = spIHNetCfgMgr;
  1805. if ( NULL != spIHNetFirewall.p )
  1806. {
  1807. ULONG ulConnections = 0;
  1808. hr = spIHNetFirewall->DisableAllFirewalling( &ulConnections );
  1809. }
  1810. else
  1811. {
  1812. hr = E_FAIL;
  1813. }
  1814. }
  1815. TRACE_LEAVE("DisablePersonalFirewallOnAll", hr);
  1816. return hr;
  1817. }
  1818. HRESULT EnablePersonalFirewallOnAll()
  1819. /*++
  1820. Routine Description:
  1821. Enable firewall on all connections that can be firewalled
  1822. Arguments:
  1823. Return Value:
  1824. hResult
  1825. --*/
  1826. {
  1827. HRESULT hr = S_OK;
  1828. HRESULT hrTemp = S_OK;
  1829. ULONG ulCount = 0;
  1830. CComPtr<IEnumNetConnection> spEnum;
  1831. // Get the net connection manager
  1832. CComPtr<INetConnectionManager> spConnMan;
  1833. CComPtr<INetConnection> spConn;
  1834. // Create Homenet Configuration Manager COM Instance
  1835. // and obtain connection settings.
  1836. CComPtr<IHNetCfgMgr> spIHNetCfgMgr;
  1837. TRACE_ENTER("EnablePersonalFirewallOnAll");
  1838. hr = CoCreateInstance(CLSID_HNetCfgMgr,
  1839. NULL,
  1840. CLSCTX_ALL,
  1841. IID_PPV_ARG(IHNetCfgMgr, &spIHNetCfgMgr));
  1842. if (FAILED(hr))
  1843. {
  1844. goto End;
  1845. }
  1846. //disable any previous firewall settings otherwise enabling
  1847. //firewall on the same connection twice will return errors
  1848. //We will continue do the enable firewall if this step fails
  1849. DisablePersonalFirewallOnAll();
  1850. hr = CoCreateInstance(CLSID_ConnectionManager,
  1851. NULL,
  1852. CLSCTX_ALL,
  1853. IID_PPV_ARG(INetConnectionManager, &spConnMan));
  1854. if (FAILED(hr))
  1855. {
  1856. goto End;
  1857. }
  1858. // Get the enumeration of connections
  1859. SetProxyBlanket(spConnMan);
  1860. hr = spConnMan->EnumConnections(NCME_DEFAULT, &spEnum);
  1861. if (FAILED(hr))
  1862. {
  1863. goto End;
  1864. }
  1865. SetProxyBlanket(spEnum);
  1866. hr = spEnum->Reset();
  1867. if (FAILED(hr))
  1868. {
  1869. goto End;
  1870. }
  1871. do
  1872. {
  1873. NETCON_PROPERTIES* pProps = NULL;
  1874. //release any previous ref count we hold
  1875. spConn = NULL;
  1876. hr = spEnum->Next(1, &spConn, &ulCount);
  1877. if (FAILED(hr) || 1 != ulCount)
  1878. {
  1879. break;
  1880. }
  1881. SetProxyBlanket(spConn);
  1882. hr = spConn->GetProperties(&pProps);
  1883. if (FAILED(hr) || NULL == pProps)
  1884. {
  1885. continue;
  1886. }
  1887. //ICF is available only for certain types of connections
  1888. if (NCM_PHONE == pProps->MediaType ||
  1889. NCM_ISDN == pProps->MediaType ||
  1890. NCM_PPPOE == pProps->MediaType ||
  1891. NCM_LAN == pProps->MediaType ||
  1892. NCM_TUNNEL == pProps->MediaType )
  1893. {
  1894. CComPtr<IHNetConnection> spHNetConnection;
  1895. //release the ref count if we are holding one
  1896. spHNetConnection = NULL;
  1897. hrTemp = spIHNetCfgMgr->GetIHNetConnectionForINetConnection(
  1898. spConn,
  1899. &spHNetConnection );
  1900. if (SUCCEEDED(hr))
  1901. {
  1902. hr = hrTemp;
  1903. }
  1904. if (SUCCEEDED(hrTemp))
  1905. {
  1906. //check whether the connect can be firewalled
  1907. HNET_CONN_PROPERTIES *phncProperties = NULL;
  1908. hrTemp = spHNetConnection->GetProperties( &phncProperties );
  1909. if (SUCCEEDED(hrTemp) && NULL != phncProperties)
  1910. {
  1911. if (phncProperties->fCanBeFirewalled)
  1912. {
  1913. CComPtr<IHNetFirewalledConnection> spFirewalledConn;
  1914. //turn on the firewall
  1915. hrTemp = spHNetConnection->Firewall( &spFirewalledConn );
  1916. }
  1917. CoTaskMemFree(phncProperties);
  1918. }
  1919. if (SUCCEEDED(hr))
  1920. {
  1921. hr = hrTemp;
  1922. }
  1923. }
  1924. }
  1925. NcFreeNetconProperties(pProps);
  1926. } while (SUCCEEDED(hr) && 1 == ulCount);
  1927. End:
  1928. TRACE_LEAVE("EnablePersonalFirewallOnAll", hr);
  1929. //normalize hr because we used IEnum
  1930. if (S_FALSE == hr)
  1931. {
  1932. hr = S_OK;
  1933. }
  1934. return hr;
  1935. }
  1936. extern "C"
  1937. BOOL
  1938. WINAPI
  1939. WinBomConfigureHomeNet(
  1940. LPCTSTR lpszUnattend,
  1941. LPCTSTR lpszSection
  1942. )
  1943. /*++
  1944. Routine Description:
  1945. Reads home networking settings from the specified unattend file and saves
  1946. those in current system that is already setup and running.
  1947. Arguments:
  1948. lpszUnattend [IN] Points to a string buffer which contains the full path
  1949. to the unattend file (winbom.ini in this case) with all
  1950. the home network settings.
  1951. lpszSection [IN] Points to a string buffer which contains the name of
  1952. the section which contains all the home network settings
  1953. in the unattend file specified above.
  1954. Return Value:
  1955. Returns TRUE if the settings were successfully read and saved to the system.
  1956. Otherwise returns FALSE to indicate something failed.
  1957. --*/
  1958. {
  1959. if (NULL == lpszSection || NULL == lpszUnattend)
  1960. return FALSE;
  1961. BOOL fRet = TRUE;
  1962. WCHAR szBuf[256] = {0};
  1963. DWORD dwRet = 0;
  1964. dwRet = GetPrivateProfileString(lpszSection,
  1965. c_szEnableFirewall,
  1966. _T(""),
  1967. szBuf,
  1968. sizeof(szBuf)/sizeof(szBuf[0]),
  1969. lpszUnattend);
  1970. if (dwRet)
  1971. {
  1972. if (0 == lstrcmpi(szBuf, c_szYes))
  1973. {
  1974. fRet = SUCCEEDED(EnablePersonalFirewallOnAll());
  1975. }
  1976. else if (0 == lstrcmpi(szBuf, c_szNo))
  1977. {
  1978. fRet = SUCCEEDED(DisablePersonalFirewallOnAll());
  1979. }
  1980. }
  1981. else
  1982. {
  1983. //if there is no EnableFirewall there, we should treat this
  1984. //as a success
  1985. fRet = TRUE;
  1986. }
  1987. return fRet;
  1988. }