1021 lines
25 KiB
C++
1021 lines
25 KiB
C++
|
//****************************************************************************
|
||
|
//
|
||
|
// Module: ULS.DLL
|
||
|
// File: connpt.cpp
|
||
|
// Content: This file contains the conection point object.
|
||
|
// History:
|
||
|
// Wed 17-Apr-1996 11:13:54 -by- Viroon Touranachun [viroont]
|
||
|
//
|
||
|
// Copyright (c) Microsoft Corporation 1995-1996
|
||
|
//
|
||
|
//****************************************************************************
|
||
|
|
||
|
#include "ulsp.h"
|
||
|
#include "connpt.h"
|
||
|
|
||
|
//****************************************************************************
|
||
|
// CEnumConnectionPoints::CEnumConnectionPoints (void)
|
||
|
//
|
||
|
// History:
|
||
|
// Wed 17-Apr-1996 11:15:18 -by- Viroon Touranachun [viroont]
|
||
|
// Created.
|
||
|
//****************************************************************************
|
||
|
|
||
|
CEnumConnectionPoints::CEnumConnectionPoints (void)
|
||
|
{
|
||
|
cRef = 0;
|
||
|
iIndex = 0;
|
||
|
pcnp = NULL;
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
//****************************************************************************
|
||
|
// CEnumConnectionPoints::~CEnumConnectionPoints (void)
|
||
|
//
|
||
|
// History:
|
||
|
// Wed 17-Apr-1996 11:15:18 -by- Viroon Touranachun [viroont]
|
||
|
// Created.
|
||
|
//****************************************************************************
|
||
|
|
||
|
CEnumConnectionPoints::~CEnumConnectionPoints (void)
|
||
|
{
|
||
|
if (pcnp != NULL)
|
||
|
{
|
||
|
pcnp->Release();
|
||
|
};
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
//****************************************************************************
|
||
|
// STDMETHODIMP
|
||
|
// CEnumConnectionPoints::Init (IConnectionPoint *pcnpInit)
|
||
|
//
|
||
|
// History:
|
||
|
// Wed 17-Apr-1996 11:15:25 -by- Viroon Touranachun [viroont]
|
||
|
// Created.
|
||
|
//****************************************************************************
|
||
|
|
||
|
STDMETHODIMP
|
||
|
CEnumConnectionPoints::Init (IConnectionPoint *pcnpInit)
|
||
|
{
|
||
|
iIndex = 0;
|
||
|
pcnp = pcnpInit;
|
||
|
|
||
|
if (pcnp != NULL)
|
||
|
{
|
||
|
pcnp->AddRef();
|
||
|
};
|
||
|
return S_OK;
|
||
|
}
|
||
|
|
||
|
//****************************************************************************
|
||
|
// STDMETHODIMP
|
||
|
// CEnumConnectionPoints::QueryInterface (REFIID riid, void **ppv)
|
||
|
//
|
||
|
// History:
|
||
|
// Wed 17-Apr-1996 11:15:31 -by- Viroon Touranachun [viroont]
|
||
|
// Created.
|
||
|
//****************************************************************************
|
||
|
|
||
|
STDMETHODIMP
|
||
|
CEnumConnectionPoints::QueryInterface (REFIID riid, void **ppv)
|
||
|
{
|
||
|
if (riid == IID_IEnumConnectionPoints || riid == IID_IUnknown)
|
||
|
{
|
||
|
*ppv = (IEnumConnectionPoints *) this;
|
||
|
AddRef();
|
||
|
return S_OK;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
*ppv = NULL;
|
||
|
return ILS_E_NO_INTERFACE;
|
||
|
};
|
||
|
}
|
||
|
|
||
|
//****************************************************************************
|
||
|
// STDMETHODIMP_(ULONG)
|
||
|
// CEnumConnectionPoints::AddRef (void)
|
||
|
//
|
||
|
// History:
|
||
|
// Wed 17-Apr-1996 11:15:37 -by- Viroon Touranachun [viroont]
|
||
|
// Created.
|
||
|
//****************************************************************************
|
||
|
|
||
|
STDMETHODIMP_(ULONG)
|
||
|
CEnumConnectionPoints::AddRef (void)
|
||
|
{
|
||
|
DllLock();
|
||
|
|
||
|
MyDebugMsg ((DM_REFCOUNT, "CEnumConnectionPoints::AddRef: ref=%ld\r\n", cRef));
|
||
|
::InterlockedIncrement ((LONG *) &cRef);
|
||
|
return cRef;
|
||
|
}
|
||
|
|
||
|
//****************************************************************************
|
||
|
// STDMETHODIMP_(ULONG)
|
||
|
// CEnumConnectionPoints::Release (void)
|
||
|
//
|
||
|
// History:
|
||
|
// Wed 17-Apr-1996 11:15:43 -by- Viroon Touranachun [viroont]
|
||
|
// Created.
|
||
|
//****************************************************************************
|
||
|
|
||
|
STDMETHODIMP_(ULONG)
|
||
|
CEnumConnectionPoints::Release (void)
|
||
|
{
|
||
|
DllRelease();
|
||
|
|
||
|
ASSERT (cRef > 0);
|
||
|
|
||
|
MyDebugMsg ((DM_REFCOUNT, "CEnumConnectionPoints::Release: ref=%ld\r\n", cRef));
|
||
|
if (::InterlockedDecrement ((LONG *) &cRef) == 0)
|
||
|
{
|
||
|
delete this;
|
||
|
return 0;
|
||
|
}
|
||
|
return cRef;
|
||
|
}
|
||
|
|
||
|
//****************************************************************************
|
||
|
// STDMETHODIMP
|
||
|
// CEnumConnectionPoints::Next (ULONG cConnections,
|
||
|
// IConnectionPoint **rgpcn,
|
||
|
// ULONG *pcFetched)
|
||
|
//
|
||
|
// History:
|
||
|
// Wed 17-Apr-1996 11:15:49 -by- Viroon Touranachun [viroont]
|
||
|
// Created.
|
||
|
//****************************************************************************
|
||
|
|
||
|
STDMETHODIMP
|
||
|
CEnumConnectionPoints::Next (ULONG cConnections,
|
||
|
IConnectionPoint **rgpcn,
|
||
|
ULONG *pcFetched)
|
||
|
{
|
||
|
ULONG cCopied;
|
||
|
|
||
|
// Validate the pointer
|
||
|
//
|
||
|
if (rgpcn == NULL)
|
||
|
return ILS_E_POINTER;
|
||
|
|
||
|
// Validate the parameters
|
||
|
//
|
||
|
if ((cConnections == 0) ||
|
||
|
((cConnections > 1) && (pcFetched == NULL)))
|
||
|
return ILS_E_PARAMETER;
|
||
|
|
||
|
// Check the enumeration index
|
||
|
//
|
||
|
cCopied = 0;
|
||
|
if ((pcnp != NULL) && (iIndex == 0))
|
||
|
{
|
||
|
// Return the only connection point
|
||
|
//
|
||
|
*rgpcn = pcnp;
|
||
|
(*rgpcn)->AddRef();
|
||
|
iIndex++;
|
||
|
cCopied++;
|
||
|
};
|
||
|
|
||
|
// Determine the returned information based on other parameters
|
||
|
//
|
||
|
if (pcFetched != NULL)
|
||
|
{
|
||
|
*pcFetched = cCopied;
|
||
|
};
|
||
|
return (cConnections == cCopied ? S_OK : S_FALSE);
|
||
|
}
|
||
|
|
||
|
//****************************************************************************
|
||
|
// STDMETHODIMP
|
||
|
// CEnumConnectionPoints::Skip (ULONG cConnections)
|
||
|
//
|
||
|
// History:
|
||
|
// Wed 17-Apr-1996 11:15:56 -by- Viroon Touranachun [viroont]
|
||
|
// Created.
|
||
|
//****************************************************************************
|
||
|
|
||
|
STDMETHODIMP
|
||
|
CEnumConnectionPoints::Skip (ULONG cConnections)
|
||
|
{
|
||
|
// Validate the parameters
|
||
|
//
|
||
|
if (cConnections == 0)
|
||
|
return ILS_E_PARAMETER;
|
||
|
|
||
|
// Check the enumeration index limit
|
||
|
//
|
||
|
if ((pcnp == NULL) || (iIndex > 0))
|
||
|
{
|
||
|
return S_FALSE;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
// Skip the only elelment
|
||
|
//
|
||
|
iIndex++;
|
||
|
return (cConnections == 1 ? S_OK : S_FALSE);
|
||
|
};
|
||
|
}
|
||
|
|
||
|
//****************************************************************************
|
||
|
// STDMETHODIMP
|
||
|
// CEnumConnectionPoints::Reset (void)
|
||
|
//
|
||
|
// History:
|
||
|
// Wed 17-Apr-1996 11:16:02 -by- Viroon Touranachun [viroont]
|
||
|
// Created.
|
||
|
//****************************************************************************
|
||
|
|
||
|
STDMETHODIMP
|
||
|
CEnumConnectionPoints::Reset (void)
|
||
|
{
|
||
|
iIndex = 0;
|
||
|
return S_OK;
|
||
|
}
|
||
|
|
||
|
//****************************************************************************
|
||
|
// STDMETHODIMP
|
||
|
// CEnumConnectionPoints::Clone(IEnumConnectionPoints **ppEnum)
|
||
|
//
|
||
|
// History:
|
||
|
// Wed 17-Apr-1996 11:16:11 -by- Viroon Touranachun [viroont]
|
||
|
// Created.
|
||
|
//****************************************************************************
|
||
|
|
||
|
STDMETHODIMP
|
||
|
CEnumConnectionPoints::Clone(IEnumConnectionPoints **ppEnum)
|
||
|
{
|
||
|
CEnumConnectionPoints *pecp;
|
||
|
|
||
|
// Validate parameters
|
||
|
//
|
||
|
if (ppEnum == NULL)
|
||
|
{
|
||
|
return ILS_E_POINTER;
|
||
|
};
|
||
|
|
||
|
*ppEnum = NULL;
|
||
|
|
||
|
// Create an enumerator
|
||
|
//
|
||
|
pecp = new CEnumConnectionPoints;
|
||
|
if (pecp == NULL)
|
||
|
return ILS_E_MEMORY;
|
||
|
|
||
|
// Clone the information
|
||
|
//
|
||
|
pecp->iIndex = iIndex;
|
||
|
pecp->pcnp = pcnp;
|
||
|
|
||
|
if (pcnp != NULL)
|
||
|
{
|
||
|
pcnp->AddRef();
|
||
|
};
|
||
|
|
||
|
// Return the cloned enumerator
|
||
|
//
|
||
|
pecp->AddRef();
|
||
|
*ppEnum = pecp;
|
||
|
return S_OK;
|
||
|
}
|
||
|
|
||
|
//****************************************************************************
|
||
|
// CConnectionPoint::CConnectionPoint (const IID *pIID,
|
||
|
// IConnectionPointContainer *pCPCInit)
|
||
|
//
|
||
|
// History:
|
||
|
// Wed 17-Apr-1996 11:16:17 -by- Viroon Touranachun [viroont]
|
||
|
// Created.
|
||
|
//****************************************************************************
|
||
|
|
||
|
CConnectionPoint::CConnectionPoint (const IID *pIID,
|
||
|
IConnectionPointContainer *pCPCInit)
|
||
|
{
|
||
|
cRef = 0;
|
||
|
riid = *pIID;
|
||
|
pCPC = pCPCInit;
|
||
|
dwNextCookie = COOKIE_INIT_VALUE;
|
||
|
cSinkNodes = 0;
|
||
|
pSinkList = NULL;
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
//****************************************************************************
|
||
|
// CConnectionPoint::~CConnectionPoint (void)
|
||
|
//
|
||
|
// History:
|
||
|
// Wed 17-Apr-1996 11:16:17 -by- Viroon Touranachun [viroont]
|
||
|
// Created.
|
||
|
//****************************************************************************
|
||
|
|
||
|
CConnectionPoint::~CConnectionPoint (void)
|
||
|
{
|
||
|
PSINKNODE pSinkNode;
|
||
|
|
||
|
// Traverse the sink list and free each one of them
|
||
|
//
|
||
|
while (pSinkList != NULL)
|
||
|
{
|
||
|
pSinkNode = pSinkList;
|
||
|
pSinkList = pSinkNode->pNext;
|
||
|
|
||
|
pSinkNode->pUnk->Release();
|
||
|
delete pSinkNode;
|
||
|
};
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
//****************************************************************************
|
||
|
// STDMETHODIMP
|
||
|
// CConnectionPoint::QueryInterface (REFIID riid, void **ppv)
|
||
|
//
|
||
|
// History:
|
||
|
// Wed 17-Apr-1996 11:16:23 -by- Viroon Touranachun [viroont]
|
||
|
// Created.
|
||
|
//****************************************************************************
|
||
|
|
||
|
STDMETHODIMP
|
||
|
CConnectionPoint::QueryInterface (REFIID riid, void **ppv)
|
||
|
{
|
||
|
if (riid == IID_IConnectionPoint || riid == IID_IUnknown)
|
||
|
{
|
||
|
*ppv = (IConnectionPoint *) this;
|
||
|
AddRef();
|
||
|
return S_OK;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
*ppv = NULL;
|
||
|
return ILS_E_NO_INTERFACE;
|
||
|
};
|
||
|
}
|
||
|
|
||
|
//****************************************************************************
|
||
|
// STDMETHODIMP_(ULONG)
|
||
|
// CConnectionPoint::AddRef (void)
|
||
|
//
|
||
|
// History:
|
||
|
// Wed 17-Apr-1996 11:16:30 -by- Viroon Touranachun [viroont]
|
||
|
// Created.
|
||
|
//****************************************************************************
|
||
|
|
||
|
STDMETHODIMP_(ULONG)
|
||
|
CConnectionPoint::AddRef (void)
|
||
|
{
|
||
|
DllLock();
|
||
|
|
||
|
MyDebugMsg ((DM_REFCOUNT, "CConnectionPoint::AddRef: ref=%ld\r\n", cRef));
|
||
|
::InterlockedIncrement ((LONG *) &cRef);
|
||
|
return cRef;
|
||
|
}
|
||
|
|
||
|
//****************************************************************************
|
||
|
// STDMETHODIMP_(ULONG)
|
||
|
// CConnectionPoint::Release (void)
|
||
|
//
|
||
|
// History:
|
||
|
// Wed 17-Apr-1996 11:16:36 -by- Viroon Touranachun [viroont]
|
||
|
// Created.
|
||
|
//****************************************************************************
|
||
|
|
||
|
STDMETHODIMP_(ULONG)
|
||
|
CConnectionPoint::Release (void)
|
||
|
{
|
||
|
DllRelease();
|
||
|
|
||
|
ASSERT (cRef > 0);
|
||
|
|
||
|
MyDebugMsg ((DM_REFCOUNT, "CConnectionPoint::Release: ref=%ld\r\n", cRef));
|
||
|
if (::InterlockedDecrement ((LONG *) &cRef) == 0)
|
||
|
{
|
||
|
delete this;
|
||
|
return 0;
|
||
|
}
|
||
|
return cRef;
|
||
|
}
|
||
|
|
||
|
//****************************************************************************
|
||
|
// STDMETHODIMP
|
||
|
// CConnectionPoint::Notify(void *pv, CONN_NOTIFYPROC pfn)
|
||
|
//
|
||
|
// History:
|
||
|
// Wed 17-Apr-1996 11:16:43 -by- Viroon Touranachun [viroont]
|
||
|
// Created.
|
||
|
//****************************************************************************
|
||
|
|
||
|
STDMETHODIMP
|
||
|
CConnectionPoint::Notify(void *pv, CONN_NOTIFYPROC pfn)
|
||
|
{
|
||
|
PSINKNODE pSinkNode, pPrev;
|
||
|
IUnknown *pUnk;
|
||
|
BOOL fNeedClear;
|
||
|
HRESULT hr;
|
||
|
|
||
|
// Enumerate each connection
|
||
|
//
|
||
|
pSinkNode = pSinkList;
|
||
|
hr = S_OK;
|
||
|
fNeedClear = FALSE;
|
||
|
while((pSinkNode != NULL) && (SUCCEEDED(hr)))
|
||
|
{
|
||
|
// Important!! Important!!
|
||
|
// Lock the sink object here. Need to do this in case that the sink
|
||
|
// object calls back to Unadvise and we remove this sink node during
|
||
|
// callback.
|
||
|
//
|
||
|
pSinkNode->uFlags |= SN_LOCKED;
|
||
|
pUnk = pSinkNode->pUnk;
|
||
|
|
||
|
// Calls the sink object
|
||
|
// Note: Do not need to reference the sink object again.
|
||
|
// We already did when Advise was called.
|
||
|
//
|
||
|
hr = (*pfn)(pUnk, pv);
|
||
|
|
||
|
pSinkNode->uFlags &= ~SN_LOCKED;
|
||
|
if (pSinkNode->uFlags & SN_REMOVED)
|
||
|
{
|
||
|
fNeedClear = TRUE;
|
||
|
};
|
||
|
|
||
|
pSinkNode = pSinkNode->pNext;
|
||
|
};
|
||
|
|
||
|
// If there is at least one node to free
|
||
|
//
|
||
|
if (fNeedClear)
|
||
|
{
|
||
|
// Traverse the list for nodes to remove
|
||
|
//
|
||
|
pSinkNode = pSinkList;
|
||
|
pPrev = NULL;
|
||
|
|
||
|
while (pSinkNode != NULL)
|
||
|
{
|
||
|
// Release the sink object, if unadvise
|
||
|
//
|
||
|
if (pSinkNode->uFlags & SN_REMOVED)
|
||
|
{
|
||
|
PSINKNODE pNext;
|
||
|
|
||
|
pNext = pSinkNode->pNext;
|
||
|
if (pPrev == NULL)
|
||
|
{
|
||
|
// This is the head of the list
|
||
|
//
|
||
|
pSinkList = pNext;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
pPrev->pNext = pNext;
|
||
|
};
|
||
|
|
||
|
pSinkNode->pUnk->Release();
|
||
|
cSinkNodes--;
|
||
|
delete pSinkNode;
|
||
|
pSinkNode = pNext;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
pPrev = pSinkNode;
|
||
|
pSinkNode = pSinkNode->pNext;
|
||
|
};
|
||
|
};
|
||
|
};
|
||
|
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
//****************************************************************************
|
||
|
// STDMETHODIMP
|
||
|
// CConnectionPoint::GetConnectionInterface(IID *pIID)
|
||
|
//
|
||
|
// History:
|
||
|
// Wed 17-Apr-1996 11:16:43 -by- Viroon Touranachun [viroont]
|
||
|
// Created.
|
||
|
//****************************************************************************
|
||
|
|
||
|
STDMETHODIMP
|
||
|
CConnectionPoint::GetConnectionInterface(IID *pIID)
|
||
|
{
|
||
|
// Validate the parameter
|
||
|
//
|
||
|
if (pIID == NULL)
|
||
|
return ILS_E_POINTER;
|
||
|
|
||
|
// Support only one connection interface
|
||
|
//
|
||
|
*pIID = riid;
|
||
|
return S_OK;
|
||
|
}
|
||
|
|
||
|
//****************************************************************************
|
||
|
// STDMETHODIMP
|
||
|
// CConnectionPoint::GetConnectionPointContainer(IConnectionPointContainer **ppCPC)
|
||
|
//
|
||
|
// History:
|
||
|
// Wed 17-Apr-1996 11:16:49 -by- Viroon Touranachun [viroont]
|
||
|
// Created.
|
||
|
//****************************************************************************
|
||
|
|
||
|
STDMETHODIMP
|
||
|
CConnectionPoint::GetConnectionPointContainer(IConnectionPointContainer **ppCPC)
|
||
|
{
|
||
|
// Validate the parameter
|
||
|
//
|
||
|
if (ppCPC == NULL)
|
||
|
return ILS_E_POINTER;
|
||
|
|
||
|
// Return the container and add its reference count
|
||
|
//
|
||
|
*ppCPC = pCPC;
|
||
|
|
||
|
if (pCPC != NULL)
|
||
|
{
|
||
|
// The container is still alive
|
||
|
//
|
||
|
pCPC->AddRef();
|
||
|
return S_OK;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
// The container no longer exists
|
||
|
//
|
||
|
return ILS_E_FAIL;
|
||
|
};
|
||
|
}
|
||
|
|
||
|
//****************************************************************************
|
||
|
// STDMETHODIMP
|
||
|
// CConnectionPoint::Advise(IUnknown *pUnk, DWORD *pdwCookie)
|
||
|
//
|
||
|
// History:
|
||
|
// Wed 17-Apr-1996 11:17:01 -by- Viroon Touranachun [viroont]
|
||
|
// Created.
|
||
|
//****************************************************************************
|
||
|
|
||
|
STDMETHODIMP
|
||
|
CConnectionPoint::Advise(IUnknown *pUnk, DWORD *pdwCookie)
|
||
|
{
|
||
|
PSINKNODE pSinkNode;
|
||
|
IUnknown *pSinkInterface;
|
||
|
|
||
|
// Validate the parameter
|
||
|
//
|
||
|
if ((pUnk == NULL) ||
|
||
|
(pdwCookie == NULL))
|
||
|
return ILS_E_PARAMETER;
|
||
|
|
||
|
// Get the sink interface
|
||
|
//
|
||
|
if (FAILED(pUnk->QueryInterface(riid, (void **)&pSinkInterface)))
|
||
|
return CONNECT_E_CANNOTCONNECT;
|
||
|
|
||
|
// Create the sink node
|
||
|
//
|
||
|
pSinkNode = new SINKNODE;
|
||
|
pSinkNode->pNext = pSinkList;
|
||
|
pSinkNode->pUnk = pSinkInterface;
|
||
|
pSinkNode->dwCookie = dwNextCookie;
|
||
|
pSinkNode->uFlags = 0;
|
||
|
*pdwCookie = dwNextCookie;
|
||
|
|
||
|
// Put it in the sink list
|
||
|
//
|
||
|
pSinkList = pSinkNode;
|
||
|
dwNextCookie++;
|
||
|
cSinkNodes++;
|
||
|
return S_OK;
|
||
|
}
|
||
|
|
||
|
//****************************************************************************
|
||
|
// STDMETHODIMP
|
||
|
// CConnectionPoint::Unadvise(DWORD dwCookie)
|
||
|
//
|
||
|
// History:
|
||
|
// Wed 17-Apr-1996 11:17:09 -by- Viroon Touranachun [viroont]
|
||
|
// Created.
|
||
|
//****************************************************************************
|
||
|
|
||
|
STDMETHODIMP
|
||
|
CConnectionPoint::Unadvise(DWORD dwCookie)
|
||
|
{
|
||
|
PSINKNODE pSinkNode, pPrev;
|
||
|
|
||
|
// Search for the matching sink object
|
||
|
//
|
||
|
pPrev = NULL;
|
||
|
pSinkNode = pSinkList;
|
||
|
|
||
|
// Traverse the sink list to find the specified sink object
|
||
|
//
|
||
|
while (pSinkNode != NULL)
|
||
|
{
|
||
|
if (pSinkNode->dwCookie == dwCookie)
|
||
|
{
|
||
|
// Flag to remove
|
||
|
//
|
||
|
pSinkNode->uFlags |= SN_REMOVED;
|
||
|
break;
|
||
|
};
|
||
|
|
||
|
pPrev = pSinkNode;
|
||
|
pSinkNode = pSinkNode->pNext;
|
||
|
};
|
||
|
|
||
|
// Have we found the specified sink object?
|
||
|
//
|
||
|
if (pSinkNode == NULL)
|
||
|
{
|
||
|
// No, return failure
|
||
|
//
|
||
|
return CONNECT_E_NOCONNECTION;
|
||
|
};
|
||
|
|
||
|
// Release the sink object, if not locked
|
||
|
//
|
||
|
if ((pSinkNode->uFlags & SN_REMOVED) &&
|
||
|
!(pSinkNode->uFlags & SN_LOCKED))
|
||
|
{
|
||
|
// Is there a previous node?
|
||
|
//
|
||
|
if (pPrev == NULL)
|
||
|
{
|
||
|
// This is the head of the list
|
||
|
//
|
||
|
pSinkList = pSinkNode->pNext;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
pPrev->pNext = pSinkNode->pNext;
|
||
|
};
|
||
|
|
||
|
pSinkNode->pUnk->Release();
|
||
|
cSinkNodes--;
|
||
|
delete pSinkNode;
|
||
|
};
|
||
|
|
||
|
return S_OK;
|
||
|
}
|
||
|
|
||
|
//****************************************************************************
|
||
|
// STDMETHODIMP
|
||
|
// CConnectionPoint::EnumConnections(IEnumConnections **ppEnum)
|
||
|
//
|
||
|
// History:
|
||
|
// Wed 17-Apr-1996 11:17:18 -by- Viroon Touranachun [viroont]
|
||
|
// Created.
|
||
|
//****************************************************************************
|
||
|
|
||
|
STDMETHODIMP
|
||
|
CConnectionPoint::EnumConnections(IEnumConnections **ppEnum)
|
||
|
{
|
||
|
CEnumConnections *pecn;
|
||
|
HRESULT hr;
|
||
|
|
||
|
// Validate parameters
|
||
|
//
|
||
|
if (ppEnum == NULL)
|
||
|
{
|
||
|
return ILS_E_POINTER;
|
||
|
};
|
||
|
|
||
|
// Assume failure
|
||
|
//
|
||
|
*ppEnum = NULL;
|
||
|
|
||
|
// Create an enumerator
|
||
|
//
|
||
|
pecn = new CEnumConnections;
|
||
|
if (pecn == NULL)
|
||
|
return ILS_E_MEMORY;
|
||
|
|
||
|
// Initialize the enumerator
|
||
|
//
|
||
|
hr = pecn->Init(pSinkList, cSinkNodes);
|
||
|
|
||
|
if (FAILED(hr))
|
||
|
{
|
||
|
delete pecn;
|
||
|
return hr;
|
||
|
};
|
||
|
|
||
|
pecn->AddRef();
|
||
|
*ppEnum = pecn;
|
||
|
return S_OK;
|
||
|
}
|
||
|
|
||
|
//****************************************************************************
|
||
|
// CEnumConnections::CEnumConnections(void)
|
||
|
//
|
||
|
// History:
|
||
|
// Wed 17-Apr-1996 11:17:25 -by- Viroon Touranachun [viroont]
|
||
|
// Created.
|
||
|
//****************************************************************************
|
||
|
|
||
|
CEnumConnections::CEnumConnections(void)
|
||
|
{
|
||
|
cRef = 0;
|
||
|
iIndex = 0;
|
||
|
cConnections = 0;
|
||
|
pConnectData = NULL;
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
//****************************************************************************
|
||
|
// CEnumConnections::~CEnumConnections(void)
|
||
|
//
|
||
|
// History:
|
||
|
// Wed 17-Apr-1996 11:17:25 -by- Viroon Touranachun [viroont]
|
||
|
// Created.
|
||
|
//****************************************************************************
|
||
|
|
||
|
CEnumConnections::~CEnumConnections(void)
|
||
|
{
|
||
|
if (pConnectData != NULL)
|
||
|
{
|
||
|
UINT i;
|
||
|
|
||
|
for (i = 0; i < cConnections; i++)
|
||
|
{
|
||
|
pConnectData[i].pUnk->Release();
|
||
|
};
|
||
|
delete [] pConnectData;
|
||
|
};
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
//****************************************************************************
|
||
|
// STDMETHODIMP
|
||
|
// CEnumConnections::Init(PSINKNODE pSinkList, ULONG cSinkNodes)
|
||
|
//
|
||
|
// History:
|
||
|
// Wed 17-Apr-1996 11:17:34 -by- Viroon Touranachun [viroont]
|
||
|
// Created.
|
||
|
//****************************************************************************
|
||
|
|
||
|
STDMETHODIMP
|
||
|
CEnumConnections::Init(PSINKNODE pSinkList, ULONG cSinkNodes)
|
||
|
{
|
||
|
HRESULT hr = S_OK;
|
||
|
|
||
|
iIndex = 0;
|
||
|
cConnections = 0;
|
||
|
pConnectData = NULL;
|
||
|
|
||
|
// Snapshot the connection list
|
||
|
//
|
||
|
if (cSinkNodes > 0)
|
||
|
{
|
||
|
UINT i;
|
||
|
|
||
|
pConnectData = new CONNECTDATA[cSinkNodes];
|
||
|
|
||
|
if (pConnectData != NULL)
|
||
|
{
|
||
|
for (i = 0; i < cSinkNodes && pSinkList != NULL; i++)
|
||
|
{
|
||
|
if (!(pSinkList->uFlags & SN_REMOVED))
|
||
|
{
|
||
|
pConnectData[cConnections].pUnk = pSinkList->pUnk;
|
||
|
pConnectData[cConnections].pUnk->AddRef();
|
||
|
pConnectData[cConnections].dwCookie = pSinkList->dwCookie;
|
||
|
cConnections++;
|
||
|
};
|
||
|
pSinkList = pSinkList->pNext;
|
||
|
};
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
hr = ILS_E_MEMORY;
|
||
|
};
|
||
|
};
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
//****************************************************************************
|
||
|
// STDMETHODIMP
|
||
|
// CEnumConnections::QueryInterface (REFIID riid, void **ppv)
|
||
|
//
|
||
|
// History:
|
||
|
// Wed 17-Apr-1996 11:17:40 -by- Viroon Touranachun [viroont]
|
||
|
// Created.
|
||
|
//****************************************************************************
|
||
|
|
||
|
STDMETHODIMP
|
||
|
CEnumConnections::QueryInterface (REFIID riid, void **ppv)
|
||
|
{
|
||
|
if (riid == IID_IEnumConnections || riid == IID_IUnknown)
|
||
|
{
|
||
|
*ppv = (IEnumConnections *) this;
|
||
|
AddRef();
|
||
|
return S_OK;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
*ppv = NULL;
|
||
|
return ILS_E_NO_INTERFACE;
|
||
|
};
|
||
|
}
|
||
|
|
||
|
//****************************************************************************
|
||
|
// STDMETHODIMP_(ULONG)
|
||
|
// CEnumConnections::AddRef (void)
|
||
|
//
|
||
|
// History:
|
||
|
// Wed 17-Apr-1996 11:17:49 -by- Viroon Touranachun [viroont]
|
||
|
// Created.
|
||
|
//****************************************************************************
|
||
|
|
||
|
STDMETHODIMP_(ULONG)
|
||
|
CEnumConnections::AddRef (void)
|
||
|
{
|
||
|
DllLock();
|
||
|
|
||
|
MyDebugMsg ((DM_REFCOUNT, "CEnumConnections::AddRef: ref=%ld\r\n", cRef));
|
||
|
::InterlockedIncrement ((LONG *) &cRef);
|
||
|
return cRef;
|
||
|
}
|
||
|
|
||
|
//****************************************************************************
|
||
|
// STDMETHODIMP_(ULONG)
|
||
|
// CEnumConnections::Release (void)
|
||
|
//
|
||
|
// History:
|
||
|
// Wed 17-Apr-1996 11:17:59 -by- Viroon Touranachun [viroont]
|
||
|
// Created.
|
||
|
//****************************************************************************
|
||
|
|
||
|
STDMETHODIMP_(ULONG)
|
||
|
CEnumConnections::Release (void)
|
||
|
{
|
||
|
DllRelease();
|
||
|
|
||
|
ASSERT (cRef > 0);
|
||
|
|
||
|
MyDebugMsg ((DM_REFCOUNT, "CEnumConnections::Release: ref=%ld\r\n", cRef));
|
||
|
if (::InterlockedDecrement ((LONG *) &cRef) == 0)
|
||
|
{
|
||
|
delete this;
|
||
|
return 0;
|
||
|
}
|
||
|
return cRef;
|
||
|
}
|
||
|
|
||
|
//****************************************************************************
|
||
|
// STDMETHODIMP
|
||
|
// CEnumConnections::Next (ULONG cConnectionDatas, CONNECTDATA *rgpcd,
|
||
|
// ULONG *pcFetched)
|
||
|
//
|
||
|
// History:
|
||
|
// Wed 17-Apr-1996 11:18:07 -by- Viroon Touranachun [viroont]
|
||
|
// Created.
|
||
|
//****************************************************************************
|
||
|
|
||
|
STDMETHODIMP
|
||
|
CEnumConnections::Next (ULONG cConnectDatas, CONNECTDATA *rgpcd,
|
||
|
ULONG *pcFetched)
|
||
|
{
|
||
|
CONNECTDATA *pConnect;
|
||
|
ULONG cCopied;
|
||
|
|
||
|
// Validate the pointer
|
||
|
//
|
||
|
if (rgpcd == NULL)
|
||
|
return ILS_E_POINTER;
|
||
|
|
||
|
// Validate the parameters
|
||
|
//
|
||
|
if ((cConnectDatas == 0) ||
|
||
|
((cConnectDatas > 1) && (pcFetched == NULL)))
|
||
|
return ILS_E_PARAMETER;
|
||
|
|
||
|
// Check the enumeration index
|
||
|
//
|
||
|
pConnect = &pConnectData[iIndex];
|
||
|
for (cCopied = 0; iIndex < cConnections && cCopied < cConnectDatas; cCopied++)
|
||
|
{
|
||
|
rgpcd[cCopied] = *pConnect;
|
||
|
rgpcd[cCopied].pUnk->AddRef();
|
||
|
iIndex++;
|
||
|
pConnect++;
|
||
|
};
|
||
|
|
||
|
// Determine the returned information based on other parameters
|
||
|
//
|
||
|
if (pcFetched != NULL)
|
||
|
{
|
||
|
*pcFetched = cCopied;
|
||
|
};
|
||
|
return (cConnectDatas == cCopied ? S_OK : S_FALSE);
|
||
|
}
|
||
|
|
||
|
//****************************************************************************
|
||
|
// STDMETHODIMP
|
||
|
// CEnumConnections::Skip (ULONG cConnectDatas)
|
||
|
//
|
||
|
// History:
|
||
|
// Wed 17-Apr-1996 11:18:15 -by- Viroon Touranachun [viroont]
|
||
|
// Created.
|
||
|
//****************************************************************************
|
||
|
|
||
|
STDMETHODIMP
|
||
|
CEnumConnections::Skip (ULONG cConnectDatas)
|
||
|
{
|
||
|
// Validate the parameters
|
||
|
//
|
||
|
if (cConnectDatas == 0)
|
||
|
return ILS_E_PARAMETER;
|
||
|
|
||
|
// Check the enumeration index limit
|
||
|
//
|
||
|
if ((iIndex+cConnectDatas) >= cConnections)
|
||
|
{
|
||
|
iIndex = cConnections;
|
||
|
return S_FALSE;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
// Skip as requested
|
||
|
//
|
||
|
iIndex += cConnectDatas;
|
||
|
return S_OK;
|
||
|
};
|
||
|
}
|
||
|
|
||
|
//****************************************************************************
|
||
|
// STDMETHODIMP
|
||
|
// CEnumConnections::Reset (void)
|
||
|
//
|
||
|
// History:
|
||
|
// Wed 17-Apr-1996 11:18:22 -by- Viroon Touranachun [viroont]
|
||
|
// Created.
|
||
|
//****************************************************************************
|
||
|
|
||
|
STDMETHODIMP
|
||
|
CEnumConnections::Reset (void)
|
||
|
{
|
||
|
iIndex = 0;
|
||
|
return S_OK;
|
||
|
}
|
||
|
|
||
|
//****************************************************************************
|
||
|
// STDMETHODIMP
|
||
|
// CEnumConnections::Clone(IEnumConnections **ppEnum)
|
||
|
//
|
||
|
// History:
|
||
|
// Wed 17-Apr-1996 11:18:29 -by- Viroon Touranachun [viroont]
|
||
|
// Created.
|
||
|
//****************************************************************************
|
||
|
|
||
|
STDMETHODIMP
|
||
|
CEnumConnections::Clone(IEnumConnections **ppEnum)
|
||
|
{
|
||
|
CEnumConnections *pecn;
|
||
|
CONNECTDATA *pConnectDataClone;
|
||
|
UINT i;
|
||
|
|
||
|
// Validate parameters
|
||
|
//
|
||
|
if (ppEnum == NULL)
|
||
|
{
|
||
|
return ILS_E_POINTER;
|
||
|
};
|
||
|
|
||
|
*ppEnum = NULL;
|
||
|
|
||
|
// Create an enumerator
|
||
|
//
|
||
|
pecn = new CEnumConnections;
|
||
|
if (pecn == NULL)
|
||
|
return ILS_E_MEMORY;
|
||
|
|
||
|
// Clone the information
|
||
|
//
|
||
|
pConnectDataClone = new CONNECTDATA[cConnections];
|
||
|
if (pConnectDataClone == NULL)
|
||
|
{
|
||
|
delete pecn;
|
||
|
return ILS_E_MEMORY;
|
||
|
};
|
||
|
|
||
|
// Clone the connect data list
|
||
|
//
|
||
|
for (i = 0; i < cConnections; i++)
|
||
|
{
|
||
|
pConnectDataClone[i] = pConnectData[i];
|
||
|
pConnectDataClone[i].pUnk->AddRef();
|
||
|
};
|
||
|
pecn->iIndex = iIndex;
|
||
|
pecn->cConnections = cConnections;
|
||
|
|
||
|
// Return the cloned enumerator
|
||
|
//
|
||
|
pecn->AddRef();
|
||
|
*ppEnum = pecn;
|
||
|
return S_OK;
|
||
|
}
|