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.

188 lines
5.5 KiB

  1. #include "stock.h"
  2. #pragma hdrstop
  3. #include <comcat.h>
  4. #include <hliface.h>
  5. #include <mshtml.h>
  6. #include <objsafe.h>
  7. #include <perhist.h>
  8. #include "cobjsafe.h"
  9. // a default isafetyobject that we generally would use... marks
  10. // deals with IDispatch
  11. HRESULT CObjectSafety::GetInterfaceSafetyOptions(REFIID riid, DWORD *pdwSupportedOptions, DWORD *pdwEnabledOptions)
  12. {
  13. if (IsEqualIID(riid, IID_IDispatch))
  14. {
  15. if (pdwSupportedOptions)
  16. *pdwSupportedOptions = (INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA);
  17. *pdwEnabledOptions = _dwSafetyOptions;
  18. }
  19. else
  20. {
  21. ::DefaultGetSafetyOptions(riid, pdwSupportedOptions, pdwEnabledOptions);
  22. }
  23. return S_OK;
  24. }
  25. HRESULT CObjectSafety::SetInterfaceSafetyOptions(REFIID riid, DWORD dwOptionSetMask, DWORD dwEnabledOptions)
  26. {
  27. if (dwOptionSetMask & ~(INTERFACESAFE_FOR_UNTRUSTED_CALLER |
  28. INTERFACESAFE_FOR_UNTRUSTED_DATA))
  29. {
  30. return E_INVALIDARG;
  31. }
  32. if (IsEqualIID(riid, IID_IDispatch))
  33. {
  34. _dwSafetyOptions = (_dwSafetyOptions & ~dwOptionSetMask) |
  35. (dwEnabledOptions & dwOptionSetMask);
  36. return S_OK;
  37. }
  38. else
  39. {
  40. return ::DefaultSetSafetyOptions(riid, dwOptionSetMask, dwEnabledOptions);
  41. }
  42. }
  43. // *** IObjectSafety
  44. //
  45. // A couple static functions called by sitemap (and webbrowser).
  46. // These are static so anyone else in this dll who has an OC
  47. // that's always safe can just call them.
  48. //
  49. // These functions say we are safe for these three interfaces we implement
  50. // IID_IDispatch
  51. // IID_IPersistStream
  52. // IID_IPersistPropertyBag
  53. //
  54. // The WebBrowser OC handles IDispatch differently.
  55. //
  56. HRESULT DefaultGetSafetyOptions(REFIID riid, DWORD *pdwSupportedOptions, DWORD *pdwEnabledOptions)
  57. {
  58. *pdwSupportedOptions = 0;
  59. *pdwEnabledOptions = 0;
  60. if (IsEqualIID(riid, IID_IDispatch) ||
  61. IsEqualIID(riid, IID_IPersistStream) ||
  62. IsEqualIID(riid, IID_IPersistStreamInit) ||
  63. IsEqualIID(riid, IID_IPersistPropertyBag) ||
  64. IsEqualIID(riid, IID_IPersistHistory))
  65. {
  66. *pdwSupportedOptions = INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA;
  67. *pdwEnabledOptions = INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA;
  68. }
  69. return S_OK;
  70. }
  71. HRESULT DefaultSetSafetyOptions(REFIID riid, DWORD dwOptionSetMask, DWORD dwEnabledOptions)
  72. {
  73. if (dwOptionSetMask & ~(INTERFACESAFE_FOR_UNTRUSTED_CALLER |
  74. INTERFACESAFE_FOR_UNTRUSTED_DATA))
  75. {
  76. return E_INVALIDARG;
  77. }
  78. if (IsEqualIID(riid, IID_IDispatch) ||
  79. IsEqualIID(riid, IID_IPersistStream) ||
  80. IsEqualIID(riid, IID_IPersistStreamInit) ||
  81. IsEqualIID(riid, IID_IPersistHistory) ||
  82. IsEqualIID(riid, IID_IPersistPropertyBag))
  83. {
  84. return S_OK;
  85. }
  86. return E_FAIL;
  87. }
  88. // When CWebBrowserOC is in the safe for scripting mode, we can't give out
  89. // anyone else's IDispatch that is not also safe for scripting.
  90. // This function encapsulates the basic functionality needed by both
  91. // MakeSafeScripting and MakeSafeForInitializing (which we don't use)
  92. BOOL MakeSafeFor(
  93. IUnknown *punk, // object to test for safety
  94. REFCATID catid, // category of safety
  95. REFIID riid, // interface on which safety is desired
  96. DWORD dwXSetMask, // options to set
  97. DWORD dwXOptions // options to make safe for
  98. // (either INTERFACESAFE_FOR_UNTRUSTED_CALLER or
  99. // INTERFACESAFE_FOR_UNTRUSTED_DATA)
  100. )
  101. {
  102. HRESULT hres;
  103. // first try IObjectSafety
  104. IObjectSafety *posafe;
  105. if (SUCCEEDED(punk->QueryInterface(IID_IObjectSafety, (LPVOID*) &posafe)))
  106. {
  107. hres = posafe->SetInterfaceSafetyOptions(riid, dwXSetMask, dwXOptions);
  108. posafe->Release();
  109. if (SUCCEEDED(hres))
  110. return TRUE;
  111. }
  112. // check the registry for "safe for scripting" component category
  113. // we need the classid -- get it thru IPersist
  114. CLSID clsid;
  115. IPersist *ppersist;
  116. hres = punk->QueryInterface(IID_IPersist, (LPVOID*) &ppersist);
  117. if (SUCCEEDED(hres))
  118. {
  119. hres = ppersist->GetClassID(&clsid);
  120. ppersist->Release();
  121. }
  122. if (FAILED(hres))
  123. {
  124. // trace from shdocvw, was TF_SHDCONTROL
  125. TraceMsg(TF_WARNING, "MakeSafeForScripting - object doesn't have IPersist!");
  126. return FALSE;
  127. }
  128. // Create the category manager
  129. ICatInformation *pcatinfo;
  130. hres = CoCreateInstance(CLSID_StdComponentCategoriesMgr,
  131. NULL, CLSCTX_INPROC_SERVER,
  132. IID_ICatInformation, (LPVOID*) &pcatinfo);
  133. if (FAILED(hres))
  134. return FALSE;
  135. // Ask if the object belongs to the specified category
  136. CATID rgcatid[1];
  137. rgcatid[0] = catid;
  138. hres = pcatinfo->IsClassOfCategories(clsid, 1, rgcatid, 0, NULL);
  139. pcatinfo->Release();
  140. return (hres==S_OK) ? TRUE : FALSE;;
  141. }
  142. HRESULT MakeSafeForScripting(IUnknown** ppDisp)
  143. {
  144. HRESULT hres = S_OK;
  145. if (!MakeSafeFor(*ppDisp, CATID_SafeForScripting, IID_IDispatch,
  146. INTERFACESAFE_FOR_UNTRUSTED_CALLER,
  147. INTERFACESAFE_FOR_UNTRUSTED_CALLER))
  148. {
  149. // trace from shdocvw, was TF_SHDCONTROL
  150. TraceMsg(TF_WARNING, "MakeSafeForScripting - IDispatch not safe");
  151. (*ppDisp)->Release();
  152. *ppDisp = NULL;
  153. hres = E_FAIL;
  154. }
  155. return hres;
  156. }