windows-nt/Source/XPSP1/NT/multimedia/dshow/guidestore/stdafx.h
2020-09-26 16:20:57 +08:00

518 lines
10 KiB
C++

// stdafx.h : include file for standard system include files,
// or project specific include files that are used frequently,
// but are changed infrequently
#if !defined(AFX_STDAFX_H__B7E9C4D4_B8E5_48DE_A578_B75F8096FB42__INCLUDED_)
#define AFX_STDAFX_H__B7E9C4D4_B8E5_48DE_A578_B75F8096FB42__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#define STRICT
#ifndef _WIN32_WINNT
#define _WIN32_WINNT 0x0400
#endif
#define _ATL_APARTMENT_THREADED
#if 0
#define _ATL_DEBUG_INTERFACES 1
#endif
#include <atlbase.h>
//You may derive a class from CComModule and use it if you want to override
//something, but do not change the name of _Module
extern CComModule _Module;
#include <atlcom.h>
#include <comdef.h>
#import "msado21.tlb" rename("EOF", "EndOfFile") raw_method_prefix("") high_method_prefix("_")
#import "sqldmo.rll" raw_method_prefix("") high_method_prefix("_") rename("GetUserName", "_GetUserName")
#import "msadox.dll" raw_method_prefix("") high_method_prefix("_")
#include <icrsint.h>
#undef END_ADO_BINDING
#define END_ADO_BINDING() {0, ADODB::adEmpty, 0, 0, 0, 0, 0, 0, 0, FALSE}};\
return rgADOBindingEntries;}
#include <oledb.h>
#include <map>
#include <list>
#include <vector>
using namespace std;
#define THIS_FILE __FILE__
#define sizeofarray(a) (sizeof(a)/sizeof((a)[0]))
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
class ILRUCache
{
public:
virtual void Lock() = 0;
virtual void Unlock() = 0;
virtual void AddToCache(IUnknown *punk) = 0;
virtual void RemoveFromCache(IUnknown *punk) = 0;
};
class DECLSPEC_UUID("321ADAAD-5334-4227-8982-585A9A3F4C02") ILRUCachedObject : public IUnknown
{
public:
virtual HRESULT put_Cache(ILRUCache *pcache) = 0;
#if 0
virtual ULONG RefCount() = 0;
#endif
};
template <class T>
class CComObjectCachedLRU : public T, public ILRUCachedObject
{
public:
CComObjectCachedLRU<T>()
{
m_pcache = NULL;
}
// Set refcount to 1 to protect destruction
~CComObjectCachedLRU()
{
m_dwRef = 1L;
FinalRelease();
#ifdef _ATL_DEBUG_INTERFACES
_Module.DeleteNonAddRefThunk(_GetRawUnknown());
#endif
}
//If InternalAddRef or InternalRelease is undefined then your class
//doesn't derive from CComObjectRoot
STDMETHOD_(ULONG, AddRef)()
{
m_csCached.Lock();
ULONG l = InternalAddRef();
if (m_dwRef == 2)
{
_Module.Lock();
if (m_pcache != NULL)
m_pcache->RemoveFromCache(GetControllingUnknown());
}
m_csCached.Unlock();
return l;
}
STDMETHOD_(ULONG, Release)()
{
m_csCached.Lock();
InternalRelease();
ULONG l = m_dwRef;
if (l > 1)
{
m_csCached.Unlock();
return l;
}
if (l == 1)
{
if (m_pcache != NULL)
{
_Module.Unlock();
// Can't reference any member variables after call to AddToCache()
// because AddToCache() might Release() this object down to
// zero refs... that would cause the object to be deleted.
ILRUCache *pcache = m_pcache;
pcache->Lock();
m_csCached.Unlock();
pcache->AddToCache(GetControllingUnknown());
pcache->Unlock();
}
else
{
m_csCached.Unlock();
}
return l;
}
if (l == 0)
{
m_csCached.Unlock();
delete this;
// Return right away so member variables aren't accidently referenced.
return l;
}
_ASSERTE(TRUE); // Should never get here.
return 0;
}
//if _InternalQueryInterface is undefined then you forgot BEGIN_COM_MAP
STDMETHOD(QueryInterface)(REFIID iid, void ** ppvObject)
{
HRESULT hr;
hr = _InternalQueryInterface(iid, ppvObject);
if (hr == E_NOINTERFACE)
{
if (iid == __uuidof(ILRUCachedObject))
{
*ppvObject = (void *)(ILRUCachedObject *)this;
AddRef();
hr = S_OK;
}
}
return hr;
}
static HRESULT WINAPI CreateInstance(CComObjectCachedLRU<T>** pp);
// ILRUCachedObject
virtual HRESULT put_Cache(ILRUCache *pcache)
{
// NOTE: No reference count
m_pcache = pcache;
return S_OK;
}
#if 0
virtual ULONG RefCount()
{
return m_dwRef;
}
#endif
protected:
CComGlobalsThreadModel::AutoCriticalSection m_csCached;
ILRUCache *m_pcache;
};
template <class T>
HRESULT WINAPI CComObjectCachedLRU<T>::CreateInstance(CComObjectCachedLRU<T>** pp)
{
ATLASSERT(pp != NULL);
HRESULT hRes = E_OUTOFMEMORY;
CComObjectCachedLRU<T>* p = NULL;
ATLTRY(p = new CComObjectCachedLRU<T>())
if (p != NULL)
{
p->SetVoid(NULL);
p->InternalFinalConstructAddRef();
hRes = p->FinalConstruct();
p->InternalFinalConstructRelease();
if (hRes != S_OK)
{
delete p;
p = NULL;
}
}
*pp = p;
return hRes;
}
class CComObjectCacheByID : public ILRUCache
{
typedef map<long, IUnknown *> t_mapIdUnk;
typedef map<IUnknown *, long> t_mapUnkId;
typedef list<IUnknown *> t_listCache;
public:
CComObjectCacheByID(long cKeep)
{
m_cKeep = cKeep;
}
void _Lock()
{
m_csCached.Lock();
}
void _Unlock()
{
m_csCached.Unlock();
}
long Count()
{
return m_mapIdUnk.size();
}
IUnknown * Item(long i)
{
t_mapIdUnk::iterator it;
it = m_mapIdUnk.begin();
while (i--)
it++;
if (it == m_mapIdUnk.end())
return NULL;
IUnknown *punk = ((*it).second);
// If it is in the cache then return NULL
t_listCache::iterator it2;
it2 = m_listCache.begin();
while (it2 != m_listCache.end())
{
if (*it2 == punk)
return NULL;
it2++;
}
punk->AddRef();
return punk;
}
long CachedCount()
{
return m_listCache.size();
}
HRESULT Cache(long id, IUnknown *punk)
{
HRESULT hr = S_OK;
Lock();
// Need the canonical IUnknown
punk->QueryInterface(__uuidof(IUnknown), (void **) &punk);
t_mapIdUnk::iterator it = m_mapIdUnk.find(id);
if (it != m_mapIdUnk.end())
{
// If it is already there... just return...
hr = (punk == ((*it).second)) ? S_FALSE : E_INVALIDARG;
// ... but don't forget to release the ref count
// from the above QueryInterface() call.
punk->Release();
}
else
{
CComQIPtr<ILRUCachedObject> pobj(punk);
pobj->put_Cache(this);
// Just keep one ref count (from QueryInterface() above) for both pointers.
m_mapIdUnk[id] = punk;
m_mapUnkId[punk] = id;
}
Unlock();
return hr;
}
long get_ID(IUnknown *pobj)
{
long id = 0;
Lock();
CComPtr<IUnknown> punk;
pobj->QueryInterface(__uuidof(IUnknown), (void **) &punk);
t_mapUnkId::iterator it = m_mapUnkId.find(punk);
if (it != m_mapUnkId.end())
id = (*it).second;
Unlock();
return id;
}
IUnknown * get_Unknown(long idObj)
{
CComPtr<IUnknown> punk;
Lock();
t_mapIdUnk::iterator it = m_mapIdUnk.find(idObj);
if (it != m_mapIdUnk.end())
punk = ((*it).second);
Unlock();
return punk.Detach();
}
void Uncache(IUnknown *punk)
{
Lock();
t_mapUnkId::iterator it = m_mapUnkId.find(punk);
if (it != m_mapUnkId.end())
{
long idObj = ((*it).second);
t_mapIdUnk::iterator it2 = m_mapIdUnk.find(idObj);
if (it2 != m_mapIdUnk.end())
m_mapIdUnk.erase(it2);
m_mapUnkId.erase(it);
RemoveFromCache(punk);
// Just one Release for both maps because only one ref count is held
// for all references from the cache.
punk->Release();
}
Unlock();
}
void Uncache(long idObj)
{
Lock();
t_mapIdUnk::iterator it = m_mapIdUnk.find(idObj);
if (it != m_mapIdUnk.end())
{
IUnknown *punk = ((*it).second);
t_mapUnkId::iterator it2 = m_mapUnkId.find(punk);
if (it2 != m_mapUnkId.end())
m_mapUnkId.erase(it2);
m_mapIdUnk.erase(it);
RemoveFromCache(punk);
// Just one Release for both maps because only one ref count is held
// for all references from the cache.
punk->Release();
}
Unlock();
}
void Keep(long cKeep)
{
m_cKeep = cKeep;
if (m_cKeep >= 0)
{
long cPurge = m_listCache.size() - m_cKeep;
while (cPurge-- > 0)
{
Uncache(m_listCache.back());
}
}
}
// ILRUCache interface
virtual void Lock()
{
_Lock();
}
virtual void Unlock()
{
_Unlock();
}
virtual void AddToCache(IUnknown *punk)
{
// if m_cKeep < 0 then keep infinite
// if m_cKeep == 0 then keep none
// else keep m_cKeep
if (m_cKeep == 0)
{
// Not keeping any, so just release it.
Uncache(punk);
}
else
{
m_listCache.push_front(punk);
Keep(m_cKeep);
}
}
virtual void RemoveFromCache(IUnknown *punk)
{
t_listCache::iterator it;
it = m_listCache.begin();
while (it != m_listCache.end())
{
if (*it == punk)
{
m_listCache.erase(it);
return;
}
it++;
}
}
protected:
CComGlobalsThreadModel::AutoCriticalSection m_csCached;
t_mapIdUnk m_mapIdUnk;
t_mapUnkId m_mapUnkId;
t_listCache m_listCache;
long m_cKeep;
};
#if 0 && defined(_DEBUG)
#define NewComObject(T) _NewComObject<T>(THIS_FILE, __LINE__)
template<class T>
T * _NewComObject(LPCSTR lpszFileName, int nLine)
{
T* pT = NULL;
try
{
pT = new(lpszFileName, nLine) CComObject<T>;
}
catch (CMemoryException *pe)
{
pe->Delete();
}
return pT;
}
#define NewComObjectCachedLRU(T) _NewComObjectCachedLRU<T>(THIS_FILE, __LINE__)
template<class T>
T * _NewComObjectCachedLRU(LPCSTR lpszFileName, int nLine)
{
CComObjectCachedLRU<T> *pT = NULL;
try
{
pT = new(lpszFileName, nLine) CComObjectCachedLRU<T>();
}
catch (CMemoryException *pe)
{
pe->Delete();
}
return pT;
}
#else
#define NewComObject(T) _NewComObject<T>()
template<class T>
T * _NewComObject()
{
CComObject<T> *pT = NULL;
HRESULT hr = CComObject<T>::CreateInstance(&pT);
return pT;
}
#define NewComObjectCachedLRU(T) _NewComObjectCachedLRU<T>()
template<class T>
T * _NewComObjectCachedLRU()
{
CComObjectCachedLRU<T> *pT = NULL;
HRESULT hr = CComObjectCachedLRU<T>::CreateInstance(&pT);
return pT;
}
#endif
#if 0
#define new DEBUG_NEW
#endif
template<class T> class MemCmpLess // : binary_function<T, T, bool>
{
public:
bool operator()(const T & _X, const T & _Y) const
{
return (memcmp(&_X, &_Y, sizeof(T)) < 0);
}
};
class BSTRCmpLess // : binary_function<BSTR, BSTR, bool>
{
public:
bool operator()(const BSTR & _X, const BSTR _Y) const
{
return (wcscmp(_X, _Y) < 0);
}
};
#define TRACE AtlTrace
#define TIMING 0
#include "timing.h"
#include "valid.h"
#include <mstvgs.h>
#include "_GuideStore.h"
#define LIBID_GUIDESTORELib LIBID_MSTVGS //UNDONE when cpp files that ref this are fixed.
#endif // !defined(AFX_STDAFX_H__B7E9C4D4_B8E5_48DE_A578_B75F8096FB42__INCLUDED)