Esempio n. 1
0
HRESULT AFXAPI CComObjectRootBase::InternalQueryInterface(void *pThis, const _ATL_INTMAP_ENTRY *pEntries, REFIID iid, LPVOID* ppvObj) {
	if (!ppvObj)
		return E_POINTER;
	*ppvObj = 0;
	if (iid == IID_IUnknown) {		// use first interface
		IUnknown* pUnk = (IUnknown*)((DWORD_PTR)pThis+pEntries->dw);
		pUnk->AddRef();
		*ppvObj = pUnk;
		return S_OK;
	}
	for (;pEntries->pFunc; pEntries++) {
		bool bBlind = !pEntries->piid;
		if (bBlind || *(pEntries->piid) == iid) {
			if (pEntries->pFunc == _EXT_SIMPLEMAPENTRY) {	//offset
				IUnknown* pUnk = (IUnknown*)((DWORD_PTR)pThis+pEntries->dw);
				pUnk->AddRef();
				*ppvObj = pUnk;
				return S_OK;
			} else {
				HRESULT hr = pEntries->pFunc(pThis, iid, ppvObj, pEntries->dw);
				if (SUCCEEDED(hr) || !bBlind)
					return hr;
				continue;
			}
		}
	}
	return E_NOINTERFACE;
}
Esempio n. 2
0
// Collect all leaked elements, passing them to the specified leak dialog.
//
void JSHook::showLeaks(MSHTML::IHTMLWindow2Ptr wnd, CLeakDlg* dlg) {
	// Ensure that all garbage collection is completed so that elements will
	//   be released.
	//
	wnd->execScript(L"window.CollectGarbage()", L"javascript");

	for (std::map<IUnknown*,Elem>::const_iterator it = m_elements.begin(); it != m_elements.end(); ++it) {
		IUnknown *unk = it->first;
		Elem const& elem = it->second;

		// For each element, AddRef() and Release() it.  The latter method will return
		//   the current ref count.
		//
		unk->AddRef();
		int refCount = unk->Release();

		// If any references (other than the one that we hold) are outstanding, then
		//   the element has been leaked.
		//
		if (refCount > 1)
			dlg->addElement(unk, elem.url, refCount - 1);
	}

	// When finished, clear the element list.
	//
	clearElements();
}
STDMETHODIMP touchmind::control::DWriteEditControlTextStoreACP::AdviseSink(REFIID riid, IUnknown *pUnknown,
                                                                           DWORD dwMask) {
  HRESULT hr;
  IUnknown *punkID;

  hr = pUnknown->QueryInterface(IID_IUnknown, (LPVOID *)&punkID);
  if (FAILED(hr)) {
    return hr;
  }

  hr = E_INVALIDARG;

  if (punkID == m_AdviseSink.punkID) {
    m_AdviseSink.dwMask = dwMask;

    hr = S_OK;
  } else if (nullptr != m_AdviseSink.punkID) {
    hr = CONNECT_E_ADVISELIMIT;
  } else if (IsEqualIID(riid, IID_ITextStoreACPSink)) {
    m_AdviseSink.dwMask = dwMask;
    m_AdviseSink.punkID = punkID;

    punkID->AddRef();
    pUnknown->QueryInterface(IID_ITextStoreACPSink, (LPVOID *)&m_AdviseSink.pTextStoreACPSink);
    pUnknown->QueryInterface(IID_ITextStoreACPServices, (LPVOID *)&m_pServices);
    hr = S_OK;
  }

  punkID->Release();
  return hr;
}
// unadvise the world without decrementing the reference count of the client.
//reduces refcount of pworld by 1.
void DeleteWorld(IWorld* pWorld, DWORD dwCookie)
{
	IConnectionPoint* pconnpt = NULL;
	IConnectionPointContainer* pconnptctr = NULL;

	if (pWorld == NULL) 
		return;

	HRESULT hr = pWorld->QueryInterface(IID_IConnectionPointContainer, (LPVOID*)&pconnptctr);
	if (SUCCEEDED(hr))
	{
		hr = pconnptctr->FindConnectionPoint(IID_IVWObjectSite, &pconnpt);
		if (SUCCEEDED(hr))
		{
			// HACK: artificially addref ptr
			IUnknown* p = (IUnknown *)dwCookie;
			p->AddRef();

			pconnpt->Unadvise(dwCookie);
			pconnpt->Release();
		}
		pconnptctr->Release();
	}

	pWorld->Terminate();

	// REVIEW: let caller SAFERELEASE ptr rather than do it in here
//	SAFERELEASE(pWorld);
}
Esempio n. 5
0
static HRESULT
VBoxSafeArrayCopyOutIfaceParamHelper(IUnknown ***ppaObj, ULONG *pcObj, SAFEARRAY *psa)
{
    ULONG mypcb;
    HRESULT rc = VBoxSafeArrayCopyOutParamHelper((void **)ppaObj, &mypcb, VT_UNKNOWN, psa);
    if (FAILED(rc))
    {
        if (pcObj)
            *pcObj = 0;
        return rc;
    }
    ULONG cElements = mypcb / sizeof(void *);
    if (pcObj)
        *pcObj = cElements;
#ifndef VBOX_WITH_XPCOM
    /* Do this only for COM, as there the SAFEARRAY destruction will release
     * the contained references automatically. XPCOM doesn't do that, which
     * means that copying implicitly transfers ownership. */
    IUnknown **paObj = *ppaObj;
    for (ULONG i = 0; i < cElements; i++)
    {
        IUnknown *pObj = paObj[i];
        if (pObj)
            pObj->AddRef();
    }
#endif /* VBOX_WITH_XPCOM */
    return S_OK;
}
Esempio n. 6
0
void CDlgIADs::OnParentPath() 
{
	  HRESULT hr;
	  UpdateData(TRUE); // Retrieve from UI


      USES_CONVERSION;
	  IUnknown *pUnk;
	  CWaitCursor wait;
	  
	  hr = App->ADsOpenObject( T2OLE( m_sParent ), IID_IUnknown, (void**) &pUnk ); 
	  
	  /////////////////////////////////////
	  // Bring up the IADsContainer Dialog
	  ///////////////////////////////////////
	  if ( SUCCEEDED(hr) )
	  {
		  pUnk->AddRef();
		  CDlgIADsContainer dlg( pUnk, this );	  
		  dlg.DoModal();

		  pUnk->Release();
	  }
	  else
	  {
		  AfxMessageBox( GetErrorMessage(hr) );
	  }

	
}
Esempio n. 7
0
STDMETHODIMP
ase_com_aseproxy::QueryInterface(REFIID iid, void **ppvObject)
{
    DBG_COM(fprintf(stderr, "wrap: %p QI\n", this));
    if (ppvObject == NULL) {
        return E_POINTER;
    }
    if (IsEqualIID(iid, IID_IUnknown)) {
        IUnknown *pu = this;
        pu->AddRef();
        *ppvObject = pu;
        return S_OK;
    } else if (IsEqualIID(iid, IID_IDispatch)) {
        IDispatch *pd = this;
        pd->AddRef();
        *ppvObject = pd;
        return S_OK;
    } else {
        IID sinkiid = value.get_event_sink_iid_synchronized();
        if (IsEqualIID(iid, sinkiid)) {
            IDispatch *pd = this;
            pd->AddRef();
            *ppvObject = pd;
            return S_OK;
        }
    }
    *ppvObject = 0;
    return E_NOINTERFACE;
}
Esempio n. 8
0
STDMETHODIMP COMUnknownEnum::Clone(OUT IEnumUnknown ** ppEnumUnknown)
{
	IUnknown *unknown;

	if (!ppEnumUnknown)
		return E_INVALIDARG;

	COMUnknownEnumObject *clone = new COMUnknownEnumObject;
	POSITION pos;
	POSITION clonePos;
	BOOL isCurPos;
	
	pos = m_list.GetHeadPosition();
	while (pos)
	{
		if (pos != m_curPos)
			isCurPos = FALSE;
		else
			isCurPos = TRUE;
		unknown = m_list.GetNext(pos);
		unknown->AddRef();
		clonePos = clone->m_list.AddTail(unknown);
		if (isCurPos)
			clone->m_curPos = clonePos;
	}

	clone->QueryInterface(IID_IEnumUnknown, (void **)ppEnumUnknown);

	return S_OK;
}
Esempio n. 9
0
Reference *
Reference::newReference (IUnknown *pOrig, const Interface *pInterface)
{
    if (pOrig == 0) {
        _com_issue_error(E_POINTER);
    }

    if (pInterface == 0) {
        pInterface = findInterfaceFromDispatch(pOrig);
    }

    // If we know it's a custom interface, then query for an interface pointer
    // to that interface, otherwise query for an IUnknown interface.
    const IID &iid = (pInterface == 0) ? IID_IUnknown : pInterface->iid();

    IUnknown *pUnknown;
    HRESULT hr = pOrig->QueryInterface(
        iid,
        reinterpret_cast<void **>(&pUnknown));
    if (FAILED(hr)) {
        pUnknown = pOrig;
        pUnknown->AddRef();
    }

    return new Reference(pUnknown, pInterface);
}
Esempio n. 10
0
CHXList::GetTail(void)
{
    HX_ASSERT_VALID_PTR(this);
    HX_ASSERT(m_pHead != NULL && m_pTail != NULL && m_nCount > 0);

    Node* pNode = m_pTail;

    IUnknown* punkItem = pNode->m_punkItem;
    punkItem->AddRef();

    return punkItem;
}
Esempio n. 11
0
 STDMETHODIMP QueryInterface(REFIID riid, void** ppvObject)
 {
     IUnknown *punk = NULL;
     if (riid == IID_IUnknown)
         punk = static_cast<IUnknown*>(this);
     else if (riid == IID_IEnumString)
         punk = static_cast<IEnumString*>(this);
     *ppvObject = punk;
     if (punk == NULL)
         return E_NOINTERFACE;
     punk->AddRef();
     return S_OK;
 }
