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.

393 lines
12 KiB

  1. //============================================================================
  2. // Copyright (C) Microsoft Corporation, 1996 - 1999
  3. //
  4. // File: std.h
  5. //
  6. // History:
  7. //
  8. // 03/15/97 Kenn Takara Created.
  9. //
  10. // Declarations for some common code/macros.
  11. //============================================================================
  12. #ifndef _STD_H_
  13. #define _STD_H_
  14. #if _MSC_VER >= 1000 // VC 5.0 or later
  15. #pragma once
  16. #endif
  17. #ifndef _DBGUTIL_H
  18. #include "dbgutil.h"
  19. #endif
  20. #include "malloc.h"
  21. #ifndef TFSCORE_API
  22. #define TFSCORE_API(type) __declspec( dllexport ) type FAR PASCAL
  23. #define TFSCORE_APIV(type) __declspec( dllexport ) type FAR CDECL
  24. #endif
  25. #define hrOK HRESULT(0)
  26. #define hrTrue HRESULT(0)
  27. #define hrFalse ResultFromScode(S_FALSE)
  28. #define hrFail ResultFromScode(E_FAIL)
  29. #define hrNotImpl ResultFromScode(E_NOTIMPL)
  30. #define hrNoInterface ResultFromScode(E_NOINTERFACE)
  31. #define hrNoMem ResultFromScode(E_OUTOFMEMORY)
  32. #define OffsetOf(s,m) (size_t)( (char *)&(((s *)0)->m) - (char *)0 )
  33. #define EmbeddorOf(C,m,p) ((C *)(((char *)p) - OffsetOf(C,m)))
  34. #define DimensionOf(rgx) (sizeof((rgx)) / sizeof(*(rgx)))
  35. /*!--------------------------------------------------------------------------
  36. DeclareSP, DeclareSPBasic
  37. DeclareSRG, DeclareSRGBasic
  38. DeclareSPT, DeclareSPTBasic
  39. DeclareSPM, DeclareSPMBasic
  40. These macros declare 'smart' pointers. Smart pointers behave like
  41. normal pointers with the exception that a smart pointer destructor
  42. frees the thing it is pointing at and assignment to a non-null smart
  43. pointer is not allowed.
  44. The DeclareSxx macros differ by how the generated smart pointer frees
  45. the memory:
  46. Macro Free Smart Pointer Type
  47. ====================== ============ ==================
  48. DeclareSP(TAG, Type) delete p; SPTAG
  49. DeclareSRG(TAG, Type) delete [] p; SRGTAG
  50. DeclareSPT(TAG, Type) TMemFree(p); SPTTAG
  51. DeclareSPM(TAG, Type) MMemFree(p); SPMTAG
  52. NOTE: use the 'Basic' variants (DeclareSPBasic, etc) for pointer to
  53. non-struct types (e.g. char, int, etc).
  54. Smart pointers have two methods:
  55. void SPTAG::Free()
  56. Free and then null the internally maintained pointer.
  57. Type *SPTAG::Transfer()
  58. Transfers pointer ownership to caller. The internally
  59. maintained pointer is cleared on exit.
  60. Author: GaryBu
  61. ---------------------------------------------------------------------------*/
  62. #define DeclareSP(TAG,Type) DeclareSmartPointer(SP##TAG,Type,delete m_p)
  63. #define DeclareSRG(TAG,Type) DeclareSmartPointer(SRG##TAG,Type,delete [] m_p)
  64. #define DeclareSPT(TAG,Type) DeclareSmartPointer(SPT##TAG,Type,TMemFree(m_p))
  65. #define DeclareSPM(TAG,Type) DeclareSmartPointer(SPM##TAG,Type,MMemFree(m_p))
  66. #define DeclareSPBasic(TAG,Type)\
  67. DeclareSPPrivateBasic(SP##TAG,Type, delete m_p)
  68. #define DeclareSRGBasic(TAG,Type)\
  69. DeclareSPPrivateBasic(SRG##TAG,Type, delete [] m_p)
  70. #define DeclareSPTBasic(TAG,Type)\
  71. DeclareSPPrivateBasic(SPT##TAG,Type,TMemFree(m_p))
  72. #define DeclareSPMBasic(TAG,Type)\
  73. DeclareSPPrivateBasic(SPM##TAG,Type,MMemFree(m_p))
  74. #define DeclareSPPrivateCore(klass, Type, free)\
  75. class klass \
  76. {\
  77. public:\
  78. klass() { m_p = 0; }\
  79. klass(Type *p) { m_p = p; }\
  80. ~klass() { free; }\
  81. operator Type*() const { return m_p; }\
  82. Type &operator*() const { return *m_p; }\
  83. Type &operator[](int i) const { return m_p[i]; }\
  84. Type &nth(int i) const { return m_p[i]; }\
  85. Type **operator &() { Assert(!m_p); return &m_p; }\
  86. Type *operator=(Type *p){ Assert(!m_p); return m_p = p; }\
  87. Type *Transfer() { Type *p = m_p; m_p = 0; return p; }\
  88. void Free() { free; m_p = 0; }\
  89. private:\
  90. void *operator=(const klass &);\
  91. klass(const klass &);\
  92. Type *m_p;
  93. #define DeclareSPPrivateBasic(klass, Type, free)\
  94. DeclareSPPrivateCore(klass, Type, free)\
  95. };
  96. /*!--------------------------------------------------------------------------
  97. DeclareSPBasicEx
  98. Variant of smart pointers that allows an extra member variable.
  99. The klassFree parameter lets you supply an alias for Free().
  100. An example is IPropertyAccess and StdRowEditingTable:
  101. DeclareSPPrivateBasicEx(SPIPropertyAccess,IPropertyAccess,
  102. m_pex->ReleaseContext(m_p), StdRowEditingTable, ReleaseContext)
  103. SPIPropertyAccess sppac(pstdtable);
  104. sppac = pstdtable->GetContext(0);
  105. ...use spfc...
  106. sppac.ReleaseContext();
  107. Author: KennT
  108. ---------------------------------------------------------------------------*/
  109. #define DeclareSPBasicEx(klass, Type, free, klassEx, klassFree)\
  110. DeclareSPPrivateCore(klass, Type, free)\
  111. public:\
  112. klass(klassEx *pex) \
  113. {\
  114. m_p = 0; m_pex=pex; } \
  115. void klassFree() \
  116. { Free(); } \
  117. private:\
  118. klassEx *m_pex; \
  119. };
  120. #define DeclareSmartPointer(klass, Type, free)\
  121. DeclareSPPrivateCore(klass, Type, free)\
  122. public:\
  123. Type * operator->() const { return m_p; }\
  124. };
  125. TFSCORE_API(HRESULT) HrQueryInterface(IUnknown *punk, REFIID iid, LPVOID *ppv);
  126. template <class T, const IID *piid>
  127. class ComSmartPointer
  128. {
  129. public:
  130. typedef T _PtrClass;
  131. ComSmartPointer() {p=NULL;}
  132. ~ComSmartPointer() { Release(); }
  133. // set p to NULL before releasing, this fixes a subtle bug
  134. // A has a ptr to B, B has a ptr to A
  135. // A gets told to release B
  136. // A calls spB.Release();
  137. // in spB.Release(), B gets destructed and calls spA.Release()
  138. // in spA.Release(), A gets destructed and calls spB.Release()
  139. // since the ptr in spB has not been set to NULL (which is bad
  140. // since B has already gone away).
  141. void Release() {T* pTemp = p; if (p) { p=NULL; pTemp->Release(); }}
  142. operator T*() {return (T*)p;}
  143. T& operator*() {Assert(p!=NULL); return *p; }
  144. T** operator&() { Assert(p==NULL); return &p; }
  145. T* operator->() { Assert(p!=NULL); return p; }
  146. T* operator=(T* lp){ Release(); p = lp; return p;}
  147. T* operator=(const ComSmartPointer<T,piid>& lp)
  148. {
  149. if (p)
  150. p->Release();
  151. p = lp.p;
  152. return p;
  153. }
  154. void Set(T* lp) { Release(); p = lp; if (p) p->AddRef(); }
  155. T * Transfer() { T* pTemp=p; p=NULL; return pTemp; }
  156. BOOL operator!(){return (p == NULL) ? TRUE : FALSE;}
  157. void Query(IUnknown *punk)
  158. { HrQuery(punk); }
  159. HRESULT HrQuery(IUnknown *punk)
  160. { return ::HrQueryInterface(punk, *piid, (LPVOID *) &p); }
  161. T* p;
  162. private:
  163. // These methods should NEVER get called.
  164. ComSmartPointer(T* lp);
  165. ComSmartPointer(const ComSmartPointer<T,piid>& lp);
  166. };
  167. // Interface utilities
  168. TFSCORE_API(void) SetI(IUnknown * volatile *punkL, IUnknown *punkR);
  169. TFSCORE_API(void) ReleaseI(IUnknown *punk);
  170. // Utilities for dealing with embedded classes
  171. #define DeclareEmbeddedInterface(interface, base) \
  172. class E##interface : public interface \
  173. { \
  174. public: \
  175. Declare##base##Members(IMPL) \
  176. Declare##interface##Members(IMPL) \
  177. } m_##interface; \
  178. friend class E##interface;
  179. #define ImplementEmbeddedUnknown(embeddor, interface) \
  180. STDMETHODIMP embeddor::E##interface::QueryInterface(REFIID iid,void **ppv)\
  181. { \
  182. return EmbeddorOf(embeddor,m_##interface,this)->QueryInterface(iid,ppv);\
  183. } \
  184. STDMETHODIMP_(ULONG) embeddor::E##interface::AddRef() \
  185. { \
  186. return EmbeddorOf(embeddor, m_##interface, this)->AddRef(); \
  187. } \
  188. STDMETHODIMP_(ULONG) embeddor::E##interface::Release() \
  189. { \
  190. return EmbeddorOf(embeddor, m_##interface, this)->Release(); \
  191. }
  192. #define ImplementEmbeddedUnknownNoRefCount(embeddor, interface) \
  193. STDMETHODIMP embeddor::E##interface::QueryInterface(REFIID iid,void **ppv)\
  194. { \
  195. return EmbeddorOf(embeddor,m_##interface,this)->QueryInterface(iid,ppv);\
  196. }
  197. #define EMPrologIsolated(embeddor, interface, method) \
  198. embeddor *pThis = EmbeddorOf(embeddor, m_##interface, this);
  199. #define ImplementIsolatedUnknown(embeddor, interface) \
  200. STDMETHODIMP embeddor::E##interface::QueryInterface(REFIID iid,void **ppv)\
  201. { \
  202. EMPrologIsolated(embeddor, interface, QueryInterface); \
  203. Assert(!FHrSucceeded(pThis->QueryInterface(IID_##interface, ppv))); \
  204. *ppv = 0; \
  205. if (iid == IID_IUnknown) *ppv = (IUnknown *) this; \
  206. else if (iid == IID_##interface) *ppv = (interface *) this; \
  207. else return ResultFromScode(E_NOINTERFACE); \
  208. ((IUnknown *) *ppv)->AddRef(); \
  209. return HRESULT_OK; \
  210. } \
  211. STDMETHODIMP_(ULONG) embeddor::E##interface::AddRef() \
  212. { \
  213. EMPrologIsolated(embeddor, interface, AddRef) \
  214. return 1; \
  215. } \
  216. STDMETHODIMP_(ULONG) embeddor::E##interface::Release() \
  217. { \
  218. EMPrologIsolated(embeddor, interface, Release) \
  219. return 1; \
  220. }
  221. #define InitPThis(embeddor, object)\
  222. embeddor *pThis = EmbeddorOf(embeddor, m_##object, this);\
  223. /*---------------------------------------------------------------------------
  224. Implements the controlling IUnknown interface for the inner object
  225. of an aggregation.
  226. ---------------------------------------------------------------------------*/
  227. #define IMPLEMENT_AGGREGATION_IUNKNOWN(klass) \
  228. STDMETHODIMP_(ULONG) klass::AddRef() \
  229. { \
  230. Assert(m_pUnknownOuter); \
  231. return m_pUnknownOuter->AddRef(); \
  232. } \
  233. STDMETHODIMP_(ULONG) klass::Release() \
  234. { \
  235. Assert(m_pUnknownOuter); \
  236. return m_pUnknownOuter->Release(); \
  237. } \
  238. STDMETHODIMP klass::QueryInterface(REFIID riid, LPVOID *ppv) \
  239. { \
  240. Assert(m_pUnknownOuter); \
  241. return m_pUnknownOuter->QueryInterface(riid, ppv); \
  242. } \
  243. /*---------------------------------------------------------------------------
  244. Declares the non-delegating IUnknown implementation in a class.
  245. ---------------------------------------------------------------------------*/
  246. #define DECLARE_AGGREGATION_NONDELEGATING_IUNKNOWN(klass) \
  247. class ENonDelegatingIUnknown : public IUnknown \
  248. { \
  249. public: \
  250. DeclareIUnknownMembers(IMPL) \
  251. } m_ENonDelegatingIUnknown; \
  252. friend class ENonDelegatingIUnknown; \
  253. IUnknown *m_pUnknownOuter; \
  254. /*---------------------------------------------------------------------------
  255. Implements the non-delegating IUnknown for a class.
  256. ---------------------------------------------------------------------------*/
  257. #define IMPLEMENT_AGGREGATION_NONDELEGATING_ADDREFRELEASE(klass,interface) \
  258. STDMETHODIMP_(ULONG) klass::ENonDelegatingIUnknown::AddRef() \
  259. { \
  260. InitPThis(klass, ENonDelegatingIUnknown); \
  261. return InterlockedIncrement(&(pThis->m_cRef)); \
  262. } \
  263. STDMETHODIMP_(ULONG) klass::ENonDelegatingIUnknown::Release() \
  264. { \
  265. InitPThis(klass, ENonDelegatingIUnknown); \
  266. if (0 == InterlockedDecrement(&(pThis->m_cRef))) \
  267. { \
  268. delete pThis; \
  269. return 0; \
  270. } \
  271. return pThis->m_cRef; \
  272. } \
  273. #define IMPLEMENT_AGGREGATION_NONDELEGATING_IUNKNOWN(klass,interface) \
  274. IMPLEMENT_AGGREGATION_NONDELEGATING_ADDREFRELEASE(klass,interface) \
  275. STDMETHODIMP klass::ENonDelegatingIUnknown::QueryInterface(REFIID riid, LPVOID *ppv) \
  276. { \
  277. InitPThis(klass, ENonDelegatingIUnknown); \
  278. if (ppv == NULL) \
  279. return E_INVALIDARG; \
  280. *ppv = NULL; \
  281. if (riid == IID_IUnknown) \
  282. *ppv = (IUnknown *) this; \
  283. else if (riid == IID_##interface) \
  284. *ppv = (interface *) pThis; \
  285. else \
  286. return E_NOINTERFACE; \
  287. ((IUnknown *)*ppv)->AddRef(); \
  288. return hrOK; \
  289. } \
  290. /*---------------------------------------------------------------------------
  291. Standard TRY/CATCH wrappers for the COM interfaces
  292. ---------------------------------------------------------------------------*/
  293. #define COM_PROTECT_TRY \
  294. try
  295. #define COM_PROTECT_ERROR_LABEL Error: ;\
  296. #ifdef DEBUG
  297. #define COM_PROTECT_CATCH \
  298. catch(CException *pe) \
  299. { \
  300. hr = COleException::Process(pe); \
  301. } \
  302. catch(...) \
  303. { \
  304. hr = E_FAIL; \
  305. }
  306. #else
  307. #define COM_PROTECT_CATCH \
  308. catch(CException *pe) \
  309. { \
  310. hr = COleException::Process(pe); \
  311. } \
  312. catch(...) \
  313. { \
  314. hr = E_FAIL; \
  315. }
  316. #endif
  317. /*---------------------------------------------------------------------------
  318. Some useful smart pointers
  319. ---------------------------------------------------------------------------*/
  320. DeclareSPPrivateBasic(SPSZ, TCHAR, delete[] m_p);
  321. DeclareSPPrivateBasic(SPWSZ, WCHAR, delete[] m_p);
  322. DeclareSPPrivateBasic(SPASZ, char, delete[] m_p);
  323. DeclareSPPrivateBasic(SPBYTE, BYTE, delete m_p);
  324. typedef ComSmartPointer<IUnknown, &IID_IUnknown> SPIUnknown;
  325. typedef ComSmartPointer<IStream, &IID_IStream> SPIStream;
  326. typedef ComSmartPointer<IPersistStreamInit, &IID_IPersistStreamInit> SPIPersistStreamInit;
  327. #endif // _STD_H_