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.

304 lines
9.7 KiB

  1. #include "priv.h"
  2. #pragma hdrstop
  3. #include "objidl.h"
  4. #include "urlmon.h"
  5. #include "exdisp.h" // IWebBrowserApp
  6. #include "shlobj.h" // IShellBrowser
  7. #include "inetreg.h"
  8. #include <mlang.h>
  9. // Internal helper functions
  10. HRESULT wrap_CreateFormatEnumerator( UINT cfmtetc, FORMATETC* rgfmtetc, IEnumFORMATETC** ppenumfmtetc);
  11. HRESULT wrap_RegisterFormatEnumerator(LPBC pBC, IEnumFORMATETC *pEFetc, DWORD reserved);
  12. STDAPI common_GetAcceptLanguages(CHAR *psz, LPDWORD pcch);
  13. #define SETFMTETC(p, a) {(p)->cfFormat = (a); \
  14. (p)->dwAspect = DVASPECT_CONTENT; \
  15. (p)->lindex = -1; \
  16. (p)->tymed = TYMED_ISTREAM; \
  17. (p)->ptd = NULL;}
  18. const SA_BSTRGUID s_sstrEFM = {
  19. 38 * sizeof(WCHAR),
  20. L"{D0FCA420-D3F5-11CF-B211-00AA004AE837}"
  21. };
  22. STDAPI CreateDefaultAcceptHeaders(VARIANT* pvar, IWebBrowserApp* pdie)
  23. {
  24. IEnumFORMATETC* pEFM;
  25. HKEY hkey;
  26. HRESULT hr = S_OK;
  27. if (RegOpenKeyEx(HKEY_LOCAL_MACHINE,
  28. TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings\\Accepted Documents"),
  29. 0, KEY_READ, &hkey) == ERROR_SUCCESS)
  30. {
  31. DWORD iValue = 0;
  32. DWORD iValidEntries = 0;
  33. TCHAR szValueName[128];
  34. DWORD cchValueName = ARRAYSIZE(szValueName);
  35. DWORD dwType;
  36. // Count the types in the registry
  37. while (RegEnumValue(hkey, iValue++, szValueName, &cchValueName,
  38. NULL, &dwType, NULL, NULL)==ERROR_SUCCESS)
  39. {
  40. // purpose is to increment iValue
  41. cchValueName = ARRAYSIZE(szValueName);
  42. }
  43. // Previous loop ends +1, so no need to add +1 for CF_NULL
  44. FORMATETC *prgfmtetc = (FORMATETC *)LocalAlloc(LPTR, iValue * sizeof(FORMATETC));
  45. if (prgfmtetc)
  46. {
  47. FORMATETC *pcurfmtetc = prgfmtetc;
  48. for (DWORD nValue=0; SUCCEEDED(hr) && (nValue < (iValue -1)); nValue++)
  49. {
  50. TCHAR szFormatName[128];
  51. DWORD cchFormatName = ARRAYSIZE(szFormatName);
  52. cchValueName = ARRAYSIZE(szValueName);
  53. if (RegEnumValue(hkey, nValue, szValueName, &cchValueName, NULL,
  54. &dwType, (LPBYTE) szFormatName, &cchFormatName)==ERROR_SUCCESS)
  55. {
  56. pcurfmtetc->cfFormat = (CLIPFORMAT) RegisterClipboardFormat(szFormatName);
  57. if (pcurfmtetc->cfFormat)
  58. {
  59. SETFMTETC (pcurfmtetc, pcurfmtetc->cfFormat);
  60. pcurfmtetc++; // move to next fmtetc
  61. iValidEntries++;
  62. }
  63. else
  64. {
  65. hr = HRESULT_FROM_WIN32(GetLastError());
  66. }
  67. } // if RegEnum
  68. } // for nValue
  69. if (SUCCEEDED(hr))
  70. {
  71. // for the last pcurfmtetc, we fill in for CF_NULL
  72. // no need to do RegisterClipboardFormat("*/*")
  73. SETFMTETC(pcurfmtetc, CF_NULL);
  74. iValidEntries++;
  75. hr = wrap_CreateFormatEnumerator (iValidEntries, prgfmtetc, &pEFM);
  76. if (SUCCEEDED(hr))
  77. {
  78. ASSERT(pvar->vt == VT_EMPTY);
  79. pvar->vt = VT_UNKNOWN;
  80. pvar->punkVal = (IUnknown *)pEFM;
  81. hr = pdie->PutProperty((BSTR)s_sstrEFM.wsz, *pvar);
  82. if (FAILED(hr))
  83. {
  84. pEFM->Release(); // if we failed to pass ownership on, free EFM
  85. pvar->vt = VT_EMPTY;
  86. pvar->punkVal = NULL;
  87. }
  88. }
  89. }
  90. LocalFree (prgfmtetc);
  91. }
  92. else
  93. {
  94. hr = E_OUTOFMEMORY;
  95. }
  96. RegCloseKey(hkey);
  97. }
  98. else
  99. {
  100. DebugMsg(TF_ERROR, TEXT("RegOpenkey failed!"));
  101. hr = E_FAIL;
  102. }
  103. return hr;
  104. }
  105. STDAPI RegisterDefaultAcceptHeaders(IBindCtx* pbc, LPSHELLBROWSER psb)
  106. {
  107. IEnumFORMATETC* pEFM;
  108. IWebBrowserApp* pdie;
  109. ASSERT(pbc);
  110. ASSERT(psb);
  111. HRESULT hres = IUnknown_QueryService(psb, IID_IWebBrowserApp, IID_IWebBrowserApp, (LPVOID*)&pdie);
  112. if (SUCCEEDED(hres))
  113. {
  114. VARIANT var;
  115. hres = pdie->GetProperty((BSTR)s_sstrEFM.wsz, &var);
  116. if (SUCCEEDED(hres))
  117. {
  118. if (var.vt == VT_EMPTY)
  119. {
  120. #ifdef FULL_DEBUG
  121. DebugMsg(DM_TRACE, TEXT("RegisterDefaultAcceptHeaders var.vt == VT_EMPTY"));
  122. #endif
  123. CreateDefaultAcceptHeaders(&var, pdie);
  124. }
  125. else if (var.vt == VT_UNKNOWN)
  126. {
  127. #ifdef FULL_DEBUG
  128. DebugMsg(DM_TRACE, TEXT("RegisterDefaultAcceptHeaders var.vt == VT_UNKNOWN"));
  129. #endif
  130. hres = var.punkVal->QueryInterface(IID_IEnumFORMATETC, (LPVOID*)&pEFM);
  131. if (SUCCEEDED(hres)) {
  132. IEnumFORMATETC* pEFMClone = NULL;
  133. hres = pEFM->Clone(&pEFMClone);
  134. if (SUCCEEDED(hres)) {
  135. #ifdef FULL_DEBUG
  136. DebugMsg(DM_TRACE, TEXT("RegisterDefaultAcceptHeaders registering FormatEnum %x"), pEFMClone);
  137. #endif
  138. hres = wrap_RegisterFormatEnumerator(pbc, pEFMClone, 0);
  139. pEFMClone->Release();
  140. } else {
  141. DebugMsg(TF_ERROR, TEXT("RegisterDefaultAcceptHeaders Clone failed %x"), hres);
  142. }
  143. pEFM->Release();
  144. }
  145. }
  146. else
  147. {
  148. DebugMsg(TF_ERROR, TEXT("GetProperty() returned illegal Variant Type: %x"), var.vt);
  149. DebugMsg(TF_ERROR, TEXT("RegisterDefaultAcceptHeaders not registering FormatEnum"));
  150. }
  151. VariantClear(&var);
  152. } else {
  153. DebugMsg(TF_ERROR, TEXT("RegisterDefaultAcceptHeaders pdie->GetProperty() failed %x"), hres);
  154. }
  155. pdie->Release();
  156. } else {
  157. DebugMsg(TF_ERROR, TEXT("RegisterDefaultAcceptHeaders QueryService(ISP) failed %x"), hres);
  158. }
  159. return hres;
  160. } // RegisterDefaultAcceptHeaders
  161. STDAPI GetAcceptLanguagesA(LPSTR pszLanguages, LPDWORD pcchLanguages)
  162. {
  163. return common_GetAcceptLanguages(pszLanguages, pcchLanguages);
  164. } // GetAcceptLanguagesA
  165. STDAPI GetAcceptLanguagesW(LPWSTR pwzLanguages, LPDWORD pcchLanguages)
  166. {
  167. if (!pwzLanguages || !pcchLanguages || !*pcchLanguages)
  168. return E_FAIL;
  169. DWORD dwcchMaxOut = *pcchLanguages;
  170. LPSTR psz = (LPSTR) LocalAlloc (LPTR, dwcchMaxOut);
  171. if (!psz)
  172. return E_OUTOFMEMORY;
  173. HRESULT hr = common_GetAcceptLanguages(psz, &dwcchMaxOut);
  174. if (SUCCEEDED(hr))
  175. {
  176. *pcchLanguages = MultiByteToWideChar(CP_ACP, 0, psz, -1,
  177. pwzLanguages, *pcchLanguages - 1);
  178. pwzLanguages[*pcchLanguages] = 0;
  179. }
  180. LocalFree(psz);
  181. return hr;
  182. } // GetAcceptLanguagesW
  183. STDAPI common_GetAcceptLanguages(CHAR *psz, LPDWORD pcch)
  184. {
  185. HKEY hk;
  186. HRESULT hr = E_FAIL;
  187. if (!psz || !pcch || !*pcch)
  188. return hr;
  189. if ((RegOpenKeyEx(HKEY_CURRENT_USER, REGSTR_PATH_INTERNATIONAL, 0, KEY_READ, &hk) == ERROR_SUCCESS) && hk)
  190. {
  191. DWORD dwType;
  192. // pcch == pcb
  193. if (RegQueryValueEx(hk, REGSTR_VAL_ACCEPT_LANGUAGE, NULL, &dwType, (UCHAR *)psz, pcch) != ERROR_SUCCESS)
  194. {
  195. // When there is no AcceptLanguage key, we have to default
  196. DWORD LCID = GetUserDefaultLCID();
  197. // Use MLang for RFC1766 language name
  198. hr = LcidToRfc1766A(LCID, psz, *pcch);
  199. if (S_OK == hr)
  200. *pcch = lstrlenA(psz);
  201. else
  202. {
  203. *pcch = 0;
  204. AssertMsg(FALSE, TEXT("We should add LCID 0x%lx to MLang RFC1766 table"), LCID);
  205. }
  206. }
  207. else
  208. {
  209. hr = S_OK;
  210. if (!*psz)
  211. {
  212. // A NULL AcceptLanguage means send no A-L: header
  213. hr = S_FALSE;
  214. }
  215. }
  216. RegCloseKey (hk);
  217. }
  218. return hr;
  219. } // w_GetAcceptLanguages
  220. //
  221. // Both of these functions will be called only once per browser session - the
  222. // first time we create the FormatEnumerator. After that, we will use the one
  223. // we created, rather than needing to call these to allocate a new one.
  224. //
  225. HRESULT wrap_RegisterFormatEnumerator(LPBC pBC, IEnumFORMATETC *pEFetc, DWORD reserved)
  226. {
  227. HRESULT hr = E_FAIL;
  228. HINSTANCE hurl = LoadLibrary(TEXT("URLMON.DLL"));
  229. if (hurl)
  230. {
  231. HRESULT (*pfnRFE)(LPBC pBC, IEnumFORMATETC * pEFetc, DWORD reserved);
  232. pfnRFE = (HRESULT (*)(LPBC, IEnumFORMATETC*, DWORD))GetProcAddress (hurl, "RegisterFormatEnumerator");
  233. if (pfnRFE)
  234. {
  235. hr = pfnRFE(pBC, pEFetc, reserved);
  236. }
  237. FreeLibrary(hurl);
  238. }
  239. return hr;
  240. }
  241. HRESULT wrap_CreateFormatEnumerator(UINT cfmtetc, FORMATETC* rgfmtetc, IEnumFORMATETC** ppenumfmtetc)
  242. {
  243. HRESULT hr = E_FAIL;
  244. HINSTANCE hurl = LoadLibrary(TEXT("URLMON.DLL"));
  245. if (hurl)
  246. {
  247. HRESULT (*pfnCFE)(UINT cfmtetc, FORMATETC* rgfmtetc, IEnumFORMATETC **ppenumfmtetc);
  248. pfnCFE = (HRESULT (*)(UINT, FORMATETC*, IEnumFORMATETC **))GetProcAddress (hurl, "CreateFormatEnumerator");
  249. if (pfnCFE)
  250. {
  251. hr = pfnCFE(cfmtetc, rgfmtetc, ppenumfmtetc);
  252. }
  253. FreeLibrary(hurl);
  254. }
  255. return hr;
  256. }