Esempio n. 12
0
STDMETHODIMP CActiveXCtrl::SetSite(IUnknown *pUnkSite)
{
   TRACE(_T("AX: CActiveXCtrl::SetSite"));
   if( m_pUnkSite != NULL ) {
      m_pUnkSite->Release();
      m_pUnkSite = NULL;
   }
   if( pUnkSite != NULL ) {
      m_pUnkSite = pUnkSite;
      m_pUnkSite->AddRef();
   }
   return S_OK;
}
Esempio n. 13
0
/**************************************************************************
*    CControlPanelFolder::GetUIObjectOf
*
* PARAMETERS
*  HWND           hwndOwner, //[in ] Parent window for any output
*  UINT           cidl,      //[in ] array size
*  LPCITEMIDLIST* apidl,     //[in ] simple pidl array
*  REFIID         riid,      //[in ] Requested Interface
*  UINT*          prgfInOut, //[   ] reserved
*  LPVOID*        ppvObject) //[out] Resulting Interface
*
*/
HRESULT WINAPI CControlPanelFolder::GetUIObjectOf(HWND hwndOwner,
        UINT cidl, PCUITEMID_CHILD_ARRAY apidl, REFIID riid, UINT * prgfInOut, LPVOID * ppvOut)
{
    LPITEMIDLIST pidl;
    IUnknown *pObj = NULL;
    HRESULT hr = E_INVALIDARG;

    TRACE("(%p)->(%p,%u,apidl=%p,%s,%p,%p)\n",
          this, hwndOwner, cidl, apidl, shdebugstr_guid(&riid), prgfInOut, ppvOut);

    if (ppvOut) {
        *ppvOut = NULL;

        if (IsEqualIID(riid, IID_IContextMenu) && (cidl >= 1)) {
            // TODO
            // create a seperate item struct
            //
            pObj = (IContextMenu *)this;
            this->apidl = apidl;
            this->cidl = cidl;
            pObj->AddRef();
            hr = S_OK;
        } else if (IsEqualIID(riid, IID_IDataObject) && (cidl >= 1)) {
            hr = IDataObject_Constructor(hwndOwner, pidlRoot, apidl, cidl, (IDataObject **)&pObj);
        } else if (IsEqualIID(riid, IID_IExtractIconA) && (cidl == 1)) {
            pidl = ILCombine(pidlRoot, apidl[0]);
            pObj = IExtractIconA_Constructor(pidl);
            SHFree(pidl);
            hr = S_OK;
        } else if (IsEqualIID(riid, IID_IExtractIconW) && (cidl == 1)) {
            pidl = ILCombine(pidlRoot, apidl[0]);
            pObj = IExtractIconW_Constructor(pidl);
            SHFree(pidl);
            hr = S_OK;
        } else if ((IsEqualIID(riid, IID_IShellLinkW) || IsEqualIID(riid, IID_IShellLinkA))
                   && (cidl == 1)) {
            pidl = ILCombine(pidlRoot, apidl[0]);
            hr = IShellLink_ConstructFromFile(NULL, riid, pidl, (LPVOID*)&pObj);
            SHFree(pidl);
        } else {
            hr = E_NOINTERFACE;
        }

        if (SUCCEEDED(hr) && !pObj)
            hr = E_OUTOFMEMORY;

        *ppvOut = pObj;
    }
    TRACE("(%p)->hr=0x%08x\n", this, hr);
    return hr;
}
Esempio n. 14
0
int main(int argc, char* argv[])
{
    if (argc != 3)
    {
	fprintf(stderr, "Usage : %s <sdp version> <sdp file>\n", argv[0]);
    }
    else
    {
	IUnknown* pContext = new CHXMiniCCF();
	
	if (pContext)
	{
	    pContext->AddRef();
	    
	    IHXCommonClassFactory* pCCF = 0;

	    if (HXR_OK == pContext->QueryInterface(IID_IHXCommonClassFactory,
						   (void**)&pCCF))
	    {
		IHXBuffer* pSDP = ReadSDPFile(pCCF, argv[2]);

		if (pSDP)
		{
		    if (HXR_OK != Parse(pContext, strtoul(argv[1], 0, 10), 
					pSDP))
		    {
			fprintf(stderr, "Failed to parse SDP\n", argv[1]);
		    }

		    pSDP->Release();
		    pSDP = 0;
		}
		else
		{
		    fprintf(stderr, "Failed to read SDP file '%s'\n", argv[2]);
		}

		pCCF->Release();
		pCCF = 0;
	    }
	    	    
	    pContext->Release();
	    pContext = 0;
	}
	
    }

    return 0;
}
Esempio n. 15
0
// Funktion entscheidet, ob DSearchObjects verfügbar ist oder nicht
HRESULT WINAPI COleObjectPropertyDual::_ChoiceSearchable (void *pv, REFIID iid, 
	void** ppvObject, DWORD dw)
{
COleObjectPropertyDual *pThis = (COleObjectPropertyDual *)pv;

	if (!pThis->m_fSearchAble)
		return E_NOINTERFACE;		// 'ConsiderSearch' et. al. ist nicht verfügbar

// ansonsten normales QI
IUnknown* pUnk = (IUnknown*)((int)pThis+dw);

	pUnk->AddRef();
	*ppvObject = pUnk;
	return S_OK;
}
Esempio n. 16
0
 STDMETHODIMP QueryInterface(REFIID riid,
                             void **ppvObject)
 {
   IUnknown *punk = nullptr;
   if (riid == IID_IUnknown) {
     punk = this;
   }
   *ppvObject = punk;
   if (punk) {
     punk->AddRef();
     return S_OK;
   } else {
     return E_NOINTERFACE;
   }
 }
