Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

552 lines
13 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1997.
  5. //
  6. // File: N C N E T C O N . C P P
  7. //
  8. // Contents: Common routines for dealing with the connections interfaces.
  9. //
  10. // Notes: Pollute this under penalty of death.
  11. //
  12. // Author: shaunco 20 Aug 1998
  13. //
  14. //----------------------------------------------------------------------------
  15. #include <pch.h>
  16. #pragma hdrstop
  17. #include <atlbase.h>
  18. #include "nccom.h"
  19. #include "ncnetcon.h"
  20. #include "netconp.h"
  21. #include "ncras.h"
  22. #include "ncreg.h"
  23. #include "ncconv.h"
  24. //+---------------------------------------------------------------------------
  25. //
  26. // Function: FreeNetconProperties
  27. //
  28. // Purpose: Free the memory associated with the output parameter of
  29. // INetConnection->GetProperties. This is a helper function
  30. // used by clients of INetConnection.
  31. //
  32. // Arguments:
  33. // pProps [in] The properties to free.
  34. //
  35. // Returns: nothing.
  36. //
  37. // Author: shaunco 1 Feb 1998
  38. //
  39. // Notes:
  40. //
  41. VOID
  42. FreeNetconProperties (
  43. IN NETCON_PROPERTIES* pProps)
  44. {
  45. if (pProps)
  46. {
  47. CoTaskMemFree (pProps->pszwName);
  48. CoTaskMemFree (pProps->pszwDeviceName);
  49. CoTaskMemFree (pProps);
  50. }
  51. }
  52. //+---------------------------------------------------------------------------
  53. //
  54. // Function: HrGetConnectionPersistData
  55. //
  56. // Purpose: Get the persistent form of a connection. This can be used
  57. // to later get back to the INetConnection interface with a call
  58. // to HrGetConnectionFromPersistData.
  59. //
  60. // Arguments:
  61. // pConn [in] Connection to get persist data from.
  62. // ppbData [out] Address of where to return pointer to data.
  63. // pcbSize [out] Address of where to return the size of the data.
  64. // pclsid [out] Address of where to return the CLSID of the connection.
  65. //
  66. // Returns: S_OK or an error code
  67. //
  68. // Author: shaunco 20 Aug 1998
  69. //
  70. // Notes: Free *ppbData with MemFree.
  71. //
  72. HRESULT
  73. HrGetConnectionPersistData (
  74. IN INetConnection* pConn,
  75. OUT BYTE** ppbData,
  76. OUT ULONG* pcbSize,
  77. OUT CLSID* pclsid OPTIONAL)
  78. {
  79. Assert (pConn);
  80. Assert (ppbData);
  81. Assert (pcbSize);
  82. // pclsid is optional.
  83. // Initialize the output parameters.
  84. //
  85. *ppbData = NULL;
  86. *pcbSize = 0;
  87. if (pclsid)
  88. {
  89. *pclsid = GUID_NULL;
  90. }
  91. // Get the IPersistNetConnection interfaces.
  92. //
  93. IPersistNetConnection* pPersist;
  94. HRESULT hr = HrQIAndSetProxyBlanket(pConn, &pPersist);
  95. if (SUCCEEDED(hr))
  96. {
  97. // Return the CLSID if requested.
  98. //
  99. if (pclsid)
  100. {
  101. hr = pPersist->GetClassID (pclsid);
  102. TraceHr(ttidError, FAL, hr, FALSE, "pPersist->GetClassID");
  103. }
  104. if (SUCCEEDED(hr))
  105. {
  106. // Get the size required, allocated a buffer, and get the data.
  107. //
  108. BYTE* pbData;
  109. ULONG cbData;
  110. hr = pPersist->GetSizeMax (&cbData);
  111. TraceHr(ttidError, FAL, hr, FALSE, "pPersist->GetSizeMax");
  112. if (SUCCEEDED(hr))
  113. {
  114. hr = E_OUTOFMEMORY;
  115. pbData = (BYTE*)MemAlloc (cbData);
  116. if (pbData)
  117. {
  118. hr = pPersist->Save (pbData, cbData);
  119. TraceHr(ttidError, FAL, hr, FALSE, "pPersist->Save");
  120. if (SUCCEEDED(hr))
  121. {
  122. *ppbData = pbData;
  123. *pcbSize = cbData;
  124. }
  125. else
  126. {
  127. MemFree (pbData);
  128. }
  129. }
  130. }
  131. }
  132. ReleaseObj (pPersist);
  133. }
  134. TraceError("HrGetConnectionPersistData", hr);
  135. return hr;
  136. }
  137. //+---------------------------------------------------------------------------
  138. //
  139. // Function: HrGetConnectionFromPersistData
  140. //
  141. // Purpose: Get an INetConnection interface given the persistent form of
  142. // the connection.
  143. //
  144. // Arguments:
  145. // clsid [in] CLSID to CoCreateInstance with.
  146. // pbData [in] Pointer to connection's persist data.
  147. // cbData [in] Size of the data in bytes.
  148. // ppConn [out] Address of where to return the pointer to the
  149. // INetConnection interface.
  150. //
  151. // Returns: S_OK or an error code.
  152. //
  153. // Author: shaunco 2 Nov 1998
  154. //
  155. // Notes:
  156. //
  157. HRESULT
  158. HrGetConnectionFromPersistData (
  159. IN const CLSID& clsid,
  160. IN const BYTE* pbData,
  161. IN ULONG cbData,
  162. IN REFIID riid,
  163. OUT VOID** ppv)
  164. {
  165. Assert (pbData);
  166. Assert (cbData);
  167. Assert (ppv);
  168. HRESULT hr;
  169. // Initialize the output parameter.
  170. //
  171. *ppv = NULL;
  172. // Create a connection object and get an IPersistNetConnection
  173. // interface pointer on it.
  174. //
  175. IPersistNetConnection* pPersist;
  176. hr = HrCreateInstance(
  177. clsid,
  178. CLSCTX_LOCAL_SERVER | CLSCTX_NO_CODE_DOWNLOAD,
  179. &pPersist);
  180. TraceHr(ttidError, FAL, hr, FALSE, "HrCreateInstance");
  181. if (SUCCEEDED(hr))
  182. {
  183. // Initialize the connection object using the persist data.
  184. //
  185. hr = pPersist->Load (pbData, cbData);
  186. TraceHr(ttidError, FAL, hr, FALSE,
  187. "pPersist->Load: pbData=0x%p, cbData=%u",
  188. pbData, cbData);
  189. if (SUCCEEDED(hr))
  190. {
  191. // Return an INetConnection interface pointer.
  192. //
  193. hr = pPersist->QueryInterface(riid, ppv);
  194. TraceHr(ttidError, FAL, hr, FALSE, "pPersist->QueryInterface");
  195. if (SUCCEEDED(hr))
  196. {
  197. NcSetProxyBlanket (reinterpret_cast<IUnknown *>(*ppv));
  198. }
  199. }
  200. ReleaseObj (pPersist);
  201. }
  202. TraceError("HrGetConnectionFromPersistData", hr);
  203. return hr;
  204. }
  205. //+---------------------------------------------------------------------------
  206. //
  207. // Function: FIsValidConnectionName
  208. //
  209. // Purpose: Determines if the given connection name is valid.
  210. //
  211. // Arguments:
  212. // pszName [in] Connection name to test
  213. //
  214. // Returns: TRUE if name is valid, FALSE if not
  215. //
  216. // Author: danielwe 14 Sep 1998
  217. //
  218. // Notes:
  219. //
  220. BOOL
  221. FIsValidConnectionName (
  222. IN PCWSTR pszName)
  223. {
  224. static const WCHAR c_szInvalidChars[] = L"\\/:*?\"<>|\t";
  225. const WCHAR* pchName;
  226. if (lstrlen(pszName) > RASAPIP_MAX_ENTRY_NAME)
  227. {
  228. return FALSE;
  229. }
  230. DWORD dwNonSpaceChars = 0;
  231. for (pchName = pszName; pchName && *pchName; pchName++)
  232. {
  233. if (wcschr(c_szInvalidChars, *pchName))
  234. {
  235. return FALSE;
  236. }
  237. if (*pchName != L' ')
  238. {
  239. dwNonSpaceChars++;
  240. }
  241. }
  242. if (!dwNonSpaceChars)
  243. {
  244. return FALSE;
  245. }
  246. return TRUE;
  247. }
  248. #define REGKEY_NETWORK_CONNECTIONS \
  249. L"System\\CurrentControlSet\\Control\\Network\\Connections"
  250. #define REGVAL_ATLEASTONELANSHOWICON \
  251. L"AtLeastOneLanShowIcon"
  252. VOID
  253. SetOrQueryAtLeastOneLanWithShowIcon (
  254. IN BOOL fSet,
  255. IN BOOL fSetValue,
  256. OUT BOOL* pfQueriedValue)
  257. {
  258. HRESULT hr;
  259. HKEY hkey;
  260. REGSAM samDesired;
  261. DWORD dwValue;
  262. samDesired = (fSet) ? KEY_WRITE : KEY_READ;
  263. hr = HrRegOpenKeyEx (
  264. HKEY_LOCAL_MACHINE,
  265. REGKEY_NETWORK_CONNECTIONS,
  266. samDesired,
  267. &hkey);
  268. if (S_OK == hr)
  269. {
  270. if (fSet)
  271. {
  272. dwValue = (fSetValue) ? 1: 0;
  273. hr = HrRegSetDword (
  274. hkey,
  275. REGVAL_ATLEASTONELANSHOWICON,
  276. dwValue);
  277. }
  278. else
  279. {
  280. Assert (pfQueriedValue);
  281. hr = HrRegQueryDword (
  282. hkey,
  283. REGVAL_ATLEASTONELANSHOWICON,
  284. &dwValue);
  285. *pfQueriedValue = !!dwValue;
  286. }
  287. RegCloseKey (hkey);
  288. }
  289. }
  290. BOOL
  291. FAnyReasonToEnumerateConnectionsForShowIconInfo (
  292. VOID)
  293. {
  294. // If any active RAS connections exist, might as well return TRUE
  295. // because they will probably have the "showicon" bit turned on.
  296. //
  297. if (FExistActiveRasConnections ())
  298. {
  299. return TRUE;
  300. }
  301. BOOL fRet = FALSE;
  302. // If the LAN connection manager has previously noted that at least
  303. // one LAN connection has the showicon bit set, return TRUE.
  304. //
  305. SetOrQueryAtLeastOneLanWithShowIcon (
  306. FALSE, // query the value
  307. FALSE,
  308. &fRet);
  309. return fRet;
  310. }
  311. //+---------------------------------------------------------------------------
  312. //
  313. // Function: HrSafeArrayFromNetConPropertiesEx
  314. //
  315. // Purpose: Create a safe array that can be marshaled across processes.
  316. //
  317. //
  318. //
  319. // Arguments:
  320. // pPropsEx [in] Properties to use to build the safe array.
  321. // ppsaProperties [out] Safe array in which to store data.
  322. //
  323. // Returns: HRESULT
  324. //
  325. // Author: ckotze 19 Mar 2001
  326. //
  327. // Notes: Caller must free array and contents.
  328. //
  329. //
  330. HRESULT
  331. HrSafeArrayFromNetConPropertiesEx (
  332. IN NETCON_PROPERTIES_EX* pPropsEx,
  333. OUT SAFEARRAY** ppsaProperties)
  334. {
  335. HRESULT hr = S_OK;
  336. SAFEARRAYBOUND rgsaBound[1] = {0};
  337. if (!pPropsEx)
  338. {
  339. return E_INVALIDARG;
  340. }
  341. if (!ppsaProperties)
  342. {
  343. return E_POINTER;
  344. }
  345. rgsaBound[0].cElements = NCP_ELEMENTS;
  346. rgsaBound[0].lLbound = 0;
  347. *ppsaProperties = SafeArrayCreate(VT_VARIANT, 1, rgsaBound);
  348. if (*ppsaProperties)
  349. {
  350. CPropertiesEx peProps(pPropsEx);
  351. for (LONG i = NCP_DWSIZE; i <= NCP_MAX; i++)
  352. {
  353. CComVariant varField;
  354. hr = peProps.GetField(i, varField);
  355. if (SUCCEEDED(hr))
  356. {
  357. hr = SafeArrayPutElement(*ppsaProperties, &i, reinterpret_cast<void*>(&varField));
  358. }
  359. if (FAILED(hr))
  360. {
  361. break;
  362. }
  363. }
  364. }
  365. else
  366. {
  367. hr = E_OUTOFMEMORY;
  368. }
  369. TraceHr (ttidError, FAL, hr, FALSE, "HrSafeArrayFromNetConPropertiesEx");
  370. return hr;
  371. }
  372. //+---------------------------------------------------------------------------
  373. //
  374. // Function: HrNetConPropertiesExFromSafeArray
  375. //
  376. // Purpose: Rebuilds a NETCON_PROPERTIES_EX* structure from the safearray.
  377. //
  378. //
  379. //
  380. // Arguments:
  381. // psaProperties [in] The safe array containing the data
  382. // ppPropsEx [out] Structure containing the properties
  383. //
  384. // Returns: HRESULT - S_OK if valid, else an error.
  385. //
  386. // Author: ckotze 19 Mar 2001
  387. //
  388. // Notes: Caller must free ppPropsEx using HrFreeNetConProperties2
  389. //
  390. HRESULT HrNetConPropertiesExFromSafeArray(
  391. IN SAFEARRAY* psaProperties,
  392. OUT NETCON_PROPERTIES_EX** ppPropsEx)
  393. {
  394. HRESULT hr = S_OK;
  395. LONG lLBound;
  396. LONG lUBound;
  397. if (!psaProperties)
  398. {
  399. return E_INVALIDARG;
  400. }
  401. *ppPropsEx = reinterpret_cast<NETCON_PROPERTIES_EX*>(CoTaskMemAlloc(sizeof(NETCON_PROPERTIES_EX)));
  402. if (*ppPropsEx)
  403. {
  404. hr = SafeArrayGetLBound(psaProperties, 1, &lLBound);
  405. if (SUCCEEDED(hr))
  406. {
  407. hr = SafeArrayGetUBound(psaProperties, 1, &lUBound);
  408. if (SUCCEEDED(hr))
  409. {
  410. CPropertiesEx PropEx(*ppPropsEx);
  411. for (LONG i = lLBound; i <= lUBound; i++)
  412. {
  413. CComVariant varField;
  414. hr = SafeArrayGetElement(psaProperties, &i, reinterpret_cast<LPVOID>(&varField));
  415. if (SUCCEEDED(hr))
  416. {
  417. hr = PropEx.SetField(i, varField);
  418. }
  419. if (FAILED(hr))
  420. {
  421. break;
  422. }
  423. }
  424. }
  425. }
  426. }
  427. else
  428. {
  429. hr = E_OUTOFMEMORY;
  430. }
  431. TraceHr (ttidError, FAL, hr, FALSE, "HrNetConPropertiesExFromSafeArray");
  432. return hr;
  433. }
  434. //+---------------------------------------------------------------------------
  435. //
  436. // Function: HrFreeNetConProperties2
  437. //
  438. // Purpose: Free all strings in the structure and then free the structure.
  439. //
  440. //
  441. //
  442. // Arguments:
  443. // pPropsEx [in] The properties to free.
  444. //
  445. // Returns: HRESULT - S_OK if success else an error
  446. //
  447. // Author: ckotze 19 Mar 2001
  448. //
  449. // Notes:
  450. //
  451. HRESULT HrFreeNetConProperties2(NETCON_PROPERTIES_EX* pPropsEx)
  452. {
  453. HRESULT hr = S_OK;
  454. Assert(pPropsEx);
  455. if (pPropsEx)
  456. {
  457. if (pPropsEx->bstrName)
  458. {
  459. SysFreeString(pPropsEx->bstrName);
  460. }
  461. if (pPropsEx->bstrDeviceName)
  462. {
  463. SysFreeString(pPropsEx->bstrDeviceName);
  464. }
  465. if (pPropsEx->bstrPhoneOrHostAddress)
  466. {
  467. SysFreeString(pPropsEx->bstrPhoneOrHostAddress);
  468. }
  469. if (pPropsEx->bstrPersistData)
  470. {
  471. SysFreeString(pPropsEx->bstrPersistData);
  472. }
  473. CoTaskMemFree(pPropsEx);
  474. }
  475. else
  476. {
  477. hr = E_INVALIDARG;
  478. }
  479. return hr;
  480. }