Leaked source code of windows server 2003
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.

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