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.

1415 lines
45 KiB

  1. /*++
  2. Copyright (c) 2000 Microsoft Corporation
  3. Module Name:
  4. sxsdebug.cpp
  5. Abstract:
  6. testing API for sxstest
  7. Author:
  8. Xiaoyu Wu (xiaoyuw) April 2000
  9. Revision History:
  10. --*/
  11. #include "stdinc.h"
  12. #include "xmlparser.hxx"
  13. #include "xmlparsertest.hxx"
  14. #include "sxsinstall.h"
  15. #include "sxsprotect.h"
  16. #include <sxsapi.h>
  17. #include "fusiontrace.h"
  18. #include "sxsasmname.h"
  19. #include "strongname.h"
  20. #include "cassemblyrecoveryinfo.h"
  21. #include "protectionui.h"
  22. #define CONFIG_FILE_EXTENSION L".config"
  23. BOOL TestReparsePointOnFullQualifiedPath(PCWSTR fullpath)
  24. {
  25. BOOL fSuccess = FALSE;
  26. FN_TRACE_WIN32(fSuccess);
  27. BOOL CrossesReparsePoint;
  28. SIZE_T Start = 0;
  29. if ((wcschr(fullpath, '\\') == NULL) && (wcschr(fullpath, '/') == NULL))
  30. {
  31. ::FusionpSetLastWin32Error(ERROR_INTERNAL_ERROR);
  32. goto Exit;
  33. }
  34. if (wcschr(fullpath, '\\'))
  35. {
  36. Start = (SIZE_T)(wcschr(fullpath, '\\') - fullpath);
  37. }
  38. if (wcschr(fullpath, '/') != NULL)
  39. if (Start < (ULONG(wcschr(fullpath, '/') - fullpath)))
  40. Start = wcschr(fullpath, '/') - fullpath;
  41. IFW32FALSE_EXIT(
  42. ::SxspDoesPathCrossReparsePoint(
  43. fullpath,
  44. Start,
  45. CrossesReparsePoint));
  46. fSuccess = TRUE;
  47. Exit:
  48. return fSuccess;
  49. }
  50. HRESULT TestDeleteInstalledAssemblyBasedOnAssemblyName()
  51. {
  52. HRESULT hr = S_OK;
  53. FN_TRACE_HR(hr);
  54. /* PCWSTR manifest_files[] = {L"Z:\\tests\\footest\\cdfiles\\cards_chn\\cards.manifest",
  55. L"Z:\\tests\\footest\\cdfiles\\cards_gen\\cards.manifest",
  56. L"Z:\\tests\\footest\\cdfiles\\cards_jan\\cards.manifest",
  57. L"Z:\\tests\\footest\\cdfiles\\cards_en\\cards.manifest",
  58. L"Z:\\tests\\footest\\cdfiles\\cards_en_us\\cards.manifest" };*/
  59. //PCWSTR manifest_files[] = { L"Z:\\tests\\footest\\cdfiles\\cards_0000\\cards.manifest" };
  60. //PCWSTR manifest_files[] = { L"Z:\\tests\\footest\\cdfiles\\policy\\policy1\\asmpol.MANIFEST" };
  61. PCWSTR manifest_files[] = { L"Z:\\tests\\footest\\cdfiles\\policy\\policy1\\asmpol.MANIFEST" };
  62. CAssemblyInstall * pInstallCookie=NULL;
  63. SXS_INSTALL_SOURCE_INFO sinfo;
  64. CStringBuffer sbTemp;
  65. const static WCHAR pwzFileName[] = L"c:\\install.logfile";
  66. //BOOL fEmpty;
  67. ZeroMemory(&sinfo, sizeof(sinfo));
  68. sinfo.cbSize = sizeof(sinfo);
  69. sinfo.pcwszLogFileName = pwzFileName;
  70. sinfo.dwFlags = SXSINSTALLSOURCE_CREATE_LOGFILE;
  71. IFW32FALSE_EXIT(::SxsBeginAssemblyInstall(0, NULL, NULL, NULL, NULL, (PVOID *)&pInstallCookie));
  72. for (DWORD i = 0; i < NUMBER_OF(manifest_files); i++)
  73. {
  74. IFW32FALSE_EXIT(::SxsInstallAssemblyW(pInstallCookie, SXS_INSTALL_ASSEMBLY_FLAG_CREATE_LOGFILE, manifest_files[i], &sinfo));
  75. }
  76. if (!SUCCEEDED(hr))
  77. {
  78. HRESULT oldHr = hr ;
  79. IFW32FALSE_EXIT(::SxsEndAssemblyInstall(pInstallCookie, SXS_END_ASSEMBLY_INSTALL_FLAG_ABORT, NULL));
  80. hr = oldHr;
  81. }else
  82. {
  83. IFW32FALSE_EXIT(::SxsEndAssemblyInstall(pInstallCookie, SXS_END_ASSEMBLY_INSTALL_FLAG_COMMIT, NULL));
  84. hr = NOERROR;
  85. }
  86. // IFW32FALSE_EXIT(::SxsUninstallAssembly(SXS_UNINSTALL_ASSEMBLY_FLAG_USING_INSTALL_LOGFILE, pwzFileName, NULL, NULL));
  87. FN_EPILOG
  88. }
  89. HRESULT TestAssemblyName()
  90. {
  91. HRESULT hr = NOERROR;
  92. FN_TRACE_HR(hr);
  93. //const WCHAR super_simple_inputstring[] = L"cards,version=\"1.0.0.0\",processorArchitecture=\"x86\",language=\"0409\",whatever=\"whatever\"";
  94. const WCHAR super_simple_inputstring[] = L"cards,version=\"1.0.0.0\",processorArchitecture=\"x86\",language=\"0409\"";
  95. //const WCHAR super_simple_inputstring[] = L"cards,,,,,";
  96. // const WCHAR simple_inputstring[] = L"ca&#x2c;r&#x2c;d&#x22;s,http://fusion:whatever=\"&#x22;&#x2c;0&#x2c;&#x22;\",http://fusion:processorarchitecture=\"x86\",http://neptune:language=\"0409\"";
  97. // const WCHAR complex_inputstring[] = L"firstcards&#x22;secondcards,http://fusion:version=\"1.0.0.0\",http://www.shuku.net/novels/prose/zxfjdsw:whatever=\"what&#x2c;ever\"";
  98. CAssemblyName * pAsmName = NULL;
  99. IAssemblyName * pIAsmName = NULL;
  100. LPWSTR szDisplayName = NULL ;
  101. ULONG ccDisplayName = 0;
  102. LPWSTR psz = NULL;
  103. CSmartRef<IAssemblyCache> pCache;
  104. CStringBuffer bufPath;
  105. PCWSTR szAssemblyStr = super_simple_inputstring;
  106. IFCOMFAILED_EXIT(::CreateAssemblyCache(&pCache, 0));
  107. // parse : convert string from Darwin to Fusion
  108. IFCOMFAILED_EXIT(::CreateAssemblyNameObject(&pIAsmName, szAssemblyStr, CANOF_PARSE_DISPLAY_NAME, NULL));
  109. pAsmName = reinterpret_cast<CAssemblyName*>(pIAsmName);
  110. ccDisplayName = static_cast<ULONG>(wcslen(szAssemblyStr));
  111. ccDisplayName ++; // for worst case
  112. szDisplayName = NEW (WCHAR[ccDisplayName]);
  113. if (!szDisplayName)
  114. goto Exit;
  115. // GetDisplayName: convert string from Fusion to Darwin
  116. IFCOMFAILED_EXIT(pAsmName->GetDisplayName(szDisplayName, &ccDisplayName, 0));
  117. //ASSERT(wcscmp(szDisplayName, szAssemblyStr) == 0);
  118. IFCOMFAILED_EXIT(pAsmName->GetInstalledAssemblyName(0, SXSP_GENERATE_SXS_PATH_PATHTYPE_ASSEMBLY, bufPath));
  119. hr = NOERROR;
  120. Exit:
  121. if (pAsmName)
  122. pAsmName->Release();
  123. delete[] szDisplayName;
  124. delete[] psz ;
  125. return hr;
  126. }
  127. BOOL
  128. SxspManifestSchemaCheck(
  129. PCWSTR parameterstring // this must be a full-qualified filename of a manifest file
  130. )
  131. {
  132. BOOL fSuccess = FALSE;
  133. FN_TRACE_WIN32(fSuccess);
  134. ACTCTXGENCTX ActCtxGenCtx;
  135. ULONG ManifestFlags;
  136. CProbedAssemblyInformation AssemblyInformation;
  137. CImpersonationData ImpersonationData;
  138. PCWSTR Slash = NULL;
  139. PASSEMBLY Asm = NULL;
  140. CStringBuffer buffManifestPath;
  141. USHORT ProcessorArchitecture = ::SxspGetSystemProcessorArchitecture();
  142. LANGID LangId = ::GetUserDefaultLangID();
  143. // BUGBUG xiaoyuw@09/17/00 : disable to set Name ans version fro mthe command line for simplicity
  144. PARAMETER_CHECK(parameterstring != NULL);
  145. IFW32FALSE_EXIT(AssemblyInformation.Initialize());
  146. IFW32FALSE_EXIT(buffManifestPath.Win32Assign(parameterstring, ::wcslen(parameterstring)));
  147. IFW32FALSE_EXIT(
  148. ::SxspInitActCtxGenCtx(
  149. &ActCtxGenCtx, // context out
  150. MANIFEST_OPERATION_VALIDATE_SYNTAX,
  151. 0,
  152. 0,
  153. ImpersonationData,
  154. ProcessorArchitecture,
  155. LangId,
  156. ACTIVATION_CONTEXT_PATH_TYPE_NONE,
  157. 0,
  158. NULL));
  159. // get manifestpath, manifestName, manifestVersion
  160. Slash = wcsrchr(buffManifestPath, L'\\');
  161. PARAMETER_CHECK(Slash != NULL);
  162. IFALLOCFAILED_EXIT(Asm = new ASSEMBLY);
  163. ManifestFlags = ASSEMBLY_MANIFEST_FILETYPE_FILE;
  164. IFW32FALSE_EXIT(AssemblyInformation.SetManifestPath(ACTIVATION_CONTEXT_PATH_TYPE_WIN32_FILE, buffManifestPath));
  165. IFW32FALSE_EXIT(AssemblyInformation.SetManifestFlags(ManifestFlags));
  166. IFW32FALSE_EXIT(AssemblyInformation.SetManifestLastWriteTime(&ActCtxGenCtx)); // using default parameter-value
  167. IFW32FALSE_EXIT(::SxspInitAssembly(Asm, AssemblyInformation));
  168. IFW32FALSE_EXIT(::SxspIncorporateAssembly(&ActCtxGenCtx, Asm));
  169. IFW32FALSE_EXIT(::SxspFireActCtxGenEnding(&ActCtxGenCtx));
  170. fSuccess = TRUE;
  171. Exit:
  172. if (Asm != NULL)
  173. Asm->Release();
  174. return fSuccess;
  175. }
  176. #if SXS_PRECOMPILED_MANIFESTS_ENABLED
  177. HRESULT
  178. GetPCMWorkingTime(PCWSTR filename, LARGE_INTEGER* pcmtime)
  179. {
  180. HRESULT hr = NOERROR;
  181. FN_TRACE_HR(hr);
  182. CStringBuffer buf ;
  183. CSmartRef<XMLParserTestFactory> factory;
  184. CSmartRef<CPrecompiledManifestReader> pPCMReader;
  185. LARGE_INTEGER timestart = {0};
  186. ULONG i = 0;
  187. ULONG j = 0;
  188. buf.Assign(filename, ::wcslen(filename));
  189. buf.Append(L".pcm", 4);
  190. factory = new XMLParserTestFactory;
  191. if (! factory) {
  192. ::FusionpDbgPrintEx(
  193. FUSION_DBG_LEVEL_INFO,
  194. "SxsDebug:: fail to new XMLParserTestFactory, out of memory\n");
  195. hr = E_OUTOFMEMORY;
  196. goto Exit;
  197. }
  198. pPCMReader = new CPrecompiledManifestReader);
  199. if (! pPCMReader) {
  200. hr = E_OUTOFMEMORY;
  201. goto Exit;
  202. }
  203. for (j=0; j<10; j++) {
  204. ::QueryPerformanceCounter(&timestart);
  205. for (i = 0 ; i < 10; i++) {
  206. hr = pPCMReader->InvokeNodeFactory(buf, factory);
  207. if (FAILED(hr))
  208. goto Exit;
  209. }
  210. ::QueryPerformanceCounter(&pcmtime[j]);
  211. pcmtime[j].QuadPart -= timestart.QuadPart;
  212. }
  213. hr = NOERROR;
  214. Exit:
  215. return hr;
  216. }
  217. #endif // SXS_PRECOMPILED_MANIFESTS_ENABLED
  218. HRESULT GetParserWorkingTime(PCWSTR filename, LARGE_INTEGER* parsertime)
  219. {
  220. HRESULT hr = S_OK;
  221. FN_TRACE_HR(hr);
  222. LARGE_INTEGER t1[10], t2[10];
  223. LARGE_INTEGER timestart;
  224. ULONG i, j;
  225. CSmartRef<IXMLParser> pIXMLParser;
  226. CSmartRef<XMLParserTestFactory> factory;
  227. CSmartRef<XMLParserTestFileStream> filestream;
  228. filestream = NEW (XMLParserTestFileStream());
  229. if (!filestream) {
  230. ::FusionpDbgPrintEx(
  231. FUSION_DBG_LEVEL_INFO,
  232. "SxsDebug:: fail to new XMLParserTestFileStream, out of memory\n");
  233. hr = E_OUTOFMEMORY;
  234. goto Exit;
  235. }
  236. if (! filestream->open(filename))
  237. {
  238. ::FusionpDbgPrintEx(
  239. FUSION_DBG_LEVEL_INFO,
  240. "SxsDebug:: fail to call XMLParserTestFileStream::open\n");
  241. hr = E_UNEXPECTED;
  242. goto Exit;
  243. }
  244. factory = new XMLParserTestFactory;
  245. if (! factory) {
  246. ::FusionpDbgPrintEx(
  247. FUSION_DBG_LEVEL_INFO,
  248. "SxsDebug:: fail to new XMLParserTestFactory, out of memory\n");
  249. hr = E_OUTOFMEMORY;
  250. goto Exit;
  251. }
  252. pIXMLParser = NEW(XMLParser);
  253. if (pIXMLParser == NULL)
  254. {
  255. ::FusionpDbgPrintEx(
  256. FUSION_DBG_LEVEL_ERROR,
  257. "SXS.DLL: Attempt to instantiate XML parser failed\n");
  258. goto Exit;
  259. }
  260. hr = pIXMLParser->SetInput(filestream); // filestream's RefCount=2
  261. if (! SUCCEEDED(hr))
  262. goto Exit;
  263. hr = pIXMLParser->SetFactory(factory); // factory's RefCount=2
  264. if (! SUCCEEDED(hr))
  265. goto Exit;
  266. for (j =0; j<10; j++) {
  267. ::QueryPerformanceCounter(&timestart);
  268. for (i = 0 ; i< 10; i++) {
  269. hr = pIXMLParser->Run(-1);
  270. if (FAILED(hr))
  271. goto Exit;
  272. pIXMLParser->Reset();
  273. pIXMLParser->SetFactory(factory);
  274. filestream->close();
  275. filestream->open(filename);
  276. pIXMLParser->SetInput(filestream);
  277. }
  278. ::QueryPerformanceCounter(&t1[j]);
  279. t1[j].QuadPart -= timestart.QuadPart;
  280. ::QueryPerformanceCounter(&timestart);
  281. for (i = 0 ; i< 10; i++) {
  282. hr = NOERROR;
  283. if (FAILED(hr))
  284. goto Exit;
  285. pIXMLParser->Reset();
  286. pIXMLParser->SetFactory(factory);
  287. filestream->close();
  288. filestream->open(filename);
  289. pIXMLParser->SetInput(filestream);
  290. }
  291. ::QueryPerformanceCounter(&t2[j]);
  292. t2[j].QuadPart -= timestart.QuadPart;
  293. parsertime[j].QuadPart = t1[j].QuadPart - t2[j].QuadPart;
  294. }
  295. hr = NOERROR;
  296. Exit:
  297. return hr;
  298. }
  299. #if SXS_PRECOMPILED_MANIFESTS_ENABLED
  300. HRESULT TestPCMTime(PCWSTR manifestfilename)
  301. {
  302. HRESULT hr = NOERROR;
  303. FN_TRACE_HR(hr);
  304. LARGE_INTEGER tmp1 = {0};
  305. LARGE_INTEGER tmp2 = {0};
  306. LARGE_INTEGER parsertime[10] = {0}, pcmtime[10] = {0};
  307. ULONG i = 0;
  308. hr = GetParserWorkingTime(manifestfilename, parsertime);
  309. if (FAILED(hr))
  310. goto Exit;
  311. hr = GetPCMWorkingTime(manifestfilename, pcmtime);
  312. if (FAILED(hr))
  313. goto Exit;
  314. for (i= 0 ; i < 10; i ++){
  315. tmp1.QuadPart = tmp1.QuadPart + parsertime[i].QuadPart;
  316. tmp2.QuadPart = tmp2.QuadPart + pcmtime[i].QuadPart;
  317. }
  318. tmp1.QuadPart = tmp1.QuadPart/10;
  319. tmp2.QuadPart = tmp2.QuadPart/10;
  320. ::FusionpDbgPrintEx(
  321. FUSION_DBG_LEVEL_INFO,
  322. "SxsDebug::TestPCMTime Result:\n\tXMLParser uses %d,\n\tPCM uses %d,\n\tthe difference is %d.\n",
  323. tmp1.QuadPart, tmp2.QuadPart, tmp1.QuadPart-tmp2.QuadPart);
  324. hr = NOERROR;
  325. Exit:
  326. return hr;
  327. }
  328. /* ---------------------------------------------------------------------------
  329. Two steps :
  330. 1. paring the manifest file,
  331. generate the NodeFactory print-out file1,
  332. generate the precompiled-manifest
  333. 2. using precompiled-manifest and call NodeFactory to generate pcm-printout file2
  334. 3. Compare file1 and file2
  335. --------------------------------------------------------------------------- */
  336. HRESULT
  337. PrecompiledManifestTest(PCWSTR filename) // this is a manifest file name
  338. {
  339. HRESULT hr = S_OK;
  340. FN_TRACE_HR(hr);
  341. CSmartRef<IXMLParser> pIXMLParser;
  342. CSmartRef<PCMTestFactory> wfactory;
  343. CSmartRef<PCMTestFactory> rfactory;
  344. CSmartRef<XMLParserTestFileStream> filestream;
  345. CStringBuffer buf;
  346. CSmartRef<CPrecompiledManifestWriter> pPCMWriter;
  347. CSmartRef<CPrecompiledManifestReader> pPCMReader;
  348. FILE *fp = NULL;
  349. if (!filename) {
  350. hr = E_INVALIDARG;
  351. goto Exit;
  352. }
  353. buf.Assign(filename, ::wcslen(filename));
  354. buf.Append(L".pcm", 4);
  355. // create filestream for xmlparser ...
  356. filestream = NEW (XMLParserTestFileStream());
  357. if (!filestream) {
  358. ::FusionpDbgPrintEx(
  359. FUSION_DBG_LEVEL_INFO,
  360. "SxsDebug:: fail to new XMLParserTestFileStream, out of memory\n");
  361. hr = E_OUTOFMEMORY;
  362. goto Exit;
  363. }
  364. if (! filestream->open(filename))
  365. {
  366. ::FusionpDbgPrintEx(
  367. FUSION_DBG_LEVEL_INFO,
  368. "SxsDebug:: fail to call XMLParserTestFileStream::open\n");
  369. hr = E_UNEXPECTED;
  370. goto Exit;
  371. }
  372. // create PCMWriter for xmlparser
  373. wfactory = new PCMTestFactory("e:\\manifest.out"));
  374. if (! wfactory) {
  375. ::FusionpDbgPrintEx(
  376. FUSION_DBG_LEVEL_INFO,
  377. "SxsDebug:: fail to new XMLParserTestFactory, out of memory\n");
  378. hr = E_OUTOFMEMORY;
  379. goto Exit;
  380. }
  381. pPCMWriter = new CPrecompiledManifestWriter);
  382. if (! pPCMWriter) {
  383. hr = E_OUTOFMEMORY;
  384. goto Exit;
  385. }
  386. pPCMWriter->Initialize(buf);
  387. pPCMWriter->SetFactory(wfactory);
  388. // Create XMLParser
  389. pIXMLParser = NEW(XMLParser);
  390. if (pIXMLParser == NULL){
  391. ::FusionpDbgPrintEx(
  392. FUSION_DBG_LEVEL_ERROR,
  393. "SXS.DLL: Attempt to instantiate XML parser failed\n");
  394. goto Exit;
  395. }
  396. hr = pIXMLParser->SetInput(filestream); // filestream's RefCount=2
  397. if (! SUCCEEDED(hr))
  398. goto Exit;
  399. hr = pIXMLParser->SetFactory(pPCMWriter); // wfactory's RefCount=2
  400. if (! SUCCEEDED(hr))
  401. goto Exit;
  402. hr = pIXMLParser->Run(-1);
  403. if (FAILED(hr))
  404. goto Exit;
  405. hr = pPCMWriter->Close();
  406. if (FAILED(hr))
  407. goto Exit;
  408. CSimpleFileStream::printf(L"PCM has been generated!!!\n\n");
  409. // PCM Reader
  410. pPCMReader = new CPrecompiledManifestReader);
  411. if (! pPCMReader) {
  412. hr = E_OUTOFMEMORY;
  413. goto Exit;
  414. }
  415. rfactory = new PCMTestFactory("e:\\pcm.out"));
  416. if (! rfactory) {
  417. ::FusionpDbgPrintEx(
  418. FUSION_DBG_LEVEL_INFO,
  419. "SxsDebug:: fail to new XMLParserTestFactory, out of memory\n");
  420. hr = E_OUTOFMEMORY;
  421. goto Exit;
  422. }
  423. hr = pPCMReader->InvokeNodeFactory(buf, rfactory);
  424. if (FAILED(hr))
  425. goto Exit;
  426. hr = NOERROR;
  427. Exit:
  428. return hr;
  429. }
  430. #endif // SXS_PRECOMPILED_MANIFESTS_ENABLED
  431. BOOL CreateMultiLevelDirectoryTest(PCWSTR pwszNewDirs)
  432. {
  433. BOOL fSuccess = TRUE;
  434. FN_TRACE_WIN32(fSuccess);
  435. const static WCHAR CurrentDirectory[]=L"e:\\tmp\\tmp";
  436. IFW32FALSE_EXIT(::SxspCreateMultiLevelDirectory(CurrentDirectory, pwszNewDirs));
  437. fSuccess = TRUE;
  438. Exit:
  439. return fSuccess;
  440. }
  441. BOOL TestCopyDirectory()
  442. {
  443. BOOL fSuccess = FALSE;
  444. FN_TRACE_WIN32(fSuccess);
  445. CStringBuffer m1;
  446. CStringBuffer m2;
  447. IFW32FALSE_EXIT(m1.Win32Assign(L"Z:\\tmp\\tmp", NUMBER_OF(L"Z:\\tmp\\tmp")-1));
  448. IFW32FALSE_EXIT(m2.Win32Assign(L"Z:\\tests\\tmp", NUMBER_OF(L"Z:\\tests\\tmp")-1));
  449. IFW32FALSE_EXIT(::SxspInstallMoveFileExW(m1, m2, MOVEFILE_REPLACE_EXISTING));
  450. fSuccess = TRUE;
  451. Exit:
  452. return fSuccess;
  453. }
  454. BOOL TestSxsGeneratePath()
  455. {
  456. //
  457. // the result is as below
  458. //
  459. //path is c:\winnt\winsxs\Manifests\x86_dynamicdll_b54bc117ce08a1e8_1.1.0.0_en-us_fb8e827d.Manifest
  460. //path is Manifests\x86_dynamicdll_b54bc117ce08a1e8_1.1.0.0_en-us_fb8e827d.Manifest
  461. //path is c:\winnt\winsxs\Manifests\
  462. //path is Manifests\x86_dynamicdll_b54bc117ce08a1e8_en-us_2ffeb063.Manifest
  463. //---------------------------------------
  464. //path is c:\winnt\winsxs\x86_policy.1.0.dynamicdll_b54bc117ce08a1e8_1.1.0.0_en-us_d51541cb\
  465. //path is x86_policy.1.0.dynamicdll_b54bc117ce08a1e8_1.1.0.0_en-us_d51541cb\
  466. //path is c:\winnt\winsxs\
  467. //path is x86_policy.1.0.dynamicdll_b54bc117ce08a1e8_en-us_b74d3d95\
  468. //---------------------------------------
  469. //path is c:\winnt\winsxs\Policies\x86_policy.1.0.dynamicdll_b54bc117ce08a1e8_en-us_b74d3d95\1.1.0.0.Policy
  470. //path is Policies\x86_policy.1.0.dynamicdll_b54bc117ce08a1e8_en-us_b74d3d95\1.1.0.0.Policy
  471. //path is c:\winnt\winsxs\Policies\
  472. //path is Policies\x86_policy.1.0.dynamicdll_b54bc117ce08a1e8_en-us_b74d3d95\1.1.0.0.Policy
  473. // if the assembly does not have version, flag=0 and pathType=policy would generate "policy store"
  474. // c:\winnt\winsxs\Policies\x86_policy.1.0.dynamicdll_b54bc117ce08a1e8_en-us_b74d3d95
  475. //
  476. BOOL fSuccess = FALSE;
  477. FN_TRACE_WIN32(fSuccess);
  478. CStringBuffer PathBuffer;
  479. PASSEMBLY_IDENTITY pAssemblyIdentity = NULL;
  480. //WCHAR szDisplayName[]=L"policy.1.0.dynamicdll,type=\"win32-policy\",publicKeyToken=\"b54bc117ce08a1e8\",version=\"1.1.0.0\",language=\"en-us\",processorArchitecture=\"x86\"";
  481. PWSTR szDisplayName[]= {
  482. L"dynamicdll,type=\"win32\",publicKeyToken=\"b54bc117ce08a1e8\",version=\"1.1.0.0\",language=\"en-us\",processorArchitecture=\"x86\"",
  483. L"policy.1.0.dynamicdll,type=\"win32-policy\",publicKeyToken=\"b54bc117ce08a1e8\",version=\"1.1.0.0\",language=\"en-us\",processorArchitecture=\"x86\"",
  484. L"policy.1.0.dynamicdll,type=\"win32-policy\",publicKeyToken=\"b54bc117ce08a1e8\",version=\"1.1.0.0\",language=\"en-us\",processorArchitecture=\"x86\""
  485. };
  486. DWORD j, dwPathType;
  487. DWORD flags[]={
  488. 0,
  489. SXSP_GENERATE_SXS_PATH_FLAG_OMIT_ROOT,
  490. SXSP_GENERATE_SXS_PATH_FLAG_PARTIAL_PATH,
  491. SXSP_GENERATE_SXS_PATH_FLAG_OMIT_ROOT | SXSP_GENERATE_SXS_PATH_FLAG_OMIT_VERSION};
  492. printf("---------------------------------------\n");
  493. for (dwPathType = SXSP_GENERATE_SXS_PATH_PATHTYPE_MANIFEST; dwPathType <= SXSP_GENERATE_SXS_PATH_PATHTYPE_POLICY; dwPathType++)
  494. //for (dwPathType = SXSP_GENERATE_SXS_PATH_PATHTYPE_ASSEMBLY; dwPathType <= SXSP_GENERATE_SXS_PATH_PATHTYPE_POLICY; dwPathType++)
  495. {
  496. IFW32FALSE_EXIT(SxspCreateAssemblyIdentityFromTextualString(
  497. szDisplayName[dwPathType - 1],
  498. &pAssemblyIdentity));
  499. for (j = 0 ; j < NUMBER_OF(flags); j++)
  500. {
  501. IFW32FALSE_EXIT(::SxspGenerateSxsPath(
  502. flags[j],
  503. dwPathType,
  504. L"c:\\winnt\\winsxs",
  505. wcslen(L"c:\\winnt\\winsxs"),
  506. pAssemblyIdentity,
  507. PathBuffer));
  508. printf("path is %S\n", static_cast<PCWSTR>(PathBuffer));
  509. }
  510. printf("---------------------------------------\n");
  511. SxsDestroyAssemblyIdentity(pAssemblyIdentity);
  512. pAssemblyIdentity = NULL;
  513. }
  514. fSuccess = TRUE;
  515. Exit:
  516. if (pAssemblyIdentity)
  517. SxsDestroyAssemblyIdentity(pAssemblyIdentity);
  518. return fSuccess;
  519. }
  520. BOOL ManifestProbeTest()
  521. {
  522. BOOL fSuccess = FALSE;
  523. FN_TRACE_WIN32(fSuccess);
  524. DWORD index = 0;
  525. CStringBuffer PathBuffer;
  526. PASSEMBLY_IDENTITY pAssemblyIdentity = NULL;
  527. ASSEMBLY_IDENTITY_ATTRIBUTE AttributeName;
  528. ASSEMBLY_IDENTITY_ATTRIBUTE AttributeVersion;
  529. ASSEMBLY_IDENTITY_ATTRIBUTE AttributeLangID;
  530. ASSEMBLY_IDENTITY_ATTRIBUTE AttributeProcessorArchitecture;
  531. PASSEMBLY_IDENTITY_ATTRIBUTE Attributes[] = {
  532. &AttributeName, &AttributeVersion,
  533. &AttributeLangID, &AttributeProcessorArchitecture};
  534. AttributeName.Flags = 0; // reserved flags : must be 0;
  535. AttributeName.NamespaceCch = 0;
  536. AttributeName.NameCch = 4;
  537. AttributeName.ValueCch = 7;
  538. AttributeName.Namespace = NULL;
  539. AttributeName.Name = L"name";
  540. AttributeName.Value = L"foo.mui";
  541. AttributeVersion.Flags = 0; // reserved flags : must be 0;
  542. AttributeVersion.NamespaceCch = 0;
  543. AttributeVersion.NameCch = 7;
  544. AttributeVersion.ValueCch = 7;
  545. AttributeVersion.Namespace = NULL;
  546. AttributeVersion.Name = L"version";
  547. AttributeVersion.Value = L"1.1.1.1";
  548. AttributeLangID.Flags = 0; // reserved flags : must be 0;
  549. AttributeLangID.NamespaceCch = 0;
  550. AttributeLangID.NameCch = 8;
  551. AttributeLangID.ValueCch = 5;
  552. AttributeLangID.Namespace = NULL;
  553. AttributeLangID.Name = L"language";
  554. AttributeLangID.Value = L"en-us";
  555. AttributeProcessorArchitecture .Flags = 0; // reserved flags : must be 0;
  556. AttributeProcessorArchitecture .NamespaceCch = 0;
  557. AttributeProcessorArchitecture .NameCch = 21;
  558. AttributeProcessorArchitecture .ValueCch = 3;
  559. AttributeProcessorArchitecture .Namespace = NULL;
  560. AttributeProcessorArchitecture .Name = L"processorArchitecture";
  561. AttributeProcessorArchitecture .Value = L"x86";
  562. IFW32FALSE_EXIT(::SxsCreateAssemblyIdentity(
  563. 0, // DWORD Flags,
  564. ASSEMBLY_IDENTITY_TYPE_DEFINITION, // ULONG Type,
  565. &pAssemblyIdentity,
  566. 4, // ULONG AttributeCount,
  567. Attributes)); // PCASSEMBLY_IDENTITY_ATTRIBUTE const *Attributes
  568. while(1) {// run until we run out of probing-path
  569. bool fDone = false;
  570. if (!::SxspGenerateManifestPathForProbing(
  571. index,
  572. 0,
  573. NULL,
  574. 0,
  575. ACTIVATION_CONTEXT_PATH_TYPE_WIN32_FILE,
  576. L"E:\\APPBASE\\",
  577. 11,
  578. pAssemblyIdentity,
  579. PathBuffer,
  580. NULL,
  581. fDone))
  582. {
  583. goto Exit;
  584. }
  585. if (fDone)
  586. break;
  587. PathBuffer.Clear();
  588. index ++;
  589. }
  590. fSuccess = TRUE;
  591. Exit:
  592. if (pAssemblyIdentity)
  593. SxsDestroyAssemblyIdentity(pAssemblyIdentity);
  594. if (!fSuccess) {
  595. DWORD dwLastError = ::FusionpGetLastWin32Error();
  596. if (dwLastError == BASESRV_SXS_RETURN_RESULT_SYSTEM_DEFAULT_DEPENDENCY_ASSEMBLY_NOT_FOUND){
  597. ::FusionpSetLastWin32Error(0);
  598. fSuccess = TRUE;
  599. }
  600. }
  601. return fSuccess;
  602. }
  603. #define WATCHBUCKET_NOTIFYSIZE (1024)
  604. typedef struct _tWATCH_BUCKET
  605. {
  606. HANDLE hFile;
  607. HANDLE hCompleteEvent;
  608. PCSXS_PROTECT_DIRECTORY pProtectInfo;
  609. OVERLAPPED olapInfo;
  610. BYTE NotifyInfo[WATCHBUCKET_NOTIFYSIZE];
  611. DWORD dwBytesBack;
  612. }
  613. WATCH_BUCKET, *PWATCH_BUCKET;
  614. HRESULT
  615. TryWatchingDirectories()
  616. {
  617. PCSXS_PROTECT_DIRECTORY pWatchList;
  618. SIZE_T cWatchList;
  619. DWORD dwWhichSignalled;
  620. DWORD dw;
  621. PWATCH_BUCKET pWatchBuckets;
  622. HANDLE* pHandleList;
  623. HRESULT hrSuccess = E_FAIL;
  624. FN_TRACE_HR(hrSuccess);
  625. IFW32FALSE_EXIT(::SxsProtectionGatherEntriesW(&pWatchList, &cWatchList));
  626. pWatchBuckets = FUSION_NEW_ARRAY(WATCH_BUCKET, cWatchList);
  627. pHandleList = FUSION_NEW_ARRAY(HANDLE, cWatchList);
  628. //
  629. // Fill in the list with handles to directories
  630. //
  631. for (dw = 0; dw < cWatchList; dw++)
  632. {
  633. PWATCH_BUCKET pbTemp = pWatchBuckets + dw;
  634. ZeroMemory(pbTemp, sizeof(*pbTemp));
  635. pbTemp->pProtectInfo = pWatchList + dw;
  636. pbTemp->hFile = ::CreateFileW(
  637. pWatchList[dw].pwszDirectory,
  638. FILE_LIST_DIRECTORY,
  639. FILE_SHARE_READ | FILE_SHARE_DELETE | FILE_SHARE_WRITE,
  640. NULL,
  641. OPEN_EXISTING,
  642. FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OVERLAPPED,
  643. NULL);
  644. pHandleList[dw] = CreateEventW(NULL, FALSE, FALSE, NULL);
  645. pbTemp->hCompleteEvent = pHandleList[dw];
  646. pbTemp->olapInfo.hEvent = pHandleList[dw];
  647. ::ReadDirectoryChangesW(
  648. pbTemp->hFile,
  649. (PVOID)(&pbTemp->NotifyInfo),
  650. WATCHBUCKET_NOTIFYSIZE,
  651. pbTemp->pProtectInfo->ulRecursiveFlag & SXS_PROTECT_RECURSIVE,
  652. SXS_PROTECT_FILTER_DEFAULT,
  653. &pbTemp->dwBytesBack,
  654. &pbTemp->olapInfo,
  655. NULL);
  656. }
  657. //
  658. // We now have a list of directories that we need to watch for changes.
  659. //
  660. while (true)
  661. {
  662. dwWhichSignalled = WaitForMultipleObjects(static_cast<DWORD>(cWatchList), pHandleList, FALSE, INFINITE);
  663. dwWhichSignalled -= WAIT_OBJECT_0;
  664. if (dwWhichSignalled < cWatchList)
  665. {
  666. //
  667. // Somebody went and fiddled with a directory!
  668. //
  669. dwWhichSignalled -= WAIT_OBJECT_0;
  670. ::FusionpDbgPrintEx(
  671. FUSION_DBG_LEVEL_INFO,
  672. "Someone changed: %ls\n",
  673. pWatchBuckets[dwWhichSignalled].pProtectInfo->pwszDirectory);
  674. ResetEvent(pHandleList[dwWhichSignalled]);
  675. PFILE_NOTIFY_INFORMATION pCursor;
  676. pCursor = (PFILE_NOTIFY_INFORMATION) pWatchBuckets[dwWhichSignalled].NotifyInfo;
  677. while (true)
  678. {
  679. ::SxsProtectionNotifyW(
  680. (PVOID)pWatchBuckets[dwWhichSignalled].pProtectInfo,
  681. pCursor->FileName,
  682. pCursor->FileNameLength / sizeof(pCursor->FileName[0]),
  683. pCursor->Action);
  684. if (pCursor->NextEntryOffset)
  685. pCursor = (PFILE_NOTIFY_INFORMATION)(((PBYTE)pCursor) + pCursor->NextEntryOffset);
  686. else
  687. break;
  688. }
  689. ::ReadDirectoryChangesW(
  690. pWatchBuckets[dwWhichSignalled].hFile,
  691. (PVOID)(&pWatchBuckets[dwWhichSignalled].NotifyInfo),
  692. WATCHBUCKET_NOTIFYSIZE,
  693. pWatchBuckets[dwWhichSignalled].pProtectInfo->ulRecursiveFlag & SXS_PROTECT_RECURSIVE,
  694. SXS_PROTECT_FILTER_DEFAULT,
  695. &pWatchBuckets[dwWhichSignalled].dwBytesBack,
  696. &pWatchBuckets[dwWhichSignalled].olapInfo,
  697. NULL);
  698. }
  699. }
  700. hrSuccess = S_OK;
  701. Exit:
  702. return hrSuccess;
  703. }
  704. BOOL
  705. DllRedirectionTest(
  706. PCWSTR manifestFileName
  707. )
  708. {
  709. BOOL fSuccess = FALSE;
  710. FN_TRACE_WIN32(fSuccess);
  711. CFileStream manifestFileStream;
  712. CResourceStream ResourceStream;
  713. CFileStream policyFileStream;
  714. SXS_GENERATE_ACTIVATION_CONTEXT_PARAMETERS parameters = {0};
  715. CUnicodeStringBuffer assemblyDirectory;
  716. CStringBuffer CandidatePolicyPathBuffer;
  717. BOOL fPolicyExist=FALSE;
  718. PWSTR p=NULL;
  719. p = wcsrchr(manifestFileName, L'.');
  720. if (p && ((_wcsicmp(p, L".dll") ==0) || (_wcsicmp(p, L".exe") ==0))) // manifest is from a resource of a DLL or EXE
  721. {
  722. IFW32FALSE_EXIT(ResourceStream.Initialize(manifestFileName, MAKEINTRESOURCEW(RT_MANIFEST)));
  723. parameters.Manifest.Path = manifestFileName;
  724. parameters.Manifest.Stream = &ResourceStream;
  725. parameters.Manifest.PathType = ACTIVATION_CONTEXT_PATH_TYPE_WIN32_FILE;
  726. IFW32FALSE_EXIT(assemblyDirectory.Win32Assign(manifestFileName, ::wcslen(manifestFileName)));
  727. assemblyDirectory.RemoveLastPathElement();
  728. parameters.AssemblyDirectory = assemblyDirectory;
  729. }
  730. else
  731. {
  732. IFW32FALSE_EXIT(
  733. manifestFileStream.OpenForRead(
  734. manifestFileName,
  735. CImpersonationData(),
  736. FILE_SHARE_READ,
  737. OPEN_EXISTING,
  738. FILE_FLAG_SEQUENTIAL_SCAN));
  739. parameters.Manifest.Path = manifestFileName;
  740. parameters.Manifest.Stream = &manifestFileStream;
  741. parameters.Manifest.PathType = ACTIVATION_CONTEXT_PATH_TYPE_WIN32_FILE;
  742. IFW32FALSE_EXIT(assemblyDirectory.Win32Assign(manifestFileName, ::wcslen(manifestFileName)));
  743. assemblyDirectory.RemoveLastPathElement();
  744. parameters.AssemblyDirectory = assemblyDirectory;
  745. }
  746. // look for policy file in the same dir as the manifest path
  747. IFW32FALSE_EXIT(CandidatePolicyPathBuffer.Win32Assign(manifestFileName, ::wcslen(manifestFileName)));
  748. IFW32FALSE_EXIT(CandidatePolicyPathBuffer.Win32ChangePathExtension(CONFIG_FILE_EXTENSION, NUMBER_OF(CONFIG_FILE_EXTENSION) - 1, eErrorIfNoExtension));
  749. if (::GetFileAttributesW(CandidatePolicyPathBuffer) != -1) { // policy file exists
  750. fPolicyExist = TRUE;
  751. IFW32FALSE_EXIT(
  752. policyFileStream.OpenForRead(
  753. CandidatePolicyPathBuffer,
  754. CImpersonationData(),
  755. FILE_SHARE_READ,
  756. OPEN_EXISTING,
  757. FILE_FLAG_SEQUENTIAL_SCAN));
  758. parameters.Policy.Path = CandidatePolicyPathBuffer;
  759. parameters.Policy.Stream = &policyFileStream;
  760. }
  761. parameters.ProcessorArchitecture = 0 ;
  762. parameters.LangId = GetUserDefaultUILanguage();
  763. IFW32FALSE_EXIT(::SxsGenerateActivationContext(&parameters));
  764. fSuccess = TRUE;
  765. Exit:
  766. CSxsPreserveLastError ple;
  767. ::CloseHandle(parameters.SectionObjectHandle);
  768. ple.Restore();
  769. return fSuccess;
  770. }
  771. BOOL TestFusionArray(PCWSTR dir1, PCWSTR dir2)
  772. {
  773. BOOL fSuccess = FALSE;
  774. FN_TRACE_WIN32(fSuccess);
  775. CStringBuffer sbDir1;
  776. CStringBuffer sbDir2;
  777. CFusionDirectoryDifference dirResult;
  778. IFW32FALSE_EXIT(sbDir1.Win32Assign(dir1, wcslen(dir1)));
  779. IFW32FALSE_EXIT(sbDir2.Win32Assign(dir2, wcslen(dir2)));
  780. IFCOMFAILED_EXIT(
  781. ::FusionpCompareDirectoriesSizewiseRecursively(
  782. &dirResult,
  783. sbDir1,
  784. sbDir2));
  785. fSuccess = TRUE;
  786. Exit:
  787. return fSuccess;
  788. }
  789. //
  790. // this function is written for Testing team to generate pAssemblyIdentity
  791. // there are two ways to generate assemblyIdentity, one is insert one attribute each time,
  792. // another way is to make all attributes to be inserted ready in an array and call
  793. // SxsCreateAssemblyIdentity. The con and pro for both approaches are obvious,
  794. // the input string must be in a format as "ns1:n1=v1;ns2:n2=v2;",
  795. // the whole string ending with a trailing ";", ns could be NULL
  796. // this fucntion does not deal with complicate case such as ns/name/value string contains
  797. // special chars. let me know if you do need deal with it...
  798. //
  799. // xiaoyuw@09/26/2000
  800. //
  801. BOOL SxspGenerateManifestPathOnAssemblyIdentity(
  802. PCWSTR str,
  803. PWSTR pszOut,
  804. ULONG *pCchstr,
  805. PASSEMBLY_IDENTITY *ppAssemblyIdentity
  806. )
  807. {
  808. BOOL fSuccess = FALSE;
  809. FN_TRACE_WIN32(fSuccess);
  810. PASSEMBLY_IDENTITY pAssemblyIdentity = NULL;
  811. CStringBuffer PathBuffer;
  812. if (ppAssemblyIdentity)
  813. *ppAssemblyIdentity = NULL;
  814. PARAMETER_CHECK(str != NULL);
  815. PARAMETER_CHECK(pCchstr != NULL);
  816. IFW32FALSE_EXIT(
  817. ::SxspCreateAssemblyIdentityFromTextualString(
  818. str,
  819. &pAssemblyIdentity));
  820. // AssemblyIdentity is created, now generate the path
  821. IFW32FALSE_EXIT(
  822. ::SxspGenerateSxsPath(
  823. SXSP_GENERATE_SXS_PATH_FLAG_OMIT_ROOT,
  824. SXSP_GENERATE_SXS_PATH_PATHTYPE_ASSEMBLY,
  825. NULL,
  826. 0,
  827. pAssemblyIdentity,
  828. PathBuffer));
  829. IFW32FALSE_EXIT(PathBuffer.Win32CopyStringOut(pszOut, pCchstr));
  830. if (ppAssemblyIdentity != NULL)
  831. {
  832. *ppAssemblyIdentity = pAssemblyIdentity ;
  833. pAssemblyIdentity = NULL;
  834. }
  835. fSuccess = TRUE;
  836. Exit:
  837. if (pAssemblyIdentity != NULL)
  838. SxsDestroyAssemblyIdentity(pAssemblyIdentity);
  839. return fSuccess ;
  840. }
  841. /* --------------------------------------------------------------------------------
  842. POLICY_PATH_FLAG_POLICY_IDENTITY_TEXTUAL_FORMAT : x86_policy.1.0.dynamicdll_b54bc117ce08a1e8_en-us_d51541cb
  843. POLICY_PATH_FLAG_FULL_QUALIFIED_POLICIES_DIR : c:\winnt\winsxs\policies
  844. POLICY_PATH_FLAG_FULL_QUALIFIED_POLICY_FILE_NAME : c:\winnt\winsxs\policies\x86_policy.1.0.dynamicdll_b54bc117ce08a1e8_en-us_d51541cb\1.1.0.0.policy, for .cat, you have to replace it manually
  845. -------------------------------------------------------------------------------- */
  846. BOOL SxspGeneratePolicyPathOnAssemblyIdentity(
  847. DWORD dwFlag,
  848. PCWSTR str,
  849. PWSTR pszOut,
  850. ULONG *pCchstr,
  851. PASSEMBLY_IDENTITY *ppAssemblyIdentity
  852. )
  853. {
  854. BOOL fSuccess = FALSE;
  855. FN_TRACE_WIN32(fSuccess);
  856. PASSEMBLY_IDENTITY pAssemblyIdentity;
  857. DWORD dwPathType;
  858. DWORD dwGenerateFlag;
  859. CStringBuffer PathBuffer;
  860. CStringBuffer bufAssemblyRootDirectory;
  861. IFW32FALSE_EXIT(
  862. ::SxspCreateAssemblyIdentityFromTextualString(
  863. str,
  864. &pAssemblyIdentity));
  865. switch (dwFlag)
  866. {
  867. case POLICY_PATH_FLAG_POLICY_IDENTITY_TEXTUAL_FORMAT:
  868. dwPathType = SXSP_GENERATE_SXS_PATH_PATHTYPE_ASSEMBLY;
  869. dwGenerateFlag = SXSP_GENERATE_SXS_PATH_FLAG_OMIT_ROOT | SXSP_GENERATE_SXS_PATH_FLAG_OMIT_VERSION;
  870. break;
  871. case POLICY_PATH_FLAG_FULL_QUALIFIED_POLICIES_DIR:
  872. {
  873. IFW32FALSE_EXIT(SxspGetAssemblyRootDirectory(bufAssemblyRootDirectory));
  874. dwPathType = SXSP_GENERATE_SXS_PATH_PATHTYPE_POLICY;
  875. dwGenerateFlag = SXSP_GENERATE_SXS_PATH_FLAG_PARTIAL_PATH;
  876. }
  877. break;
  878. case POLICY_PATH_FLAG_FULL_QUALIFIED_POLICY_FILE_NAME:
  879. {
  880. IFW32FALSE_EXIT(SxspGetAssemblyRootDirectory(bufAssemblyRootDirectory));
  881. dwPathType = SXSP_GENERATE_SXS_PATH_PATHTYPE_POLICY;
  882. dwGenerateFlag = 0;
  883. }
  884. break;
  885. default:
  886. ::FusionpSetLastWin32Error(ERROR_INVALID_PARAMETER);
  887. goto Exit;
  888. }
  889. IFW32FALSE_EXIT(
  890. ::SxspGenerateSxsPath(
  891. dwGenerateFlag,
  892. dwPathType,
  893. bufAssemblyRootDirectory,
  894. bufAssemblyRootDirectory.Cch(),
  895. pAssemblyIdentity,
  896. PathBuffer));
  897. IFW32FALSE_EXIT(PathBuffer.Win32CopyStringOut(pszOut, pCchstr));
  898. if (ppAssemblyIdentity != NULL)
  899. {
  900. *ppAssemblyIdentity = pAssemblyIdentity ;
  901. pAssemblyIdentity = NULL;
  902. }
  903. fSuccess = TRUE;
  904. Exit:
  905. if (pAssemblyIdentity != NULL)
  906. SxsDestroyAssemblyIdentity(pAssemblyIdentity);
  907. return fSuccess ;
  908. }
  909. BOOL TestAssemblyIdentityHash()
  910. {
  911. BOOL fSuccess = FALSE;
  912. FN_TRACE_WIN32(fSuccess);
  913. ULONG hash1=0, hash2=0;
  914. PASSEMBLY_IDENTITY pAssemblyIdentity = NULL;
  915. ASSEMBLY_IDENTITY_ATTRIBUTE Attribute;
  916. IFW32FALSE_EXIT(::SxsCreateAssemblyIdentity(0, ASSEMBLY_IDENTITY_TYPE_DEFINITION, &pAssemblyIdentity, 0, NULL));
  917. Attribute.Flags = 0;
  918. Attribute.NamespaceCch = 18;
  919. Attribute.Namespace = L"http://interesting";
  920. Attribute.NameCch = 8;
  921. Attribute.Name = L"whatever";
  922. Attribute.ValueCch = 32;
  923. Attribute.Value = L"@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_";
  924. IFW32FALSE_EXIT(::SxsInsertAssemblyIdentityAttribute(0, pAssemblyIdentity, &Attribute));
  925. IFW32FALSE_EXIT(SxsHashAssemblyIdentity(0, pAssemblyIdentity, &hash1));
  926. ::SxsDestroyAssemblyIdentity(pAssemblyIdentity);
  927. // create second assembly identity
  928. IFW32FALSE_EXIT(::SxsCreateAssemblyIdentity(0, ASSEMBLY_IDENTITY_TYPE_DEFINITION, &pAssemblyIdentity, 0, NULL));
  929. Attribute.Flags = 0;
  930. Attribute.NamespaceCch = 18;
  931. Attribute.Namespace = L"http://interesting";
  932. Attribute.NameCch = 8;
  933. Attribute.Name = L"whatever";
  934. Attribute.ValueCch = 32;
  935. Attribute.Value = L"/>BABCDGHGHKLMNMNOPSTUVUVYZYZ[\\_`";
  936. IFW32FALSE_EXIT(::SxsInsertAssemblyIdentityAttribute(0, pAssemblyIdentity, &Attribute));
  937. IFW32FALSE_EXIT(SxsHashAssemblyIdentity(0, pAssemblyIdentity, &hash2));
  938. ::SxsDestroyAssemblyIdentity(pAssemblyIdentity);
  939. fSuccess = TRUE;
  940. Exit:
  941. if (pAssemblyIdentity)
  942. ::SxsDestroyAssemblyIdentity(pAssemblyIdentity);
  943. return fSuccess;
  944. }
  945. BOOL
  946. TestNewCatalogSignerThingy(
  947. PCWSTR pcwszCatalog
  948. )
  949. {
  950. BOOL fSuccess = FALSE;
  951. ULONG ulKeyLength;
  952. CPublicKeyInformation CatalogInformation;
  953. CSmallStringBuffer sbSignerString;
  954. CStringBuffer sbCatalogName;
  955. FN_TRACE_WIN32(fSuccess);
  956. IFW32FALSE_EXIT(sbCatalogName.Win32Assign(pcwszCatalog, ::wcslen(pcwszCatalog)));
  957. IFW32FALSE_EXIT(CatalogInformation.Initialize(sbCatalogName));
  958. IFW32FALSE_EXIT(CatalogInformation.GetStrongNameString(sbSignerString));
  959. IFW32FALSE_EXIT(CatalogInformation.GetPublicKeyBitLength(ulKeyLength));
  960. FusionpDbgPrintEx(
  961. FUSION_DBG_LEVEL_INFO,
  962. "Strong name of catalog signer: %ls\n"
  963. "Key: %ls (length %ld)\n",
  964. static_cast<PCWSTR>(sbSignerString),
  965. ulKeyLength);
  966. fSuccess = TRUE;
  967. Exit:
  968. return fSuccess;
  969. };
  970. BOOL TestSystemDefaultActCtxGeneration()
  971. {
  972. BOOL fSuccess = FALSE;
  973. FN_TRACE_WIN32(fSuccess);
  974. SXS_GENERATE_ACTIVATION_CONTEXT_PARAMETERS Parameter = {0};
  975. WCHAR pszTextualAssemblyIdentity[] =
  976. L"Microsoft.Windows.SystemCompactAssembly,version=\"1.0.0.0\",type=\"win32\",processorArchitecture=\"x86\"\0";
  977. CStringBuffer AssemblyDirectory;
  978. IFW32FALSE_EXIT(::SxspGetAssemblyRootDirectory(AssemblyDirectory));
  979. IFW32FALSE_EXIT(AssemblyDirectory.Win32AppendPathElement(
  980. MANIFEST_ROOT_DIRECTORY_NAME,
  981. NUMBER_OF(MANIFEST_ROOT_DIRECTORY_NAME)-1));
  982. IFW32FALSE_EXIT(AssemblyDirectory.Win32EnsureTrailingPathSeparator());
  983. Parameter.ProcessorArchitecture = 0 ;
  984. Parameter.LangId = 0x0409;
  985. Parameter.Flags = SXS_GENERATE_ACTIVATION_CONTEXT_FLAG_SYSTEM_DEFAULT_TEXTUAL_ASSEMBLY_IDENTITY;
  986. Parameter.TextualAssemblyIdentity = pszTextualAssemblyIdentity;
  987. Parameter.AssemblyDirectory = AssemblyDirectory;
  988. IFW32FALSE_EXIT(SxsGenerateActivationContext(&Parameter));
  989. fSuccess = TRUE;
  990. Exit:
  991. // check LastError
  992. if (Parameter.SectionObjectHandle != NULL)
  993. ::CloseHandle(Parameter.SectionObjectHandle);
  994. if (Parameter.Manifest.Stream)
  995. Parameter.Manifest.Stream->Release();
  996. return fSuccess;
  997. }
  998. BOOL
  999. TestSfcUIPopup()
  1000. {
  1001. BOOL fSuccess = FALSE;
  1002. FN_TRACE_WIN32(fSuccess);
  1003. CAssemblyRecoveryInfo RecoverInfo;
  1004. CSXSMediaPromptDialog PromptDialog;
  1005. CStringBuffer sbAssemblyName;
  1006. static WCHAR wchTestName[] = L"x86_Microsoft.Tools.VisualCPlusPlus.Runtime-Libraries_6595b64144ccf1df_6.0.0.0_x-ww_ff9986d7";
  1007. bool fNoAssembly;
  1008. IFW32FALSE_EXIT(RecoverInfo.Initialize());
  1009. IFW32FALSE_EXIT(sbAssemblyName.Win32Assign(wchTestName, NUMBER_OF(wchTestName) - 1));
  1010. IFW32FALSE_EXIT(RecoverInfo.AssociateWithAssembly(sbAssemblyName, fNoAssembly));
  1011. #if 0
  1012. if (fNoAssembly)
  1013. {
  1014. IFW32FALSE_EXIT(PromptDialog.Initialize(RecoverInfo, CSXSMediaPromptDialog::Source_FileURL));
  1015. IFW32FALSE_EXIT(PromptDialog.ShowSelf());
  1016. }
  1017. #endif // 0
  1018. fSuccess = TRUE;
  1019. Exit:
  1020. return fSuccess;
  1021. }
  1022. BOOL
  1023. TestPolicyPathGeneration()
  1024. {
  1025. WCHAR str[] = L"policy.1.0.ms-sxstest-folder1,processorArchitecture=\"x86\",type=\"win32-policy\",language=\"en\",version=\"2.2.2.2\",publicKeyToken=\"75e377300ab7b886\"";
  1026. WCHAR pszOut[1024];
  1027. ULONG Cchstr =0;
  1028. for (DWORD dwFlag=0; dwFlag<3; dwFlag++)
  1029. {
  1030. SxspGeneratePolicyPathOnAssemblyIdentity(
  1031. dwFlag,
  1032. str,
  1033. pszOut,
  1034. &Cchstr,
  1035. NULL);
  1036. };
  1037. return TRUE;
  1038. }
  1039. BOOL
  1040. SxspDebug(
  1041. ULONG iOperation,
  1042. DWORD dwFlags,
  1043. PCWSTR pszParameter1,
  1044. PVOID pvParameter2)
  1045. {
  1046. BOOL fSuccess = FALSE;
  1047. FN_TRACE_WIN32(fSuccess);
  1048. switch (iOperation)
  1049. {
  1050. case SXS_DEBUG_SYSTEM_DEFAULT_ACTCTX_GENERATION:
  1051. IFW32FALSE_EXIT(::TestSystemDefaultActCtxGeneration());
  1052. break;
  1053. case SXS_DEBUG_SFC_UI_TEST:
  1054. IFW32FALSE_EXIT( TestSfcUIPopup() );
  1055. break;
  1056. case SXS_DEBUG_CATALOG_SIGNER_CHECK:
  1057. IFW32FALSE_EXIT(::TestNewCatalogSignerThingy(pszParameter1));
  1058. break;
  1059. case SXS_DEBUG_ASSEMBLY_IDENTITY_HASH:
  1060. IFW32FALSE_EXIT(::TestAssemblyIdentityHash());
  1061. break;
  1062. case SXS_DEBUG_ASSEMBLYNAME_CONVERSION:
  1063. //IFCOMFAILED_EXIT(TestAssemblyName());
  1064. //IFCOMFAILED_EXIT(::TestDeleteInstalledAssemblyBasedOnAssemblyName());
  1065. IFW32FALSE_EXIT(::TestPolicyPathGeneration());
  1066. break;
  1067. case SXS_DEBUG_GET_STRONGNAME:
  1068. {
  1069. CPublicKeyInformation pkInfo;
  1070. CFusionArray<BYTE> PublicKeyBytes;
  1071. CStringBuffer *pStringBuffers = (CStringBuffer*) pvParameter2;
  1072. PCCERT_CONTEXT pContext = (PCCERT_CONTEXT) pszParameter1;
  1073. PARAMETER_CHECK(pszParameter1 != NULL);
  1074. PARAMETER_CHECK(pvParameter2 != NULL);
  1075. IFW32FALSE_EXIT(pkInfo.Initialize(pContext));
  1076. IFW32FALSE_EXIT(pkInfo.GetSignerNiceName(pStringBuffers[0]));
  1077. IFW32FALSE_EXIT(pkInfo.GetStrongNameString(pStringBuffers[1]));
  1078. IFW32FALSE_EXIT(pkInfo.GetWrappedPublicKeyBytes(PublicKeyBytes));
  1079. IFW32FALSE_EXIT(::SxspHashBytesToString(PublicKeyBytes.GetArrayPtr(), PublicKeyBytes.GetSize(), pStringBuffers[2]));
  1080. break;
  1081. }
  1082. case SXS_DEBUG_FUSION_REPARSEPOINT:
  1083. PARAMETER_CHECK(pszParameter1 != NULL);
  1084. IFW32FALSE_EXIT(::TestReparsePointOnFullQualifiedPath(pszParameter1));
  1085. break;
  1086. case SXS_DEBUG_FOLDERNAME_FROM_ASSEMBLYIDENTITY_GENERATION:
  1087. {
  1088. WCHAR pstr[1024];
  1089. ULONG cch = NUMBER_OF(pstr);
  1090. PARAMETER_CHECK(pszParameter1 != NULL);
  1091. IFW32FALSE_EXIT(SxspGenerateManifestPathOnAssemblyIdentity(pszParameter1, pstr, &cch, NULL));
  1092. }
  1093. break;
  1094. case SXS_DEBUG_FUSION_ARRAY:
  1095. PARAMETER_CHECK(pszParameter1 != NULL);
  1096. PARAMETER_CHECK(pvParameter2 != NULL);
  1097. IFW32FALSE_EXIT(TestFusionArray(pszParameter1, reinterpret_cast<PCWSTR>(pvParameter2)));
  1098. break;
  1099. case SXS_DEBUG_FORCE_LEAK:
  1100. {
  1101. //
  1102. // Leaking memory intentionally - do not fix!
  1103. // - if pvParameter2 is NULL, then leaks one byte
  1104. // - Otherwise, assumes pvParameter2 is a PDWORD that is now many bytes
  1105. // should be leaked.
  1106. //
  1107. // Uses new[] to interact with the heap; might want to use the flags to
  1108. // indicate use of the Fusion heap or whatnot.
  1109. //
  1110. DWORD dwLeakCount = pvParameter2 ? *((PDWORD)pvParameter2) : 1;
  1111. PCHAR pLeaked = NEW(CHAR[ dwLeakCount ]);
  1112. if (pLeaked)
  1113. {
  1114. ::FusionpDbgPrintEx(
  1115. FUSION_DBG_LEVEL_INFO,
  1116. "SxsDebug::ForceLeak allocates %d bytes\n",
  1117. dwLeakCount);
  1118. fSuccess = TRUE;
  1119. }
  1120. else
  1121. {
  1122. ::FusionpDbgPrintEx(
  1123. FUSION_DBG_LEVEL_INFO,
  1124. "SxsDebug::ForceLeak didn't allocate anything, new failed\n");
  1125. }
  1126. break;
  1127. }
  1128. case SXS_DEBUG_SFC_SCANNER:
  1129. IFW32FALSE_EXIT(SxsProtectionPerformScanNow(NULL, TRUE, TRUE));
  1130. break;
  1131. case SXS_DEBUG_DLL_REDIRECTION:
  1132. PARAMETER_CHECK(pszParameter1 != NULL);
  1133. IFW32FALSE_EXIT(::DllRedirectionTest(pszParameter1));
  1134. break;
  1135. case SXS_DEBUG_DIRECTORY_WATCHER:
  1136. IFCOMFAILED_EXIT(TryWatchingDirectories());
  1137. break;
  1138. case SXS_DEBUG_CREAT_MULTILEVEL_DIRECTORY:
  1139. PARAMETER_CHECK(pszParameter1 != NULL);
  1140. IFW32FALSE_EXIT(CreateMultiLevelDirectoryTest(pszParameter1));
  1141. break;
  1142. case SXS_DEBUG_PROBE_MANIFST:
  1143. //IFW32FALSE_EXIT(ManifestProbeTest());
  1144. //IFW32FALSE_EXIT(TestSxsGeneratePath());
  1145. IFW32FALSE_EXIT(TestCopyDirectory());
  1146. break;
  1147. case SXS_DEBUG_XML_PARSER:
  1148. PARAMETER_CHECK(pszParameter1 != NULL);
  1149. IFCOMFAILED_EXIT(::XMLParserTest(pszParameter1));
  1150. break;
  1151. case SXS_DEBUG_CHECK_MANIFEST_SCHEMA:
  1152. PARAMETER_CHECK(pszParameter1 != NULL);
  1153. IFW32FALSE_EXIT(::SxspManifestSchemaCheck(pszParameter1));
  1154. break;
  1155. #if SXS_PRECOMPILED_MANIFESTS_ENABLED
  1156. case SXS_DEBUG_PRECOMPILED_MANIFEST:
  1157. PARAMETER_CHECK(pszParameter1 != NULL);
  1158. IFCOMFAILED_EXIT(::PrecompiledManifestTest(pszParameter1));
  1159. break;
  1160. case SXS_DEBUG_TIME_PCM:
  1161. PARAMETER_CHECK(pszParameter1 != NULL);
  1162. IFCOMFAILED_EXIT(::TestPCMTime(const_cast<LPWSTR>(pszParameter1)));
  1163. break;
  1164. #endif // SXS_PRECOMPILED_MANIFESTS_ENABLED
  1165. case SXS_DEBUG_SET_ASSEMBLY_STORE_ROOT:
  1166. {
  1167. PWSTR pszTemp = NULL;
  1168. PCWSTR pszTemp2 = NULL;
  1169. PARAMETER_CHECK(pszParameter1 != NULL);
  1170. // Make a copy of the input string
  1171. IFW32FALSE_EXIT(::FusionDupString(&pszTemp, pszParameter1, ::wcslen(pszParameter1)));
  1172. pszTemp2 = ::SxspInterlockedExchange(&g_AlternateAssemblyStoreRoot, pszTemp);
  1173. if (pszTemp2 != NULL)
  1174. FUSION_DELETE_ARRAY(pszTemp2);
  1175. break;
  1176. }
  1177. case SXS_DEBUG_EXIT_PROCESS:
  1178. ExitProcess(123);
  1179. break;
  1180. case SXS_DEBUG_TERMINATE_PROCESS:
  1181. TerminateProcess(GetCurrentProcess(), 456);
  1182. break;
  1183. } // end of switch
  1184. fSuccess = TRUE;
  1185. Exit:
  1186. return fSuccess;
  1187. }// end of SxspDebug