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.

1373 lines
37 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1997.
  5. //
  6. // File: cnetapi.cpp
  7. //
  8. // Contents: Network/SENS API wrappers
  9. //
  10. // Classes:
  11. //
  12. // Notes:
  13. //
  14. // History: 08-Dec-97 rogerg Created.
  15. //
  16. //--------------------------------------------------------------------------
  17. #include "precomp.h"
  18. // SENS DLL and function strings
  19. const WCHAR c_szSensApiDll[] = TEXT("SensApi.dll");
  20. STRING_INTERFACE(szIsNetworkAlive,"IsNetworkAlive");
  21. // RAS Dll and Function Strings
  22. const WCHAR c_szRasDll[] = TEXT("RASAPI32.DLL");
  23. // RAS function strings
  24. STRING_INTERFACE(szRasEnumConnectionsW,"RasEnumConnectionsW");
  25. STRING_INTERFACE(szRasEnumConnectionsA,"RasEnumConnectionsA");
  26. STRING_INTERFACE(szRasEnumEntriesA,"RasEnumEntriesA");
  27. STRING_INTERFACE(szRasEnumEntriesW,"RasEnumEntriesW");
  28. STRING_INTERFACE(szRasGetEntryPropertiesW,"RasGetEntryPropertiesW");
  29. STRING_INTERFACE(szRasGetErrorStringW,"RasGetErrorStringW");
  30. STRING_INTERFACE(szRasGetErrorStringA,"RasGetErrorStringA");
  31. STRING_INTERFACE(szRasGetAutodialParam, "RasGetAutodialParamA");
  32. STRING_INTERFACE(szRasSetAutodialParam, "RasSetAutodialParamA");
  33. // wininet declarations
  34. // warning - IE 4.0 only exported InternetDial which was ANSI. IE5 has InternetDailA and
  35. // internetDialW. we always use InternetDial for Ansi. So we prefere InternetDialW but
  36. // must fall back to ANSI for IE 4.0
  37. const WCHAR c_szWinInetDll[] = TEXT("WININET.DLL");
  38. STRING_INTERFACE(szInternetDial,"InternetDial");
  39. STRING_INTERFACE(szInternetDialW,"InternetDialW");
  40. STRING_INTERFACE(szInternetHangup,"InternetHangUp");
  41. STRING_INTERFACE(szInternetAutodial,"InternetAutodial");
  42. STRING_INTERFACE(szInternetAutodialHangup,"InternetAutodialHangup");
  43. STRING_INTERFACE(szInternetQueryOption,"InternetQueryOptionA"); // always use the A Version
  44. STRING_INTERFACE(szInternetSetOption,"InternetSetOptionA"); // always use A Version
  45. // SENS install key under HKLM
  46. const WCHAR wszSensInstallKey[] = TEXT("Software\\Microsoft\\Mobile\\Sens");
  47. //+---------------------------------------------------------------------------
  48. //
  49. // Member: CNetApi::CNetApi, public
  50. //
  51. // Synopsis: Constructor
  52. //
  53. // Arguments:
  54. //
  55. // Returns:
  56. //
  57. // Modifies:
  58. //
  59. // History: 08-Dec-97 rogerg Created.
  60. //
  61. //----------------------------------------------------------------------------
  62. CNetApi::CNetApi()
  63. {
  64. m_fTriedToLoadSens = FALSE;
  65. m_hInstSensApiDll = NULL;
  66. m_pIsNetworkAlive = NULL;
  67. m_fTriedToLoadRas = FALSE;
  68. m_hInstRasApiDll = NULL;
  69. m_pRasEnumConnectionsW = NULL;
  70. m_pRasEnumConnectionsA = NULL;
  71. m_pRasEnumEntriesA = NULL;
  72. m_pRasEnumEntriesW = NULL;
  73. m_pRasGetEntryPropertiesW = NULL;
  74. m_pRasGetErrorStringW = NULL;
  75. m_pRasGetErrorStringA = NULL;
  76. m_pRasGetAutodialParam = NULL;
  77. m_pRasSetAutodialParam = NULL;
  78. m_fTriedToLoadWinInet = FALSE;
  79. m_hInstWinInetDll = NULL;
  80. m_pInternetDial = NULL;
  81. m_pInternetDialW = NULL;
  82. m_pInternetHangUp = NULL;
  83. m_pInternetAutodial = NULL;
  84. m_pInternetAutodialHangup = NULL;
  85. m_pInternetQueryOption = NULL;
  86. m_pInternetSetOption = NULL;
  87. m_cRefs = 1;
  88. }
  89. //+---------------------------------------------------------------------------
  90. //
  91. // Member: CNetApi::~CNetApi, public
  92. //
  93. // Synopsis: Destructor
  94. //
  95. // Arguments:
  96. //
  97. // Returns:
  98. //
  99. // Modifies:
  100. //
  101. // History: 08-Dec-97 rogerg Created.
  102. //
  103. //----------------------------------------------------------------------------
  104. CNetApi::~CNetApi()
  105. {
  106. Assert(0 == m_cRefs);
  107. if (NULL != m_hInstSensApiDll)
  108. {
  109. FreeLibrary(m_hInstSensApiDll);
  110. }
  111. if (NULL != m_hInstWinInetDll)
  112. {
  113. FreeLibrary(m_hInstWinInetDll);
  114. }
  115. if (NULL != m_hInstRasApiDll)
  116. {
  117. FreeLibrary(m_hInstWinInetDll);
  118. }
  119. }
  120. //+-------------------------------------------------------------------------
  121. //
  122. // Method: CNetApi::QueryInterface
  123. //
  124. // Synopsis: Increments refcount
  125. //
  126. // History: 31-Jul-1998 SitaramR Created
  127. //
  128. //--------------------------------------------------------------------------
  129. STDMETHODIMP CNetApi::QueryInterface( REFIID, LPVOID* )
  130. {
  131. AssertSz(0,"E_NOTIMPL");
  132. return E_NOINTERFACE;
  133. }
  134. //+-------------------------------------------------------------------------
  135. //
  136. // Method: CNetApiXf
  137. //
  138. // Synopsis: Increments refcount
  139. //
  140. // History: 31-Jul-1998 SitaramR Created
  141. //
  142. //--------------------------------------------------------------------------
  143. STDMETHODIMP_(ULONG) CNetApi::AddRef()
  144. {
  145. DWORD dwTmp = InterlockedIncrement( (long *) &m_cRefs );
  146. return dwTmp;
  147. }
  148. //+-------------------------------------------------------------------------
  149. //
  150. // Method: CNetApi::Release
  151. //
  152. // Synopsis: Decrement refcount. Delete if necessary.
  153. //
  154. // History: 31-Jul-1998 SitaramR Created
  155. //
  156. //--------------------------------------------------------------------------
  157. STDMETHODIMP_(ULONG) CNetApi::Release()
  158. {
  159. Assert( m_cRefs > 0 );
  160. DWORD dwTmp = InterlockedDecrement( (long *) &m_cRefs );
  161. if ( 0 == dwTmp )
  162. delete this;
  163. return dwTmp;
  164. }
  165. //+---------------------------------------------------------------------------
  166. //
  167. // Member: CNetApi::LoadSensDll
  168. //
  169. // Synopsis: Trys to Load Sens Library.
  170. //
  171. // Arguments:
  172. //
  173. // Returns: NOERROR if successfull.
  174. //
  175. // Modifies:
  176. //
  177. // History: 08-Dec-97 rogerg Created.
  178. //
  179. //----------------------------------------------------------------------------
  180. STDMETHODIMP CNetApi::LoadSensDll()
  181. {
  182. HRESULT hr = S_FALSE;
  183. if (m_fTriedToLoadSens)
  184. {
  185. return m_hInstSensApiDll ? NOERROR : S_FALSE;
  186. }
  187. CLock lock(this);
  188. lock.Enter();
  189. if (!m_fTriedToLoadSens)
  190. {
  191. Assert(NULL == m_hInstSensApiDll);
  192. m_hInstSensApiDll = LoadLibrary(c_szSensApiDll);
  193. if (m_hInstSensApiDll)
  194. {
  195. // for now, don't return an error is GetProc Fails but check in each function.
  196. m_pIsNetworkAlive = (ISNETWORKALIVE)
  197. GetProcAddress(m_hInstSensApiDll, szIsNetworkAlive);
  198. }
  199. if (NULL == m_hInstSensApiDll
  200. || NULL == m_pIsNetworkAlive)
  201. {
  202. hr = S_FALSE;
  203. if (m_hInstSensApiDll)
  204. {
  205. FreeLibrary(m_hInstSensApiDll);
  206. m_hInstSensApiDll = NULL;
  207. }
  208. }
  209. else
  210. {
  211. hr = NOERROR;
  212. }
  213. m_fTriedToLoadSens = TRUE; // set after all initialization is done.
  214. }
  215. else
  216. {
  217. hr = m_hInstSensApiDll ? NOERROR : S_FALSE;
  218. }
  219. lock.Leave();
  220. return hr;
  221. }
  222. //+---------------------------------------------------------------------------
  223. //
  224. // Member: CNetApi::IsNetworkAlive, public
  225. //
  226. // Synopsis: Calls the Sens IsNetworkAlive API.
  227. //
  228. // Arguments:
  229. //
  230. // Returns: IsNetworkAlive results or FALSE is failed to load
  231. // sens or import.
  232. //
  233. // Modifies:
  234. //
  235. // History: 08-Dec-97 rogerg Created.
  236. //
  237. //----------------------------------------------------------------------------
  238. STDMETHODIMP_(BOOL) CNetApi::IsNetworkAlive(LPDWORD lpdwFlags)
  239. {
  240. //
  241. // Sens load fail is not an error
  242. //
  243. LoadSensDll();
  244. BOOL fResult = FALSE;
  245. if (NULL == m_pIsNetworkAlive)
  246. {
  247. DWORD cbNumEntries;
  248. RASCONN *pWanConnections;
  249. // if couldn't load export see if there are any WAN Connections.
  250. if (NOERROR == GetWanConnections(&cbNumEntries,&pWanConnections))
  251. {
  252. if (cbNumEntries)
  253. {
  254. fResult = TRUE;
  255. *lpdwFlags = NETWORK_ALIVE_WAN;
  256. }
  257. if (pWanConnections)
  258. {
  259. FreeWanConnections(pWanConnections);
  260. }
  261. }
  262. // for testing without sens
  263. // fResult = TRUE;
  264. // *lpdwFlags |= NETWORK_ALIVE_LAN;
  265. // end of testing without sens
  266. }
  267. else
  268. {
  269. fResult = m_pIsNetworkAlive(lpdwFlags);
  270. }
  271. return fResult;
  272. }
  273. //+---------------------------------------------------------------------------
  274. //
  275. // Member: CNetApi::IsSensInstalled, public
  276. //
  277. // Synopsis: Determines if SENS is installed on the System.
  278. //
  279. // Arguments:
  280. //
  281. // Returns: TRUE if sens is installed
  282. //
  283. // Modifies:
  284. //
  285. // History: 12-Aug-98 Kyle Created.
  286. //
  287. //----------------------------------------------------------------------------
  288. STDMETHODIMP_(BOOL) CNetApi::IsSensInstalled(void)
  289. {
  290. HKEY hkResult;
  291. BOOL fResult = FALSE;
  292. if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_LOCAL_MACHINE,wszSensInstallKey,0,
  293. KEY_READ,&hkResult))
  294. {
  295. fResult = TRUE;
  296. RegCloseKey(hkResult);
  297. }
  298. return fResult;
  299. }
  300. //+---------------------------------------------------------------------------
  301. //
  302. // Member: CNetApi::GetWanConnections, public
  303. //
  304. // Synopsis: returns an array of Active Wan connections.
  305. // up to the caller to free RasEntries structure when done.
  306. //
  307. // Arguments: [out] [cbNumEntries] - Number of Connections found
  308. // [out] [pWanConnections] - Array of Connections found.
  309. //
  310. // Returns: IsNetworkAlive results or FALSE is failed to load
  311. // sens or import.
  312. //
  313. // Modifies:
  314. //
  315. // History: 08-Dec-97 rogerg Created.
  316. //
  317. //----------------------------------------------------------------------------
  318. STDMETHODIMP CNetApi::GetWanConnections(DWORD *cbNumEntries,RASCONN **pWanConnections)
  319. {
  320. DWORD dwError = -1;
  321. DWORD dwSize;
  322. DWORD cConnections;
  323. *pWanConnections = NULL;
  324. *pWanConnections = 0;
  325. LPRASCONN lpRasConn;
  326. dwSize = sizeof(RASCONN);
  327. lpRasConn = (LPRASCONN) ALLOC(dwSize);
  328. if(lpRasConn)
  329. {
  330. lpRasConn->dwSize = sizeof(RASCONN);
  331. cConnections = 0;
  332. dwError = RasEnumConnections(lpRasConn, &dwSize, &cConnections);
  333. if (dwError == ERROR_BUFFER_TOO_SMALL)
  334. {
  335. dwSize = lpRasConn->dwSize; // get size needed
  336. FREE(lpRasConn);
  337. lpRasConn = (LPRASCONN) ALLOC(dwSize);
  338. if(lpRasConn)
  339. {
  340. lpRasConn->dwSize = sizeof(RASCONN);
  341. cConnections = 0;
  342. dwError = RasEnumConnections(lpRasConn, &dwSize, &cConnections);
  343. }
  344. }
  345. }
  346. if (!dwError && lpRasConn)
  347. {
  348. *cbNumEntries = cConnections;
  349. *pWanConnections = lpRasConn;
  350. return NOERROR;
  351. }
  352. else
  353. {
  354. if (lpRasConn)
  355. {
  356. FREE(lpRasConn);
  357. }
  358. }
  359. return S_FALSE;
  360. }
  361. //+---------------------------------------------------------------------------
  362. //
  363. // Member: CNetApi::FreeWanConnections, public
  364. //
  365. // Synopsis: Called by caller to free up memory
  366. // allocated by GetWanConnections.
  367. //
  368. // Arguments: [in] [pWanConnections] - WanConnection Array to free
  369. //
  370. // Returns:
  371. //
  372. // Modifies:
  373. //
  374. // History: 08-Dec-98 rogerg Created.
  375. //
  376. //----------------------------------------------------------------------------
  377. STDMETHODIMP CNetApi::FreeWanConnections(RASCONN *pWanConnections)
  378. {
  379. Assert(pWanConnections);
  380. if (pWanConnections)
  381. {
  382. FREE(pWanConnections);
  383. }
  384. return NOERROR;
  385. }
  386. //+---------------------------------------------------------------------------
  387. //
  388. // Member: CNetApi::RasEnumConnections, public
  389. //
  390. // Synopsis: Wraps RasEnumConnections.
  391. //
  392. // Arguments:
  393. //
  394. // Returns:
  395. //
  396. // Modifies:
  397. //
  398. // History: 02-Aug-98 rogerg Created.
  399. //
  400. //----------------------------------------------------------------------------
  401. STDMETHODIMP_(DWORD) CNetApi::RasEnumConnections(LPRASCONNW lprasconn,LPDWORD lpcb,LPDWORD lpcConnections)
  402. {
  403. DWORD dwReturn = -1;
  404. if (NOERROR != LoadRasApiDll())
  405. return -1;
  406. if(m_pRasEnumConnectionsW)
  407. {
  408. dwReturn = (*m_pRasEnumConnectionsW)(lprasconn,lpcb,lpcConnections);
  409. }
  410. return dwReturn;
  411. }
  412. //+---------------------------------------------------------------------------
  413. //
  414. // Member: CNetApi::GetConnectionStatus, private
  415. //
  416. // Synopsis: Given a Connection Name determines if the connection
  417. // has already been established.
  418. // Also set ths WanActive flag to indicate if there are any
  419. // existing RAS connections.
  420. //
  421. // Arguments: [pszConnectionName] - Name of the Connection
  422. // [out] [fConnected] - Indicates if specified connection is currently connected.
  423. // [out] [fCanEstablishConnection] - Flag indicates if the connection is not found can establish it.
  424. //
  425. // Returns: NOERROR if the dll was sucessfully loaded
  426. //
  427. // Modifies:
  428. //
  429. // History: 08-Dec-97 rogerg Created.
  430. //
  431. //----------------------------------------------------------------------------
  432. STDMETHODIMP CNetApi::GetConnectionStatus(LPCTSTR pszConnectionName,DWORD dwConnectionType,BOOL *fConnected,BOOL *fCanEstablishConnection)
  433. {
  434. *fConnected = FALSE;
  435. *fCanEstablishConnection = FALSE;
  436. // if this is a lan connection then see if network is alive,
  437. // else go through the Ras apis.
  438. if (CNETAPI_CONNECTIONTYPELAN == dwConnectionType)
  439. {
  440. DWORD dwFlags;
  441. if (IsNetworkAlive(&dwFlags)
  442. && (dwFlags & NETWORK_ALIVE_LAN) )
  443. {
  444. *fConnected = TRUE;
  445. }
  446. }
  447. else
  448. { // check for Ras Connections.
  449. RASCONN *pWanConnections;
  450. DWORD cbNumConnections;
  451. if (NOERROR == GetWanConnections(&cbNumConnections,&pWanConnections))
  452. {
  453. *fCanEstablishConnection = TRUE;
  454. if (cbNumConnections > 0)
  455. {
  456. *fCanEstablishConnection = FALSE;
  457. // loop through the entries to see if this connection is already
  458. // connected.
  459. while (cbNumConnections)
  460. {
  461. cbNumConnections--;
  462. if (0 == lstrcmp(pWanConnections[cbNumConnections].szEntryName,pszConnectionName))
  463. {
  464. *fConnected = TRUE;
  465. break;
  466. }
  467. }
  468. }
  469. if (pWanConnections)
  470. {
  471. FreeWanConnections(pWanConnections);
  472. }
  473. }
  474. }
  475. return NOERROR;
  476. }
  477. //+---------------------------------------------------------------------------
  478. //
  479. // Member: CNetApi::RasGetErrorStringProc, public
  480. //
  481. // Synopsis: Directly calls RasGetErrorString()
  482. //
  483. // Arguments:
  484. //
  485. // Returns: Appropriate Error codes
  486. //
  487. // Modifies:
  488. //
  489. // History: 08-Dec-97 rogerg Created.
  490. //
  491. //----------------------------------------------------------------------------
  492. STDMETHODIMP_(DWORD) CNetApi::RasGetErrorStringProc( UINT uErrorValue, LPTSTR lpszErrorString,DWORD cBufSize)
  493. {
  494. DWORD dwErr = -1;
  495. if (NOERROR != LoadRasApiDll())
  496. return -1;
  497. if (m_pRasGetErrorStringW)
  498. {
  499. dwErr = m_pRasGetErrorStringW(uErrorValue,lpszErrorString,cBufSize);
  500. }
  501. return dwErr;
  502. }
  503. //+---------------------------------------------------------------------------
  504. //
  505. // Member: CNetApi::RasEnumEntries, public
  506. //
  507. // Synopsis: wraps RasEnumEntries
  508. //
  509. // Arguments:
  510. //
  511. // Returns:
  512. //
  513. // Modifies:
  514. //
  515. // History: 08-Aug-98 rogerg Created.
  516. //
  517. //----------------------------------------------------------------------------
  518. DWORD CNetApi::RasEnumEntries(LPWSTR reserved,LPWSTR lpszPhoneBook,
  519. LPRASENTRYNAME lprasEntryName,LPDWORD lpcb,LPDWORD lpcEntries)
  520. {
  521. if (NOERROR != LoadRasApiDll())
  522. return -1;
  523. if(m_pRasEnumEntriesW)
  524. {
  525. return (m_pRasEnumEntriesW)(reserved,lpszPhoneBook,lprasEntryName,lpcb,lpcEntries);
  526. }
  527. return -1;
  528. }
  529. //+---------------------------------------------------------------------------
  530. //
  531. // Member: CNetApi::RasGetAutodial
  532. //
  533. // Synopsis: Gets the autodial state
  534. //
  535. // Arguments: [fEnabled] - Whether Ras autodial is enabled or disabled returned here
  536. //
  537. // History: 28-Jul-98 SitaramR Created
  538. //
  539. //----------------------------------------------------------------------------
  540. STDMETHODIMP CNetApi::RasGetAutodial( BOOL& fEnabled )
  541. {
  542. //
  543. // In case of failures the default is to assume that Ras autodial is enabled
  544. //
  545. fEnabled = TRUE;
  546. if (NOERROR != LoadRasApiDll())
  547. return NOERROR;
  548. if ( m_pRasGetAutodialParam == NULL )
  549. return NOERROR;
  550. DWORD dwValue;
  551. DWORD dwSize = sizeof(dwValue);
  552. DWORD dwRet = m_pRasGetAutodialParam( RASADP_LoginSessionDisable,
  553. &dwValue,
  554. &dwSize );
  555. if ( dwRet == ERROR_SUCCESS )
  556. {
  557. Assert( dwSize == sizeof(dwValue) );
  558. fEnabled = (dwValue == 0);
  559. }
  560. return NOERROR;
  561. }
  562. //+---------------------------------------------------------------------------
  563. //
  564. // Member: CNetApi::RasSetAutodial
  565. //
  566. // Synopsis: Sets the autodial state
  567. //
  568. // Arguments: [fEnabled] - Whether Ras is to be enabled or disabled
  569. //
  570. // History: 28-Jul-98 SitaramR Created
  571. //
  572. //----------------------------------------------------------------------------
  573. STDMETHODIMP CNetApi::RasSetAutodial( BOOL fEnabled )
  574. {
  575. //
  576. // Ignore failures
  577. //
  578. if (NOERROR != LoadRasApiDll())
  579. return NOERROR;
  580. if ( m_pRasGetAutodialParam == NULL )
  581. return NOERROR;
  582. DWORD dwValue = !fEnabled;
  583. DWORD dwRet = m_pRasSetAutodialParam( RASADP_LoginSessionDisable,
  584. &dwValue,
  585. sizeof(dwValue) );
  586. return NOERROR;
  587. }
  588. //+---------------------------------------------------------------------------
  589. //
  590. // Member: CNetApi::LoadRasApiDll, private
  591. //
  592. // Synopsis: If not already loaded, loads the RasApi Dll.
  593. //
  594. // Arguments:
  595. //
  596. // Returns: NOERROR if the dll was sucessfully loaded
  597. //
  598. // Modifies:
  599. //
  600. // History: 08-Dec-97 rogerg Created.
  601. //
  602. //----------------------------------------------------------------------------
  603. HRESULT CNetApi::LoadRasApiDll()
  604. {
  605. HRESULT hr = S_FALSE;;
  606. if (m_fTriedToLoadRas)
  607. {
  608. return m_hInstRasApiDll ? NOERROR : S_FALSE;
  609. }
  610. CLock lock(this);
  611. lock.Enter();
  612. if (!m_fTriedToLoadRas)
  613. {
  614. Assert(NULL == m_hInstRasApiDll);
  615. m_hInstRasApiDll = NULL;
  616. m_hInstRasApiDll = LoadLibrary(c_szRasDll);
  617. if (m_hInstRasApiDll)
  618. {
  619. m_pRasEnumConnectionsW = (RASENUMCONNECTIONSW)
  620. GetProcAddress(m_hInstRasApiDll, szRasEnumConnectionsW);
  621. m_pRasEnumConnectionsA = (RASENUMCONNECTIONSA)
  622. GetProcAddress(m_hInstRasApiDll, szRasEnumConnectionsA);
  623. m_pRasEnumEntriesA = (RASENUMENTRIESPROCA)
  624. GetProcAddress(m_hInstRasApiDll, szRasEnumEntriesA);
  625. m_pRasEnumEntriesW = (RASENUMENTRIESPROCW)
  626. GetProcAddress(m_hInstRasApiDll, szRasEnumEntriesW);
  627. m_pRasGetEntryPropertiesW = (RASGETENTRYPROPERTIESPROC)
  628. GetProcAddress(m_hInstRasApiDll, szRasGetEntryPropertiesW);
  629. m_pRasGetErrorStringW = (RASGETERRORSTRINGPROCW)
  630. GetProcAddress(m_hInstRasApiDll, szRasGetErrorStringW);
  631. m_pRasGetErrorStringA = (RASGETERRORSTRINGPROCA)
  632. GetProcAddress(m_hInstRasApiDll, szRasGetErrorStringA);
  633. m_pRasGetAutodialParam = (RASGETAUTODIALPARAM)
  634. GetProcAddress(m_hInstRasApiDll, szRasGetAutodialParam);
  635. m_pRasSetAutodialParam = (RASSETAUTODIALPARAM)
  636. GetProcAddress(m_hInstRasApiDll, szRasSetAutodialParam);
  637. }
  638. //
  639. // No check for Get/SetAutodialParam because they don't exist on Win 95
  640. //
  641. if (NULL == m_hInstRasApiDll
  642. || NULL == m_hInstRasApiDll
  643. || NULL == m_pRasEnumConnectionsA
  644. || NULL == m_pRasGetErrorStringA
  645. || NULL == m_pRasEnumEntriesA
  646. )
  647. {
  648. if (m_hInstRasApiDll)
  649. {
  650. FreeLibrary(m_hInstRasApiDll);
  651. m_hInstRasApiDll = NULL;
  652. }
  653. hr = S_FALSE;
  654. }
  655. else
  656. {
  657. hr = NOERROR;
  658. }
  659. m_fTriedToLoadRas = TRUE; // set after all init is done.
  660. }
  661. else
  662. {
  663. hr = m_hInstRasApiDll ? NOERROR : S_FALSE;
  664. }
  665. lock.Leave();
  666. return hr;
  667. }
  668. //+---------------------------------------------------------------------------
  669. //
  670. // Member: CNetApi::LoadWinInetDll, private
  671. //
  672. // Synopsis: If not already loaded, loads the WinInet Dll.
  673. //
  674. // Arguments:
  675. //
  676. // Returns: NOERROR if the dll was sucessfully loaded
  677. //
  678. // Modifies:
  679. //
  680. // History: 26-May-98 rogerg Created.
  681. //
  682. //----------------------------------------------------------------------------
  683. HRESULT CNetApi::LoadWinInetDll()
  684. {
  685. if (m_fTriedToLoadWinInet)
  686. {
  687. return m_hInstWinInetDll ? NOERROR : S_FALSE;
  688. }
  689. CLock lock(this);
  690. lock.Enter();
  691. HRESULT hr = NOERROR;
  692. if (!m_fTriedToLoadWinInet)
  693. {
  694. Assert(NULL == m_hInstWinInetDll);
  695. m_hInstWinInetDll = LoadLibrary(c_szWinInetDll);
  696. if (m_hInstWinInetDll)
  697. {
  698. m_pInternetDial = (INTERNETDIAL) GetProcAddress(m_hInstWinInetDll, szInternetDial);
  699. m_pInternetDialW = (INTERNETDIALW) GetProcAddress(m_hInstWinInetDll, szInternetDialW);
  700. m_pInternetHangUp = (INTERNETHANGUP) GetProcAddress(m_hInstWinInetDll, szInternetHangup);
  701. m_pInternetAutodial = (INTERNETAUTODIAL) GetProcAddress(m_hInstWinInetDll, szInternetAutodial);
  702. m_pInternetAutodialHangup = (INTERNETAUTODIALHANGUP) GetProcAddress(m_hInstWinInetDll, szInternetAutodialHangup);
  703. m_pInternetQueryOption = (INTERNETQUERYOPTION) GetProcAddress(m_hInstWinInetDll, szInternetQueryOption);
  704. m_pInternetSetOption = (INTERNETSETOPTION) GetProcAddress(m_hInstWinInetDll, szInternetSetOption);
  705. // note: not an error if can't get wide version of InternetDial
  706. Assert(m_pInternetDial);
  707. Assert(m_pInternetHangUp);
  708. Assert(m_pInternetAutodial);
  709. Assert(m_pInternetAutodialHangup);
  710. Assert(m_pInternetQueryOption);
  711. Assert(m_pInternetSetOption);
  712. }
  713. // note: don't bail if can't get wide version of InternetDial
  714. if (NULL == m_hInstWinInetDll
  715. || NULL == m_pInternetDial
  716. || NULL == m_pInternetHangUp
  717. || NULL == m_pInternetAutodial
  718. || NULL == m_pInternetAutodialHangup
  719. || NULL == m_pInternetQueryOption
  720. || NULL == m_pInternetSetOption
  721. )
  722. {
  723. if (m_hInstWinInetDll)
  724. {
  725. FreeLibrary(m_hInstWinInetDll);
  726. m_hInstWinInetDll = NULL;
  727. }
  728. hr = S_FALSE;
  729. }
  730. else
  731. {
  732. hr = NOERROR;
  733. }
  734. m_fTriedToLoadWinInet = TRUE; // set after all init is done.
  735. }
  736. else
  737. {
  738. // someone took the lock before us, return the new resul
  739. hr = m_hInstWinInetDll ? NOERROR : S_FALSE;
  740. }
  741. lock.Leave();
  742. return hr;
  743. }
  744. //+---------------------------------------------------------------------------
  745. //
  746. // Member: CNetApi::InternetDial, private
  747. //
  748. // Synopsis: Calls the WinInet InternetDial API.
  749. //
  750. // Arguments:
  751. //
  752. // Returns: -1 can't load dll
  753. // whatever API returns.
  754. //
  755. // Modifies:
  756. //
  757. // History: 26-May-98 rogerg Created.
  758. //
  759. //----------------------------------------------------------------------------
  760. STDMETHODIMP_(DWORD) CNetApi::InternetDialA(HWND hwndParent,char* lpszConnectoid,DWORD dwFlags,
  761. LPDWORD lpdwConnection, DWORD dwReserved)
  762. {
  763. DWORD dwRet = -1;
  764. if (NOERROR == LoadWinInetDll())
  765. {
  766. dwRet = m_pInternetDial(hwndParent,lpszConnectoid,dwFlags,lpdwConnection,dwReserved);
  767. }
  768. return dwRet;
  769. }
  770. //+---------------------------------------------------------------------------
  771. //
  772. // Member: CNetApi::InternetDial, private
  773. //
  774. // Synopsis: Calls the WinInet InternetDial API.
  775. //
  776. // Arguments:
  777. //
  778. // Returns: -1 can't load dll
  779. // whatever API returns.
  780. //
  781. // Modifies:
  782. //
  783. // History: 26-May-98 rogerg Created.
  784. //
  785. //----------------------------------------------------------------------------
  786. STDMETHODIMP_(DWORD) CNetApi::InternetDialW(HWND hwndParent,WCHAR* lpszConnectoid,DWORD dwFlags,
  787. LPDWORD lpdwConnection, DWORD dwReserved)
  788. {
  789. DWORD dwRet = -1;
  790. if (NOERROR == LoadWinInetDll())
  791. {
  792. if (m_pInternetDialW)
  793. {
  794. dwRet = m_pInternetDialW(hwndParent,lpszConnectoid,dwFlags,lpdwConnection,dwReserved);
  795. }
  796. }
  797. return dwRet;
  798. }
  799. //+---------------------------------------------------------------------------
  800. //
  801. // Member: CNetApi::InternetHangUp, private
  802. //
  803. // Synopsis: Calls the WinInet InternetHangUp API.
  804. //
  805. // Arguments:
  806. //
  807. // Returns: -1 can't load dll
  808. // whatever API returns.
  809. //
  810. // Modifies:
  811. //
  812. // History: 26-May-98 rogerg Created.
  813. //
  814. //----------------------------------------------------------------------------
  815. STDMETHODIMP_(DWORD) CNetApi::InternetHangUp(DWORD dwConnection,DWORD dwReserved)
  816. {
  817. DWORD dwRet = -1;
  818. if (NOERROR == LoadWinInetDll())
  819. {
  820. dwRet = m_pInternetHangUp(dwConnection,dwReserved);
  821. }
  822. return dwRet;
  823. }
  824. //+---------------------------------------------------------------------------
  825. //
  826. // Member: CNetApi::InternetAutodial, private
  827. //
  828. // Synopsis: Calls the WinInet InternetAutodial API.
  829. //
  830. // Arguments:
  831. //
  832. // Returns: TRUE if connection was established.
  833. //
  834. // Modifies:
  835. //
  836. // History: 26-May-98 rogerg Created.
  837. //
  838. //----------------------------------------------------------------------------
  839. STDMETHODIMP_(BOOL) WINAPI CNetApi::InternetAutodial(DWORD dwFlags,DWORD dwReserved)
  840. {
  841. BOOL fRet = FALSE;
  842. if (NOERROR == LoadWinInetDll())
  843. {
  844. fRet = m_pInternetAutodial(dwFlags,dwReserved);
  845. }
  846. return fRet;
  847. }
  848. //+---------------------------------------------------------------------------
  849. //
  850. // Member: CNetApi::InternetAutodialHangup, private
  851. //
  852. // Synopsis: Calls the WinInet InternetAutodialHangup API.
  853. //
  854. // Arguments:
  855. //
  856. // Returns: TRUE if hangup was successful.
  857. //
  858. // Modifies:
  859. //
  860. // History: 26-May-98 rogerg Created.
  861. //
  862. //----------------------------------------------------------------------------
  863. STDMETHODIMP_(BOOL) WINAPI CNetApi::InternetAutodialHangup(DWORD dwReserved)
  864. {
  865. BOOL fRet = FALSE;
  866. if (NOERROR == LoadWinInetDll())
  867. {
  868. fRet = m_pInternetAutodialHangup(dwReserved);
  869. }
  870. return fRet;
  871. }
  872. //+---------------------------------------------------------------------------
  873. //
  874. // Member: CNetApi::InternetGetAutoDial
  875. //
  876. // Synopsis: Gets the wininet autodial state
  877. //
  878. // Arguments: [fDisabled] - Whether autodial is enabled or disabled
  879. //
  880. // History: 28-Jul-98 SitaramR Created
  881. // 22-Mar-02 BrianAu Use autodial mode.
  882. //
  883. //----------------------------------------------------------------------------
  884. STDMETHODIMP CNetApi::InternetGetAutodial(DWORD *pdwMode)
  885. {
  886. //
  887. // In case of failures use the same default as used in wininet.
  888. //
  889. *pdwMode = AUTODIAL_MODE_NO_NETWORK_PRESENT;
  890. HRESULT hr = _InternetGetAutodialFromWininet(pdwMode);
  891. if (FAILED(hr))
  892. {
  893. hr = _InternetGetAutodialFromRegistry(pdwMode);
  894. }
  895. //
  896. // Don't return a failure value. The caller should always
  897. // receive a mode value. If the caller wishes, they can check for
  898. // S_OK vs. S_FALSE to know if they're getting a default or not.
  899. //
  900. return SUCCEEDED(hr) ? S_OK : S_FALSE;
  901. }
  902. //
  903. // Obtains the current Internet Autodial mode from wininet.
  904. // Returns:
  905. // S_OK - Mode value obtained and returned.
  906. // E_FAIL - Mode value not obtained. Most likely, this particular option query
  907. // is not supported on the installed version of wininet.
  908. //
  909. HRESULT CNetApi::_InternetGetAutodialFromWininet(DWORD *pdwMode)
  910. {
  911. if (NOERROR == LoadWinInetDll())
  912. {
  913. DWORD dwMode;
  914. DWORD dwSize = sizeof(dwMode);
  915. if (m_pInternetQueryOption(NULL, INTERNET_OPTION_AUTODIAL_MODE, &dwMode, &dwSize))
  916. {
  917. //
  918. // InternetQueryOption( .. AUTODIAL .. ) is available on IE 5 only
  919. //
  920. *pdwMode = dwMode;
  921. return S_OK;
  922. }
  923. }
  924. return E_FAIL;
  925. }
  926. //
  927. // Reads the Internet Autodial mode from the registry.
  928. // This function effectively duplicates InternetQueryOption(INTERNET_OPTION_AUTODIAL_MODE).
  929. //
  930. // Returns:
  931. // S_OK - Settings key was opened and a mode value has been returned.
  932. // Error - No mode value returned. One of the following happened:
  933. // a. Settings key not opened.
  934. // b. Key opened but no "EnableAutodial" or NoNetAutodial" values found.
  935. //
  936. HRESULT CNetApi::_InternetGetAutodialFromRegistry(DWORD *pdwMode)
  937. {
  938. HRESULT hr = E_FAIL;
  939. HKEY hkey;
  940. LONG lr = RegOpenKeyEx(HKEY_CURRENT_USER,
  941. REGSTR_PATH_INTERNET_SETTINGS,
  942. NULL,
  943. KEY_READ,
  944. &hkey);
  945. if (ERROR_SUCCESS == lr)
  946. {
  947. DWORD dwType;
  948. DWORD dwValue;
  949. DWORD dwSize = sizeof(dwValue);
  950. lr = RegQueryValueEx(hkey,
  951. REGSTR_VAL_ENABLEAUTODIAL,
  952. NULL,
  953. &dwType,
  954. (BYTE *)&dwValue,
  955. &dwSize);
  956. if ((ERROR_SUCCESS != lr) || (0 == dwValue))
  957. {
  958. *pdwMode = AUTODIAL_MODE_NEVER;
  959. hr = S_OK;
  960. }
  961. else
  962. {
  963. dwSize = sizeof(dwValue);
  964. lr = RegQueryValueEx(hkey,
  965. REGSTR_VAL_NONETAUTODIAL,
  966. NULL,
  967. &dwType,
  968. (BYTE *)&dwValue,
  969. &dwSize);
  970. if ((ERROR_SUCCESS != lr) || (0 == dwValue))
  971. {
  972. *pdwMode = AUTODIAL_MODE_ALWAYS;
  973. hr = S_OK;
  974. }
  975. }
  976. RegCloseKey(hkey);
  977. }
  978. if (S_OK != hr)
  979. {
  980. hr = HRESULT_FROM_WIN32(lr);
  981. }
  982. return hr;
  983. }
  984. //+---------------------------------------------------------------------------
  985. //
  986. // Member: CNetApi::InternetSetAutoDial
  987. //
  988. // Synopsis: Sets the wininet autodial state
  989. //
  990. // Arguments: [fEnabled] - Whether autodial is to be enabled or disabled
  991. //
  992. // History: 28-Jul-98 SitaramR Created
  993. // 22-Mar-02 BrianAu Use autodial mode.
  994. //
  995. //----------------------------------------------------------------------------
  996. STDMETHODIMP CNetApi::InternetSetAutodial( DWORD dwMode )
  997. {
  998. HRESULT hr = _InternetSetAutodialViaWininet(dwMode);
  999. if (FAILED(hr))
  1000. {
  1001. hr = _InternetSetAutodialViaRegistry(dwMode);
  1002. }
  1003. return hr;
  1004. }
  1005. //
  1006. // Sets the Internet Autodial mode value using Wininet.
  1007. // Returns:
  1008. // S_OK - Mode successfully written.
  1009. // E_FAIL - Mode not successfully written. Likely because this particular
  1010. // internet option is not available on loaded version of wininet.
  1011. //
  1012. HRESULT CNetApi::_InternetSetAutodialViaWininet(DWORD dwMode)
  1013. {
  1014. if (NOERROR == LoadWinInetDll())
  1015. {
  1016. if (m_pInternetSetOption(NULL, INTERNET_OPTION_AUTODIAL_MODE, &dwMode, sizeof(dwMode)))
  1017. {
  1018. //
  1019. // InternetSetOption( .. AUTODIAL .. ) is available on IE 5 only
  1020. //
  1021. return S_OK;
  1022. }
  1023. }
  1024. return E_FAIL;
  1025. }
  1026. //
  1027. // Sets the Internet Autodial mode value using the registry.
  1028. // Returns:
  1029. // S_OK - Mode value(s) set.
  1030. // Error - One or more mode value(s) not set.
  1031. //
  1032. // Note that we refer to "value(s)" plural. This mode setting is represented
  1033. // by two registry values; "enabled" and "no net". It is unlikely but possible
  1034. // that the function could set "enabled" but not "no net".
  1035. //
  1036. HRESULT CNetApi::_InternetSetAutodialViaRegistry(DWORD dwMode)
  1037. {
  1038. HKEY hkey;
  1039. LONG lr = RegOpenKeyEx(HKEY_CURRENT_USER,
  1040. REGSTR_PATH_INTERNET_SETTINGS,
  1041. NULL,
  1042. KEY_READ | KEY_WRITE,
  1043. &hkey);
  1044. if (ERROR_SUCCESS == lr)
  1045. {
  1046. DWORD dwEnable = 0;
  1047. DWORD dwNonet = 0;
  1048. switch(dwMode)
  1049. {
  1050. case AUTODIAL_MODE_NEVER:
  1051. //
  1052. // Use defaults of "no enable", "no net".
  1053. //
  1054. break;
  1055. case AUTODIAL_MODE_NO_NETWORK_PRESENT:
  1056. dwNonet = 1;
  1057. //
  1058. // Fall through...
  1059. //
  1060. case AUTODIAL_MODE_ALWAYS:
  1061. dwEnable = 1;
  1062. break;
  1063. default:
  1064. lr = ERROR_INVALID_PARAMETER;
  1065. break;
  1066. }
  1067. if (ERROR_SUCCESS == lr)
  1068. {
  1069. lr = RegSetValueEx(hkey,
  1070. REGSTR_VAL_ENABLEAUTODIAL,
  1071. NULL,
  1072. REG_DWORD,
  1073. (BYTE *)&dwEnable,
  1074. sizeof(dwEnable));
  1075. if (ERROR_SUCCESS == lr)
  1076. {
  1077. lr = RegSetValueEx(hkey,
  1078. REGSTR_VAL_NONETAUTODIAL,
  1079. NULL,
  1080. REG_DWORD,
  1081. (BYTE *)&dwNonet,
  1082. sizeof(dwNonet));
  1083. }
  1084. }
  1085. RegCloseKey(hkey);
  1086. }
  1087. return HRESULT_FROM_WIN32(lr);
  1088. }
  1089. //+-------------------------------------------------------------------
  1090. //
  1091. // Function: IsGlobalOffline
  1092. //
  1093. // Synopsis: Determines if in WorkOffline State
  1094. //
  1095. // Arguments:
  1096. //
  1097. // Notes: Code Provided by DarrenMi
  1098. //
  1099. //
  1100. // History:
  1101. //
  1102. //--------------------------------------------------------------------
  1103. STDMETHODIMP_(BOOL) CNetApi::IsGlobalOffline(void)
  1104. {
  1105. DWORD dwState = 0, dwSize = sizeof(dwState);
  1106. BOOL fRet = FALSE;
  1107. LoadWinInetDll();
  1108. if (NULL == m_pInternetQueryOption)
  1109. {
  1110. Assert(m_pInternetQueryOption)
  1111. return FALSE; // USUAL NOT OFFLINE
  1112. }
  1113. if(m_pInternetQueryOption(NULL, INTERNET_OPTION_CONNECTED_STATE, &dwState,
  1114. &dwSize))
  1115. {
  1116. if(dwState & INTERNET_STATE_DISCONNECTED_BY_USER)
  1117. fRet = TRUE;
  1118. }
  1119. return fRet;
  1120. }
  1121. //+-------------------------------------------------------------------
  1122. //
  1123. // Function: SetOffline
  1124. //
  1125. // Synopsis: Sets the WorkOffline state to on or off.
  1126. //
  1127. // Arguments:
  1128. //
  1129. // Notes: Code Provided by DarrenMi
  1130. //
  1131. //
  1132. // History:
  1133. //
  1134. //--------------------------------------------------------------------
  1135. STDMETHODIMP_(BOOL) CNetApi::SetOffline(BOOL fOffline)
  1136. {
  1137. INTERNET_CONNECTED_INFO ci;
  1138. BOOL fReturn = FALSE;
  1139. LoadWinInetDll();
  1140. if (NULL == m_pInternetSetOption)
  1141. {
  1142. Assert(m_pInternetSetOption);
  1143. return FALSE;
  1144. }
  1145. ZeroMemory(&ci, sizeof(ci));
  1146. if(fOffline) {
  1147. ci.dwConnectedState = INTERNET_STATE_DISCONNECTED_BY_USER;
  1148. ci.dwFlags = ISO_FORCE_DISCONNECTED;
  1149. } else {
  1150. ci.dwConnectedState = INTERNET_STATE_CONNECTED;
  1151. }
  1152. fReturn = m_pInternetSetOption(NULL, INTERNET_OPTION_CONNECTED_STATE, &ci, sizeof(ci));
  1153. return fReturn;
  1154. }