mirror of https://github.com/tongzx/nt5src
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.
946 lines
24 KiB
946 lines
24 KiB
#include "pch.h"
|
|
#pragma hdrstop
|
|
|
|
#include "nccom.h"
|
|
#include "ncnetcon.h"
|
|
#include "ncreg.h"
|
|
#include "saconob.h"
|
|
static const CLSID CLSID_SharedAccessConnectionUi =
|
|
{0x7007ACD5,0x3202,0x11D1,{0xAA,0xD2,0x00,0x80,0x5F,0xC1,0x27,0x0E}};
|
|
|
|
static const WCHAR c_szConnName[] = L"Name";
|
|
static const WCHAR c_szShowIcon[] = L"ShowIcon";
|
|
static const WCHAR c_szSharedAccessClientKeyPath[] = L"System\\CurrentControlSet\\Control\\Network\\SharedAccessConnection";
|
|
|
|
#define UPNP_ACTION_HRESULT(lError) (UPNP_E_ACTION_SPECIFIC_BASE + (lError - FAULT_ACTION_SPECIFIC_BASE))
|
|
|
|
|
|
CSharedAccessConnection::CSharedAccessConnection()
|
|
{
|
|
m_pSharedAccessBeacon = NULL;
|
|
m_pWANConnectionService = NULL;
|
|
}
|
|
|
|
HRESULT CSharedAccessConnection::FinalConstruct()
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
ISharedAccessBeaconFinder* pBeaconFinder;
|
|
hr = HrCreateInstance(CLSID_SharedAccessConnectionManager, CLSCTX_SERVER, &pBeaconFinder);
|
|
if(SUCCEEDED(hr))
|
|
{
|
|
hr = pBeaconFinder->GetSharedAccessBeacon(NULL, &m_pSharedAccessBeacon);
|
|
if(SUCCEEDED(hr))
|
|
{
|
|
NETCON_MEDIATYPE MediaType;
|
|
hr = m_pSharedAccessBeacon->GetMediaType(&MediaType);
|
|
if(SUCCEEDED(hr))
|
|
{
|
|
hr = m_pSharedAccessBeacon->GetService(NCM_SHAREDACCESSHOST_LAN == MediaType ? SAHOST_SERVICE_WANIPCONNECTION : SAHOST_SERVICE_WANPPPCONNECTION, &m_pWANConnectionService);
|
|
}
|
|
}
|
|
pBeaconFinder->Release();
|
|
}
|
|
return hr;
|
|
}
|
|
|
|
HRESULT CSharedAccessConnection::FinalRelease()
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
if(NULL != m_pSharedAccessBeacon)
|
|
{
|
|
m_pSharedAccessBeacon->Release();
|
|
}
|
|
|
|
if(NULL != m_pWANConnectionService)
|
|
{
|
|
m_pWANConnectionService->Release();
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Member: CSharedAccessConnection::GetConnectionName
|
|
//
|
|
// Purpose: Initializes the connection object for the first time.
|
|
//
|
|
// Arguments:
|
|
// (none)
|
|
//
|
|
// Returns: S_OK if success, Win32 or OLE error code otherwise
|
|
//
|
|
// Author: kenwic 8 Aug 2000
|
|
//
|
|
// Notes: This function is only called when the object is created for
|
|
// the very first time and has no identity.
|
|
//
|
|
HRESULT CSharedAccessConnection::GetConnectionName(LPWSTR* pName)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
HKEY hKey;
|
|
|
|
// first get the user assigned name
|
|
|
|
hr = HrRegOpenKeyEx(HKEY_LOCAL_MACHINE, c_szSharedAccessClientKeyPath, KEY_READ, &hKey);
|
|
if(SUCCEEDED(hr))
|
|
{
|
|
tstring strName;
|
|
hr = HrRegQueryString(hKey, c_szConnName, &strName);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
hr = HrCoTaskMemAllocAndDupSz (strName.c_str(), pName);
|
|
}
|
|
RegCloseKey(hKey);
|
|
}
|
|
|
|
// if that doesn't exist, construct the name
|
|
|
|
if(FAILED(hr))
|
|
{
|
|
IUPnPService* pOSInfoService;
|
|
hr = m_pSharedAccessBeacon->GetService(SAHOST_SERVICE_OSINFO, &pOSInfoService);
|
|
if(SUCCEEDED(hr))
|
|
{
|
|
BSTR MachineName;
|
|
hr = GetStringStateVariable(pOSInfoService, L"OSMachineName", &MachineName);
|
|
if(SUCCEEDED(hr))
|
|
{
|
|
BSTR SharedAdapterName;
|
|
hr = GetStringStateVariable(m_pWANConnectionService, L"X_Name", &SharedAdapterName);
|
|
if(SUCCEEDED(hr))
|
|
{
|
|
LPWSTR szNameString;
|
|
LPCWSTR szTemplateString = SzLoadIds(IDS_SHAREDACCESS_CONN_NAME);
|
|
Assert(NULL != szTemplateString);
|
|
|
|
LPOLESTR pszParams[] = {SharedAdapterName, MachineName};
|
|
|
|
if(0 != FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_ARGUMENT_ARRAY, szTemplateString, 0, 0, reinterpret_cast<LPWSTR>(&szNameString), 0, reinterpret_cast<va_list *>(pszParams)))
|
|
{
|
|
HrCoTaskMemAllocAndDupSz (szNameString, pName);
|
|
LocalFree(szNameString);
|
|
}
|
|
else
|
|
{
|
|
hr = HRESULT_FROM_WIN32(GetLastError());
|
|
}
|
|
SysFreeString(SharedAdapterName);
|
|
}
|
|
SysFreeString(MachineName);
|
|
}
|
|
pOSInfoService->Release();
|
|
}
|
|
|
|
}
|
|
|
|
// if that fails, use the default
|
|
|
|
if(FAILED(hr))
|
|
{
|
|
hr = HrCoTaskMemAllocAndDupSz (SzLoadIds(IDS_SHAREDACCESS_DEFAULT_CONN_NAME), pName);
|
|
}
|
|
|
|
TraceError("CSharedAccessConnection::HrInitialize", hr);
|
|
return hr;
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Member: CSharedAccessConnection::GetStatus
|
|
//
|
|
// Purpose: Returns the status of this ICS connection
|
|
//
|
|
// Arguments:
|
|
// pStatus [out] Returns status value
|
|
//
|
|
// Returns: S_OK if success, OLE or Win32 error code otherwise
|
|
//
|
|
// Author: kenwic 8 Aug 2000
|
|
//
|
|
// Notes:
|
|
//
|
|
HRESULT CSharedAccessConnection::GetStatus(NETCON_STATUS *pStatus)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
if (!pStatus)
|
|
{
|
|
hr = E_POINTER;
|
|
}
|
|
else
|
|
{
|
|
BSTR ConnectionStatus;
|
|
hr = GetStringStateVariable(m_pWANConnectionService, L"ConnectionStatus", &ConnectionStatus);
|
|
if(SUCCEEDED(hr))
|
|
{
|
|
if(0 == lstrcmp(ConnectionStatus, L"Connected"))
|
|
{
|
|
*pStatus = NCS_CONNECTED;
|
|
}
|
|
else if(0 == lstrcmp(ConnectionStatus, L"Disconnected"))
|
|
{
|
|
*pStatus = NCS_DISCONNECTED;
|
|
}
|
|
else if(0 == lstrcmp(ConnectionStatus, L"Unconfigured"))
|
|
{
|
|
*pStatus = NCS_HARDWARE_DISABLED; // REVIEW: better state?
|
|
}
|
|
else if(0 == lstrcmp(ConnectionStatus, L"Connecting"))
|
|
{
|
|
*pStatus = NCS_CONNECTING;
|
|
}
|
|
else if(0 == lstrcmp(ConnectionStatus, L"Authenticating"))
|
|
{
|
|
*pStatus = NCS_CONNECTING;
|
|
}
|
|
else if(0 == lstrcmp(ConnectionStatus, L"PendingDisconnect"))
|
|
{
|
|
*pStatus = NCS_DISCONNECTING;
|
|
}
|
|
else if(0 == lstrcmp(ConnectionStatus, L"Disconnecting"))
|
|
{
|
|
*pStatus = NCS_DISCONNECTING;
|
|
}
|
|
else
|
|
{
|
|
*pStatus = NCS_HARDWARE_DISABLED;
|
|
}
|
|
SysFreeString(ConnectionStatus);
|
|
}
|
|
}
|
|
|
|
TraceError("CSharedAccessConnection::GetStatus", hr);
|
|
return hr;
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Member: CSharedAccessConnection::GetCharacteristics
|
|
//
|
|
// Purpose: Returns the characteristics of this connection type
|
|
//
|
|
// Arguments:
|
|
// pdwFlags [out] Returns characteristics flags
|
|
//
|
|
// Returns: S_OK if successful, OLE or Win32 error code otherwise
|
|
//
|
|
// Author: kenwic 8 Aug 2000
|
|
//
|
|
// Notes:
|
|
//
|
|
HRESULT CSharedAccessConnection::GetCharacteristics(DWORD* pdwFlags)
|
|
{
|
|
Assert (pdwFlags);
|
|
|
|
// TODO when get have a place to save the name, allow rename
|
|
HRESULT hr = S_OK;
|
|
|
|
*pdwFlags = NCCF_ALL_USERS | NCCF_ALLOW_RENAME; // REVIEW always ok, group policy?
|
|
|
|
HKEY hKey;
|
|
hr = HrRegOpenKeyEx(HKEY_LOCAL_MACHINE, c_szSharedAccessClientKeyPath, KEY_QUERY_VALUE, &hKey);
|
|
if(SUCCEEDED(hr))
|
|
{
|
|
DWORD dwShowIcon = 0;
|
|
DWORD dwSize = sizeof(dwShowIcon);
|
|
DWORD dwType;
|
|
hr = HrRegQueryValueEx(hKey, c_szShowIcon, &dwType, reinterpret_cast<LPBYTE>(&dwShowIcon), &dwSize);
|
|
if(SUCCEEDED(hr) && REG_DWORD == dwType)
|
|
{
|
|
if(0 != dwShowIcon)
|
|
{
|
|
*pdwFlags |= NCCF_SHOW_ICON;
|
|
}
|
|
}
|
|
RegCloseKey(hKey);
|
|
|
|
}
|
|
|
|
hr = S_OK; // it's ok if the key doesn't exist
|
|
|
|
TraceError("CSharedAccessConnection::GetCharacteristics", hr);
|
|
return hr;
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Member: CSharedAccessConnection::Connect
|
|
//
|
|
// Purpose: Connects the remote ICS host
|
|
//
|
|
// Arguments:
|
|
// (none)
|
|
//
|
|
// Returns: S_OK if success, OLE or Win32 error code otherwise
|
|
//
|
|
// Author: kenwic 8 Aug 2000
|
|
//
|
|
|
|
HRESULT CSharedAccessConnection::Connect()
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
VARIANT OutArgs;
|
|
hr = InvokeVoidAction(m_pWANConnectionService, L"RequestConnection", &OutArgs);
|
|
if(UPNP_ACTION_HRESULT(800) == hr)
|
|
{
|
|
hr = E_ACCESSDENIED;
|
|
VariantClear(&OutArgs);
|
|
}
|
|
|
|
TraceError("CSharedAccessConnection::Connect", hr);
|
|
return hr;
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Member: CSharedAccessConnection::Disconnect
|
|
//
|
|
// Purpose: Disconnects the remote ICS host
|
|
//
|
|
// Arguments:
|
|
// (none)
|
|
//
|
|
// Returns: S_OK if success, OLE or Win32 error code otherwise
|
|
//
|
|
// Author: kenwic 8 Aug 2000
|
|
//
|
|
|
|
HRESULT CSharedAccessConnection::Disconnect()
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
VARIANT OutArgs;
|
|
hr = InvokeVoidAction(m_pWANConnectionService, L"ForceTermination", &OutArgs);
|
|
if(UPNP_ACTION_HRESULT(800) == hr)
|
|
{
|
|
hr = E_ACCESSDENIED;
|
|
VariantClear(&OutArgs);
|
|
}
|
|
|
|
TraceError("CSharedAccessConnection::Disconnect", hr);
|
|
return hr;
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Member: CSharedAccessConnection::Delete
|
|
//
|
|
// Purpose: Delete the remote ICS connection. This not allowed.
|
|
//
|
|
// Arguments:
|
|
// (none)
|
|
//
|
|
// Returns: E_FAIL;
|
|
//
|
|
// Author: kenwic 8 Aug 2000
|
|
//
|
|
// Notes: This function is not expected to ever be called.
|
|
//
|
|
|
|
HRESULT CSharedAccessConnection::Delete()
|
|
{
|
|
return E_FAIL; // can't delete the beacon
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Member: CSharedAccessConnection::Duplicate
|
|
//
|
|
// Purpose: Duplicates the remote ICS connection. This not allowed.
|
|
//
|
|
// Arguments:
|
|
// (none)
|
|
//
|
|
// Returns: E_UNEXPECTED;
|
|
//
|
|
// Author: kenwic 8 Aug 2000
|
|
//
|
|
// Notes: This function is not expected to ever be called.
|
|
//
|
|
|
|
STDMETHODIMP CSharedAccessConnection::Duplicate (
|
|
PCWSTR pszDuplicateName,
|
|
INetConnection** ppCon)
|
|
{
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Member: CSharedAccessConnection::GetProperties
|
|
//
|
|
// Purpose: Get all of the properties associated with the connection.
|
|
// Returning all of them at once saves us RPCs vs. returning
|
|
// each one individually.
|
|
//
|
|
// Arguments:
|
|
// ppProps [out] Returned block of properties.
|
|
//
|
|
// Returns: S_OK or an error.
|
|
//
|
|
// Author: kenwic 8 Aug 2000
|
|
//
|
|
// Notes:
|
|
//
|
|
STDMETHODIMP CSharedAccessConnection::GetProperties (
|
|
NETCON_PROPERTIES** ppProps)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
// Validate parameters.
|
|
//
|
|
if (!ppProps)
|
|
{
|
|
hr = E_POINTER;
|
|
}
|
|
else
|
|
{
|
|
// Initialize the output parameter.
|
|
//
|
|
*ppProps = NULL;
|
|
|
|
NETCON_PROPERTIES* pProps;
|
|
hr = HrCoTaskMemAlloc (sizeof (NETCON_PROPERTIES), reinterpret_cast<void**>(&pProps));
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
HRESULT hrT;
|
|
|
|
ZeroMemory (pProps, sizeof (NETCON_PROPERTIES));
|
|
|
|
// guidId
|
|
//
|
|
pProps->guidId = CLSID_SharedAccessConnection; // there is only ever one beacon icon, so we'll just use our class id.
|
|
// we can't use all zeroes because the add connection wizard does that
|
|
|
|
// pszwName
|
|
//
|
|
|
|
hrT = GetConnectionName(&pProps->pszwName);
|
|
if (FAILED(hrT))
|
|
{
|
|
hr = hrT;
|
|
}
|
|
|
|
// pszwDeviceName
|
|
//
|
|
hrT = HrCoTaskMemAllocAndDupSz (pProps->pszwName, &pProps->pszwDeviceName); // TODO the spec says the same as pszwName here, is that right
|
|
if (FAILED(hrT))
|
|
{
|
|
hr = hrT;
|
|
}
|
|
|
|
// Status
|
|
//
|
|
hrT = GetStatus (&pProps->Status);
|
|
if (FAILED(hrT))
|
|
{
|
|
hr = hrT;
|
|
}
|
|
|
|
if(NULL != m_pSharedAccessBeacon)
|
|
{
|
|
hr = m_pSharedAccessBeacon->GetMediaType(&pProps->MediaType);
|
|
}
|
|
else
|
|
{
|
|
hr = E_UNEXPECTED;
|
|
}
|
|
|
|
hrT = GetCharacteristics (&pProps->dwCharacter);
|
|
if (FAILED(hrT))
|
|
{
|
|
hr = hrT;
|
|
}
|
|
|
|
// clsidThisObject
|
|
//
|
|
pProps->clsidThisObject = CLSID_SharedAccessConnection;
|
|
|
|
// clsidUiObject
|
|
//
|
|
pProps->clsidUiObject = CLSID_SharedAccessConnectionUi;
|
|
|
|
// Assign the output parameter or cleanup if we had any failures.
|
|
//
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
*ppProps = pProps;
|
|
}
|
|
else
|
|
{
|
|
Assert (NULL == *ppProps);
|
|
FreeNetconProperties (pProps);
|
|
}
|
|
}
|
|
}
|
|
TraceError ("CLanConnection::GetProperties", hr);
|
|
return hr;
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Member: CSharedAccessConnection::GetUiObjectClassId
|
|
//
|
|
// Purpose: Returns the CLSID of the object that handles UI for this
|
|
// connection type
|
|
//
|
|
// Arguments:
|
|
// pclsid [out] Returns CLSID of UI object
|
|
//
|
|
// Returns: S_OK if success, OLE error code otherwise
|
|
//
|
|
// Author: kenwic 8 Aug 2000
|
|
//
|
|
// Notes:
|
|
//
|
|
STDMETHODIMP CSharedAccessConnection::GetUiObjectClassId(CLSID *pclsid)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
// Validate parameters.
|
|
//
|
|
if (!pclsid)
|
|
{
|
|
hr = E_POINTER;
|
|
}
|
|
else
|
|
{
|
|
*pclsid = CLSID_SharedAccessConnectionUi;
|
|
}
|
|
|
|
TraceError("CLanConnection::GetUiObjectClassId", hr);
|
|
return hr;
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Member: CSharedAccessConnection::Rename
|
|
//
|
|
// Purpose: Changes the name of the connection
|
|
//
|
|
// Arguments:
|
|
// pszName [in] New connection name (must be valid)
|
|
//
|
|
// Returns: S_OK if success, OLE error code otherwise
|
|
//
|
|
// Author: kenwic 8 Aug 2000
|
|
//
|
|
// Notes:
|
|
//
|
|
STDMETHODIMP CSharedAccessConnection::Rename(PCWSTR pszName)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
if (!pszName)
|
|
{
|
|
hr = E_POINTER;
|
|
}
|
|
else if (!FIsValidConnectionName(pszName))
|
|
{
|
|
// Bad connection name
|
|
hr = E_INVALIDARG;
|
|
}
|
|
else
|
|
{
|
|
|
|
HKEY hKey;
|
|
hr = HrRegCreateKeyEx(HKEY_LOCAL_MACHINE, c_szSharedAccessClientKeyPath, NULL, KEY_SET_VALUE, NULL, &hKey, NULL);
|
|
if(SUCCEEDED(hr))
|
|
{
|
|
hr = HrRegSetSz(hKey, c_szConnName, pszName);
|
|
if (S_OK == hr)
|
|
{
|
|
INetConnectionRefresh* pNetConnectionRefresh;
|
|
hr = CoCreateInstance(CLSID_ConnectionManager, NULL, CLSCTX_SERVER, IID_INetConnectionRefresh, reinterpret_cast<void**>(&pNetConnectionRefresh));
|
|
if(SUCCEEDED(hr))
|
|
{
|
|
pNetConnectionRefresh->ConnectionRenamed(this);
|
|
pNetConnectionRefresh->Release();
|
|
}
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
TraceError("CLanConnection::Rename", hr);
|
|
return hr;
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
// IPersistNetConnection
|
|
//
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Member: CSharedAccessConnection::GetClassID
|
|
//
|
|
// Purpose: Returns the CLSID of connection objects
|
|
//
|
|
// Arguments:
|
|
// pclsid [out] Returns CLSID to caller
|
|
//
|
|
// Returns: S_OK if success, OLE error otherwise
|
|
//
|
|
// Author: kenwic 8 Aug 2000
|
|
//
|
|
// Notes:
|
|
//
|
|
STDMETHODIMP CSharedAccessConnection::GetClassID(CLSID* pclsid)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
// Validate parameters.
|
|
//
|
|
if (!pclsid)
|
|
{
|
|
hr = E_POINTER;
|
|
}
|
|
else
|
|
{
|
|
*pclsid = CLSID_SharedAccessConnection; // we just use our guid since there is only ever one saconob
|
|
}
|
|
TraceError("CSharedAccessConnection::GetClassID", hr);
|
|
return hr;
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Member: CSharedAccessConnection::GetSizeMax
|
|
//
|
|
// Purpose: Returns the maximum size of the persistence data
|
|
//
|
|
// Arguments:
|
|
// pcbSize [out] Returns size
|
|
//
|
|
// Returns: S_OK if success, OLE error otherwise
|
|
//
|
|
// Author: kenwic 8 Aug 2000
|
|
//
|
|
// Notes:
|
|
//
|
|
STDMETHODIMP CSharedAccessConnection::GetSizeMax(ULONG *pcbSize)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
// Validate parameters.
|
|
//
|
|
if (!pcbSize)
|
|
{
|
|
hr = E_POINTER;
|
|
}
|
|
else
|
|
{
|
|
*pcbSize = sizeof(GUID);
|
|
}
|
|
|
|
TraceError("CLanConnection::GetSizeMax", hr);
|
|
return hr;
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Member: CSharedAccessConnection::Load
|
|
//
|
|
// Purpose: Allows the connection object to initialize (restore) itself
|
|
// from previously persisted data
|
|
//
|
|
// Arguments:
|
|
// pbBuf [in] Private data to use for restoring
|
|
// cbSize [in] Size of data
|
|
//
|
|
// Returns: S_OK if success, OLE error otherwise
|
|
//
|
|
// Author: kenwic 8 Aug 2000
|
|
//
|
|
// Notes:
|
|
//
|
|
STDMETHODIMP CSharedAccessConnection::Load(const BYTE *pbBuf, ULONG cbSize)
|
|
{
|
|
HRESULT hr = E_INVALIDARG;
|
|
|
|
// Validate parameters.
|
|
//
|
|
if (!pbBuf)
|
|
{
|
|
hr = E_POINTER;
|
|
}
|
|
else if (cbSize != sizeof(GUID))
|
|
{
|
|
hr = E_INVALIDARG;
|
|
}
|
|
else
|
|
{
|
|
hr = S_OK; // we don't need this guid, but we have to implemenet IPersistNetConnection
|
|
}
|
|
|
|
TraceError("CLanConnection::Load", hr);
|
|
return hr;
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Member: CSharedAccessConnection::Save
|
|
//
|
|
// Purpose: Provides the caller with data to use in restoring this object
|
|
// at a later time.
|
|
//
|
|
// Arguments:
|
|
// pbBuf [out] Returns data to use for restoring
|
|
// cbSize [in] Size of data buffer
|
|
//
|
|
// Returns: S_OK if success, OLE error otherwise
|
|
//
|
|
// Author: kenwic 8 Aug 2000
|
|
//
|
|
// Notes:
|
|
//
|
|
STDMETHODIMP CSharedAccessConnection::Save(BYTE *pbBuf, ULONG cbSize)
|
|
{
|
|
HRESULT hr;
|
|
|
|
// Validate parameters.
|
|
//
|
|
if (!pbBuf)
|
|
{
|
|
hr = E_POINTER;
|
|
}
|
|
else
|
|
{
|
|
CopyMemory(pbBuf, &CLSID_SharedAccessConnection, cbSize); // REVIEW can we eliminate this?
|
|
}
|
|
|
|
TraceError("CLanConnection::Save", hr);
|
|
return hr;
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Member: CSharedAccessConnection::GetInfo
|
|
//
|
|
// Purpose: Returns information about this connection
|
|
//
|
|
// Arguments:
|
|
// dwMask [in] Flags that control which fields to return. Use
|
|
// SACIF_ALL to get all fields.
|
|
// pLanConInfo [out] Structure that holds returned information
|
|
//
|
|
// Returns: S_OK if success, OLE error code otherwise
|
|
//
|
|
// Author: kenwic 6 Sep 2000
|
|
//
|
|
// Notes: Caller should delete the szwConnName value.
|
|
//
|
|
STDMETHODIMP CSharedAccessConnection::GetInfo(DWORD dwMask, SHAREDACCESSCON_INFO* pConInfo)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
if (!pConInfo)
|
|
{
|
|
hr = E_POINTER;
|
|
}
|
|
else
|
|
{
|
|
ZeroMemory(pConInfo, sizeof(SHAREDACCESSCON_INFO));
|
|
|
|
if (dwMask & SACIF_ICON)
|
|
{
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
DWORD dwValue;
|
|
|
|
// OK if value not there. Default to FALSE always.
|
|
//
|
|
|
|
HKEY hKey;
|
|
hr = HrRegOpenKeyEx(HKEY_LOCAL_MACHINE, c_szSharedAccessClientKeyPath, KEY_QUERY_VALUE, &hKey);
|
|
if(SUCCEEDED(hr))
|
|
{
|
|
if (S_OK == HrRegQueryDword(hKey, c_szShowIcon, &dwValue))
|
|
{
|
|
pConInfo->fShowIcon = !!(dwValue);
|
|
}
|
|
RegCloseKey(hKey);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Mask S_FALSE if it slipped thru.
|
|
if (S_FALSE == hr)
|
|
{
|
|
hr = S_OK;
|
|
}
|
|
|
|
TraceError("CSharedAccessConnection::GetInfo", hr);
|
|
return hr;
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Member: CSharedAccessConnection::SetInfo
|
|
//
|
|
// Purpose: Sets information about this connection.
|
|
//
|
|
// Arguments:
|
|
// dwMask [in] Flags that control which fields to set
|
|
// pConInfo [in] Structure containing information to set
|
|
//
|
|
// Returns: S_OK if success, OLE or Win32 error code otherwise
|
|
//
|
|
// Author: kenwic 6 Sep 2000
|
|
//
|
|
|
|
STDMETHODIMP CSharedAccessConnection::SetInfo(DWORD dwMask,
|
|
const SHAREDACCESSCON_INFO* pConInfo)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
if (!pConInfo)
|
|
{
|
|
hr = E_POINTER;
|
|
}
|
|
else
|
|
{
|
|
if (dwMask & SACIF_ICON)
|
|
{
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
// Set ShowIcon value
|
|
HKEY hKey;
|
|
hr = HrRegCreateKeyEx(HKEY_LOCAL_MACHINE, c_szSharedAccessClientKeyPath, NULL, KEY_SET_VALUE, NULL, &hKey, NULL);
|
|
if(SUCCEEDED(hr))
|
|
{
|
|
hr = HrRegSetDword(hKey, c_szShowIcon, pConInfo->fShowIcon);
|
|
RegCloseKey(hKey);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
INetConnectionRefresh* pNetConnectionRefresh;
|
|
hr = CoCreateInstance(CLSID_ConnectionManager, NULL, CLSCTX_SERVER, IID_INetConnectionRefresh, reinterpret_cast<void**>(&pNetConnectionRefresh));
|
|
if(SUCCEEDED(hr))
|
|
{
|
|
pNetConnectionRefresh->ConnectionModified(this);
|
|
pNetConnectionRefresh->Release();
|
|
}
|
|
}
|
|
}
|
|
|
|
TraceError("CSharedAccessConnection::SetInfo", hr);
|
|
return hr;
|
|
}
|
|
|
|
|
|
HRESULT CSharedAccessConnection::GetLocalAdapterGUID(GUID* pGuid)
|
|
{
|
|
return m_pSharedAccessBeacon->GetLocalAdapterGUID(pGuid);
|
|
}
|
|
|
|
HRESULT CSharedAccessConnection::GetService(SAHOST_SERVICES ulService, IUPnPService** ppService)
|
|
{
|
|
return m_pSharedAccessBeacon->GetService(ulService, ppService);
|
|
}
|
|
|
|
HRESULT CSharedAccessConnection::GetStringStateVariable(IUPnPService* pService, LPWSTR pszVariableName, BSTR* pString)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
VARIANT Variant;
|
|
VariantInit(&Variant);
|
|
|
|
BSTR VariableName;
|
|
VariableName = SysAllocString(pszVariableName);
|
|
if(NULL != VariableName)
|
|
{
|
|
hr = pService->QueryStateVariable(VariableName, &Variant);
|
|
if(SUCCEEDED(hr))
|
|
{
|
|
if(V_VT(&Variant) == VT_BSTR)
|
|
{
|
|
*pString = V_BSTR(&Variant);
|
|
}
|
|
else
|
|
{
|
|
hr = E_UNEXPECTED;
|
|
}
|
|
}
|
|
|
|
if(FAILED(hr))
|
|
{
|
|
VariantClear(&Variant);
|
|
}
|
|
|
|
SysFreeString(VariableName);
|
|
}
|
|
else
|
|
{
|
|
hr = E_OUTOFMEMORY;
|
|
}
|
|
|
|
TraceHr (ttidError, FAL, hr, FALSE, "CSharedAccessConnection::GetStringStateVariable");
|
|
|
|
return hr;
|
|
|
|
}
|
|
|
|
HRESULT InvokeVoidAction(IUPnPService * pService, LPTSTR pszCommand, VARIANT* pOutParams)
|
|
{
|
|
HRESULT hr;
|
|
BSTR bstrActionName;
|
|
|
|
bstrActionName = SysAllocString(pszCommand);
|
|
if (NULL != bstrActionName)
|
|
{
|
|
SAFEARRAYBOUND rgsaBound[1];
|
|
SAFEARRAY * psa = NULL;
|
|
|
|
rgsaBound[0].lLbound = 0;
|
|
rgsaBound[0].cElements = 0;
|
|
|
|
psa = SafeArrayCreate(VT_VARIANT, 1, rgsaBound);
|
|
|
|
if (psa)
|
|
{
|
|
LONG lStatus;
|
|
VARIANT varInArgs;
|
|
VARIANT varReturnVal;
|
|
|
|
VariantInit(&varInArgs);
|
|
VariantInit(pOutParams);
|
|
VariantInit(&varReturnVal);
|
|
|
|
varInArgs.vt = VT_VARIANT | VT_ARRAY;
|
|
|
|
V_ARRAY(&varInArgs) = psa;
|
|
|
|
hr = pService->InvokeAction(bstrActionName,
|
|
varInArgs,
|
|
pOutParams,
|
|
&varReturnVal);
|
|
if(SUCCEEDED(hr))
|
|
{
|
|
VariantClear(&varReturnVal);
|
|
}
|
|
|
|
SafeArrayDestroy(psa);
|
|
}
|
|
else
|
|
{
|
|
hr = E_OUTOFMEMORY;
|
|
}
|
|
|
|
SysFreeString(bstrActionName);
|
|
}
|
|
else
|
|
{
|
|
hr = E_OUTOFMEMORY;
|
|
}
|
|
return hr;
|
|
}
|