Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

2796 lines
74 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. delete[] lpWideStr;
  411. }
  412. }
  413. else
  414. {
  415. hr = HrFromLastWin32Error();
  416. }
  417. return hr;
  418. }
  419. HRESULT
  420. CheckNetCfgWriteLock(
  421. IN LPHNWCALLBACK lpHnwCallback,
  422. IN LPARAM lpContext
  423. )
  424. /*++
  425. Routine Description:
  426. Arguments:
  427. Return Value:
  428. hResult
  429. --*/
  430. {
  431. HRESULT hr;
  432. INetCfg *pnetcfg = NULL;
  433. TRACE_ENTER("CheckNetCfgWriteLock");
  434. hr = CoCreateInstance( CLSID_CNetCfg, NULL, CLSCTX_SERVER, IID_PPV_ARG(INetCfg, &pnetcfg ) );
  435. if ( SUCCEEDED(hr) )
  436. {
  437. INetCfgLock *pncfglock = NULL;
  438. // Get the lock interface
  439. hr = pnetcfg->QueryInterface( IID_PPV_ARG(INetCfgLock, &pncfglock) );
  440. if ( SUCCEEDED(hr) )
  441. {
  442. // Get the NetCfg lock
  443. hr = pncfglock->AcquireWriteLock( 5, L"HNetCfg", NULL );
  444. if ( SUCCEEDED(hr) )
  445. {
  446. pncfglock->ReleaseWriteLock();
  447. }
  448. else
  449. {
  450. }
  451. pncfglock->Release();
  452. }
  453. else
  454. {
  455. }
  456. pnetcfg->Release();
  457. }
  458. else
  459. {
  460. }
  461. TRACE_LEAVE("CheckNetCfgWriteLock", hr);
  462. return hr;
  463. }
  464. HRESULT
  465. ArpForConflictingDhcpAddress(
  466. IN LPHNWCALLBACK lpHnwCallback,
  467. IN LPARAM lpContext
  468. )
  469. /*++
  470. Routine Description:
  471. Arguments:
  472. Return Value:
  473. hResult
  474. --*/
  475. {
  476. HRESULT hr = S_OK;
  477. WSADATA wsaData;
  478. int iWsaErr;
  479. TRACE_ENTER("ArpForConflictingDhcpAddress");
  480. iWsaErr = WSAStartup( 0x202, &wsaData );
  481. if ( 0 != iWsaErr )
  482. {
  483. hr = MAKE_HRESULT( SEVERITY_ERROR, FACILITY_INTERNET, iWsaErr );
  484. UpdateHnwLog( lpHnwCallback, lpContext, IDS_WSAERRORDURINGDETECTION, iWsaErr );
  485. }
  486. else
  487. {
  488. // Obtain required ICS server address
  489. ULONG TargetAddress, TargetMask;
  490. hr = ReadDhcpScopeSettings( &TargetAddress, &TargetMask );
  491. if ( SUCCEEDED(hr) )
  492. {
  493. // Retrieve the best interface for the target IP address,
  494. // and also perform a UDP-connect to determine the 'closest'
  495. // local IP address to the target IP address.
  496. ULONG InterfaceIndex;
  497. if ( GetBestInterface( TargetAddress, &InterfaceIndex ) != NO_ERROR )
  498. {
  499. int Length;
  500. SOCKADDR_IN SockAddrIn;
  501. SOCKET Socket;
  502. SockAddrIn.sin_family = AF_INET;
  503. SockAddrIn.sin_port = 0;
  504. SockAddrIn.sin_addr.s_addr = TargetAddress;
  505. Socket = socket( AF_INET, SOCK_DGRAM, IPPROTO_UDP );
  506. if ( INVALID_SOCKET != Socket )
  507. {
  508. iWsaErr = connect( Socket, (PSOCKADDR)&SockAddrIn, sizeof(SockAddrIn) );
  509. if ( NO_ERROR == iWsaErr )
  510. {
  511. iWsaErr = getsockname( Socket, ( PSOCKADDR)&SockAddrIn, &Length );
  512. }
  513. }
  514. else
  515. {
  516. iWsaErr = SOCKET_ERROR;
  517. }
  518. if ( NO_ERROR != iWsaErr )
  519. {
  520. hr = MAKE_SCODE( SEVERITY_ERROR, FACILITY_INTERNET, iWsaErr );
  521. UpdateHnwLog( lpHnwCallback, lpContext, IDS_WSAERRORDURINGDETECTION, iWsaErr );
  522. }
  523. else
  524. {
  525. // Make sure the target IP address isn't already cached,
  526. // by removing it from the ARP cache if present using the interface index
  527. // determined above.
  528. MIB_IPNETROW IpNetRow;
  529. DWORD dwError;
  530. CHAR HardwareAddress[6];
  531. ULONG HardwareAddressLength;
  532. ULONG SourceAddress;
  533. SourceAddress = SockAddrIn.sin_addr.s_addr;
  534. ZeroMemory( &IpNetRow, sizeof(IpNetRow) );
  535. IpNetRow.dwIndex = InterfaceIndex;
  536. IpNetRow.dwPhysAddrLen = 6;
  537. IpNetRow.dwAddr = TargetAddress;
  538. IpNetRow.dwType = MIB_IPNET_TYPE_INVALID;
  539. DeleteIpNetEntry( &IpNetRow );
  540. dwError = SendARP( TargetAddress, // destination IP address
  541. SourceAddress, // IP address of sender
  542. (PULONG)HardwareAddress, // returned physical address
  543. &HardwareAddressLength // length of returned physical addr.
  544. );
  545. if ( NO_ERROR == dwError )
  546. {
  547. TargetAddress = inet_addr( HardwareAddress );
  548. if ( TargetAddress != SourceAddress )
  549. {
  550. hr = E_ICSADDRESSCONFLICT;
  551. UpdateHnwLog( lpHnwCallback,
  552. lpContext,
  553. IDS_ICSADDRESSCONFLICTDETECTED,
  554. HardwareAddress );
  555. }
  556. else
  557. {
  558. hr = S_OK;
  559. }
  560. }
  561. else
  562. {
  563. hr = MAKE_SCODE( SEVERITY_ERROR, FACILITY_INTERNET, dwError );
  564. UpdateHnwLog( lpHnwCallback, lpContext, IDS_SENDARPERRORDURINGDETECTION, dwError );
  565. }
  566. }
  567. }
  568. }
  569. }
  570. TRACE_LEAVE("ArpForConflictingDhcpAddress", hr);
  571. return hr;
  572. }
  573. HRESULT
  574. ObtainIcsErrorConditions(
  575. IN LPHNWCALLBACK lpHnwCallback,
  576. IN LPARAM lpContext
  577. )
  578. /*++
  579. Routine Description:
  580. Arguments:
  581. Return Value:
  582. hResult
  583. --*/
  584. {
  585. HRESULT hr;
  586. TRACE_ENTER("ObtainIcsErrorConditions");
  587. hr = ArpForConflictingDhcpAddress( lpHnwCallback, lpContext );
  588. if ( SUCCEEDED(hr) )
  589. {
  590. hr = CheckNetCfgWriteLock( lpHnwCallback, lpContext );
  591. if ( SUCCEEDED(hr) )
  592. {
  593. // Create Homenet Configuration Manager COM Instance
  594. IHNetCfgMgr* pCfgMgr;
  595. hr = CoCreateInstance( CLSID_HNetCfgMgr,
  596. NULL,
  597. CLSCTX_INPROC_SERVER,
  598. IID_PPV_ARG(IHNetCfgMgr, &pCfgMgr) );
  599. if ( SUCCEEDED(hr) )
  600. {
  601. pCfgMgr->Release();
  602. }
  603. else
  604. {
  605. UpdateHnwLog( lpHnwCallback, lpContext, IDS_SHARINGCONFIGURATIONUNAVAIL );
  606. }
  607. }
  608. }
  609. TRACE_LEAVE("ObtainIcsErrorConditions", hr);
  610. return hr;
  611. }
  612. HRESULT
  613. HRGetConnectionAdapterName(
  614. INetConnection *pNetConnection,
  615. LPWSTR *ppzwAdapterName
  616. )
  617. /*++
  618. Routine Description:
  619. Arguments:
  620. Return Value:
  621. hResult
  622. --*/
  623. {
  624. HRESULT hr;
  625. TRACE_ENTER("HRGetConnectionAdapterName");
  626. if ( NULL == pNetConnection )
  627. {
  628. hr = E_INVALIDARG;
  629. }
  630. else if ( NULL == ppzwAdapterName )
  631. {
  632. hr = E_POINTER;
  633. }
  634. else
  635. {
  636. NETCON_PROPERTIES* pProps;
  637. *ppzwAdapterName = NULL;
  638. hr = pNetConnection->GetProperties(&pProps);
  639. if ( SUCCEEDED( hr ) )
  640. {
  641. *ppzwAdapterName = new WCHAR[ wcslen( pProps->pszwDeviceName ) + 1 ];
  642. if ( NULL != *ppzwAdapterName )
  643. {
  644. wcscpy( *ppzwAdapterName, pProps->pszwDeviceName );
  645. debugprintf( _T("\t"), *ppzwAdapterName );
  646. }
  647. else
  648. {
  649. hr = E_OUTOFMEMORY;
  650. }
  651. NcFreeNetconProperties( pProps );
  652. }
  653. }
  654. TRACE_LEAVE("HRGetConnectionAdapterName", hr);
  655. return hr;
  656. }
  657. HRESULT
  658. GetIcsPublicConnection(
  659. IN CComPtr<IHNetCfgMgr> spIHNetCfgMgr,
  660. OUT INetConnection **ppNetPublicConnection,
  661. OUT BOOLEAN *pbSharePublicConnection OPTIONAL,
  662. OUT BOOLEAN *pbFirewallPublicConnection OPTIONAL
  663. )
  664. /*++
  665. Routine Description:
  666. Arguments:
  667. Return Value:
  668. hResult
  669. --*/
  670. {
  671. HRESULT hr;
  672. TRACE_ENTER("GetIcsPublicConnection");
  673. CComPtr<IHNetIcsSettings> spIHNetIcsSettings;
  674. _ASSERT( spIHNetCfgMgr != NULL );
  675. _ASSERT( NULL != ppNetPublicConnection );
  676. if ( NULL == ppNetPublicConnection )
  677. {
  678. hr = E_POINTER;
  679. }
  680. else if ( spIHNetCfgMgr == NULL )
  681. {
  682. hr = E_INVALIDARG;
  683. *ppNetPublicConnection = NULL;
  684. }
  685. else
  686. {
  687. // initialize arguments
  688. *ppNetPublicConnection = NULL;
  689. if ( NULL != pbSharePublicConnection )
  690. *pbSharePublicConnection = FALSE;
  691. if ( NULL != pbFirewallPublicConnection )
  692. *pbFirewallPublicConnection = FALSE;
  693. // Obtain interface pointer
  694. hr = spIHNetCfgMgr->QueryInterface( IID_PPV_ARG( IHNetIcsSettings, &spIHNetIcsSettings ) );
  695. if ( SUCCEEDED(hr) )
  696. {
  697. hr = S_OK;
  698. }
  699. }
  700. if ( S_OK == hr )
  701. {
  702. CComPtr<IEnumHNetIcsPublicConnections> spehiPublic;
  703. if ( ( hr = spIHNetIcsSettings->EnumIcsPublicConnections( &spehiPublic ) ) == S_OK )
  704. {
  705. CComPtr<IHNetIcsPublicConnection> spIHNetIcsPublic;
  706. // obtain only the first IHNetIcsPublicConnetion
  707. if ( ( hr = spehiPublic->Next( 1, &spIHNetIcsPublic, NULL ) ) == S_OK )
  708. {
  709. // obtain pointer to IID_IHNetConnection interface of object
  710. CComPtr<IHNetConnection> spIHNetPublic;
  711. hr = spIHNetIcsPublic->QueryInterface( IID_PPV_ARG( IHNetConnection, &spIHNetPublic ) );
  712. _ASSERT( SUCCEEDED(hr) );
  713. if ( SUCCEEDED(hr) )
  714. {
  715. // The reference count will be decremented by the caller
  716. // if necessary. Notice we are using the caller's pointer
  717. // variable.
  718. hr = spIHNetPublic->GetINetConnection( ppNetPublicConnection );
  719. if ( SUCCEEDED(hr) )
  720. {
  721. HNET_CONN_PROPERTIES *phncProperties;
  722. hr = spIHNetPublic->GetProperties( &phncProperties );
  723. if ( SUCCEEDED(hr) && ( NULL != phncProperties ) )
  724. {
  725. if ( NULL != pbSharePublicConnection )
  726. *pbSharePublicConnection = phncProperties->fIcsPublic;
  727. if ( NULL != pbFirewallPublicConnection )
  728. *pbFirewallPublicConnection = phncProperties->fFirewalled;
  729. CoTaskMemFree( phncProperties );
  730. } //if ( SUCCEEDED(hr) && ( NULL != phncProperties ) )
  731. if ( FAILED(hr) )
  732. {
  733. (*ppNetPublicConnection)->Release();
  734. *ppNetPublicConnection = NULL;
  735. }
  736. } // if ( SUCCEEDED(hr) )
  737. } // if ( SUCCEEDED(hr) )
  738. } // if ( ( hr = pehiPublic->Next( 1, &sphicPublic, NULL ) ) == S_OK )
  739. } // if ( ( hr = pIHNetCfgMgr->EnumIcsPublicConnections( &pehiPublic ) ) == S_OK )
  740. }
  741. TRACE_LEAVE("GetIcsPublicConnection", hr);
  742. return hr;
  743. }
  744. HRESULT
  745. GetIcsPrivateConnections(
  746. IN CComPtr<IHNetCfgMgr> spIHNetCfgMgr,
  747. OUT INetConnection ***ppNetPrivateConnection
  748. )
  749. /*++
  750. Routine Description:
  751. Obtain the private connections enumerator and loop
  752. through enumeration twice. Set the required array
  753. length during the first enumeration. If the parameter
  754. array is big enough initialize it during the second
  755. enumeration.
  756. Arguments:
  757. Return Value:
  758. hResult
  759. --*/
  760. {
  761. HRESULT hr;
  762. ULONG ulArrayLength, ulListLength, uIndex;
  763. BOOLEAN bBufferAllocated;
  764. CComPtr<IHNetIcsSettings> spIHNetIcsSettings;
  765. IHNetIcsPrivateConnection *pIHNetIcsPrivate;
  766. IHNetIcsPrivateConnection **ppIHNetIPList;
  767. CComPtr<IEnumHNetIcsPrivateConnections> spehiPrivate;
  768. TRACE_ENTER("GetIcsPrivateConnections");
  769. _ASSERT( spIHNetCfgMgr != NULL );
  770. _ASSERT( NULL != ppNetPrivateConnection );
  771. if ( spIHNetCfgMgr == NULL )
  772. {
  773. hr = E_POINTER;
  774. }
  775. else if ( NULL == ppNetPrivateConnection )
  776. {
  777. hr = E_INVALIDARG;
  778. }
  779. else
  780. {
  781. // initialize local vars
  782. ulArrayLength = 0L;
  783. ulListLength = 0L;
  784. bBufferAllocated = FALSE;
  785. // Obtain interface pointer
  786. hr = spIHNetCfgMgr->QueryInterface( IID_PPV_ARG( IHNetIcsSettings, &spIHNetIcsSettings ) );
  787. if ( SUCCEEDED(hr) )
  788. {
  789. hr = S_OK;
  790. }
  791. } // else
  792. if ( S_OK == hr )
  793. {
  794. if ( ( hr = spIHNetIcsSettings->EnumIcsPrivateConnections( &spehiPrivate ) ) == S_OK )
  795. {
  796. while ( spehiPrivate->Next( 1, &pIHNetIcsPrivate, NULL ) == S_OK )
  797. {
  798. ulArrayLength++;
  799. pIHNetIcsPrivate->Release();
  800. }
  801. // releasing the enumeration interface now so we can re-initialize it later
  802. spehiPrivate = NULL;
  803. } // if ( ( hr = spIHNetIcsSettings->EnumIcsPublicConnections( &pehiPublic ) ) == S_OK )
  804. } // if ( S_OK == hr )
  805. if ( S_OK == hr )
  806. {
  807. if ( ( hr = spIHNetIcsSettings->EnumIcsPrivateConnections( &spehiPrivate ) ) == S_OK )
  808. {
  809. hr = spehiPrivate->Next( ulArrayLength, &pIHNetIcsPrivate, &ulListLength );
  810. if ( S_OK == hr )
  811. {
  812. // Allocate array of INetConnection pointers. There will
  813. // be on extra pointer element for the NULL pointer at the
  814. // end of the array. We allocate this buffer with
  815. // NetApiBufferAllocate so the buffer must be released using
  816. // NetApiBufferFree.
  817. NET_API_STATUS nErr;
  818. LPVOID lpvBuffer;
  819. ++ulArrayLength;
  820. nErr = NetApiBufferAllocate( ulArrayLength * sizeof(INetConnection *),
  821. (LPVOID *)ppNetPrivateConnection );
  822. if ( NERR_Success == nErr )
  823. {
  824. bBufferAllocated = TRUE;
  825. for ( uIndex = 0L; uIndex < ulArrayLength; uIndex++ )
  826. {
  827. (*ppNetPrivateConnection)[uIndex] = NULL;
  828. }
  829. }
  830. else
  831. {
  832. hr = E_OUTOFMEMORY;
  833. // must release IHNetIcsPrivateConnection instances
  834. ppIHNetIPList = &pIHNetIcsPrivate;
  835. for ( uIndex = 0L; uIndex < ulListLength; uIndex++ )
  836. {
  837. ppIHNetIPList[uIndex]->Release();
  838. }
  839. }
  840. } // if ( S_OK == hr )
  841. // done with enumeration interface pointer so we explicitly release it
  842. spehiPrivate = NULL;
  843. } // if ( ( hr = spIHNetIcsSettings->EnumIcsPublicConnections( &pehiPublic ) ) == S_OK )
  844. } // if ( S_OK == hr )
  845. if ( S_OK == hr )
  846. {
  847. ppIHNetIPList = &pIHNetIcsPrivate;
  848. for ( uIndex = 0L; uIndex < ulListLength; uIndex++ )
  849. {
  850. if ( uIndex < ulArrayLength - 1 )
  851. {
  852. CComPtr<IHNetConnection> spIHNetPrivate;
  853. hr = ppIHNetIPList[uIndex]->QueryInterface( IID_PPV_ARG( IHNetConnection, &spIHNetPrivate ) );
  854. _ASSERT( SUCCEEDED(hr) );
  855. if ( SUCCEEDED(hr) )
  856. {
  857. // We allow the caller to invoke Release for (*ppNetPrivateConnection)[uIndex]
  858. hr = spIHNetPrivate->GetINetConnection( &((*ppNetPrivateConnection)[uIndex]) );
  859. _ASSERT( SUCCEEDED(hr) );
  860. }
  861. } // if ( uIndex < uiArrayLength - 1 )
  862. ppIHNetIPList[uIndex]->Release();
  863. } // for ( uIndex = 0L; ...
  864. } // if ( S_OK == hr )
  865. if ( !SUCCEEDED(hr) )
  866. {
  867. // If we fail after allocating the buffer then we need release
  868. // references and buffer
  869. if ( bBufferAllocated )
  870. {
  871. for ( uIndex = 0L; uIndex < ulArrayLength; uIndex++ )
  872. {
  873. if ( NULL != (*ppNetPrivateConnection)[uIndex] )
  874. {
  875. (*ppNetPrivateConnection)[uIndex]->Release();
  876. }
  877. }
  878. NetApiBufferFree( *ppNetPrivateConnection );
  879. }
  880. }
  881. TRACE_LEAVE("GetIcsPrivateConnections", hr);
  882. return hr;
  883. }
  884. HRESULT
  885. GetBridge(
  886. IN CComPtr<IHNetCfgMgr> spIHNetCfgMgr,
  887. OUT IHNetBridge **ppBridge
  888. )
  889. /*++
  890. Routine Description:
  891. Obtain the bridge enumerator and loop through enumeration.
  892. Arguments:
  893. Return Value:
  894. --*/
  895. {
  896. HRESULT hr = E_INVALIDARG;
  897. TRACE_ENTER("GetBridge");
  898. _ASSERT( spIHNetCfgMgr != NULL );
  899. _ASSERT( NULL != ppBridge );
  900. if ( spIHNetCfgMgr == NULL )
  901. {
  902. hr = E_POINTER;
  903. }
  904. else if ( NULL == ppBridge )
  905. {
  906. hr = E_INVALIDARG;
  907. }
  908. else
  909. {
  910. CComPtr<IHNetBridgeSettings> spIHNetBridgeSettings;
  911. hr = spIHNetCfgMgr->QueryInterface( IID_PPV_ARG( IHNetBridgeSettings, &spIHNetBridgeSettings ) );
  912. if ( SUCCEEDED(hr) )
  913. {
  914. CComPtr<IEnumHNetBridges> spBridgeEnum;
  915. hr = spIHNetBridgeSettings->EnumBridges( &spBridgeEnum );
  916. if ( SUCCEEDED(hr) )
  917. {
  918. hr = spBridgeEnum->Next( 1, ppBridge, NULL );
  919. if ( S_FALSE == hr )
  920. {
  921. hr = E_FAIL;
  922. }
  923. // We allow the caller to invoke Release for *ppBridge
  924. }
  925. } // if ( SUCCEEDED(hr) )
  926. } // else
  927. TRACE_LEAVE("GetBridge", hr);
  928. return hr;
  929. }
  930. HRESULT
  931. GetBridgedConnections(
  932. IN CComPtr<IHNetCfgMgr> spIHNetCfgMgr,
  933. OUT INetConnection ***ppNetPrivateConnection
  934. )
  935. /*++
  936. Routine Description:
  937. Obtain the bridge connections enumerator and loop
  938. through enumeration twice. Set the required array
  939. length during the first enumeration. If the parameter
  940. array is big enough initialize it during the second
  941. enumeration.
  942. Arguments:
  943. Return Value:
  944. hResult
  945. --*/
  946. {
  947. HRESULT hr;
  948. ULONG ulArrayLength, ulListLength, uIndex;
  949. CComPtr<IHNetBridge> spBridge;
  950. CComPtr<IEnumHNetBridgedConnections> spEnum;
  951. IHNetBridgedConnection *pIHNetBridged;
  952. IHNetBridgedConnection **ppIHNetBridgeList;
  953. TRACE_ENTER("GetBridgedConnections");
  954. _ASSERT( spIHNetCfgMgr != NULL );
  955. _ASSERT( NULL != ppNetPrivateConnection );
  956. if ( NULL == ppNetPrivateConnection )
  957. {
  958. hr = E_POINTER;
  959. }
  960. else if ( spIHNetCfgMgr == NULL )
  961. {
  962. hr = E_INVALIDARG;
  963. *ppNetPrivateConnection = NULL;
  964. }
  965. else
  966. {
  967. // initialize arguments
  968. *ppNetPrivateConnection = NULL;
  969. ulArrayLength = 0L;
  970. ulListLength = 0L;
  971. // Obtain bridge interface pointer
  972. hr = GetBridge( spIHNetCfgMgr, &spBridge );
  973. } // else
  974. if ( S_OK == hr )
  975. {
  976. if ( ( hr = spBridge->EnumMembers( &spEnum ) ) == S_OK )
  977. {
  978. while ( spEnum->Next( 1, &pIHNetBridged, NULL ) == S_OK )
  979. {
  980. ulArrayLength++;
  981. pIHNetBridged->Release();
  982. }
  983. // releasing the enumeration interface instance so we can re-initialize it later
  984. spEnum = NULL;
  985. } // if ( ( hr = spBridge->EnumMembers( &spEnum ) ) == S_OK )
  986. } // if ( S_OK == hr )
  987. if ( S_OK == hr )
  988. {
  989. if ( ( hr = spBridge->EnumMembers( &spEnum ) ) == S_OK )
  990. {
  991. hr = spEnum->Next( ulArrayLength, &pIHNetBridged, &ulListLength );
  992. if ( S_OK == hr )
  993. {
  994. // Allocate array of INetConnection pointers. There will
  995. // be on extra pointer element for the NULL pointer at the
  996. // end of the array. We allocate this buffer with
  997. // NetApiBufferAllocate so the buffer must be released using
  998. // NetApiBufferFree.
  999. NET_API_STATUS nErr;
  1000. ++ulArrayLength;
  1001. nErr = NetApiBufferAllocate( ulArrayLength*sizeof(INetConnection *),
  1002. (LPVOID *)ppNetPrivateConnection );
  1003. if ( NERR_Success == nErr )
  1004. {
  1005. for ( uIndex = 0L; uIndex < ulArrayLength; uIndex++ )
  1006. {
  1007. (*ppNetPrivateConnection)[uIndex] = NULL;
  1008. }
  1009. }
  1010. else
  1011. {
  1012. hr = E_OUTOFMEMORY;
  1013. // must release IHNetIcsPrivateConnection instances
  1014. ppIHNetBridgeList = &pIHNetBridged;
  1015. for ( uIndex = 0L; uIndex < ulListLength; uIndex++ )
  1016. {
  1017. ppIHNetBridgeList[uIndex]->Release();
  1018. }
  1019. } // else
  1020. } // if ( S_OK == hr )
  1021. // releasing enumeration interface instance
  1022. spEnum = NULL;
  1023. } // if ( ( hr = pBridge->EnumMembers( &spEnum ) ) == S_OK )
  1024. } // if ( S_OK == hr )
  1025. if ( S_OK == hr )
  1026. {
  1027. ppIHNetBridgeList = &pIHNetBridged;
  1028. for ( uIndex = 0L; uIndex < ulListLength; uIndex++ )
  1029. {
  1030. if ( uIndex < ulArrayLength - 1 )
  1031. {
  1032. CComPtr<IHNetConnection> spIHNetPrivate;
  1033. hr = ppIHNetBridgeList[uIndex]->QueryInterface( IID_PPV_ARG( IHNetConnection, &spIHNetPrivate ) );
  1034. _ASSERT( SUCCEEDED(hr) );
  1035. if ( SUCCEEDED(hr) )
  1036. {
  1037. // We allow the caller to invoke Release for (*ppNetPrivateConnection)[uIndex]
  1038. hr = spIHNetPrivate->GetINetConnection( &((*ppNetPrivateConnection)[uIndex]) );
  1039. _ASSERT( SUCCEEDED(hr) );
  1040. }
  1041. } // if ( uIndex < uiArrayLength - 1 )
  1042. ppIHNetBridgeList[uIndex]->Release();
  1043. } // for ( uIndex = 0L; ...
  1044. } // if ( S_OK == hr )
  1045. TRACE_LEAVE("GetBridgedConnections", hr);
  1046. return hr;
  1047. }
  1048. HRESULT
  1049. SetIcsPublicConnection(
  1050. IN CComPtr<IHNetCfgMgr> spIHNetCfgMgr,
  1051. IN INetConnection *pNetPublicConnection,
  1052. IN BOOLEAN bSharePublicConnection,
  1053. IN BOOLEAN bFirewallPublicConnection,
  1054. IN LPHNWCALLBACK lpHnwCallback,
  1055. IN LPARAM lpContext
  1056. )
  1057. /*++
  1058. Routine Description:
  1059. Arguments:
  1060. Return Value:
  1061. hResult
  1062. --*/
  1063. {
  1064. HRESULT hr;
  1065. TRACE_ENTER("SetIcsPublicConnection");
  1066. _ASSERT( spIHNetCfgMgr != NULL );
  1067. _ASSERT( NULL != pNetPublicConnection );
  1068. if ( spIHNetCfgMgr == NULL )
  1069. {
  1070. hr = E_POINTER;
  1071. }
  1072. else if ( NULL == pNetPublicConnection )
  1073. {
  1074. hr = E_INVALIDARG;
  1075. }
  1076. else
  1077. {
  1078. INetConnectionRefresh* pNetConnectionRefresh;
  1079. hr = CoCreateInstance(CLSID_ConnectionManager, NULL, CLSCTX_SERVER, IID_INetConnectionRefresh, reinterpret_cast<void**>(&pNetConnectionRefresh));
  1080. if( SUCCEEDED(hr) )
  1081. {
  1082. _ASSERT( pNetConnectionRefresh );
  1083. pNetConnectionRefresh->DisableEvents( TRUE, MAX_DISABLE_EVENT_TIMEOUT );
  1084. OLECHAR *strAdapter = L"Adapter";
  1085. OLECHAR *strName = strAdapter;
  1086. CComPtr<IHNetConnection> spHNetConnection;
  1087. hr = spIHNetCfgMgr->GetIHNetConnectionForINetConnection( pNetPublicConnection,
  1088. &spHNetConnection );
  1089. if ( S_OK == hr )
  1090. {
  1091. if ( HRGetConnectionAdapterName( pNetPublicConnection, &strName ) != S_OK )
  1092. {
  1093. strName = strAdapter;
  1094. }
  1095. if ( bSharePublicConnection )
  1096. {
  1097. CComPtr<IHNetIcsPublicConnection> spIcsPublicConn;
  1098. hr = spHNetConnection->SharePublic( &spIcsPublicConn );
  1099. if ( SUCCEEDED(hr) )
  1100. {
  1101. // Instantiating the IHNetIcsPublicConnection pointer with
  1102. // SharePublic results in updating our WMI store with
  1103. // the new sharing properties for this connection. This
  1104. // is our only goal at this time.
  1105. //
  1106. // set the power scheme!
  1107. //
  1108. if (!SetActivePwrScheme(3, NULL, NULL)) {
  1109. debugprintf( _T("Unable to set power scheme to always on\n"), strName);
  1110. }
  1111. UpdateHnwLog( lpHnwCallback, lpContext, IDS_NEWPUBLICCONNECTIONCREATED, strName );
  1112. spIcsPublicConn.Release();
  1113. debugprintf( _T("\t"), strName );
  1114. }
  1115. else
  1116. {
  1117. UpdateHnwLog( lpHnwCallback, lpContext, IDS_NEWPUBLICCONNECTIONFAILED, strName );
  1118. }
  1119. } // if ( bSharePublicConnection )
  1120. if ( SUCCEEDED(hr) && bFirewallPublicConnection )
  1121. {
  1122. CComPtr<IHNetFirewalledConnection> spFirewalledConn;
  1123. hr = spHNetConnection->Firewall( &spFirewalledConn );
  1124. if ( SUCCEEDED(hr) )
  1125. {
  1126. // Instantiating the IHNetFirewalledConnection pointer with
  1127. // SharePublic results in updating our WMI store with
  1128. // the new firewall properties for this connection. This
  1129. // is our only goal at this time.
  1130. UpdateHnwLog( lpHnwCallback, lpContext, IDS_FIREWALLCONNECTION, strName );
  1131. spFirewalledConn.Release();
  1132. }
  1133. else
  1134. {
  1135. UpdateHnwLog( lpHnwCallback, lpContext, IDS_FIREWALLCONNECTIONFAILED, strName );
  1136. }
  1137. } // if ( SUCCEEDED(hr) && bFirewallPublicConnection )
  1138. } // if ( S_OK == hr )
  1139. else
  1140. {
  1141. UpdateHnwLog( lpHnwCallback, lpContext, IDS_SHARINGCFGFORADAPTERUNAVAIL, strName );
  1142. }
  1143. if ( strName != strAdapter )
  1144. {
  1145. delete strName;
  1146. }
  1147. pNetConnectionRefresh->DisableEvents( FALSE, 0L );
  1148. pNetConnectionRefresh->Release();
  1149. } // if( SUCCEEDED(hr) )
  1150. } // else
  1151. TRACE_LEAVE("SetIcsPublicConnection", hr);
  1152. return hr;
  1153. }
  1154. HRESULT WaitForConnectionToInitialize(
  1155. IN CComPtr<IHNetConnection> spIHNC,
  1156. IN ULONG ulSeconds,
  1157. IN BOOLEAN bIsBridge
  1158. )
  1159. {
  1160. HRESULT hr;
  1161. GUID *pGuid;
  1162. UNICODE_STRING UnicodeString;
  1163. TRACE_ENTER("WaitForConnectionToInitialize");
  1164. ZeroMemory( &UnicodeString, sizeof(UnicodeString) );
  1165. hr = spIHNC->GetGuid( &pGuid );
  1166. if ( SUCCEEDED(hr) )
  1167. {
  1168. NTSTATUS Status = RtlStringFromGUID( *pGuid, &UnicodeString );
  1169. hr = ( STATUS_SUCCESS == Status ) ? S_OK : E_FAIL;
  1170. CoTaskMemFree( pGuid );
  1171. }
  1172. pGuid = NULL;
  1173. #ifdef WAIT_FOR_MEDIA_STATUS_CONNECTED
  1174. if ( SUCCEEDED(hr) && bIsBridge )
  1175. {
  1176. // Query the state of the connection. Try to wait for the
  1177. // bridge to build the spanning tree and report media state connected.
  1178. LPWSTR pwsz;
  1179. // Build a buffer large enough for the device string
  1180. pwsz = new WCHAR[ sizeof(c_wszDevice)/sizeof(WCHAR) + UnicodeString.Length/sizeof(WCHAR) + 1 ];
  1181. if ( NULL != pwsz )
  1182. {
  1183. UNICODE_STRING DeviceString;
  1184. NIC_STATISTICS NdisStatistics;
  1185. ULONG ulTimeout;
  1186. swprintf( pwsz, L"%s%s", c_wszDevice, UnicodeString.Buffer );
  1187. ulTimeout = SECONDS_TO_WAIT_FOR_BRIDGE;
  1188. RtlInitUnicodeString( &DeviceString, pwsz );
  1189. do
  1190. {
  1191. ZeroMemory( &NdisStatistics, sizeof(NdisStatistics) );
  1192. NdisStatistics.Size = sizeof(NdisStatistics);
  1193. NdisQueryStatistics( &DeviceString, &NdisStatistics );
  1194. if ( NdisStatistics.MediaState == MEDIA_STATE_UNKNOWN )
  1195. {
  1196. hr = HRESULT_FROM_WIN32(ERROR_SHARING_HOST_ADDRESS_CONFLICT);
  1197. }
  1198. else if ( NdisStatistics.DeviceState != DEVICE_STATE_CONNECTED ||
  1199. NdisStatistics.MediaState != MEDIA_STATE_CONNECTED )
  1200. {
  1201. hr = HRESULT_FROM_WIN32(ERROR_SHARING_NO_PRIVATE_LAN);
  1202. }
  1203. else
  1204. {
  1205. // AHA! Bridge initialized!
  1206. hr = S_OK;
  1207. break;
  1208. }
  1209. debugretprintf( pwsz, hr );
  1210. Sleep( 1000 );
  1211. }
  1212. while ( ulTimeout-- );
  1213. delete [] pwsz;
  1214. } // if ( NULL != pwsz )
  1215. } // if ( SUCCEEDED(hr) && bIsBridge )
  1216. #endif
  1217. if ( SUCCEEDED(hr) )
  1218. {
  1219. DWORD dwResult;
  1220. DWORD dwVersion; // version of the DHCP Client Options API reported
  1221. hr = HRESULT_FROM_WIN32(ERROR_SHARING_NO_PRIVATE_LAN);
  1222. dwResult = DhcpCApiInitialize( &dwVersion );
  1223. if ( ERROR_SUCCESS == dwResult )
  1224. {
  1225. DHCPCAPI_PARAMS requests[1] = { {0, OPTION_SUBNET_MASK, FALSE, NULL, 0} }; // subnet mask
  1226. DHCPCAPI_PARAMS_ARRAY sendarray = { 0, NULL }; // we aren't sending anything
  1227. DHCPCAPI_PARAMS_ARRAY requestarray = { 1, requests }; // we are requesting 2 items
  1228. while ( --ulSeconds )
  1229. {
  1230. DWORD dwSize = INITIAL_BUFFER_SIZE; // size of buffer for options
  1231. LPBYTE buffer = NULL; // buffer for options
  1232. IN_ADDR addr; // address in return code
  1233. do
  1234. {
  1235. if ( NULL != buffer )
  1236. {
  1237. LocalFree( buffer );
  1238. }
  1239. buffer = (LPBYTE) LocalAlloc( LPTR, dwSize ); // allocate the buffer
  1240. if ( NULL == buffer )
  1241. {
  1242. break;
  1243. }
  1244. // make the request on the adapter
  1245. dwResult = DhcpRequestParams( DHCPCAPI_REQUEST_SYNCHRONOUS,
  1246. NULL,
  1247. UnicodeString.Buffer,
  1248. NULL,
  1249. sendarray,
  1250. requestarray,
  1251. buffer,
  1252. &dwSize,
  1253. NULL );
  1254. }
  1255. while ( ERROR_MORE_DATA == dwResult );
  1256. if ( NULL != buffer )
  1257. {
  1258. LocalFree( buffer );
  1259. }
  1260. if ( ERROR_SUCCESS == dwResult )
  1261. {
  1262. hr = S_OK;
  1263. break;
  1264. }
  1265. // wait for dhcp to pick up connection
  1266. debugretprintf( UnicodeString.Buffer, hr );
  1267. Sleep( 1000 );
  1268. } // while ( --ulSeconds )
  1269. DhcpCApiCleanup();
  1270. } // if ( 0 == dwResult )
  1271. } // if ( SUCCEEDED(hr) )
  1272. RtlFreeUnicodeString( &UnicodeString );
  1273. TRACE_LEAVE("WaitForConnectionToInitialize", hr);
  1274. return hr;
  1275. }
  1276. HRESULT
  1277. SetIcsPrivateConnections(
  1278. IN CComPtr<IHNetCfgMgr> spIHNetCfgMgr,
  1279. IN INetConnection *pNetPrivateConnection[],
  1280. IN BOOLEAN bSharePublicConnection,
  1281. IN LPHNWCALLBACK lpHnwCallback,
  1282. IN LPARAM lpContext,
  1283. OUT INetConnection **pNetPrivateInterface
  1284. )
  1285. /*++
  1286. Routine Description:
  1287. Arguments:
  1288. Return Value:
  1289. hResult
  1290. --*/
  1291. {
  1292. HRESULT hr;
  1293. TRACE_ENTER("SetIcsPrivateConnections");
  1294. CComPtr<IHNetBridgeSettings> spIHNetBridgeSettings;
  1295. INetConnectionRefresh* pNetConnectionRefresh = NULL;
  1296. _ASSERT( spIHNetCfgMgr != NULL );
  1297. _ASSERT( NULL != pNetPrivateConnection );
  1298. if ( spIHNetCfgMgr == NULL )
  1299. {
  1300. hr = E_POINTER;
  1301. }
  1302. else if ( NULL == pNetPrivateConnection )
  1303. {
  1304. hr = E_INVALIDARG;
  1305. }
  1306. else
  1307. {
  1308. hr = spIHNetCfgMgr->QueryInterface( IID_PPV_ARG( IHNetBridgeSettings, &spIHNetBridgeSettings ) );
  1309. }
  1310. if ( SUCCEEDED(hr) )
  1311. {
  1312. hr = CoCreateInstance(CLSID_ConnectionManager, NULL, CLSCTX_SERVER, IID_INetConnectionRefresh, reinterpret_cast<void**>(&pNetConnectionRefresh));
  1313. if( SUCCEEDED(hr) )
  1314. {
  1315. _ASSERT( pNetConnectionRefresh );
  1316. pNetConnectionRefresh->DisableEvents( TRUE, MAX_DISABLE_EVENT_TIMEOUT );
  1317. }
  1318. else
  1319. {
  1320. pNetConnectionRefresh = NULL;
  1321. }
  1322. }
  1323. if ( SUCCEEDED(hr) )
  1324. {
  1325. CComPtr<IHNetConnection> spIHNC;
  1326. INetConnection **ppNC;
  1327. ULONG uIndex;
  1328. BOOLEAN bIsBridge;
  1329. INetCfg *pnetcfg = NULL;
  1330. INetCfgLock *pncfglock = NULL;
  1331. ppNC = pNetPrivateConnection;
  1332. bIsBridge = FALSE;
  1333. for ( uIndex=0L; NULL != *ppNC; ppNC++ )
  1334. {
  1335. _ASSERT( !IsBadReadPtr( *ppNC, sizeof( *ppNC ) ) );
  1336. if ( IsBadReadPtr( *ppNC, sizeof( *ppNC ) ) )
  1337. {
  1338. hr = E_POINTER;
  1339. break;
  1340. }
  1341. else
  1342. {
  1343. #if DBG
  1344. LPWSTR lpzwAdapterName;
  1345. HRESULT hrGetName;
  1346. hrGetName = HRGetConnectionAdapterName( *ppNC, &lpzwAdapterName );
  1347. if ( SUCCEEDED( hrGetName ) )
  1348. {
  1349. debugprintf( _T("\t"), lpzwAdapterName );
  1350. delete lpzwAdapterName;
  1351. }
  1352. #endif
  1353. // We only count this as a valid connection for valid pointers
  1354. uIndex++;
  1355. }
  1356. } // if ( SUCCEEDED(hr) )
  1357. if ( SUCCEEDED(hr) )
  1358. {
  1359. HRESULT hrWrite;
  1360. hrWrite = InitializeNetCfgForWrite( &pnetcfg, &pncfglock );
  1361. if ( 1 < uIndex )
  1362. {
  1363. CComPtr<IHNetBridge> spHNetBridge;
  1364. pNetConnectionRefresh->DisableEvents( TRUE, MAX_DISABLE_EVENT_TIMEOUT );
  1365. hr = spIHNetBridgeSettings->CreateBridge( &spHNetBridge, pnetcfg );
  1366. if ( S_OK == hr )
  1367. {
  1368. ULONG uCount;
  1369. ppNC = pNetPrivateConnection;
  1370. for ( uCount=0L; (NULL != *ppNC) && (uCount < uIndex); uCount++, ppNC++ )
  1371. {
  1372. pNetConnectionRefresh->DisableEvents( TRUE, MAX_DISABLE_EVENT_TIMEOUT );
  1373. hr = spIHNetCfgMgr->GetIHNetConnectionForINetConnection( *ppNC, &spIHNC );
  1374. if ( SUCCEEDED(hr) )
  1375. {
  1376. CComPtr<IHNetBridgedConnection> spBridgedConn;
  1377. hr = spHNetBridge->AddMember( spIHNC, &spBridgedConn, pnetcfg );
  1378. if ( S_OK == hr )
  1379. {
  1380. // Instantiating the IHNetBridgeConnection pointer with
  1381. // SharePublic results in updating our WMI store with
  1382. // the new bridge properties for this connection. This
  1383. // is our only goal at this time.
  1384. spBridgedConn.Release();
  1385. }
  1386. else
  1387. {
  1388. debugretprintf( _T("AddMember FAILED with "), hr );
  1389. }
  1390. // We no longer need this IHNetConnection reference
  1391. // so we NULL the smart pointer to release it.
  1392. spIHNC = NULL;
  1393. }
  1394. } // for ( uCount=0L; ...
  1395. hr = spHNetBridge->QueryInterface( IID_PPV_ARG( IHNetConnection, &spIHNC ) );
  1396. _ASSERT( SUCCEEDED(hr) );
  1397. if ( SUCCEEDED(hr) )
  1398. {
  1399. bIsBridge = TRUE;
  1400. UpdateHnwLog( lpHnwCallback, lpContext, IDS_NEWBRIDGECREATED );
  1401. }
  1402. else
  1403. {
  1404. UpdateHnwLog( lpHnwCallback, lpContext, IDS_NEWBRIDGEFAILED );
  1405. }
  1406. } // if ( SUCCEEDED(hr) )
  1407. } // if ( 1 < uIndex )
  1408. else if ( 1 == uIndex )
  1409. {
  1410. pNetConnectionRefresh->DisableEvents( TRUE, MAX_DISABLE_EVENT_TIMEOUT );
  1411. hr = spIHNetCfgMgr->GetIHNetConnectionForINetConnection( pNetPrivateConnection[0], &spIHNC );
  1412. _ASSERT( SUCCEEDED(hr) );
  1413. }
  1414. else
  1415. {
  1416. // We don't have ANY private connections so we null out
  1417. // this pointer to make sure we don't try to use it.
  1418. spIHNC = NULL;
  1419. }
  1420. if ( SUCCEEDED(hrWrite) )
  1421. {
  1422. UninitializeNetCfgForWrite( pnetcfg, pncfglock );
  1423. }
  1424. } // if ( SUCCEEDED(hr) )
  1425. else
  1426. {
  1427. // Some previous error condition occurred and we need to
  1428. // null out this pointer to make sure we don't try to use it.
  1429. spIHNC = NULL;
  1430. }
  1431. if ( bSharePublicConnection && SUCCEEDED(hr) && ( spIHNC != NULL ) )
  1432. {
  1433. OLECHAR *strAdapter = _T("Adapter");
  1434. OLECHAR *strName = strAdapter;
  1435. CComPtr<IHNetIcsPrivateConnection> spIcsPrivateConn;
  1436. // Get name of private connection candidate
  1437. if ( spIHNC != NULL )
  1438. {
  1439. if ( S_OK != spIHNC->GetName( &strName ) )
  1440. {
  1441. strName = strAdapter;
  1442. }
  1443. }
  1444. // Wait for connection to finish initialization and share it
  1445. if ( SUCCEEDED(hr) )
  1446. {
  1447. // if we are in ICS Upgrade, don't wait for dhcp
  1448. // service because it won't be running during GUI Mode Setup.
  1449. HANDLE hIcsUpgradeEvent = OpenEvent( EVENT_MODIFY_STATE, FALSE, c_wszIcsUpgradeEventName );
  1450. if ( NULL != hIcsUpgradeEvent )
  1451. {
  1452. CloseHandle( hIcsUpgradeEvent );
  1453. }
  1454. else
  1455. {
  1456. // We are running normally with dhcp so we must wait
  1457. // for dhcp to pick up the new bridge interface
  1458. pNetConnectionRefresh->DisableEvents( TRUE, MAX_DISABLE_EVENT_TIMEOUT );
  1459. hr = WaitForConnectionToInitialize( spIHNC, SECONDS_TO_WAIT_FOR_DHCP, bIsBridge );
  1460. if ( HRESULT_FROM_WIN32(ERROR_SHARING_NO_PRIVATE_LAN) == hr )
  1461. {
  1462. // If WaitForConnectionToInitialize can't get statistics then try
  1463. // SharePrivate anyway.
  1464. hr = S_OK;
  1465. }
  1466. }
  1467. if ( SUCCEEDED(hr) )
  1468. {
  1469. pNetConnectionRefresh->DisableEvents( TRUE, MAX_DISABLE_EVENT_TIMEOUT );
  1470. hr = spIHNC->SharePrivate( &spIcsPrivateConn );
  1471. }
  1472. }
  1473. if ( SUCCEEDED(hr) )
  1474. {
  1475. // We are only configuring the connection
  1476. // Instantiating the IHNetIcsPrivateConnection pointer with
  1477. // SharePublic results in updating our WMI store with
  1478. // the new private connection properties for this connection.
  1479. // Obtain Interface pointer to private connection if requested
  1480. if ( NULL != pNetPrivateInterface )
  1481. {
  1482. spIHNC->GetINetConnection( pNetPrivateInterface );
  1483. }
  1484. UpdateHnwLog( lpHnwCallback, lpContext, IDS_NEWPRIVATECONNECTIONCREATED, strName );
  1485. spIcsPrivateConn.Release();
  1486. debugprintf( _T("SharePrivate: "), strName );
  1487. }
  1488. else
  1489. {
  1490. UpdateHnwLog( lpHnwCallback, lpContext, IDS_NEWPRIVATECONNECTIONFAILED, strName );
  1491. debugretprintf( _T("SharePrivate FAILED with "), hr );
  1492. }
  1493. if ( strName != strAdapter )
  1494. {
  1495. CoTaskMemFree( strName );
  1496. }
  1497. } // if ( SUCCEEDED(hr) && ( spIHNC != NULL ) )
  1498. // We no longer need this IHNetConnection reference so we NULL the smart
  1499. // pointer to release it. If the smart pointer is all ready NULL then
  1500. // no release or AV will occur. We do this here because the smart pointer
  1501. // may be valid even though we did not enter the preceeding block.
  1502. spIHNC = NULL;
  1503. } // if ( SUCCEEDED(hr) )
  1504. if ( pNetConnectionRefresh )
  1505. {
  1506. pNetConnectionRefresh->DisableEvents( FALSE, 0L );
  1507. pNetConnectionRefresh->Release();
  1508. }
  1509. TRACE_LEAVE("SetIcsPrivateConnections", hr);
  1510. return hr;
  1511. }
  1512. HRESULT
  1513. DisableEverything(
  1514. IN CComPtr<IHNetCfgMgr> spIHNetCfgMgr,
  1515. IN INetConnection *pNetPublicConnection,
  1516. IN INetConnection *pNetPrivateConnection[],
  1517. IN LPHNWCALLBACK lpHnwCallback,
  1518. IN LPARAM lpContext
  1519. )
  1520. /*++
  1521. Routine Description:
  1522. Arguments:
  1523. Return Value:
  1524. hResult
  1525. --*/
  1526. {
  1527. HRESULT hr;
  1528. INetConnectionRefresh* pNetConnectionRefresh;
  1529. TRACE_ENTER("DisableEverything");
  1530. hr = CoCreateInstance(CLSID_ConnectionManager, NULL, CLSCTX_SERVER, IID_INetConnectionRefresh, reinterpret_cast<void**>(&pNetConnectionRefresh));
  1531. if( SUCCEEDED(hr) )
  1532. {
  1533. ULONG ulConnections;
  1534. pNetConnectionRefresh->DisableEvents( TRUE, MAX_DISABLE_EVENT_TIMEOUT );
  1535. if ( pNetPublicConnection )
  1536. {
  1537. IHNetConnection* pHNetPublicConnection;
  1538. hr = spIHNetCfgMgr->GetIHNetConnectionForINetConnection( pNetPublicConnection,
  1539. &pHNetPublicConnection );
  1540. if ( S_OK == hr )
  1541. {
  1542. IHNetFirewalledConnection* pPublicConnectionFirewall;
  1543. hr = pHNetPublicConnection->GetControlInterface( IID_IHNetFirewalledConnection,
  1544. (void**)&pPublicConnectionFirewall );
  1545. if ( SUCCEEDED(hr) )
  1546. {
  1547. hr = pPublicConnectionFirewall->Unfirewall();
  1548. pPublicConnectionFirewall->Release();
  1549. pPublicConnectionFirewall = NULL;
  1550. if ( FAILED(hr) )
  1551. {
  1552. UpdateHnwLog( lpHnwCallback, lpContext, IDS_DISABLEFIREWALLFAIL, hr );
  1553. }
  1554. }
  1555. pHNetPublicConnection->Release();
  1556. pHNetPublicConnection = NULL;
  1557. }
  1558. }
  1559. if ( pNetPrivateConnection && pNetPrivateConnection[0] )
  1560. {
  1561. INetConnection** ppNC = pNetPrivateConnection;
  1562. while ( *ppNC )
  1563. {
  1564. IHNetConnection* pHNetPrivateConnection;
  1565. _ASSERT( !IsBadReadPtr( *ppNC, sizeof( *ppNC ) ) );
  1566. if ( IsBadReadPtr( *ppNC, sizeof( *ppNC ) ) )
  1567. {
  1568. hr = E_POINTER;
  1569. break;
  1570. }
  1571. hr = spIHNetCfgMgr->GetIHNetConnectionForINetConnection( *ppNC,
  1572. &pHNetPrivateConnection );
  1573. if ( S_OK == hr )
  1574. {
  1575. IHNetFirewalledConnection* pPrivateConnectionFirewall;
  1576. hr = pHNetPrivateConnection->GetControlInterface( IID_IHNetFirewalledConnection,
  1577. (void**)&pPrivateConnectionFirewall );
  1578. if ( SUCCEEDED(hr) )
  1579. {
  1580. pNetConnectionRefresh->DisableEvents( TRUE, MAX_DISABLE_EVENT_TIMEOUT );
  1581. hr = pPrivateConnectionFirewall->Unfirewall();
  1582. pPrivateConnectionFirewall->Release();
  1583. pPrivateConnectionFirewall = NULL;
  1584. if ( FAILED(hr) )
  1585. {
  1586. UpdateHnwLog( lpHnwCallback, lpContext, IDS_DISABLEFIREWALLFAIL, hr );
  1587. }
  1588. }
  1589. pHNetPrivateConnection->Release();
  1590. pHNetPrivateConnection = NULL;
  1591. } // if ( S_OK == hr )
  1592. ppNC++;
  1593. } // while ( ppNC )
  1594. } // if ( pNetPrivateConnection && pNetPrivateConnection[0] )
  1595. {
  1596. CComQIPtr<IHNetBridgeSettings> spIHNetBridge = spIHNetCfgMgr;
  1597. if ( spIHNetBridge != NULL )
  1598. {
  1599. pNetConnectionRefresh->DisableEvents( TRUE, MAX_DISABLE_EVENT_TIMEOUT );
  1600. hr = spIHNetBridge->DestroyAllBridges( &ulConnections );
  1601. if ( FAILED(hr) )
  1602. {
  1603. UpdateHnwLog( lpHnwCallback, lpContext, IDS_DESTROYBRIDGEFAIL, hr );
  1604. }
  1605. }
  1606. }
  1607. {
  1608. CComQIPtr<IHNetIcsSettings> spIHNetIcs = spIHNetCfgMgr;
  1609. if ( spIHNetIcs != NULL )
  1610. {
  1611. ULONG ulPrivateConnections;
  1612. pNetConnectionRefresh->DisableEvents( TRUE, MAX_DISABLE_EVENT_TIMEOUT );
  1613. hr = spIHNetIcs->DisableIcs( &ulConnections, &ulPrivateConnections );
  1614. if ( FAILED(hr) )
  1615. {
  1616. UpdateHnwLog( lpHnwCallback, lpContext, IDS_DISABLEICS, hr );
  1617. }
  1618. }
  1619. }
  1620. pNetConnectionRefresh->DisableEvents( FALSE, 0L );
  1621. pNetConnectionRefresh->Release();
  1622. }
  1623. TRACE_LEAVE("DisableEverything", hr);
  1624. return hr;
  1625. }
  1626. extern
  1627. HRESULT APIENTRY
  1628. HNetSetShareAndBridgeSettings(
  1629. IN INetConnection *pNetPublicConnection,
  1630. IN INetConnection *pNetPrivateConnection[],
  1631. IN BOOLEAN bSharePublicConnection,
  1632. IN BOOLEAN bFirewallPublicConnection,
  1633. IN LPHNWCALLBACK lpHnwCallback,
  1634. IN LPARAM lpContext,
  1635. OUT INetConnection **pNetPrivateInterface
  1636. )
  1637. /*++
  1638. Routine Description:
  1639. Arguments:
  1640. Return Value:
  1641. hResult
  1642. --*/
  1643. {
  1644. TRACE_ENTER("HNetSetShareAndBridgeSettings");
  1645. HRESULT hr;
  1646. // Initialize returned interface pointer if necessary
  1647. if ( NULL != pNetPrivateInterface )
  1648. {
  1649. *pNetPrivateInterface = NULL;
  1650. }
  1651. // Create Homenet Configuration Manager COM Instance
  1652. // and obtain connection settings.
  1653. CComPtr<IHNetCfgMgr> spIHNetCfgMgr;
  1654. hr = spIHNetCfgMgr.CoCreateInstance( CLSID_HNetCfgMgr );
  1655. if ( SUCCEEDED(hr) )
  1656. {
  1657. DisableEverything( spIHNetCfgMgr,
  1658. pNetPublicConnection,
  1659. pNetPrivateConnection,
  1660. lpHnwCallback,
  1661. lpContext );
  1662. if ( NULL != pNetPublicConnection )
  1663. {
  1664. hr = SetIcsPublicConnection( spIHNetCfgMgr,
  1665. pNetPublicConnection,
  1666. bSharePublicConnection,
  1667. bFirewallPublicConnection,
  1668. lpHnwCallback,
  1669. lpContext );
  1670. }
  1671. if ( ( NULL != pNetPrivateConnection ) && ( NULL != pNetPrivateConnection[0] ) && SUCCEEDED(hr) )
  1672. {
  1673. hr = SetIcsPrivateConnections( spIHNetCfgMgr,
  1674. pNetPrivateConnection,
  1675. bSharePublicConnection,
  1676. lpHnwCallback,
  1677. lpContext,
  1678. pNetPrivateInterface );
  1679. }
  1680. if ( FAILED(hr) )
  1681. {
  1682. DisableEverything( spIHNetCfgMgr,
  1683. pNetPublicConnection,
  1684. pNetPrivateConnection,
  1685. lpHnwCallback,
  1686. lpContext );
  1687. }
  1688. }
  1689. else
  1690. {
  1691. UpdateHnwLog( lpHnwCallback, lpContext, IDS_SHARINGCONFIGURATIONUNAVAIL );
  1692. }
  1693. TRACE_LEAVE("HNetSetShareAndBridgeSettings", hr);
  1694. return hr;
  1695. }
  1696. extern
  1697. HRESULT APIENTRY
  1698. HNetGetShareAndBridgeSettings(
  1699. OUT INetConnection **ppNetPublicConnection,
  1700. OUT INetConnection ***ppNetPrivateConnection,
  1701. OUT BOOLEAN *pbSharePublicConnection,
  1702. OUT BOOLEAN *pbFirewallPublicConnection
  1703. )
  1704. /*++
  1705. Routine Description:
  1706. Arguments:
  1707. Return Value:
  1708. hResult
  1709. --*/
  1710. {
  1711. HRESULT hr;
  1712. TRACE_ENTER("HNetGetShareAndBridgeSettings");
  1713. // Create Homenet Configuration Manager COM Instance
  1714. // and obtain connection settings.
  1715. CComPtr<IHNetCfgMgr> spIHNetCfgMgr;
  1716. *ppNetPublicConnection = NULL;
  1717. *ppNetPrivateConnection = NULL;
  1718. *pbSharePublicConnection = FALSE;
  1719. *pbFirewallPublicConnection = FALSE;
  1720. hr = spIHNetCfgMgr.CoCreateInstance( CLSID_HNetCfgMgr );
  1721. if ( SUCCEEDED(hr) )
  1722. {
  1723. if ( NULL != ppNetPublicConnection )
  1724. {
  1725. hr = GetIcsPublicConnection( spIHNetCfgMgr,
  1726. ppNetPublicConnection,
  1727. pbSharePublicConnection,
  1728. pbFirewallPublicConnection );
  1729. }
  1730. if ( NULL != ppNetPrivateConnection )
  1731. {
  1732. hr = GetIcsPrivateConnections( spIHNetCfgMgr, ppNetPrivateConnection );
  1733. if ( S_OK == hr )
  1734. {
  1735. CComPtr<IHNetConnection> spIHNetConnection;
  1736. INetConnection **ppINetCon;
  1737. // Check first private connection to see if it is the bridge
  1738. hr = spIHNetCfgMgr->GetIHNetConnectionForINetConnection( (*ppNetPrivateConnection)[0],
  1739. &spIHNetConnection );
  1740. _ASSERT( SUCCEEDED(hr) );
  1741. if ( SUCCEEDED(hr) )
  1742. {
  1743. HNET_CONN_PROPERTIES *phncProperties;
  1744. hr = spIHNetConnection->GetProperties( &phncProperties );
  1745. if ( SUCCEEDED(hr) && ( NULL != phncProperties ) )
  1746. {
  1747. if ( phncProperties->fBridge )
  1748. {
  1749. // If Bridge, then release the private connection instances
  1750. // and get the list of bridged connections
  1751. for ( ppINetCon = *ppNetPrivateConnection; NULL != *ppINetCon; ppINetCon++ )
  1752. {
  1753. (*ppINetCon)->Release();
  1754. *ppINetCon = NULL;
  1755. }
  1756. NetApiBufferFree( *ppNetPrivateConnection );
  1757. *ppNetPrivateConnection = NULL;
  1758. hr = GetBridgedConnections( spIHNetCfgMgr, ppNetPrivateConnection );
  1759. } // if ( phncProperties->fBridge )
  1760. CoTaskMemFree( phncProperties );
  1761. } // if ( SUCCEEDED(hr) && ( NULL != phncProperties ) )
  1762. } // if ( SUCCEEDED(hr)
  1763. // What if we fail along this path? Then we need to release
  1764. // any private connection interface pointer held.
  1765. if ( FAILED(hr) && ( NULL != ppNetPrivateConnection ) )
  1766. {
  1767. for ( ppINetCon = *ppNetPrivateConnection; NULL != *ppINetCon; ppINetCon++ )
  1768. {
  1769. (*ppINetCon)->Release();
  1770. }
  1771. NetApiBufferFree( *ppNetPrivateConnection );
  1772. *ppNetPrivateConnection = NULL;
  1773. }
  1774. } // if ( S_OK == hr )
  1775. } // if ( NULL != ppNetPrivateConnection )
  1776. // If we fail along the way then we need to release the public interface
  1777. // and NULL the pointer so that it won't be used.
  1778. if ( FAILED(hr) && ( NULL != ppNetPublicConnection ) )
  1779. {
  1780. (*ppNetPublicConnection)->Release();
  1781. *ppNetPublicConnection = NULL;
  1782. }
  1783. } // if ( SUCCEEDED(hr) )
  1784. TRACE_LEAVE("HNetGetShareAndBridgeSettings", hr);
  1785. return hr;
  1786. }
  1787. HRESULT DisablePersonalFirewallOnAll()
  1788. /*++
  1789. Routine Description:
  1790. Disable firewall on all connections
  1791. Arguments:
  1792. Return Value:
  1793. hResult
  1794. --*/
  1795. {
  1796. HRESULT hr = S_OK;
  1797. CComPtr<IHNetCfgMgr> spIHNetCfgMgr;
  1798. TRACE_ENTER("DisablePersonalFirewallOnAll");
  1799. hr = CoCreateInstance(CLSID_HNetCfgMgr,
  1800. NULL,
  1801. CLSCTX_ALL,
  1802. IID_PPV_ARG(IHNetCfgMgr, &spIHNetCfgMgr));
  1803. if (SUCCEEDED(hr))
  1804. {
  1805. CComQIPtr<IHNetFirewallSettings> spIHNetFirewall = spIHNetCfgMgr;
  1806. if ( NULL != spIHNetFirewall.p )
  1807. {
  1808. ULONG ulConnections = 0;
  1809. hr = spIHNetFirewall->DisableAllFirewalling( &ulConnections );
  1810. }
  1811. else
  1812. {
  1813. hr = E_FAIL;
  1814. }
  1815. }
  1816. TRACE_LEAVE("DisablePersonalFirewallOnAll", hr);
  1817. return hr;
  1818. }
  1819. HRESULT EnablePersonalFirewallOnAll()
  1820. /*++
  1821. Routine Description:
  1822. Enable firewall on all connections that can be firewalled
  1823. Arguments:
  1824. Return Value:
  1825. hResult
  1826. --*/
  1827. {
  1828. HRESULT hr = S_OK;
  1829. HRESULT hrTemp = S_OK;
  1830. ULONG ulCount = 0;
  1831. CComPtr<IEnumNetConnection> spEnum;
  1832. // Get the net connection manager
  1833. CComPtr<INetConnectionManager> spConnMan;
  1834. CComPtr<INetConnection> spConn;
  1835. // Create Homenet Configuration Manager COM Instance
  1836. // and obtain connection settings.
  1837. CComPtr<IHNetCfgMgr> spIHNetCfgMgr;
  1838. TRACE_ENTER("EnablePersonalFirewallOnAll");
  1839. hr = CoCreateInstance(CLSID_HNetCfgMgr,
  1840. NULL,
  1841. CLSCTX_ALL,
  1842. IID_PPV_ARG(IHNetCfgMgr, &spIHNetCfgMgr));
  1843. if (FAILED(hr))
  1844. {
  1845. goto End;
  1846. }
  1847. //disable any previous firewall settings otherwise enabling
  1848. //firewall on the same connection twice will return errors
  1849. //We will continue do the enable firewall if this step fails
  1850. DisablePersonalFirewallOnAll();
  1851. hr = CoCreateInstance(CLSID_ConnectionManager,
  1852. NULL,
  1853. CLSCTX_ALL,
  1854. IID_PPV_ARG(INetConnectionManager, &spConnMan));
  1855. if (FAILED(hr))
  1856. {
  1857. goto End;
  1858. }
  1859. // Get the enumeration of connections
  1860. SetProxyBlanket(spConnMan);
  1861. hr = spConnMan->EnumConnections(NCME_DEFAULT, &spEnum);
  1862. if (FAILED(hr))
  1863. {
  1864. goto End;
  1865. }
  1866. SetProxyBlanket(spEnum);
  1867. hr = spEnum->Reset();
  1868. if (FAILED(hr))
  1869. {
  1870. goto End;
  1871. }
  1872. do
  1873. {
  1874. NETCON_PROPERTIES* pProps = NULL;
  1875. //release any previous ref count we hold
  1876. spConn = NULL;
  1877. hr = spEnum->Next(1, &spConn, &ulCount);
  1878. if (FAILED(hr) || 1 != ulCount)
  1879. {
  1880. break;
  1881. }
  1882. SetProxyBlanket(spConn);
  1883. hr = spConn->GetProperties(&pProps);
  1884. if (FAILED(hr) || NULL == pProps)
  1885. {
  1886. continue;
  1887. }
  1888. //ICF is available only for certain types of connections
  1889. if (NCM_PHONE == pProps->MediaType ||
  1890. NCM_ISDN == pProps->MediaType ||
  1891. NCM_PPPOE == pProps->MediaType ||
  1892. NCM_LAN == pProps->MediaType ||
  1893. NCM_TUNNEL == pProps->MediaType )
  1894. {
  1895. CComPtr<IHNetConnection> spHNetConnection;
  1896. //release the ref count if we are holding one
  1897. spHNetConnection = NULL;
  1898. hrTemp = spIHNetCfgMgr->GetIHNetConnectionForINetConnection(
  1899. spConn,
  1900. &spHNetConnection );
  1901. if (SUCCEEDED(hr))
  1902. {
  1903. hr = hrTemp;
  1904. }
  1905. if (SUCCEEDED(hrTemp))
  1906. {
  1907. //check whether the connect can be firewalled
  1908. HNET_CONN_PROPERTIES *phncProperties = NULL;
  1909. hrTemp = spHNetConnection->GetProperties( &phncProperties );
  1910. if (SUCCEEDED(hrTemp) && NULL != phncProperties)
  1911. {
  1912. if (phncProperties->fCanBeFirewalled)
  1913. {
  1914. CComPtr<IHNetFirewalledConnection> spFirewalledConn;
  1915. //turn on the firewall
  1916. hrTemp = spHNetConnection->Firewall( &spFirewalledConn );
  1917. }
  1918. CoTaskMemFree(phncProperties);
  1919. }
  1920. if (SUCCEEDED(hr))
  1921. {
  1922. hr = hrTemp;
  1923. }
  1924. }
  1925. }
  1926. NcFreeNetconProperties(pProps);
  1927. } while (SUCCEEDED(hr) && 1 == ulCount);
  1928. End:
  1929. TRACE_LEAVE("EnablePersonalFirewallOnAll", hr);
  1930. //normalize hr because we used IEnum
  1931. if (S_FALSE == hr)
  1932. {
  1933. hr = S_OK;
  1934. }
  1935. return hr;
  1936. }
  1937. extern "C"
  1938. BOOL
  1939. WINAPI
  1940. WinBomConfigureHomeNet(
  1941. LPCTSTR lpszUnattend,
  1942. LPCTSTR lpszSection
  1943. )
  1944. /*++
  1945. Routine Description:
  1946. Reads home networking settings from the specified unattend file and saves
  1947. those in current system that is already setup and running.
  1948. Arguments:
  1949. lpszUnattend [IN] Points to a string buffer which contains the full path
  1950. to the unattend file (winbom.ini in this case) with all
  1951. the home network settings.
  1952. lpszSection [IN] Points to a string buffer which contains the name of
  1953. the section which contains all the home network settings
  1954. in the unattend file specified above.
  1955. Return Value:
  1956. Returns TRUE if the settings were successfully read and saved to the system.
  1957. Otherwise returns FALSE to indicate something failed.
  1958. --*/
  1959. {
  1960. if (NULL == lpszSection || NULL == lpszUnattend)
  1961. return FALSE;
  1962. BOOL fRet = TRUE;
  1963. WCHAR szBuf[256] = {0};
  1964. DWORD dwRet = 0;
  1965. dwRet = GetPrivateProfileString(lpszSection,
  1966. c_szEnableFirewall,
  1967. _T(""),
  1968. szBuf,
  1969. sizeof(szBuf)/sizeof(szBuf[0]),
  1970. lpszUnattend);
  1971. if (dwRet)
  1972. {
  1973. if (0 == lstrcmpi(szBuf, c_szYes))
  1974. {
  1975. fRet = SUCCEEDED(EnablePersonalFirewallOnAll());
  1976. }
  1977. else if (0 == lstrcmpi(szBuf, c_szNo))
  1978. {
  1979. fRet = SUCCEEDED(DisablePersonalFirewallOnAll());
  1980. }
  1981. }
  1982. else
  1983. {
  1984. //if there is no EnableFirewall there, we should treat this
  1985. //as a success
  1986. fRet = TRUE;
  1987. }
  1988. return fRet;
  1989. }