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.

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