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.

418 lines
13 KiB

  1. // w32extend.h - win32 helpers
  2. // copyright (c) Microsoft Corp. 1998
  3. #pragma once
  4. #ifndef W32EXTEND_H
  5. #define W32EXTEND_H
  6. #include <guiddef.h>
  7. #include <ocidl.h>
  8. #include <urlmon.h>
  9. #if defined(DEBUG) || defined(W32_OBJECT_STREAMING)
  10. #include <atlconv.h>
  11. #endif
  12. using namespace ::ATL;
  13. #include <atltmp.h>
  14. #include <trace.h>
  15. #include <throw.h>
  16. // build a class to override the standard GUID in basetyps.h
  17. // in order to put them into STL containers and dump them to debug
  18. class GUID2 : public GUID {
  19. private:
  20. void init(const LPCOLESTR guid) {
  21. OLECHAR temp[42]; // max guid string size
  22. HRESULT hr = StringCchCopyW(temp, SIZEOF_CH(temp), guid);
  23. if (FAILED(hr)) {
  24. memset(this, 0, sizeof(GUID));
  25. THROWCOM(hr);
  26. }
  27. hr = CLSIDFromString(temp, this);
  28. if (FAILED(hr)) {
  29. memset(this, 0, sizeof(GUID));
  30. THROWCOM(hr);
  31. }
  32. }
  33. public:
  34. inline GUID2() : GUID(GUID_NULL) {}
  35. inline GUID2(const GUID2 &g) : GUID(g) {}
  36. inline GUID2(const struct _GUID &g) : GUID(g) {}
  37. inline GUID2(const struct _GUID *g) : GUID(*g) {}
  38. inline GUID2(const BSTR guid) {
  39. if (!guid || !SysStringLen(guid)) {
  40. memset(this, 0, sizeof(GUID));
  41. } else {
  42. init(guid);
  43. }
  44. }
  45. inline GUID2(const LPCOLESTR guid) {
  46. if (!guid || !ocslen(guid)) {
  47. memset(this, 0, sizeof(GUID));
  48. } else {
  49. init(guid);
  50. }
  51. }
  52. // operators
  53. GUID2 & operator=(const BSTR guid) {
  54. if (!guid || !SysStringLen(guid)) {
  55. memset(this, 0, sizeof(GUID));
  56. } else {
  57. init(guid);
  58. }
  59. return *this;
  60. }
  61. GUID2& operator=(const LPCOLESTR guid) {
  62. if (!guid || !ocslen(guid)) {
  63. memset(this, 0, sizeof(GUID));
  64. } else {
  65. init(guid);
  66. }
  67. }
  68. GUID2 & operator=(const GUID2 &g) {
  69. if (&g != this) {
  70. ASSERT(sizeof(*this) == sizeof(struct _GUID));
  71. memcpy(this, &g, sizeof(GUID2));
  72. }
  73. return *this;
  74. }
  75. GUID2 & operator=(const struct _GUID &g) {
  76. if (&g != this) {
  77. ASSERT(sizeof(*this) == sizeof(g));
  78. memcpy(this, &g, min(sizeof(GUID2), sizeof(GUID)));
  79. }
  80. return *this;
  81. }
  82. BSTR GetBSTR() const {
  83. OLECHAR guidstr[(((sizeof(_GUID) * 2/* bin to char*/) + 1/*str null term*/) * 2/*ansi to unicode*/)];
  84. int rc = StringFromGUID2(*this, guidstr, sizeof(guidstr)/sizeof(OLECHAR));
  85. ASSERT(rc);
  86. return SysAllocString(guidstr);
  87. }
  88. #if defined(DEBUG) || defined(W32_OBJECT_STREAMING)
  89. void inline Dump(tostream &dc) const {
  90. BSTR guidstr(GetBSTR());
  91. USES_CONVERSION;
  92. dc << OLE2T(guidstr);
  93. ::SysFreeString(guidstr);
  94. return;
  95. }
  96. #endif
  97. bool inline operator<(const GUID2 &op2) const {
  98. if (memcmp(this, &op2, sizeof(GUID2)) < 0) {
  99. return true;
  100. }
  101. return false;
  102. }
  103. bool inline operator>(const GUID2 &op2) const {
  104. if (memcmp(this, &op2, sizeof(GUID2)) > 0) {
  105. return true;
  106. }
  107. return false;
  108. }
  109. bool inline operator==(const GUID2 &op2) const {
  110. if (!memcmp(this, &op2, sizeof(GUID2))) {
  111. return true;
  112. }
  113. return false;
  114. }
  115. bool inline operator!=(const GUID2 &op2) const {
  116. if (memcmp(this, &op2, sizeof(GUID2))) {
  117. return true;
  118. }
  119. return false;
  120. }
  121. bool inline operator<(const GUID &op2) const {
  122. if (memcmp(this, &op2, sizeof(GUID)) < 0) {
  123. return true;
  124. }
  125. return false;
  126. }
  127. bool inline operator>(const GUID &op2) const {
  128. if (memcmp(this, &op2, sizeof(GUID)) > 0) {
  129. return true;
  130. }
  131. return false;
  132. }
  133. bool inline operator==(const GUID &op2) const {
  134. if (!memcmp(this, &op2, sizeof(GUID))) {
  135. return true;
  136. }
  137. return false;
  138. }
  139. bool inline operator!=(const GUID &op2) const {
  140. if (memcmp(this, &op2, sizeof(GUID))) {
  141. return true;
  142. }
  143. return false;
  144. }
  145. };
  146. typedef CComPtr<IUnknown> PUnknown;
  147. #if defined(DEBUG) || defined(W32_OBJECT_STREAMING)
  148. inline tostream &operator<<(tostream &dc, const GUID2 &g)
  149. {
  150. g.Dump(dc);
  151. return dc;
  152. }
  153. inline tostream &operator<<(tostream &dc, const GUID &g)
  154. {
  155. GUID2 g2(g);
  156. g2.Dump(dc);
  157. return dc;
  158. }
  159. inline tostream &operator<<(tostream &dc, const RECT& r)
  160. {
  161. dc << "T(" << r.top <<
  162. ") L(" << r.left <<
  163. ") B(" << r.bottom <<
  164. ") R(" << r.right <<
  165. ") W(" << (r.right - r.left) <<
  166. ") H(" << (r.bottom - r.top) << ")";
  167. return dc;
  168. }
  169. inline tostream &operator<<(tostream &dc, const SIZE& s)
  170. {
  171. dc << "X(" << s.cx << ") Y(" << s.cy << ")";
  172. return dc;
  173. }
  174. #if 0
  175. inline tostream &operator<<(tostream &dc, ULONGLONG &ul) {
  176. TCHAR buf[128];
  177. _stprintf(buf, "%I64X", ul);
  178. dc << buf;
  179. return dc;
  180. }
  181. #endif
  182. inline tostream &operator<<(tostream &dc, const VARIANT &v)
  183. {
  184. USES_CONVERSION;
  185. switch (v.vt) {
  186. case VT_UI4:
  187. dc << _T("VT_UI4: ") << v.ulVal;
  188. break;
  189. case VT_UI8: {
  190. dc << _T("VT_UI8: ");
  191. TCHAR buf[128];
  192. _ui64tot(v.ullVal, buf, 16);
  193. dc << buf;
  194. } break;
  195. case VT_BSTR:
  196. dc << _T("VT_BSTR: ") << OLE2T(v.bstrVal);
  197. break;
  198. case VT_UNKNOWN:
  199. dc << _T("VT_UNKNOWN: ") << v.punkVal;
  200. break;
  201. case VT_DISPATCH:
  202. dc << _T("VT_DISPATCH: ") << v.pdispVal;
  203. break;
  204. case VT_UI1 | VT_ARRAY:
  205. dc << _T("VT_UI1 | VT_ARRAY: blob");
  206. break;
  207. default:
  208. dc << std::endl << "cant dump variant. vt = " << (int)v.vt << std::endl;
  209. }
  210. return dc;
  211. }
  212. #endif
  213. inline bool operator!(const VARIANT &v) {
  214. return v.vt == VT_EMPTY || v.vt == VT_NULL;
  215. }
  216. // provide an operator form and work around the fact that VarCmp
  217. // only supports unsigned ints of size 1
  218. inline bool operator==(const VARIANT &lhs, const VARIANT &rhs) {
  219. HRESULT hrc = VarCmp(const_cast<VARIANT*>(&lhs),
  220. const_cast<VARIANT*>(&rhs),
  221. LOCALE_USER_DEFAULT,
  222. 0);
  223. if (hrc == DISP_E_BADVARTYPE) {
  224. // check for types VarCmp doesn't support that we need to support
  225. // coerce unsigned to next largest signed if possible and then
  226. // fall back to VarCmp for lowest risk way to get most identical
  227. // behavior
  228. // for UI8 which is max compiler supports we'll do the compare
  229. // ourselves using the compiler support
  230. switch (lhs.vt) {
  231. case VT_UI2: {
  232. VARIANT v;
  233. VariantInit(&v);
  234. hrc = VariantChangeTypeEx(&v, const_cast<VARIANT *>(&lhs), LOCALE_USER_DEFAULT, 0, VT_I4);
  235. if (SUCCEEDED(hrc)) {
  236. return operator==(v, rhs);
  237. }
  238. } break;
  239. case VT_UI4: {
  240. VARIANT v;
  241. VariantInit(&v);
  242. hrc = VariantChangeTypeEx(&v, const_cast<VARIANT *>(&lhs), LOCALE_USER_DEFAULT, 0, VT_I8);
  243. if (SUCCEEDED(hrc)) {
  244. return operator==(v, rhs);
  245. }
  246. } break;
  247. case VT_UI8: {
  248. if (rhs.vt == VT_UI8) {
  249. return lhs.ullVal == rhs.ullVal;
  250. }
  251. VARIANT v;
  252. VariantInit(&v);
  253. hrc = VariantChangeTypeEx(&v, const_cast<VARIANT *>(&rhs), LOCALE_USER_DEFAULT, 0, VT_UI8);
  254. if (SUCCEEDED(hrc)) {
  255. return operator==(lhs, v);
  256. }
  257. } break;
  258. default: {
  259. // the problem is either lhs of some type we can't help with
  260. // or its the rhs. so we'll check the rhs...
  261. switch(rhs.vt) {
  262. case VT_UI2: {
  263. VARIANT v;
  264. VariantInit(&v);
  265. hrc = VariantChangeTypeEx(&v, const_cast<VARIANT *>(&rhs), LOCALE_USER_DEFAULT, 0, VT_I4);
  266. if (SUCCEEDED(hrc)) {
  267. return operator==(lhs, v);
  268. }
  269. } break;
  270. case VT_UI4: {
  271. VARIANT v;
  272. VariantInit(&v);
  273. hrc = VariantChangeTypeEx(&v, const_cast<VARIANT *>(&rhs), LOCALE_USER_DEFAULT, 0, VT_I8);
  274. if (SUCCEEDED(hrc)) {
  275. return operator==(lhs, v);
  276. }
  277. } break;
  278. case VT_UI8: {
  279. if (lhs.vt == VT_UI8) {
  280. return lhs.ullVal == rhs.ullVal;
  281. }
  282. VARIANT v;
  283. VariantInit(&v);
  284. hrc = VariantChangeTypeEx(&v, const_cast<VARIANT *>(&lhs), LOCALE_USER_DEFAULT, 0, VT_UI8);
  285. if (SUCCEEDED(hrc)) {
  286. return operator==(v, rhs);
  287. }
  288. }}; //switch rhs
  289. // must be some other bad type we can't help with
  290. }}; //switch lhs
  291. }
  292. return (hrc == VARCMP_EQ);
  293. }
  294. inline bool operator!=(const VARIANT &lhs, const VARIANT &rhs) {
  295. return !operator==(lhs, rhs);
  296. }
  297. typedef CComQIPtr<IEnumVARIANT, &IID_IEnumVARIANT> PQEnumVARIANT;
  298. typedef CComPtr<IUnknown> PUnknown;
  299. typedef CComQIPtr<IPersist> PQPersist;
  300. typedef CComQIPtr<IPropertyBag, &IID_IPropertyBag> PQPropertyBag;
  301. typedef CComQIPtr<IPropertyBag2> PQPropertyBag2;
  302. typedef CComQIPtr<IPersistPropertyBag> PQPersistPropertyBag;
  303. typedef CComQIPtr<IPersistPropertyBag2> PQPersistPropertyBag2;
  304. typedef CComQIPtr<IMoniker, &IID_IMoniker> PQMoniker;
  305. typedef CComQIPtr<IBindCtx> PQBindCtx;
  306. typedef CComQIPtr<IServiceProvider> PQServiceProvider;
  307. typedef CComQIPtr<IGlobalInterfaceTable> PQGIT;
  308. typedef CComQIPtr<IRunningObjectTable> PQROT;
  309. typedef CComQIPtr<IOleWindow> PQOleWindow;
  310. typedef CComQIPtr<IMalloc> PQMalloc;
  311. typedef CComQIPtr<IObjectWithSite> PQObjectWithSite;
  312. typedef CComQIPtr<IConnectionPoint> PQConnectionPoint;
  313. typedef CComQIPtr<IInternetHostSecurityManager> PQSecurityManager;
  314. class W32Moniker : public PQMoniker {
  315. public:
  316. inline W32Moniker() {}
  317. inline W32Moniker(const PQMoniker &a) : PQMoniker(a) {}
  318. inline W32Moniker(IMoniker *p) : PQMoniker(p) {}
  319. inline W32Moniker(IUnknown *p) : PQMoniker(p) {}
  320. inline W32Moniker(const W32Moniker &a) : PQMoniker(a) {}
  321. PQPropertyBag GetPropertyBag() const {
  322. PQPropertyBag pPropBag;
  323. HRESULT hr = (*this)->BindToStorage(0, 0, IID_IPropertyBag, reinterpret_cast<LPVOID *>(&pPropBag));
  324. if (FAILED(hr)) {
  325. TRACELSM(TRACE_ERROR, (dbgDump << "W32Moniker::GetPropertyBag() can't bind to storage hr = " << hr), "");
  326. THROWCOM(hr);
  327. }
  328. return pPropBag;
  329. }
  330. PUnknown GetObject() const {
  331. PUnknown pObj;
  332. HRESULT hr = (*this)->BindToObject(0, 0, __uuidof(IUnknown), reinterpret_cast<LPVOID *>(&pObj));
  333. if (FAILED(hr)) {
  334. TRACELSM(TRACE_ERROR, (dbgDump << "W32Moniker::GetObject() can't bind to object. hr = " << hr), "");
  335. THROWCOM(hr);
  336. }
  337. return pObj;
  338. }
  339. CString DisplayName() const {
  340. LPOLESTR lpszName;
  341. HRESULT hr = (*this)->GetDisplayName(NULL, NULL, &lpszName);
  342. if (FAILED(hr)) {
  343. return CString();
  344. }
  345. CString rc(lpszName);
  346. CoTaskMemFree(lpszName);
  347. return rc;
  348. }
  349. };
  350. inline HRESULT IsSafeZone(DWORD dwZone) {
  351. switch (dwZone) {
  352. case URLZONE_LOCAL_MACHINE:
  353. case URLZONE_INTRANET:
  354. case URLZONE_TRUSTED:
  355. // the fixed list of zones we trust
  356. return NOERROR;
  357. default:
  358. // everything else is untrusted
  359. return E_FAIL;
  360. }
  361. }
  362. inline HRESULT IsSafeSite(IUnknown* pSite) {
  363. PQServiceProvider psp(pSite);
  364. if (!psp) {
  365. // no service provider interface on the site implies that we're not running in IE
  366. // so by defn running local and trusted thus we return OK
  367. return NOERROR;
  368. }
  369. PQSecurityManager pManager;
  370. HRESULT hr = psp->QueryService(SID_SInternetHostSecurityManager, IID_IInternetHostSecurityManager, (LPVOID *)&pManager);
  371. if (FAILED(hr)) {
  372. // no security manager interface on the site's service provider implies that we're not
  373. // running in IE, so by defn running local and trusted thus we return OK
  374. return NOERROR;
  375. }
  376. const int MAXZONE = MAX_SIZE_SECURITY_ID+6/*scheme*/+4/*zone(dword)*/+1/*wildcard*/+1/*trailing null*/;
  377. char pbSecurityId[MAXZONE];
  378. DWORD pcbSecurityId = sizeof(pbSecurityId);
  379. ZeroMemory(pbSecurityId, sizeof(pbSecurityId));
  380. hr = pManager->GetSecurityId(reinterpret_cast<BYTE*>(pbSecurityId), &pcbSecurityId, NULL);
  381. if(FAILED(hr)){
  382. // security manager not working(unexpected). but, the site tried to provide one. thus we
  383. // must assume untrusted content and fail
  384. return E_FAIL;
  385. }
  386. char *pbEnd = pbSecurityId + pcbSecurityId - 1;
  387. if (*pbEnd == '*') { //ignore the optional wildcard flag
  388. pbEnd--;
  389. }
  390. pbEnd -= 3; // point to beginning of little endian zone dword
  391. DWORD dwZone = *(reinterpret_cast<long *>(pbEnd));
  392. return IsSafeZone(dwZone);
  393. }
  394. typedef CComQIPtr<IDispatch, &IID_IDispatch> PQDispatch;
  395. #endif // w32extend.h