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.

1082 lines
27 KiB

  1. // This is a part of the Active Template Library.
  2. // Copyright (C) 1996-1997 Microsoft Corporation
  3. // All rights reserved.
  4. //
  5. // This source code is only intended as a supplement to the
  6. // Active Template Library Reference and related
  7. // electronic documentation provided with the library.
  8. // See these sources for detailed information regarding the
  9. // Active Template Library product.
  10. #ifndef __ATLBASE_H__
  11. #define __ATLBASE_H__
  12. #ifndef __cplusplus
  13. #error ATL requires C++ compilation (use a .cpp suffix)
  14. #endif
  15. #ifdef _UNICODE
  16. #ifndef UNICODE
  17. #define UNICODE // UNICODE is used by Windows headers
  18. #endif
  19. #endif
  20. #ifdef UNICODE
  21. #ifndef _UNICODE
  22. #define _UNICODE // _UNICODE is used by C-runtime/MFC headers
  23. #endif
  24. #endif
  25. #ifdef _DEBUG
  26. #ifndef DEBUG
  27. #define DEBUG
  28. #endif
  29. #endif
  30. // namespace and our templates don't quite work with earlier compiler
  31. // Can turn off namespace support directly, also
  32. #if _MSC_VER<1100
  33. #ifndef ATL_NO_NAMESPACE
  34. #define ATL_NO_NAMESPACE
  35. #endif
  36. #endif
  37. ///////////////////////////////////////////////////////////////////////////////
  38. // __declspec(novtable) is used on a class declaration to prevent the vtable
  39. // pointer from being initialized in the constructor and destructor for the
  40. // class. This has many benefits because the linker can now eliminate the
  41. // vtable and all the functions pointed to by the vtable. Also, the actual
  42. // constructor and destructor code are now smaller.
  43. ///////////////////////////////////////////////////////////////////////////////
  44. // This should only be used on a class that is not directly createable but is
  45. // rather only used as a base class. Additionally, the constructor and
  46. // destructor (if provided by the user) should not call anything that may cause
  47. // a virtual function call to occur back on the object.
  48. ///////////////////////////////////////////////////////////////////////////////
  49. // By default, the wizards will generate new ATL object classes with this
  50. // attribute (through the ATL_NO_VTABLE macro). This is normally safe as long
  51. // the restriction mentioned above is followed. It is always safe to remove
  52. // this macro from your class, so if in doubt, remove it.
  53. ///////////////////////////////////////////////////////////////////////////////
  54. #if _MSC_VER<1100
  55. #define ATL_NO_VTABLE
  56. #else
  57. #ifdef _ATL_DISABLE_NO_VTABLE
  58. #define ATL_NO_VTABLE
  59. #else
  60. #define ATL_NO_VTABLE __declspec(novtable)
  61. #endif
  62. #endif
  63. #ifndef _ATL_NO_PRAGMA_WARNINGS
  64. #pragma warning(disable: 4201) // nameless unions are part of C++
  65. #pragma warning(disable: 4127) // constant expression
  66. #pragma warning(disable: 4512) // can't generate assignment operator (so what?)
  67. #pragma warning(disable: 4514) // unreferenced inlines are common
  68. #pragma warning(disable: 4103) // pragma pack
  69. #pragma warning(disable: 4702) // unreachable code
  70. #pragma warning(disable: 4237) // bool
  71. #pragma warning(disable: 4710) // function couldn't be inlined
  72. #pragma warning(disable: 4355) // 'this' : used in base member initializer list
  73. #pragma warning(disable: 4097) // typedef name used as synonym for class-name
  74. #endif //!_ATL_NO_PRAGMA_WARNINGS
  75. #include <windows.h>
  76. #include <winnls.h>
  77. #include <ole2.h>
  78. #include <stddef.h>
  79. #include <tchar.h>
  80. #include <malloc.h>
  81. #ifndef _ATL_NO_DEBUG_CRT
  82. // Warning: if you define the above symbol, you will have
  83. // to provide your own definition of the _ASSERTE(x) macro
  84. // in order to compile ATL
  85. #include <crtdbg.h>
  86. #endif
  87. #ifndef ATLASSERT
  88. #define ATLASSERT(expr) _ASSERTE(expr)
  89. #endif
  90. #include <olectl.h>
  91. #include <winreg.h>
  92. #include <atliface.h>
  93. #ifndef _ATL_PACKING
  94. #define _ATL_PACKING 8
  95. #endif
  96. #pragma pack(push, _ATL_PACKING)
  97. #include <atlconv.h>
  98. #if defined(_ATL_DLL)
  99. #define ATLAPI extern "C" HRESULT __declspec(dllimport) __stdcall
  100. #define ATLAPI_(x) extern "C" __declspec(dllimport) x __stdcall
  101. #define ATLINLINE
  102. #elif defined(_ATL_DLL_IMPL)
  103. #define ATLAPI extern "C" HRESULT __declspec(dllexport) __stdcall
  104. #define ATLAPI_(x) extern "C" __declspec(dllexport) x __stdcall
  105. #define ATLINLINE
  106. #else
  107. #define ATLAPI HRESULT __stdcall
  108. #define ATLAPI_(x) x __stdcall
  109. #define ATLINLINE inline
  110. #endif
  111. #ifndef ATL_NO_NAMESPACE
  112. #ifndef _ATL_DLL_IMPL
  113. namespace ATL
  114. {
  115. #endif
  116. #endif
  117. typedef HRESULT (WINAPI _ATL_CREATORFUNC)(void* pv, REFIID riid, LPVOID* ppv);
  118. typedef HRESULT (WINAPI _ATL_CREATORARGFUNC)(void* pv, REFIID riid, LPVOID* ppv, ULONG_PTR dw);
  119. typedef HRESULT (WINAPI _ATL_MODULEFUNC)(ULONG_PTR dw);
  120. typedef LPCTSTR (WINAPI _ATL_DESCRIPTIONFUNC)();
  121. struct _ATL_OBJMAP_ENTRY
  122. {
  123. const CLSID* pclsid;
  124. HRESULT (WINAPI *pfnUpdateRegistry)(BOOL bRegister);
  125. _ATL_CREATORFUNC* pfnGetClassObject;
  126. _ATL_CREATORFUNC* pfnCreateInstance;
  127. IUnknown* pCF;
  128. DWORD dwRegister;
  129. _ATL_DESCRIPTIONFUNC* pfnGetObjectDescription;
  130. HRESULT WINAPI RevokeClassObject()
  131. {
  132. return CoRevokeClassObject(dwRegister);
  133. }
  134. HRESULT WINAPI RegisterClassObject(DWORD dwClsContext, DWORD dwFlags)
  135. {
  136. IUnknown* p = NULL;
  137. HRESULT hRes = pfnGetClassObject(pfnCreateInstance, IID_IUnknown, (LPVOID*) &p);
  138. if (SUCCEEDED(hRes))
  139. hRes = CoRegisterClassObject(*pclsid, p, dwClsContext, dwFlags, &dwRegister);
  140. if (p != NULL)
  141. p->Release();
  142. return hRes;
  143. }
  144. };
  145. struct _ATL_REGMAP_ENTRY
  146. {
  147. LPCOLESTR szKey;
  148. LPCOLESTR szData;
  149. };
  150. struct _ATL_MODULE
  151. {
  152. // Attributes
  153. public:
  154. UINT cbSize;
  155. HINSTANCE m_hInst;
  156. HINSTANCE m_hInstResource;
  157. HINSTANCE m_hInstTypeLib;
  158. _ATL_OBJMAP_ENTRY* m_pObjMap;
  159. LONG m_nLockCnt;
  160. HANDLE m_hHeap;
  161. CRITICAL_SECTION m_csTypeInfoHolder;
  162. CRITICAL_SECTION m_csWindowCreate;
  163. CRITICAL_SECTION m_csObjMap;
  164. };
  165. //This define makes debugging asserts easier.
  166. #define _ATL_SIMPLEMAPENTRY ((_ATL_CREATORARGFUNC*)1)
  167. struct _ATL_INTMAP_ENTRY
  168. {
  169. const IID* piid; // the interface id (IID)
  170. ULONG_PTR dw;
  171. _ATL_CREATORARGFUNC* pFunc; //NULL:end, 1:offset, n:ptr
  172. };
  173. /////////////////////////////////////////////////////////////////////////////
  174. // QI Support
  175. ATLAPI AtlInternalQueryInterface(void* pThis,
  176. const _ATL_INTMAP_ENTRY* pEntries, REFIID iid, void** ppvObject);
  177. /////////////////////////////////////////////////////////////////////////////
  178. // Smart Pointer helpers
  179. ATLAPI_(IUnknown*) AtlComPtrAssign(IUnknown** pp, IUnknown* lp);
  180. ATLAPI_(IUnknown*) AtlComQIPtrAssign(IUnknown** pp, IUnknown* lp, REFIID riid);
  181. /////////////////////////////////////////////////////////////////////////////
  182. // Inproc Marshaling helpers
  183. ATLAPI AtlFreeMarshalStream(IStream* pStream);
  184. ATLAPI AtlMarshalPtrInProc(IUnknown* pUnk, const IID& iid, IStream** ppStream);
  185. ATLAPI AtlUnmarshalPtr(IStream* pStream, const IID& iid, IUnknown** ppUnk);
  186. ATLAPI_(BOOL) AtlWaitWithMessageLoop(HANDLE hEvent);
  187. /////////////////////////////////////////////////////////////////////////////
  188. // Connection Point Helpers
  189. ATLAPI AtlAdvise(IUnknown* pUnkCP, IUnknown* pUnk, const IID& iid, LPDWORD pdw);
  190. ATLAPI AtlUnadvise(IUnknown* pUnkCP, const IID& iid, DWORD dw);
  191. /////////////////////////////////////////////////////////////////////////////
  192. // IDispatch Error handling
  193. ATLAPI AtlSetErrorInfo(const CLSID& clsid, LPCOLESTR lpszDesc,
  194. DWORD dwHelpID, LPCOLESTR lpszHelpFile, const IID& iid, HRESULT hRes,
  195. HINSTANCE hInst);
  196. /////////////////////////////////////////////////////////////////////////////
  197. // Module
  198. ATLAPI AtlModuleInit(_ATL_MODULE* pM, _ATL_OBJMAP_ENTRY* p, HINSTANCE h);
  199. ATLAPI AtlModuleRegisterClassObjects(_ATL_MODULE* pM, DWORD dwClsContext, DWORD dwFlags);
  200. ATLAPI AtlModuleRevokeClassObjects(_ATL_MODULE* pM);
  201. ATLAPI AtlModuleGetClassObject(_ATL_MODULE* pM, REFCLSID rclsid, REFIID riid, LPVOID* ppv);
  202. ATLAPI AtlModuleTerm(_ATL_MODULE* pM);
  203. ATLAPI AtlModuleRegisterServer(_ATL_MODULE* pM, BOOL bRegTypeLib, const CLSID* pCLSID = NULL);
  204. ATLAPI AtlModuleUnregisterServer(_ATL_MODULE* pM, const CLSID* pCLSID = NULL);
  205. ATLAPI AtlModuleUpdateRegistryFromResourceD(_ATL_MODULE*pM, LPCOLESTR lpszRes,
  206. BOOL bRegister, struct _ATL_REGMAP_ENTRY* pMapEntries, IRegistrar* pReg = NULL);
  207. ATLAPI AtlModuleRegisterTypeLib(_ATL_MODULE* pM, LPCOLESTR lpszIndex);
  208. #ifndef ATL_NO_NAMESPACE
  209. #ifndef _ATL_DLL_IMPL
  210. }; //namespace ATL
  211. #endif
  212. #endif
  213. #ifndef ATL_NO_NAMESPACE
  214. namespace ATL
  215. {
  216. #endif
  217. #if defined (_CPPUNWIND) & (defined(_ATL_EXCEPTIONS) | defined(_AFX))
  218. #define ATLTRY(x) try{x;} catch(...) {}
  219. #else
  220. #define ATLTRY(x) x;
  221. #endif
  222. #ifdef _DEBUG
  223. void _cdecl AtlTrace(LPCTSTR lpszFormat, ...);
  224. #ifndef ATLTRACE
  225. #define ATLTRACE AtlTrace
  226. #endif
  227. #define ATLTRACENOTIMPL(funcname) ATLTRACE(_T("%s not implemented.\n"), funcname); return E_NOTIMPL
  228. #else
  229. inline void _cdecl AtlTrace(LPCTSTR , ...){}
  230. #ifndef ATLTRACE
  231. #define ATLTRACE 1 ? (void)0 : AtlTrace
  232. #endif
  233. #define ATLTRACENOTIMPL(funcname) return E_NOTIMPL
  234. #endif //_DEBUG
  235. #ifndef offsetofclass
  236. #define offsetofclass(base, derived) ((ULONG_PTR)(static_cast<base*>((derived*)8))-8)
  237. #endif
  238. /////////////////////////////////////////////////////////////////////////////
  239. // Master version numbers
  240. #define _ATL 1 // Active Template Library
  241. #undef _ATL_VER
  242. #define _ATL_VER 0x0202 // Active Template Library version 2.02, VC++ SP3 release
  243. /////////////////////////////////////////////////////////////////////////////
  244. // Win32 libraries
  245. #ifndef _ATL_NO_FORCE_LIBS
  246. #pragma comment(lib, "kernel32.lib")
  247. #pragma comment(lib, "user32.lib")
  248. #pragma comment(lib, "ole32.lib")
  249. #pragma comment(lib, "oleaut32.lib")
  250. #pragma comment(lib, "olepro32.lib")
  251. #pragma comment(lib, "uuid.lib")
  252. #pragma comment(lib, "advapi32.lib")
  253. #endif // _ATL_NO_FORCE_LIBS
  254. template <class T>
  255. class CComPtr
  256. {
  257. public:
  258. typedef T _PtrClass;
  259. CComPtr() {p=NULL;}
  260. CComPtr(T* lp)
  261. {
  262. if ((p = lp) != NULL)
  263. p->AddRef();
  264. }
  265. CComPtr(const CComPtr<T>& lp)
  266. {
  267. if ((p = lp.p) != NULL)
  268. p->AddRef();
  269. }
  270. ~CComPtr() {if (p) p->Release();}
  271. void Release() {if (p) p->Release(); p=NULL;}
  272. operator T*() {return (T*)p;}
  273. T& operator*() {ATLASSERT(p!=NULL); return *p; }
  274. //The assert on operator& usually indicates a bug. If this is really
  275. //what is needed, however, take the address of the p member explicitly.
  276. T** operator&() { ATLASSERT(p==NULL); return &p; }
  277. T* operator->() { ATLASSERT(p!=NULL); return p; }
  278. T* operator=(T* lp){return (T*)AtlComPtrAssign((IUnknown**)&p, lp);}
  279. T* operator=(const CComPtr<T>& lp)
  280. {
  281. return (T*)AtlComPtrAssign((IUnknown**)&p, lp.p);
  282. }
  283. #if _MSC_VER>1020
  284. bool operator!(){return (p == NULL);}
  285. #else
  286. BOOL operator!(){return (p == NULL) ? TRUE : FALSE;}
  287. #endif
  288. T* p;
  289. };
  290. //Note: CComQIPtr<IUnknown, &IID_IUnknown> is not meaningful
  291. // Use CComPtr<IUnknown>
  292. template <class T, const IID* piid>
  293. class CComQIPtr
  294. {
  295. public:
  296. typedef T _PtrClass;
  297. CComQIPtr() {p=NULL;}
  298. CComQIPtr(T* lp)
  299. {
  300. if ((p = lp) != NULL)
  301. p->AddRef();
  302. }
  303. CComQIPtr(const CComQIPtr<T,piid>& lp)
  304. {
  305. if ((p = lp.p) != NULL)
  306. p->AddRef();
  307. }
  308. // If you get an error that this member is already defined, you are probably
  309. // using a CComQIPtr<IUnknown, &IID_IUnknown>. This is not necessary.
  310. // Use CComPtr<IUnknown>
  311. CComQIPtr(IUnknown* lp)
  312. {
  313. p=NULL;
  314. if (lp != NULL)
  315. lp->QueryInterface(*piid, (void **)&p);
  316. }
  317. ~CComQIPtr() {if (p) p->Release();}
  318. void Release() {if (p) p->Release(); p=NULL;}
  319. operator T*() {return p;}
  320. T& operator*() {ATLASSERT(p!=NULL); return *p; }
  321. //The assert on operator& usually indicates a bug. If this is really
  322. //what is needed, however, take the address of the p member explicitly.
  323. T** operator&() { ATLASSERT(p==NULL); return &p; }
  324. T* operator->() {ATLASSERT(p!=NULL); return p; }
  325. T* operator=(T* lp){return (T*)AtlComPtrAssign((IUnknown**)&p, lp);}
  326. T* operator=(const CComQIPtr<T,piid>& lp)
  327. {
  328. return (T*)AtlComPtrAssign((IUnknown**)&p, lp.p);
  329. }
  330. T* operator=(IUnknown* lp)
  331. {
  332. return (T*)AtlComQIPtrAssign((IUnknown**)&p, lp, *piid);
  333. }
  334. #if _MSC_VER>1020
  335. bool operator!(){return (p == NULL);}
  336. #else
  337. BOOL operator!(){return (p == NULL) ? TRUE : FALSE;}
  338. #endif
  339. T* p;
  340. };
  341. /////////////////////////////////////////////////////////////////////////////
  342. // CComBSTR
  343. class CComBSTR
  344. {
  345. public:
  346. BSTR m_str;
  347. CComBSTR()
  348. {
  349. m_str = NULL;
  350. }
  351. /*explicit*/ CComBSTR(int nSize, LPCOLESTR sz = NULL)
  352. {
  353. m_str = ::SysAllocStringLen(sz, nSize);
  354. }
  355. /*explicit*/ CComBSTR(LPCOLESTR pSrc)
  356. {
  357. m_str = ::SysAllocString(pSrc);
  358. }
  359. /*explicit*/ CComBSTR(const CComBSTR& src)
  360. {
  361. m_str = src.Copy();
  362. }
  363. CComBSTR& operator=(const CComBSTR& src);
  364. CComBSTR& operator=(LPCOLESTR pSrc);
  365. ~CComBSTR()
  366. {
  367. ::SysFreeString(m_str);
  368. }
  369. unsigned int Length() const
  370. {
  371. return SysStringLen(m_str);
  372. }
  373. operator BSTR() const
  374. {
  375. return m_str;
  376. }
  377. BSTR* operator&()
  378. {
  379. return &m_str;
  380. }
  381. BSTR Copy() const
  382. {
  383. return ::SysAllocStringLen(m_str, ::SysStringLen(m_str));
  384. }
  385. void Attach(BSTR src)
  386. {
  387. ATLASSERT(m_str == NULL);
  388. m_str = src;
  389. }
  390. BSTR Detach()
  391. {
  392. BSTR s = m_str;
  393. m_str = NULL;
  394. return s;
  395. }
  396. void Empty()
  397. {
  398. ::SysFreeString(m_str);
  399. m_str = NULL;
  400. }
  401. #if _MSC_VER>1020
  402. bool operator!()
  403. {
  404. return (m_str == NULL);
  405. }
  406. #else
  407. BOOL operator!()
  408. {
  409. return (m_str == NULL) ? TRUE : FALSE;
  410. }
  411. #endif
  412. void Append(const CComBSTR& bstrSrc)
  413. {
  414. Append(bstrSrc.m_str, SysStringLen(bstrSrc.m_str));
  415. }
  416. void Append(LPCOLESTR lpsz)
  417. {
  418. Append(lpsz, (int) ocslen(lpsz));
  419. }
  420. // a BSTR is just a LPCOLESTR so we need a special version to signify
  421. // that we are appending a BSTR
  422. void AppendBSTR(BSTR p)
  423. {
  424. Append(p, SysStringLen(p));
  425. }
  426. void Append(LPCOLESTR lpsz, int nLen);
  427. CComBSTR& operator+=(const CComBSTR& bstrSrc)
  428. {
  429. AppendBSTR(bstrSrc.m_str);
  430. return *this;
  431. }
  432. #ifndef OLE2ANSI
  433. /*explicit*/ CComBSTR(LPCSTR pSrc);
  434. /*explicit*/ CComBSTR(int nSize, LPCSTR sz = NULL);
  435. CComBSTR& operator=(LPCSTR pSrc);
  436. void Append(LPCSTR);
  437. #endif
  438. HRESULT WriteToStream(IStream* pStream);
  439. HRESULT ReadFromStream(IStream* pStream);
  440. };
  441. /////////////////////////////////////////////////////////////////////////////
  442. // CComVariant
  443. class CComVariant : public tagVARIANT
  444. {
  445. // Constructors
  446. public:
  447. CComVariant()
  448. {
  449. ::VariantInit(this);
  450. }
  451. ~CComVariant()
  452. {
  453. Clear();
  454. }
  455. CComVariant(const VARIANT& varSrc)
  456. {
  457. ::VariantInit(this);
  458. InternalCopy(&varSrc);
  459. }
  460. CComVariant(const CComVariant& varSrc)
  461. {
  462. ::VariantInit(this);
  463. InternalCopy(&varSrc);
  464. }
  465. CComVariant(BSTR bstrSrc)
  466. {
  467. ::VariantInit(this);
  468. *this = bstrSrc;
  469. }
  470. CComVariant(LPCOLESTR lpszSrc)
  471. {
  472. ::VariantInit(this);
  473. *this = lpszSrc;
  474. }
  475. #ifndef OLE2ANSI
  476. CComVariant(LPCSTR lpszSrc)
  477. {
  478. ::VariantInit(this);
  479. *this = lpszSrc;}
  480. #endif
  481. #if _MSC_VER>1020
  482. CComVariant(bool bSrc)
  483. {
  484. ::VariantInit(this);
  485. vt = VT_BOOL;
  486. #pragma warning(disable: 4310) // cast truncates constant value
  487. boolVal = bSrc ? VARIANT_TRUE : VARIANT_FALSE;
  488. #pragma warning(default: 4310) // cast truncates constant value
  489. }
  490. #endif
  491. CComVariant(int nSrc)
  492. {
  493. ::VariantInit(this);
  494. vt = VT_I4;
  495. lVal = nSrc;
  496. }
  497. CComVariant(BYTE nSrc)
  498. {
  499. ::VariantInit(this);
  500. vt = VT_UI1;
  501. bVal = nSrc;
  502. }
  503. CComVariant(short nSrc)
  504. {
  505. ::VariantInit(this);
  506. vt = VT_I2;
  507. iVal = nSrc;
  508. }
  509. CComVariant(long nSrc, VARTYPE vtSrc = VT_I4)
  510. {
  511. ATLASSERT(vtSrc == VT_I4 || vtSrc == VT_ERROR);
  512. ::VariantInit(this);
  513. vt = vtSrc;
  514. lVal = nSrc;
  515. }
  516. CComVariant(float fltSrc)
  517. {
  518. ::VariantInit(this);
  519. vt = VT_R4;
  520. fltVal = fltSrc;
  521. }
  522. CComVariant(double dblSrc)
  523. {
  524. ::VariantInit(this);
  525. vt = VT_R8;
  526. dblVal = dblSrc;
  527. }
  528. CComVariant(CY cySrc)
  529. {
  530. ::VariantInit(this);
  531. vt = VT_CY;
  532. cyVal.Hi = cySrc.Hi;
  533. cyVal.Lo = cySrc.Lo;
  534. }
  535. CComVariant(IDispatch* pSrc)
  536. {
  537. ::VariantInit(this);
  538. vt = VT_DISPATCH;
  539. pdispVal = pSrc;
  540. // Need to AddRef as VariantClear will Release
  541. if (pdispVal != NULL)
  542. pdispVal->AddRef();
  543. }
  544. CComVariant(IUnknown* pSrc)
  545. {
  546. ::VariantInit(this);
  547. vt = VT_UNKNOWN;
  548. punkVal = pSrc;
  549. // Need to AddRef as VariantClear will Release
  550. if (punkVal != NULL)
  551. punkVal->AddRef();
  552. }
  553. // Assignment Operators
  554. public:
  555. CComVariant& operator=(const CComVariant& varSrc)
  556. {
  557. InternalCopy(&varSrc);
  558. return *this;
  559. }
  560. CComVariant& operator=(const VARIANT& varSrc)
  561. {
  562. InternalCopy(&varSrc);
  563. return *this;
  564. }
  565. CComVariant& operator=(BSTR bstrSrc);
  566. CComVariant& operator=(LPCOLESTR lpszSrc);
  567. #ifndef OLE2ANSI
  568. CComVariant& operator=(LPCSTR lpszSrc);
  569. #endif
  570. #if _MSC_VER>1020
  571. CComVariant& operator=(bool bSrc);
  572. #endif
  573. CComVariant& operator=(int nSrc);
  574. CComVariant& operator=(BYTE nSrc);
  575. CComVariant& operator=(short nSrc);
  576. CComVariant& operator=(long nSrc);
  577. CComVariant& operator=(float fltSrc);
  578. CComVariant& operator=(double dblSrc);
  579. CComVariant& operator=(CY cySrc);
  580. CComVariant& operator=(IDispatch* pSrc);
  581. CComVariant& operator=(IUnknown* pSrc);
  582. // Comparison Operators
  583. public:
  584. #if _MSC_VER>1020
  585. bool operator==(const VARIANT& varSrc);
  586. bool operator!=(const VARIANT& varSrc) {return !operator==(varSrc);}
  587. #else
  588. BOOL operator==(const VARIANT& varSrc);
  589. BOOL operator!=(const VARIANT& varSrc) {return !operator==(varSrc);}
  590. #endif
  591. // Operations
  592. public:
  593. HRESULT Clear() { return ::VariantClear(this); }
  594. HRESULT Copy(const VARIANT* pSrc) { return ::VariantCopy(this, const_cast<VARIANT*>(pSrc)); }
  595. HRESULT Attach(VARIANT* pSrc);
  596. HRESULT Detach(VARIANT* pDest);
  597. HRESULT ChangeType(VARTYPE vtNew, const VARIANT* pSrc = NULL);
  598. HRESULT WriteToStream(IStream* pStream);
  599. HRESULT ReadFromStream(IStream* pStream);
  600. // Implementation
  601. public:
  602. HRESULT InternalClear();
  603. void InternalCopy(const VARIANT* pSrc);
  604. };
  605. /////////////////////////////////////////////////////////////////////////////
  606. // GUID comparison
  607. #if 0
  608. inline BOOL InlineIsEqualGUID(REFGUID rguid1, REFGUID rguid2)
  609. {
  610. return (
  611. ((PLONG) &rguid1)[0] == ((PLONG) &rguid2)[0] &&
  612. ((PLONG) &rguid1)[1] == ((PLONG) &rguid2)[1] &&
  613. ((PLONG) &rguid1)[2] == ((PLONG) &rguid2)[2] &&
  614. ((PLONG) &rguid1)[3] == ((PLONG) &rguid2)[3]);
  615. }
  616. #endif
  617. inline BOOL InlineIsEqualUnknown(REFGUID rguid1)
  618. {
  619. return (
  620. ((PLONG) &rguid1)[0] == 0 &&
  621. ((PLONG) &rguid1)[1] == 0 &&
  622. #ifdef _MAC
  623. ((PLONG) &rguid1)[2] == 0xC0000000 &&
  624. ((PLONG) &rguid1)[3] == 0x00000046);
  625. #else
  626. ((PLONG) &rguid1)[2] == 0x000000C0 &&
  627. ((PLONG) &rguid1)[3] == 0x46000000);
  628. #endif
  629. }
  630. /////////////////////////////////////////////////////////////////////////////
  631. // Threading Model Support
  632. class CComCriticalSection
  633. {
  634. public:
  635. void Lock() {EnterCriticalSection(&m_sec);}
  636. void Unlock() {LeaveCriticalSection(&m_sec);}
  637. void Init() {InitializeCriticalSection(&m_sec);}
  638. void Term() {DeleteCriticalSection(&m_sec);}
  639. CRITICAL_SECTION m_sec;
  640. };
  641. class CComAutoCriticalSection
  642. {
  643. public:
  644. void Lock() {EnterCriticalSection(&m_sec);}
  645. void Unlock() {LeaveCriticalSection(&m_sec);}
  646. CComAutoCriticalSection() {InitializeCriticalSection(&m_sec);}
  647. ~CComAutoCriticalSection() {DeleteCriticalSection(&m_sec);}
  648. CRITICAL_SECTION m_sec;
  649. };
  650. class CComFakeCriticalSection
  651. {
  652. public:
  653. void Lock() {}
  654. void Unlock() {}
  655. void Init() {}
  656. void Term() {}
  657. };
  658. class CComMultiThreadModelNoCS
  659. {
  660. public:
  661. static ULONG WINAPI Increment(LPLONG p) {return InterlockedIncrement(p);}
  662. static ULONG WINAPI Decrement(LPLONG p) {return InterlockedDecrement(p);}
  663. typedef CComFakeCriticalSection AutoCriticalSection;
  664. typedef CComFakeCriticalSection CriticalSection;
  665. typedef CComMultiThreadModelNoCS ThreadModelNoCS;
  666. };
  667. class CComMultiThreadModel
  668. {
  669. public:
  670. static ULONG WINAPI Increment(LPLONG p) {return InterlockedIncrement(p);}
  671. static ULONG WINAPI Decrement(LPLONG p) {return InterlockedDecrement(p);}
  672. typedef CComAutoCriticalSection AutoCriticalSection;
  673. typedef CComCriticalSection CriticalSection;
  674. typedef CComMultiThreadModelNoCS ThreadModelNoCS;
  675. };
  676. class CComSingleThreadModel
  677. {
  678. public:
  679. static ULONG WINAPI Increment(LPLONG p) {return ++(*p);}
  680. static ULONG WINAPI Decrement(LPLONG p) {return --(*p);}
  681. typedef CComFakeCriticalSection AutoCriticalSection;
  682. typedef CComFakeCriticalSection CriticalSection;
  683. typedef CComSingleThreadModel ThreadModelNoCS;
  684. };
  685. #ifndef _ATL_SINGLE_THREADED
  686. #ifndef _ATL_APARTMENT_THREADED
  687. #ifndef _ATL_FREE_THREADED
  688. #define _ATL_FREE_THREADED
  689. #endif
  690. #endif
  691. #endif
  692. #if defined(_ATL_SINGLE_THREADED)
  693. typedef CComSingleThreadModel CComObjectThreadModel;
  694. typedef CComSingleThreadModel CComGlobalsThreadModel;
  695. #elif defined(_ATL_APARTMENT_THREADED)
  696. typedef CComSingleThreadModel CComObjectThreadModel;
  697. typedef CComMultiThreadModel CComGlobalsThreadModel;
  698. #else
  699. typedef CComMultiThreadModel CComObjectThreadModel;
  700. typedef CComMultiThreadModel CComGlobalsThreadModel;
  701. #endif
  702. /////////////////////////////////////////////////////////////////////////////
  703. // CComModule
  704. #define THREADFLAGS_APARTMENT 0x1
  705. #define THREADFLAGS_BOTH 0x2
  706. #define AUTPRXFLAG 0x4
  707. struct _AtlCreateWndData
  708. {
  709. void* m_pThis;
  710. DWORD m_dwThreadID;
  711. _AtlCreateWndData* m_pNext;
  712. };
  713. class CComModule : public _ATL_MODULE
  714. {
  715. // Operations
  716. public:
  717. _AtlCreateWndData* m_pCreateWndList;
  718. void AddCreateWndData(_AtlCreateWndData* pData, void* pObject);
  719. void* ExtractCreateWndData();
  720. void Init(_ATL_OBJMAP_ENTRY* p, HINSTANCE h)
  721. {
  722. cbSize = sizeof(_ATL_MODULE);
  723. m_pCreateWndList = NULL;
  724. AtlModuleInit(this, p, h);
  725. }
  726. void Term()
  727. {
  728. AtlModuleTerm(this);
  729. }
  730. LONG Lock() {return CComGlobalsThreadModel::Increment(&m_nLockCnt);}
  731. LONG Unlock() {return CComGlobalsThreadModel::Decrement(&m_nLockCnt);}
  732. LONG GetLockCount() {return m_nLockCnt;}
  733. HINSTANCE GetModuleInstance() {return m_hInst;}
  734. HINSTANCE GetResourceInstance() {return m_hInstResource;}
  735. HINSTANCE GetTypeLibInstance() {return m_hInstTypeLib;}
  736. // Registry support (helpers)
  737. HRESULT RegisterTypeLib()
  738. {
  739. return AtlModuleRegisterTypeLib(this, NULL);
  740. }
  741. HRESULT RegisterTypeLib(LPCTSTR lpszIndex)
  742. {
  743. USES_CONVERSION;
  744. return AtlModuleRegisterTypeLib(this, T2COLE(lpszIndex));
  745. }
  746. HRESULT RegisterServer(BOOL bRegTypeLib = FALSE, const CLSID* pCLSID = NULL)
  747. {
  748. return AtlModuleRegisterServer(this, bRegTypeLib, pCLSID);
  749. }
  750. HRESULT UnregisterServer(const CLSID* pCLSID = NULL)
  751. {
  752. return AtlModuleUnregisterServer(this, pCLSID);
  753. }
  754. // Resource-based Registration
  755. HRESULT WINAPI UpdateRegistryFromResourceD(LPCTSTR lpszRes, BOOL bRegister,
  756. struct _ATL_REGMAP_ENTRY* pMapEntries = NULL)
  757. {
  758. USES_CONVERSION;
  759. return AtlModuleUpdateRegistryFromResourceD(this, T2COLE(lpszRes), bRegister,
  760. pMapEntries);
  761. }
  762. HRESULT WINAPI UpdateRegistryFromResourceD(UINT nResID, BOOL bRegister,
  763. struct _ATL_REGMAP_ENTRY* pMapEntries = NULL)
  764. {
  765. return AtlModuleUpdateRegistryFromResourceD(this,
  766. (LPCOLESTR)MAKEINTRESOURCE(nResID), bRegister, pMapEntries);
  767. }
  768. #ifdef _ATL_STATIC_REGISTRY
  769. // Statically linking to Registry Ponent
  770. HRESULT WINAPI UpdateRegistryFromResourceS(LPCTSTR lpszRes, BOOL bRegister,
  771. struct _ATL_REGMAP_ENTRY* pMapEntries = NULL);
  772. HRESULT WINAPI UpdateRegistryFromResourceS(UINT nResID, BOOL bRegister,
  773. struct _ATL_REGMAP_ENTRY* pMapEntries = NULL);
  774. #endif //_ATL_STATIC_REGISTRY
  775. // Standard Registration
  776. HRESULT WINAPI UpdateRegistryClass(const CLSID& clsid, LPCTSTR lpszProgID,
  777. LPCTSTR lpszVerIndProgID, UINT nDescID, DWORD dwFlags, BOOL bRegister);
  778. HRESULT WINAPI RegisterClassHelper(const CLSID& clsid, LPCTSTR lpszProgID,
  779. LPCTSTR lpszVerIndProgID, UINT nDescID, DWORD dwFlags);
  780. HRESULT WINAPI UnregisterClassHelper(const CLSID& clsid, LPCTSTR lpszProgID,
  781. LPCTSTR lpszVerIndProgID);
  782. // Register/Revoke All Class Factories with the OS (EXE only)
  783. HRESULT RegisterClassObjects(DWORD dwClsContext, DWORD dwFlags)
  784. {
  785. return AtlModuleRegisterClassObjects(this, dwClsContext, dwFlags);
  786. }
  787. HRESULT RevokeClassObjects()
  788. {
  789. return AtlModuleRevokeClassObjects(this);
  790. }
  791. // Obtain a Class Factory (DLL only)
  792. HRESULT GetClassObject(REFCLSID rclsid, REFIID riid, LPVOID* ppv)
  793. {
  794. return AtlModuleGetClassObject(this, rclsid, riid, ppv);
  795. }
  796. // Only used in CComAutoThreadModule
  797. HRESULT CreateInstance(void* /*pfnCreateInstance*/, REFIID /*riid*/, void** /*ppvObj*/)
  798. {
  799. return S_OK;
  800. }
  801. };
  802. /////////////////////////////////////////////////////////////////////////////////////////////
  803. // Thread Pooling classes
  804. class _AtlAptCreateObjData
  805. {
  806. public:
  807. _ATL_CREATORFUNC* pfnCreateInstance;
  808. const IID* piid;
  809. HANDLE hEvent;
  810. LPSTREAM pStream;
  811. HRESULT hRes;
  812. };
  813. class CComApartment
  814. {
  815. public:
  816. static UINT ATL_CREATE_OBJECT;
  817. static DWORD WINAPI _Apartment(void* pv)
  818. {
  819. return ((CComApartment*)pv)->Apartment();
  820. }
  821. DWORD Apartment()
  822. {
  823. CoInitialize(NULL);
  824. MSG msg;
  825. while(GetMessage(&msg, 0, 0, 0))
  826. {
  827. if (msg.message == ATL_CREATE_OBJECT)
  828. {
  829. _AtlAptCreateObjData* pdata = (_AtlAptCreateObjData*)msg.lParam;
  830. IUnknown* pUnk = NULL;
  831. pdata->hRes = pdata->pfnCreateInstance(NULL, IID_IUnknown, (void**)&pUnk);
  832. if (SUCCEEDED(pdata->hRes))
  833. pdata->hRes = CoMarshalInterThreadInterfaceInStream(*pdata->piid, pUnk, &pdata->pStream);
  834. if (SUCCEEDED(pdata->hRes))
  835. {
  836. pUnk->Release();
  837. ATLTRACE(_T("Object created on thread = %d\n"), GetCurrentThreadId());
  838. }
  839. SetEvent(pdata->hEvent);
  840. }
  841. DispatchMessage(&msg);
  842. }
  843. CoUninitialize();
  844. return 0;
  845. }
  846. LONG Lock() {return CComGlobalsThreadModel::Increment(&m_nLockCnt);}
  847. LONG Unlock(){return CComGlobalsThreadModel::Decrement(&m_nLockCnt);
  848. }
  849. LONG GetLockCount() {return m_nLockCnt;}
  850. DWORD m_dwThreadID;
  851. HANDLE m_hThread;
  852. LONG m_nLockCnt;
  853. };
  854. class CComSimpleThreadAllocator
  855. {
  856. public:
  857. CComSimpleThreadAllocator()
  858. {
  859. m_nThread = 0;
  860. }
  861. int GetThread(CComApartment* /*pApt*/, int nThreads)
  862. {
  863. if (++m_nThread == nThreads)
  864. m_nThread = 0;
  865. return m_nThread;
  866. }
  867. int m_nThread;
  868. };
  869. #if _MSC_VER>1020
  870. template <class ThreadAllocator = CComSimpleThreadAllocator>
  871. #else
  872. template <class ThreadAllocator>
  873. #endif
  874. class CComAutoThreadModule : public CComModule
  875. {
  876. public:
  877. void Init(_ATL_OBJMAP_ENTRY* p, HINSTANCE h, int nThreads = GetDefaultThreads());
  878. ~CComAutoThreadModule();
  879. HRESULT CreateInstance(void* pfnCreateInstance, REFIID riid, void** ppvObj);
  880. LONG Lock();
  881. LONG Unlock();
  882. DWORD dwThreadID;
  883. int m_nThreads;
  884. CComApartment* m_pApartments;
  885. ThreadAllocator m_Allocator;
  886. static int GetDefaultThreads()
  887. {
  888. SYSTEM_INFO si;
  889. GetSystemInfo(&si);
  890. return si.dwNumberOfProcessors * 4;
  891. }
  892. };
  893. #ifdef _ATL_STATIC_REGISTRY
  894. #define UpdateRegistryFromResource UpdateRegistryFromResourceS
  895. #else
  896. #define UpdateRegistryFromResource UpdateRegistryFromResourceD
  897. #endif
  898. /////////////////////////////////////////////////////////////////////////////
  899. // CRegKey
  900. class CRegKey
  901. {
  902. public:
  903. CRegKey();
  904. ~CRegKey();
  905. // Attributes
  906. public:
  907. operator HKEY() const;
  908. HKEY m_hKey;
  909. // Operations
  910. public:
  911. LONG SetValue(DWORD dwValue, LPCTSTR lpszValueName);
  912. LONG QueryValue(DWORD& dwValue, LPCTSTR lpszValueName);
  913. LONG QueryValue(LPTSTR szValue, LPCTSTR lpszValueName, DWORD* pdwCount);
  914. LONG SetValue(LPCTSTR lpszValue, LPCTSTR lpszValueName = NULL);
  915. LONG SetKeyValue(LPCTSTR lpszKeyName, LPCTSTR lpszValue, LPCTSTR lpszValueName = NULL);
  916. static LONG WINAPI SetValue(HKEY hKeyParent, LPCTSTR lpszKeyName,
  917. LPCTSTR lpszValue, LPCTSTR lpszValueName = NULL);
  918. LONG Create(HKEY hKeyParent, LPCTSTR lpszKeyName,
  919. LPTSTR lpszClass = REG_NONE, DWORD dwOptions = REG_OPTION_NON_VOLATILE,
  920. REGSAM samDesired = KEY_ALL_ACCESS,
  921. LPSECURITY_ATTRIBUTES lpSecAttr = NULL,
  922. LPDWORD lpdwDisposition = NULL);
  923. LONG Open(HKEY hKeyParent, LPCTSTR lpszKeyName,
  924. REGSAM samDesired = KEY_ALL_ACCESS);
  925. LONG Close();
  926. HKEY Detach();
  927. void Attach(HKEY hKey);
  928. LONG DeleteSubKey(LPCTSTR lpszSubKey);
  929. LONG RecurseDeleteKey(LPCTSTR lpszKey);
  930. LONG DeleteValue(LPCTSTR lpszValue);
  931. };
  932. inline CRegKey::CRegKey()
  933. {m_hKey = NULL;}
  934. inline CRegKey::~CRegKey()
  935. {Close();}
  936. inline CRegKey::operator HKEY() const
  937. {return m_hKey;}
  938. inline HKEY CRegKey::Detach()
  939. {
  940. HKEY hKey = m_hKey;
  941. m_hKey = NULL;
  942. return hKey;
  943. }
  944. inline void CRegKey::Attach(HKEY hKey)
  945. {
  946. ATLASSERT(m_hKey == NULL);
  947. m_hKey = hKey;
  948. }
  949. inline LONG CRegKey::DeleteSubKey(LPCTSTR lpszSubKey)
  950. {
  951. ATLASSERT(m_hKey != NULL);
  952. return RegDeleteKey(m_hKey, lpszSubKey);
  953. }
  954. inline LONG CRegKey::DeleteValue(LPCTSTR lpszValue)
  955. {
  956. ATLASSERT(m_hKey != NULL);
  957. return RegDeleteValue(m_hKey, (LPTSTR)lpszValue);
  958. }
  959. #pragma pack(pop)
  960. #ifndef ATL_NO_NAMESPACE
  961. }; //namespace ATL
  962. using namespace ATL;
  963. #endif
  964. #endif // __ATLBASE_H__
  965. /////////////////////////////////////////////////////////////////////////////