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.

302 lines
7.1 KiB

  1. #ifndef _OBJECT_SAFE_IMPL_H_
  2. #define _OBJECT_SAFE_IMPL_H_
  3. #include <atlcom.h>
  4. #include <atlwin.h>
  5. #include <atlctl.h>
  6. /*++
  7. Copyright (c) 1999 Microsoft Corporation
  8. Module Name:
  9. ObjectSafeImpl.h
  10. Abstract:
  11. base class for object safety. basic implementation for IObjectSafety
  12. derive your control from this class if the control is safe for scripting
  13. on all the interfaces it exposes
  14. if you want to delegate IObjectSafety requests to the IObjectSafety
  15. interface of the aggrefate that supports the interface requested,
  16. have your derived class implement QIOnAggregate()
  17. --*/
  18. class CObjectSafeImpl : public IObjectSafety
  19. {
  20. public:
  21. CObjectSafeImpl()
  22. :m_dwSafety(0)
  23. {}
  24. //
  25. // we support INTERFACESAFE_FOR_UNTRUSTED_CALLER and INTERFACESAFE_FOR_UNTRUSTED_DATA
  26. //
  27. enum { SUPPORTED_SAFETY_OPTIONS =
  28. INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA };
  29. STDMETHOD(SetInterfaceSafetyOptions)(REFIID riid, DWORD dwOptionSetMask, DWORD dwEnabledOptions)
  30. {
  31. IUnknown *pNonDelegatingUnknown = NULL;
  32. //
  33. // any options requested that we do not support?
  34. //
  35. if ( (~SUPPORTED_SAFETY_OPTIONS & dwOptionSetMask) != 0 )
  36. {
  37. return E_FAIL;
  38. }
  39. //
  40. // Is the interface exposed by one of the aggregated objects?
  41. //
  42. HRESULT hr = QIOnAggregates(riid, &pNonDelegatingUnknown);
  43. if (SUCCEEDED(hr))
  44. {
  45. //
  46. // get IObjectSafety on non delegating unknown of the aggregated object
  47. //
  48. IObjectSafety *pAggrObjectSafety = NULL;
  49. hr = pNonDelegatingUnknown->QueryInterface(IID_IObjectSafety, (void**)&pAggrObjectSafety);
  50. pNonDelegatingUnknown->Release();
  51. pNonDelegatingUnknown = NULL;
  52. if (SUCCEEDED(hr))
  53. {
  54. //
  55. // the aggregate exposes IObjectSafety. use it to set the new
  56. // safety options
  57. //
  58. hr = pAggrObjectSafety->SetInterfaceSafetyOptions(riid,
  59. dwOptionSetMask,
  60. dwEnabledOptions);
  61. pAggrObjectSafety->Release();
  62. pAggrObjectSafety = NULL;
  63. }
  64. }
  65. else
  66. {
  67. //
  68. // the interface requested is not requested by the object's
  69. // aggregates. see if the interface is supported at all
  70. //
  71. hr = InterfaceSupported(riid);
  72. if (SUCCEEDED(hr))
  73. {
  74. //
  75. // the object supports the interface. Set safety options.
  76. //
  77. s_CritSection.Lock();
  78. //
  79. // set the bits specified by the mask to the values specified by the values
  80. //
  81. m_dwSafety = (dwEnabledOptions & dwOptionSetMask) |
  82. (m_dwSafety & ~dwOptionSetMask);
  83. s_CritSection.Unlock();
  84. }
  85. }
  86. return hr;
  87. }
  88. STDMETHOD(GetInterfaceSafetyOptions)(REFIID riid, DWORD *pdwSupportedOptions, DWORD *pdwEnabledOptions)
  89. {
  90. //
  91. // check caller's pointers
  92. //
  93. if ( IsBadWritePtr(pdwSupportedOptions, sizeof(DWORD)) ||
  94. IsBadWritePtr(pdwEnabledOptions, sizeof(DWORD)) )
  95. {
  96. return E_POINTER;
  97. }
  98. //
  99. // if we fail, at least return something meaningful.
  100. //
  101. *pdwSupportedOptions = 0;
  102. *pdwEnabledOptions = 0;
  103. IUnknown *pNonDelegatingUnknown = NULL;
  104. //
  105. // Is the interface exposed by one of the aggregated objects?
  106. //
  107. HRESULT hr = QIOnAggregates(riid, &pNonDelegatingUnknown);
  108. if (SUCCEEDED(hr))
  109. {
  110. //
  111. // get IObjectSafety on non delegating unknown of the aggregated object
  112. //
  113. IObjectSafety *pAggrObjectSafety = NULL;
  114. hr = pNonDelegatingUnknown->QueryInterface(IID_IObjectSafety, (void**)&pAggrObjectSafety);
  115. pNonDelegatingUnknown->Release();
  116. pNonDelegatingUnknown = NULL;
  117. if (SUCCEEDED(hr))
  118. {
  119. //
  120. // the aggregate exposes IObjectSafety. use it to get the new
  121. // safety options
  122. //
  123. hr = pAggrObjectSafety->GetInterfaceSafetyOptions(riid,
  124. pdwSupportedOptions,
  125. pdwEnabledOptions);
  126. pAggrObjectSafety->Release();
  127. pAggrObjectSafety = NULL;
  128. }
  129. }
  130. else
  131. {
  132. //
  133. // the interface requested is not requested by the object's
  134. // aggregates. see if the interface is supported at all
  135. //
  136. hr = InterfaceSupported(riid);
  137. if (SUCCEEDED(hr))
  138. {
  139. //
  140. // the object supports the interface. get options
  141. //
  142. *pdwSupportedOptions = SUPPORTED_SAFETY_OPTIONS;
  143. s_CritSection.Lock();
  144. *pdwEnabledOptions = m_dwSafety;
  145. s_CritSection.Unlock();
  146. }
  147. }
  148. return hr;
  149. }
  150. private:
  151. DWORD m_dwSafety;
  152. //
  153. // thread safety
  154. //
  155. // this interface is not likely to be a performance bottleneck,
  156. // at the same time, having one critical section per object
  157. // is wasteful. so have a static critical section
  158. //
  159. static CComAutoCriticalSection s_CritSection;
  160. protected:
  161. //
  162. // return S_OK if the interface requested is exposed
  163. // by the object
  164. //
  165. HRESULT InterfaceSupported(REFIID riid)
  166. {
  167. void *pVoid = NULL;
  168. HRESULT hr = E_FAIL;
  169. //
  170. // does the object support requested interface
  171. //
  172. hr = QueryInterface(riid, &pVoid);
  173. if (SUCCEEDED(hr))
  174. {
  175. //
  176. // don't need the interface itself, just wanted to see if
  177. // it is supported
  178. //
  179. ((IUnknown*)pVoid)->Release();
  180. }
  181. return hr;
  182. }
  183. //
  184. // Implement in the derived class if you have any aggregates
  185. //
  186. // returns the non delegating IUnknown of the first (in the order of COMMAP)
  187. // aggregate that supports the iid requested
  188. //
  189. virtual HRESULT QIOnAggregates(REFIID riid, IUnknown **ppNonDelegatingUnknown)
  190. {
  191. return E_NOINTERFACE;
  192. }
  193. };
  194. #endif // _OBJECT_SAFE_IMPL_H_