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.

445 lines
13 KiB

  1. #include "stdinc.h"
  2. #include "util.h"
  3. #include "fusionbuffer.h"
  4. #include "xmlparser.h"
  5. #include "fusionhandle.h"
  6. // deliberately no surrounding parens or trailing comma
  7. #define STRING_AND_LENGTH(x) (x), (NUMBER_OF(x) - 1)
  8. #define MAXIMUM_PROCESSOR_ARCHITECTURE_NAME_LENGTH (sizeof("Alpha64") - 1)
  9. const static struct
  10. {
  11. USHORT ProcessorArchitecture;
  12. WCHAR String[MAXIMUM_PROCESSOR_ARCHITECTURE_NAME_LENGTH+1];
  13. SIZE_T Cch;
  14. } gs_rgPAMap[] =
  15. {
  16. { PROCESSOR_ARCHITECTURE_INTEL, STRING_AND_LENGTH(L"x86") },
  17. { PROCESSOR_ARCHITECTURE_AMD64, STRING_AND_LENGTH(L"AMD64") },
  18. { PROCESSOR_ARCHITECTURE_IA64, STRING_AND_LENGTH(L"IA64") },
  19. { PROCESSOR_ARCHITECTURE_ALPHA, STRING_AND_LENGTH(L"Alpha") },
  20. { PROCESSOR_ARCHITECTURE_MIPS, STRING_AND_LENGTH(L"Mips") },
  21. { PROCESSOR_ARCHITECTURE_PPC, STRING_AND_LENGTH(L"PPC") },
  22. { PROCESSOR_ARCHITECTURE_ALPHA64, STRING_AND_LENGTH(L"Alpha64") },
  23. { PROCESSOR_ARCHITECTURE_SHX, STRING_AND_LENGTH(L"SHX") },
  24. { PROCESSOR_ARCHITECTURE_ARM, STRING_AND_LENGTH(L"ARM") },
  25. { PROCESSOR_ARCHITECTURE_MSIL, STRING_AND_LENGTH(L"MSIL") },
  26. { PROCESSOR_ARCHITECTURE_IA32_ON_WIN64, STRING_AND_LENGTH(L"WOW64") },
  27. { PROCESSOR_ARCHITECTURE_UNKNOWN, STRING_AND_LENGTH(L"Data") },
  28. };
  29. static BOOL
  30. FusionpGetLocaleInfo(
  31. LANGID LangID,
  32. CBaseStringBuffer *Buffer,
  33. LCTYPE lcType,
  34. SIZE_T *CchWritten = NULL
  35. )
  36. {
  37. LCID locale = MAKELCID(LangID, SORT_DEFAULT);
  38. CStringBufferAccessor BufferAccessor;
  39. BufferAccessor.Attach(Buffer);
  40. INT i = GetLocaleInfoW(locale, lcType, BufferAccessor.GetBufferPtr(), static_cast<INT>(BufferAccessor.GetBufferCch()));
  41. if (i != 0)
  42. {
  43. goto Exit;
  44. }
  45. if (::FusionpGetLastWin32Error() != ERROR_INSUFFICIENT_BUFFER)
  46. {
  47. goto Exit;
  48. }
  49. i = GetLocaleInfoW(locale, lcType, NULL, 0);
  50. if (i == 0)
  51. {
  52. goto Exit;
  53. }
  54. if (!Buffer->Win32ResizeBuffer(i, eDoNotPreserveBufferContents))
  55. {
  56. i = 0;
  57. goto Exit;
  58. }
  59. i = GetLocaleInfoW(locale, lcType, BufferAccessor.GetBufferPtr(), static_cast<INT>(BufferAccessor.GetBufferCch()));
  60. Exit:
  61. if (i != 0 && CchWritten != NULL)
  62. {
  63. *CchWritten = i;
  64. }
  65. return TRUE;
  66. }
  67. BOOL
  68. FusionpFormatEnglishLanguageName(
  69. LANGID LangID,
  70. CBaseStringBuffer *Buffer,
  71. SIZE_T *CchWritten
  72. )
  73. {
  74. return ::FusionpGetLocaleInfo(LangID, Buffer, LOCALE_SENGLANGUAGE, CchWritten);
  75. }
  76. BOOL
  77. FusionpParseProcessorArchitecture(
  78. PCWSTR String,
  79. SIZE_T Cch,
  80. USHORT *ProcessorArchitecture,
  81. bool &rfValid
  82. )
  83. {
  84. ULONG i;
  85. BOOL fSuccess = FALSE;
  86. rfValid = false;
  87. // We'll let ProcessorArchitecture be NULL if the caller just wants to
  88. // test whether there is a match.
  89. for (i=0; i<NUMBER_OF(gs_rgPAMap); i++)
  90. {
  91. if (::FusionpCompareStrings(
  92. gs_rgPAMap[i].String,
  93. gs_rgPAMap[i].Cch,
  94. String,
  95. Cch,
  96. true) == 0)
  97. {
  98. if (ProcessorArchitecture != NULL)
  99. *ProcessorArchitecture = gs_rgPAMap[i].ProcessorArchitecture;
  100. break;
  101. }
  102. }
  103. if (i != NUMBER_OF(gs_rgPAMap))
  104. rfValid = true;
  105. fSuccess = TRUE;
  106. // Exit:
  107. return fSuccess;
  108. }
  109. /*
  110. BOOL
  111. FusionpFormatLocalizedLanguageName(
  112. LANGID LangID,
  113. CBaseStringBuffer *Buffer,
  114. SIZE_T *CchWritten
  115. )
  116. {
  117. LOCALE_SNATIVELANGNAME -- I think this is the one want, the language's name in its own language
  118. LOCALE_SLANGUAGE -- I think this is the language's name in the language of the installed OS
  119. return SxspFormatLanguageName(LangID, Buffer, ?);
  120. }
  121. */
  122. BOOL
  123. FusionpFormatProcessorArchitecture(
  124. USHORT ProcessorArchitecture,
  125. CBaseStringBuffer &rBuffer
  126. )
  127. {
  128. BOOL fSuccess = FALSE;
  129. FN_TRACE_WIN32(fSuccess);
  130. ULONG i;
  131. for (i=0; i<NUMBER_OF(gs_rgPAMap); i++)
  132. {
  133. if (gs_rgPAMap[i].ProcessorArchitecture == ProcessorArchitecture)
  134. break;
  135. }
  136. PARAMETER_CHECK(i != NUMBER_OF(gs_rgPAMap));
  137. IFW32FALSE_EXIT(rBuffer.Win32Assign(gs_rgPAMap[i].String, gs_rgPAMap[i].Cch));
  138. fSuccess = TRUE;
  139. Exit:
  140. return fSuccess;
  141. }
  142. DWORD
  143. FusionpHRESULTToWin32(
  144. HRESULT hr
  145. )
  146. {
  147. DWORD dwWin32ErrorCode = ERROR_INTERNAL_ERROR;
  148. if ((HRESULT_FACILITY(hr) != FACILITY_WIN32) &&
  149. (FAILED(hr)))
  150. {
  151. switch (hr)
  152. {
  153. default:
  154. break;
  155. #define X(x,y) case x: hr = HRESULT_FROM_WIN32(y); break;
  156. X(E_UNEXPECTED, ERROR_INTERNAL_ERROR)
  157. X(E_FAIL, ERROR_FUNCTION_FAILED)
  158. X(STG_E_PATHNOTFOUND, ERROR_PATH_NOT_FOUND)
  159. X(STG_E_FILENOTFOUND, ERROR_FILE_NOT_FOUND)
  160. X(STG_E_ACCESSDENIED, ERROR_ACCESS_DENIED)
  161. X(STG_E_INVALIDHANDLE, ERROR_INVALID_HANDLE)
  162. X(STG_E_INSUFFICIENTMEMORY, ERROR_NOT_ENOUGH_MEMORY) // or ERROR_OUTOFMEMORY
  163. X(STG_E_TOOMANYOPENFILES, ERROR_TOO_MANY_OPEN_FILES)
  164. X(STG_E_NOMOREFILES, ERROR_NO_MORE_FILES)
  165. X(STG_E_WRITEFAULT, ERROR_WRITE_FAULT)
  166. X(STG_E_READFAULT, ERROR_READ_FAULT)
  167. X(STG_E_SHAREVIOLATION, ERROR_SHARING_VIOLATION)
  168. X(STG_E_LOCKVIOLATION, ERROR_LOCK_VIOLATION)
  169. X(STG_E_INVALIDPARAMETER, ERROR_INVALID_PARAMETER)
  170. X(STG_E_MEDIUMFULL, ERROR_DISK_FULL) // or ERROR_HANDLE_DISK_FULL
  171. // There's more, but I doubt we really need most of this.
  172. #undef X
  173. }
  174. }
  175. if ((HRESULT_FACILITY(hr) == FACILITY_WIN32) &&
  176. (FAILED(hr)))
  177. {
  178. dwWin32ErrorCode = HRESULT_CODE(hr);
  179. if (FAILED(hr) && (dwWin32ErrorCode == ERROR_SUCCESS))
  180. {
  181. dwWin32ErrorCode = ERROR_INTERNAL_ERROR;
  182. }
  183. }
  184. else
  185. {
  186. ::FusionpDbgPrintEx(
  187. FUSION_DBG_LEVEL_INFO,
  188. "SXS.DLL: " __FUNCTION__ " HRESULT 0x%08x - facility is not Win32; setting to ERROR_SXS_UNTRANSLATABLE_HRESULT\n",
  189. hr);
  190. dwWin32ErrorCode = ERROR_SXS_UNTRANSLATABLE_HRESULT;
  191. }
  192. return dwWin32ErrorCode;
  193. }
  194. VOID
  195. FusionpSetLastErrorFromHRESULT(
  196. HRESULT hr
  197. )
  198. {
  199. ::SetLastError(::FusionpHRESULTToWin32(hr));
  200. }
  201. VOID
  202. FusionpConvertCOMFailure(HRESULT & __hr)
  203. {
  204. /*
  205. XML_E_PARSEERRORBASE = 0xC00CE500L,
  206. // character level error codes.
  207. XML_E_ENDOFINPUT = XML_E_PARSEERRORBASE,
  208. XML_E_MISSINGEQUALS, // 1
  209. XML_E_MISSINGQUOTE, // 2
  210. XML_E_COMMENTSYNTAX, // 3
  211. XML_E_BADSTARTNAMECHAR, // 4
  212. XML_E_BADNAMECHAR, // 5
  213. XML_E_BADCHARINSTRING, // 6
  214. // under 256
  215. */
  216. if ((__hr & XML_E_PARSEERRORBASE) == XML_E_PARSEERRORBASE)
  217. {
  218. //
  219. // for normal XML ERROR,we convert hresult to a better-understanding hresult
  220. // xiaoyuw@01/08/2001
  221. //
  222. #define MAP_XML_HRESULT(x) case(x) : dwWin32Error = ERROR_SXS_## x; break
  223. DWORD dwWin32Error;
  224. switch (__hr)
  225. {
  226. MAP_XML_HRESULT(XML_E_MISSINGEQUALS);
  227. MAP_XML_HRESULT(XML_E_MISSINGQUOTE);
  228. MAP_XML_HRESULT(XML_E_COMMENTSYNTAX);
  229. MAP_XML_HRESULT(XML_E_BADSTARTNAMECHAR);
  230. MAP_XML_HRESULT(XML_E_BADNAMECHAR);
  231. MAP_XML_HRESULT(XML_E_BADCHARINSTRING);
  232. MAP_XML_HRESULT(XML_E_XMLDECLSYNTAX);
  233. MAP_XML_HRESULT(XML_E_BADCHARDATA);
  234. MAP_XML_HRESULT(XML_E_MISSINGWHITESPACE);
  235. MAP_XML_HRESULT(XML_E_EXPECTINGTAGEND);
  236. MAP_XML_HRESULT(XML_E_MISSINGSEMICOLON);
  237. MAP_XML_HRESULT(XML_E_UNBALANCEDPAREN);
  238. MAP_XML_HRESULT(XML_E_INTERNALERROR);
  239. MAP_XML_HRESULT(XML_E_UNEXPECTED_WHITESPACE);
  240. MAP_XML_HRESULT(XML_E_INCOMPLETE_ENCODING);
  241. MAP_XML_HRESULT(XML_E_MISSING_PAREN);
  242. MAP_XML_HRESULT(XML_E_EXPECTINGCLOSEQUOTE);
  243. MAP_XML_HRESULT(XML_E_MULTIPLE_COLONS);
  244. MAP_XML_HRESULT(XML_E_INVALID_DECIMAL);
  245. MAP_XML_HRESULT(XML_E_INVALID_HEXIDECIMAL);
  246. MAP_XML_HRESULT(XML_E_INVALID_UNICODE);
  247. MAP_XML_HRESULT(XML_E_WHITESPACEORQUESTIONMARK);
  248. MAP_XML_HRESULT(XML_E_UNEXPECTEDENDTAG);
  249. MAP_XML_HRESULT(XML_E_UNCLOSEDTAG);
  250. MAP_XML_HRESULT(XML_E_DUPLICATEATTRIBUTE);
  251. MAP_XML_HRESULT(XML_E_MULTIPLEROOTS);
  252. MAP_XML_HRESULT(XML_E_INVALIDATROOTLEVEL);
  253. MAP_XML_HRESULT(XML_E_BADXMLDECL);
  254. MAP_XML_HRESULT(XML_E_MISSINGROOT);
  255. MAP_XML_HRESULT(XML_E_UNEXPECTEDEOF);
  256. MAP_XML_HRESULT(XML_E_BADPEREFINSUBSET);
  257. MAP_XML_HRESULT(XML_E_UNCLOSEDSTARTTAG);
  258. MAP_XML_HRESULT(XML_E_UNCLOSEDENDTAG);
  259. MAP_XML_HRESULT(XML_E_UNCLOSEDSTRING);
  260. MAP_XML_HRESULT(XML_E_UNCLOSEDCOMMENT);
  261. MAP_XML_HRESULT(XML_E_UNCLOSEDDECL);
  262. MAP_XML_HRESULT(XML_E_UNCLOSEDCDATA);
  263. MAP_XML_HRESULT(XML_E_RESERVEDNAMESPACE);
  264. MAP_XML_HRESULT(XML_E_INVALIDENCODING);
  265. MAP_XML_HRESULT(XML_E_INVALIDSWITCH);
  266. MAP_XML_HRESULT(XML_E_BADXMLCASE);
  267. MAP_XML_HRESULT(XML_E_INVALID_STANDALONE);
  268. MAP_XML_HRESULT(XML_E_UNEXPECTED_STANDALONE);
  269. MAP_XML_HRESULT(XML_E_INVALID_VERSION);
  270. default:
  271. dwWin32Error=(ERROR_SXS_MANIFEST_PARSE_ERROR);
  272. break;
  273. } // end of switch
  274. __hr = HRESULT_FROM_WIN32(dwWin32Error);
  275. } //end of if
  276. return;
  277. }
  278. BOOL
  279. FusionpGetActivationContextFromFindResult(
  280. PCACTCTX_SECTION_KEYED_DATA askd,
  281. HANDLE * phActCtx
  282. )
  283. {
  284. FN_PROLOG_WIN32;
  285. HANDLE hActCtx = NULL;
  286. if (phActCtx != NULL)
  287. *phActCtx = NULL;
  288. PARAMETER_CHECK(askd != NULL);
  289. PARAMETER_CHECK(phActCtx != NULL);
  290. PARAMETER_CHECK(RTL_CONTAINS_FIELD(askd, askd->cbSize, hActCtx));
  291. PARAMETER_CHECK(RTL_CONTAINS_FIELD(askd, askd->cbSize, ulFlags));
  292. hActCtx = askd->hActCtx;
  293. if (hActCtx == ACTCTX_PROCESS_DEFAULT)
  294. {
  295. switch (askd->ulFlags
  296. & (
  297. ACTIVATION_CONTEXT_SECTION_KEYED_DATA_FLAG_FOUND_IN_PROCESS_DEFAULT
  298. | ACTIVATION_CONTEXT_SECTION_KEYED_DATA_FLAG_FOUND_IN_SYSTEM_DEFAULT
  299. ))
  300. {
  301. case ACTIVATION_CONTEXT_SECTION_KEYED_DATA_FLAG_FOUND_IN_PROCESS_DEFAULT:
  302. break;
  303. case ACTIVATION_CONTEXT_SECTION_KEYED_DATA_FLAG_FOUND_IN_SYSTEM_DEFAULT:
  304. hActCtx = ACTCTX_SYSTEM_DEFAULT;
  305. break;
  306. default:
  307. TRACE_PARAMETER_CHECK(askd->ulFlags);
  308. break;
  309. }
  310. }
  311. *phActCtx = hActCtx;
  312. FN_EPILOG;
  313. }
  314. BOOL
  315. FusionpSearchPath(
  316. ULONG ulFusionFlags,
  317. LPCWSTR lpPath,
  318. LPCWSTR lpFileName, // file name
  319. LPCWSTR lpExtension, // file extension
  320. CBaseStringBuffer & StringBuffer,
  321. SIZE_T * lpFilePartOffset, // file component
  322. HANDLE hActCtx
  323. )
  324. {
  325. FN_PROLOG_WIN32;
  326. ULONG_PTR ulActCookie = 0;
  327. PWSTR lpFilePart = NULL;
  328. CFusionActCtxScope ActCtxScope;
  329. if (lpFilePartOffset != NULL)
  330. *lpFilePartOffset = 0;
  331. PARAMETER_CHECK((ulFusionFlags & ~(FUSIONP_SEARCH_PATH_ACTCTX)) == 0);
  332. if ((ulFusionFlags & FUSIONP_SEARCH_PATH_ACTCTX) != 0)
  333. {
  334. IFW32FALSE_EXIT(ActCtxScope.Win32Activate(hActCtx));
  335. }
  336. if (StringBuffer.GetBufferCch() == 0)
  337. IFW32FALSE_EXIT(StringBuffer.Win32ResizeBuffer(MAX_PATH, eDoNotPreserveBufferContents));
  338. for (;;)
  339. {
  340. DWORD dw = 0;
  341. {
  342. CStringBufferAccessor StringBufferAccessor(&StringBuffer);
  343. IFW32FALSE_EXIT((dw = ::SearchPathW(
  344. lpPath,
  345. lpFileName,
  346. lpExtension,
  347. StringBufferAccessor.GetBufferCchAsDWORD(),
  348. StringBufferAccessor,
  349. &lpFilePart
  350. )) != 0);
  351. if (dw < StringBuffer.GetBufferCch())
  352. {
  353. // lpFilePart equals NULL if filename ends in a slash, or somesuch..
  354. if (lpFilePartOffset != NULL && lpFilePart != NULL)
  355. {
  356. *lpFilePartOffset = (lpFilePart - static_cast<PWSTR>(StringBufferAccessor));
  357. }
  358. break;
  359. }
  360. }
  361. IFW32FALSE_EXIT(StringBuffer.Win32ResizeBuffer(dw + 1, eDoNotPreserveBufferContents));
  362. }
  363. FN_EPILOG;
  364. }
  365. BOOL
  366. FusionpGetModuleFileName(
  367. ULONG ulFusionFlags,
  368. HMODULE hmodDll,
  369. CBaseStringBuffer & StringBuffer
  370. )
  371. /* note that GetModuleFileName is an unusual truncating API,
  372. that's why we fudge the buffer size
  373. if GetModuleFileName returns buffersize - 1, it may be a truncated result
  374. */
  375. {
  376. FN_PROLOG_WIN32;
  377. PARAMETER_CHECK(ulFusionFlags == 0);
  378. if (StringBuffer.GetBufferCch() < 2)
  379. IFW32FALSE_EXIT(StringBuffer.Win32ResizeBuffer(MAX_PATH, eDoNotPreserveBufferContents));
  380. for (;;)
  381. {
  382. DWORD dw = 0;
  383. {
  384. CStringBufferAccessor StringBufferAccessor(&StringBuffer);
  385. IFW32FALSE_EXIT((dw = ::GetModuleFileNameW(
  386. hmodDll,
  387. StringBufferAccessor,
  388. StringBufferAccessor.GetBufferCchAsDWORD()
  389. )) != 0);
  390. if (dw < (StringBuffer.GetBufferCch() - 1))
  391. {
  392. break;
  393. }
  394. }
  395. /* we don't know what to grow to, so grow by a slightly big chunk */
  396. IFW32FALSE_EXIT(StringBuffer.Win32ResizeBuffer(dw + 64, eDoNotPreserveBufferContents));
  397. }
  398. FN_EPILOG;
  399. }