//+--------------------------------------------------------------------------- // // Microsoft Windows // Copyright (C) Microsoft Corporation, 1997. // // File: N C N E T C O N . C P P // // Contents: Common routines for dealing with the connections interfaces. // // Notes: Pollute this under penalty of death. // // Author: shaunco 20 Aug 1998 // //---------------------------------------------------------------------------- #include #pragma hdrstop #include #include "nccom.h" #include "ncnetcon.h" #include "netconp.h" #include "ncras.h" #include "ncreg.h" #include "ncconv.h" //+--------------------------------------------------------------------------- // // Function: FreeNetconProperties // // Purpose: Free the memory associated with the output parameter of // INetConnection->GetProperties. This is a helper function // used by clients of INetConnection. // // Arguments: // pProps [in] The properties to free. // // Returns: nothing. // // Author: shaunco 1 Feb 1998 // // Notes: // VOID FreeNetconProperties ( IN NETCON_PROPERTIES* pProps) { if (pProps) { CoTaskMemFree (pProps->pszwName); CoTaskMemFree (pProps->pszwDeviceName); CoTaskMemFree (pProps); } } //+--------------------------------------------------------------------------- // // Function: HrGetConnectionPersistData // // Purpose: Get the persistent form of a connection. This can be used // to later get back to the INetConnection interface with a call // to HrGetConnectionFromPersistData. // // Arguments: // pConn [in] Connection to get persist data from. // ppbData [out] Address of where to return pointer to data. // pcbSize [out] Address of where to return the size of the data. // pclsid [out] Address of where to return the CLSID of the connection. // // Returns: S_OK or an error code // // Author: shaunco 20 Aug 1998 // // Notes: Free *ppbData with MemFree. // HRESULT HrGetConnectionPersistData ( IN INetConnection* pConn, OUT BYTE** ppbData, OUT ULONG* pcbSize, OUT CLSID* pclsid OPTIONAL) { Assert (pConn); Assert (ppbData); Assert (pcbSize); // pclsid is optional. // Initialize the output parameters. // *ppbData = NULL; *pcbSize = 0; if (pclsid) { *pclsid = GUID_NULL; } // Get the IPersistNetConnection interfaces. // IPersistNetConnection* pPersist; HRESULT hr = HrQIAndSetProxyBlanket(pConn, &pPersist); if (SUCCEEDED(hr)) { // Return the CLSID if requested. // if (pclsid) { hr = pPersist->GetClassID (pclsid); TraceHr(ttidError, FAL, hr, FALSE, "pPersist->GetClassID"); } if (SUCCEEDED(hr)) { // Get the size required, allocated a buffer, and get the data. // BYTE* pbData; ULONG cbData; hr = pPersist->GetSizeMax (&cbData); TraceHr(ttidError, FAL, hr, FALSE, "pPersist->GetSizeMax"); if (SUCCEEDED(hr)) { hr = E_OUTOFMEMORY; pbData = (BYTE*)MemAlloc (cbData); if (pbData) { hr = pPersist->Save (pbData, cbData); TraceHr(ttidError, FAL, hr, FALSE, "pPersist->Save"); if (SUCCEEDED(hr)) { *ppbData = pbData; *pcbSize = cbData; } else { MemFree (pbData); } } } } ReleaseObj (pPersist); } TraceError("HrGetConnectionPersistData", hr); return hr; } //+--------------------------------------------------------------------------- // // Function: HrGetConnectionFromPersistData // // Purpose: Get an INetConnection interface given the persistent form of // the connection. // // Arguments: // clsid [in] CLSID to CoCreateInstance with. // pbData [in] Pointer to connection's persist data. // cbData [in] Size of the data in bytes. // ppConn [out] Address of where to return the pointer to the // INetConnection interface. // // Returns: S_OK or an error code. // // Author: shaunco 2 Nov 1998 // // Notes: // HRESULT HrGetConnectionFromPersistData ( IN const CLSID& clsid, IN const BYTE* pbData, IN ULONG cbData, IN REFIID riid, OUT VOID** ppv) { Assert (pbData); Assert (cbData); Assert (ppv); HRESULT hr; // Initialize the output parameter. // *ppv = NULL; // Create a connection object and get an IPersistNetConnection // interface pointer on it. // IPersistNetConnection* pPersist; hr = HrCreateInstance( clsid, CLSCTX_LOCAL_SERVER | CLSCTX_NO_CODE_DOWNLOAD, &pPersist); TraceHr(ttidError, FAL, hr, FALSE, "HrCreateInstance"); if (SUCCEEDED(hr)) { // Initialize the connection object using the persist data. // hr = pPersist->Load (pbData, cbData); TraceHr(ttidError, FAL, hr, FALSE, "pPersist->Load: pbData=0x%p, cbData=%u", pbData, cbData); if (SUCCEEDED(hr)) { // Return an INetConnection interface pointer. // hr = pPersist->QueryInterface(riid, ppv); TraceHr(ttidError, FAL, hr, FALSE, "pPersist->QueryInterface"); if (SUCCEEDED(hr)) { NcSetProxyBlanket (reinterpret_cast(*ppv)); } } ReleaseObj (pPersist); } TraceError("HrGetConnectionFromPersistData", hr); return hr; } //+--------------------------------------------------------------------------- // // Function: FIsValidConnectionName // // Purpose: Determines if the given connection name is valid. // // Arguments: // pszName [in] Connection name to test // // Returns: TRUE if name is valid, FALSE if not // // Author: danielwe 14 Sep 1998 // // Notes: // BOOL FIsValidConnectionName ( IN PCWSTR pszName) { static const WCHAR c_szInvalidChars[] = L"\\/:*?\"<>|\t"; const WCHAR* pchName; if (lstrlen(pszName) > RASAPIP_MAX_ENTRY_NAME) { return FALSE; } DWORD dwNonSpaceChars = 0; for (pchName = pszName; pchName && *pchName; pchName++) { if (wcschr(c_szInvalidChars, *pchName)) { return FALSE; } if (*pchName != L' ') { dwNonSpaceChars++; } } if (!dwNonSpaceChars) { return FALSE; } return TRUE; } #define REGKEY_NETWORK_CONNECTIONS \ L"System\\CurrentControlSet\\Control\\Network\\Connections" #define REGVAL_ATLEASTONELANSHOWICON \ L"AtLeastOneLanShowIcon" VOID SetOrQueryAtLeastOneLanWithShowIcon ( IN BOOL fSet, IN BOOL fSetValue, OUT BOOL* pfQueriedValue) { HRESULT hr; HKEY hkey; REGSAM samDesired; DWORD dwValue; samDesired = (fSet) ? KEY_WRITE : KEY_READ; hr = HrRegOpenKeyEx ( HKEY_LOCAL_MACHINE, REGKEY_NETWORK_CONNECTIONS, samDesired, &hkey); if (S_OK == hr) { if (fSet) { dwValue = (fSetValue) ? 1: 0; hr = HrRegSetDword ( hkey, REGVAL_ATLEASTONELANSHOWICON, dwValue); } else { Assert (pfQueriedValue); hr = HrRegQueryDword ( hkey, REGVAL_ATLEASTONELANSHOWICON, &dwValue); *pfQueriedValue = !!dwValue; } RegCloseKey (hkey); } } BOOL FAnyReasonToEnumerateConnectionsForShowIconInfo ( VOID) { // If any active RAS connections exist, might as well return TRUE // because they will probably have the "showicon" bit turned on. // if (FExistActiveRasConnections ()) { return TRUE; } BOOL fRet = FALSE; // If the LAN connection manager has previously noted that at least // one LAN connection has the showicon bit set, return TRUE. // SetOrQueryAtLeastOneLanWithShowIcon ( FALSE, // query the value FALSE, &fRet); return fRet; } //+--------------------------------------------------------------------------- // // Function: HrSafeArrayFromNetConPropertiesEx // // Purpose: Create a safe array that can be marshaled across processes. // // // // Arguments: // pPropsEx [in] Properties to use to build the safe array. // ppsaProperties [out] Safe array in which to store data. // // Returns: HRESULT // // Author: ckotze 19 Mar 2001 // // Notes: Caller must free array and contents. // // HRESULT HrSafeArrayFromNetConPropertiesEx ( IN NETCON_PROPERTIES_EX* pPropsEx, OUT SAFEARRAY** ppsaProperties) { HRESULT hr = S_OK; SAFEARRAYBOUND rgsaBound[1] = {0}; if (!pPropsEx) { return E_INVALIDARG; } if (!ppsaProperties) { return E_POINTER; } rgsaBound[0].cElements = NCP_ELEMENTS; rgsaBound[0].lLbound = 0; *ppsaProperties = SafeArrayCreate(VT_VARIANT, 1, rgsaBound); if (*ppsaProperties) { CPropertiesEx peProps(pPropsEx); for (LONG i = NCP_DWSIZE; i <= NCP_MAX; i++) { CComVariant varField; hr = peProps.GetField(i, varField); if (SUCCEEDED(hr)) { hr = SafeArrayPutElement(*ppsaProperties, &i, reinterpret_cast(&varField)); } if (FAILED(hr)) { break; } } } else { hr = E_OUTOFMEMORY; } TraceHr (ttidError, FAL, hr, FALSE, "HrSafeArrayFromNetConPropertiesEx"); return hr; } //+--------------------------------------------------------------------------- // // Function: HrNetConPropertiesExFromSafeArray // // Purpose: Rebuilds a NETCON_PROPERTIES_EX* structure from the safearray. // // // // Arguments: // psaProperties [in] The safe array containing the data // ppPropsEx [out] Structure containing the properties // // Returns: HRESULT - S_OK if valid, else an error. // // Author: ckotze 19 Mar 2001 // // Notes: Caller must free ppPropsEx using HrFreeNetConProperties2 // HRESULT HrNetConPropertiesExFromSafeArray( IN SAFEARRAY* psaProperties, OUT NETCON_PROPERTIES_EX** ppPropsEx) { HRESULT hr = S_OK; LONG lLBound; LONG lUBound; if (!psaProperties) { return E_INVALIDARG; } *ppPropsEx = reinterpret_cast(CoTaskMemAlloc(sizeof(NETCON_PROPERTIES_EX))); if (*ppPropsEx) { hr = SafeArrayGetLBound(psaProperties, 1, &lLBound); if (SUCCEEDED(hr)) { hr = SafeArrayGetUBound(psaProperties, 1, &lUBound); if (SUCCEEDED(hr)) { CPropertiesEx PropEx(*ppPropsEx); for (LONG i = lLBound; i <= lUBound; i++) { CComVariant varField; hr = SafeArrayGetElement(psaProperties, &i, reinterpret_cast(&varField)); if (SUCCEEDED(hr)) { hr = PropEx.SetField(i, varField); } if (FAILED(hr)) { break; } } } } } else { hr = E_OUTOFMEMORY; } TraceHr (ttidError, FAL, hr, FALSE, "HrNetConPropertiesExFromSafeArray"); return hr; } //+--------------------------------------------------------------------------- // // Function: HrFreeNetConProperties2 // // Purpose: Free all strings in the structure and then free the structure. // // // // Arguments: // pPropsEx [in] The properties to free. // // Returns: HRESULT - S_OK if success else an error // // Author: ckotze 19 Mar 2001 // // Notes: // HRESULT HrFreeNetConProperties2(NETCON_PROPERTIES_EX* pPropsEx) { HRESULT hr = S_OK; Assert(pPropsEx); if (pPropsEx) { if (pPropsEx->bstrName) { SysFreeString(pPropsEx->bstrName); } if (pPropsEx->bstrDeviceName) { SysFreeString(pPropsEx->bstrDeviceName); } if (pPropsEx->bstrPhoneOrHostAddress) { SysFreeString(pPropsEx->bstrPhoneOrHostAddress); } if (pPropsEx->bstrPersistData) { SysFreeString(pPropsEx->bstrPersistData); } CoTaskMemFree(pPropsEx); } else { hr = E_INVALIDARG; } return hr; }