Source code of Windows XP (NT5)
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.

517 lines
10 KiB

  1. // stdafx.h : include file for standard system include files,
  2. // or project specific include files that are used frequently,
  3. // but are changed infrequently
  4. #if !defined(AFX_STDAFX_H__B7E9C4D4_B8E5_48DE_A578_B75F8096FB42__INCLUDED_)
  5. #define AFX_STDAFX_H__B7E9C4D4_B8E5_48DE_A578_B75F8096FB42__INCLUDED_
  6. #if _MSC_VER > 1000
  7. #pragma once
  8. #endif // _MSC_VER > 1000
  9. #define STRICT
  10. #ifndef _WIN32_WINNT
  11. #define _WIN32_WINNT 0x0400
  12. #endif
  13. #define _ATL_APARTMENT_THREADED
  14. #if 0
  15. #define _ATL_DEBUG_INTERFACES 1
  16. #endif
  17. #include <atlbase.h>
  18. //You may derive a class from CComModule and use it if you want to override
  19. //something, but do not change the name of _Module
  20. extern CComModule _Module;
  21. #include <atlcom.h>
  22. #include <comdef.h>
  23. #import "msado21.tlb" rename("EOF", "EndOfFile") raw_method_prefix("") high_method_prefix("_")
  24. #import "sqldmo.rll" raw_method_prefix("") high_method_prefix("_") rename("GetUserName", "_GetUserName")
  25. #import "msadox.dll" raw_method_prefix("") high_method_prefix("_")
  26. #include <icrsint.h>
  27. #undef END_ADO_BINDING
  28. #define END_ADO_BINDING() {0, ADODB::adEmpty, 0, 0, 0, 0, 0, 0, 0, FALSE}};\
  29. return rgADOBindingEntries;}
  30. #include <oledb.h>
  31. #include <map>
  32. #include <list>
  33. #include <vector>
  34. using namespace std;
  35. #define THIS_FILE __FILE__
  36. #define sizeofarray(a) (sizeof(a)/sizeof((a)[0]))
  37. //{{AFX_INSERT_LOCATION}}
  38. // Microsoft Visual C++ will insert additional declarations immediately before the previous line.
  39. class ILRUCache
  40. {
  41. public:
  42. virtual void Lock() = 0;
  43. virtual void Unlock() = 0;
  44. virtual void AddToCache(IUnknown *punk) = 0;
  45. virtual void RemoveFromCache(IUnknown *punk) = 0;
  46. };
  47. class DECLSPEC_UUID("321ADAAD-5334-4227-8982-585A9A3F4C02") ILRUCachedObject : public IUnknown
  48. {
  49. public:
  50. virtual HRESULT put_Cache(ILRUCache *pcache) = 0;
  51. #if 0
  52. virtual ULONG RefCount() = 0;
  53. #endif
  54. };
  55. template <class T>
  56. class CComObjectCachedLRU : public T, public ILRUCachedObject
  57. {
  58. public:
  59. CComObjectCachedLRU<T>()
  60. {
  61. m_pcache = NULL;
  62. }
  63. // Set refcount to 1 to protect destruction
  64. ~CComObjectCachedLRU()
  65. {
  66. m_dwRef = 1L;
  67. FinalRelease();
  68. #ifdef _ATL_DEBUG_INTERFACES
  69. _Module.DeleteNonAddRefThunk(_GetRawUnknown());
  70. #endif
  71. }
  72. //If InternalAddRef or InternalRelease is undefined then your class
  73. //doesn't derive from CComObjectRoot
  74. STDMETHOD_(ULONG, AddRef)()
  75. {
  76. m_csCached.Lock();
  77. ULONG l = InternalAddRef();
  78. if (m_dwRef == 2)
  79. {
  80. _Module.Lock();
  81. if (m_pcache != NULL)
  82. m_pcache->RemoveFromCache(GetControllingUnknown());
  83. }
  84. m_csCached.Unlock();
  85. return l;
  86. }
  87. STDMETHOD_(ULONG, Release)()
  88. {
  89. m_csCached.Lock();
  90. InternalRelease();
  91. ULONG l = m_dwRef;
  92. if (l > 1)
  93. {
  94. m_csCached.Unlock();
  95. return l;
  96. }
  97. if (l == 1)
  98. {
  99. if (m_pcache != NULL)
  100. {
  101. _Module.Unlock();
  102. // Can't reference any member variables after call to AddToCache()
  103. // because AddToCache() might Release() this object down to
  104. // zero refs... that would cause the object to be deleted.
  105. ILRUCache *pcache = m_pcache;
  106. pcache->Lock();
  107. m_csCached.Unlock();
  108. pcache->AddToCache(GetControllingUnknown());
  109. pcache->Unlock();
  110. }
  111. else
  112. {
  113. m_csCached.Unlock();
  114. }
  115. return l;
  116. }
  117. if (l == 0)
  118. {
  119. m_csCached.Unlock();
  120. delete this;
  121. // Return right away so member variables aren't accidently referenced.
  122. return l;
  123. }
  124. _ASSERTE(TRUE); // Should never get here.
  125. return 0;
  126. }
  127. //if _InternalQueryInterface is undefined then you forgot BEGIN_COM_MAP
  128. STDMETHOD(QueryInterface)(REFIID iid, void ** ppvObject)
  129. {
  130. HRESULT hr;
  131. hr = _InternalQueryInterface(iid, ppvObject);
  132. if (hr == E_NOINTERFACE)
  133. {
  134. if (iid == __uuidof(ILRUCachedObject))
  135. {
  136. *ppvObject = (void *)(ILRUCachedObject *)this;
  137. AddRef();
  138. hr = S_OK;
  139. }
  140. }
  141. return hr;
  142. }
  143. static HRESULT WINAPI CreateInstance(CComObjectCachedLRU<T>** pp);
  144. // ILRUCachedObject
  145. virtual HRESULT put_Cache(ILRUCache *pcache)
  146. {
  147. // NOTE: No reference count
  148. m_pcache = pcache;
  149. return S_OK;
  150. }
  151. #if 0
  152. virtual ULONG RefCount()
  153. {
  154. return m_dwRef;
  155. }
  156. #endif
  157. protected:
  158. CComGlobalsThreadModel::AutoCriticalSection m_csCached;
  159. ILRUCache *m_pcache;
  160. };
  161. template <class T>
  162. HRESULT WINAPI CComObjectCachedLRU<T>::CreateInstance(CComObjectCachedLRU<T>** pp)
  163. {
  164. ATLASSERT(pp != NULL);
  165. HRESULT hRes = E_OUTOFMEMORY;
  166. CComObjectCachedLRU<T>* p = NULL;
  167. ATLTRY(p = new CComObjectCachedLRU<T>())
  168. if (p != NULL)
  169. {
  170. p->SetVoid(NULL);
  171. p->InternalFinalConstructAddRef();
  172. hRes = p->FinalConstruct();
  173. p->InternalFinalConstructRelease();
  174. if (hRes != S_OK)
  175. {
  176. delete p;
  177. p = NULL;
  178. }
  179. }
  180. *pp = p;
  181. return hRes;
  182. }
  183. class CComObjectCacheByID : public ILRUCache
  184. {
  185. typedef map<long, IUnknown *> t_mapIdUnk;
  186. typedef map<IUnknown *, long> t_mapUnkId;
  187. typedef list<IUnknown *> t_listCache;
  188. public:
  189. CComObjectCacheByID(long cKeep)
  190. {
  191. m_cKeep = cKeep;
  192. }
  193. void _Lock()
  194. {
  195. m_csCached.Lock();
  196. }
  197. void _Unlock()
  198. {
  199. m_csCached.Unlock();
  200. }
  201. long Count()
  202. {
  203. return m_mapIdUnk.size();
  204. }
  205. IUnknown * Item(long i)
  206. {
  207. t_mapIdUnk::iterator it;
  208. it = m_mapIdUnk.begin();
  209. while (i--)
  210. it++;
  211. if (it == m_mapIdUnk.end())
  212. return NULL;
  213. IUnknown *punk = ((*it).second);
  214. // If it is in the cache then return NULL
  215. t_listCache::iterator it2;
  216. it2 = m_listCache.begin();
  217. while (it2 != m_listCache.end())
  218. {
  219. if (*it2 == punk)
  220. return NULL;
  221. it2++;
  222. }
  223. punk->AddRef();
  224. return punk;
  225. }
  226. long CachedCount()
  227. {
  228. return m_listCache.size();
  229. }
  230. HRESULT Cache(long id, IUnknown *punk)
  231. {
  232. HRESULT hr = S_OK;
  233. Lock();
  234. // Need the canonical IUnknown
  235. punk->QueryInterface(__uuidof(IUnknown), (void **) &punk);
  236. t_mapIdUnk::iterator it = m_mapIdUnk.find(id);
  237. if (it != m_mapIdUnk.end())
  238. {
  239. // If it is already there... just return...
  240. hr = (punk == ((*it).second)) ? S_FALSE : E_INVALIDARG;
  241. // ... but don't forget to release the ref count
  242. // from the above QueryInterface() call.
  243. punk->Release();
  244. }
  245. else
  246. {
  247. CComQIPtr<ILRUCachedObject> pobj(punk);
  248. pobj->put_Cache(this);
  249. // Just keep one ref count (from QueryInterface() above) for both pointers.
  250. m_mapIdUnk[id] = punk;
  251. m_mapUnkId[punk] = id;
  252. }
  253. Unlock();
  254. return hr;
  255. }
  256. long get_ID(IUnknown *pobj)
  257. {
  258. long id = 0;
  259. Lock();
  260. CComPtr<IUnknown> punk;
  261. pobj->QueryInterface(__uuidof(IUnknown), (void **) &punk);
  262. t_mapUnkId::iterator it = m_mapUnkId.find(punk);
  263. if (it != m_mapUnkId.end())
  264. id = (*it).second;
  265. Unlock();
  266. return id;
  267. }
  268. IUnknown * get_Unknown(long idObj)
  269. {
  270. CComPtr<IUnknown> punk;
  271. Lock();
  272. t_mapIdUnk::iterator it = m_mapIdUnk.find(idObj);
  273. if (it != m_mapIdUnk.end())
  274. punk = ((*it).second);
  275. Unlock();
  276. return punk.Detach();
  277. }
  278. void Uncache(IUnknown *punk)
  279. {
  280. Lock();
  281. t_mapUnkId::iterator it = m_mapUnkId.find(punk);
  282. if (it != m_mapUnkId.end())
  283. {
  284. long idObj = ((*it).second);
  285. t_mapIdUnk::iterator it2 = m_mapIdUnk.find(idObj);
  286. if (it2 != m_mapIdUnk.end())
  287. m_mapIdUnk.erase(it2);
  288. m_mapUnkId.erase(it);
  289. RemoveFromCache(punk);
  290. // Just one Release for both maps because only one ref count is held
  291. // for all references from the cache.
  292. punk->Release();
  293. }
  294. Unlock();
  295. }
  296. void Uncache(long idObj)
  297. {
  298. Lock();
  299. t_mapIdUnk::iterator it = m_mapIdUnk.find(idObj);
  300. if (it != m_mapIdUnk.end())
  301. {
  302. IUnknown *punk = ((*it).second);
  303. t_mapUnkId::iterator it2 = m_mapUnkId.find(punk);
  304. if (it2 != m_mapUnkId.end())
  305. m_mapUnkId.erase(it2);
  306. m_mapIdUnk.erase(it);
  307. RemoveFromCache(punk);
  308. // Just one Release for both maps because only one ref count is held
  309. // for all references from the cache.
  310. punk->Release();
  311. }
  312. Unlock();
  313. }
  314. void Keep(long cKeep)
  315. {
  316. m_cKeep = cKeep;
  317. if (m_cKeep >= 0)
  318. {
  319. long cPurge = m_listCache.size() - m_cKeep;
  320. while (cPurge-- > 0)
  321. {
  322. Uncache(m_listCache.back());
  323. }
  324. }
  325. }
  326. // ILRUCache interface
  327. virtual void Lock()
  328. {
  329. _Lock();
  330. }
  331. virtual void Unlock()
  332. {
  333. _Unlock();
  334. }
  335. virtual void AddToCache(IUnknown *punk)
  336. {
  337. // if m_cKeep < 0 then keep infinite
  338. // if m_cKeep == 0 then keep none
  339. // else keep m_cKeep
  340. if (m_cKeep == 0)
  341. {
  342. // Not keeping any, so just release it.
  343. Uncache(punk);
  344. }
  345. else
  346. {
  347. m_listCache.push_front(punk);
  348. Keep(m_cKeep);
  349. }
  350. }
  351. virtual void RemoveFromCache(IUnknown *punk)
  352. {
  353. t_listCache::iterator it;
  354. it = m_listCache.begin();
  355. while (it != m_listCache.end())
  356. {
  357. if (*it == punk)
  358. {
  359. m_listCache.erase(it);
  360. return;
  361. }
  362. it++;
  363. }
  364. }
  365. protected:
  366. CComGlobalsThreadModel::AutoCriticalSection m_csCached;
  367. t_mapIdUnk m_mapIdUnk;
  368. t_mapUnkId m_mapUnkId;
  369. t_listCache m_listCache;
  370. long m_cKeep;
  371. };
  372. #if 0 && defined(_DEBUG)
  373. #define NewComObject(T) _NewComObject<T>(THIS_FILE, __LINE__)
  374. template<class T>
  375. T * _NewComObject(LPCSTR lpszFileName, int nLine)
  376. {
  377. T* pT = NULL;
  378. try
  379. {
  380. pT = new(lpszFileName, nLine) CComObject<T>;
  381. }
  382. catch (CMemoryException *pe)
  383. {
  384. pe->Delete();
  385. }
  386. return pT;
  387. }
  388. #define NewComObjectCachedLRU(T) _NewComObjectCachedLRU<T>(THIS_FILE, __LINE__)
  389. template<class T>
  390. T * _NewComObjectCachedLRU(LPCSTR lpszFileName, int nLine)
  391. {
  392. CComObjectCachedLRU<T> *pT = NULL;
  393. try
  394. {
  395. pT = new(lpszFileName, nLine) CComObjectCachedLRU<T>();
  396. }
  397. catch (CMemoryException *pe)
  398. {
  399. pe->Delete();
  400. }
  401. return pT;
  402. }
  403. #else
  404. #define NewComObject(T) _NewComObject<T>()
  405. template<class T>
  406. T * _NewComObject()
  407. {
  408. CComObject<T> *pT = NULL;
  409. HRESULT hr = CComObject<T>::CreateInstance(&pT);
  410. return pT;
  411. }
  412. #define NewComObjectCachedLRU(T) _NewComObjectCachedLRU<T>()
  413. template<class T>
  414. T * _NewComObjectCachedLRU()
  415. {
  416. CComObjectCachedLRU<T> *pT = NULL;
  417. HRESULT hr = CComObjectCachedLRU<T>::CreateInstance(&pT);
  418. return pT;
  419. }
  420. #endif
  421. #if 0
  422. #define new DEBUG_NEW
  423. #endif
  424. template<class T> class MemCmpLess // : binary_function<T, T, bool>
  425. {
  426. public:
  427. bool operator()(const T & _X, const T & _Y) const
  428. {
  429. return (memcmp(&_X, &_Y, sizeof(T)) < 0);
  430. }
  431. };
  432. class BSTRCmpLess // : binary_function<BSTR, BSTR, bool>
  433. {
  434. public:
  435. bool operator()(const BSTR & _X, const BSTR _Y) const
  436. {
  437. return (wcscmp(_X, _Y) < 0);
  438. }
  439. };
  440. #define TRACE AtlTrace
  441. #define TIMING 0
  442. #include "timing.h"
  443. #include "valid.h"
  444. #include <mstvgs.h>
  445. #include "_GuideStore.h"
  446. #define LIBID_GUIDESTORELib LIBID_MSTVGS //UNDONE when cpp files that ref this are fixed.
  447. #endif // !defined(AFX_STDAFX_H__B7E9C4D4_B8E5_48DE_A578_B75F8096FB42__INCLUDED)