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.

479 lines
12 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) > NETCON_MAX_NAME_LEN)
  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. //+---------------------------------------------------------------------------
  253. //
  254. // Function: HrSafeArrayFromNetConPropertiesEx
  255. //
  256. // Purpose: Create a safe array that can be marshaled across processes.
  257. //
  258. //
  259. //
  260. // Arguments:
  261. // pPropsEx [in] Properties to use to build the safe array.
  262. // ppsaProperties [out] Safe array in which to store data.
  263. //
  264. // Returns: HRESULT
  265. //
  266. // Author: ckotze 19 Mar 2001
  267. //
  268. // Notes: Caller must free array and contents.
  269. //
  270. //
  271. HRESULT
  272. HrSafeArrayFromNetConPropertiesEx (
  273. IN NETCON_PROPERTIES_EX* pPropsEx,
  274. OUT SAFEARRAY** ppsaProperties)
  275. {
  276. HRESULT hr = S_OK;
  277. SAFEARRAYBOUND rgsaBound[1] = {0};
  278. if (!pPropsEx)
  279. {
  280. return E_INVALIDARG;
  281. }
  282. if (!ppsaProperties)
  283. {
  284. return E_POINTER;
  285. }
  286. rgsaBound[0].cElements = NCP_ELEMENTS;
  287. rgsaBound[0].lLbound = 0;
  288. *ppsaProperties = SafeArrayCreate(VT_VARIANT, 1, rgsaBound);
  289. if (*ppsaProperties)
  290. {
  291. CPropertiesEx peProps(pPropsEx);
  292. for (LONG i = NCP_DWSIZE; i <= NCP_MAX; i++)
  293. {
  294. CComVariant varField;
  295. hr = peProps.GetField(i, varField);
  296. if (SUCCEEDED(hr))
  297. {
  298. hr = SafeArrayPutElement(*ppsaProperties, &i, reinterpret_cast<void*>(&varField));
  299. }
  300. if (FAILED(hr))
  301. {
  302. break;
  303. }
  304. }
  305. }
  306. else
  307. {
  308. hr = E_OUTOFMEMORY;
  309. }
  310. TraceHr (ttidError, FAL, hr, FALSE, "HrSafeArrayFromNetConPropertiesEx");
  311. return hr;
  312. }
  313. //+---------------------------------------------------------------------------
  314. //
  315. // Function: HrNetConPropertiesExFromSafeArray
  316. //
  317. // Purpose: Rebuilds a NETCON_PROPERTIES_EX* structure from the safearray.
  318. //
  319. //
  320. //
  321. // Arguments:
  322. // psaProperties [in] The safe array containing the data
  323. // ppPropsEx [out] Structure containing the properties
  324. //
  325. // Returns: HRESULT - S_OK if valid, else an error.
  326. //
  327. // Author: ckotze 19 Mar 2001
  328. //
  329. // Notes: Caller must free ppPropsEx using HrFreeNetConProperties2
  330. //
  331. HRESULT HrNetConPropertiesExFromSafeArray(
  332. IN SAFEARRAY* psaProperties,
  333. OUT NETCON_PROPERTIES_EX** ppPropsEx)
  334. {
  335. HRESULT hr = S_OK;
  336. LONG lLBound;
  337. LONG lUBound;
  338. if (!psaProperties)
  339. {
  340. return E_INVALIDARG;
  341. }
  342. *ppPropsEx = reinterpret_cast<NETCON_PROPERTIES_EX*>(CoTaskMemAlloc(sizeof(NETCON_PROPERTIES_EX)));
  343. if (*ppPropsEx)
  344. {
  345. hr = SafeArrayGetLBound(psaProperties, 1, &lLBound);
  346. if (SUCCEEDED(hr))
  347. {
  348. hr = SafeArrayGetUBound(psaProperties, 1, &lUBound);
  349. if (SUCCEEDED(hr))
  350. {
  351. CPropertiesEx PropEx(*ppPropsEx);
  352. for (LONG i = lLBound; i <= lUBound; i++)
  353. {
  354. CComVariant varField;
  355. hr = SafeArrayGetElement(psaProperties, &i, reinterpret_cast<LPVOID>(&varField));
  356. if (SUCCEEDED(hr))
  357. {
  358. hr = PropEx.SetField(i, varField);
  359. }
  360. if (FAILED(hr))
  361. {
  362. break;
  363. }
  364. }
  365. }
  366. }
  367. }
  368. else
  369. {
  370. hr = E_OUTOFMEMORY;
  371. }
  372. TraceHr (ttidError, FAL, hr, FALSE, "HrNetConPropertiesExFromSafeArray");
  373. return hr;
  374. }
  375. //+---------------------------------------------------------------------------
  376. //
  377. // Function: HrFreeNetConProperties2
  378. //
  379. // Purpose: Free all strings in the structure and then free the structure.
  380. //
  381. //
  382. //
  383. // Arguments:
  384. // pPropsEx [in] The properties to free.
  385. //
  386. // Returns: HRESULT - S_OK if success else an error
  387. //
  388. // Author: ckotze 19 Mar 2001
  389. //
  390. // Notes:
  391. //
  392. HRESULT HrFreeNetConProperties2(NETCON_PROPERTIES_EX* pPropsEx)
  393. {
  394. HRESULT hr = S_OK;
  395. if (pPropsEx)
  396. {
  397. if (pPropsEx->bstrName)
  398. {
  399. SysFreeString(pPropsEx->bstrName);
  400. }
  401. if (pPropsEx->bstrDeviceName)
  402. {
  403. SysFreeString(pPropsEx->bstrDeviceName);
  404. }
  405. if (pPropsEx->bstrPhoneOrHostAddress)
  406. {
  407. SysFreeString(pPropsEx->bstrPhoneOrHostAddress);
  408. }
  409. if (pPropsEx->bstrPersistData)
  410. {
  411. SysFreeString(pPropsEx->bstrPersistData);
  412. }
  413. CoTaskMemFree(pPropsEx);
  414. }
  415. else
  416. {
  417. hr = S_FALSE;
  418. }
  419. return hr;
  420. }