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.
848 lines
23 KiB
848 lines
23 KiB
//+---------------------------------------------------------------------------
|
|
//
|
|
// Microsoft Windows
|
|
// Copyright (C) Microsoft Corporation, 1997 - 2001.
|
|
//
|
|
// File: I N B O U N D . C P P
|
|
//
|
|
// Contents: Implements the inbound connection object.
|
|
//
|
|
// Notes:
|
|
//
|
|
// Author: shaunco 12 Nov 1997
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
#include "pch.h"
|
|
#pragma hdrstop
|
|
#include "inbound.h"
|
|
#include "nccom.h"
|
|
#include "ncnetcon.h"
|
|
#include "..\conman\conman.h"
|
|
|
|
LONG g_CountIncomingConnectionObjects;
|
|
|
|
static const CLSID CLSID_InboundConnectionUi =
|
|
{0x7007ACC3,0x3202,0x11D1,{0xAA,0xD2,0x00,0x80,0x5F,0xC1,0x27,0x0E}};
|
|
|
|
extern const GUID GUID_InboundConfigConnectionId =
|
|
{ /* 89150b9f-9b5c-11d1-a91f-00805fc1270e */
|
|
0x89150b9f,
|
|
0x9b5c,
|
|
0x11d1,
|
|
{0xa9, 0x1f, 0x00, 0x80, 0x5f, 0xc1, 0x27, 0x0e}
|
|
};
|
|
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Member: CInboundConnection::CreateInstance
|
|
//
|
|
// Purpose: Creates an inbound connection object.
|
|
//
|
|
// Arguments:
|
|
// fIsConfigConnection [in]
|
|
// hRasSrvConn [in]
|
|
// pszwName [in]
|
|
// pguidId [in]
|
|
// riid [in]
|
|
// ppv [in]
|
|
//
|
|
// Returns: S_OK or an error code.
|
|
//
|
|
// Author: shaunco 12 Nov 1997
|
|
//
|
|
// Notes:
|
|
//
|
|
HRESULT
|
|
CInboundConnection::CreateInstance (
|
|
IN BOOL fIsConfigConnection,
|
|
IN HRASSRVCONN hRasSrvConn,
|
|
IN PCWSTR pszwName,
|
|
IN PCWSTR pszwDeviceName,
|
|
IN DWORD dwType,
|
|
IN const GUID* pguidId,
|
|
IN REFIID riid,
|
|
OUT void** ppv)
|
|
{
|
|
Assert (FIff(fIsConfigConnection, !hRasSrvConn));
|
|
Assert (pguidId);
|
|
|
|
HRESULT hr = E_OUTOFMEMORY;
|
|
|
|
CInboundConnection* pObj;
|
|
pObj = new CComObject <CInboundConnection>;
|
|
if (pObj)
|
|
{
|
|
if (fIsConfigConnection)
|
|
{
|
|
// No need to start the service (FALSE) since we're being
|
|
// created as a result of the service running.
|
|
//
|
|
pObj->InitializeAsConfigConnection (FALSE);
|
|
}
|
|
else
|
|
{
|
|
// Initialize our members.
|
|
//
|
|
pObj->m_fIsConfigConnection = FALSE;
|
|
pObj->m_hRasSrvConn = hRasSrvConn;
|
|
pObj->SetName (pszwName);
|
|
pObj->SetDeviceName (pszwDeviceName);
|
|
|
|
switch (dwType)
|
|
{
|
|
case RASSRVUI_MODEM:
|
|
pObj->m_MediaType = NCM_PHONE;
|
|
break;
|
|
case RASSRVUI_VPN:
|
|
pObj->m_MediaType = NCM_TUNNEL;
|
|
break;
|
|
case RASSRVUI_DCC:
|
|
pObj->m_MediaType = NCM_DIRECT;
|
|
break;
|
|
default:
|
|
pObj->m_MediaType = NCM_PHONE;
|
|
break;
|
|
}
|
|
|
|
pObj->m_guidId = *pguidId;
|
|
|
|
// We are now a full-fledged object.
|
|
//
|
|
pObj->m_fInitialized = TRUE;
|
|
}
|
|
|
|
// Do the standard CComCreator::CreateInstance stuff.
|
|
//
|
|
pObj->SetVoid (NULL);
|
|
pObj->InternalFinalConstructAddRef ();
|
|
hr = pObj->FinalConstruct ();
|
|
pObj->InternalFinalConstructRelease ();
|
|
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
INetConnection* pCon = static_cast<INetConnection*>(pObj);
|
|
hr = pCon->QueryInterface (riid, ppv);
|
|
}
|
|
|
|
if (FAILED(hr))
|
|
{
|
|
delete pObj;
|
|
}
|
|
}
|
|
TraceError ("CInboundConnection::CreateInstance", hr);
|
|
return hr;
|
|
}
|
|
|
|
CInboundConnection::CInboundConnection() throw()
|
|
{
|
|
InterlockedIncrement (&g_CountIncomingConnectionObjects);
|
|
|
|
m_fIsConfigConnection = FALSE;
|
|
m_hRasSrvConn = NULL;
|
|
m_MediaType = NCM_NONE;
|
|
m_fInitialized = FALSE;
|
|
}
|
|
|
|
CInboundConnection::~CInboundConnection() throw()
|
|
{
|
|
InterlockedDecrement (&g_CountIncomingConnectionObjects);
|
|
}
|
|
|
|
HRESULT
|
|
CInboundConnection::GetCharacteristics (
|
|
OUT DWORD* pdwFlags)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
// Validate parameters.
|
|
//
|
|
if (!pdwFlags)
|
|
{
|
|
hr = E_POINTER;
|
|
}
|
|
else if (!m_fInitialized)
|
|
{
|
|
hr = E_UNEXPECTED;
|
|
}
|
|
else
|
|
{
|
|
*pdwFlags = NCCF_INCOMING_ONLY | NCCF_ALL_USERS;
|
|
|
|
// For the configuration connection, we only allow removal.
|
|
// Don't query for NCCF_SHOW_ICON (below) because this connection
|
|
// never get's connected.
|
|
//
|
|
if (m_fIsConfigConnection)
|
|
{
|
|
*pdwFlags |= NCCF_ALLOW_REMOVAL;
|
|
}
|
|
else
|
|
{
|
|
BOOL fShowIcon;
|
|
DWORD dwErr = RasSrvQueryShowIcon (&fShowIcon);
|
|
|
|
TraceError ("RasSrvQueryShowIcon", HRESULT_FROM_WIN32(dwErr));
|
|
|
|
if ((ERROR_SUCCESS == dwErr) && fShowIcon)
|
|
{
|
|
*pdwFlags |= NCCF_SHOW_ICON;
|
|
}
|
|
}
|
|
}
|
|
TraceError ("CInboundConnection::GetCharacteristics", hr);
|
|
return hr;
|
|
}
|
|
|
|
HRESULT
|
|
CInboundConnection::GetStatus (
|
|
OUT NETCON_STATUS* pStatus)
|
|
{
|
|
Assert (pStatus);
|
|
|
|
HRESULT hr = S_OK;
|
|
|
|
// Initialize the output parameter.
|
|
//
|
|
*pStatus = NCS_DISCONNECTED;
|
|
|
|
if (!m_fIsConfigConnection)
|
|
{
|
|
BOOL fConnected;
|
|
DWORD dwErr = RasSrvIsConnectionConnected (m_hRasSrvConn,
|
|
&fConnected);
|
|
|
|
TraceError ("RasSrvIsConnectionConnected",
|
|
HRESULT_FROM_WIN32(dwErr));
|
|
|
|
if ((ERROR_SUCCESS == dwErr) && fConnected)
|
|
{
|
|
*pStatus = NCS_CONNECTED;
|
|
}
|
|
}
|
|
TraceError ("CInboundConnection::GetStatus", hr);
|
|
return hr;
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
// INetConnection
|
|
//
|
|
|
|
STDMETHODIMP
|
|
CInboundConnection::Connect ()
|
|
{
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
STDMETHODIMP
|
|
CInboundConnection::Disconnect ()
|
|
{
|
|
HRESULT hr;
|
|
|
|
// We don't expect to be called on Disconnect if we are the
|
|
// configuration connection object. Why? Because this object never
|
|
// reports itself as connected through GetStatus.
|
|
//
|
|
if (!m_fInitialized || m_fIsConfigConnection)
|
|
{
|
|
hr = E_UNEXPECTED;
|
|
}
|
|
else
|
|
{
|
|
DWORD dwErr = RasSrvHangupConnection (m_hRasSrvConn);
|
|
hr = HRESULT_FROM_WIN32 (dwErr);
|
|
|
|
TraceError ("RasSrvHangupConnection", hr);
|
|
|
|
// Disconnect means this object is no longer valid.
|
|
// Indicate so by uniniatializing ourselves (so subsequent
|
|
// method calls will fail) and returning S_OBJECT_NO_LONGER_VALID.
|
|
//
|
|
m_fInitialized = FALSE;
|
|
hr = S_OBJECT_NO_LONGER_VALID;
|
|
}
|
|
TraceError ("CInboundConnection::Disconnect",
|
|
(S_OBJECT_NO_LONGER_VALID == hr) ? S_OK : hr);
|
|
return hr;
|
|
}
|
|
|
|
STDMETHODIMP
|
|
CInboundConnection::Delete ()
|
|
{
|
|
HRESULT hr;
|
|
|
|
// We don't expect to be called on Remove if we are not the
|
|
// configuration connection object. Why? Because connected objects never
|
|
// report themselves as removeable through GetCharacteristics.
|
|
//
|
|
if (!m_fInitialized || !m_fIsConfigConnection)
|
|
{
|
|
hr = E_UNEXPECTED;
|
|
}
|
|
else
|
|
{
|
|
DWORD dwErr = RasSrvCleanupService ();
|
|
hr = HRESULT_FROM_WIN32 (dwErr);
|
|
|
|
TraceError ("RasSrvCleanupService", hr);
|
|
}
|
|
TraceError ("CInboundConnection::Delete", hr);
|
|
return hr;
|
|
}
|
|
|
|
STDMETHODIMP
|
|
CInboundConnection::Duplicate (
|
|
IN PCWSTR pszwDuplicateName,
|
|
OUT INetConnection** ppCon)
|
|
{
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
STDMETHODIMP
|
|
CInboundConnection::GetProperties (
|
|
OUT NETCON_PROPERTIES** ppProps)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
// Validate parameters.
|
|
//
|
|
if (!ppProps)
|
|
{
|
|
hr = E_POINTER;
|
|
}
|
|
else if (!m_fInitialized)
|
|
{
|
|
hr = E_UNEXPECTED;
|
|
}
|
|
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 = m_guidId;
|
|
|
|
// pszwName
|
|
//
|
|
hrT = HrCoTaskMemAllocAndDupSz (PszwName(),
|
|
&pProps->pszwName,
|
|
NETCON_MAX_NAME_LEN);
|
|
if (FAILED(hrT))
|
|
{
|
|
hr = hrT;
|
|
}
|
|
|
|
// pszwDeviceName
|
|
//
|
|
if (!m_fIsConfigConnection)
|
|
{
|
|
hrT = HrCoTaskMemAllocAndDupSz (PszwDeviceName(),
|
|
&pProps->pszwDeviceName,
|
|
NETCON_MAX_NAME_LEN);
|
|
if (FAILED(hrT))
|
|
{
|
|
hr = hrT;
|
|
}
|
|
}
|
|
|
|
// Status
|
|
//
|
|
hrT = GetStatus (&pProps->Status);
|
|
if (FAILED(hrT))
|
|
{
|
|
hr = hrT;
|
|
}
|
|
|
|
// MediaType
|
|
//
|
|
pProps->MediaType = m_MediaType;
|
|
|
|
// dwCharacter
|
|
//
|
|
hrT = GetCharacteristics (&pProps->dwCharacter);
|
|
if (FAILED(hrT))
|
|
{
|
|
hr = hrT;
|
|
}
|
|
|
|
// clsidThisObject
|
|
//
|
|
pProps->clsidThisObject = CLSID_InboundConnection;
|
|
|
|
// clsidUiObject
|
|
//
|
|
pProps->clsidUiObject = CLSID_InboundConnectionUi;
|
|
|
|
// Assign the output parameter or cleanup if we had any failures.
|
|
//
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
*ppProps = pProps;
|
|
}
|
|
else
|
|
{
|
|
Assert (NULL == *ppProps);
|
|
FreeNetconProperties (pProps);
|
|
}
|
|
}
|
|
}
|
|
TraceError ("CInboundConnection::GetProperties", hr);
|
|
return hr;
|
|
}
|
|
|
|
STDMETHODIMP
|
|
CInboundConnection::GetUiObjectClassId (
|
|
OUT CLSID* pclsid)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
// Validate parameters.
|
|
//
|
|
if (!pclsid)
|
|
{
|
|
hr = E_POINTER;
|
|
}
|
|
else if (!m_fInitialized)
|
|
{
|
|
hr = E_UNEXPECTED;
|
|
}
|
|
else
|
|
{
|
|
*pclsid = CLSID_InboundConnectionUi;
|
|
}
|
|
TraceError ("CInboundConnection::GetUiObjectClassId", hr);
|
|
return hr;
|
|
}
|
|
|
|
STDMETHODIMP
|
|
CInboundConnection::Rename (
|
|
IN PCWSTR pszwNewName)
|
|
{
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
|
|
//+---------------------------------------------------------------------------
|
|
// INetInboundConnection
|
|
//
|
|
STDMETHODIMP
|
|
CInboundConnection::GetServerConnectionHandle (
|
|
OUT ULONG_PTR* phRasSrvConn)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
// If this is the configuration connection, the server connection
|
|
// handle better be zero. This is used by the UI object so that it
|
|
// knows it is the configuration connection.
|
|
//
|
|
Assert (FIff (m_fIsConfigConnection, !m_hRasSrvConn));
|
|
|
|
// Because MIDL doesn't know about HRASSRVCONN's, just make sure
|
|
// it is the same size as the ULONG_PTR we pass it as.
|
|
//
|
|
Assert (sizeof (m_hRasSrvConn) == sizeof (*phRasSrvConn));
|
|
|
|
*phRasSrvConn = reinterpret_cast<ULONG_PTR>(m_hRasSrvConn);
|
|
|
|
TraceError ("CInboundConnection::GetServerConnectionHandle", hr);
|
|
return hr;
|
|
}
|
|
|
|
STDMETHODIMP
|
|
CInboundConnection::InitializeAsConfigConnection (
|
|
IN BOOL fStartRemoteAccess)
|
|
{
|
|
Assert (!m_fInitialized);
|
|
|
|
// Initialize our members.
|
|
//
|
|
m_fIsConfigConnection = TRUE;
|
|
m_hRasSrvConn = 0;
|
|
SetName (SzLoadIds (IDS_INBOUND_CONFIG_CONNECTION_NAME));
|
|
SetDeviceName (NULL);
|
|
m_MediaType = NCM_NONE;
|
|
m_guidId = GUID_InboundConfigConnectionId;
|
|
|
|
// We are now a full-fledged object.
|
|
//
|
|
m_fInitialized = TRUE;
|
|
|
|
// Start the service if we were told.
|
|
//
|
|
HRESULT hr = S_OK;
|
|
if (fStartRemoteAccess)
|
|
{
|
|
DWORD dwErr = RasSrvInitializeService ();
|
|
hr = HRESULT_FROM_WIN32 (dwErr);
|
|
TraceError ("RasSrvInitializeService", hr);
|
|
}
|
|
TraceError ("CInboundConnection::InitializeAsConfigConnection", hr);
|
|
return hr;
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
// IPersistNetConnection
|
|
//
|
|
STDMETHODIMP
|
|
CInboundConnection::GetClassID (
|
|
OUT CLSID* pclsid)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
// Validate parameters.
|
|
//
|
|
if (!pclsid)
|
|
{
|
|
hr = E_POINTER;
|
|
}
|
|
else
|
|
{
|
|
*pclsid = CLSID_InboundConnection;
|
|
}
|
|
TraceError ("CInboundConnection::GetClassID", hr);
|
|
return hr;
|
|
}
|
|
|
|
|
|
static const WCHAR c_chwLead = 0x19;
|
|
static const WCHAR c_chwTrail = 0x07;
|
|
|
|
STDMETHODIMP
|
|
CInboundConnection::GetSizeMax (
|
|
OUT ULONG* pcbSize)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
// Validate parameters.
|
|
//
|
|
if (!pcbSize)
|
|
{
|
|
hr = E_POINTER;
|
|
}
|
|
else if (!m_fInitialized)
|
|
{
|
|
hr = E_UNEXPECTED;
|
|
}
|
|
else
|
|
{
|
|
// Size the buffer for the following form:
|
|
// +--------------------------------------------------------------+
|
|
// |0x19<m_fIsConfigConnection><m_hRasSrvConn><m_strName>...\00x07|
|
|
// +--------------------------------------------------------------+
|
|
//
|
|
// m_strDeviceName may be empty, in which case we want to still
|
|
// store the null-terminator. Don't use PszwDeviceName() as it
|
|
// returns NULL when m_strDeviceName is empty.
|
|
//
|
|
*pcbSize = sizeof (c_chwLead) +
|
|
sizeof (m_fIsConfigConnection) +
|
|
sizeof (m_hRasSrvConn) +
|
|
CbOfSzAndTerm (PszwName()) +
|
|
CbOfSzAndTerm (m_strDeviceName.c_str()) +
|
|
sizeof (m_MediaType) +
|
|
sizeof (m_guidId) +
|
|
sizeof (c_chwTrail);
|
|
}
|
|
TraceError ("CInboundConnection::GetSizeMax", hr);
|
|
return hr;
|
|
}
|
|
|
|
STDMETHODIMP
|
|
CInboundConnection::Load (
|
|
IN const BYTE* pbBuf,
|
|
IN ULONG cbSize)
|
|
{
|
|
// The theoretical minimum size for the buffer. Computed
|
|
// as the number of bytes in the following minimum string:
|
|
//
|
|
const ULONG c_cbSizeMin = sizeof (c_chwLead) +
|
|
sizeof (m_fIsConfigConnection) +
|
|
sizeof (m_hRasSrvConn) +
|
|
4 + // 4 bytes for 1 UNICODE char and NULL
|
|
2 + // 1 UNICODE NULL for empty device name
|
|
sizeof (m_MediaType) +
|
|
sizeof (m_guidId) +
|
|
sizeof (c_chwTrail);
|
|
|
|
HRESULT hr = E_INVALIDARG;
|
|
|
|
// Validate parameters.
|
|
//
|
|
if (!pbBuf)
|
|
{
|
|
hr = E_POINTER;
|
|
}
|
|
else if (cbSize < c_cbSizeMin)
|
|
{
|
|
hr = E_INVALIDARG;
|
|
}
|
|
// We can only accept one call on this method and only if we're not
|
|
// already initialized.
|
|
//
|
|
else if (m_fInitialized)
|
|
{
|
|
hr = E_UNEXPECTED;
|
|
}
|
|
else
|
|
{
|
|
// The buffer *should* look like this:
|
|
// +--------------------------------------------------------------+
|
|
// |0x19<m_fIsConfigConnection><m_hRasSrvConn><m_strName>...\00x07|
|
|
// +--------------------------------------------------------------+
|
|
//
|
|
const WCHAR * pchw;
|
|
const WCHAR * pchwMax;
|
|
const BOOL UNALIGNED * pfIsConfigConnection;
|
|
BOOL fIsConfigConnection;
|
|
const HRASSRVCONN UNALIGNED * phRasSrvCon;
|
|
HRASSRVCONN hRasSrvConn;
|
|
PCWSTR pszwName;
|
|
PCWSTR pszwDeviceName;
|
|
const NETCON_MEDIATYPE UNALIGNED * pMediaType;
|
|
const GUID UNALIGNED * pguidTemp;
|
|
const GUID UNALIGNED * pguidId;
|
|
NETCON_MEDIATYPE MediaType;
|
|
|
|
pchw = reinterpret_cast<const WCHAR*>(pbBuf);
|
|
|
|
// The last valid pointer for the embedded strings.
|
|
//
|
|
pchwMax = reinterpret_cast<const WCHAR*>(pbBuf + cbSize
|
|
- (sizeof (m_MediaType) +
|
|
sizeof (m_guidId) +
|
|
sizeof (c_chwTrail)));
|
|
|
|
// Check our lead byte.
|
|
//
|
|
if (c_chwLead != *pchw)
|
|
{
|
|
goto finished;
|
|
}
|
|
pchw++;
|
|
|
|
// Get m_fIsConfigConnection.
|
|
//
|
|
pfIsConfigConnection = reinterpret_cast<const BOOL*>(pchw);
|
|
CopyMemory(&fIsConfigConnection, pfIsConfigConnection, sizeof(fIsConfigConnection));
|
|
pfIsConfigConnection++;
|
|
|
|
// Get m_hRasSrvConn.
|
|
//
|
|
phRasSrvCon = reinterpret_cast<const HRASSRVCONN*>(pfIsConfigConnection);
|
|
CopyMemory(&hRasSrvConn, phRasSrvCon, sizeof(hRasSrvConn));
|
|
phRasSrvCon++;
|
|
|
|
// Get m_strName. Search for the terminating null and make sure
|
|
// we find it before the end of the buffer. Using lstrlen to skip
|
|
// the string can result in an AV in the event the string is not
|
|
// actually null-terminated.
|
|
//
|
|
pchw = reinterpret_cast<const WCHAR*>(phRasSrvCon);
|
|
|
|
for (pszwName = pchw; ; pchw++)
|
|
{
|
|
if (pchw >= pchwMax)
|
|
{
|
|
goto finished;
|
|
}
|
|
if (0 == *pchw)
|
|
{
|
|
pchw++;
|
|
break;
|
|
}
|
|
}
|
|
|
|
// Get m_strDeviceName. Search for the terminating null and make
|
|
// sure we find it before the end of the buffer.
|
|
//
|
|
for (pszwDeviceName = pchw; ; pchw++)
|
|
{
|
|
if (pchw >= pchwMax)
|
|
{
|
|
goto finished;
|
|
}
|
|
if (0 == *pchw)
|
|
{
|
|
pchw++;
|
|
break;
|
|
}
|
|
}
|
|
|
|
// Get m_MediaType.
|
|
//
|
|
pMediaType = reinterpret_cast<const NETCON_MEDIATYPE*>(pchw);
|
|
CopyMemory(&MediaType, pMediaType, sizeof(MediaType));
|
|
pMediaType++;
|
|
|
|
// Get m_guidId.
|
|
//
|
|
pguidTemp = reinterpret_cast<const GUID*>(pMediaType);
|
|
pguidId = pguidTemp;
|
|
pguidTemp++;
|
|
|
|
// Check our trail byte.
|
|
//
|
|
pchw = reinterpret_cast<const WCHAR*>(pguidTemp);
|
|
if (c_chwTrail != *pchw)
|
|
{
|
|
goto finished;
|
|
}
|
|
|
|
// If we're the configuration object, we can't have a connection
|
|
// HANDLE and vice-versa.
|
|
//
|
|
if ((fIsConfigConnection && hRasSrvConn) ||
|
|
(!fIsConfigConnection && !hRasSrvConn))
|
|
{
|
|
goto finished;
|
|
}
|
|
|
|
// We are now a full-fledged object.
|
|
//
|
|
m_fIsConfigConnection = fIsConfigConnection;
|
|
m_hRasSrvConn = hRasSrvConn;
|
|
SetName (pszwName);
|
|
SetDeviceName (pszwDeviceName);
|
|
m_MediaType = MediaType;
|
|
CopyMemory(&m_guidId, pguidId, sizeof(m_guidId));
|
|
m_fInitialized = TRUE;
|
|
hr = S_OK;
|
|
|
|
finished:
|
|
;
|
|
}
|
|
TraceError ("CInboundConnection::Load", hr);
|
|
return hr;
|
|
}
|
|
|
|
STDMETHODIMP
|
|
CInboundConnection::Save (
|
|
OUT BYTE* pbBuf,
|
|
IN ULONG cbSize)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
// Validate parameters.
|
|
//
|
|
if (!pbBuf)
|
|
{
|
|
hr = E_POINTER;
|
|
}
|
|
else if (!m_fInitialized)
|
|
{
|
|
hr = E_UNEXPECTED;
|
|
}
|
|
else
|
|
{
|
|
// Make sure the user's buffer is big enough.
|
|
//
|
|
ULONG cbSizeRequired;
|
|
SideAssert (SUCCEEDED(GetSizeMax(&cbSizeRequired)));
|
|
|
|
if (cbSize < cbSizeRequired)
|
|
{
|
|
hr = E_INVALIDARG;
|
|
}
|
|
else
|
|
{
|
|
// Make the buffer look like this when we're done:
|
|
// +--------------------------------------------------------------+
|
|
// |0x19<m_fIsConfigConnection><m_hRasSrvConn><m_strName>...\00x07|
|
|
// +--------------------------------------------------------------+
|
|
//
|
|
WCHAR* pchw = reinterpret_cast<WCHAR*>(pbBuf);
|
|
|
|
// Put our lead byte.
|
|
//
|
|
*pchw = c_chwLead;
|
|
pchw++;
|
|
|
|
// Put m_fIsConfigConnection.
|
|
//
|
|
BOOL UNALIGNED *pfIsConfigConnection =
|
|
reinterpret_cast<BOOL*>(pchw);
|
|
CopyMemory(pfIsConfigConnection, &m_fIsConfigConnection, sizeof(m_fIsConfigConnection));
|
|
pfIsConfigConnection++;
|
|
|
|
// Put m_hRasSrvConn.
|
|
//
|
|
HRASSRVCONN UNALIGNED *phRasSrvCon =
|
|
reinterpret_cast<HRASSRVCONN*>(pfIsConfigConnection);
|
|
CopyMemory(phRasSrvCon, &m_hRasSrvConn, sizeof(m_hRasSrvConn));
|
|
phRasSrvCon++;
|
|
|
|
// Put m_strName.
|
|
//
|
|
pchw = reinterpret_cast<WCHAR*>(phRasSrvCon);
|
|
lstrcpyW (pchw, PszwName());
|
|
pchw += lstrlenW (PszwName()) + 1;
|
|
|
|
// Put m_strDeviceName.
|
|
//
|
|
lstrcpyW (pchw, m_strDeviceName.c_str());
|
|
pchw += m_strDeviceName.length() + 1;
|
|
|
|
// Put m_MediaType.
|
|
//
|
|
NETCON_MEDIATYPE UNALIGNED *pMediaType = reinterpret_cast<NETCON_MEDIATYPE*>(pchw);
|
|
CopyMemory(pMediaType, &m_MediaType, sizeof(m_MediaType));
|
|
pMediaType++;
|
|
|
|
// Put m_guidId.
|
|
//
|
|
GUID UNALIGNED *pguidId = reinterpret_cast<GUID*>(pMediaType);
|
|
CopyMemory(pguidId, &m_guidId, sizeof(m_guidId));
|
|
pguidId++;
|
|
|
|
// Put our trail byte.
|
|
//
|
|
pchw = reinterpret_cast<WCHAR*>(pguidId);
|
|
*pchw = c_chwTrail;
|
|
pchw++;
|
|
|
|
AssertSz (pbBuf + cbSizeRequired == (BYTE*)pchw,
|
|
"pch isn't pointing where it should be.");
|
|
}
|
|
}
|
|
TraceError ("CInboundConnection::Save", hr);
|
|
return hr;
|
|
}
|
|
|
|
#define ID_DEVICE_DATABASE 1
|
|
#define ID_MISC_DATABASE 8
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Function: IconStateChanged
|
|
//
|
|
// Purpose: Fires an event to notify NetShell of a Change occuring in an
|
|
// incoming connection.
|
|
//
|
|
// Arguments:
|
|
//
|
|
// Returns: S_OK on success; error otherwise
|
|
//
|
|
// Author: ckotze 25 September 2000
|
|
//
|
|
// Notes:
|
|
//
|
|
HRESULT CInboundConnection::IconStateChanged()
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
IncomingEventNotify(REFRESH_ALL, NULL, NULL, NULL);
|
|
|
|
return hr;
|
|
}
|