Esempio n. 17
0
HRESULT OcxObject::InternalQueryInterface(const GUID& iid, void **ppv)
{
#if LOG_QUERIES >= 2
	OCXLOG("OcxObject::InternalQueryInterface -> " << GetInterfaceName(iid));
#endif
	int i;
	IUnknown *punk;
	if(iid == IID_IUnknown)
		punk = static_cast<IUnknown *>(&inner_unknown);
	else if((i = interface_map.Find(iid)) >= 0)
		punk = interface_map[i];
	else {
		*ppv = 0;
#if LOG_QUERIES >= 1
		String name;
		if(ocx_info)
			name = ocx_info->GetName();
		else
			name = "<unknown object>";
#endif
		LOGQUERY("\t\tcast ERROR: " << name << " -> "<< GetInterfaceName(iid) << ", " << Guid(iid));
#if LOG_QUERIES >= 3
		OCXLOG("\tGUID = " << Format(iid));
		for(int i = 0; i < interface_map.GetCount(); i++) {
			const GUID& imid = interface_map.GetKey(i);
			String n = GetInterfaceName(imid);
			if(n.GetLength() < 30)
				n.Cat(' ', 30 - n.GetLength());
			OCXLOG("\t\t\t" << n << " - " << Format(imid));
		}
#endif
		return E_NOINTERFACE;
	}
	punk->AddRef();
	*ppv = punk;
#if LOG_QUERIES >= 2
	String name;
	if(ocx_info)
		name = ocx_info->GetName();
	else
		name = "<unknown object>";
	OCXLOG("\t\tcast OK:    " << name << " -> " << GetInterfaceName(iid));
#endif
	return S_OK;
}
Esempio n. 18
0
STDMETHODIMP 
IMemStream::QueryInterface( REFIID iid, void** ppv )  
{    
    *ppv = NULL; 
    IUnknown *pUnk = NULL;
     
    if( IsEqualIID( iid, IID_IStream ) )
    {
        pUnk = this;      
        pUnk->AddRef(); 
        *ppv = pUnk;
        return NOERROR;     
    }
    else if( m_pOuterUnk )
        return m_pOuterUnk->QueryInterface( iid, ppv );
    else
        return E_NOINTERFACE;
} 
Esempio n. 19
0
HRESULT PrintingContentHandler::QueryInterface( const IID& riid, void** ppvObject )
{
    IUnknown*   unk = NULL;

    if ( ppvObject == NULL )
        return E_POINTER;

    if ( riid == IID_IUnknown )
        unk = static_cast<IUnknown*>( this );
    else if ( riid == IID_ISAXContentHandler )
        unk = static_cast<ISAXContentHandler*>( this );
    else
        return E_NOINTERFACE;

    unk->AddRef();
    *ppvObject = unk;

    return S_OK;
}
HRESULT Rayman3XInput_DirectInputDevice8A::QueryInterface(REFIID riid, void** ppvObject)
{
	IUnknown* pUnk = NULL;
	if (riid == IID_IUnknown) {
		pUnk = this;
	} else if (riid == IID_IDirectInputDevice8A) {
		pUnk = this;
	}

	*ppvObject = pUnk;
	if (pUnk)
	{
		pUnk->AddRef();
		return S_OK;
	}
	else
	{
		return E_NOINTERFACE;
	}
}
Esempio n. 21
0
CHXVector::GetTail(void)
{
    HX_ASSERT_VALID_PTR(this);

    if (m_ppunkData != NULL && m_ulSize > 0)
    {
        IUnknown* punkItem = m_ppunkData[m_ulSize-1];

        if (punkItem)
        {
            punkItem->AddRef();
        }

        return punkItem;
    }
    else
    {
        return NULL;
    }
}
Esempio n. 22
0
CHXRingBuffer::GetTail(void)
{
    HX_ASSERT_VALID_PTR(this);

    if (m_ppunkData != NULL && m_ulCount > 0)
    {
        IUnknown* punkItem = m_ppunkData[m_ulTail ? m_ulTail-1 : m_ulAlloc-1];

        if (punkItem)
        {
            punkItem->AddRef();
        }

        return punkItem;
    }
    else
    {
        return NULL;
    }
}
/*** IUnknown methods ***/
HRESULT Rayman2InputFix_DirectInputA::QueryInterface(REFIID riid, LPVOID * ppvObj)
{
	Debug("DI: QueryInterface called\n");
	IUnknown* pUnk = NULL;
	if (riid == IID_IUnknown) {
		pUnk = this;
	} else if (riid == IID_IDirectInputA) {
		pUnk = this;
	}

	*ppvObj = pUnk;
	if (pUnk)
	{
		pUnk->AddRef();
		return S_OK;
	}
	else
	{
		return E_NOINTERFACE;
	}
}
Esempio n. 24
0
//*****************************************************************************
// Gets a cached Internal importer, if available.
// 
// Arguments:
//     fWithLock - if true, takes a reader lock. 
//     If false, assumes caller is handling the synchronization.
//
// Returns:
//     A cached Internal importer, which gets addreffed. Caller must release!
//     If no importer is set, returns NULL
//
// Notes:
//     This function also does not trigger the creation of Internal interface.
//     Set the cached importer via code:RegMeta.SetCachedInternalInterface
// 
// Implements internal API code:IMetaDataHelper::GetCachedInternalInterface.
//*****************************************************************************
IUnknown* RegMeta::GetCachedInternalInterface(BOOL fWithLock) 
{
    IUnknown        *pRet = NULL;
    HRESULT hr = S_OK;
    
    if (fWithLock)
    {
        LOCKREAD();
        
        pRet = m_pInternalImport;
    }
    else
    {
        pRet = m_pInternalImport;
    }
    if (pRet) pRet->AddRef();

ErrExit:

    return pRet;
} //RegMeta::GetCachedInternalInterface
Esempio n. 25
0
void CDlgIADs::OnSchemaPath() 
{
	  HRESULT hr;
	  UpdateData(TRUE); // Retrieve from UI


      USES_CONVERSION;
	  IUnknown *pUnk;
	  IADs	   *pADs;
	  BSTR      bstr;
	  CWaitCursor wait;

	  
	  hr = App->ADsOpenObject( T2OLE( m_sSchema ), IID_IADs, (void**) &pADs ); 
	  RETURN_ON_FAILURE(hr);
	  

	  hr = pADs->get_Parent( &bstr );
	  pADs->Release();

	  RETURN_ON_FAILURE(hr);

	  hr = App->ADsOpenObject( bstr, IID_IUnknown, (void**) &pUnk ); 
	  SysFreeString( bstr );

	  /////////////////////////////////////
	  // Bring up the IADsContainer Dialog
	  ///////////////////////////////////////
	  if ( SUCCEEDED(hr) )
	  {
		  pUnk->AddRef();
		  CDlgIADsContainer dlg( pUnk, this );	  
		  dlg.DoModal();

		  pUnk->Release();
	  }


	
}
Esempio n. 26
0
void comset_variant( VARIANT *var, void *data, int vtype )
{
	//		HSPの型→VARIANT 型に変換する
	//
	IUnknown *punk;

	VariantClear( var );
	switch( vtype ) {
	case HSPVAR_FLAG_INT:
		var->vt = VT_I4;
		var->lVal = *(int *)data;
		break;
	case HSPVAR_FLAG_DOUBLE:
		var->vt = VT_R8;
		var->dblVal = *(double *)data;
		break;
	case HSPVAR_FLAG_STR:
		var->vt = VT_BSTR;
		var->bstrVal = comget_bstr( (char *)data );
		break;
	case HSPVAR_FLAG_COMSTRUCT:
		var->vt = VT_UNKNOWN;
		var->punkVal = NULL;
		punk = *(IUnknown **)data;
		if ( punk == NULL ) break;
		punk->QueryInterface( IID_IDispatch, (void**)&var->pdispVal );
		if ( var->pdispVal != NULL ) {
			var->vt = VT_DISPATCH;
		} else {
			var->punkVal = punk;
			punk->AddRef();
		}
		break;
	case HSPVAR_FLAG_VARIANT:
		VariantCopy( var, (VARIANT *)data );
		break;
	default:
		throw HSPERR_INVALID_TYPE;
	}
}
Esempio n. 27
0
//---------------------------------------------------------------------------
HRESULT _stdcall TStorageProviderImpl::GetStreamForRead(LPWSTR url, IUnknown ** stream )
{
	TStream *tvpstream;

	try
	{
		tvpstream = new TFileStream(AnsiString(url), fmOpenRead|fmShareDenyWrite);
	}
	catch(...)
	{
		return E_FAIL;
	}

	TStreamAdapter * adapter;
	adapter = new TStreamAdapter(tvpstream, soOwned);

	IUnknown *istream = (IUnknown*)(IStream*)(*adapter);
	*stream = istream;
	istream->AddRef();

	return S_OK;
}
Esempio n. 28
0
HRESULT WINAPI CNetConUiObject::GetSite(REFIID riid, PVOID *ppvSite)
{
    HRESULT hr;
    IUnknown *pUnknown;

    if (!this->pUnknown)
    {
        *ppvSite = NULL;
        return E_FAIL;
    }

    hr = this->pUnknown->QueryInterface(riid, (LPVOID*)&pUnknown);
    if (SUCCEEDED(hr))
    {
        pUnknown->AddRef();
        *ppvSite = pUnknown;
        return S_OK;
    }

    *ppvSite = NULL;
    return hr;
}
Esempio n. 29
0
HRESULT WINAPI CNetConUiObject::GetSite(REFIID riid, PVOID *ppvSite)
{
    HRESULT hr;
    IUnknown *pUnknown;

    if (!m_pUnknown)
    {
        *ppvSite = NULL;
        return E_FAIL;
    }

    hr = m_pUnknown->QueryInterface(riid, reinterpret_cast<PVOID*>(&pUnknown));
    if (SUCCEEDED(hr))
    {
        pUnknown->AddRef();
        *ppvSite = pUnknown;
        return S_OK;
    }

    *ppvSite = NULL;
    return hr;
}
LRESULT CSaveModifiedItemsDialog::OnListViewInsertItem(int /*idCtrl*/, LPNMHDR pnmh, BOOL& bHandled)
{
	bHandled = TRUE;
	LPNMLISTVIEW pnmLV = (LPNMLISTVIEW)pnmh;
	if(pnmLV != NULL)
	{
		// It'd be nice if they set the lParam of NMLISTVIEW, but they don't.
		// Only iItem is valid
		//LPARAM lParam = pnmLV->lParam;
		//if(lParam != NULL)
		//{
		//	// Keep an AddRef around for the item, and Release in OnDeleteItem
		//	((IUnknown*)lParam)->AddRef();
		//}
		IUnknown* punk = this->GetIUnknownForItem(pnmLV->iItem);
		if(punk)
		{
			// Keep an AddRef around for the item, and Release in OnDeleteItem
			punk->AddRef();
		}
	}
	return 0;
}