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.

180 lines
5.2 KiB

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