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.

7962 lines
251 KiB

  1. // Copyright (c) Microsoft Corporation
  2. #include "stdinc.h" // actually from dll\whistler directory
  3. /*-----------------------------------------------------------------------------
  4. Side X ("by") Side Test
  5. -----------------------------------------------------------------------------*/
  6. #include "nt.h"
  7. #include "ntrtl.h"
  8. #include "nturtl.h"
  9. #include "windows.h"
  10. #include "lm.h"
  11. #include "lmdfs.h"
  12. #define CRegKey ATL_CRegKey
  13. #include "atlbase.h"
  14. #undef CRegKey
  15. #include "fusionlastwin32error.h"
  16. #include <stddef.h>
  17. #include <stdlib.h>
  18. #include <stdio.h>
  19. #include <stdarg.h>
  20. #include "fusionbuffer.h"
  21. #include "fusion.h"
  22. #include "sxsasmname.h"
  23. #include "util.h"
  24. #include "sxsapi.h"
  25. #include "fusiontrace.h"
  26. #include "wintrust.h"
  27. #include "softpub.h"
  28. #include "perfclocking.h"
  29. #include "strongname.h"
  30. #include "fusionversion.h"
  31. #include <setupapi.h>
  32. #include "commctrl.h"
  33. #include "fusionsha1.h"
  34. #include "cguid.h"
  35. #include "winbasep.h"
  36. #include "sxstest_idl.h"
  37. #include <time.h>
  38. #include "fusiondump.h"
  39. #include "imagehlp.h"
  40. #undef ADDRESS
  41. #undef LoadLibraryA
  42. #undef LoadLibraryW
  43. #undef LoadLibraryExA
  44. #undef LoadLibraryExW
  45. #undef InitCommonControls
  46. BOOL IamExe;
  47. BOOL IamDll;
  48. extern "C" { void (__cdecl * _aexit_rtn)(int); }
  49. #include "sxstest.h"
  50. #include "sxstest_trace.cpp"
  51. __inline
  52. ULONGLONG
  53. GetCycleCount(void)
  54. {
  55. #if defined(_X86_)
  56. __asm {
  57. RDTSC
  58. }
  59. #else
  60. return 0;
  61. #endif // defined(_X86_)
  62. }
  63. typedef BOOL (WINAPI * PSXSPGENERATEMANIFESTPATHONASSEMBLYIDENTITY)(
  64. PWSTR str, // input string, must have name, version, langid and processorarchitecture
  65. PWSTR psz, // output string, like x86_cards_strongname,.......
  66. SIZE_T * pCch, // IN : length of psz, OUT : used
  67. PASSEMBLY_IDENTITY *ppAssemblyIdentity // could be NULL
  68. );
  69. #define SXSTEST_BEGIN_INSTALL (0x4000000000000000i64)
  70. #define SXSTEST_INSTALL (0x2000000000000000i64)
  71. #define SXSTEST_END_INSTALL (0x1000000000000000i64)
  72. #define SXSTEST_END_OF_FLAGS (0x0200000000000000i64)
  73. #define SXSTEST_THREADS (0x0100000000000000i64)
  74. #define SXSTEST_INSTALLED_DLL (0x0080000000000000i64)
  75. #define SXSTEST_BUILT_DLL (0x0040000000000000i64)
  76. #define SXSTEST_STATIC_DLL (0x0020000000000000i64)
  77. inline int PRINTABLE(int ch) { return isprint(ch) ? ch : '.'; }
  78. VOID
  79. PrintBlob(
  80. FILE *pf,
  81. PVOID Data,
  82. SIZE_T Length,
  83. PCWSTR PerLinePrefix
  84. );
  85. BOOL GenerateHashOfFileLikeSxsDoes(PCWSTR pcwszFileName);
  86. BOOL TestLeakMemory(DWORD Amount);
  87. BOOL TestAssemblyProbing(int argc, wchar_t **argv, int *piNext);
  88. BOOL TestDirectoryChangeWatcher(int argc, wchar_t **argv, int *piNext);
  89. BOOL TestXMLParsing(int argc, wchar_t **argv, int *piNext);
  90. BOOL TestMultiAct(int argc, wchar_t **argv);
  91. BOOL TestManifestSchema(int argc, wchar_t **argv, int *piNext);
  92. BOOL TestDirect(int argc, wchar_t **argv, int *piNext);
  93. void TestWin32(wchar_t** argv);
  94. BOOL TestAct(int argc, wchar_t **argv, int *piNext);
  95. BOOL TestInstall(PCWSTR manifest, __int64 flags, DWORD beginInstallFlags, DWORD installFlags, DWORD endInstallFlags);
  96. int TestDiffDir(PCWSTR dir1, PCWSTR dir2);
  97. BOOL TestSearchPath(int argc, wchar_t** argv, int* piNext);
  98. BOOL TestMSIInstall(int argc, wchar_t** argv, int* piNext);
  99. int TestDirWalk(PCWSTR root, PWSTR filter);
  100. BOOL TestLoadLibrary(int argc, wchar_t** argv, int* piNext);
  101. int TestAssemblyName(VOID);
  102. int TestPrecomiledManifest(PCWSTR szFileName);
  103. int TestPCMTime(PCWSTR manifestFilename);
  104. int TestCreateProcess(wchar_t** argv);
  105. int TestCreateProcess2(wchar_t** argv);
  106. BOOL TestInstallPrivateAssembly(int argc, wchar_t** argv, int* piNext);
  107. BOOL TestManifestProbing(int argc, wchar_t** argv, int* piNext);
  108. int TestCreateMultiLevelDirectory(PCWSTR dirs);
  109. BOOL TestXMLDOM(PCWSTR xmlfilename);
  110. BOOL TestFusionArray(PCWSTR, PCWSTR);
  111. BOOL TestGeneratePathFromIdentityAttributeString(PCWSTR str);
  112. BOOL TestRefreshAssembly(PCWSTR wsAssembly);
  113. BOOL TestInstallWithInstallInfo(PCWSTR wsAssemblyManifest, PCWSTR wsReference);
  114. BOOL TestOpeningStuff(PCWSTR wsSourceName, PCWSTR wsType, PCWSTR wsCount);
  115. BOOL TestVerifyFileSignature(PCWSTR wsFilename);
  116. BOOL TestInstallLikeWindowsSetup(PCWSTR szDirectory, PCWSTR szCodebase);
  117. BOOL TestDumpContainedManifests(PCWSTR wsFilename);
  118. BOOL TestGenerateStringWithIdenticalHash(WCHAR iString[33]);
  119. BOOL TestAssemblyIdentityHash();
  120. void TestInherit();
  121. void TestNoInherit();
  122. void TestEmpty();
  123. BOOL TestMessagePerf(int argc, wchar_t **arg, int *piNext);
  124. LRESULT CALLBACK TestMessagePerfWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
  125. void TestTrickyMultipleAssemblyCacheItems(PCWSTR);
  126. void TestSfcScanKickoff();
  127. void GenerateStrongNameAndPublicKey(PCWSTR wsCertificate);
  128. VOID TestCreateActctxLeakHandles(DWORD num);
  129. BOOL TestSystemDefaultActivationContextGeneration();
  130. BOOL TestAsyncIO(int argc, wchar_t **argv, int *piNext);
  131. void TestRefCount();
  132. void TestGuidSort();
  133. void TestStringSort();
  134. BOOL TestNewCatalogSignerThingy(PCWSTR pcwszCatalog);
  135. void TestExeDll();
  136. int TestThreadInheritLeak();
  137. BOOL TestSxsSfcUI();
  138. void TestGetModuleHandleEx();
  139. void TestGetFullPathName(PCWSTR);
  140. void TestCreateFile(PCWSTR);
  141. void TestGetPathBaseName(LPCWSTR Path);
  142. PCSTR PrintPathToString(RTL_PATH_TYPE);
  143. void TestPathType(PCWSTR*);
  144. void TestVersion();
  145. void TestGetProcessImageFileName();
  146. void TestErrorInfra();
  147. void TestQueryActCtx();
  148. void TestQueryActCtx2();
  149. void Test64k();
  150. void TestDotLocalSingleInstancing();
  151. void TestCreateActCtx(int nCreations, wchar_t **rgCreations);
  152. void TestCreateActctxLikeCreateProcess();
  153. void TestCreateActctxAdminOverride();
  154. void TestQueryManifestInformationBasic(PCWSTR pszManifest);
  155. void TestCreateActctxWindowsShellManifest();
  156. void TestCreateGlobalEvent();
  157. void TestHandleLeaks(void);
  158. void TestCRuntimeAsms(void);
  159. BOOL TestMfcCreateAndMarshal(void);
  160. void TestAtlCreate(void);
  161. void TestAlignment(void);
  162. BOOL TestPrivateSha1Impl(PCWSTR pcwszDirName);
  163. BOOL TestNewSxsInstallAPI(PCWSTR pcwszManifest);
  164. void TestImage(void);
  165. void TestInterlockedAlignment(void);
  166. void TestCreateActCtx_PE_flags0(void);
  167. void TestUninstall(PCWSTR ManifestPath, PCWSTR ReferenceString);
  168. void TestParsePatchInfo(PCWSTR PatchInfoFile);
  169. PCWSTR GetLastErrorMessage();
  170. void DumpXmlErrors();
  171. BOOL TestCoCreate(wchar_t ** argv);
  172. void TestDFS();
  173. BOOL TestFindActCtx_AssemblyInfo(PCWSTR *);
  174. void FusionpTestOleAut1(DWORD dwCoInit = COINIT_MULTITHREADED);
  175. void FusionpTestOleAut2();
  176. void FusionpTestOle32Cache(); // bug 482347 Server RC1 DllGetClassObject of initially activated activation context is called instead of DGCO of current act ctx
  177. void FusionpTestProgidCache();
  178. BOOL FusionpTestUniqueValues();
  179. void TestExpandCabinet(PCWSTR CabinetPath, PCWSTR TargetPath);
  180. BOOL GenerateFileHash(PCWSTR pcwsz);
  181. BOOL TestComctl5Comctl6();
  182. void TestSystemDefaultDllRedirection();
  183. DWORD LastError;
  184. BOOL CreateActCtxLocally(PCWSTR pcwszManifestFile, PCWSTR pcwszConfigFile);
  185. BOOL LoadSxs();
  186. int Usage(const char* argv0);
  187. PFNCreateAssemblyCache g_pfnCreateAssemblyCache;
  188. PFNCreateAssemblyCacheItem g_pfnCreateAssemblyCacheItem;
  189. SXSP_DEBUG_FUNCTION g_pfnSxspDebug;
  190. PSXS_BEGIN_ASSEMBLY_INSTALL g_pfnSxsBeginAssemblyInstall;
  191. PSXS_INSTALL_W g_pfnSxsInstallW;
  192. PSXS_END_ASSEMBLY_INSTALL g_pfnSxsEndAssemblyInstall;
  193. PSXSPGENERATEMANIFESTPATHONASSEMBLYIDENTITY g_pfnGenerateManifestPathOnAssemblyIdentity;
  194. BOOL (WINAPI *g_pfnSxsGenerateActivationContext)(PSXS_GENERATE_ACTIVATION_CONTEXT_PARAMETERS Parameters);
  195. PSXS_UNINSTALL_W_ROUTINE g_pfnSxsUninstallW;
  196. PSXS_QUERY_MANIFEST_INFORMATION g_pfnQueryManifestInformation;
  197. PSXS_PROBE_ASSEMBLY_INSTALLATION g_pfnSxsProbeAssemblyInstallation;
  198. PSXS_QUERY_MANIFEST_INFORMATION g_pfnSxsQueryManifestInformation;
  199. PFN_SXS_FIND_CLR_CLASS_INFO g_pfnClrClass;
  200. PFN_SXS_FIND_CLR_SURROGATE_INFO g_pfnClrSurrogate;
  201. PFN_SXS_LOOKUP_CLR_GUID g_pfnClrLookup;
  202. BOOL ParseProcessorArchitecture(int argc, wchar_t** argv, int* piCurrent);
  203. BOOL ParseLangId(int argc, wchar_t** argv, int* piCurrent);
  204. PCWSTR FusionpThreadUnsafeGetLastWin32ErrorMessageW()
  205. {
  206. CSxsPreserveLastError ple;
  207. static WCHAR LastErrorMessage[4096];
  208. LastErrorMessage[0] = 0;
  209. ::FormatMessageW(
  210. FORMAT_MESSAGE_FROM_SYSTEM,
  211. NULL,
  212. ::FusionpGetLastWin32Error(),
  213. 0,
  214. LastErrorMessage,
  215. RTL_NUMBER_OF(LastErrorMessage),
  216. NULL);
  217. if (LastErrorMessage[0] != 0)
  218. {
  219. PWSTR p = LastErrorMessage + ::StringLength(LastErrorMessage) - 1;
  220. while (p != LastErrorMessage && (*p == '\n' || *p == '\r' || *p == ' ' || *p == '\t'))
  221. {
  222. *p-- = 0;
  223. }
  224. }
  225. ple.Restore();
  226. return LastErrorMessage;
  227. }
  228. void __stdcall ThrowLastError(DWORD error)
  229. {
  230. RaiseException(error, 0, 0, NULL);
  231. //throw HRESULT_FROM_WIN32(error);
  232. }
  233. void __stdcall ThrowWin32(ULONG_PTR error = ::GetLastError())
  234. {
  235. ThrowLastError(static_cast<DWORD>(error));
  236. }
  237. void __stdcall CheckHresult(HRESULT hr)
  238. {
  239. if (FAILED(hr))
  240. throw hr;
  241. }
  242. void SetDllBitInPeImage(PCWSTR Path)
  243. /*++
  244. .exes and .dlls are the same format except one bit in the headers distinguishes them.
  245. --*/
  246. {
  247. CFusionFile File;
  248. CFileMapping FileMapping;
  249. CMappedViewOfFile MappedViewOfFile;
  250. if (!File.Win32CreateFile(Path, GENERIC_READ | GENERIC_WRITE, 0, OPEN_EXISTING))
  251. ThrowLastError();
  252. if (!FileMapping.Win32CreateFileMapping(File, PAGE_READWRITE))
  253. ThrowLastError();
  254. if (!MappedViewOfFile.Win32MapViewOfFile(FileMapping, FILE_MAP_WRITE))
  255. ThrowLastError();
  256. PIMAGE_NT_HEADERS NtHeaders = ImageNtHeader(static_cast<PVOID>(MappedViewOfFile));
  257. if (NtHeaders == NULL)
  258. ThrowLastError(ERROR_BAD_EXE_FORMAT);
  259. // This is correct for PE32 or PE32+.
  260. NtHeaders->FileHeader.Characteristics |= IMAGE_FILE_DLL;
  261. if (!MappedViewOfFile.Win32Close())
  262. ThrowLastError();
  263. if (!FileMapping.Win32Close())
  264. ThrowLastError();
  265. if (!File.Win32Close())
  266. ThrowLastError();
  267. }
  268. PCSTR PrintPathToString(RTL_PATH_TYPE PathType)
  269. {
  270. switch (PathType)
  271. {
  272. #define X(x) case x: return #x;
  273. X(RtlPathTypeUnknown)
  274. X(RtlPathTypeUncAbsolute)
  275. X(RtlPathTypeDriveAbsolute)
  276. X(RtlPathTypeDriveRelative)
  277. X(RtlPathTypeRooted)
  278. X(RtlPathTypeRelative)
  279. X(RtlPathTypeLocalDevice)
  280. X(RtlPathTypeRootLocalDevice)
  281. #undef X
  282. default:
  283. return "unknown";
  284. }
  285. }
  286. void TestPathType(const PCWSTR* argv)
  287. {
  288. if (*argv != NULL)
  289. {
  290. while (*argv != NULL)
  291. {
  292. RTL_PATH_TYPE PathType = SxspDetermineDosPathNameType(*argv);
  293. printf("%ls -> %s\n", *argv, PrintPathToString(PathType));
  294. argv += 1;
  295. }
  296. }
  297. else
  298. {
  299. const static PCWSTR args[] =
  300. {
  301. L"a",
  302. L"\\a",
  303. L"\\\\a",
  304. L"\\\\\\a",
  305. L"a:",
  306. L"a:\\",
  307. L"\\?",
  308. L"\\.",
  309. L"\\\\?",
  310. L"\\\\.",
  311. L"\\\\?\\",
  312. L"\\\\.\\",
  313. L"\\\\?\\a",
  314. L"\\\\.\\a",
  315. L"\\\\?\\a:",
  316. L"\\\\.\\a:",
  317. L"\\\\?\\a:\\",
  318. L"\\\\.\\a:\\",
  319. L"\\\\?\\unc",
  320. L"\\\\.\\unc",
  321. L"\\\\?\\unc\\",
  322. L"\\\\.\\unc\\",
  323. NULL
  324. };
  325. TestPathType(args);
  326. }
  327. }
  328. CSxsTestGlobals g;
  329. const static struct
  330. {
  331. DWORD (WINAPI * GetModuleFileNameW)(HMODULE, LPWSTR, DWORD);
  332. SIZE_T (WINAPI * VirtualQuery)(LPCVOID, PMEMORY_BASIC_INFORMATION, SIZE_T);
  333. BOOL (WINAPI * ReadFile)(HANDLE, LPVOID, DWORD, LPDWORD, LPOVERLAPPED);
  334. BOOL (WINAPI * WriteFile)(HANDLE, LPCVOID, DWORD, LPDWORD, LPOVERLAPPED);
  335. UINT (WINAPI * GetTempFileNameW)(LPCWSTR, LPCWSTR, UINT, LPWSTR);
  336. BOOL (WINAPI * DeleteFileW)(LPCWSTR);
  337. }
  338. Kernel32 =
  339. {
  340. GetModuleFileNameW,
  341. VirtualQuery,
  342. ReadFile,
  343. WriteFile,
  344. GetTempFileNameW,
  345. DeleteFileW
  346. };
  347. const static struct
  348. {
  349. HRESULT (WINAPI * IIDFromString)(LPOLESTR, LPIID);
  350. HRESULT (WINAPI * CLSIDFromString)(LPOLESTR, LPIID);
  351. HRESULT (WINAPI * CoCreateInstance)(REFCLSID, LPUNKNOWN, DWORD, REFIID, LPVOID*);
  352. HRESULT (WINAPI * CoInitialize)(LPVOID);
  353. void (WINAPI * CoUninitialize)();
  354. HRESULT (WINAPI * CoInitializeEx)(void * Reserved, DWORD dwCoInit);
  355. }
  356. Ole32 =
  357. {
  358. IIDFromString,
  359. CLSIDFromString,
  360. CoCreateInstance,
  361. CoInitialize,
  362. CoUninitialize,
  363. CoInitializeEx,
  364. };
  365. void
  366. ManifestStringToTempFile(
  367. PCWSTR ManifestString,
  368. CBaseStringBuffer &rTempFilePath
  369. )
  370. {
  371. CFusionFile File;
  372. WCHAR xTempFilePath[MAX_PATH];
  373. WCHAR TempDirectory[MAX_PATH];
  374. const static WCHAR NativeUnicodeByteOrderMark = 0xfeff;
  375. DWORD BytesWritten = 0;
  376. //if (!::GetTempPathW(NUMBER_OF(TempDirectory), TempDirectory))
  377. // ThrowLastError();
  378. Kernel32.GetModuleFileNameW(NULL, TempDirectory, NUMBER_OF(TempDirectory));
  379. *wcsrchr(TempDirectory, '\\') = 0;
  380. ::Trace("TempDirectory:%ls\n", TempDirectory);
  381. if (!Kernel32.GetTempFileNameW(TempDirectory, L"", 0, xTempFilePath))
  382. ::ThrowLastError();
  383. rTempFilePath.Win32Assign(xTempFilePath, wcslen(xTempFilePath));
  384. ::Trace("xTempFilePath:%ls\n", xTempFilePath);
  385. ::Trace("TempFilePath:%ls\n", static_cast<PCWSTR>(xTempFilePath));
  386. if (!File.Win32CreateFile(rTempFilePath, GENERIC_WRITE, 0, CREATE_ALWAYS))
  387. ::ThrowLastError();
  388. if (!Kernel32.WriteFile(File, &NativeUnicodeByteOrderMark, sizeof(NativeUnicodeByteOrderMark), &BytesWritten, NULL))
  389. ::ThrowLastError();
  390. if (!Kernel32.WriteFile(File, ManifestString, static_cast<DWORD>(sizeof(*ManifestString) * StringLength(ManifestString)), &BytesWritten, NULL))
  391. ::ThrowLastError();
  392. }
  393. HANDLE
  394. CreateActivationContextFromStringW(
  395. PCWSTR ManifestString
  396. )
  397. {
  398. CStringBuffer TempFilePath;
  399. ::ManifestStringToTempFile(ManifestString, TempFilePath);
  400. ACTCTXW ActivationContextCreate = { sizeof(ActivationContextCreate) };
  401. ActivationContextCreate.lpSource = TempFilePath;
  402. HANDLE ActivationContextHandle = ::CreateActCtxW(&ActivationContextCreate);
  403. DWORD Error = ::GetLastError();
  404. Kernel32.DeleteFileW(TempFilePath);
  405. if (ActivationContextHandle == INVALID_HANDLE_VALUE)
  406. ::ThrowLastError(Error);
  407. return ActivationContextHandle;
  408. }
  409. int Usage(const wchar_t* argv0)
  410. {
  411. #if 0
  412. std::wstring strargv0 = argv0;
  413. fprintf(stderr,
  414. "%ls",
  415. (
  416. L"Usage: \n"
  417. L" " + strargv0 + L" [install-flags] manifest-or-image-with-manifest-resource-path\n"
  418. L" " + strargv0 + L" [-pa processor-architecture] [-langid langid] -d manifest-path ...\n"
  419. L" " + strargv0 + L" [-pa processor-architecture] [-langid langid] -p manifest-path ...\n"
  420. L" " + strargv0 + L" [-pa processor-architecture] [-langid langid] -w32 manifest-path ...\n"
  421. L" " + strargv0 + L" [-pa processor-architecture] [-langid langid] -msi msi-script...\n"
  422. L" " + strargv0 + L" -tcreateprocess ...\n"
  423. L" " + strargv0 + L" -tsearchpath ...\n"
  424. L" " + strargv0 + L" -tcreateprocess ...\n"
  425. L" " + strargv0 + L" -tempty test pushing a special empty context ...\n"
  426. L" " + strargv0 + L" -tinherit test the usual default inheritance ...\n"
  427. L" " + strargv0 + L" -tnoinherit test the noinherit bit ...\n"
  428. L" " + strargv0 + L" [-threads n] create n threads for some tests ...\n"
  429. L" " + strargv0 + L" probably other choices, use the source\n"
  430. L"\n"
  431. L"install-flags:\n"
  432. L" -i\n"
  433. L" -install\n"
  434. L" -install-from-resource\n"
  435. L" -install-move\n"
  436. ).c_str()
  437. );
  438. #endif
  439. return EXIT_FAILURE;
  440. }
  441. const wchar_t* GetLastOperation()
  442. {
  443. return g.lastOperation;
  444. }
  445. void SetLastOperation(const wchar_t* format, ...)
  446. {
  447. va_list args;
  448. g.lastOperation[0] = 0;
  449. g.lastOperation[NUMBER_OF(g.lastOperation) - 1] = 0;
  450. va_start(args, format);
  451. _vsnwprintf(g.lastOperation, NUMBER_OF(g.lastOperation) - 1, format, args);
  452. va_end(args);
  453. }
  454. HANDLE DuplicateHandle(HANDLE handle)
  455. {
  456. HANDLE newHandle = NULL;
  457. if (!DuplicateHandle(GetCurrentProcess(), handle, GetCurrentProcess(), &newHandle, 0, FALSE, DUPLICATE_SAME_ACCESS))
  458. {
  459. ThrowLastError();
  460. }
  461. return newHandle;
  462. }
  463. __int64 IsFlag(PCWSTR arg)
  464. {
  465. const static struct
  466. {
  467. WCHAR name[32];
  468. __int64 value;
  469. } flags[] =
  470. {
  471. { L"i", SXSTEST_BEGIN_INSTALL},
  472. { L"install", SXSTEST_BEGIN_INSTALL},
  473. { L"install-from-resource", SXS_INSTALL_FLAG_FROM_RESOURCE | SXSTEST_INSTALL},
  474. { L"install-move", SXS_INSTALL_FLAG_MOVE | SXSTEST_INSTALL },
  475. { L"install-dir", SXS_INSTALL_FLAG_FROM_DIRECTORY | SXSTEST_INSTALL},
  476. { L"install-dir-recursive", SXS_INSTALL_FLAG_FROM_DIRECTORY_RECURSIVE | SXSTEST_INSTALL},
  477. { L"install-no-verify", SXS_INSTALL_FLAG_NO_VERIFY | SXSTEST_INSTALL},
  478. { L"install-no-transact", SXS_INSTALL_FLAG_NOT_TRANSACTIONAL | SXSTEST_INSTALL},
  479. { L"install-replace-existing", SXS_INSTALL_FLAG_REPLACE_EXISTING | SXSTEST_INSTALL},
  480. { L"begin-install-replace-existing", SXS_BEGIN_ASSEMBLY_INSTALL_FLAG_REPLACE_EXISTING | SXSTEST_BEGIN_INSTALL},
  481. { L"begin-install-from-resource", SXS_BEGIN_ASSEMBLY_INSTALL_FLAG_FROM_RESOURCE | SXSTEST_BEGIN_INSTALL},
  482. { L"begin-install-move", SXS_BEGIN_ASSEMBLY_INSTALL_FLAG_MOVE | SXSTEST_BEGIN_INSTALL },
  483. { L"begin-install-dir", SXS_BEGIN_ASSEMBLY_INSTALL_FLAG_FROM_DIRECTORY | SXSTEST_BEGIN_INSTALL},
  484. { L"begin-install-dir-recursive", SXS_BEGIN_ASSEMBLY_INSTALL_FLAG_FROM_DIRECTORY_RECURSIVE | SXSTEST_BEGIN_INSTALL},
  485. { L"begin-install-no-verify", SXS_BEGIN_ASSEMBLY_INSTALL_FLAG_NO_VERIFY | SXSTEST_BEGIN_INSTALL},
  486. { L"begin-install-no-transact", SXS_BEGIN_ASSEMBLY_INSTALL_FLAG_NOT_TRANSACTIONAL | SXSTEST_BEGIN_INSTALL},
  487. { L"end-install-no-verify", SXS_END_ASSEMBLY_INSTALL_FLAG_NO_VERIFY | SXSTEST_END_INSTALL},
  488. { L"threads", SXSTEST_THREADS },
  489. { L"-installed-dll", SXSTEST_INSTALLED_DLL },
  490. { L"-built-dll", SXSTEST_BUILT_DLL },
  491. { L"-static", SXSTEST_STATIC_DLL },
  492. { L"-static-dll", SXSTEST_STATIC_DLL },
  493. { L"-", SXSTEST_END_OF_FLAGS }
  494. };
  495. if (*arg == '-')
  496. {
  497. arg += 1;
  498. for (SIZE_T i = 0 ; i != NUMBER_OF(flags) ; ++i)
  499. {
  500. if (_wcsicmp(flags[i].name, arg) == 0)
  501. return flags[i].value;
  502. }
  503. }
  504. return 0;
  505. }
  506. DWORD __stdcall ThreadMain(PVOID)
  507. {
  508. //
  509. // We run stuff in other threads via QueueUserAPC.
  510. //
  511. __try
  512. {
  513. WaitForSingleObjectEx(g.ThreadExitEvent, INFINITE, TRUE);
  514. }
  515. __except(EXCEPTION_EXECUTE_HANDLER)
  516. {
  517. #if DBG
  518. if (IsDebuggerPresent())
  519. {
  520. FUSION_DEBUG_BREAK();
  521. }
  522. #endif
  523. QueueUserAPC(ThrowWin32, g.MainThread, GetExceptionCode());
  524. }
  525. return 0;
  526. }
  527. void CreateThreads()
  528. {
  529. INT i;
  530. g.MainThread = DuplicateHandle(GetCurrentThread());
  531. g.ThreadExitEvent = CreateEventW(NULL, TRUE, FALSE, NULL);
  532. if (g.ThreadExitEvent == NULL)
  533. {
  534. ThrowLastError();
  535. }
  536. for (i = 0 ; i < g.NumberOfThreads ; i++)
  537. {
  538. g.Threads[i] = CreateThread(NULL, 0, ThreadMain, NULL, 0, NULL);
  539. if (g.Threads[i] == NULL)
  540. {
  541. int error = ::GetLastError();
  542. if (i > 2)
  543. {
  544. fprintf(stderr, "Only able to created %d threads, error=%d, continuing\n", i, error);
  545. g.NumberOfThreads = i;
  546. break;
  547. }
  548. fprintf(stderr, "Unable to create threads, error=%d, terminating\n", error);
  549. ThrowWin32(error);
  550. }
  551. }
  552. }
  553. void
  554. GetFlags(
  555. wchar_t**& argv,
  556. __int64& flags,
  557. DWORD& beginInstallFlags,
  558. DWORD& installFlags,
  559. DWORD& endInstallFlags
  560. )
  561. {
  562. __int64 flag;
  563. while (flag = IsFlag(argv[1]))
  564. {
  565. ++argv;
  566. if (flag & SXSTEST_END_OF_FLAGS)
  567. {
  568. break;
  569. }
  570. else if (flag & SXSTEST_BEGIN_INSTALL)
  571. {
  572. beginInstallFlags |= flag;
  573. }
  574. else if (flag & SXSTEST_INSTALL)
  575. {
  576. installFlags |= flag;
  577. }
  578. else if (flag & SXSTEST_END_INSTALL)
  579. {
  580. endInstallFlags |= flag;
  581. }
  582. else if (flag & SXSTEST_THREADS)
  583. {
  584. g.NumberOfThreads = _wtoi(*++argv);
  585. if (g.NumberOfThreads > NUMBER_OF(g.Threads))
  586. {
  587. g.NumberOfThreads = NUMBER_OF(g.Threads);
  588. }
  589. }
  590. else if (flag & SXSTEST_INSTALLED_DLL)
  591. {
  592. LoadInstalledSxsDll();
  593. }
  594. else if (flag & SXSTEST_BUILT_DLL)
  595. {
  596. LoadBuiltSxsDll();
  597. }
  598. else if (flag & SXSTEST_STATIC_DLL)
  599. {
  600. UseStaticSxsDll();
  601. }
  602. // always set flags because normal installation is 0 now
  603. flags |= flag;
  604. }
  605. }
  606. VOID
  607. FusionpSetSystemSetupInProgress(bool f)
  608. {
  609. CFusionRegKey Regkey;
  610. CFusionRegKey RegkeyLocalMachine(HKEY_LOCAL_MACHINE);
  611. if (!RegkeyLocalMachine.OpenSubKey(Regkey, L"System\\Setup", KEY_ALL_ACCESS))
  612. return;
  613. Regkey.SetValue(L"SystemSetupInProgress", f ? 1 : 0);
  614. }
  615. int Main(int argc, wchar_t** argv)
  616. {
  617. int i = 0;
  618. __int64 flags = 0;
  619. //__int64 flag = 0;
  620. DWORD beginInstallFlags = 0;
  621. DWORD installFlags = 0;
  622. DWORD endInstallFlags = 0;
  623. wchar_t* argv0 = argv[0];
  624. g.wProcessorArchitecture = SxspGetSystemProcessorArchitecture();
  625. g.wLangId = ::GetUserDefaultLangID();
  626. if (argc > 1)
  627. {
  628. FusionpSetSystemSetupInProgress(false);
  629. __try
  630. {
  631. __try
  632. {
  633. if (!SxsDllMain(GetModuleHandle(NULL), DLL_PROCESS_ATTACH, NULL))
  634. ThrowLastError();
  635. GetFlags(argv, flags, beginInstallFlags, installFlags, endInstallFlags);
  636. i = 1;
  637. // consume global flags...
  638. for (;;)
  639. {
  640. if (::FusionpEqualStringsI(argv[i], L"-pa"))
  641. {
  642. if (!ParseProcessorArchitecture(argc, argv, &i))
  643. goto Exit;
  644. }
  645. else if (::FusionpEqualStringsI(argv[i], L"-langid"))
  646. {
  647. if (!ParseLangId(argc, argv, &i))
  648. goto Exit;
  649. }
  650. else
  651. break;
  652. }
  653. if (false) { }
  654. else if (::FusionpEqualStringsI(argv[i], L"-id"))
  655. {
  656. DWORD index = 0;
  657. if (argv[3]){ // have an index present
  658. index = argv[3][0] - L'0';
  659. }
  660. i = TestGeneratePathFromIdentityAttributeString(argv[2]);
  661. }
  662. else if (::FusionpEqualStringsI(argv[i], L"-tPathType"))
  663. {
  664. TestPathType(argv + i + 1);
  665. }
  666. else if (::FusionpEqualStringsI(argv[i], L"-dfs"))
  667. {
  668. TestDFS();
  669. }
  670. else if (::FusionpEqualStringsI(argv[i], L"-systemdefault"))
  671. {
  672. i = TestSystemDefaultActivationContextGeneration();
  673. }
  674. else if (::FusionpEqualStringsI(argv[i], L"-dom"))
  675. {
  676. i = TestXMLDOM(argv[2]);
  677. }
  678. else if (::FusionpEqualStringsI(argv[i], L"-hash"))
  679. {
  680. i = TestGenerateStringWithIdenticalHash(argv[2]);
  681. }
  682. else if (::FusionpEqualStringsI(argv[i], L"-tasyncio"))
  683. {
  684. i++;
  685. i = TestAsyncIO(argc, argv, &i);
  686. }
  687. else if (::FusionpEqualStringsI(argv[i], L"-assemblyidentityhash"))
  688. {
  689. i = TestAssemblyIdentityHash();
  690. }
  691. else if (::FusionpEqualStringsI(argv[i], L"-array"))
  692. {
  693. i = TestFusionArray(argv[2], argv[3]);
  694. }
  695. else if (::FusionpEqualStringsI(argv[i], L"-diffdir"))
  696. {
  697. i = TestDiffDir(argv[i + 1], argv[i + 2]);
  698. }
  699. else if (::FusionpEqualStringsI(argv[1], L"-pcm"))
  700. {
  701. i = TestPrecomiledManifest(argv[2]);
  702. }
  703. else if (::FusionpEqualStringsI(argv[1], L"-dll"))
  704. {
  705. TestSystemDefaultDllRedirection();
  706. }
  707. else if (::FusionpEqualStringsI(argv[1], L"-testpcm"))
  708. {
  709. i = TestPCMTime(argv[2]);
  710. }
  711. else if (::FusionpEqualStringsI(argv[1], L"-cd"))
  712. {
  713. i = TestCreateMultiLevelDirectory(argv[2]);
  714. }
  715. else if (::FusionpEqualStringsI(argv[i], L"-manifests"))
  716. {
  717. TestDumpContainedManifests(argv[++i]);
  718. }
  719. else if (::FusionpEqualStringsI(argv[1], L"-dirwalk"))
  720. {
  721. i = TestDirWalk(argv[i + 1], argv[i + 2]);
  722. }
  723. else if (::FusionpEqualStringsI(argv[i], L"-cabextract"))
  724. {
  725. TestExpandCabinet(
  726. argv[i+1],
  727. argv[i+2]);
  728. i += 2;
  729. }
  730. else if (::FusionpEqualStringsI(argv[i], L"-patchfile"))
  731. {
  732. TestParsePatchInfo(argv[++i]);
  733. }
  734. else if (::FusionpEqualStringsI(argv[1], L"-tmultiact"))
  735. {
  736. i = TestMultiAct(argc, argv);
  737. }
  738. else if (flags)
  739. {
  740. i = TestInstall(argv[i], flags, beginInstallFlags, installFlags, endInstallFlags);
  741. }
  742. else if (::FusionpEqualStringsI(argv[i], L"-sfcui"))
  743. {
  744. if ( !TestSxsSfcUI() )
  745. goto Exit;
  746. i++;
  747. }
  748. else if (FusionpEqualStringsI( argv[i], L"-installwithinfo"))
  749. {
  750. TestInstallWithInstallInfo(
  751. ( i + 1 < argc ) ? argv[i + 1] : NULL,
  752. ( i + 2 < argc ) ? argv[i+2] : NULL);
  753. i += 2;
  754. }
  755. else if (::FusionpEqualStringsI(argv[i], L"-multicache"))
  756. {
  757. TestTrickyMultipleAssemblyCacheItems(argv[i + 1]);
  758. i++;
  759. }
  760. else if (::FusionpEqualStringsI(argv[i], L"-d"))
  761. {
  762. if (!TestDirect(argc, argv, &i))
  763. goto Exit;
  764. }
  765. else if (::FusionpEqualStringsI(argv[i], L"-tcomctl"))
  766. {
  767. if (!TestComctl5Comctl6())
  768. goto Exit;
  769. }
  770. else if (::FusionpEqualStringsI(argv[i], L"-probe"))
  771. {
  772. i++;
  773. argv[i] = L"foo,type=\"win32\",processorArchitecture=\"x86\",version=\"6.0.0.0\",publicKeyToken=\"6595b64144ccf1df\"";
  774. if (!TestAssemblyProbing(argc, argv, &i))
  775. goto Exit;
  776. }
  777. else if (::FusionpEqualStringsI(argv[i], L"-dirchanges"))
  778. {
  779. if (!TestDirectoryChangeWatcher(argc, argv, &i))
  780. goto Exit;
  781. }
  782. else if (::FusionpEqualStringsI(argv[i], L"-newinstall"))
  783. {
  784. if (!TestNewSxsInstallAPI(argv[++i]))
  785. goto Exit;
  786. }
  787. else if (::FusionpEqualStringsI(argv[i], L"-tuninstall")
  788. || ::FusionpEqualStringsI(argv[i], L"-uninstall"))
  789. {
  790. TestUninstall(argv[i + 1], argv[i + 2]);
  791. goto Exit;
  792. }
  793. else if (::FusionpEqualStringsI(argv[i], L"-hashimage"))
  794. {
  795. if (!GenerateHashOfFileLikeSxsDoes(argv[++i]))
  796. goto Exit;
  797. }
  798. else if (::FusionpEqualStringsI(argv[i], L"-localcreateactctx"))
  799. {
  800. if (!CreateActCtxLocally(argv[i + 1], argv[i+2]))
  801. goto Exit;
  802. i += 2;
  803. }
  804. else if (::FusionpEqualStringsI(argv[i], L"-probemanifest"))
  805. {
  806. if (!TestManifestProbing(argc, argv, &i))
  807. goto Exit;
  808. }
  809. else if (::FusionpEqualStringsI(argv[i], L"-p"))
  810. {
  811. if (!TestXMLParsing(argc, argv, &i))
  812. goto Exit;
  813. }
  814. else if (::FusionpEqualStringsI(argv[i], L"-w32"))
  815. {
  816. TestWin32(argv + i + 1);
  817. }
  818. else if (::FusionpEqualStringsI(argv[i], L"-msi"))
  819. {
  820. if (!TestMSIInstall(argc, argv, &i))
  821. goto Exit;
  822. }
  823. else if (::FusionpEqualStringsI(argv[i], L"-mp"))
  824. {
  825. if (!TestManifestSchema(argc, argv, &i))
  826. goto Exit;
  827. }
  828. else if (::FusionpEqualStringsI(argv[i], L"-act"))
  829. {
  830. if (!TestAct(argc, argv, &i))
  831. goto Exit;
  832. }
  833. else if (::FusionpEqualStringsI(argv[i], L"-hashfile"))
  834. {
  835. if (!GenerateFileHash(argv[++i]))
  836. goto Exit;
  837. }
  838. else if (::FusionpEqualStringsI(argv[i], L"-shatest"))
  839. {
  840. if (!TestPrivateSha1Impl(argv[++i]))
  841. goto Exit;
  842. }
  843. else if (::FusionpEqualStringsI(argv[1], L"-am"))
  844. {
  845. i = TestAssemblyName();
  846. }
  847. else if (::FusionpEqualStringsI(argv[i], L"-tsearchpath"))
  848. {
  849. if (!TestSearchPath(argc, argv, &i))
  850. goto Exit;
  851. }
  852. else if (::FusionpEqualStringsI(argv[i], L"-testmapping"))
  853. {
  854. if (!TestOpeningStuff(argv[i+1], argv[i+2], argv[i+3]))
  855. goto Exit;
  856. i += 3;
  857. }
  858. else if (::FusionpEqualStringsI(argv[i], L"-validatefile"))
  859. {
  860. if (!TestVerifyFileSignature(argv[++i]))
  861. goto Exit;
  862. }
  863. else if (::FusionpEqualStringsI(argv[i], L"-tloadlibrary"))
  864. {
  865. if (!TestLoadLibrary(argc, argv, &i))
  866. goto Exit;
  867. }
  868. else if (::FusionpEqualStringsI(argv[i], L"-refresh"))
  869. {
  870. if (!TestRefreshAssembly(argv[i+1]))
  871. goto Exit;
  872. }
  873. else if (::FusionpEqualStringsI(argv[i], L"-unique"))
  874. {
  875. if (!FusionpTestUniqueValues())
  876. goto Exit;
  877. }
  878. else if (::FusionpEqualStringsI(argv[i], L"-leak"))
  879. {
  880. //
  881. // We dump a little bit of memory
  882. //
  883. UINT iAmount = 0;
  884. iAmount = _wtoi(argv[++i]);
  885. if (!TestLeakMemory(iAmount))
  886. goto Exit;
  887. }
  888. else if (::FusionpEqualStringsI(argv[i], L"-tcreateprocess"))
  889. {
  890. if (!TestCreateProcess(argv + i + 1))
  891. goto Exit;
  892. }
  893. else if (::FusionpEqualStringsI(argv[i], L"-tcreateprocess2"))
  894. {
  895. if (!TestCreateProcess2(argv + i + 1))
  896. goto Exit;
  897. }
  898. else if (::FusionpEqualStringsI(argv[i], L"-tinherit"))
  899. {
  900. TestInherit();
  901. }
  902. else if (::FusionpEqualStringsI(argv[i], L"-tnoinherit"))
  903. {
  904. TestNoInherit();
  905. }
  906. else if (::FusionpEqualStringsI(argv[i], L"-tempty"))
  907. {
  908. TestEmpty();
  909. }
  910. else if (::FusionpEqualStringsI(argv[i], L"-ttsappcmp"))
  911. {
  912. TestCreateGlobalEvent();
  913. }
  914. else if (::FusionpEqualStringsI(argv[i], L"-tmsgperf"))
  915. {
  916. i++;
  917. if (!TestMessagePerf(argc, argv, &i))
  918. goto Exit;
  919. }
  920. else if (::FusionpEqualStringsI(argv[i], L"-twinsetup"))
  921. {
  922. FusionpSetSystemSetupInProgress(true);
  923. if (!TestInstallLikeWindowsSetup(argv[i + 1], (argv[i + 2] != NULL) ? argv[i + 2] : argv[i + 1]))
  924. goto Exit;
  925. i += 3;
  926. }
  927. else if (::FusionpEqualStringsI(argv[i], L"-sfcscan"))
  928. {
  929. TestSfcScanKickoff();
  930. }
  931. else if (::FusionpEqualStringsI(argv[i], L"-certinfo"))
  932. {
  933. GenerateStrongNameAndPublicKey(argv[++i]);
  934. }
  935. else if (::FusionpEqualStringsI(argv[i], L"-thandle"))
  936. {
  937. DWORD iAmount = 0;
  938. iAmount = _wtoi(argv[++i]);
  939. TestCreateActctxLeakHandles(iAmount);
  940. }
  941. else if (::FusionpEqualStringsI(argv[i], L"-catsigner"))
  942. {
  943. TestNewCatalogSignerThingy(argv[++i]);
  944. }
  945. else if (::FusionpEqualStringsI(argv[i], L"-trefcount"))
  946. {
  947. TestRefCount();
  948. }
  949. else if (::FusionpEqualStringsI(argv[i], L"-ttileak"))
  950. {
  951. TestThreadInheritLeak();
  952. }
  953. else if (::FusionpEqualStringsI(argv[i], L"-tguidsort"))
  954. {
  955. TestGuidSort();
  956. }
  957. else if (::FusionpEqualStringsI(argv[i], L"-tstringsort"))
  958. {
  959. TestStringSort();
  960. }
  961. else if (::FusionpEqualStringsI(argv[i], L"-tExeDll"))
  962. {
  963. TestExeDll();
  964. }
  965. else if (FusionpEqualStringsI(argv[i], L"-tExitProcess"))
  966. {
  967. LoadSxs();
  968. g_pfnSxspDebug(SXS_DEBUG_EXIT_PROCESS, 0, 0, NULL);
  969. }
  970. else if (FusionpEqualStringsI(argv[i], L"-tTerminateProcess"))
  971. {
  972. LoadSxs();
  973. g_pfnSxspDebug(SXS_DEBUG_TERMINATE_PROCESS, 0, 0, NULL);
  974. }
  975. else if (FusionpEqualStringsI(argv[i], L"-tLastError"))
  976. {
  977. ::SetLastError(123);
  978. printf("%lu\n", FusionpGetLastWin32Error());
  979. printf("%lu\n", ::GetLastError());
  980. ::FusionpSetLastWin32Error(456);
  981. printf("%lu\n", FusionpGetLastWin32Error());
  982. printf("%lu\n", ::GetLastError());
  983. }
  984. else if (FusionpEqualStringsI(argv[i], L"-tGetModuleHandleEx"))
  985. {
  986. TestGetModuleHandleEx();
  987. }
  988. else if (FusionpEqualStringsI(argv[i], L"-tGetFullPathName"))
  989. {
  990. TestGetFullPathName(argv[i + 1]);
  991. }
  992. else if (FusionpEqualStringsI(argv[i], L"-tCreateFile"))
  993. {
  994. TestCreateFile(argv[i + 1]);
  995. }
  996. else if (FusionpEqualStringsI(argv[i], L"-tGetPathBaseName"))
  997. {
  998. TestGetPathBaseName(argv[i + 1]);
  999. }
  1000. else if (FusionpEqualStringsI(argv[i], L"-tVersion"))
  1001. {
  1002. TestVersion();
  1003. }
  1004. else if (FusionpEqualStringsI(argv[i], L"-tGetProcessImageFileName"))
  1005. {
  1006. TestGetProcessImageFileName();
  1007. }
  1008. else if (FusionpEqualStringsI(argv[i], L"-tErrorInfra"))
  1009. {
  1010. TestErrorInfra();
  1011. }
  1012. else if (FusionpEqualStringsI(argv[i], L"-tQueryActCtx"))
  1013. TestQueryActCtx();
  1014. else if (FusionpEqualStringsI(argv[i], L"-tQueryActCtx2"))
  1015. TestQueryActCtx2();
  1016. else if (FusionpEqualStringsI(argv[i], L"-tqmib"))
  1017. {
  1018. TestQueryManifestInformationBasic(argv[i+1]);
  1019. }
  1020. else if (FusionpEqualStringsI(argv[i], L"-t64k"))
  1021. {
  1022. Test64k();
  1023. }
  1024. else if (FusionpEqualStringsI(argv[i], L"-tcreateactctx"))
  1025. {
  1026. TestCreateActCtx(argc - (i + 1), &argv[i+1]);
  1027. }
  1028. else if (FusionpEqualStringsI(argv[i], L"-TestCreateActCtx_PE_flags0"))
  1029. {
  1030. TestCreateActCtx_PE_flags0();
  1031. }
  1032. else if (FusionpEqualStringsI(argv[i], L"-tDotLocalSingleInstancing"))
  1033. {
  1034. TestDotLocalSingleInstancing();
  1035. }
  1036. else if (FusionpEqualStringsI(argv[i], L"-tCreateActctxLikeCreateProcess"))
  1037. {
  1038. TestCreateActctxLikeCreateProcess();
  1039. }
  1040. else if (FusionpEqualStringsI(argv[i], L"-tCreateActctxLikeCreateProcess"))
  1041. {
  1042. TestCreateActctxLikeCreateProcess();
  1043. }
  1044. else if (FusionpEqualStringsI(argv[i], L"-tCreateActctxAdminOverride"))
  1045. {
  1046. TestCreateActctxAdminOverride();
  1047. }
  1048. else if (FusionpEqualStringsI(argv[i], L"-tCreateActctxWindowsShellManifest"))
  1049. {
  1050. TestCreateActctxWindowsShellManifest();
  1051. }
  1052. else if (FusionpStrCmpI(argv[i], L"-tHandleLeak") == 0)
  1053. {
  1054. //for (SIZE_T i = 0 ; i != 5 ; i += 1)
  1055. TestHandleLeaks();
  1056. }
  1057. else if (FusionpEqualStringsI(argv[i], L"-tMfcCreateAndMarshal"))
  1058. {
  1059. TestMfcCreateAndMarshal();
  1060. }
  1061. else if (FusionpEqualStringsI(argv[i], L"-tAtlCreate"))
  1062. {
  1063. TestAtlCreate();
  1064. }
  1065. else if (FusionpEqualStringsI(argv[i], L"-TestAlignment"))
  1066. {
  1067. TestAlignment();
  1068. }
  1069. else if (FusionpEqualStringsI(argv[i], L"-DoNothingJustSeeIfItRuns"))
  1070. {
  1071. printf("%wZ ran successfully\n", &NtCurrentPeb()->ProcessParameters->ImagePathName);
  1072. }
  1073. else if (FusionpEqualStringsI(argv[i], L"-TestImage"))
  1074. {
  1075. TestImage();
  1076. }
  1077. else if (FusionpEqualStringsI(argv[i], L"-TestInterlockedAlignment"))
  1078. {
  1079. TestInterlockedAlignment();
  1080. }
  1081. else if (FusionpEqualStringsI(argv[i], L"-DumpXmlErrors"))
  1082. {
  1083. DumpXmlErrors();
  1084. }
  1085. else if (FusionpEqualStringsI(argv[i], L"-TestCoCreate"))
  1086. {
  1087. TestCoCreate(argv + i + 1);
  1088. }
  1089. else if (FusionpEqualStringsI(argv[i], L"-TestFindActCtx_AssemblyInfo"))
  1090. {
  1091. TestFindActCtx_AssemblyInfo(const_cast<PCWSTR*>(argv + i + 1));
  1092. }
  1093. else if (FusionpEqualStringsI(argv[i], L"-TestOleAut1"))
  1094. {
  1095. FusionpTestOleAut1();
  1096. }
  1097. else if (FusionpEqualStringsI(argv[i], L"-TestOleAut2"))
  1098. {
  1099. FusionpTestOleAut2();
  1100. }
  1101. else if (FusionpEqualStringsI(argv[i], L"-TestOle32Cache"))
  1102. {
  1103. FusionpTestOle32Cache();
  1104. }
  1105. else if (FusionpEqualStringsI(argv[i], L"-TestProgidCache"))
  1106. {
  1107. FusionpTestProgidCache();
  1108. }
  1109. else if (::FusionpEqualStringsI(argv[i], L"-DeleteShortNamesInRegistry"))
  1110. {
  1111. SxspDeleteShortNamesInRegistry();
  1112. }
  1113. else if (::FusionpEqualStringsI(argv[i], L"-DllInstall"))
  1114. {
  1115. DllInstall(TRUE, NULL);
  1116. }
  1117. else if (::FusionpEqualStringsI(argv[i], L"-snprintf"))
  1118. {
  1119. char buffer[2];
  1120. buffer[0] = 0;
  1121. buffer[1] = 0;
  1122. ::printf("%d\n", ::_snprintf(buffer, 2, "%s", "1"));
  1123. ::printf("%d %d\n", buffer[0], buffer[1]);
  1124. buffer[0] = 0;
  1125. buffer[1] = 0;
  1126. ::printf("%d\n", ::_snprintf(buffer, 2, "%s", "12"));
  1127. ::printf("%d %d\n", buffer[0], buffer[1]);
  1128. buffer[0] = 0;
  1129. buffer[1] = 0;
  1130. ::printf("%d\n", ::_snprintf(buffer, 2, "%s", "123"));
  1131. ::printf("%d %d\n", buffer[0], buffer[1]);
  1132. }
  1133. else
  1134. {
  1135. i = Usage(argv0);
  1136. }
  1137. if (g.ThreadExitEvent)
  1138. {
  1139. SetEvent(g.ThreadExitEvent);
  1140. WaitForMultipleObjectsEx(g.NumberOfThreads, g.Threads, TRUE, INFINITE, TRUE);
  1141. }
  1142. if (g.sxsDll != NULL)
  1143. {
  1144. FreeLibrary(g.sxsDll);
  1145. }
  1146. }
  1147. __finally
  1148. {
  1149. FusionpSetSystemSetupInProgress(false);
  1150. }
  1151. }
  1152. __except(EXCEPTION_EXECUTE_HANDLER)
  1153. {
  1154. #if DBG
  1155. if (IsDebuggerPresent())
  1156. {
  1157. FUSION_DEBUG_BREAK();
  1158. }
  1159. #endif
  1160. i = GetExceptionCode();
  1161. WCHAR message[128];
  1162. DWORD flags = FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_SYSTEM;
  1163. FormatMessageW(flags, NULL, i, 0, message, NUMBER_OF(message), NULL);
  1164. PWSTR end = message + wcslen(message);
  1165. while (end != message && isspace(*(end - 1)))
  1166. {
  1167. --end;
  1168. }
  1169. *end = 0;
  1170. ::Trace("%ls failed, %d, %#x, %ls", g.lastOperation, i, i, message);
  1171. }
  1172. PTEB teb;
  1173. teb = NtCurrentTeb();
  1174. if (teb->CountOfOwnedCriticalSections != 0)
  1175. {
  1176. DbgPrint("teb->CountOfOwnedCriticalSections %d\n", teb->CountOfOwnedCriticalSections);
  1177. //ASSERT(teb->CountOfOwnedCriticalSections == 0);
  1178. }
  1179. return i ? EXIT_SUCCESS : EXIT_FAILURE;
  1180. }
  1181. return Usage(argv[0]);
  1182. Exit:
  1183. return ::GetLastError();
  1184. }
  1185. int TestDiffDir(PCWSTR dir1, PCWSTR dir2)
  1186. {
  1187. CFusionDirectoryDifference diff;
  1188. CStringBuffer buf1;
  1189. CStringBuffer buf2;
  1190. BOOL fSuccess = FALSE;
  1191. if (!buf1.Win32Assign(dir1, ::wcslen(dir1)))
  1192. goto Exit;
  1193. if (!buf2.Win32Assign(dir2, ::wcslen(dir2)))
  1194. goto Exit;
  1195. if (!::FusionpCompareDirectoriesSizewiseRecursively(&diff, buf1, buf2))
  1196. goto Exit;
  1197. diff.DbgPrint(buf1, buf2);
  1198. fSuccess = TRUE;
  1199. Exit:
  1200. return fSuccess ? EXIT_SUCCESS : EXIT_FAILURE;
  1201. }
  1202. PCWSTR GetUser()
  1203. {
  1204. static bool fInited;
  1205. static WCHAR userName[MAX_PATH];
  1206. if (!fInited)
  1207. {
  1208. DWORD size = NUMBER_OF(userName);
  1209. userName[0] = 0;
  1210. userName[1] = 0;
  1211. GetUserNameW(userName, &size);
  1212. if (userName[1] == '-')
  1213. {
  1214. wmemcpy(userName, 2+userName, 1+wcslen(2+userName));
  1215. }
  1216. fInited = true;
  1217. }
  1218. return userName;
  1219. }
  1220. void UserBreakPoint(PCWSTR user)
  1221. {
  1222. if (::IsDebuggerPresent() && _wcsicmp(GetUser(), user) == 0)
  1223. {
  1224. ASSERT2_NTC(FALSE, __FUNCTION__);
  1225. }
  1226. }
  1227. __declspec(selectany) extern const UNICODE_STRING x86String = RTL_CONSTANT_STRING(L"x86");
  1228. __declspec(selectany) extern const UNICODE_STRING i386String = RTL_CONSTANT_STRING(L"i386");
  1229. __declspec(selectany) extern const UNICODE_STRING BackslashString = RTL_CONSTANT_STRING(L"\\");
  1230. __declspec(selectany) extern const UNICODE_STRING asms01_dot_cabString = RTL_CONSTANT_STRING(L"asms01.cab");
  1231. __declspec(selectany) extern const UNICODE_STRING ProcessorBuildObjString = RTL_CONSTANT_STRING(SXSP_PROCESSOR_BUILD_OBJ_DIRECTORY_W);
  1232. __declspec(selectany) extern const UNICODE_STRING ProcessorInstallDirectoryString = RTL_CONSTANT_STRING(SXSP_PROCESSOR_INSTALL_DIRECTORY_W);
  1233. BOOL
  1234. SxspConvertI386ToX86(
  1235. CBaseStringBuffer & buffProcessor
  1236. )
  1237. {
  1238. FN_PROLOG_WIN32;
  1239. if (::FusionpEqualStringsI(buffProcessor, i386String.Buffer, RTL_STRING_GET_LENGTH_CHARS(&i386String)))
  1240. {
  1241. IFW32FALSE_EXIT(buffProcessor.Win32Assign(&x86String));
  1242. }
  1243. FN_EPILOG;
  1244. }
  1245. inline
  1246. BOOL
  1247. SxspConvertX86ToI386(
  1248. CBaseStringBuffer & buffProcessor
  1249. )
  1250. {
  1251. FN_PROLOG_WIN32;
  1252. if (::FusionpEqualStringsI(buffProcessor, x86String.Buffer, RTL_STRING_GET_LENGTH_CHARS(&x86String)))
  1253. {
  1254. IFW32FALSE_EXIT(buffProcessor.Win32Assign(&i386String));
  1255. }
  1256. FN_EPILOG;
  1257. }
  1258. typedef struct _SXSP_PROCEDURE_NAME_AND_ADDRESS {
  1259. union
  1260. {
  1261. PCSTR Name;
  1262. ULONG_PTR Ordinal;
  1263. };
  1264. PVOID *Address;
  1265. } SXSP_PROCEDURE_NAME_AND_ADDRESS, *PSXSP_PROCEDURE_NAME_AND_ADDRESS;
  1266. const static SXSP_PROCEDURE_NAME_AND_ADDRESS SxsProcs[] =
  1267. {
  1268. { "CreateAssemblyCache", (PVOID*)&g_pfnCreateAssemblyCache },
  1269. //{ "CreateAssemblyCacheItem", (PVOID*)&g_pfnCreateAssemblyCacheItem },
  1270. { "SxsBeginAssemblyInstall", (PVOID*)&g_pfnSxsBeginAssemblyInstall },
  1271. { "SxsEndAssemblyInstall", (PVOID*)&g_pfnSxsEndAssemblyInstall },
  1272. { "SxspGenerateManifestPathOnAssemblyIdentity", (PVOID*)&g_pfnGenerateManifestPathOnAssemblyIdentity },
  1273. { "SxsGenerateActivationContext", (PVOID*)&g_pfnSxsGenerateActivationContext },
  1274. { "SxsQueryManifestInformation", (PVOID*)&g_pfnQueryManifestInformation },
  1275. { "SxsInstallW", (PVOID*)&g_pfnSxsInstallW },
  1276. { "SxsUninstallW", (PVOID*)&g_pfnSxsUninstallW },
  1277. { (PCSTR)SXSP_DEBUG_ORDINAL, (PVOID*)&g_pfnSxspDebug },
  1278. { SXS_PROBE_ASSEMBLY_INSTALLATION, (PVOID*)&g_pfnSxsProbeAssemblyInstallation },
  1279. { SXS_FIND_CLR_SURROGATE_INFO, (PVOID*)&g_pfnClrSurrogate },
  1280. { SXS_FIND_CLR_CLASS_INFO, (PVOID*)&g_pfnClrClass },
  1281. { SXS_LOOKUP_CLR_GUID, (PVOID*)&g_pfnClrLookup }
  1282. };
  1283. extern const UNICODE_STRING sxs_dot_dll_UnicodeString = RTL_CONSTANT_STRING(L"sxs.dll");
  1284. extern const UNICODE_STRING sxs_dot_cap_dot_dll_UnicodeString = RTL_CONSTANT_STRING(L"sxs.cap.dll");
  1285. extern const UNICODE_STRING d_UnicodeString = RTL_CONSTANT_STRING(L"d");
  1286. extern const UNICODE_STRING obj_UnicodeString = RTL_CONSTANT_STRING(L"obj");
  1287. extern const UNICODE_STRING dll_backslash_whistler_UnicodeString = RTL_CONSTANT_STRING(L"dll\\whistler");
  1288. extern const UNICODE_STRING base_backslash_win32_backslash_fusion_backslash_dll_whistler_UnicodeString = RTL_CONSTANT_STRING(L"base\\win32\\fusion\\dll\\whistler");
  1289. BOOL LoadSxsDllCommonTail()
  1290. {
  1291. //
  1292. // raise an exception if the load failed
  1293. // call GetProcAddress a bunch of times
  1294. //
  1295. FN_PROLOG_WIN32;
  1296. BOOL IsWow = FALSE;
  1297. SIZE_T i = 0;
  1298. if (g.sxsDll == NULL)
  1299. {
  1300. ThrowLastError();
  1301. }
  1302. for (i = 0 ; i != NUMBER_OF(SxsProcs) ; ++i)
  1303. {
  1304. if (SxsProcs[i].Ordinal == SXSP_DEBUG_ORDINAL)
  1305. {
  1306. GetSxsProc(SxsProcs[i].Ordinal, SxsProcs[i].Address);
  1307. }
  1308. else
  1309. {
  1310. GetSxsProc(SxsProcs[i].Name, SxsProcs[i].Address);
  1311. }
  1312. }
  1313. if (IsWow64Process(GetCurrentProcess(), &IsWow) && !IsWow)
  1314. {
  1315. UserBreakPoint(L"JayKrell");
  1316. }
  1317. FN_EPILOG;
  1318. }
  1319. BOOL LoadInstalledSxsDll()
  1320. {
  1321. FN_PROLOG_WIN32;
  1322. if (g.sxsDll == NULL)
  1323. {
  1324. CTinyStringBuffer DllPath;
  1325. CStringBufferAccessor acc;
  1326. IFW32FALSE_EXIT(DllPath.Win32ResizeBuffer(MAX_PATH, eDoNotPreserveBufferContents));
  1327. acc.Attach(&DllPath);
  1328. acc.GetBufferPtr()[acc.GetBufferCch() - 1] = 0;
  1329. GetSystemDirectoryW(
  1330. acc.GetBufferPtr(),
  1331. acc.GetBufferCchAsDWORD() - 1
  1332. );
  1333. acc.Detach();
  1334. IFW32FALSE_EXIT(DllPath.Win32AppendPathElement(&sxs_dot_dll_UnicodeString));
  1335. g.sxsDll = LoadLibraryW(DllPath);
  1336. LoadSxsDllCommonTail();
  1337. }
  1338. FN_EPILOG;
  1339. }
  1340. BOOL
  1341. SxspGetEnvironmentVariable(
  1342. PCWSTR Name,
  1343. CBaseStringBuffer &Value,
  1344. DWORD *pdw OPTIONAL = NULL
  1345. )
  1346. {
  1347. FN_PROLOG_WIN32;
  1348. CStringBufferAccessor acc;
  1349. DWORD dw = 0;
  1350. pdw = (pdw != NULL) ? pdw : &dw;
  1351. IFW32FALSE_EXIT(Value.Win32ResizeBuffer(MAX_PATH, eDoNotPreserveBufferContents));
  1352. acc.Attach(&Value);
  1353. acc.GetBufferPtr()[0] = 0;
  1354. acc.GetBufferPtr()[acc.GetBufferCch() - 1] = 0;
  1355. *pdw = ::GetEnvironmentVariableW(
  1356. Name,
  1357. acc.GetBufferPtr(),
  1358. acc.GetBufferCchAsDWORD() - 1
  1359. );
  1360. FN_EPILOG;
  1361. }
  1362. BOOL
  1363. UseStaticSxsDll()
  1364. {
  1365. FN_PROLOG_WIN32;
  1366. if (g.sxsDll == NULL)
  1367. {
  1368. g.sxsDll = ::GetModuleHandleW(NULL);
  1369. LoadSxsDllCommonTail();
  1370. }
  1371. FN_EPILOG;
  1372. }
  1373. BOOL
  1374. LoadBuiltSxsDll()
  1375. {
  1376. FN_PROLOG_WIN32;
  1377. if (g.sxsDll == NULL)
  1378. {
  1379. CTinyStringBuffer DllPath;
  1380. CTinyStringBuffer SdxRoot;
  1381. CTinyStringBuffer ExePath;
  1382. CTinyStringBuffer BuildAltDirEnvironmentVariable;
  1383. CTinyStringBuffer ObjDirEnvironmentVariable;
  1384. CTinyStringBuffer CheckedAltDirEnvironmentVariable;
  1385. #if DBG
  1386. bool FreeBuild = false;
  1387. #else
  1388. bool FreeBuild = true;
  1389. #endif
  1390. CTinyStringBuffer ObjDir;
  1391. CStringBufferAccessor acc;
  1392. //
  1393. // see makefile.def
  1394. //
  1395. SxspGetEnvironmentVariable(L"BUILD_ALT_DIR", BuildAltDirEnvironmentVariable);
  1396. SxspGetEnvironmentVariable(L"_OBJ_DIR", ObjDirEnvironmentVariable);
  1397. SxspGetEnvironmentVariable(L"CHECKED_ALT_DIR", CheckedAltDirEnvironmentVariable);
  1398. if (BuildAltDirEnvironmentVariable.Cch() == 0)
  1399. {
  1400. if (CheckedAltDirEnvironmentVariable.Cch() != 0)
  1401. {
  1402. if (!FreeBuild)
  1403. {
  1404. IFW32FALSE_EXIT(BuildAltDirEnvironmentVariable.Win32Assign(&d_UnicodeString));
  1405. }
  1406. }
  1407. }
  1408. if (ObjDirEnvironmentVariable.Cch() != 0)
  1409. {
  1410. IFW32FALSE_EXIT(ObjDir.Win32Assign(ObjDirEnvironmentVariable));
  1411. }
  1412. else
  1413. {
  1414. IFW32FALSE_EXIT(ObjDir.Win32Assign(&obj_UnicodeString));
  1415. IFW32FALSE_EXIT(ObjDir.Win32Append(BuildAltDirEnvironmentVariable));
  1416. }
  1417. // Override with the SXS_DLL environment variable first...
  1418. SxspGetEnvironmentVariable(L"SXS_DLL", DllPath);
  1419. if (DllPath.Cch() != 0)
  1420. {
  1421. g.sxsDll = ::LoadLibraryW(DllPath);
  1422. }
  1423. //
  1424. // try %sdxroot%\base\win32\fusion\dll\whistler\obj\i386\sxs.cap.dll
  1425. // and %sdxroot%\base\win32\fusion\dll\whistler\obj\i386\sxs.dll
  1426. //
  1427. if (g.sxsDll == NULL)
  1428. {
  1429. SxspGetEnvironmentVariable(L"SdxRoot", SdxRoot);
  1430. if (SdxRoot.Cch() != 0)
  1431. {
  1432. IFW32FALSE_EXIT(DllPath.Win32Assign(SdxRoot));
  1433. IFW32FALSE_EXIT(DllPath.Win32EnsureTrailingPathSeparator());
  1434. IFW32FALSE_EXIT(DllPath.Win32Append(&base_backslash_win32_backslash_fusion_backslash_dll_whistler_UnicodeString));
  1435. IFW32FALSE_EXIT(DllPath.Win32AppendPathElement(ObjDir));
  1436. IFW32FALSE_EXIT(DllPath.Win32AppendPathElement(&ProcessorBuildObjString));
  1437. IFW32FALSE_EXIT(DllPath.Win32AppendPathElement(&sxs_dot_cap_dot_dll_UnicodeString));
  1438. if (g.sxsDll == NULL)
  1439. {
  1440. g.sxsDll = LoadLibraryW(DllPath);
  1441. }
  1442. if (g.sxsDll == NULL)
  1443. {
  1444. IFW32FALSE_EXIT(DllPath.Win32RemoveLastPathElement());
  1445. IFW32FALSE_EXIT(DllPath.Win32AppendPathElement(&sxs_dot_dll_UnicodeString));
  1446. g.sxsDll = LoadLibraryW(DllPath);
  1447. }
  1448. }
  1449. }
  1450. //
  1451. // try to get it relative to where the .exe is instead of relative to sdxroot
  1452. //
  1453. if (g.sxsDll == NULL)
  1454. {
  1455. IFW32FALSE_EXIT(ExePath.Win32ResizeBuffer(MAX_PATH, eDoNotPreserveBufferContents));
  1456. acc.Attach(&ExePath);
  1457. acc.GetBufferPtr()[acc.GetBufferCch() - 1] = 0;
  1458. GetModuleFileNameW(
  1459. NULL,
  1460. acc.GetBufferPtr(),
  1461. acc.GetBufferCchAsDWORD() - 1
  1462. );
  1463. acc.Detach();
  1464. }
  1465. //
  1466. // try the same directory as the .exe
  1467. //
  1468. if (g.sxsDll == NULL)
  1469. {
  1470. IFW32FALSE_EXIT(DllPath.Win32Assign(ExePath));
  1471. IFW32FALSE_EXIT(DllPath.Win32RemoveLastPathElement());
  1472. IFW32FALSE_EXIT(DllPath.Win32AppendPathElement(&sxs_dot_dll_UnicodeString));
  1473. g.sxsDll = LoadLibraryW(DllPath);
  1474. }
  1475. //
  1476. // try relative to where the .exe is built
  1477. //
  1478. //
  1479. // W:\fusi\base\win32\fusion\dll\whistler\obj\ia64\sxs.dll
  1480. // W:\fusi\base\win32\fusion\whistler\obj\ia64\sxstest.exe
  1481. //
  1482. if (g.sxsDll == NULL)
  1483. {
  1484. IFW32FALSE_EXIT(DllPath.Win32Assign(ExePath));
  1485. IFW32FALSE_EXIT(DllPath.Win32RemoveLastPathElement()); // sxstest.exe
  1486. IFW32FALSE_EXIT(DllPath.Win32RemoveLastPathElement()); // ia64
  1487. IFW32FALSE_EXIT(DllPath.Win32RemoveLastPathElement()); // obj
  1488. IFW32FALSE_EXIT(DllPath.Win32RemoveLastPathElement()); // whistler
  1489. IFW32FALSE_EXIT(DllPath.Win32EnsureTrailingPathSeparator());
  1490. IFW32FALSE_EXIT(DllPath.Win32Append(&dll_backslash_whistler_UnicodeString)); // dll\whistler
  1491. IFW32FALSE_EXIT(DllPath.Win32AppendPathElement(ObjDir)); // obj
  1492. IFW32FALSE_EXIT(DllPath.Win32AppendPathElement(&ProcessorBuildObjString)); // i386
  1493. IFW32FALSE_EXIT(DllPath.Win32AppendPathElement(&sxs_dot_dll_UnicodeString)); // sxs.dll
  1494. g.sxsDll = LoadLibraryW(DllPath);
  1495. }
  1496. LoadSxsDllCommonTail();
  1497. }
  1498. FN_EPILOG;
  1499. }
  1500. BOOL
  1501. LoadSxs()
  1502. {
  1503. return
  1504. LoadBuiltSxsDll()
  1505. || LoadInstalledSxsDll()
  1506. || UseStaticSxsDll();
  1507. }
  1508. int
  1509. TestInstall(
  1510. PCWSTR manifest,
  1511. __int64 flags,
  1512. DWORD beginInstallFlags,
  1513. DWORD installFlags,
  1514. DWORD endInstallFlags
  1515. )
  1516. {
  1517. BOOL fSuccess = FALSE;
  1518. PVOID installCookie = NULL;
  1519. BOOL fCleanup = FALSE;
  1520. SXS_INSTALL_SOURCE_INFO SxsInstallInfo = {0};
  1521. SXS_INSTALLW SxsInstall = {sizeof(SxsInstall) };
  1522. PSXS_INSTALLATION_FILE_COPY_CALLBACK callback = NULL;
  1523. PVOID context = NULL;
  1524. LoadSxs();
  1525. if (!(*g_pfnSxsBeginAssemblyInstall)(
  1526. beginInstallFlags,
  1527. callback,
  1528. context,
  1529. NULL, // ImpersonationCallback,
  1530. NULL, // ImpersonationContext,
  1531. &installCookie))
  1532. {
  1533. goto Exit;
  1534. }
  1535. fCleanup = TRUE;
  1536. SxsInstall.dwFlags = installFlags | SXS_INSTALL_FLAG_INSTALL_COOKIE_VALID;
  1537. SxsInstall.lpManifestPath = manifest;
  1538. SxsInstall.pvInstallCookie = installCookie;
  1539. SxsInstall.lpReference = NULL;
  1540. fSuccess = g_pfnSxsInstallW(&SxsInstall);
  1541. Exit:
  1542. if (fCleanup)
  1543. {
  1544. (*g_pfnSxsEndAssemblyInstall)(installCookie, endInstallFlags | (fSuccess ? SXS_END_ASSEMBLY_INSTALL_FLAG_COMMIT : SXS_END_ASSEMBLY_INSTALL_FLAG_ABORT), NULL);
  1545. }
  1546. if (!fSuccess)
  1547. {
  1548. fprintf(stderr, "%s failed!\n", __FUNCTION__);
  1549. return EXIT_FAILURE;
  1550. }
  1551. else
  1552. return EXIT_SUCCESS;
  1553. }
  1554. BOOL
  1555. TestManifestSchema(
  1556. int argc,
  1557. wchar_t** argv,
  1558. int* piNext
  1559. )
  1560. {
  1561. BOOL fSuccess = FALSE;
  1562. int i = (*piNext) + 1;
  1563. if (i >= argc)
  1564. {
  1565. fprintf(stderr, "%S: Missing parameter after \"%S\"\n", argv[0], argv[i-1]);
  1566. goto Exit;
  1567. }
  1568. LoadSxs();
  1569. fSuccess = (*g_pfnSxspDebug)(SXS_DEBUG_CHECK_MANIFEST_SCHEMA, 0, argv[i++], NULL);
  1570. if (!fSuccess)
  1571. {
  1572. fprintf(stderr, "%s failed!\n", __FUNCTION__);
  1573. goto Exit;
  1574. }
  1575. *piNext = i;
  1576. fSuccess = TRUE;
  1577. Exit:
  1578. return fSuccess;
  1579. }
  1580. BOOL
  1581. TestXMLParsing(
  1582. int argc,
  1583. wchar_t** argv,
  1584. int* piNext)
  1585. {
  1586. BOOL fSuccess = FALSE;
  1587. int i = (*piNext) + 1;
  1588. if (i >= argc)
  1589. {
  1590. fprintf(stderr, "%S: missing parameter after \"%S\"\n", argv[0], argv[i-1]);
  1591. goto Exit;
  1592. }
  1593. LoadSxs();
  1594. fSuccess = (*g_pfnSxspDebug)(SXS_DEBUG_XML_PARSER, 0, argv[i], NULL);
  1595. if (!fSuccess)
  1596. {
  1597. fprintf(stderr, "%s failed!\n", __FUNCTION__);
  1598. goto Exit;
  1599. }
  1600. *piNext = i + 1;
  1601. fSuccess = TRUE;
  1602. Exit:
  1603. return fSuccess;
  1604. }
  1605. BOOL
  1606. TestDirect(
  1607. int argc,
  1608. wchar_t** argv,
  1609. int* piNext)
  1610. {
  1611. BOOL fSuccess = FALSE;
  1612. int i = (*piNext) + 1;
  1613. int n = 1;
  1614. ULONGLONG cc1, cc2;
  1615. if (i >= argc)
  1616. {
  1617. fprintf(stderr, "%S: missing parameter after \"%S\"\n", argv[0], argv[i-1]);
  1618. goto Exit;
  1619. }
  1620. LoadSxs();
  1621. fSuccess = (*g_pfnSxspDebug)(SXS_DEBUG_DLL_REDIRECTION, 0, argv[i], NULL);
  1622. if (!fSuccess)
  1623. {
  1624. fprintf(stderr, "%s failed!\n", __FUNCTION__);
  1625. goto Exit;
  1626. }
  1627. cc1 = GetCycleCount();
  1628. for (n=0; n<10; n++)
  1629. fSuccess = (*g_pfnSxspDebug)(SXS_DEBUG_DLL_REDIRECTION, 0, argv[i], NULL);
  1630. cc2 = GetCycleCount();
  1631. printf("%I64u cycles for %d iterations\n", cc2 - cc1, n);
  1632. *piNext = i + 1;
  1633. fSuccess = TRUE;
  1634. Exit:
  1635. return fSuccess;
  1636. }
  1637. VOID
  1638. PrintBlob(
  1639. FILE *pf,
  1640. PVOID Data,
  1641. SIZE_T Length,
  1642. PCWSTR PerLinePrefix
  1643. )
  1644. {
  1645. SIZE_T Offset = 0;
  1646. if (PerLinePrefix == NULL)
  1647. PerLinePrefix = L"";
  1648. // we'll output in 8-byte chunks as shown:
  1649. //
  1650. // [prefix]Binary section %p (%d bytes)
  1651. // [prefix] 00000000: xx-xx-xx-xx-xx-xx-xx-xx (........)
  1652. // [prefix] 00000008: xx-xx-xx-xx-xx-xx-xx-xx (........)
  1653. // [prefix] 00000010: xx-xx-xx-xx-xx-xx-xx-xx (........)
  1654. //
  1655. while (Length >= 8)
  1656. {
  1657. BYTE *pb = (BYTE *) (((ULONG_PTR) Data) + Offset);
  1658. fprintf(
  1659. pf,
  1660. "%S %08lx: %02x-%02x-%02x-%02x-%02x-%02x-%02x-%02x (%c%c%c%c%c%c%c%c)\n",
  1661. PerLinePrefix,
  1662. Offset,
  1663. pb[0], pb[1], pb[2], pb[3], pb[4], pb[5], pb[6], pb[7],
  1664. PRINTABLE(pb[0]),
  1665. PRINTABLE(pb[1]),
  1666. PRINTABLE(pb[2]),
  1667. PRINTABLE(pb[3]),
  1668. PRINTABLE(pb[4]),
  1669. PRINTABLE(pb[5]),
  1670. PRINTABLE(pb[6]),
  1671. PRINTABLE(pb[7]));
  1672. Offset += 8;
  1673. Length -= 8;
  1674. }
  1675. if (Length != 0)
  1676. {
  1677. CStringBuffer buffTemp;
  1678. bool First = true;
  1679. ULONG i;
  1680. BYTE *pb = (BYTE *) (((ULONG_PTR) Data) + Offset);
  1681. buffTemp.Win32ResizeBuffer(48, eDoNotPreserveBufferContents);
  1682. buffTemp.Win32Format(L" %08lx: ", Offset);
  1683. for (i=0; i<8; i++)
  1684. {
  1685. if (Length > 0)
  1686. {
  1687. if (!First)
  1688. buffTemp.Win32Append("-", 1);
  1689. else
  1690. First = false;
  1691. buffTemp.Win32FormatAppend(L"%02x", pb[i]);
  1692. Length--;
  1693. }
  1694. else
  1695. {
  1696. buffTemp.Win32Append(" ", 3);
  1697. }
  1698. }
  1699. buffTemp.Win32Append(" (", 2);
  1700. i = 0;
  1701. while (Length != 0)
  1702. {
  1703. CHAR chTemp = static_cast<CHAR>(PRINTABLE(pb[i]));
  1704. i++;
  1705. buffTemp.Win32Append(&chTemp, 1);
  1706. Length--;
  1707. }
  1708. buffTemp.Win32Append(L")", 1);
  1709. fprintf(
  1710. pf,
  1711. "%S%S\n",
  1712. PerLinePrefix,
  1713. static_cast<PCWSTR>(buffTemp));
  1714. }
  1715. }
  1716. void __stdcall TestWin32Apc(ULONG_PTR arg)
  1717. {
  1718. ACTCTXW ac = {sizeof(ac)};
  1719. int error = 0;
  1720. PWSTR source = reinterpret_cast<PWSTR>(arg);
  1721. HANDLE hActCtx = NULL;
  1722. BOOL fSuccess = FALSE;
  1723. ac.lpSource = source;
  1724. PWSTR pound = wcschr(source, '#');
  1725. if (pound != NULL)
  1726. {
  1727. *pound = 0;
  1728. ac.lpResourceName = pound + 1;
  1729. ac.dwFlags |= ACTCTX_FLAG_RESOURCE_NAME_VALID;
  1730. }
  1731. ac.wProcessorArchitecture = g.wProcessorArchitecture;
  1732. ac.wLangId = g.wLangId;
  1733. hActCtx = ::CreateActCtxW(&ac);
  1734. if (hActCtx == INVALID_HANDLE_VALUE)
  1735. {
  1736. error = ::GetLastError();
  1737. fwprintf(stderr, L"CreateActCtxW(%ls) failed; ::GetLastError() = %d\n", source, error);
  1738. goto Exit;
  1739. }
  1740. //fSuccess = ::ReleaseActCtx(hActCtx);
  1741. fSuccess = TRUE;
  1742. hActCtx = NULL;
  1743. if (!fSuccess)
  1744. {
  1745. error = ::GetLastError();
  1746. goto Exit;
  1747. }
  1748. Exit:
  1749. if (error)
  1750. ThrowWin32(error);
  1751. }
  1752. void
  1753. TestWin32(
  1754. wchar_t** argv
  1755. )
  1756. {
  1757. CreateThreads();
  1758. int i = 0;
  1759. for (i = 0 ; argv[i] ; ++i)
  1760. {
  1761. if (g.NumberOfThreads)
  1762. {
  1763. if (!QueueUserAPC(TestWin32Apc, g.Threads[i % g.NumberOfThreads], reinterpret_cast<ULONG_PTR>(argv[i])))
  1764. {
  1765. fprintf(stderr, "QueueUserAPC() failed\n");
  1766. ThrowWin32(((ULONG_PTR) (LONG_PTR) -1));
  1767. }
  1768. }
  1769. else
  1770. {
  1771. TestWin32Apc(reinterpret_cast<ULONG_PTR>(argv[i]));
  1772. }
  1773. }
  1774. }
  1775. const static WCHAR InheritManifest[] =
  1776. L"<assembly xmlns=\"urn:schemas-microsoft-com:asm.v1\" manifestVersion=\"1.0\">"
  1777. L"<assemblyIdentity type=\"win32\" name=\"Microsoft.Windows.SystemCompatibleAssembly\" version=\"1.0.0.0\" processorArchitecture=\"x86\" />"
  1778. L"<description>System Compatible Default</description> "
  1779. L"<dependency> <dependentAssembly>"
  1780. L"<assemblyIdentity type=\"win32\" name=\"Microsoft.Tools.VisualCPlusPlus.Runtime-Libraries\" version=\"6.0.0.0\" language=\"*\" processorArchitecture=\"x86\" publicKeyToken=\"6595b64144ccf1df\" />"
  1781. L"</dependentAssembly> </dependency></assembly>"
  1782. ;
  1783. const static WCHAR NoInheritManifest[] =
  1784. L"<assembly manifestversion=\"1.0\" name=\"InheritManifest\">"
  1785. L"<dependency assemblyname=\"Microsoft-Visual-CPlusPlus-Runtime-Libraries\" version=\"6.0.0.0\" language=\"0000\"/>"
  1786. L"<noinherit/>"
  1787. L"</assembly>"
  1788. ;
  1789. const static WCHAR RefCountManifest[] =
  1790. L"<assembly xmlns=\"urn:schemas-microsoft-com:asm.v1\" manifestVersion=\"1.0\">"
  1791. L"<assemblyIdentity type=\"win32\" name=\"Microsoft.Windows.SxsTest.RefCount\" version=\"1.0.0.0\" processorArchitecture=\"x86\" />"
  1792. L"<description>blah</description> "
  1793. L"<dependency><dependentAssembly>"
  1794. //L"<assemblyIdentity type=\"win32\" name=\"Microsoft.Windows.SxsTest1\" version=\"1.0.0.0\" language=\"*\" processorArchitecture=\"x86\" publicKeyToken=\"6595b64144ccf1df\" />"
  1795. L"<assemblyIdentity type=\"win32\" name=\"Microsoft.Tools.VisualCPlusPlus.Runtime-Libraries\" version=\"6.0.0.0\" language=\"*\" processorArchitecture=\"x86\" publicKeyToken=\"6595b64144ccf1df\" />"
  1796. L"</dependentAssembly> </dependency></assembly>"
  1797. ;
  1798. // to test the empty actctx, we push this, probe, push empty, probe
  1799. const static PCWSTR DependentOnMsvc6Manifest = InheritManifest;
  1800. WCHAR SearchPathResult[MAX_PATH];
  1801. void ProbeContext(const char* Function, PCWSTR Dll = L"msvcrt.dll")
  1802. {
  1803. SearchPathResult[0] = 0;
  1804. SearchPathW(NULL, Dll, NULL, NUMBER_OF(SearchPathResult), SearchPathResult, NULL);
  1805. DbgPrint("%s %ls\n", Function, SearchPathResult);
  1806. }
  1807. DWORD CALLBACK InheritThreadMain(VOID*)
  1808. {
  1809. ProbeContext(__FUNCTION__);
  1810. return 0;
  1811. }
  1812. DWORD CALLBACK NoinheritThreadMain(VOID*)
  1813. {
  1814. ProbeContext(__FUNCTION__);
  1815. return 0;
  1816. }
  1817. void TestInherit()
  1818. {
  1819. ProbeContext(__FUNCTION__);
  1820. HANDLE ActivationContextHandle = ::CreateActivationContextFromStringW(InheritManifest);
  1821. ULONG_PTR Cookie;
  1822. ActivateActCtx(ActivationContextHandle, &Cookie);
  1823. ProbeContext(__FUNCTION__);
  1824. DWORD ThreadId;
  1825. WaitForSingleObject(CreateThread(NULL, 0, InheritThreadMain, NULL, 0, &ThreadId), INFINITE);
  1826. }
  1827. void TestNoInherit()
  1828. {
  1829. ProbeContext(__FUNCTION__);
  1830. HANDLE ActivationContextHandle = ::CreateActivationContextFromStringW(NoInheritManifest);
  1831. ULONG_PTR Cookie;
  1832. ActivateActCtx(ActivationContextHandle, &Cookie);
  1833. ProbeContext(__FUNCTION__);
  1834. DWORD ThreadId;
  1835. WaitForSingleObject(CreateThread(NULL, 0, NoinheritThreadMain, NULL, 0, &ThreadId), INFINITE);
  1836. }
  1837. void TestEmpty()
  1838. {
  1839. ProbeContext(__FUNCTION__);
  1840. HANDLE ActivationContextHandle = ::CreateActivationContextFromStringW(DependentOnMsvc6Manifest);
  1841. ULONG_PTR Cookie1;
  1842. ULONG_PTR Cookie2;
  1843. ActivateActCtx(ActivationContextHandle, &Cookie1);
  1844. ProbeContext(__FUNCTION__);
  1845. ActivateActCtx(ACTCTX_EMPTY, &Cookie2);
  1846. ProbeContext(__FUNCTION__);
  1847. DeactivateActCtx(0, Cookie2);
  1848. ProbeContext(__FUNCTION__);
  1849. DeactivateActCtx(0, Cookie1);
  1850. ProbeContext(__FUNCTION__);
  1851. }
  1852. void TestRefCount()
  1853. {
  1854. //
  1855. // 1) newly created actctx has refcount==1
  1856. // 2) activated actctx has refcount==1
  1857. // 3) load a library with no deps with actctx, refcount==2
  1858. // 4) freelibrary, refcount==1
  1859. // directory of library is closed
  1860. // 5) release actctx refcount==0
  1861. //
  1862. // First order, just step through the code to look at the refcount.
  1863. // Second order, "detour" like crazy and look at the memory
  1864. // (including detouring away RtlFreeHeap, NtUnmapViewOfSection)
  1865. //
  1866. HANDLE ActivationContextHandle = ::CreateActivationContextFromStringW(RefCountManifest);
  1867. ULONG_PTR Cookie1;
  1868. ActivateActCtx(ActivationContextHandle, &Cookie1);
  1869. FreeLibrary(LoadLibraryW(L"msvcrt.dll"));
  1870. DeactivateActCtx(0, Cookie1);
  1871. ReleaseActCtx(ActivationContextHandle);
  1872. }
  1873. GUID Guids[100];
  1874. WCHAR GuidStrings[100][64];
  1875. #include "sxstest_formatguid.cpp"
  1876. extern "C" HRESULT __stdcall
  1877. DllGetClassObject(
  1878. REFCLSID rclsid, //CLSID for the class object
  1879. REFIID riid, //Reference to the identifier of the interface
  1880. // that communicates with the class object
  1881. LPVOID * ppv //Address of output variable that receives the
  1882. // interface pointer requested in riid
  1883. )
  1884. {
  1885. WCHAR GuidString[64];
  1886. FormatGuid(GuidString, NUMBER_OF(GuidString), rclsid);
  1887. printf("%s : {%ls}\n", __FUNCTION__, GuidString);
  1888. if (riid == IID_IUnknown)
  1889. {
  1890. *ppv = &g.unknown;
  1891. return S_OK;
  1892. }
  1893. else
  1894. {
  1895. return E_NOINTERFACE;
  1896. }
  1897. }
  1898. void TestGuidSort()
  1899. {
  1900. const int MAX = 100;
  1901. FN_TRACE_SMART_TLS();
  1902. CStringBuffer Manifest;
  1903. int i = 0;
  1904. Ole32.CoInitialize(NULL);
  1905. Manifest.Win32ResizeBuffer(1 << 15, eDoNotPreserveBufferContents);
  1906. Manifest.Win32Format(
  1907. L"<assembly xmlns=\"urn:schemas-microsoft-com:asm.v1\" manifestVersion=\"1.0\"> \
  1908. <assemblyIdentity \
  1909. type=\"win32\" \
  1910. name=\"Microsoft.Windows.SxsTest.GuidSort\" \
  1911. version=\"1.0.0.0\" \
  1912. processorArchitecture=\"x86\" \
  1913. publicKeyToken=\"6595b64144ccf1df\" \
  1914. /> \
  1915. <file name=\"sxstest.exe\">");
  1916. for (i = 0 ; i < MAX ; ++i)
  1917. {
  1918. GUID& Guid = Guids[i];
  1919. CoCreateGuid(&Guid);
  1920. FormatGuid(GuidStrings[i], NUMBER_OF(GuidStrings[i]), Guid);
  1921. if (!Manifest.Win32FormatAppend(
  1922. L"\n<comClass description=\"a%d\" clsid=\"{%ls}\"/>",
  1923. i,
  1924. static_cast<PCWSTR>(GuidStrings[i])))
  1925. ThrowLastError();
  1926. }
  1927. if (!Manifest.Win32FormatAppend(L"\n</file>\n</assembly>"))
  1928. ThrowLastError();
  1929. printf("%ls\n", static_cast<PCWSTR>(Manifest));
  1930. HANDLE ActivationContextHandle = ::CreateActivationContextFromStringW(Manifest);
  1931. ULONG_PTR Cookie1;
  1932. ActivateActCtx(ActivationContextHandle, &Cookie1);
  1933. for (i = 0 ; i < MAX ; ++i)
  1934. {
  1935. HRESULT hr;
  1936. PVOID pv = NULL;
  1937. hr = Ole32.CoCreateInstance(Guids[i], NULL, CLSCTX_INPROC, IID_IUnknown, &pv);
  1938. printf("CoCreateInstance({%ls}): %08lx%s%s%s\n",
  1939. GuidStrings[i],
  1940. static_cast<unsigned long>(hr),
  1941. ( (hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND))
  1942. || hr == REGDB_E_CLASSNOTREG
  1943. || (hr == HRESULT_FROM_WIN32(ERROR_INVALID_PARAMETER))
  1944. || (hr == E_NOINTERFACE)
  1945. ) ? "(" : "",
  1946. (hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND))
  1947. ? "ERROR_FILE_NOT_FOUND"
  1948. : (hr == REGDB_E_CLASSNOTREG)
  1949. ? "REGDB_E_CLASSNOTREG"
  1950. : (hr == ERROR_INVALID_PARAMETER)
  1951. ? "ERROR_INVALID_PARAMETER"
  1952. : (hr == E_NOINTERFACE)
  1953. ? "E_NOINTERFACE (ok)"
  1954. : "",
  1955. ( hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND)
  1956. || hr == REGDB_E_CLASSNOTREG
  1957. || hr == HRESULT_FROM_WIN32(ERROR_INVALID_PARAMETER))
  1958. || hr == E_NOINTERFACE
  1959. ? ")" : "");
  1960. }
  1961. DeactivateActCtx(0, Cookie1);
  1962. ReleaseActCtx(ActivationContextHandle);
  1963. }
  1964. void TestStringSort()
  1965. {
  1966. /*
  1967. Mike says this takes between 2 and 7 to visit the code.
  1968. */
  1969. const int MAX = 50;
  1970. FN_TRACE_SMART_TLS();
  1971. WCHAR ExePath[MAX_PATH];
  1972. CStringBuffer DllPaths[MAX];
  1973. CStringBuffer Manifest;
  1974. int i = 0;
  1975. if (!Kernel32.GetModuleFileNameW(NULL, ExePath, RTL_NUMBER_OF(ExePath)))
  1976. ThrowLastError();
  1977. if (!Manifest.Win32ResizeBuffer(1 << 15, eDoNotPreserveBufferContents))
  1978. ThrowLastError();
  1979. if (!Manifest.Win32Format(
  1980. L"<assembly xmlns=\"urn:schemas-microsoft-com:asm.v1\" manifestVersion=\"1.0\"> \
  1981. <assemblyIdentity \
  1982. type=\"win32\" \
  1983. name=\"Microsoft.Windows.SxsTest.StringSort\" \
  1984. version=\"1.0.0.0\" \
  1985. processorArchitecture=\"x86\" \
  1986. publicKeyToken=\"6595b64144ccf1df\" \
  1987. /> \
  1988. <file name=\"sxstest.exe\"/>"))
  1989. ThrowLastError();
  1990. for (i = 0 ; i < MAX ; ++i)
  1991. {
  1992. if (!DllPaths[i].Win32Format(L"%ls.%d.dll", ExePath, i))
  1993. ThrowLastError();
  1994. if (!::CopyFileW(ExePath, DllPaths[i], FALSE))
  1995. ThrowLastError();
  1996. SetDllBitInPeImage(DllPaths[i]);
  1997. if (!Manifest.Win32FormatAppend(L"\n<file name=\"%ls\"/>\n", 1 + wcsrchr(static_cast<PCWSTR>(DllPaths[i]), '\\')))
  1998. ThrowLastError();
  1999. }
  2000. if (!Manifest.Win32FormatAppend(L"\n</assembly>"))
  2001. ThrowLastError();
  2002. printf("%ls\n", static_cast<PCWSTR>(Manifest));
  2003. HANDLE ActivationContextHandle = ::CreateActivationContextFromStringW(Manifest);
  2004. ULONG_PTR Cookie1;
  2005. ActivateActCtx(ActivationContextHandle, &Cookie1);
  2006. for (i = 0 ; i < MAX ; ++i)
  2007. {
  2008. HMODULE h;
  2009. PCWSTR DllName = 1 + wcsrchr(DllPaths[i], '\\');
  2010. h = ::LoadLibraryW(DllName);
  2011. printf("LoadLibrary(%ls):%p, LastError=%d\n",
  2012. DllName,
  2013. h,
  2014. ::GetLastError());
  2015. //FreeLibrary(h);
  2016. Kernel32.DeleteFileW(DllPaths[i]);
  2017. }
  2018. DeactivateActCtx(0, Cookie1);
  2019. ReleaseActCtx(ActivationContextHandle);
  2020. }
  2021. int
  2022. TestSearchPathHelper1(
  2023. PCSTR RunId,
  2024. PCWSTR Path,
  2025. PCWSTR File,
  2026. PCWSTR Extension,
  2027. bool GetFilePart,
  2028. ULONG cch
  2029. )
  2030. {
  2031. WCHAR Buffer[65536]; // we know that the underlying code can never use a buffer this big
  2032. PWSTR FilePart = NULL;
  2033. PWSTR *lpFilePart = (GetFilePart ? &FilePart : NULL);
  2034. SetLastError(ERROR_GEN_FAILURE);
  2035. ULONG Result = ::SearchPathW(
  2036. Path,
  2037. File,
  2038. Extension,
  2039. 0,
  2040. NULL,
  2041. lpFilePart);
  2042. printf("SearchPath() RunId = %s (Path %s; File %s; Extension %s; GetFilePart %s; cch = %lu; buffer=null) result = %lu ::GetLastError() = %u; FilePart = %s %u\n",
  2043. RunId,
  2044. Path ? "present" : "null",
  2045. File ? "present" : "null",
  2046. Extension ? "present" : "null",
  2047. GetFilePart ? "true" : "false",
  2048. 0,
  2049. Result,
  2050. ::GetLastError(),
  2051. FilePart ? "present" : "null",
  2052. FilePart ? (FilePart - Buffer) : 0);
  2053. SetLastError(ERROR_GEN_FAILURE);
  2054. FilePart = NULL;
  2055. ULONG NewResult = ::SearchPathW(
  2056. Path,
  2057. File,
  2058. Extension,
  2059. Result,
  2060. Buffer,
  2061. lpFilePart);
  2062. printf("SearchPath() RunId = %s (Path %s; File %s; Extension %s; GetFilePart %s; cch = %lu) result = %lu ::GetLastError() = %u; FilePart = %s %u\n",
  2063. RunId,
  2064. Path ? "present" : "null",
  2065. File ? "present" : "null",
  2066. Extension ? "present" : "null",
  2067. GetFilePart ? "true" : "false",
  2068. Result,
  2069. NewResult,
  2070. ::GetLastError(),
  2071. FilePart ? "present" : "null",
  2072. FilePart ? (FilePart - Buffer) : 0);
  2073. SetLastError(ERROR_GEN_FAILURE);
  2074. FilePart = NULL;
  2075. Result = ::SearchPathW(
  2076. Path,
  2077. File,
  2078. Extension,
  2079. cch,
  2080. Buffer,
  2081. lpFilePart);
  2082. printf("SearchPath() RunId = %s (Path %s; File %s; Extension %s; GetFilePart %s; cch = %lu) result = %lu ::GetLastError() = %u; FilePart = %s %u\n",
  2083. RunId,
  2084. Path ? "present" : "null",
  2085. File ? "present" : "null",
  2086. Extension ? "present" : "null",
  2087. GetFilePart ? "true" : "false",
  2088. cch,
  2089. Result,
  2090. ::GetLastError(),
  2091. FilePart ? "present" : "null",
  2092. FilePart ? (FilePart - Buffer) : 0);
  2093. return EXIT_SUCCESS;
  2094. }
  2095. int
  2096. TestSearchPathHelper2(
  2097. PCSTR RunId,
  2098. PCWSTR Path,
  2099. PCWSTR File,
  2100. PCWSTR Extension,
  2101. ULONG cch
  2102. )
  2103. {
  2104. TestSearchPathHelper1(RunId, NULL, File, NULL, true, cch);
  2105. TestSearchPathHelper1(RunId, NULL, File, NULL, false, cch);
  2106. TestSearchPathHelper1(RunId, Path, File, NULL, true, cch);
  2107. TestSearchPathHelper1(RunId, Path, File, NULL, false, cch);
  2108. TestSearchPathHelper1(RunId, NULL, File, Extension, true, cch);
  2109. TestSearchPathHelper1(RunId, NULL, File, Extension, false, cch);
  2110. TestSearchPathHelper1(RunId, Path, File, Extension, true, cch);
  2111. TestSearchPathHelper1(RunId, Path, File, Extension, false, cch);
  2112. return EXIT_SUCCESS;
  2113. }
  2114. int
  2115. TestSearchPathHelper3(
  2116. PCSTR RunId,
  2117. PCWSTR Path,
  2118. PCWSTR File,
  2119. PCWSTR Extension
  2120. )
  2121. {
  2122. ULONG i;
  2123. for (i=0; i<5; i++)
  2124. TestSearchPathHelper2(RunId, Path, File, Extension, i);
  2125. for (i=MAX_PATH-5; i<(MAX_PATH+5); i++)
  2126. TestSearchPathHelper2(RunId, Path, File, Extension, i);
  2127. for (i=32760; i<32770; i++)
  2128. TestSearchPathHelper2(RunId, Path, File, Extension, i);
  2129. return EXIT_SUCCESS;
  2130. }
  2131. BOOL
  2132. TestSearchPath(
  2133. int argc,
  2134. wchar_t** argv,
  2135. int* piNext
  2136. )
  2137. {
  2138. ULONG i;
  2139. PWSTR PathToSearch = (PWSTR) malloc(100000* sizeof(WCHAR));
  2140. int iNext = (*piNext) + 1;
  2141. PathToSearch[0] = L'C';
  2142. PathToSearch[1] = L'\\';
  2143. for (i=2; i<60000; i++)
  2144. PathToSearch[i] = L'X';
  2145. wcscpy(&PathToSearch[i], L";C:\\");
  2146. TestSearchPathHelper3("1.0", L"C:\\DirectoryDoesNotExist;C:\\", L"boot.ini", L".ini");
  2147. TestSearchPathHelper3("1.1", L"C:\\DirectoryDoesNotExist;C:\\", L"boot.", L".ini");
  2148. TestSearchPathHelper3("1.2", L"C:\\DirectoryDoesNotExist;C:\\", L"boot", L".ini");
  2149. TestSearchPathHelper3("1.3", L"C:\\DirectoryDoesNotExist;C:\\", L"doesnotexist.doesnotexist", L".ini");
  2150. TestSearchPathHelper3("1.4", L"C:\\DirectoryDoesNotExist;C:\\", L"d:\\readme.txt", L".ini");
  2151. TestSearchPathHelper3("1.5", L"C:\\DirectoryDoesNotExist;C:\\", L"kernel32.dll", L".dll");
  2152. TestSearchPathHelper3("1.6", L"C:\\DirectoryDoesNotExist;C:\\", L"kernel32.", L".dll");
  2153. TestSearchPathHelper3("1.7", L"C:\\DirectoryDoesNotExist;C:\\", L"kernel32", L".dll");
  2154. TestSearchPathHelper3("1.8", L"C:\\DirectoryDoesNotExist;C:\\", L"kernel32.dll", L".ini");
  2155. TestSearchPathHelper3("1.9", L"C:\\DirectoryDoesNotExist;C:\\", L"kernel32.", L".ini");
  2156. TestSearchPathHelper3("1.10", L"C:\\DirectoryDoesNotExist;C:\\", L"kernel32", L".ini");
  2157. TestSearchPathHelper3("2.0", L"C:\\;C:\\DirectoryDoesNotExist", L"boot.ini", L".ini");
  2158. TestSearchPathHelper3("2.1", L"C:\\;C:\\DirectoryDoesNotExist", L"boot.", L".ini");
  2159. TestSearchPathHelper3("2.2", L"C:\\;C:\\DirectoryDoesNotExist", L"boot", L".ini");
  2160. TestSearchPathHelper3("2.3", L"C:\\;C:\\DirectoryDoesNotExist", L"doesnotexist.doesnotexist", L".ini");
  2161. TestSearchPathHelper3("2.4", L"C:\\;C:\\DirectoryDoesNotExist", L"d:\\readme.txt", L".ini");
  2162. TestSearchPathHelper3("2.5", L"C:\\;C:\\DirectoryDoesNotExist", L"kernel32.dll", L".dll");
  2163. TestSearchPathHelper3("2.6", L"C:\\;C:\\DirectoryDoesNotExist", L"kernel32.", L".dll");
  2164. TestSearchPathHelper3("2.7", L"C:\\;C:\\DirectoryDoesNotExist", L"kernel32", L".dll");
  2165. TestSearchPathHelper3("2.8", L"C:\\;C:\\DirectoryDoesNotExist", L"kernel32.dll", L".ini");
  2166. TestSearchPathHelper3("2.9", L"C:\\;C:\\DirectoryDoesNotExist", L"kernel32.", L".ini");
  2167. TestSearchPathHelper3("2.10", L"C:\\;C:\\DirectoryDoesNotExist", L"kernel32", L".ini");
  2168. TestSearchPathHelper3("3.0", PathToSearch, L"boot.ini", L".ini");
  2169. TestSearchPathHelper3("3.1", PathToSearch, L"boot", L".ini");
  2170. TestSearchPathHelper3("3.1", PathToSearch, L"boot.", L".ini");
  2171. TestSearchPathHelper3("3.2", PathToSearch, L"doesnotexist.doesnotexist", L".ini");
  2172. TestSearchPathHelper3("3.3", PathToSearch, L"d:\\readme.txt", L".ini");
  2173. *piNext = iNext;
  2174. return EXIT_SUCCESS;
  2175. }
  2176. BOOL
  2177. TestAct(
  2178. int argc,
  2179. wchar_t** argv,
  2180. int* piNext)
  2181. {
  2182. ULONG i, c;
  2183. ULONG_PTR *prgCookies = NULL;
  2184. HANDLE hActCtx = NULL;
  2185. CHAR buffer[1024];
  2186. int iNext = (*piNext + 1);
  2187. BOOL fSuccess = FALSE;
  2188. if (iNext >= argc)
  2189. {
  2190. fprintf(stderr, "%S: missing parameter after \"%S\"\n", argv[0], argv[iNext - 1]);
  2191. goto Exit;
  2192. }
  2193. WideCharToMultiByte(CP_ACP, 0, argv[iNext++], -1, buffer, NUMBER_OF(buffer), NULL, NULL);
  2194. ACTCTXA ac;
  2195. ac.cbSize = sizeof(ac);
  2196. ac.dwFlags = 0;
  2197. ac.lpSource = buffer;
  2198. ac.wProcessorArchitecture = g.wProcessorArchitecture;
  2199. ac.wLangId = g.wLangId;
  2200. hActCtx = ::CreateActCtxA(&ac);
  2201. if (hActCtx == INVALID_HANDLE_VALUE)
  2202. {
  2203. fprintf(stderr, "CreateActCtxA() failed; ::GetLastError() = %d\n", ::GetLastError());
  2204. return EXIT_FAILURE;
  2205. }
  2206. c = 0;
  2207. if (argc > iNext)
  2208. c = _wtoi(argv[iNext++]);
  2209. if (c == 0)
  2210. c = 100;
  2211. prgCookies = NEW(ULONG_PTR[c]);
  2212. if (prgCookies == NULL)
  2213. {
  2214. fprintf(stderr, "Unable to allocate %lu cookies.\n", c);
  2215. goto Exit;
  2216. }
  2217. for (i=0; i<c; i++)
  2218. {
  2219. if (!ActivateActCtx(hActCtx, &prgCookies[i]))
  2220. {
  2221. fprintf(stderr, "Attempt to activate to depth %lu failed; ::GetLastError() = %d\n", i, ::GetLastError());
  2222. goto Exit;
  2223. }
  2224. }
  2225. for (i=0; i<c; i++)
  2226. {
  2227. ULONG j = (c - i) - 1;
  2228. DeactivateActCtx(0, prgCookies[j]);
  2229. }
  2230. ReleaseActCtx(hActCtx);
  2231. fSuccess = TRUE;
  2232. *piNext = iNext;
  2233. Exit:
  2234. delete []prgCookies;
  2235. return fSuccess;
  2236. }
  2237. HRESULT Helper_WriteStream(CBaseStringBuffer * pFileNameBuf,
  2238. IStream *pStream)
  2239. {
  2240. HRESULT hr = NOERROR;
  2241. LPBYTE pBuf[0x4000];
  2242. DWORD cbBuf = 0x4000;
  2243. DWORD dwWritten = 0;
  2244. DWORD cbRead = 0;
  2245. HANDLE hf = INVALID_HANDLE_VALUE;
  2246. hf = ::CreateFileW(static_cast<PCWSTR>(*pFileNameBuf), GENERIC_READ, FILE_SHARE_READ,
  2247. NULL, OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, NULL);
  2248. if (hf == INVALID_HANDLE_VALUE){
  2249. hr = HRESULT_FROM_WIN32 (GetLastError());
  2250. goto Exit;
  2251. }
  2252. while (::ReadFile(hf, pBuf, cbBuf, &cbRead, NULL) && cbRead){
  2253. hr = pStream->Write(pBuf, cbRead, &dwWritten);
  2254. if (FAILED(hr))
  2255. goto Exit;
  2256. }
  2257. if (! SUCCEEDED(hr =pStream->Commit(0)))
  2258. goto Exit;
  2259. CloseHandle(hf);
  2260. Exit:
  2261. return hr;
  2262. }
  2263. BOOL
  2264. TestMSIInstall(
  2265. int argc,
  2266. wchar_t** argv,
  2267. int* piNext
  2268. )
  2269. {
  2270. BOOL fSuccess = FALSE;
  2271. FN_TRACE_WIN32(fSuccess);
  2272. CSmartRef<IAssemblyCache> pCache;
  2273. CSmartRef<IAssemblyCacheItem> ppCacheItem[4];
  2274. CSmartRef<IStream> pStream;
  2275. CStringBuffer SourceFilePathBuf;
  2276. CStringBuffer SourceFileNameBuf;
  2277. CHAR buf[1024];
  2278. FILE* fp = NULL;
  2279. LPSTR p1, pbuf ;
  2280. int i, cAsm;
  2281. int iArg = (*piNext) + 1;
  2282. if (iArg >= argc)
  2283. {
  2284. fprintf(stderr, "%S: missing parameter after \"%S\"\n", argv[0], argv[iArg-1]);
  2285. goto Exit;
  2286. }
  2287. LoadSxs();
  2288. IFCOMFAILED_EXIT((*g_pfnCreateAssemblyCache)(&pCache, 0));
  2289. WideCharToMultiByte(CP_ACP, 0, argv[iArg], -1, buf, NUMBER_OF(buf), NULL, NULL);
  2290. fp = fopen(buf, "r");
  2291. if (!fp) {
  2292. fprintf(stderr, "%S: Error opening script file \"%S\"\n", argv[0], argv[iArg]);
  2293. goto Exit;
  2294. }
  2295. cAsm = 0;
  2296. while (! feof(fp)) {
  2297. if (! fgets(buf, 80, fp)) { // end of file or error
  2298. if (ferror(fp)){ // error occur
  2299. fprintf(stderr, "%S: Error occur while reading the script file\n", argv[0]);
  2300. goto Exit;
  2301. }
  2302. else{ // end of file
  2303. fprintf(stderr, "%S: end of script file\n", argv[0]);
  2304. break;
  2305. }
  2306. }
  2307. // trim the string
  2308. i = 0 ;
  2309. while (buf[i] == ' ') i++; // skip the whitespace at the beginning of the line
  2310. pbuf = buf + i ; // pointer to the first un-whitespace char in the line
  2311. i = 0 ;
  2312. while (pbuf[i] != '\n') i++;
  2313. pbuf[i] = '\0';
  2314. p1 = NULL;
  2315. p1 = strchr(pbuf, ' ');
  2316. if (p1 == NULL) { // instruction line
  2317. if (strcmp(pbuf, "BeginAsmCacheItem") == 0) {
  2318. IFCOMFAILED_EXIT(pCache->CreateAssemblyCacheItem(0, NULL, &ppCacheItem[cAsm], NULL));
  2319. }else
  2320. if (strcmp(pbuf, "EndAsmCacheItem") == 0) {
  2321. IFCOMFAILED_EXIT(ppCacheItem[cAsm]->Commit(0, NULL));
  2322. cAsm ++;
  2323. }
  2324. }
  2325. else
  2326. { // get the first word of the line
  2327. *p1 = '\0';
  2328. p1++; // p1 points to the filename now
  2329. IFW32FALSE_EXIT(SourceFileNameBuf.Win32Assign(p1, ::strlen(p1)));
  2330. if (strcmp(pbuf,"SourceFilePath") == 0) { // fullpath of source files, which would be in a CD
  2331. IFW32FALSE_EXIT(SourceFilePathBuf.Win32Assign(p1, ::strlen(p1)));
  2332. SourceFilePathBuf.Win32EnsureTrailingPathSeparator();
  2333. }else
  2334. if (strcmp(pbuf, "FILE") == 0) {
  2335. IFCOMFAILED_EXIT(ppCacheItem[cAsm]->CreateStream(0, SourceFileNameBuf, STREAM_FORMAT_WIN32_MODULE, 0, &pStream, NULL));
  2336. IFW32FALSE_EXIT(SourceFileNameBuf.Win32Assign(SourceFilePathBuf, ::wcslen(SourceFilePathBuf)));
  2337. IFW32FALSE_EXIT(SourceFileNameBuf.Win32Append(p1, ::strlen(p1))); // containing full-path of the source file
  2338. IFCOMFAILED_EXIT(Helper_WriteStream(&SourceFileNameBuf, pStream));
  2339. pStream.Release(); // stream should be released since writtingfile has been done
  2340. }else
  2341. if (strcmp(pbuf, "MANIFEST") == 0) {
  2342. IFCOMFAILED_EXIT(ppCacheItem[cAsm]->CreateStream(0, SourceFileNameBuf, STREAM_FORMAT_WIN32_MANIFEST, 0, &pStream, NULL));
  2343. IFW32FALSE_EXIT(SourceFileNameBuf.Win32Assign(SourceFilePathBuf, SourceFilePathBuf.Cch())); // containing full-path of the source file
  2344. IFW32FALSE_EXIT(SourceFileNameBuf.Win32Append(p1, ::strlen(p1)));
  2345. IFCOMFAILED_EXIT(Helper_WriteStream(&SourceFileNameBuf, pStream));
  2346. pStream.Release(); // stream should be released since writtingfile has been done
  2347. }
  2348. } // end of else
  2349. }// end of while
  2350. fSuccess = TRUE;
  2351. *piNext = iArg;
  2352. Exit:
  2353. fp ? fclose(fp) : 0;
  2354. return fSuccess;
  2355. }
  2356. CDirWalk::ECallbackResult
  2357. DirWalkCallback(
  2358. CDirWalk::ECallbackReason reason,
  2359. CDirWalk* dirWalk,
  2360. DWORD dwFlags
  2361. )
  2362. {
  2363. PCWSTR parent = dirWalk->m_strParent;
  2364. PCWSTR leaf = dirWalk->m_fileData.cFileName;
  2365. if (reason == CDirWalk::eFile)
  2366. printf("file %lu, %ls, %ls\n", reason, parent, leaf);
  2367. else
  2368. printf("directory %lu, %ls\n", reason, parent);
  2369. return CDirWalk::eKeepWalking;
  2370. }
  2371. int
  2372. TestDirWalk(
  2373. PCWSTR root,
  2374. PWSTR filter
  2375. )
  2376. {
  2377. #if 0
  2378. CDirWalk dirWalk;
  2379. StdVector<std::wstring> vstrFilter;
  2380. StdVector<PCWSTR> vstrFilter2;
  2381. PWSTR filterTok;
  2382. if (filterTok = wcstok(filter, L";"))
  2383. {
  2384. do
  2385. {
  2386. vstrFilter.push_back(filterTok);
  2387. vstrFilter2.push_back(vstrFilter.back().c_str());
  2388. } while (filterTok = wcstok(NULL, L";"));
  2389. }
  2390. dirWalk.m_fileFiltersBegin = &*vstrFilter2.begin();
  2391. dirWalk.m_fileFiltersEnd = &*vstrFilter2.end();
  2392. dirWalk.m_strParent.Win32Assign(root, ::wcslen(root));
  2393. dirWalk.m_callback = DirWalkCallback;
  2394. dirWalk.Walk();
  2395. #endif
  2396. return 0;
  2397. }
  2398. int
  2399. TestMultiAct(
  2400. int argc,
  2401. wchar_t **argv
  2402. )
  2403. {
  2404. HANDLE h1, h2;
  2405. ACTCTXW acw;
  2406. memset(&acw, 0, sizeof(acw));
  2407. acw.cbSize = sizeof(acw);
  2408. acw.dwFlags = ACTCTX_FLAG_RESOURCE_NAME_VALID;
  2409. acw.lpSource = argv[2];
  2410. acw.lpResourceName = MAKEINTRESOURCEW(1);
  2411. h1 = ::CreateActCtxW(&acw);
  2412. if (h1 == INVALID_HANDLE_VALUE)
  2413. {
  2414. fprintf(stderr, "1st CreateActCtxW() failed; ::GetLastError() = %d\n", ::GetLastError());
  2415. return EXIT_FAILURE;
  2416. }
  2417. h2 = ::CreateActCtxW(&acw);
  2418. if (h2 == INVALID_HANDLE_VALUE)
  2419. {
  2420. fprintf(stderr, "2nd CreateActCtxW() failed; ::GetLastError() = %d\n", ::GetLastError());
  2421. return EXIT_FAILURE;
  2422. }
  2423. return EXIT_SUCCESS;
  2424. }
  2425. BOOL
  2426. ParseProcessorArchitecture(
  2427. int argc,
  2428. wchar_t** argv,
  2429. int* piCurrent
  2430. )
  2431. {
  2432. BOOL fSuccess = FALSE;
  2433. int i = *piCurrent;
  2434. i++;
  2435. if (i >= argc)
  2436. {
  2437. fprintf(stderr, "%S: missing parameter after %S\n", argv[0], argv[i - 1]);
  2438. goto Exit;
  2439. }
  2440. if (::FusionpStrCmpI(argv[i], L"x86") == 0)
  2441. g.wProcessorArchitecture = PROCESSOR_ARCHITECTURE_INTEL;
  2442. else if (::FusionpStrCmpI(argv[i], L"i386") == 0)
  2443. g.wProcessorArchitecture = PROCESSOR_ARCHITECTURE_INTEL;
  2444. else if (::FusionpStrCmpI(argv[i], L"ia64") == 0)
  2445. g.wProcessorArchitecture = PROCESSOR_ARCHITECTURE_IA64;
  2446. else if (::FusionpStrCmpI(argv[i], L"amd64") == 0)
  2447. g.wProcessorArchitecture = PROCESSOR_ARCHITECTURE_AMD64;
  2448. else
  2449. {
  2450. fprintf(stderr, "%S: invalid -pa value \"%S\"\n", argv[0], argv[i]);
  2451. goto Exit;
  2452. }
  2453. *piCurrent = i + 1;
  2454. fSuccess = TRUE;
  2455. Exit:
  2456. return fSuccess;
  2457. }
  2458. BOOL
  2459. ParseLangId(
  2460. int argc,
  2461. wchar_t** argv,
  2462. int* piCurrent
  2463. )
  2464. {
  2465. BOOL fSuccess = FALSE;
  2466. int i = *piCurrent;
  2467. i++;
  2468. if (i >= argc)
  2469. {
  2470. fprintf(stderr, "%S: missing parameter after %S\n", argv[0], argv[i - 1]);
  2471. goto Exit;
  2472. }
  2473. swscanf(argv[i], L"%hx", &g.wLangId);
  2474. *piCurrent = i + 1;
  2475. fSuccess = TRUE;
  2476. Exit:
  2477. return fSuccess;
  2478. }
  2479. BOOL
  2480. TestLoadLibrary(
  2481. int argc,
  2482. wchar_t** argv,
  2483. int* piNext
  2484. )
  2485. {
  2486. int i = (*piNext) + 1;
  2487. HINSTANCE hInstance = NULL;
  2488. BOOL fExpectedToFail = FALSE;
  2489. BOOL fSuccess = FALSE;
  2490. while (i < argc)
  2491. {
  2492. if (::FusionpStrCmpI(argv[i], L"-fail-") == 0)
  2493. fExpectedToFail = TRUE;
  2494. else if (::FusionpStrCmpI(argv[i], L"-succeed-") == 0)
  2495. fExpectedToFail = FALSE;
  2496. else
  2497. {
  2498. hInstance = LoadLibraryW(argv[i]);
  2499. if (hInstance == NULL)
  2500. {
  2501. if (!fExpectedToFail)
  2502. {
  2503. fprintf(stderr, "%S: Failed to LoadLibraryW(\"%S\"); ::GetLastError() = %d\n", argv[0], argv[i], ::GetLastError());
  2504. }
  2505. }
  2506. else
  2507. {
  2508. if (fExpectedToFail)
  2509. {
  2510. WCHAR LibraryPath[4096];
  2511. Kernel32.GetModuleFileNameW(hInstance, LibraryPath, NUMBER_OF(LibraryPath));
  2512. fprintf(stderr, "%S: LoadLibraryW(\"%S\") was supposed to fail, but instead we got \"%S\"\n", argv[0], argv[i], LibraryPath);
  2513. }
  2514. ::FreeLibrary(hInstance);
  2515. hInstance = NULL;
  2516. }
  2517. }
  2518. i++;
  2519. }
  2520. fSuccess = TRUE;
  2521. // Exit:
  2522. return fSuccess;
  2523. }
  2524. int TestAssemblyName()
  2525. {
  2526. BOOL fSuccess = FALSE;
  2527. LoadSxs();
  2528. fSuccess = (*g_pfnSxspDebug)(SXS_DEBUG_ASSEMBLYNAME_CONVERSION, 0, NULL, NULL);
  2529. if (! fSuccess){
  2530. fprintf(stderr, "%s failed!\n", __FUNCTION__);
  2531. return EXIT_FAILURE;
  2532. }
  2533. else
  2534. return EXIT_SUCCESS;
  2535. }
  2536. int TestPrecomiledManifest(PCWSTR manifestFileName)
  2537. {
  2538. BOOL fSuccess = FALSE;
  2539. LoadSxs();
  2540. fSuccess = (*g_pfnSxspDebug)(SXS_DEBUG_PRECOMPILED_MANIFEST, 0, manifestFileName, NULL);
  2541. if (! fSuccess){
  2542. fprintf(stderr, "%s failed!\n", __FUNCTION__);
  2543. return EXIT_FAILURE;
  2544. }
  2545. else
  2546. return EXIT_SUCCESS;
  2547. }
  2548. int TestPCMTime(PCWSTR manifestFilename)
  2549. {
  2550. BOOL fSuccess = FALSE;
  2551. LoadSxs();
  2552. fSuccess = (*g_pfnSxspDebug)(SXS_DEBUG_TIME_PCM, 0, manifestFilename, NULL);
  2553. if (! fSuccess)
  2554. {
  2555. fprintf(stderr, "%s failed!\n", __FUNCTION__);
  2556. return EXIT_FAILURE;
  2557. }
  2558. else
  2559. return EXIT_SUCCESS;
  2560. }
  2561. int TestCreateMultiLevelDirectory(PCWSTR dirs)
  2562. {
  2563. BOOL fSuccess = FALSE;
  2564. LoadSxs();
  2565. fSuccess = (*g_pfnSxspDebug)(SXS_DEBUG_CREAT_MULTILEVEL_DIRECTORY, 0, dirs, NULL);
  2566. if (! fSuccess)
  2567. {
  2568. fprintf(stderr, "%s failed!\n", __FUNCTION__);
  2569. return EXIT_FAILURE;
  2570. }
  2571. else
  2572. return EXIT_SUCCESS;
  2573. }
  2574. BOOL
  2575. TestLeakMemory(
  2576. DWORD dwAmount
  2577. )
  2578. {
  2579. BOOL fSuccess = FALSE;
  2580. if (dwAmount < 1) {
  2581. fprintf(stderr, "%s got a bad parameter, %d; rectifying to 1.\n", __FUNCTION__, dwAmount);
  2582. dwAmount = 1;
  2583. }
  2584. LoadSxs();
  2585. fSuccess = (*g_pfnSxspDebug)(SXS_DEBUG_FORCE_LEAK, 0, NULL, (PDWORD)&dwAmount);
  2586. if (! fSuccess)
  2587. {
  2588. fprintf(stderr, "%s failed to leak %d bytes of memory!\n", __FUNCTION__, dwAmount);
  2589. return EXIT_FAILURE;
  2590. }
  2591. else
  2592. {
  2593. fprintf(stdout, "%s leaked %d bytes of memory.\n", __FUNCTION__, dwAmount);
  2594. return EXIT_SUCCESS;
  2595. }
  2596. }
  2597. BOOL
  2598. TestManifestProbing(
  2599. int argc,
  2600. wchar_t **argv,
  2601. int *piNext
  2602. )
  2603. {
  2604. BOOL fSuccess = FALSE;
  2605. LoadSxs();
  2606. fSuccess = (*g_pfnSxspDebug)(SXS_DEBUG_PROBE_MANIFST, 0, NULL, NULL);
  2607. if (! fSuccess){
  2608. fprintf(stderr, "%s failed!\n", __FUNCTION__);
  2609. return EXIT_FAILURE;
  2610. }
  2611. else
  2612. return EXIT_SUCCESS;
  2613. }
  2614. BOOL
  2615. TestAssemblyProbing(
  2616. int argc,
  2617. wchar_t **argv,
  2618. int *piNext
  2619. )
  2620. {
  2621. BOOL fSuccess = FALSE;
  2622. DWORD dwDisposition = 0;
  2623. LoadSxs();
  2624. fSuccess = (*g_pfnSxsProbeAssemblyInstallation)(0, argv[*piNext], &dwDisposition);
  2625. return (fSuccess ? EXIT_SUCCESS : EXIT_FAILURE);
  2626. }
  2627. int TestCreateProcess2(wchar_t** argv)
  2628. {
  2629. STARTUPINFOW StartupInfo = { sizeof(StartupInfo) };
  2630. PROCESS_INFORMATION ProcessInformation = {0};
  2631. *argv += wcsspn(*argv, L" \t\r\n");
  2632. BOOL f = ::CreateProcessW(
  2633. *argv,
  2634. NULL,
  2635. NULL,
  2636. NULL,
  2637. FALSE,
  2638. 0,
  2639. NULL,
  2640. NULL,
  2641. &StartupInfo,
  2642. &ProcessInformation);
  2643. printf("CreateProcess(%S) returned %s\n", *argv, f ? "True" : "False");
  2644. return EXIT_SUCCESS;
  2645. }
  2646. int TestCreateProcess(wchar_t** argv)
  2647. {
  2648. CUnicodeStringBuffer CommandLine;
  2649. STARTUPINFOW StartupInfo = { sizeof(StartupInfo) };
  2650. PROCESS_INFORMATION ProcessInformation = {0};
  2651. while (*argv)
  2652. {
  2653. CommandLine.Win32Append(L" ", 1);
  2654. CommandLine.Win32Append(*argv, ::wcslen(*argv));
  2655. argv++;
  2656. }
  2657. CUnicodeStringBufferAccessor MutableCommandLine(&CommandLine);
  2658. BOOL f = ::CreateProcessW(
  2659. NULL,
  2660. MutableCommandLine,
  2661. NULL,
  2662. NULL,
  2663. FALSE,
  2664. 0,
  2665. NULL,
  2666. NULL,
  2667. &StartupInfo,
  2668. &ProcessInformation);
  2669. printf("CreateProcess(%S) returned %s\n", static_cast<PCWSTR>(MutableCommandLine), f ? "True" : "False");
  2670. return EXIT_SUCCESS;
  2671. }
  2672. ////////////////////////////////////////////////////////////////////////////
  2673. // XMLDOM Helper function:
  2674. ////////////////////////////////////////////////////////////////////////////
  2675. HRESULT XMLDOMHelper_WalkTree(IXMLDOMNode* node, int level)
  2676. {
  2677. IXMLDOMNode* pChild, *pNext;
  2678. BSTR nodeName;
  2679. IXMLDOMNamedNodeMap* pattrs;
  2680. node->get_nodeName(&nodeName);
  2681. for (int i = 0; i < level; i++)
  2682. printf(" ");
  2683. printf("%S",nodeName);
  2684. SysFreeString(nodeName);
  2685. if (SUCCEEDED(node->get_attributes(&pattrs)) && pattrs != NULL)
  2686. {
  2687. pattrs->nextNode(&pChild);
  2688. while (pChild)
  2689. {
  2690. BSTR name;
  2691. pChild->get_nodeName(&name);
  2692. printf(" %S='", name);
  2693. ::SysFreeString(name);
  2694. VARIANT value;
  2695. pChild->get_nodeValue(&value);
  2696. if (value.vt == VT_BSTR)
  2697. {
  2698. printf("%S", V_BSTR(&value));
  2699. }
  2700. printf("'");
  2701. VariantClear(&value);
  2702. pChild->Release();
  2703. pattrs->nextNode(&pChild);
  2704. }
  2705. pattrs->Release();
  2706. }
  2707. printf("\n");
  2708. node->get_firstChild(&pChild);
  2709. while (pChild)
  2710. {
  2711. XMLDOMHelper_WalkTree(pChild, level+1);
  2712. pChild->get_nextSibling(&pNext);
  2713. pChild->Release();
  2714. pChild = pNext;
  2715. }
  2716. return S_OK;
  2717. }
  2718. ////////////////////////////////////////////////////////////////////////////
  2719. // XMLDOM Helper function:
  2720. ////////////////////////////////////////////////////////////////////////////
  2721. HRESULT XMLDOMHelper_ReportError(IXMLDOMParseError *pXMLError)
  2722. {
  2723. long line, linePos;
  2724. LONG errorCode;
  2725. BSTR pBURL = NULL, pBReason = NULL;
  2726. HRESULT hr;
  2727. hr = pXMLError->get_line(&line);
  2728. if (FAILED(hr))
  2729. goto Exit;
  2730. hr = pXMLError->get_linepos(&linePos);
  2731. if (FAILED(hr))
  2732. goto Exit;
  2733. hr = pXMLError->get_errorCode(&errorCode);
  2734. if (FAILED(hr))
  2735. goto Exit;
  2736. hr = pXMLError->get_url(&pBURL);
  2737. if (FAILED(hr))
  2738. goto Exit;
  2739. hr = pXMLError->get_reason(&pBReason);
  2740. if (FAILED(hr))
  2741. goto Exit;
  2742. fprintf(stderr, "%S", pBReason);
  2743. if (line > 0)
  2744. {
  2745. fprintf(stderr, "Error on line %d, position %d in \"%S\".\n",
  2746. line, linePos, pBURL);
  2747. }
  2748. hr= E_FAIL;
  2749. Exit:
  2750. SysFreeString(pBURL);
  2751. SysFreeString(pBReason);
  2752. return hr;
  2753. }
  2754. ////////////////////////////////////////////////////////////////////////////
  2755. // XMLDOM Helper function: Check load results
  2756. ////////////////////////////////////////////////////////////////////////////
  2757. HRESULT XMLDOMHelper_CheckLoad(IXMLDOMDocument* pDoc)
  2758. {
  2759. // And since we don't have the VARIANT_BOOL from load we
  2760. // need to check the parse Error errorCode property to see
  2761. // if everything went ok.
  2762. IXMLDOMParseError *pXMLError = NULL;
  2763. LONG errorCode;
  2764. HRESULT hr = NOERROR;
  2765. hr = pDoc->get_parseError(&pXMLError);
  2766. if (FAILED(hr))
  2767. goto Exit;
  2768. hr = pXMLError->get_errorCode(&errorCode);
  2769. if (FAILED(hr))
  2770. goto Exit;
  2771. if (errorCode != 0){
  2772. hr = XMLDOMHelper_ReportError(pXMLError);
  2773. goto Exit;
  2774. }
  2775. hr = NOERROR;
  2776. Exit:
  2777. if (pXMLError)
  2778. pXMLError->Release();
  2779. return hr;
  2780. }
  2781. ////////////////////////////////////////////////////////////////////////////
  2782. // XMLDOM Helper function:
  2783. ////////////////////////////////////////////////////////////////////////////
  2784. HRESULT XMLDOMHelper_LoadDocumentSync(IXMLDOMDocument *pDoc, BSTR pBURL)
  2785. {
  2786. IXMLDOMParseError *pXMLError = NULL;
  2787. VARIANT vURL;
  2788. VARIANT_BOOL vb;
  2789. HRESULT hr;
  2790. hr = pDoc->put_async(VARIANT_FALSE);
  2791. if (FAILED(hr))
  2792. goto Exit;
  2793. // Load xml document from the given URL or file path
  2794. VariantInit(&vURL);
  2795. vURL.vt = VT_BSTR;
  2796. V_BSTR(&vURL) = pBURL;
  2797. hr = pDoc->load(vURL, &vb);
  2798. if (FAILED(hr))
  2799. goto Exit;
  2800. hr = XMLDOMHelper_CheckLoad(pDoc);
  2801. if (FAILED(hr))
  2802. goto Exit;
  2803. hr = NOERROR;
  2804. Exit:
  2805. if (pXMLError)
  2806. pXMLError->Release();
  2807. return hr;
  2808. }
  2809. BOOL TestXMLDOM(PCWSTR pswzXMLFileName)
  2810. {
  2811. HRESULT hr = S_OK;
  2812. IXMLDOMDocument *pDoc = NULL;
  2813. IXMLDOMNode* pNode = NULL;
  2814. BSTR pBURL = NULL;
  2815. Ole32.CoInitialize(NULL);
  2816. // Create an empty XML document
  2817. hr = Ole32.CoCreateInstance(CLSID_DOMDocument, NULL, CLSCTX_INPROC_SERVER,
  2818. IID_IXMLDOMDocument, (void**)&pDoc);
  2819. if (FAILED(hr))
  2820. goto Exit;
  2821. pBURL = SysAllocString(pswzXMLFileName);
  2822. hr = XMLDOMHelper_LoadDocumentSync(pDoc, pBURL);
  2823. if (FAILED(hr))
  2824. goto Exit;
  2825. // Now walk the loaded XML document dumping the node names to stdout.
  2826. hr = pDoc->QueryInterface(IID_IXMLDOMNode,(void**)&pNode);
  2827. if (FAILED(hr))
  2828. goto Exit;
  2829. hr = XMLDOMHelper_WalkTree(pNode,0);
  2830. if (FAILED(hr))
  2831. goto Exit;
  2832. hr = NOERROR;
  2833. Exit:
  2834. if (pDoc) pDoc->Release();
  2835. SysFreeString(pBURL);
  2836. if (pNode) pNode->Release();
  2837. Ole32.CoUninitialize();
  2838. return hr == 0 ? 0 : 1;
  2839. }
  2840. BOOL TestFusionArray(PCWSTR dir1, PCWSTR dir2)
  2841. {
  2842. BOOL fSuccess = FALSE;
  2843. LoadSxs();
  2844. fSuccess = (*g_pfnSxspDebug)(SXS_DEBUG_FUSION_ARRAY, 0, dir1, (PVOID)dir2);
  2845. if (! fSuccess){
  2846. fprintf(stderr, "%s failed!\n", __FUNCTION__);
  2847. return EXIT_FAILURE;
  2848. }
  2849. else
  2850. return EXIT_SUCCESS;
  2851. }
  2852. BOOL TestGeneratePathFromIdentityAttributeString(PCWSTR str)
  2853. {
  2854. BOOL fSuccess = FALSE;
  2855. WCHAR folderName[5000];
  2856. SIZE_T cch = NUMBER_OF(folderName);
  2857. LoadSxs();
  2858. fSuccess = (*g_pfnGenerateManifestPathOnAssemblyIdentity)((PWSTR) str, folderName, &cch, NULL);
  2859. if (! fSuccess)
  2860. {
  2861. fprintf(stderr, "%s failed!\n", __FUNCTION__);
  2862. return EXIT_FAILURE;
  2863. }
  2864. else
  2865. {
  2866. wprintf(L"Folder name returned is %s\n", folderName);
  2867. return EXIT_SUCCESS;
  2868. }
  2869. }
  2870. BOOL
  2871. TestDirectoryChangeWatcher(
  2872. int argc,
  2873. wchar_t **argv,
  2874. int *piNext
  2875. )
  2876. {
  2877. BOOL fSuccess = FALSE;
  2878. LoadSxs();
  2879. fSuccess = (*g_pfnSxspDebug)(SXS_DEBUG_DIRECTORY_WATCHER, 0, NULL, NULL);
  2880. return (fSuccess ? EXIT_SUCCESS : EXIT_FAILURE);
  2881. }
  2882. BOOL
  2883. TestRefreshAssembly(
  2884. PCWSTR wsAssemblyManifest
  2885. )
  2886. {
  2887. BOOL fSuccess = FALSE;
  2888. SXS_INSTALLW Install = {sizeof(Install)};
  2889. LoadSxs();
  2890. Install.dwFlags = SXS_INSTALL_FLAG_REPLACE_EXISTING;
  2891. Install.lpManifestPath = wsAssemblyManifest;
  2892. if (!g_pfnSxsInstallW(&Install))
  2893. {
  2894. fwprintf(
  2895. stderr,
  2896. L"Failed reinstalling assembly '%ls', 0x%08X\n",
  2897. wsAssemblyManifest,
  2898. ::GetLastError());
  2899. }
  2900. else
  2901. {
  2902. fSuccess = TRUE;
  2903. }
  2904. return fSuccess;
  2905. }
  2906. BOOL
  2907. TestInstallWithInstallInfo(
  2908. PCWSTR wsAssemblyManifest,
  2909. PCWSTR wsReferenceString
  2910. )
  2911. {
  2912. #define SXS_TEST
  2913. BOOL fSuccess = FALSE;
  2914. FN_TRACE_WIN32(fSuccess);
  2915. SXS_INSTALLW InstallParameters = {sizeof(InstallParameters)};
  2916. SXS_INSTALL_REFERENCEW InstallReference = {sizeof(InstallReference)};
  2917. LoadSxs();
  2918. InstallParameters.dwFlags =
  2919. SXS_INSTALL_FLAG_REPLACE_EXISTING |
  2920. SXS_INSTALL_FLAG_CODEBASE_URL_VALID |
  2921. SXS_INSTALL_FLAG_REFERENCE_VALID |
  2922. SXS_INSTALL_FLAG_REFRESH_PROMPT_VALID |
  2923. SXS_INSTALL_FLAG_FROM_CABINET;
  2924. //
  2925. // if the manfiest file is a dll file, set SXS_INSTALL_FLAG_FROM_RESOURCE
  2926. //
  2927. {
  2928. PWSTR p = wcsrchr(wsAssemblyManifest, L'.');
  2929. if ((p) && ((wcscmp(p, L".dll")== 0) || (wcscmp(p, L".exe")== 0)))
  2930. InstallParameters.dwFlags |= SXS_INSTALL_FLAG_FROM_RESOURCE;
  2931. }
  2932. InstallParameters.lpCodebaseURL = wsAssemblyManifest;
  2933. InstallParameters.lpManifestPath = wsAssemblyManifest;
  2934. InstallParameters.lpReference = &InstallReference;
  2935. InstallParameters.lpRefreshPrompt = L"boop";
  2936. InstallReference.guidScheme = SXS_INSTALL_REFERENCE_SCHEME_OPAQUESTRING;
  2937. InstallReference.lpIdentifier = wsReferenceString ? wsReferenceString : L"TempRef";
  2938. if (!(*g_pfnSxsInstallW)(&InstallParameters))
  2939. {
  2940. goto Exit;
  2941. }
  2942. fSuccess = TRUE;
  2943. Exit:
  2944. if (!fSuccess)
  2945. {
  2946. fprintf(stderr, "%s failed!\n", __FUNCTION__);
  2947. return EXIT_FAILURE;
  2948. }
  2949. else
  2950. return EXIT_SUCCESS;
  2951. }
  2952. BOOL
  2953. TestInstallLikeWindowsSetup(
  2954. PCWSTR wsAssemblyManifest,
  2955. PCWSTR wsCodebase
  2956. )
  2957. {
  2958. BOOL fSuccess = FALSE;
  2959. FN_TRACE_WIN32(fSuccess);
  2960. SXS_INSTALLW InstallParameters = {sizeof(InstallParameters)};
  2961. SXS_INSTALL_REFERENCEW InstallReference = {sizeof(InstallReference)};
  2962. LoadSxs();
  2963. IFW32FALSE_EXIT(
  2964. (*g_pfnSxsBeginAssemblyInstall)(
  2965. SXS_BEGIN_ASSEMBLY_INSTALL_FLAG_NOT_TRANSACTIONAL
  2966. | SXS_BEGIN_ASSEMBLY_INSTALL_FLAG_NO_VERIFY
  2967. | SXS_BEGIN_ASSEMBLY_INSTALL_FLAG_REPLACE_EXISTING,
  2968. NULL,
  2969. NULL,
  2970. NULL,
  2971. NULL,
  2972. &InstallParameters.pvInstallCookie));
  2973. InstallReference.guidScheme = SXS_INSTALL_REFERENCE_SCHEME_OSINSTALL;
  2974. InstallReference.lpNonCanonicalData = L"Foom";
  2975. /*
  2976. InstallParameters.dwFlags |= SXS_INSTALL_FLAG_CODEBASE_URL_VALID
  2977. | SXS_INSTALL_FLAG_FROM_DIRECTORY
  2978. | SXS_INSTALL_FLAG_FROM_DIRECTORY_RECURSIVE
  2979. | SXS_INSTALL_FLAG_FROM_CABINET
  2980. | SXS_INSTALL_FLAG_REFRESH_PROMPT_VALID
  2981. | SXS_INSTALL_FLAG_INSTALL_COOKIE_VALID
  2982. | SXS_INSTALL_FLAG_REFERENCE_VALID
  2983. ;
  2984. */
  2985. //
  2986. // First call - indicate that the given path may contain asmsN.cab
  2987. //
  2988. InstallParameters.lpCodebaseURL = wsCodebase;
  2989. InstallParameters.lpRefreshPrompt = L"like..Windows CD..";
  2990. InstallParameters.lpManifestPath = wsAssemblyManifest;
  2991. InstallParameters.lpReference = &InstallReference;
  2992. InstallParameters.dwFlags = SXS_INSTALL_FLAG_FROM_DIRECTORY |
  2993. SXS_INSTALL_FLAG_REFERENCE_VALID |
  2994. SXS_INSTALL_FLAG_REFRESH_PROMPT_VALID |
  2995. SXS_INSTALL_FLAG_INSTALL_COOKIE_VALID |
  2996. SXS_INSTALL_FLAG_INSTALLED_BY_OSSETUP |
  2997. SXS_INSTALL_FLAG_FROM_CABINET |
  2998. SXS_INSTALL_FLAG_CODEBASE_URL_VALID;
  2999. IFW32FALSE_EXIT((*g_pfnSxsInstallW)(&InstallParameters));
  3000. InstallParameters.dwFlags = SXS_INSTALL_FLAG_FROM_DIRECTORY |
  3001. SXS_INSTALL_FLAG_FROM_DIRECTORY_RECURSIVE |
  3002. SXS_INSTALL_FLAG_REFERENCE_VALID |
  3003. SXS_INSTALL_FLAG_REFRESH_PROMPT_VALID |
  3004. SXS_INSTALL_FLAG_INSTALL_COOKIE_VALID |
  3005. SXS_INSTALL_FLAG_INSTALLED_BY_OSSETUP |
  3006. SXS_INSTALL_FLAG_CODEBASE_URL_VALID;
  3007. IFW32FALSE_EXIT((*g_pfnSxsInstallW)(&InstallParameters));
  3008. IFW32FALSE_EXIT(
  3009. (*g_pfnSxsEndAssemblyInstall)(
  3010. InstallParameters.pvInstallCookie,
  3011. SXS_END_ASSEMBLY_INSTALL_FLAG_COMMIT,
  3012. NULL));
  3013. InstallParameters.pvInstallCookie = NULL;
  3014. fSuccess = TRUE;
  3015. Exit:
  3016. if (InstallParameters.pvInstallCookie != NULL)
  3017. {
  3018. CSxsPreserveLastError ple;
  3019. (void) (*g_pfnSxsEndAssemblyInstall)(InstallParameters.pvInstallCookie, SXS_END_ASSEMBLY_INSTALL_FLAG_ABORT, NULL);
  3020. ple.Restore();
  3021. }
  3022. if (!fSuccess)
  3023. {
  3024. fprintf(stderr, "%s failed!\n", __FUNCTION__);
  3025. return EXIT_FAILURE;
  3026. }
  3027. else
  3028. return EXIT_SUCCESS;
  3029. }
  3030. //#define ASM_CPUID { __asm __emit 0fh __asm __emit 0a2h }
  3031. #define ASM_CPUID { __asm cpuid }
  3032. #define ASM_RDTSC { __asm rdtsc }
  3033. inline VOID GetCpuIdLag(LARGE_INTEGER *ref)
  3034. {
  3035. #if !defined(_WIN64)
  3036. LARGE_INTEGER temp, temp2;
  3037. _asm
  3038. {
  3039. cpuid
  3040. cpuid
  3041. cpuid
  3042. cpuid
  3043. cpuid
  3044. rdtsc
  3045. mov temp.LowPart, eax
  3046. mov temp.HighPart, edx
  3047. cpuid
  3048. rdtsc
  3049. mov temp2.LowPart, eax
  3050. mov temp2.HighPart, edx
  3051. }
  3052. ref->QuadPart = temp2.QuadPart - temp.QuadPart;
  3053. #else
  3054. ref->QuadPart = 0;
  3055. #endif
  3056. }
  3057. BOOL
  3058. TestOpeningStuff(PCWSTR wsSourceName, PCWSTR wsType, PCWSTR wsCount)
  3059. {
  3060. BOOL fSuccess = FALSE;
  3061. LARGE_INTEGER llStartCount, llEndCount, llCountsPerSec, llTotalSizeSoFar;
  3062. LARGE_INTEGER CpuIdLag;
  3063. BYTE bBuffer[65536];
  3064. SIZE_T cNumTries = _wtol(wsCount);
  3065. double dCountsPerSecond, dSeconds, dCountsPerIteration, dSecondsPerIteration;
  3066. int iFinalIterationsPerSecond;
  3067. GetCpuIdLag(&CpuIdLag);
  3068. llTotalSizeSoFar.QuadPart = 0;
  3069. {
  3070. FUSION_PERF_INFO PerfInfo[2];
  3071. HANDLE hFile;
  3072. for (int i = 0; i < 5000; i++)
  3073. {
  3074. PERFINFOTIME(&PerfInfo[0], hFile = ::CreateFileW(wsSourceName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, NULL));
  3075. PERFINFOTIME(&PerfInfo[1], ::CloseHandle(hFile));
  3076. }
  3077. FusionpReportPerfInfo(
  3078. FUSIONPERF_DUMP_TO_STDOUT |
  3079. FUSIONPERF_DUMP_ALL_STATISTICS |
  3080. FUSIONPERF_DUMP_ALL_SOURCEINFO,
  3081. PerfInfo,
  3082. NUMBER_OF(PerfInfo));
  3083. }
  3084. //
  3085. // Map the DLL as a resource a few thousand times.
  3086. //
  3087. if ((wsType[0] == L'd') || (wsType[0] == L's'))
  3088. {
  3089. FUSION_PERF_INFO PerfInfo[7];
  3090. HMODULE hDllModule;
  3091. HRSRC hManifestResource;
  3092. HGLOBAL hResource;
  3093. PVOID pvResourceData;
  3094. SIZE_T cbResourceSize;
  3095. for (SIZE_T i = 0; i < cNumTries; i++)
  3096. {
  3097. PERFINFOTIME(&PerfInfo[0], hDllModule = ::LoadLibraryExW(wsSourceName, NULL, DONT_RESOLVE_DLL_REFERENCES | LOAD_LIBRARY_AS_DATAFILE));
  3098. PERFINFOTIME(&PerfInfo[1], hManifestResource = ::FindResourceW(hDllModule, L"#1", MAKEINTRESOURCEW(RT_MANIFEST)));
  3099. PERFINFOTIME(&PerfInfo[2], hResource = ::LoadResource(hDllModule, hManifestResource));
  3100. PERFINFOTIME(&PerfInfo[3], pvResourceData = ::LockResource(hResource));
  3101. PERFINFOTIME(&PerfInfo[4], cbResourceSize = ::SizeofResource(hDllModule, hManifestResource));
  3102. PERFINFOTIME(&PerfInfo[5],
  3103. { for (SIZE_T i2 = 0; i2 < cbResourceSize; i2++)
  3104. bBuffer[i2] = ((PBYTE)pvResourceData)[i2]; }
  3105. );
  3106. PERFINFOTIME(&PerfInfo[6], FreeLibrary(hDllModule))
  3107. }
  3108. FusionpReportPerfInfo(
  3109. FUSIONPERF_DUMP_TO_STDOUT |
  3110. FUSIONPERF_DUMP_ALL_STATISTICS |
  3111. FUSIONPERF_DUMP_ALL_SOURCEINFO,
  3112. PerfInfo,
  3113. NUMBER_OF(PerfInfo));
  3114. }
  3115. else if (wsType[0] == L'x')
  3116. {
  3117. HANDLE hFile;
  3118. HANDLE hFileMapping;
  3119. PVOID pvFileData;
  3120. SIZE_T cbFileSize;
  3121. FUSION_PERF_INFO PerfInfo[9];
  3122. for (SIZE_T i = 0; i < cNumTries; i++)
  3123. {
  3124. PERFINFOTIME(&PerfInfo[0], hFile = ::CreateFileW(wsSourceName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, NULL));
  3125. PERFINFOTIME(&PerfInfo[1], cbFileSize = ::GetFileSize(hFile, 0));
  3126. PERFINFOTIME(&PerfInfo[2], hFileMapping = ::CreateFileMappingW(hFile, NULL, PAGE_READONLY, 0, 0, NULL));
  3127. PERFINFOTIME(&PerfInfo[3], pvFileData = ::MapViewOfFile(hFileMapping, FILE_MAP_READ, 0, 0, 0));
  3128. PERFINFOTIME(&PerfInfo[4], { for (SIZE_T i2 = 0; i2 < cbFileSize; i2++)
  3129. PERFINFOTIME(&PerfInfo[8], bBuffer[i2] = ((PBYTE)pvFileData)[i2]); });
  3130. PERFINFOTIME(&PerfInfo[5], ::UnmapViewOfFile(pvFileData));
  3131. PERFINFOTIME(&PerfInfo[6], ::CloseHandle(hFileMapping));
  3132. PERFINFOTIME(&PerfInfo[7], ::CloseHandle(hFile));
  3133. }
  3134. FusionpReportPerfInfo(
  3135. FUSIONPERF_DUMP_TO_STDOUT |
  3136. FUSIONPERF_DUMP_ALL_STATISTICS |
  3137. FUSIONPERF_DUMP_ALL_SOURCEINFO,
  3138. PerfInfo,
  3139. NUMBER_OF(PerfInfo));
  3140. }
  3141. else if (wsType[0] == L'r')
  3142. {
  3143. BYTE bTempBlock[8192];
  3144. ULONG cbReadCount;
  3145. FUSION_PERF_INFO PerfInfo[3];
  3146. for (SIZE_T i = 0; i < cNumTries; i++)
  3147. {
  3148. CResourceStream RStream;
  3149. QueryPerformanceCounter(&llStartCount);
  3150. PERFINFOTIME(&PerfInfo[0], RStream.Initialize(wsSourceName, MAKEINTRESOURCEW(RT_MANIFEST)));
  3151. PERFINFOTIME(&PerfInfo[1], RStream.Read(bTempBlock, sizeof(bTempBlock), &cbReadCount));
  3152. PERFINFOTIME(&PerfInfo[2],
  3153. for (SIZE_T i2 = 0; i2 < cbReadCount; i2++)
  3154. {
  3155. bBuffer[i2] = bTempBlock[i2];
  3156. }
  3157. );
  3158. wprintf(L"%s", bBuffer);
  3159. QueryPerformanceCounter(&llEndCount);
  3160. llTotalSizeSoFar.QuadPart += llEndCount.QuadPart - llStartCount.QuadPart;
  3161. }
  3162. for (int i = 0; i < NUMBER_OF(PerfInfo); i++)
  3163. {
  3164. FusionpDumpPerfInfo(FUSIONPERF_DUMP_TO_STDOUT, PerfInfo + i);
  3165. }
  3166. }
  3167. else if (wsType[0] == L'f')
  3168. {
  3169. BYTE bTempBlock[8192];
  3170. ULONG cbReadCount;
  3171. for (SIZE_T i = 0; i < cNumTries; i++)
  3172. {
  3173. CFileStream RStream;
  3174. QueryPerformanceCounter(&llStartCount);
  3175. RStream.OpenForRead(
  3176. wsSourceName,
  3177. CImpersonationData(),
  3178. FILE_SHARE_READ,
  3179. OPEN_EXISTING,
  3180. FILE_FLAG_SEQUENTIAL_SCAN);
  3181. RStream.Read(bTempBlock, sizeof(bTempBlock), &cbReadCount);
  3182. for (SIZE_T i2 = 0; i2 < cbReadCount; i2++)
  3183. {
  3184. bBuffer[i2] = bTempBlock[i2];
  3185. }
  3186. QueryPerformanceCounter(&llEndCount);
  3187. llTotalSizeSoFar.QuadPart += llEndCount.QuadPart - llStartCount.QuadPart;
  3188. }
  3189. }
  3190. QueryPerformanceFrequency(&llCountsPerSec);
  3191. dCountsPerIteration = (double)llTotalSizeSoFar.QuadPart / cNumTries;
  3192. dCountsPerSecond = (double)llCountsPerSec.QuadPart;
  3193. dSeconds = (double)llTotalSizeSoFar.QuadPart / dCountsPerSecond;
  3194. dSecondsPerIteration = dCountsPerIteration / dCountsPerSecond;
  3195. iFinalIterationsPerSecond = static_cast<int>(1.0 / dSecondsPerIteration);
  3196. fwprintf(
  3197. stdout,
  3198. L"Completed %d runs: %d attempts per second available\n",
  3199. cNumTries,
  3200. iFinalIterationsPerSecond);
  3201. fSuccess = TRUE;
  3202. return fSuccess;
  3203. }
  3204. BOOL
  3205. TestVerifyFileSignature(PCWSTR wsFilename)
  3206. {
  3207. WINTRUST_FILE_INFO fInfo;
  3208. WINTRUST_DATA wtData;
  3209. GUID guidTrustType = WINTRUST_ACTION_GENERIC_VERIFY_V2;
  3210. HRESULT hResult = E_FAIL;
  3211. PWSTR pwszMessageText = NULL;
  3212. ZeroMemory(&wtData, sizeof(wtData));
  3213. ZeroMemory(&fInfo, sizeof(fInfo));
  3214. fInfo.cbStruct = sizeof(fInfo);
  3215. fInfo.pcwszFilePath = wsFilename;
  3216. fInfo.hFile = NULL;
  3217. wtData.cbStruct = sizeof(wtData);
  3218. wtData.dwUIChoice = WTD_UI_ALL;
  3219. wtData.fdwRevocationChecks = WTD_REVOKE_WHOLECHAIN;
  3220. wtData.dwUnionChoice = WTD_CHOICE_FILE;
  3221. wtData.pFile = &fInfo;
  3222. hResult = WinVerifyTrust(0, &guidTrustType, &wtData);
  3223. if (FAILED(hResult))
  3224. {
  3225. ::FormatMessageW(
  3226. FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER,
  3227. NULL,
  3228. hResult,
  3229. 0,
  3230. (PWSTR)&pwszMessageText,
  3231. 500,
  3232. NULL);
  3233. fwprintf(stdout, L"Error: %ls (code 0x%08x)\n", pwszMessageText, hResult);
  3234. LocalFree(pwszMessageText);
  3235. }
  3236. else
  3237. {
  3238. fwprintf(stdout, L"File signature(s) are valid.");
  3239. }
  3240. return TRUE;
  3241. }
  3242. BOOL TestMessagePerf(int argc, wchar_t **argv, int *piNext)
  3243. {
  3244. ATOM a;
  3245. WNDCLASSEXW wc;
  3246. ULONGLONG cc1, cc2, cc3, cc4;
  3247. ULONG i, t;
  3248. HWND hwnd;
  3249. MSG m;
  3250. ULONG mcount;
  3251. HANDLE hActCtx = NULL;
  3252. ULONG_PTR ulCookie;
  3253. wc.cbSize = sizeof(wc);
  3254. wc.style = 0;
  3255. wc.lpfnWndProc = &TestMessagePerfWndProc;
  3256. wc.cbClsExtra = 0;
  3257. wc.cbWndExtra = 0;
  3258. wc.hInstance = NULL;
  3259. wc.hIcon = NULL;
  3260. wc.hCursor = NULL;
  3261. wc.hbrBackground = NULL;
  3262. wc.lpszMenuName = NULL;
  3263. wc.lpszClassName = L"SxsMsgPerfTest";
  3264. wc.hIconSm = NULL;
  3265. printf("Beginning message perf test...\n");
  3266. a = ::RegisterClassExW(&wc);
  3267. if (a == NULL)
  3268. {
  3269. printf("RegisterClassExW() failed; ::GetLastError = %d\n", ::GetLastError());
  3270. return FALSE;
  3271. }
  3272. if (argv[*piNext][0] != L'*')
  3273. {
  3274. ACTCTXW ac;
  3275. ac.cbSize = sizeof(ac);
  3276. ac.dwFlags = 0;
  3277. ac.lpSource = argv[*piNext];
  3278. hActCtx = ::CreateActCtxW(&ac);
  3279. if (hActCtx == INVALID_HANDLE_VALUE)
  3280. {
  3281. printf("CreateActCtxW() failed; ::GetLastError() = %d\n", ::GetLastError());
  3282. goto ErrorExit;
  3283. }
  3284. }
  3285. if (!ActivateActCtx(hActCtx, &ulCookie))
  3286. {
  3287. printf("ActivateActCtx() failed; ::GetLastError() = %d\n", ::GetLastError());
  3288. goto ErrorExit;
  3289. }
  3290. (*piNext)++;
  3291. hwnd = ::CreateWindowW(
  3292. (LPCWSTR) a,
  3293. L"PerfTestWindow",
  3294. WS_VISIBLE,
  3295. 0, // x
  3296. 0, // y
  3297. 100, // width
  3298. 100, // height
  3299. NULL, // hwndParent
  3300. NULL, // hMenu
  3301. NULL, // hInstance
  3302. NULL); // lpParam
  3303. if (hwnd == NULL)
  3304. return FALSE;
  3305. t = _wtoi(argv[*piNext]);
  3306. (*piNext)++;
  3307. mcount = 0;
  3308. cc3 = 0;
  3309. cc4 = 0;
  3310. for (i=0; i<t; i++)
  3311. {
  3312. if (!PostMessageW(hwnd, WM_USER, 0, 0))
  3313. {
  3314. printf("PostMessageW() failed; ::GetLastError() = %d\n", ::GetLastError());
  3315. goto ErrorExit;
  3316. }
  3317. cc1 = GetCycleCount();
  3318. while (::PeekMessage(&m, hwnd, 0, 0, PM_REMOVE))
  3319. {
  3320. mcount++;
  3321. ::TranslateMessage(&m);
  3322. ::DispatchMessage(&m);
  3323. }
  3324. cc2 = GetCycleCount();
  3325. // accumulate the time spend just processing the message...
  3326. cc3 = cc3 + (cc2 - cc1);
  3327. }
  3328. printf("%lu messages in %I64u cycles\n", mcount, cc3);
  3329. printf(" avg cycles/msg: %I64u\n", static_cast<ULONGLONG>((cc3 / static_cast<ULONGLONG>(mcount))));
  3330. return TRUE;
  3331. ErrorExit:
  3332. return FALSE;
  3333. }
  3334. LRESULT CALLBACK TestMessagePerfWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
  3335. {
  3336. return DefWindowProc(hwnd, uMsg, wParam, lParam);
  3337. }
  3338. void
  3339. TestTrickyMultipleAssemblyCacheItems(PCWSTR pvManifest)
  3340. {
  3341. CSmartRef<IAssemblyCache> AssemblyCache;
  3342. CSmartRef<IAssemblyCacheItem> AssemblyCacheItems[2];
  3343. CStringBuffer sbManifestName;
  3344. HRESULT hr;
  3345. LoadSxs();
  3346. sbManifestName.Win32Assign(pvManifest, wcslen(pvManifest));
  3347. for (int i = 0; i < 2; i++)
  3348. {
  3349. CSmartRef<IStream> pStream;
  3350. CSmartRef<IAssemblyCacheItem> AssemblyItemTemp;
  3351. CStringBuffer TempStreamName;
  3352. hr = (*g_pfnCreateAssemblyCacheItem)(
  3353. &AssemblyItemTemp,
  3354. NULL,
  3355. NULL,
  3356. NULL,
  3357. 0,
  3358. 0);
  3359. //
  3360. // Manifest
  3361. //
  3362. hr = AssemblyItemTemp->CreateStream(0, pvManifest, STREAM_FORMAT_WIN32_MANIFEST, 0, &pStream, NULL);
  3363. TempStreamName.Win32Assign(sbManifestName);
  3364. hr = Helper_WriteStream(&TempStreamName, pStream);
  3365. pStream.Release();
  3366. //
  3367. // Dll
  3368. //
  3369. sbManifestName.Win32ChangePathExtension(L".dll", 4, eAddIfNoExtension);
  3370. hr = AssemblyItemTemp->CreateStream(0, static_cast<PCWSTR>(TempStreamName), STREAM_FORMAT_WIN32_MODULE, 0, &pStream, NULL);
  3371. hr = Helper_WriteStream(&TempStreamName, pStream);
  3372. pStream.Release();
  3373. hr = AssemblyItemTemp->Commit(0, NULL);
  3374. AssemblyCacheItems[i] = AssemblyItemTemp;
  3375. }
  3376. /*
  3377. hr = g_pfnCreateAssemblyCache(&AssemblyCache, 0);
  3378. hr = AssemblyCache->MarkAssembliesVisible((IUnknown**)AssemblyCacheItems, 2, 0);
  3379. */
  3380. }
  3381. void
  3382. TestSfcScanKickoff()
  3383. {
  3384. BOOL fSuccess = FALSE;
  3385. LoadSxs();
  3386. fSuccess = (*g_pfnSxspDebug)(SXS_DEBUG_SFC_SCANNER, 0, NULL, NULL);
  3387. }
  3388. void
  3389. GenerateStrongNameAndPublicKey(PCWSTR wsCertificate)
  3390. {
  3391. BOOL bSuccess = FALSE;
  3392. CStringBuffer sbStrings[3];
  3393. PCCERT_CONTEXT pContext = NULL;
  3394. HCERTSTORE hCertStore = NULL;
  3395. hCertStore = CertOpenStore(
  3396. CERT_STORE_PROV_FILENAME,
  3397. X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
  3398. NULL,
  3399. CERT_STORE_OPEN_EXISTING_FLAG,
  3400. (void*)wsCertificate);
  3401. LoadSxs();
  3402. while (pContext = CertEnumCertificatesInStore(hCertStore, pContext))
  3403. {
  3404. bSuccess = (*g_pfnSxspDebug)(SXS_DEBUG_GET_STRONGNAME, 0, (PCWSTR)pContext, (PVOID)sbStrings);
  3405. wprintf(L"Signer display name: %ls\n\tPublic Key: %ls\n\tPublic Key Token: %ls\n",
  3406. static_cast<PCWSTR>(sbStrings[0]),
  3407. static_cast<PCWSTR>(sbStrings[1]),
  3408. static_cast<PCWSTR>(sbStrings[2]));
  3409. }
  3410. bSuccess = TRUE;
  3411. if (pContext) CertFreeCertificateContext(pContext);
  3412. if (hCertStore) CertCloseStore(hCertStore, CERT_CLOSE_STORE_FORCE_FLAG);
  3413. }
  3414. BOOL CALLBACK
  3415. DumpResourceWorker(
  3416. HMODULE hModule,
  3417. PCWSTR lpszType,
  3418. PWSTR lpszName,
  3419. LONG_PTR lParam
  3420. )
  3421. {
  3422. HGLOBAL hGlobal;
  3423. HRSRC hResource;
  3424. PVOID pvData;
  3425. SIZE_T cbResource;
  3426. hResource = ::FindResourceW(hModule, lpszName, lpszType);
  3427. hGlobal = ::LoadResource(hModule, hResource);
  3428. pvData = ::LockResource(hGlobal);
  3429. if (lpszName < (PCWSTR)0xFFFF)
  3430. {
  3431. wprintf(L"----\nResource id: %p\n", lpszName);
  3432. }
  3433. else
  3434. {
  3435. wprintf(L"----\nResource name: %ls\n", lpszName);
  3436. }
  3437. cbResource = ::SizeofResource(hModule, hResource);
  3438. for (SIZE_T i = 0; i < cbResource; i++)
  3439. {
  3440. wprintf(L"%c", ((char*)pvData)[i]);
  3441. }
  3442. wprintf(L"\n");
  3443. return TRUE;
  3444. }
  3445. BOOL
  3446. TestDumpContainedManifests(PCWSTR wsFilename)
  3447. {
  3448. HMODULE hThing;
  3449. hThing = ::LoadLibraryExW(wsFilename, NULL, LOAD_LIBRARY_AS_DATAFILE);
  3450. if ((hThing == NULL) || (hThing == INVALID_HANDLE_VALUE))
  3451. {
  3452. wprintf(L"Bad mojo: can't open %ls for enumeration.\n", wsFilename);
  3453. return FALSE;
  3454. }
  3455. if (!::EnumResourceNamesW(hThing, MAKEINTRESOURCEW(RT_MANIFEST), DumpResourceWorker, NULL))
  3456. {
  3457. if (GetLastError() == ERROR_RESOURCE_TYPE_NOT_FOUND)
  3458. {
  3459. wprintf(L"No manifests found in %ls\n", wsFilename);
  3460. }
  3461. else
  3462. {
  3463. wprintf(L"Bad mojo: can't enumerate resources from %ls, error=0x%08x\n",
  3464. wsFilename,
  3465. ::GetLastError());
  3466. }
  3467. }
  3468. ::FreeLibrary(hThing);
  3469. return TRUE;
  3470. }
  3471. BOOL TestGenerateStringWithIdenticalHash(WCHAR iString[33])
  3472. {
  3473. #define START_VALUE 1
  3474. #define STR_LEN 32
  3475. #define HASH_SEED 65599
  3476. #define MAGIC_ARRAY {1, 1, -1, -1, -1, -1, 1, 1, -1, -1, 1, 1, 1, 1, -1, -1,-1, -1, 1, 1, 1, 1, -1, -1, 1, 1, -1, -1, -1, -1, 1, 1} ;
  3477. #define UPPER(ch) if (ch >=L'a' && ch <= L'z') ch = ch- L'a' + L'A';
  3478. WCHAR oString[STR_LEN + 1];
  3479. DWORD i, nLen, a[STR_LEN];
  3480. ULONG hash1, hash2;
  3481. WCHAR ch;
  3482. a[0] = a[1] = START_VALUE;
  3483. nLen = 2;
  3484. while(nLen < STR_LEN) {
  3485. for(i = nLen; i < nLen*2; i++)
  3486. a[i] = static_cast<ULONG>(-static_cast<LONG>(a[i-nLen]));
  3487. nLen *= 2;
  3488. }
  3489. oString[32] = iString[32] = L'\0';
  3490. // generate the new string
  3491. for (i = 0; i< 32; i++)
  3492. oString[i] = static_cast<WCHAR>(iString[i] + a[i]);
  3493. // verify that these two string have the same hash
  3494. hash1 = 0 ;
  3495. for (i = 0 ; i<STR_LEN; i++) {
  3496. ch = iString[i];
  3497. UPPER(ch);
  3498. hash1 = hash1*HASH_SEED + ch;
  3499. }
  3500. hash2 = 0 ;
  3501. for (i = 0 ; i<STR_LEN; i++){
  3502. ch = oString[i];
  3503. UPPER(ch);
  3504. hash2 = hash2*HASH_SEED + ch;
  3505. }
  3506. return (hash1 == hash2)? TRUE : FALSE;
  3507. #undef START_VALUE
  3508. #undef STR_LEN
  3509. #undef HASH_SEED
  3510. }
  3511. BOOL TestAssemblyIdentityHash()
  3512. {
  3513. BOOL fSuccess = FALSE;
  3514. LoadSxs();
  3515. fSuccess = (*g_pfnSxspDebug)(SXS_DEBUG_ASSEMBLY_IDENTITY_HASH, 0, 0, NULL);
  3516. if (! fSuccess){
  3517. fprintf(stderr, "%s failed!\n", __FUNCTION__);
  3518. return EXIT_FAILURE;
  3519. }
  3520. else
  3521. return EXIT_SUCCESS;
  3522. }
  3523. const static WCHAR Beta2Manifest[] =
  3524. L"<assembly xmlns=\"urn:schemas-microsoft-com:asm.v1\" manifestVersion=\"1.0\">"
  3525. L" <assemblyIdentity type=\"win32\" name=\"cards\" version=\"2.0.0.0\" processorArchitecture=\"X86\" language=\"en-us\" />"
  3526. L" <file name=\"cards.dll\"/>"
  3527. L"</assembly>;"
  3528. ;
  3529. // check whether the handle counter of csrss has changed dramatically after running this code.....
  3530. VOID TestCreateActctxLeakHandles(DWORD dwCallCounter)
  3531. {
  3532. int result = -1;
  3533. BOOL fSuccess = FALSE;
  3534. for (DWORD i =0 ; i < dwCallCounter ; i ++)
  3535. {
  3536. HANDLE ActivationContextHandle = ::CreateActivationContextFromStringW(InheritManifest);
  3537. if (ActivationContextHandle == INVALID_HANDLE_VALUE) {
  3538. result = i ;
  3539. break;
  3540. }
  3541. ULONG_PTR Cookie;
  3542. ActivateActCtx(ActivationContextHandle, &Cookie);
  3543. HINSTANCE hInstanceKernel32 = ::GetModuleHandleW(L"KERNEL32.DLL");
  3544. PQUERYACTCTXW_FUNC pQueryActCtxW = (PQUERYACTCTXW_FUNC) ::GetProcAddress(hInstanceKernel32, "QueryActCtxW");
  3545. SIZE_T CbWritten;
  3546. if (pQueryActCtxW != NULL)
  3547. {
  3548. for ( ULONG ulInfoClass = ActivationContextBasicInformation; ulInfoClass <= FileInformationInAssemblyOfAssemblyInActivationContext; ulInfoClass ++)
  3549. {
  3550. switch (ulInfoClass) {
  3551. case ActivationContextBasicInformation :
  3552. break;
  3553. case ActivationContextDetailedInformation :
  3554. {
  3555. struct
  3556. {
  3557. ACTIVATION_CONTEXT_DETAILED_INFORMATION acdi;
  3558. WCHAR Buffer[_MAX_PATH * 3]; // manifest, policy and appdir
  3559. } Data;
  3560. ULONG index = 0 ;
  3561. fSuccess = (*pQueryActCtxW)(0, ActivationContextHandle, &index, ulInfoClass, &Data, sizeof(Data), &CbWritten);
  3562. fprintf(stderr, "\ncall QueryActCtxW with ActivationContextDetailedInformation\n" );
  3563. if (fSuccess)
  3564. {
  3565. fprintf(stderr, "1st string: %ls\n", Data.acdi.lpAppDirPath);
  3566. fprintf(stderr, "2nd string: %ls\n", Data.acdi.lpRootManifestPath);
  3567. }
  3568. else
  3569. fprintf(stderr, "QueryActCtxW() failed; ::GetLastError() = %d\n", ::GetLastError());
  3570. }
  3571. break;
  3572. case AssemblyDetailedInformationInActivationContext:
  3573. {
  3574. struct
  3575. {
  3576. ACTIVATION_CONTEXT_ASSEMBLY_DETAILED_INFORMATION acdi;
  3577. WCHAR Buffer[_MAX_PATH * 4];
  3578. } Data;
  3579. ULONG AssemblyIndex = 1;
  3580. fSuccess = (*pQueryActCtxW)(0, ActivationContextHandle, &AssemblyIndex, ulInfoClass, &Data, sizeof(Data), &CbWritten);
  3581. fprintf(stderr, "\ncall QueryActCtxW with AssemblyDetailedInformationInActivationContext\n" );
  3582. if (fSuccess)
  3583. {
  3584. fprintf(stderr, "Encoded assembly Identity: %ls\n", Data.acdi.lpAssemblyEncodedAssemblyIdentity);
  3585. fprintf(stderr, "manifest path: %ls\n", Data.acdi.lpAssemblyManifestPath);
  3586. fprintf(stderr, "policy path: %ls\n", Data.acdi.lpAssemblyPolicyPath);
  3587. fprintf(stderr, "Assembly Directory: %ls\n", Data.acdi.lpAssemblyDirectoryName);
  3588. }
  3589. else
  3590. fprintf(stderr, "QueryActCtxW() failed; ::GetLastError() = %d\n", ::GetLastError());
  3591. }
  3592. break;
  3593. case FileInformationInAssemblyOfAssemblyInActivationContext:
  3594. {
  3595. struct
  3596. {
  3597. ASSEMBLY_DLL_REDIRECTION_DETAILED_INFORMATION acdi;
  3598. WCHAR Buffer[_MAX_PATH * 2];
  3599. } Data;
  3600. ACTIVATION_CONTEXT_QUERY_INDEX index;
  3601. index.ulAssemblyIndex = 1;
  3602. index.ulFileIndexInAssembly = 0;
  3603. fSuccess = (*pQueryActCtxW)(0, ActivationContextHandle, &index, ulInfoClass, &Data, sizeof(Data), &CbWritten);
  3604. fprintf(stderr, "\ncall QueryActCtxW with FileInformationInAssemblyOfAssemblyInActivationContext\n" );
  3605. if (fSuccess)
  3606. {
  3607. fprintf(stderr, "file name: %ls\n", Data.acdi.lpFileName);
  3608. fprintf(stderr, "file path: %ls\n", Data.acdi.lpFilePath);
  3609. }
  3610. else
  3611. fprintf(stderr, "QueryActCtxW() failed; ::GetLastError() = %d\n", ::GetLastError());
  3612. }
  3613. } // end of switch
  3614. }// end of for
  3615. }
  3616. DeactivateActCtx(0, Cookie);
  3617. // CloseHandle(ActivationContextHandle);
  3618. }
  3619. return;
  3620. }
  3621. BOOL TestSystemDefaultActivationContextGeneration()
  3622. {
  3623. BOOL fSuccess = FALSE;
  3624. LoadSxs();
  3625. fSuccess = (*g_pfnSxspDebug)(SXS_DEBUG_SYSTEM_DEFAULT_ACTCTX_GENERATION, 0, NULL, NULL);
  3626. if (! fSuccess){
  3627. fprintf(stderr, "%s failed!\n", __FUNCTION__);
  3628. return EXIT_FAILURE;
  3629. }
  3630. else
  3631. return EXIT_SUCCESS;
  3632. }
  3633. CHAR g_AsyncIOBuffer[16384];
  3634. struct AsyncIOBlock
  3635. {
  3636. OVERLAPPED ol_input;
  3637. OVERLAPPED ol_output;
  3638. HANDLE hInputFile;
  3639. HANDLE hOutputFile;
  3640. } g_AsyncIOBlock;
  3641. bool g_AsyncIODone = false;
  3642. DWORD g_AsyncIOError = ERROR_SUCCESS;
  3643. VOID CALLBACK AsyncReadCompleted(
  3644. DWORD dwErrorCode,
  3645. DWORD dwBytesTransferred,
  3646. LPOVERLAPPED ol
  3647. );
  3648. VOID CALLBACK AsyncWriteCompleted(
  3649. DWORD dwErrorCode,
  3650. DWORD dwBytesTransferred,
  3651. LPOVERLAPPED ol
  3652. );
  3653. VOID CALLBACK AsyncReadCompleted(
  3654. DWORD dwErrorCode,
  3655. DWORD dwBytesTransferred,
  3656. LPOVERLAPPED ol
  3657. )
  3658. {
  3659. if (dwErrorCode != ERROR_SUCCESS)
  3660. {
  3661. fprintf(stderr, "Error passed to AsyncReadCompleted(); error code = %ul; bytes transferred = %ul\n", dwErrorCode, dwBytesTransferred);
  3662. g_AsyncIOError = dwErrorCode;
  3663. g_AsyncIODone = true;
  3664. }
  3665. else
  3666. {
  3667. g_AsyncIOBlock.ol_input.Offset += dwBytesTransferred;
  3668. if (!::WriteFileEx(g_AsyncIOBlock.hOutputFile, g_AsyncIOBuffer, dwBytesTransferred, &g_AsyncIOBlock.ol_output, &AsyncWriteCompleted))
  3669. {
  3670. g_AsyncIOError = ::GetLastError();
  3671. fprintf(stderr, "WriteFileEx() failed; ::GetLastError() = %d\n", g_AsyncIOError);
  3672. g_AsyncIODone = true;
  3673. }
  3674. }
  3675. }
  3676. VOID CALLBACK AsyncWriteCompleted(
  3677. DWORD dwErrorCode,
  3678. DWORD dwBytesTransferred,
  3679. LPOVERLAPPED ol
  3680. )
  3681. {
  3682. if (dwErrorCode != ERROR_SUCCESS)
  3683. {
  3684. fprintf(stderr, "Error passed to AsyncWriteCompleted(); error code = %ul; dwBytesTransferred = %ul\n", dwErrorCode, dwBytesTransferred);
  3685. g_AsyncIOError = dwErrorCode;
  3686. g_AsyncIODone = true;
  3687. }
  3688. else
  3689. {
  3690. g_AsyncIOBlock.ol_output.Offset += dwBytesTransferred;
  3691. if (!::ReadFileEx(g_AsyncIOBlock.hInputFile, g_AsyncIOBuffer, sizeof(g_AsyncIOBuffer), &g_AsyncIOBlock.ol_input, &AsyncReadCompleted))
  3692. {
  3693. g_AsyncIOError = ::GetLastError();
  3694. if (g_AsyncIOError != ERROR_HANDLE_EOF)
  3695. fprintf(stderr, "ReadFileEx() failed; ::GetLastError() = %d\n", g_AsyncIOError);
  3696. else
  3697. g_AsyncIOError = ERROR_SUCCESS;
  3698. g_AsyncIODone = true;
  3699. }
  3700. }
  3701. }
  3702. BOOL
  3703. TestAsyncIO(int argc, wchar_t **argv, int *piNext)
  3704. {
  3705. HANDLE hFileIn;
  3706. HANDLE hFileOut;
  3707. HANDLE hActCtx = NULL;
  3708. ULONG_PTR cookie = 0;
  3709. PCWSTR pszManifest;
  3710. PCWSTR pszInputFile;
  3711. PCWSTR pszOutputFile;
  3712. ACTCTXW acw;
  3713. pszManifest = argv[(*piNext)++];
  3714. pszInputFile = argv[(*piNext)++];
  3715. pszOutputFile = argv[(*piNext)++];
  3716. if (wcscmp(pszManifest, L"-") != 0)
  3717. {
  3718. acw.cbSize = sizeof(acw);
  3719. acw.dwFlags = 0;
  3720. acw.lpSource = pszManifest;
  3721. hActCtx = ::CreateActCtxW(&acw);
  3722. if (hActCtx == INVALID_HANDLE_VALUE)
  3723. {
  3724. fprintf(stderr, "CreateActCtxW() on %ls failed; ::GetLastError() = %d\n", pszManifest, ::GetLastError());
  3725. return EXIT_FAILURE;
  3726. }
  3727. }
  3728. hFileIn = ::CreateFileW(pszInputFile, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED | FILE_FLAG_NO_BUFFERING | FILE_FLAG_SEQUENTIAL_SCAN, NULL);
  3729. if (hFileIn == INVALID_HANDLE_VALUE)
  3730. {
  3731. fprintf(stderr, "CreateFileW() on %ls failed; ::GetLastError() = %d\n", pszInputFile, ::GetLastError());
  3732. return EXIT_FAILURE;
  3733. }
  3734. hFileOut = ::CreateFileW(pszOutputFile, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_FLAG_OVERLAPPED | FILE_FLAG_NO_BUFFERING, NULL);
  3735. if (hFileOut == INVALID_HANDLE_VALUE)
  3736. {
  3737. fprintf(stderr, "CreateFileW() on %ls failed; ::GetLastError() = %d\n", pszOutputFile, ::GetLastError());
  3738. return EXIT_FAILURE;
  3739. }
  3740. ActivateActCtx(hActCtx, &cookie);
  3741. g_AsyncIOBlock.ol_input.Offset = 0;
  3742. g_AsyncIOBlock.ol_input.OffsetHigh = 0;
  3743. g_AsyncIOBlock.ol_output.Offset = 0;
  3744. g_AsyncIOBlock.ol_output.OffsetHigh = 0;
  3745. g_AsyncIOBlock.hInputFile = hFileIn;
  3746. g_AsyncIOBlock.hOutputFile = hFileOut;
  3747. if (!::ReadFileEx(hFileIn, &g_AsyncIOBuffer, sizeof(g_AsyncIOBuffer), &g_AsyncIOBlock.ol_input, &AsyncReadCompleted))
  3748. {
  3749. fprintf(stderr, "First ReadFileEx() failed; ::GetLastError() = %d\n", ::GetLastError());
  3750. return EXIT_FAILURE;
  3751. }
  3752. while (!g_AsyncIODone)
  3753. {
  3754. ::SleepEx(1000, TRUE);
  3755. }
  3756. if (g_AsyncIOError != ERROR_SUCCESS)
  3757. {
  3758. fprintf(stderr, "Async IO test failed; win32 error code = %d\n", g_AsyncIOError);
  3759. return EXIT_FAILURE;
  3760. }
  3761. CloseHandle(hFileIn);
  3762. CloseHandle(hFileOut);
  3763. return EXIT_SUCCESS;
  3764. }
  3765. DWORD
  3766. WINAPI
  3767. TestThreadInheritLeakThreadProc(
  3768. LPVOID lpParameter
  3769. )
  3770. {
  3771. // Don't need to do anything...
  3772. return 1;
  3773. }
  3774. int
  3775. TestThreadInheritLeak()
  3776. {
  3777. HANDLE ActivationContextHandle = ::CreateActivationContextFromStringW(InheritManifest);
  3778. DWORD dwThreadId;
  3779. ULONG_PTR ulpCookie;
  3780. HANDLE hThread = NULL;
  3781. ::ActivateActCtx(ActivationContextHandle, &ulpCookie);
  3782. hThread = ::CreateThread(NULL, 0, &TestThreadInheritLeakThreadProc, NULL, 0, &dwThreadId);
  3783. if (hThread == NULL)
  3784. {
  3785. fprintf(stderr, "CreateThread() failed with ::GetLastError = %d\n", ::GetLastError());
  3786. return EXIT_FAILURE;
  3787. }
  3788. WaitForSingleObject(hThread, INFINITE);
  3789. fprintf(stderr, "Created thread %lu\n", dwThreadId);
  3790. ::DeactivateActCtx(0, ulpCookie);
  3791. ::ReleaseActCtx(ActivationContextHandle);
  3792. return EXIT_SUCCESS;
  3793. }
  3794. BOOL
  3795. TestNewCatalogSignerThingy(
  3796. PCWSTR CatalogName
  3797. )
  3798. {
  3799. BOOL fSuccess = FALSE;
  3800. LoadSxs();
  3801. fSuccess = (*g_pfnSxspDebug)(SXS_DEBUG_CATALOG_SIGNER_CHECK, 0, CatalogName, NULL);
  3802. return fSuccess;
  3803. }
  3804. HMODULE MyHandle;
  3805. WCHAR MyModuleFullPath[MAX_PATH];
  3806. WCHAR MyModuleFullPathWithoutExtension[MAX_PATH];
  3807. /*
  3808. see \\scratch\scratch\JayK\exedll for a slightly different approach
  3809. */
  3810. HANDLE GetExeHandle()
  3811. {
  3812. return GetModuleHandleW(NULL);
  3813. }
  3814. extern "C" { extern IMAGE_DOS_HEADER __ImageBase; }
  3815. HMODULE GetMyHandle()
  3816. {
  3817. //Trace("GetMyHandle():%p\n", &__ImageBase);
  3818. return (HMODULE)&__ImageBase;
  3819. }
  3820. BOOL AmITheExe()
  3821. {
  3822. IamExe = (GetExeHandle() == GetMyHandle());
  3823. IamDll = !IamExe;
  3824. return IamExe;
  3825. }
  3826. PCWSTR GetMyModuleFullPath()
  3827. {
  3828. return
  3829. ((MyModuleFullPath[0]
  3830. || ::GetModuleFileNameW(GetMyHandle(), MyModuleFullPath, RTL_NUMBER_OF(MyModuleFullPath))),
  3831. MyModuleFullPath);
  3832. }
  3833. PCWSTR GetMyModuleFullPathWithoutExtension()
  3834. {
  3835. //
  3836. // not thread safe
  3837. //
  3838. wcscpy(MyModuleFullPathWithoutExtension, GetMyModuleFullPath());
  3839. *wcsrchr(MyModuleFullPathWithoutExtension, '.') = 0;
  3840. return MyModuleFullPathWithoutExtension;
  3841. }
  3842. void TestExeDll()
  3843. {
  3844. #if defined(_X86_)
  3845. WCHAR x[MAX_PATH];
  3846. CStringBuffer y;
  3847. Kernel32.GetModuleFileNameW(NULL, x, RTL_NUMBER_OF(x));
  3848. if (!y.Win32Assign(x, StringLength(x)))
  3849. ThrowLastError();
  3850. if (!y.Win32ChangePathExtension(L"dll", 3, eAddIfNoExtension))
  3851. ThrowLastError();
  3852. if (!CopyFileW(x, y, FALSE))
  3853. ThrowLastError();
  3854. SetDllBitInPeImage(y);
  3855. FreeLibrary(LoadLibraryW(y));
  3856. #endif
  3857. }
  3858. void PrintDll()
  3859. {
  3860. //Trace("dll %ls\n", GetMyModuleFullPath());
  3861. }
  3862. void PrintExe()
  3863. {
  3864. //Trace("exe %ls\n", GetMyModuleFullPath());
  3865. }
  3866. extern "C" void __cdecl wmainCRTStartup();
  3867. extern "C" BOOL __stdcall _DllMainCRTStartup(HINSTANCE, DWORD, PVOID);
  3868. extern "C" BOOL __stdcall DllMain(HINSTANCE DllHandle, DWORD Reason, PVOID SemiReserved)
  3869. {
  3870. //Trace("Enter DllMain\n");
  3871. switch (Reason)
  3872. {
  3873. default:
  3874. break;
  3875. case DLL_PROCESS_ATTACH:
  3876. if (
  3877. wcsstr(GetCommandLineW(), L" -tQueryActCtx")
  3878. || wcsstr(GetCommandLineW(), L" -tqueryactctx")
  3879. || wcsstr(GetCommandLineW(), L" /tQueryActCtx")
  3880. || wcsstr(GetCommandLineW(), L" /tqueryactctx")
  3881. )
  3882. {
  3883. TestQueryActCtx();
  3884. }
  3885. }
  3886. //Trace("Exit DllMain\n");
  3887. return TRUE;
  3888. }
  3889. #if defined(_X86_)
  3890. extern "C" void __declspec(naked) Entry()
  3891. // This works for .dlls or .exes.
  3892. // void ExeMain(void)
  3893. // BOOL __stdcall DllMain(HINSTANCE dll, DWORD reason, void* reserved)
  3894. {
  3895. static const char* DllReason[] =
  3896. {
  3897. "DllProcessDetach %ls\n",
  3898. "DllProcessAttach %ls\n",
  3899. "DllThreadAttach %ls\n",
  3900. "DllThreadDetach %ls\n"
  3901. };
  3902. __asm {
  3903. //int 3
  3904. call AmITheExe
  3905. test eax,eax
  3906. jne Lexe
  3907. //Ldll:
  3908. call GetMyModuleFullPath
  3909. push eax
  3910. mov eax, [esp+12]
  3911. mov eax, DllReason[eax*4]
  3912. push eax
  3913. call Trace
  3914. add esp,8
  3915. jmp _DllMainCRTStartup
  3916. Lexe:
  3917. call PrintExe
  3918. jmp wmainCRTStartup
  3919. }
  3920. }
  3921. #else
  3922. extern "C" void Entry()
  3923. {
  3924. wmainCRTStartup();
  3925. }
  3926. #endif
  3927. BOOL TestSxsSfcUI()
  3928. {
  3929. BOOL fSuccess = FALSE;
  3930. LoadSxs();
  3931. fSuccess = (*g_pfnSxspDebug)(SXS_DEBUG_SFC_UI_TEST, 0, 0, NULL);
  3932. if (! fSuccess){
  3933. fprintf(stderr, "%s failed!\n", __FUNCTION__);
  3934. return EXIT_FAILURE;
  3935. }
  3936. else
  3937. return EXIT_SUCCESS;
  3938. return fSuccess;
  3939. }
  3940. void TestGetModuleHandleEx()
  3941. {
  3942. #if 0
  3943. HMODULE p;
  3944. BOOL f;
  3945. HMODULE q;
  3946. unsigned u;
  3947. #define GetModuleHandleExA pfnGetModuleHandleExA
  3948. #define GetModuleHandleExW pfnGetModuleHandleExW
  3949. HMODULE kernel32 = GetModuleHandleW(L"Kernel32");
  3950. PGET_MODULE_HANDLE_EXA GetModuleHandleExA = reinterpret_cast<PGET_MODULE_HANDLE_EXA>(GetProcAddress(kernel32, "GetModuleHandleExA"));
  3951. PGET_MODULE_HANDLE_EXW GetModuleHandleExW = reinterpret_cast<PGET_MODULE_HANDLE_EXW>(GetProcAddress(kernel32, "GetModuleHandleExW"));
  3952. if (GetModuleHandleExA == NULL || GetModuleHandleExW == NULL)
  3953. {
  3954. return;
  3955. }
  3956. union
  3957. {
  3958. CHAR BufferA[MAX_PATH];
  3959. WCHAR BufferW[MAX_PATH];
  3960. };
  3961. BufferA[0] = 0;
  3962. GetWindowsDirectoryA(BufferA, MAX_PATH);
  3963. std::string windowsA = BufferA;
  3964. std::string systemA = windowsA + "System32";
  3965. BufferW[0] = 0;
  3966. GetWindowsDirectoryW(BufferW, MAX_PATH);
  3967. std::wstring windowsW = BufferW;
  3968. std::wstring systemW = windowsW + L"System32";
  3969. #define PIN GET_MODULE_HANDLE_EX_FLAG_PIN
  3970. #define NOCHANGE GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT
  3971. #define ADDRESS GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS
  3972. #define X(x) SetLastError(NO_ERROR); p = x; printf("%s:%p,%d\n", #x, p, ::GetLastError());
  3973. #define Y(x) SetLastError(NO_ERROR); f = x; printf("%s:%s,%p,%d\n", #x, "false\0true"+f*6, p, ::GetLastError());
  3974. printf("first some basic GetModuleHandle testing\n\n");
  3975. X(GetModuleHandleA(NULL));
  3976. X(GetModuleHandleW(NULL));
  3977. X(GetModuleHandleA("ntdll.dll"));
  3978. X(GetModuleHandleW(L"ntdll.dll"));
  3979. X(GetModuleHandleA("ntdll"));
  3980. X(GetModuleHandleW(L"ntdll"));
  3981. X(GetModuleHandleA("c:\\ntdll"));
  3982. X(GetModuleHandleW(L"c:\\ntdll"));
  3983. X(GetModuleHandleA((systemA + "\\ntdll").c_str()));
  3984. X(GetModuleHandleW((systemW + L"\\ntdll").c_str()));
  3985. X(GetModuleHandleA((systemA + "\\ntdll.dll").c_str()));
  3986. X(GetModuleHandleW((systemW + L"\\ntdll.dll").c_str()));
  3987. X(GetModuleHandleA("sxs"));
  3988. X(GetModuleHandleW(L"sxs.dll"));
  3989. printf("\n\nnow show that FreeLibrary \"works\", GetModuleHandle honors it\n\n");
  3990. X(LoadLibraryA("Sxs.dll"));
  3991. X(GetModuleHandleA("sxs"));
  3992. X(GetModuleHandleW(L"sxs.dll"));
  3993. Y(FreeLibrary(p = GetModuleHandleA("Sxs.dll")));
  3994. X(GetModuleHandleA("sxs"));
  3995. X(GetModuleHandleW(L"sxs.dll"));
  3996. X(LoadLibraryW(L"Sxs.dll"));
  3997. Y(GetModuleHandleExA(0, NULL, &p));
  3998. Y(GetModuleHandleExW(0, NULL, &p));
  3999. printf("\n\nsome invalid parameters (%d)\n\n", ERROR_INVALID_PARAMETER);
  4000. Y(GetModuleHandleExA(PIN | NOCHANGE, "sxs", &p));
  4001. Y(GetModuleHandleExW(PIN | NOCHANGE, L"sxs", &p));
  4002. Y(GetModuleHandleExA(PIN | NOCHANGE, "ntdll", &p));
  4003. Y(GetModuleHandleExW(PIN | NOCHANGE, L"ntdll", &p));
  4004. printf("\n\nshow NOCHANGE's equiv to regular\n\n");
  4005. Y(GetModuleHandleExA(NOCHANGE, "sxs", &p));
  4006. Y(GetModuleHandleExW(NOCHANGE, L"sxs", &p));
  4007. Y(FreeLibrary(p = GetModuleHandleA("Sxs.dll")));
  4008. Y(GetModuleHandleExA(NOCHANGE, "sxs", &p));
  4009. Y(GetModuleHandleExW(NOCHANGE, L"sxs", &p));
  4010. printf("\n\nshow PIN works\n\n");
  4011. X(LoadLibraryW(L"Sxs.dll"));
  4012. Y(GetModuleHandleExA(PIN, "sxs", &p));
  4013. Y(FreeLibrary(p = GetModuleHandleA("Sxs.dll")));
  4014. Y(GetModuleHandleExW(0, L"sxs", &(q = p)));
  4015. Y(GetModuleHandleExW(0, L"c:\\sxs", &p));
  4016. printf("\n\nshow the VirtualQuery form\n\n");
  4017. Y(GetModuleHandleExA(ADDRESS, "sxs", &p)); // string, actually in .exe
  4018. Y(GetModuleHandleExW(ADDRESS, L"c:\\sxs", &p));
  4019. Y(GetModuleHandleExA(ADDRESS, reinterpret_cast<LPCSTR>(q), &p));
  4020. Y(GetModuleHandleExW(ADDRESS, reinterpret_cast<LPCWSTR>(q), &p));
  4021. printf("\n\nsome more invalid parameters (%d)\n\n", ERROR_INVALID_PARAMETER);
  4022. Y(GetModuleHandleExA(0, NULL, NULL));
  4023. Y(GetModuleHandleExW(0, NULL, NULL));
  4024. printf("\n\nshow that static loads can't be unloaded\n\n");
  4025. for (u = 0 ; u < 4 ; ++u)
  4026. {
  4027. printf("%#x\n", u);
  4028. Y(FreeLibrary(p = GetModuleHandleA("kernel32")));
  4029. Y(FreeLibrary(p = GetModuleHandleW(L"sxstest.exe")));
  4030. Y(FreeLibrary(p = GetModuleHandleA("msvcrt.dll")));
  4031. }
  4032. printf("\n\ntry all flag combinations, including invalids ones\n\n");
  4033. for (u = 0 ; u <= (PIN | ADDRESS | NOCHANGE) ; ++u)
  4034. {
  4035. printf("%#x\n", u);
  4036. p = NULL;
  4037. Y( GetModuleHandleExA(u, NULL, NULL)); p = NULL;
  4038. Y( GetModuleHandleExW(u, NULL, NULL)); p = NULL;
  4039. Y( GetModuleHandleExA(u, NULL, &p)); p = NULL;
  4040. Y( GetModuleHandleExW(u, NULL, &p)); p = NULL;
  4041. if (u & ADDRESS)
  4042. {
  4043. Y( GetModuleHandleExA(u, "", NULL)); p = NULL;
  4044. Y( GetModuleHandleExW(u, reinterpret_cast<LPCWSTR>(GetModuleHandleExA), NULL)); p = NULL;
  4045. Y( GetModuleHandleExW(u, reinterpret_cast<LPCWSTR>(atexit), NULL)); p = NULL;
  4046. Y( GetModuleHandleExA(u, "", &p)); p = NULL;
  4047. Y( GetModuleHandleExW(u, reinterpret_cast<LPCWSTR>(GetModuleHandleExA), &p)); p = NULL;
  4048. Y( GetModuleHandleExW(u, reinterpret_cast<LPCWSTR>(atexit), &p)); p = NULL;
  4049. }
  4050. else
  4051. {
  4052. Y( GetModuleHandleExA(u, "foo32", NULL)); p = NULL;
  4053. Y( GetModuleHandleExW(u, L"kernel32", NULL)); p = NULL;
  4054. Y( GetModuleHandleExA(u, "foo32", &p)); p = NULL;
  4055. Y( GetModuleHandleExW(u, L"kernel32", &p)); p = NULL;
  4056. }
  4057. }
  4058. printf("\n\ntry all bits of flags, should be mostly invalid (%d)\n\n", ERROR_INVALID_PARAMETER);
  4059. for (u = 0 ; u < RTL_BITS_OF(u) ; ++u)
  4060. {
  4061. printf("%#x\n", u);
  4062. Y(GetModuleHandleExW(1<<u, L"kernel32", &p));
  4063. }
  4064. printf("\n\nPIN | ADDRESS wasn't covered\n\n", ERROR_INVALID_PARAMETER);
  4065. X(GetModuleHandleW(L"shell32"));
  4066. X(q = LoadLibraryA("shell32"));
  4067. Y(FreeLibrary(GetModuleHandleA("shell32")));
  4068. Y(GetModuleHandleExW(PIN | ADDRESS, reinterpret_cast<LPCWSTR>(q), &p));
  4069. X(q = LoadLibraryW(L"shell32"));
  4070. Y(GetModuleHandleExW(PIN | ADDRESS, reinterpret_cast<LPCWSTR>(q) + 100, &p));
  4071. Y(FreeLibrary(q)); Y(FreeLibrary(q)); Y(FreeLibrary(q));
  4072. X(GetModuleHandleW(L"shell32.dll"));
  4073. Y(GetModuleHandleExW(ADDRESS, reinterpret_cast<LPCWSTR>(q) + 1000, &p));
  4074. #undef X
  4075. #undef Y
  4076. #undef PIN
  4077. #undef NOCHANGE
  4078. #undef ADDRESS
  4079. #endif
  4080. }
  4081. void
  4082. TestGetFullPathName(
  4083. PCWSTR s
  4084. )
  4085. {
  4086. WCHAR FullPath[MAX_PATH * 2];
  4087. PWSTR FilePart = L"";
  4088. DWORD dw;
  4089. DWORD dwError;
  4090. SetLastError(NO_ERROR);
  4091. dw = GetFullPathNameW(s, RTL_NUMBER_OF(FullPath), FullPath, &FilePart);
  4092. dwError = ::GetLastError();
  4093. printf(
  4094. "GetFullPathNameW(%ls):%lu,lastError=%lu,filePart=%ls\n",
  4095. FullPath,
  4096. dw,
  4097. dwError,
  4098. FilePart
  4099. );
  4100. }
  4101. void
  4102. TestCreateFile(
  4103. PCWSTR s
  4104. )
  4105. {
  4106. HANDLE handle;
  4107. DWORD dwError;
  4108. SetLastError(NO_ERROR);
  4109. handle = CreateFileW(
  4110. s,
  4111. 0,
  4112. FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
  4113. NULL,
  4114. OPEN_ALWAYS,
  4115. FILE_ATTRIBUTE_NORMAL,
  4116. NULL
  4117. );
  4118. dwError = ::GetLastError();
  4119. if (handle != INVALID_HANDLE_VALUE)
  4120. CloseHandle(handle);
  4121. printf(
  4122. "CreateFileW(%ls):%p,lastError=%lu\n",
  4123. s,
  4124. handle,
  4125. dwError
  4126. );
  4127. }
  4128. /*
  4129. from base\ntsetup\dll\sxs.c
  4130. */
  4131. VOID
  4132. SxspGetPathBaseName(
  4133. LPCWSTR Path,
  4134. LPWSTR Base
  4135. )
  4136. {
  4137. LPCWSTR Dot = wcsrchr(Path, '.');
  4138. LPCWSTR Slash = wcsrchr(Path, '\\');
  4139. //
  4140. // beware \foo.txt\bar
  4141. // beware \bar
  4142. // beware bar
  4143. // beware .bar
  4144. // beware \.bar
  4145. //
  4146. *Base = 0;
  4147. if (Slash == NULL)
  4148. Slash = Path;
  4149. else
  4150. Slash += 1;
  4151. if (Dot == NULL || Dot < Slash)
  4152. Dot = Path + StringLength(Path);
  4153. CopyMemory(Base, Slash, (Dot - Slash) * sizeof(*Base));
  4154. Base[Dot - Slash] = 0;
  4155. }
  4156. NTSTATUS
  4157. NTAPI
  4158. RtlCopyMappedMemory(
  4159. PVOID ToAddress,
  4160. PCVOID FromAddress,
  4161. SIZE_T Size
  4162. )
  4163. {
  4164. CopyMemory(ToAddress, FromAddress, Size);
  4165. return STATUS_SUCCESS;
  4166. }
  4167. VOID
  4168. TestGetPathBaseName(
  4169. LPCWSTR Path
  4170. )
  4171. {
  4172. WCHAR Base[MAX_PATH];
  4173. SxspGetPathBaseName(Path, Base);
  4174. printf("\"%ls\" -> \"%ls\"\n", Path, Base);
  4175. }
  4176. void TestVersion()
  4177. {
  4178. printf(
  4179. "Windows NT %lu.%lu.%lu\n",
  4180. FusionpGetWindowsNtMajorVersion(),
  4181. FusionpGetWindowsNtMinorVersion(),
  4182. FusionpGetWindowsNtBuildVersion()
  4183. );
  4184. }
  4185. void TestGetProcessImageFileName()
  4186. {
  4187. UNICODE_STRING s;
  4188. FusionpGetProcessImageFileName(&s);
  4189. printf("%wZ\n", &s);
  4190. }
  4191. BOOL TestErrorInfra1() { FN_PROLOG_WIN32; IFW32FALSE_ORIGINATE_AND_EXIT(LoadLibraryA("1")); FN_EPILOG; }
  4192. BOOL TestErrorInfra2() { FN_PROLOG_WIN32; IFW32NULL_EXIT(LoadLibraryA(" 2 ")); FN_EPILOG; }
  4193. BOOL TestErrorInfra3() { FN_PROLOG_WIN32; IFFAILED_CONVERTHR_HRTOWIN32_EXIT_TRACE(E_FAIL | 3); FN_EPILOG; }
  4194. BOOL TestErrorInfra4() { FN_PROLOG_WIN32; IFCOMFAILED_EXIT(E_FAIL | 4); FN_EPILOG; }
  4195. BOOL TestErrorInfra5() { FN_PROLOG_WIN32; IFCOMFAILED_ORIGINATE_AND_EXIT(E_FAIL | 5); FN_EPILOG; }
  4196. BOOL TestErrorInfra6() { FN_PROLOG_WIN32; IFREGFAILED_EXIT(6); FN_EPILOG; }
  4197. BOOL TestErrorInfra7() { FN_PROLOG_WIN32; IFREGFAILED_ORIGINATE_AND_EXIT(7); FN_EPILOG; }
  4198. HRESULT TestErrorInfra8() { FN_PROLOG_HR; IFW32FALSE_ORIGINATE_AND_EXIT(LoadLibraryA("8")); FN_EPILOG; }
  4199. HRESULT TestErrorInfra9() { FN_PROLOG_HR; IFW32NULL_EXIT(LoadLibraryA("!@# 9 \\")); FN_EPILOG; }
  4200. HRESULT TestErrorInfra10() { FN_PROLOG_HR; IFFAILED_CONVERTHR_HRTOWIN32_EXIT_TRACE(E_FAIL | 10); FN_EPILOG; }
  4201. HRESULT TestErrorInfra11() { FN_PROLOG_HR; IFCOMFAILED_EXIT(E_FAIL | 11); FN_EPILOG; }
  4202. HRESULT TestErrorInfra12() { FN_PROLOG_HR; IFCOMFAILED_ORIGINATE_AND_EXIT(E_FAIL | 12); FN_EPILOG; }
  4203. HRESULT TestErrorInfra13() { FN_PROLOG_HR; IFREGFAILED_EXIT(13); FN_EPILOG; }
  4204. HRESULT TestErrorInfra14() { FN_PROLOG_HR; IFREGFAILED_ORIGINATE_AND_EXIT(14); FN_EPILOG; }
  4205. void TestErrorInfra()
  4206. {
  4207. #define X(x) DbgPrint("%s\n", #x); x()
  4208. X(TestErrorInfra1);
  4209. X(TestErrorInfra2);
  4210. X(TestErrorInfra3);
  4211. X(TestErrorInfra4);
  4212. X(TestErrorInfra5);
  4213. X(TestErrorInfra7);
  4214. X(TestErrorInfra8);
  4215. X(TestErrorInfra9);
  4216. X(TestErrorInfra10);
  4217. X(TestErrorInfra11);
  4218. X(TestErrorInfra12);
  4219. X(TestErrorInfra13);
  4220. X(TestErrorInfra14);
  4221. #undef X
  4222. }
  4223. void TestQueryActCtx3(
  4224. ULONG Flags,
  4225. HANDLE ActCtxHandle
  4226. )
  4227. {
  4228. SIZE_T BytesWrittenOrRequired = 0;
  4229. BYTE QueryBuffer[4][4096];
  4230. ACTIVATION_CONTEXT_QUERY_INDEX QueryIndex = { 0 };
  4231. PACTIVATION_CONTEXT_BASIC_INFORMATION BasicInfo = reinterpret_cast<PACTIVATION_CONTEXT_BASIC_INFORMATION>(&QueryBuffer[0]);
  4232. PASSEMBLY_DLL_REDIRECTION_DETAILED_INFORMATION DllRedir = reinterpret_cast<PASSEMBLY_DLL_REDIRECTION_DETAILED_INFORMATION>(&QueryBuffer[1]);
  4233. PACTIVATION_CONTEXT_DETAILED_INFORMATION ContextDetailed = reinterpret_cast<PACTIVATION_CONTEXT_DETAILED_INFORMATION>(&QueryBuffer[2]);
  4234. PACTIVATION_CONTEXT_ASSEMBLY_DETAILED_INFORMATION AssemblyDetailed = reinterpret_cast<PACTIVATION_CONTEXT_ASSEMBLY_DETAILED_INFORMATION>(&QueryBuffer[3]);
  4235. CStringBuffer decimalContext;
  4236. RtlZeroMemory(&QueryBuffer, sizeof(QueryBuffer));
  4237. if (IS_SPECIAL_ACTCTX(ActCtxHandle))
  4238. decimalContext.Win32Format(L" (%Id)", reinterpret_cast<LONG_PTR>(ActCtxHandle));
  4239. #define QueryFailed(x,n) Trace("%s:%ld:QueryActCtx(%s) failed %lu\n", __FUNCTION__, ULONG(n), x, GetLastError())
  4240. if (!QueryActCtxW(
  4241. Flags,
  4242. ActCtxHandle,
  4243. NULL,
  4244. ActivationContextBasicInformation,
  4245. &QueryBuffer,
  4246. sizeof(QueryBuffer),
  4247. &BytesWrittenOrRequired
  4248. ))
  4249. QueryFailed("ActivationContextBasicInformation", __LINE__ - 1);
  4250. else
  4251. {
  4252. if (IS_SPECIAL_ACTCTX(BasicInfo->hActCtx))
  4253. decimalContext.Win32Format(L" (%Id)", reinterpret_cast<LONG_PTR>(BasicInfo->hActCtx));
  4254. Trace(
  4255. "BytesWrittenOrRequired : 0x%lx\n"
  4256. "BasicInfo->hActCtx : %p%ls\n"
  4257. "BasicInfo->Flags : 0x%lx\n",
  4258. BytesWrittenOrRequired,
  4259. BasicInfo->hActCtx,
  4260. static_cast<PCWSTR>(decimalContext),
  4261. BasicInfo->Flags
  4262. );
  4263. }
  4264. Flags = (Flags & ~QUERY_ACTCTX_FLAG_NO_ADDREF);
  4265. if (!QueryActCtxW(Flags, ActCtxHandle, NULL, ActivationContextDetailedInformation, ContextDetailed, 4096, &BytesWrittenOrRequired))
  4266. QueryFailed("ActivationContextDetailedInformation", __LINE__ - 1);
  4267. else
  4268. {
  4269. Trace(
  4270. "BytesWrittenOrRequired : 0x%lx\n"
  4271. "ContextDetailed->dwFlags : 0x%lx\n"
  4272. "ContextDetailed->ulFormatVersion : 0x%lx\n"
  4273. "ContextDetailed->ulAssemblyCount : 0x%lx\n"
  4274. "ContextDetailed->ulRootManifestPathType : 0x%lx\n"
  4275. "ContextDetailed->ulRootManifestPathChars : 0x%lx\n"
  4276. "ContextDetailed->ulRootConfigurationPathType : 0x%lx\n"
  4277. "ContextDetailed->ulRootConfigurationPathChars : 0x%lx\n"
  4278. "ContextDetailed->ulAppDirPathType : 0x%lx\n"
  4279. "ContextDetailed->ulAppDirPathChars : 0x%lx\n"
  4280. "ContextDetailed->lpRootManifestPath : %ls\n"
  4281. "ContextDetailed->lpRootConfigurationPath : %ls\n"
  4282. "ContextDetailed->lpAppDirPath : %ls\n"
  4283. ,
  4284. BytesWrittenOrRequired,
  4285. ContextDetailed->dwFlags,
  4286. ContextDetailed->ulFormatVersion,
  4287. ContextDetailed->ulAssemblyCount,
  4288. ContextDetailed->ulRootManifestPathType,
  4289. ContextDetailed->ulRootManifestPathChars,
  4290. ContextDetailed->ulRootConfigurationPathType,
  4291. ContextDetailed->ulRootConfigurationPathChars,
  4292. ContextDetailed->ulAppDirPathType,
  4293. ContextDetailed->ulAppDirPathChars,
  4294. ContextDetailed->lpRootManifestPath,
  4295. ContextDetailed->lpRootConfigurationPath,
  4296. ContextDetailed->lpAppDirPath
  4297. );
  4298. }
  4299. {
  4300. ULONG AssemblyIndex = 0;
  4301. ULONG FileInAssemblyIndex = 0;
  4302. //
  4303. // 0 produces ERROR_INTERNAL_ERROR
  4304. //
  4305. for (AssemblyIndex = 0 ; AssemblyIndex <= ContextDetailed->ulAssemblyCount ; AssemblyIndex += 1)
  4306. {
  4307. if (!QueryActCtxW(Flags, ActCtxHandle, &AssemblyIndex, AssemblyDetailedInformationInActivationContext, AssemblyDetailed, 4096, &BytesWrittenOrRequired))
  4308. {
  4309. Trace(
  4310. "%s(%lu):QueryActCtx(Flags=0x%lx, ActCtxHandle=%p%ls, AssemblyIndex=0x%lx, AssemblyDetailedInformationInActivationContext) LastError=%lu (%ls)\n",
  4311. __FUNCTION__,
  4312. __LINE__ - 1,
  4313. Flags,
  4314. ActCtxHandle,
  4315. static_cast<PCWSTR>(decimalContext),
  4316. AssemblyIndex,
  4317. ::FusionpGetLastWin32Error(),
  4318. ::FusionpThreadUnsafeGetLastWin32ErrorMessageW()
  4319. );
  4320. }
  4321. else
  4322. {
  4323. Trace(
  4324. "AssemblyIndex : 0x%lx\n"
  4325. "BytesWrittenOrRequired : 0x%lx\n"
  4326. "AssemblyDetailed->ulFlags : 0x%lx\n"
  4327. "AssemblyDetailed->ulEncodedAssemblyIdentityLength : 0x%lx\n"
  4328. "AssemblyDetailed->ulManifestPathType : 0x%lx\n"
  4329. "AssemblyDetailed->ulManifestPathLength : 0x%lx\n"
  4330. "AssemblyDetailed->liManifestLastWriteTime : 0x%I64x\n"
  4331. "AssemblyDetailed->ulPolicyPathType : 0x%lx\n"
  4332. "AssemblyDetailed->ulPolicyPathLength : 0x%lx\n"
  4333. "AssemblyDetailed->liPolicyLastWriteTime : 0x%I64x\n"
  4334. "AssemblyDetailed->ulMetadataSatelliteRosterIndex : 0x%lx\n"
  4335. "AssemblyDetailed->ulManifestVersionMajor : 0x%lx\n"
  4336. "AssemblyDetailed->ulManifestVersionMinor : 0x%lx\n"
  4337. "AssemblyDetailed->ulPolicyVersionMajor : 0x%lx\n"
  4338. "AssemblyDetailed->ulPolicyVersionMinor : 0x%lx\n"
  4339. "AssemblyDetailed->ulAssemblyDirectoryNameLength : 0x%lx\n"
  4340. "AssemblyDetailed->lpAssemblyEncodedAssemblyIdentity : %ls\n"
  4341. "AssemblyDetailed->lpAssemblyManifestPath : %ls\n"
  4342. "AssemblyDetailed->lpAssemblyPolicyPath : %ls\n"
  4343. "AssemblyDetailed->lpAssemblyDirectoryName : %ls\n"
  4344. "AssemblyDetailed->ulFileCount : 0x%lx\n"
  4345. ,
  4346. AssemblyIndex,
  4347. BytesWrittenOrRequired,
  4348. AssemblyDetailed->ulFlags,
  4349. AssemblyDetailed->ulEncodedAssemblyIdentityLength,
  4350. AssemblyDetailed->ulManifestPathType,
  4351. AssemblyDetailed->ulManifestPathLength,
  4352. AssemblyDetailed->liManifestLastWriteTime.QuadPart,
  4353. AssemblyDetailed->ulPolicyPathType,
  4354. AssemblyDetailed->ulPolicyPathLength,
  4355. AssemblyDetailed->liPolicyLastWriteTime.QuadPart,
  4356. AssemblyDetailed->ulMetadataSatelliteRosterIndex,
  4357. AssemblyDetailed->ulManifestVersionMajor,
  4358. AssemblyDetailed->ulManifestVersionMinor,
  4359. AssemblyDetailed->ulPolicyVersionMajor,
  4360. AssemblyDetailed->ulPolicyVersionMinor,
  4361. AssemblyDetailed->ulAssemblyDirectoryNameLength,
  4362. AssemblyDetailed->lpAssemblyEncodedAssemblyIdentity,
  4363. AssemblyDetailed->lpAssemblyManifestPath,
  4364. AssemblyDetailed->lpAssemblyPolicyPath,
  4365. AssemblyDetailed->lpAssemblyDirectoryName,
  4366. AssemblyDetailed->ulFileCount
  4367. );
  4368. QueryIndex.ulAssemblyIndex = AssemblyIndex;
  4369. SetLastError(NO_ERROR);
  4370. if (AssemblyDetailed->ulFileCount == 0)
  4371. {
  4372. Trace("AssemblyDetailed->ulFileCount is 0, working around bug, setting it to 4.\n");
  4373. AssemblyDetailed->ulFileCount = 4; // bug workaround
  4374. }
  4375. for (FileInAssemblyIndex = 0 ; FileInAssemblyIndex != AssemblyDetailed->ulFileCount ; FileInAssemblyIndex += 1)
  4376. {
  4377. QueryIndex.ulFileIndexInAssembly = FileInAssemblyIndex;
  4378. if (!QueryActCtxW(Flags, ActCtxHandle, &QueryIndex, FileInformationInAssemblyOfAssemblyInActivationContext, DllRedir, 4096, &BytesWrittenOrRequired))
  4379. {
  4380. Trace(
  4381. "%s(%lu):QueryActCtx(Flags=0x%lx, ActCtxHandle=%p%ls, QueryIndex={ulAssemblyIndex=0x%lx, ulFileIndexInAssembly=0x%lx}, FileInformationInAssemblyOfAssemblyInActivationContext) LastError=%lu (%ls)\n",
  4382. __FUNCTION__,
  4383. __LINE__,
  4384. Flags,
  4385. ActCtxHandle,
  4386. static_cast<PCWSTR>(decimalContext),
  4387. QueryIndex.ulAssemblyIndex,
  4388. QueryIndex.ulFileIndexInAssembly,
  4389. ::FusionpGetLastWin32Error(),
  4390. ::FusionpThreadUnsafeGetLastWin32ErrorMessageW()
  4391. );
  4392. //break;
  4393. }
  4394. else
  4395. {
  4396. Trace(
  4397. "AssemblyIndex : 0x%lx\n"
  4398. "FileIndex : 0x%lx\n"
  4399. "BytesWrittenOrRequired : 0x%lx\n"
  4400. "DllRedir[0x%lx,0x%lx]->ulFlags : 0x%lx\n"
  4401. "DllRedir[0x%lx,0x%lx]->ulFilenameLength : 0x%lx\n"
  4402. "DllRedir[0x%lx,0x%lx]->ulPathLength : 0x%lx\n"
  4403. "DllRedir[0x%lx,0x%lx]->lpFileName : %ls\n"
  4404. "DllRedir[0x%lx,0x%lx]->lpFilePath : %ls\n"
  4405. ,
  4406. AssemblyIndex,
  4407. FileInAssemblyIndex,
  4408. BytesWrittenOrRequired,
  4409. AssemblyIndex, FileInAssemblyIndex, DllRedir->ulFlags,
  4410. AssemblyIndex, FileInAssemblyIndex, DllRedir->ulFilenameLength,
  4411. AssemblyIndex, FileInAssemblyIndex, DllRedir->ulPathLength,
  4412. AssemblyIndex, FileInAssemblyIndex, DllRedir->lpFileName,
  4413. AssemblyIndex, FileInAssemblyIndex, DllRedir->lpFilePath
  4414. );
  4415. }
  4416. }
  4417. }
  4418. }
  4419. }
  4420. }
  4421. void TestQueryActCtx2()
  4422. {
  4423. {
  4424. CFusionActCtxHandle LogonuiActCtxHandle;
  4425. {
  4426. WCHAR LogonuiManifest[MAX_PATH * 2];
  4427. ACTCTXW LogonuiActCtx = {sizeof(LogonuiActCtx)};
  4428. LogonuiManifest[0] = 0;
  4429. GetSystemDirectoryW(LogonuiManifest, MAX_PATH);
  4430. wcscat(LogonuiManifest, L"\\logonui.exe.manifest");
  4431. LogonuiActCtx.lpSource = LogonuiManifest;
  4432. LogonuiActCtxHandle.Win32Create(&LogonuiActCtx);
  4433. }
  4434. {
  4435. CFusionActCtxScope LogonuiActCtxScope;
  4436. LogonuiActCtxScope.Win32Activate(LogonuiActCtxHandle);
  4437. TestQueryActCtx3(QUERY_ACTCTX_FLAG_USE_ACTIVE_ACTCTX | QUERY_ACTCTX_FLAG_NO_ADDREF, NULL);
  4438. }
  4439. TestQueryActCtx3(QUERY_ACTCTX_FLAG_NO_ADDREF, LogonuiActCtxHandle);
  4440. }
  4441. TestQueryActCtx3(QUERY_ACTCTX_FLAG_NO_ADDREF, ACTCTX_EMPTY);
  4442. TestQueryActCtx3(QUERY_ACTCTX_FLAG_NO_ADDREF, ACTCTX_SYSTEM_DEFAULT);
  4443. }
  4444. void TestQueryActCtx()
  4445. {
  4446. WCHAR ExePath[MAX_PATH];
  4447. CStringBuffer DllPath;
  4448. HMODULE hmod = NULL;
  4449. WCHAR buffer[200];
  4450. if (IamExe)
  4451. {
  4452. if (!Kernel32.GetModuleFileNameW(NULL, ExePath, RTL_NUMBER_OF(ExePath)))
  4453. ThrowLastError();
  4454. if (!DllPath.Win32Format(L"%ls.dll", ExePath))
  4455. ThrowLastError();
  4456. ::CopyFileW(ExePath, DllPath, FALSE);
  4457. }
  4458. if (IamDll)
  4459. {
  4460. hmod = NULL;
  4461. hmod = (HMODULE)RtlPcToFileHeader(InitCommonControls, (PVOID*)&hmod);
  4462. wcscpy(buffer, L"FAILED");
  4463. if (hmod != NULL)
  4464. Kernel32.GetModuleFileNameW(hmod, buffer, RTL_NUMBER_OF(buffer));
  4465. Trace("from dll static dep: %p %ls\n", hmod, buffer);
  4466. #if defined(ISOLATION_AWARE_ENABLED)
  4467. hmod = IsolationAwareLoadLibraryW(L"comctl32.dll");
  4468. LastError = ::GetLastError();
  4469. wcscpy(buffer, L"FAILED");
  4470. if (hmod != NULL)
  4471. Kernel32.GetModuleFileNameW(hmod, buffer, RTL_NUMBER_OF(buffer));
  4472. Trace("from dll IsolationAwareLoadLibraryW: %p %ls\n", hmod, buffer);
  4473. #endif
  4474. hmod = LoadLibraryW(L"comctl32.dll");
  4475. LastError = ::GetLastError();
  4476. wcscpy(buffer, L"FAILED");
  4477. if (hmod != NULL)
  4478. Kernel32.GetModuleFileNameW(hmod, buffer, RTL_NUMBER_OF(buffer));
  4479. Trace("from dll LoadLibraryW: %p %ls\n", hmod, buffer);
  4480. return;
  4481. }
  4482. {
  4483. hmod = NULL;
  4484. hmod = (HMODULE)RtlPcToFileHeader(InitCommonControls, (PVOID*)&hmod);
  4485. wcscpy(buffer, L"FAILED");
  4486. if (hmod != NULL)
  4487. Kernel32.GetModuleFileNameW(hmod, buffer, RTL_NUMBER_OF(buffer));
  4488. Trace("from exe static dep: %p %ls\n", hmod, buffer);
  4489. #if defined(ISOLATION_AWARE_ENABLED)
  4490. hmod = IsolationAwareLoadLibraryW(L"comctl32.dll");
  4491. LastError = ::GetLastError();
  4492. wcscpy(buffer, L"FAILED");
  4493. if (hmod != NULL)
  4494. Kernel32.GetModuleFileNameW(hmod, buffer, RTL_NUMBER_OF(buffer));
  4495. Trace("from exe IsolationAwareLoadLibraryW: %p %ls\n", hmod, buffer);
  4496. #endif
  4497. hmod = LoadLibraryW(L"comctl32.dll");
  4498. LastError = ::GetLastError();
  4499. wcscpy(buffer, L"FAILED");
  4500. if (hmod != NULL)
  4501. Kernel32.GetModuleFileNameW(hmod, buffer, RTL_NUMBER_OF(buffer));
  4502. Trace("from exe LoadLibraryW: %p %ls\n", hmod, buffer);
  4503. }
  4504. SetDllBitInPeImage(DllPath);
  4505. Trace("Enter LoadLibraryW\n");
  4506. hmod = LoadLibraryW(DllPath);
  4507. LastError = ::GetLastError();
  4508. Trace("Exit LoadLibraryW\n");
  4509. void (*pfn)(void) = reinterpret_cast<void (*)(void)>(GetProcAddress(hmod, "TestQueryActCtx"));
  4510. Trace("Enter non DllMain call to TestQueryActCtx\n");
  4511. pfn();
  4512. Trace("Exit non DllMain call to TestQueryActCtx\n");
  4513. FreeLibrary(hmod);
  4514. Kernel32.DeleteFileW(DllPath);
  4515. }
  4516. DWORD WINAPI Test64kThreadMain(void* pv)
  4517. {
  4518. LONG_PTR i = 0;
  4519. HANDLE h = 0;
  4520. ULONG_PTR cookie = 0;
  4521. LONG_PTR j = reinterpret_cast<LONG_PTR>(pv);
  4522. GetCurrentActCtx(&h);
  4523. ActivateActCtx(h, &cookie);
  4524. printf("%Id ", cookie);
  4525. if (cookie == 0) printf("cookie 0\n");
  4526. ActivateActCtx(h, &cookie);
  4527. printf("%Id ", cookie);
  4528. if (cookie == 0) printf("cookie 0\n");
  4529. __try
  4530. {
  4531. for (i = 0 ; i < j ; ++i)
  4532. {
  4533. if (!ActivateActCtx(h, &cookie))
  4534. printf("activate error %lu\n", ::GetLastError());
  4535. else
  4536. {
  4537. if (cookie == 0) printf("cookie 0\n");
  4538. //printf("%Id ", cookie);
  4539. if (!DeactivateActCtx(0, cookie))
  4540. printf("deactivate error %lu\n", ::GetLastError());
  4541. }
  4542. }
  4543. }
  4544. __except(printf("exception %lx\n", GetExceptionCode()),EXCEPTION_EXECUTE_HANDLER)
  4545. {
  4546. }
  4547. printf("final cookie value %Id\n", cookie);
  4548. return 0;
  4549. }
  4550. void Test64k()
  4551. {
  4552. HANDLE h = 0;
  4553. ULONG_PTR cookie = 0;
  4554. DWORD threadId = 0;
  4555. LONG_PTR i = 0;
  4556. LONG_PTR j = 0;
  4557. HANDLE thread = 0;
  4558. GetCurrentActCtx(&h);
  4559. ActivateActCtx(h, &cookie);
  4560. if (cookie == 0) printf("cookie 0\n");
  4561. printf("%Id ", cookie);
  4562. ActivateActCtx(h, &cookie);
  4563. if (cookie == 0) printf("cookie 0\n");
  4564. printf("%Id ", cookie);
  4565. for (j = 0 ; j < 0xfff0 ; ++j)
  4566. {
  4567. if (!ActivateActCtx(h, &cookie))
  4568. printf("activate error %lu\n", ::GetLastError());
  4569. else
  4570. {
  4571. if (cookie == 0) printf("cookie 0\n");
  4572. if (!DeactivateActCtx(0, cookie))
  4573. printf("deactivate error %lu\n", ::GetLastError());
  4574. }
  4575. }
  4576. for ( ; j < 0xffff + 0xf ; ++j)
  4577. {
  4578. if (!ActivateActCtx(h, &cookie))
  4579. printf("activate error %lu\n", ::GetLastError());
  4580. printf("%Id ", cookie);
  4581. if (cookie == 0) printf("cookie 0\n");
  4582. thread = CreateThread(NULL, 0, Test64kThreadMain, reinterpret_cast<void*>(j), 0, &threadId);
  4583. }
  4584. WaitForSingleObject(thread, INFINITE);
  4585. }
  4586. void TestDotLocalSingleInstancing()
  4587. {
  4588. FILE* File = 0;
  4589. HMODULE DllHandle = 0;
  4590. {
  4591. WCHAR DotLocal[MAX_PATH];
  4592. if (!Kernel32.GetModuleFileNameW(GetMyHandle(), DotLocal, NUMBER_OF(DotLocal) - sizeof(".local")))
  4593. ThrowLastError();
  4594. wcscat(DotLocal, L".local");
  4595. File = _wfopen(DotLocal, L"w");
  4596. fprintf(File, "\n");
  4597. fclose(File);
  4598. }
  4599. {
  4600. WCHAR System32Mshtml[MAX_PATH];
  4601. WCHAR LocalMshtml[MAX_PATH];
  4602. WCHAR ResultingMshtml[MAX_PATH];
  4603. if (!GetSystemDirectoryW(System32Mshtml, NUMBER_OF(System32Mshtml) - sizeof("\\Mshtml.dll")))
  4604. ThrowLastError();
  4605. wcscat(System32Mshtml, L"\\Mshtml.dll");
  4606. if (!Kernel32.GetModuleFileNameW(GetMyHandle(), LocalMshtml, NUMBER_OF(LocalMshtml) - sizeof("\\Mshtml.dll")))
  4607. ThrowLastError();
  4608. *wcsrchr(LocalMshtml, '\\') = 0;
  4609. wcscat(LocalMshtml, L"\\Mshtml.dll");
  4610. //DllHandle = LoadLibraryW(L"Mshtml.dll");
  4611. //Trace("LoadLibrary(Mshtml): %p\n", DllHandle);
  4612. if (!CopyFileW(System32Mshtml, LocalMshtml, FALSE))
  4613. ThrowLastError();
  4614. Trace("copy %ls -> %ls\n", System32Mshtml, LocalMshtml);
  4615. ULONG i;
  4616. for (i = 0 ; i != 4 ; i += 1)
  4617. {
  4618. DllHandle = LoadLibraryW(System32Mshtml);
  4619. wcscpy(ResultingMshtml, L"FAILED");
  4620. if (DllHandle != NULL)
  4621. Kernel32.GetModuleFileNameW(DllHandle, ResultingMshtml, RTL_NUMBER_OF(ResultingMshtml));
  4622. Trace("LoadLibrary(%ls): %p %ls\n", System32Mshtml, DllHandle, ResultingMshtml);
  4623. }
  4624. }
  4625. }
  4626. void
  4627. TestCreateActCtx(
  4628. int n,
  4629. wchar_t **args
  4630. )
  4631. {
  4632. ACTCTXW acw;
  4633. int i = 0;
  4634. WCHAR rgwchSource[MAX_PATH];
  4635. PCWSTR pszResource = NULL;
  4636. HANDLE hActCtx = NULL;
  4637. DWORD dwLastError = 0;
  4638. for (i=0; i<n; i++)
  4639. {
  4640. PCWSTR arg = args[i];
  4641. PCWSTR semi = wcschr(arg, L';');
  4642. memset(&acw, 0, sizeof(acw));
  4643. acw.cbSize = sizeof(acw);
  4644. if (semi == NULL)
  4645. {
  4646. acw.lpSource = arg;
  4647. }
  4648. else
  4649. {
  4650. int cch = (int) (semi - arg);
  4651. if (cch >= NUMBER_OF(rgwchSource))
  4652. cch = NUMBER_OF(rgwchSource) - 1;
  4653. memcpy(rgwchSource, arg, cch * sizeof(WCHAR));
  4654. rgwchSource[cch] = L'\0';
  4655. if (semi[1] == L'#')
  4656. {
  4657. wchar_t *pszDummy;
  4658. pszResource = MAKEINTRESOURCEW(wcstoul(semi+1, &pszDummy, 10));
  4659. }
  4660. else
  4661. {
  4662. pszResource = semi+1;
  4663. }
  4664. acw.lpSource = rgwchSource;
  4665. acw.lpResourceName = pszResource;
  4666. acw.dwFlags |= ACTCTX_FLAG_RESOURCE_NAME_VALID;
  4667. }
  4668. hActCtx = ::CreateActCtxW(&acw);
  4669. dwLastError = ::GetLastError();
  4670. printf("CreateActCtxW() on \"%ls\" returned %p\n", arg, hActCtx);
  4671. if (hActCtx == INVALID_HANDLE_VALUE)
  4672. {
  4673. printf(" ::GetLastError() = %lu\n", dwLastError);
  4674. }
  4675. ::ReleaseActCtx(hActCtx);
  4676. }
  4677. }
  4678. const char comctlv6manifest[]=
  4679. "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>"
  4680. "<assembly xmlns=\"urn:schemas-microsoft-com:asm.v1\" manifestVersion=\"1.0\">"
  4681. "<assemblyIdentity"
  4682. " name=\"Microsoft.Windows.Shell.notepad\""
  4683. " processorArchitecture=\"x86\""
  4684. " version=\"5.1.0.0\""
  4685. " type=\"win32\"/>"
  4686. "<dependency>"
  4687. " <dependentAssembly>"
  4688. " <assemblyIdentity"
  4689. " type=\"win32\""
  4690. " name=\"Microsoft.Windows.Common-Controls\""
  4691. " version=\"6.0.0.0\""
  4692. " processorArchitecture=\"x86\""
  4693. " publicKeyToken=\"6595b64144ccf1df\""
  4694. " language=\"*\""
  4695. " />"
  4696. " </dependentAssembly>"
  4697. "</dependency>"
  4698. "</assembly>"
  4699. ;
  4700. const char comctlv5manifest[]=
  4701. "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>"
  4702. "<assembly xmlns=\"urn:schemas-microsoft-com:asm.v1\" manifestVersion=\"1.0\">"
  4703. "<assemblyIdentity"
  4704. " name=\"Microsoft.Windows.Shell.notepad\""
  4705. " processorArchitecture=\"x86\""
  4706. " version=\"5.1.0.0\""
  4707. " type=\"win32\"/>"
  4708. "</assembly>"
  4709. ;
  4710. void TestCreateActctxAdminOverride()
  4711. {
  4712. WCHAR exe[MAX_PATH];
  4713. WCHAR dll[MAX_PATH];
  4714. WCHAR comctl[MAX_PATH];
  4715. WCHAR manifest[MAX_PATH];
  4716. ACTCTXW Actctx = {sizeof(Actctx)};
  4717. FILE* File = NULL;
  4718. ULONG_PTR ulCookie = 0;
  4719. HMODULE DllHandle = 0;
  4720. HANDLE ActctxHandle = NULL;
  4721. GUID Guid = { 0 };
  4722. wcscpy(exe, GetMyModuleFullPath());
  4723. wcscpy(dll, GetMyModuleFullPath());
  4724. wcscat(dll, L".dll");
  4725. CopyFileW(exe, dll, FALSE);
  4726. SetDllBitInPeImage(dll);
  4727. Actctx.lpSource = dll;
  4728. /*
  4729. ActctxHandle = CreateActCtxW(&Actctx);
  4730. if (ActctxHandle == INVALID_HANDLE_VALUE)
  4731. return;
  4732. Trace("CreateActCtxW succeeded\n");
  4733. */
  4734. //
  4735. // manfile is number to put in the manifest file name, 0 for none
  4736. // good is what the contents of the file are, 0=>bad, 1=>v5, 2=>v6
  4737. // res is what resource id to ask for
  4738. //
  4739. for (int manfile = 0 ; manfile != 4 ; manfile += 1)
  4740. {
  4741. WCHAR Number[RTL_BITS_OF(ULONG_PTR) + 3];
  4742. for (int good = 0 ; good != 3 ; good += 1)
  4743. {
  4744. for (int res = -1 ; res != 4 ; res += 1)
  4745. {
  4746. Trace("---------------------------------------------------------------\n");
  4747. Trace("resourceid is %d%s\n", res, (res != -1) ? "" : " (flag not set)");
  4748. if (res != -1)
  4749. {
  4750. Actctx.lpResourceName = MAKEINTRESOURCEW(res);
  4751. Actctx.dwFlags |= ACTCTX_FLAG_RESOURCE_NAME_VALID;
  4752. Actctx.lpResourceName = MAKEINTRESOURCEW(res);
  4753. }
  4754. else
  4755. {
  4756. Actctx.dwFlags &= ~ACTCTX_FLAG_RESOURCE_NAME_VALID;
  4757. }
  4758. for (int delman = 0 ; delman != 4 ; delman += 1)
  4759. {
  4760. Number[0] = 0;
  4761. if (delman)
  4762. swprintf(Number, L".%d", delman);
  4763. swprintf(manifest, L"%ls%ls%ls%ls", GetMyModuleFullPathWithoutExtension(), L".dll", Number, L".Manifest");
  4764. /*
  4765. CoCreateGuid(&Guid);
  4766. swprintf(String3, L"%ls%I64x%I64x", GetMyModuleFullPath(), *reinterpret_cast<__int64*>(&Guid), *(1+reinterpret_cast<__int64*>(&Guid)));
  4767. if (!MoveFileW(String, String3) && ::GetLastError() != ERROR_FILE_NOT_FOUND)
  4768. Trace("MoveFile(%ls -> %ls) FAILED %d\n", String, String3, ::GetLastError());
  4769. else
  4770. ;//Trace("MoveFile(%ls -> %ls)\n", String, String3);
  4771. */
  4772. if (!Kernel32.DeleteFileW(manifest) && ::GetLastError() != ERROR_FILE_NOT_FOUND)
  4773. Trace("DeleteFile(%ls) FAILED %d\n", manifest, ::GetLastError());
  4774. else
  4775. ;//Trace("DeleteFile(%ls)\n", String3);
  4776. }
  4777. Number[0] = 0;
  4778. if (manfile != 0)
  4779. {
  4780. swprintf(Number, L".%d", manfile);
  4781. }
  4782. swprintf(manifest, L"%ls%ls%ls%ls", GetMyModuleFullPathWithoutExtension(), L".dll", Number, L".Manifest");
  4783. //Trace("fopen(%ls)\n", String);
  4784. File = _wfopen(manifest, L"w+");
  4785. if (File == NULL)
  4786. {
  4787. perror("fopen");
  4788. }
  4789. switch (good)
  4790. {
  4791. case 0:
  4792. fprintf(File, "bad");
  4793. Trace("%ls is bad\n", manifest);
  4794. break;
  4795. case 1:
  4796. fprintf(File, "%s", comctlv5manifest);
  4797. Trace("%ls is comctlv5manifest\n", manifest);
  4798. break;
  4799. case 2:
  4800. fprintf(File, "%s", comctlv6manifest);
  4801. Trace("%ls is comctlv6manifest\n", manifest);
  4802. break;
  4803. }
  4804. fclose(File);
  4805. ActctxHandle = CreateActCtxW(&Actctx);
  4806. if (ActctxHandle == INVALID_HANDLE_VALUE)
  4807. {
  4808. Trace("CreateActCtxW failed %d\n", ::GetLastError());
  4809. ulCookie = 0;
  4810. }
  4811. else
  4812. {
  4813. Trace("CreateActCtxW succeeded %p\n", ActctxHandle);
  4814. ActivateActCtx(ActctxHandle, &ulCookie);
  4815. }
  4816. __try
  4817. {
  4818. PWSTR filePart;
  4819. comctl[0] = 0;
  4820. SearchPathW(NULL, L"comctl32.dll", NULL, RTL_NUMBER_OF(comctl), comctl, &filePart);
  4821. }
  4822. __finally
  4823. {
  4824. if (ActctxHandle != INVALID_HANDLE_VALUE)
  4825. DeactivateActCtx(0, ulCookie);
  4826. }
  4827. Trace("SearchPathW(comctl32.dll): %ls\n", comctl);
  4828. }
  4829. }
  4830. }
  4831. }
  4832. void TestCreateActctxLikeCreateProcess()
  4833. {
  4834. #if defined(ACTCTX_FLAG_LIKE_CREATEPROCESS)
  4835. WCHAR comctl[MAX_PATH];
  4836. WCHAR manifest[MAX_PATH];
  4837. ACTCTXW Actctx = {sizeof(Actctx)};
  4838. FILE* File = NULL;
  4839. ULONG_PTR ulCookie = 0;
  4840. HMODULE DllHandle = 0;
  4841. HANDLE ActctxHandle;
  4842. PWSTR filePart = NULL;
  4843. Actctx.lpSource = GetMyModuleFullPath();
  4844. Actctx.dwFlags = ACTCTX_FLAG_LIKE_CREATEPROCESS;
  4845. wcscpy(manifest, GetMyModuleFullPath());
  4846. wcscat(manifest, L".Manifest");
  4847. Kernel32.DeleteFileW(manifest);
  4848. //Trace("DeleteFile(%ls)\n", manifest);
  4849. ActctxHandle = CreateActCtxW(&Actctx);
  4850. if (ActctxHandle == INVALID_HANDLE_VALUE)
  4851. {
  4852. Trace("CreateActCtxW failed %d\n", ::GetLastError());
  4853. ulCookie = 0;
  4854. }
  4855. else
  4856. {
  4857. Trace("CreateActCtxW succeeded %p\n", ActctxHandle);
  4858. ActivateActCtx(ActctxHandle, &ulCookie);
  4859. }
  4860. __try
  4861. {
  4862. comctl[0] = 0;
  4863. SearchPathW(NULL, L"comctl32.dll", NULL, RTL_NUMBER_OF(comctl), comctl, &filePart);
  4864. }
  4865. __finally
  4866. {
  4867. if (ActctxHandle != INVALID_HANDLE_VALUE)
  4868. DeactivateActCtx(0, ulCookie);
  4869. }
  4870. Trace("SearchPathW(comctl32.dll): %ls\n", comctl);
  4871. File = _wfopen(manifest, L"w");
  4872. fprintf(File, "%s", comctlv5manifest);
  4873. fclose(File);
  4874. Trace("%ls == comctlv5manifest\n", manifest);
  4875. ActctxHandle = CreateActCtxW(&Actctx);
  4876. if (ActctxHandle == INVALID_HANDLE_VALUE)
  4877. {
  4878. Trace("CreateActCtxW failed %d\n", ::GetLastError());
  4879. ulCookie = 0;
  4880. }
  4881. else
  4882. {
  4883. Trace("CreateActCtxW succeeded %p\n", ActctxHandle);
  4884. ActivateActCtx(ActctxHandle, &ulCookie);
  4885. }
  4886. __try
  4887. {
  4888. comctl[0] = 0;
  4889. SearchPathW(NULL, L"comctl32.dll", NULL, RTL_NUMBER_OF(comctl), comctl, &filePart);
  4890. }
  4891. __finally
  4892. {
  4893. if (ActctxHandle != INVALID_HANDLE_VALUE)
  4894. DeactivateActCtx(0, ulCookie);
  4895. }
  4896. Trace("SearchPathW(comctl32.dll): %ls\n", comctl);
  4897. File = _wfopen(manifest, L"w");
  4898. fprintf(File, "%ls", comctlv6manifest);
  4899. fclose(File);
  4900. Trace("%ls == comctlv6manifest\n", manifest);
  4901. ActctxHandle = CreateActCtxW(&Actctx);
  4902. if (ActctxHandle == INVALID_HANDLE_VALUE)
  4903. {
  4904. Trace("CreateActCtxW failed %d\n", ::GetLastError());
  4905. ulCookie = 0;
  4906. }
  4907. else
  4908. {
  4909. Trace("CreateActCtxW succeeded %p\n", ActctxHandle);
  4910. ActivateActCtx(ActctxHandle, &ulCookie);
  4911. }
  4912. __try
  4913. {
  4914. comctl[0] = 0;
  4915. SearchPathW(NULL, L"comctl32.dll", NULL, RTL_NUMBER_OF(comctl), comctl, &filePart);
  4916. }
  4917. __finally
  4918. {
  4919. if (ActctxHandle != INVALID_HANDLE_VALUE)
  4920. DeactivateActCtx(0, ulCookie);
  4921. }
  4922. Trace("SearchPathW(comctl32.dll): %ls\n", comctl);
  4923. #endif
  4924. }
  4925. void
  4926. TestQueryManifestInformationBasic(
  4927. PCWSTR pszManifest
  4928. )
  4929. {
  4930. LoadSxs();
  4931. struct {
  4932. SXS_MANIFEST_INFORMATION_BASIC mib;
  4933. WCHAR rgwchSpaceForIdentity[1024];
  4934. WCHAR rgwchSpaceForDirName[1024];
  4935. } buff;
  4936. if (!(*g_pfnSxsQueryManifestInformation)(0, pszManifest, SXS_QUERY_MANIFEST_INFORMATION_INFOCLASS_BASIC, 0, sizeof(buff), &buff, NULL)) {
  4937. fprintf(stderr, "%s failed!\n", __FUNCTION__);
  4938. }
  4939. }
  4940. void TestImage()
  4941. {
  4942. PIMAGE_RESOURCE_DIRECTORY ImageResourceDirectory = (PIMAGE_RESOURCE_DIRECTORY)4;
  4943. PIMAGE_RESOURCE_DIRECTORY_ENTRY ImageResourceDirectoryEntry = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)4;;
  4944. printf("ImageResourceDirectory %p\n", ImageResourceDirectory);
  4945. printf("ImageResourceDirectory + 1 %p\n", ImageResourceDirectory + 1);
  4946. printf("ImageResourceDirectoryEntry %p\n", ImageResourceDirectoryEntry);
  4947. printf("ImageResourceDirectoryEntry + 1 %p\n", ImageResourceDirectoryEntry + 1);
  4948. }
  4949. class CSxsTestCleanup : public CCleanupBase
  4950. {
  4951. public:
  4952. VOID DeleteYourself() { }
  4953. ~CSxsTestCleanup() { }
  4954. };
  4955. #define private public
  4956. #include "sxsprotect.h"
  4957. #undef private
  4958. void TestInterlockedAlignment()
  4959. {
  4960. __declspec(align(16)) SLIST_HEADER SlistHeader;
  4961. RtlInitializeSListHead(&SlistHeader);
  4962. CSxsTestCleanup* pc = new CSxsTestCleanup();
  4963. printf("%p\n", pc);
  4964. printf("%p\n", static_cast<SLIST_ENTRY*>(pc));
  4965. SxspAtExit(pc);
  4966. CProtectionRequestRecord* pr = new CProtectionRequestRecord;
  4967. printf("%p\n", pr);
  4968. printf("%p\n", &pr->m_ListHeader);
  4969. CStringListEntry* psle = new CStringListEntry;
  4970. printf("%p\n", psle);
  4971. printf("%p\n", static_cast<SLIST_ENTRY*>(psle));
  4972. RtlInterlockedPushEntrySList(&SlistHeader, pc);
  4973. RtlInterlockedPushEntrySList(&SlistHeader, psle);
  4974. RtlQueryDepthSList(&SlistHeader);
  4975. RtlInterlockedPopEntrySList(&SlistHeader);
  4976. RtlInterlockedFlushSList(&SlistHeader);
  4977. // untested: RtlInterlockedPushListSList
  4978. RtlInterlockedPushEntrySList(&pr->m_ListHeader, pc);
  4979. RtlInterlockedPushEntrySList(&pr->m_ListHeader, psle);
  4980. RtlQueryDepthSList(&pr->m_ListHeader);
  4981. RtlInterlockedPopEntrySList(&pr->m_ListHeader);
  4982. RtlInterlockedFlushSList(&pr->m_ListHeader);
  4983. // untested: RtlInterlockedPushListSList
  4984. printf("success\n");
  4985. }
  4986. void TestCreateActctxWindowsShellManifest()
  4987. {
  4988. WCHAR WindowsShellManifestFileName[MAX_PATH];
  4989. ACTCTXW ActCtx = { sizeof(ActCtx) };
  4990. HANDLE ActCtxHandle = 0;
  4991. WindowsShellManifestFileName[0] = 0;
  4992. GetWindowsDirectoryW(WindowsShellManifestFileName, NUMBER_OF(WindowsShellManifestFileName) - 64);
  4993. wcscat(WindowsShellManifestFileName, L"\\WindowsShell.Manifest");
  4994. ActCtx.lpSource = WindowsShellManifestFileName;
  4995. ActCtxHandle = CreateActCtxW(&ActCtx);
  4996. Trace("TestCreateActctxWindowsShellManifest: %p, %lu\n", ActCtxHandle, ::GetLastError());
  4997. ReleaseActCtx(ActCtxHandle);
  4998. }
  4999. void TestCreateGlobalEvent()
  5000. {
  5001. if (!::CreateEventW(NULL, FALSE, FALSE, L"MGRIER"))
  5002. return;
  5003. Sleep(500000);
  5004. }
  5005. #if 0
  5006. class CObjectTypes
  5007. {
  5008. protected:
  5009. std::vector<BYTE> m_ByteBuffer;
  5010. PSYSTEM_OBJECTTYPE_INFORMATION m_TypedBuffer;
  5011. public:
  5012. };
  5013. class CObjectSnapshot
  5014. {
  5015. protected:
  5016. //
  5017. // This interface is not very good, but it's easy..the entries
  5018. // are of variable size...
  5019. //
  5020. std::vector<BYTE> m_ByteBuffer;
  5021. SIZE_T m_Size;
  5022. //
  5023. // Some operations, like sorting, require us to move all the string data
  5024. // out of the elements. We do not manage this data in a lossless way.
  5025. //
  5026. // Ultimately, you may benefit from copying/transforming the data completely.
  5027. //
  5028. std::vector<BYTE> m_StringData;
  5029. public:
  5030. SIZE_T size() const { return m_Size; }
  5031. class iterator;
  5032. class const_iterator
  5033. {
  5034. protected:
  5035. const SYSTEM_OBJECT_INFORMATION* m_p;
  5036. public:
  5037. ~const_iterator() { }
  5038. void operator=(const const_iterator& x) { m_p = x.m_p; }
  5039. const_iterator(const const_iterator& x) : m_p(x.m_p) { }
  5040. const_iterator(const BYTE* p = NULL) : m_p(reinterpret_cast<const SYSTEM_OBJECT_INFORMATION*>(p)) { }
  5041. //void operator=(const iterator& x);
  5042. //const_iterator(const iterator& x);
  5043. bool operator==(const const_iterator& i) const
  5044. {
  5045. return (m_p == i.m_p);
  5046. }
  5047. bool operator!=(const const_iterator& i) const
  5048. {
  5049. return (m_p != i.m_p);
  5050. }
  5051. const SYSTEM_OBJECT_INFORMATION& operator*() const { return *m_p; }
  5052. void operator++()
  5053. {
  5054. if (m_p != NULL)
  5055. {
  5056. if (m_p->NextEntryOffset != 0)
  5057. m_p = reinterpret_cast<const SYSTEM_OBJECT_INFORMATION*>(reinterpret_cast<const BYTE*>(m_p) + m_p->NextEntryOffset);
  5058. else
  5059. m_p = NULL; // end
  5060. }
  5061. }
  5062. const_iterator operator++(int)
  5063. {
  5064. const_iterator tmp = *this;
  5065. ++*this;;
  5066. return tmp;
  5067. }
  5068. };
  5069. class iterator : public const_iterator
  5070. {
  5071. private:
  5072. void operator=(const const_iterator&);
  5073. public:
  5074. ~iterator() { }
  5075. iterator(BYTE* p = NULL) : const_iterator(p) { }
  5076. SYSTEM_OBJECT_INFORMATION& operator*() { return const_cast<SYSTEM_OBJECT_INFORMATION&>(*m_p); }
  5077. };
  5078. const_iterator begin() const { return const_iterator(&m_ByteBuffer[0]); }
  5079. iterator begin() { return iterator(&m_ByteBuffer[0]); }
  5080. const_iterator end() const { return const_iterator(); }
  5081. iterator end() { return iterator(); }
  5082. void swap(CObjectSnapshot& x)
  5083. {
  5084. std::swap(m_ByteBuffer, x.m_ByteBuffer);
  5085. std::swap(m_Size, x.m_Size);
  5086. }
  5087. CObjectSnapshot() { }
  5088. ~CObjectSnapshot() { }
  5089. };
  5090. class CHandleSnapshot
  5091. {
  5092. protected:
  5093. std::vector<BYTE> m_ByteBuffer;
  5094. PSYSTEM_HANDLE_INFORMATION_EX m_TypedBuffer;
  5095. public:
  5096. SIZE_T size() const { return m_TypedBuffer->NumberOfHandles; }
  5097. SYSTEM_HANDLE_TABLE_ENTRY_INFO_EX* begin() { return &m_TypedBuffer->Handles[0]; }
  5098. const SYSTEM_HANDLE_TABLE_ENTRY_INFO_EX* begin() const { return &m_TypedBuffer->Handles[0]; }
  5099. SYSTEM_HANDLE_TABLE_ENTRY_INFO_EX* end() { return begin() + size(); }
  5100. const SYSTEM_HANDLE_TABLE_ENTRY_INFO_EX* end() const { return begin() + size(); }
  5101. SYSTEM_HANDLE_TABLE_ENTRY_INFO_EX& operator[](size_t index) { return *(begin() + index); }
  5102. const SYSTEM_HANDLE_TABLE_ENTRY_INFO_EX& operator[](size_t index) const { return *(begin() + index); }
  5103. void reserve(SIZE_T n)
  5104. {
  5105. resize(n); // since there's no constructor..
  5106. }
  5107. void resize(SIZE_T n)
  5108. {
  5109. m_ByteBuffer.resize(sizeof(SYSTEM_HANDLE_INFORMATION_EX) + (n - 1) * sizeof(SYSTEM_HANDLE_TABLE_ENTRY_INFO_EX));
  5110. Resync();
  5111. m_TypedBuffer->NumberOfHandles = n;
  5112. }
  5113. void swap(CHandleSnapshot& x)
  5114. {
  5115. std::swap(m_ByteBuffer, x.m_ByteBuffer);
  5116. x.Resync();
  5117. Resync();
  5118. }
  5119. CHandleSnapshot() : m_TypedBuffer(NULL) { }
  5120. ~CHandleSnapshot() { }
  5121. void GetHandlesForCurrentProcess()
  5122. {
  5123. GetHandlesForProcess(GetCurrentProcessId());
  5124. }
  5125. void GetHandlesForProcess(ULONG_PTR pid)
  5126. {
  5127. GetHandlesForSystem();
  5128. FilterByProcessId(pid);
  5129. }
  5130. void GetHandlesForSystem()
  5131. {
  5132. //
  5133. // the actual needed size can be very large, over 256k
  5134. //
  5135. ULONG Size = 0;
  5136. m_TypedBuffer = NULL;
  5137. m_ByteBuffer.resize(sizeof(SYSTEM_HANDLE_INFORMATION_EX));
  5138. NTSTATUS Status = NtQuerySystemInformation(SystemExtendedHandleInformation, &m_ByteBuffer[0], static_cast<ULONG>(m_ByteBuffer.size()), &Size);
  5139. while (Status == STATUS_INFO_LENGTH_MISMATCH && Size != 0)
  5140. {
  5141. //
  5142. // since it is transient, let's be safe and double it
  5143. //
  5144. m_ByteBuffer.resize(Size * 2);
  5145. Status = NtQuerySystemInformation(SystemExtendedHandleInformation, &m_ByteBuffer[0], static_cast<ULONG>(m_ByteBuffer.size()), &Size);
  5146. }
  5147. if (!NT_SUCCESS(Status))
  5148. {
  5149. Trace("NtQuerySystemInformation failed 0x%lx\n", Status);
  5150. return;
  5151. }
  5152. m_ByteBuffer.resize(Size);
  5153. m_TypedBuffer = reinterpret_cast<PSYSTEM_HANDLE_INFORMATION_EX>(&m_ByteBuffer[0]);
  5154. Trace("%Id total handles system-wide\n", m_TypedBuffer->NumberOfHandles);
  5155. }
  5156. void FilterByProcessId(ULONG_PTR pid)
  5157. {
  5158. SIZE_T Scan = 0;
  5159. SIZE_T Keep = 0;
  5160. for (Scan = 0 ; Scan != m_TypedBuffer->NumberOfHandles ; Scan += 1)
  5161. {
  5162. if (m_TypedBuffer->Handles[Scan].UniqueProcessId == pid)
  5163. {
  5164. if (Keep != Scan)
  5165. m_TypedBuffer->Handles[Keep] = m_TypedBuffer->Handles[Scan]; // struct copy
  5166. Keep += 1;
  5167. }
  5168. }
  5169. m_TypedBuffer->NumberOfHandles = Keep;
  5170. }
  5171. void Resync()
  5172. {
  5173. m_TypedBuffer = reinterpret_cast<PSYSTEM_HANDLE_INFORMATION_EX>(&m_ByteBuffer[0]);
  5174. }
  5175. CHandleSnapshot(const CHandleSnapshot& x) : m_TypedBuffer(NULL)
  5176. {
  5177. this->m_ByteBuffer = x.m_ByteBuffer;
  5178. Resync();
  5179. }
  5180. void operator=(const CHandleSnapshot& x)
  5181. {
  5182. this->m_ByteBuffer = x.m_ByteBuffer;
  5183. Resync();
  5184. }
  5185. class CHandleValueOperatorLessThan
  5186. {
  5187. public:
  5188. bool operator()(const SYSTEM_HANDLE_TABLE_ENTRY_INFO_EX& x, const SYSTEM_HANDLE_TABLE_ENTRY_INFO_EX& y)
  5189. {
  5190. return (x.HandleValue < y.HandleValue);
  5191. }
  5192. };
  5193. void SortByHandleValue()
  5194. {
  5195. std::sort(begin(), end(), CHandleValueOperatorLessThan());
  5196. }
  5197. void operator-=(/*const*/CHandleSnapshot& x)
  5198. {
  5199. SortByHandleValue();
  5200. x.SortByHandleValue();
  5201. CHandleSnapshot temp(*this);
  5202. resize(
  5203. std::set_difference(temp.begin(), temp.end(), x.begin(), x.end(), begin(), CHandleValueOperatorLessThan())
  5204. - begin());
  5205. }
  5206. void Dump()
  5207. {
  5208. }
  5209. };
  5210. class CHandleSnapshots
  5211. {
  5212. public:
  5213. void Begin() { m_Begin.GetHandlesForCurrentProcess(); }
  5214. void End() { m_End.GetHandlesForCurrentProcess(); m_Diff = m_Begin; m_Diff -= m_End; }
  5215. CHandleSnapshot m_Begin;
  5216. CHandleSnapshot m_End;
  5217. CHandleSnapshot m_Diff;
  5218. };
  5219. #endif
  5220. void Pause()
  5221. {
  5222. Trace("Press a key to continue\n");
  5223. getchar();
  5224. }
  5225. void TestHandleLeaks()
  5226. {
  5227. #if 0
  5228. WCHAR WindowsDirectory[MAX_PATH];
  5229. ULONG i = 0;
  5230. CFusionFile DevNull;
  5231. //SECURITY_ATTRIBUTES SecurityAttributes = { sizeof(SecurityAttributes), NULL, TRUE};
  5232. WindowsDirectory[0] = 0;
  5233. DevNull = CreateFileW(L"nul:", GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
  5234. NULL/*&SecurityAttributes*/, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
  5235. if (DevNull == INVALID_HANDLE_VALUE)
  5236. Trace("Open(nul:) failed %ld\n", ::GetLastError());
  5237. GetWindowsDirectoryW(WindowsDirectory, NUMBER_OF(WindowsDirectory) - 64);
  5238. {
  5239. const WCHAR SubFunction[] = L"CreateActCtx";
  5240. CHandleSnapshots handleSnapshots;
  5241. handleSnapshots.Begin();
  5242. Trace("%s Begin %ls : %Id handles\n", __FUNCTION__, SubFunction, handleSnapshots.m_Begin.size());
  5243. {
  5244. WCHAR WindowsShellManifestFileName[MAX_PATH];
  5245. ACTCTXW ActCtx = { sizeof(ActCtx) };
  5246. HANDLE ActCtxHandle = 0;
  5247. WindowsShellManifestFileName[0] = 0;
  5248. wcscpy(WindowsShellManifestFileName, WindowsDirectory);
  5249. wcscat(WindowsShellManifestFileName, L"\\WindowsShell.Manifest");
  5250. ActCtx.lpSource = WindowsShellManifestFileName;
  5251. for (i = 0 ; i != 100 ; ++i)
  5252. {
  5253. HANDLE ActCtxHandle = CreateActCtxW(&ActCtx);
  5254. if (ActCtxHandle == INVALID_HANDLE_VALUE)
  5255. Trace("TestCreateActctxWindowsShellManifest: %p, %lu\n", ActCtxHandle, ::GetLastError());
  5256. else
  5257. ReleaseActCtx(ActCtxHandle);
  5258. }
  5259. }
  5260. handleSnapshots.End();
  5261. Trace("%s End %ls : %Id handles\n", __FUNCTION__, SubFunction, handleSnapshots.m_End.size());
  5262. if (handleSnapshots.m_Diff.size() != 0)
  5263. {
  5264. Trace("%s Diff %ls : %Id handles\n", __FUNCTION__, SubFunction, handleSnapshots.m_Diff.size());
  5265. }
  5266. }
  5267. Pause();
  5268. {
  5269. const WCHAR SubFunction[] = L"CreateActCtx + LoadLibrary(comctl32)";
  5270. CHandleSnapshots handleSnapshots;
  5271. handleSnapshots.Begin();
  5272. Trace("%s Begin %ls : %Id handles\n", __FUNCTION__, SubFunction, handleSnapshots.m_Begin.size());
  5273. {
  5274. WCHAR WindowsShellManifestFileName[MAX_PATH];
  5275. ACTCTXW ActCtx = { sizeof(ActCtx) };
  5276. HANDLE ActCtxHandle = 0;
  5277. WindowsShellManifestFileName[0] = 0;
  5278. wcscpy(WindowsShellManifestFileName, WindowsDirectory);
  5279. wcscat(WindowsShellManifestFileName, L"\\WindowsShell.Manifest");
  5280. ActCtx.lpSource = WindowsShellManifestFileName;
  5281. for (i = 0 ; i != 100 ; ++i)
  5282. {
  5283. ULONG_PTR ulCookie = 0;
  5284. HANDLE ActCtxHandle = CreateActCtxW(&ActCtx);
  5285. if (ActCtxHandle == INVALID_HANDLE_VALUE)
  5286. Trace("TestCreateActctxWindowsShellManifest: %p, %lu\n", ActCtxHandle, ::GetLastError());
  5287. else
  5288. {
  5289. ActivateActCtx(ActCtxHandle, &ulCookie);
  5290. HMODULE Comctl = LoadLibraryW(L"comctl32.dll");
  5291. if (i == 1)
  5292. {
  5293. CHandleSnapshot handleSnapshot;
  5294. handleSnapshot.GetHandlesForCurrentProcess();
  5295. Trace("Comctl32.dll loaded first time %Id\n", handleSnapshot.size());
  5296. Pause();
  5297. }
  5298. FreeLibrary(Comctl);
  5299. if (i == 1)
  5300. {
  5301. CHandleSnapshot handleSnapshot;
  5302. handleSnapshot.GetHandlesForCurrentProcess();
  5303. Trace("Comctl32.dll unloaded first time %Id\n", handleSnapshot.size());
  5304. Pause();
  5305. }
  5306. if (ulCookie != 0)
  5307. DeactivateActCtx(0, ulCookie);
  5308. ReleaseActCtx(ActCtxHandle);
  5309. if (i == 1)
  5310. {
  5311. CHandleSnapshot handleSnapshot;
  5312. handleSnapshot.GetHandlesForCurrentProcess();
  5313. Trace("Comctl32.dll unloaded + ReleaseActCtxfirst time %Id\n", handleSnapshot.size());
  5314. Pause();
  5315. }
  5316. }
  5317. }
  5318. }
  5319. handleSnapshots.End();
  5320. Trace("%s End %ls : %Id handles\n", __FUNCTION__, SubFunction, handleSnapshots.m_End.size());
  5321. if (handleSnapshots.m_Diff.size() != 0)
  5322. {
  5323. Trace("%s Diff %ls : %Id handles\n", __FUNCTION__, SubFunction, handleSnapshots.m_Diff.size());
  5324. }
  5325. }
  5326. Pause();
  5327. {
  5328. WCHAR Me[MAX_PATH];
  5329. STARTUPINFOW StartupInfo = {sizeof(StartupInfo)};
  5330. PROCESS_INFORMATION ProcessInfo = {0};
  5331. static const WCHAR SubFunction[] = L"CreateProcess";
  5332. Kernel32.GetModuleFileNameW(NULL, Me, NUMBER_OF(Me));
  5333. CHandleSnapshots handleSnapshots;
  5334. handleSnapshots.Begin();
  5335. Trace("%s Begin %ls : %Id handles\n", __FUNCTION__, SubFunction, handleSnapshots.m_Begin.size());
  5336. for (i = 0 ; i != 100 ; ++i)
  5337. {
  5338. StartupInfo.hStdOutput = DevNull;
  5339. StartupInfo.hStdError = DevNull;
  5340. StartupInfo.dwFlags = STARTF_USESTDHANDLES;
  5341. if (!CreateProcessW(Me, NULL, NULL, NULL, FALSE, 0, NULL, NULL, &StartupInfo, &ProcessInfo))
  5342. {
  5343. Trace("CreateProcess failed %ld\n", ::GetLastError());
  5344. }
  5345. else
  5346. {
  5347. WaitForSingleObject(ProcessInfo.hProcess, INFINITE);
  5348. WaitForSingleObject(ProcessInfo.hThread, INFINITE);
  5349. if (!CloseHandle(ProcessInfo.hProcess))
  5350. Trace("CloseHandle(Process %p) failed %ld\n", ProcessInfo.hProcess, ::GetLastError());
  5351. if (!CloseHandle(ProcessInfo.hThread))
  5352. Trace("CloseHandle(Thread %p) failed %ld\n", ProcessInfo.hThread, ::GetLastError());
  5353. }
  5354. }
  5355. handleSnapshots.End();
  5356. Trace("%s End %ls : %Id handles\n", __FUNCTION__, SubFunction, handleSnapshots.m_End.size());
  5357. if (handleSnapshots.m_Diff.size() != 0)
  5358. {
  5359. Trace("%s Diff %ls : %Id handles\n", __FUNCTION__, SubFunction, handleSnapshots.m_Diff.size());
  5360. }
  5361. }
  5362. Pause();
  5363. {
  5364. WCHAR SubFunction[sizeof("LoadLibrary xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx")];
  5365. WCHAR DllPath[MAX_PATH];
  5366. ULONG j = 0;
  5367. const static PCWSTR Leaves[] = {
  5368. L"mshtml.dll",
  5369. L"wintrust.dll",
  5370. L"shell32.dll",
  5371. L"crypt32.dll",
  5372. L"msxml.dll",
  5373. L"shdocvw.dll",
  5374. L"msxml2.dll",
  5375. L"msxml3.dll"
  5376. };
  5377. for (j = 0 ; j != NUMBER_OF(Leaves) ; ++j)
  5378. {
  5379. SubFunction[0] = 0;
  5380. wcscat(SubFunction, L"LoadLibrary ");
  5381. wcscat(SubFunction, Leaves[j]);
  5382. DllPath[0] = 0;
  5383. wcscat(DllPath, WindowsDirectory);
  5384. wcscat(DllPath, L"\\system32\\");
  5385. wcscat(DllPath, Leaves[j]);
  5386. CHandleSnapshots handleSnapshots;
  5387. handleSnapshots.Begin();
  5388. Trace("%s Begin %ls : %Id handles\n", __FUNCTION__, SubFunction, handleSnapshots.m_Begin.size());
  5389. for (i = 0 ; i != 20 ; ++i)
  5390. {
  5391. HMODULE DllHandle;
  5392. if ((DllHandle = LoadLibraryW(DllPath)) != NULL)
  5393. FreeLibrary(DllHandle);
  5394. else
  5395. Trace("LoadLibraryW(%ls) failed %ld\n", DllPath, ::GetLastError());
  5396. }
  5397. handleSnapshots.End();
  5398. Trace("%s End %ls : %Id handles\n", __FUNCTION__, SubFunction, handleSnapshots.m_End.size());
  5399. if (handleSnapshots.m_Diff.size() != 0)
  5400. {
  5401. Trace("%s Diff %s : %Id handles\n", __FUNCTION__, SubFunction, handleSnapshots.m_Diff.size());
  5402. }
  5403. }
  5404. }
  5405. Pause();
  5406. #endif
  5407. }
  5408. #define YET_ANOTHER_PASTE(x,y) x##y
  5409. #define YET_YET_ANOTHER_PASTE(x,y) YET_ANOTHER_PASTE(x,y)
  5410. #define LSXS_PROCESSOR_ARCHITECTURE YET_YET_ANOTHER_PASTE(L, SXS_PROCESSOR_ARCHITECTURE)
  5411. const WCHAR ToolsCrtManifest[]=
  5412. L"<?xml version=\"1.0\" standalone=\"yes\"?>"
  5413. L"<assembly xmlns=\"urn:schemas-microsoft-com:asm.v1\" manifestVersion=\"1.0\">"
  5414. L"<assemblyIdentity"
  5415. L" name=\"Microsoft.Windows.SxsTest.ToolsCrtClient\""
  5416. L" processorArchitecture=\"" LSXS_PROCESSOR_ARCHITECTURE L"\"" /* Note that this only actually exists on x86 */
  5417. L" version=\"5.1.0.0\""
  5418. L" type=\"win32\"/>"
  5419. L"<dependency>"
  5420. L" <dependentAssembly>"
  5421. L" <assemblyIdentity"
  5422. L" type=\"win32\""
  5423. L" name=\"Microsoft.Tools.VisualCPlusPlus.Runtime-Libraries\""
  5424. L" version=\"6.0.0.0\""
  5425. L" processorArchitecture=\"" LSXS_PROCESSOR_ARCHITECTURE L"\""
  5426. L" publicKeyToken=\"6595b64144ccf1df\""
  5427. L" language=\"*\""
  5428. L" />"
  5429. L" </dependentAssembly>"
  5430. L"</dependency>"
  5431. L"</assembly>"
  5432. ;
  5433. const WCHAR WindowsCrtManifest[]=
  5434. L"<?xml version=\"1.0\" standalone=\"yes\"?>"
  5435. L"<assembly xmlns=\"urn:schemas-microsoft-com:asm.v1\" manifestVersion=\"1.0\">"
  5436. L"<assemblyIdentity"
  5437. L" name=\"Microsoft.Windows.SxsTest.WindowsCrtClient\""
  5438. L" processorArchitecture=\"" LSXS_PROCESSOR_ARCHITECTURE L"\""
  5439. L" version=\"5.1.0.0\""
  5440. L" type=\"win32\"/>"
  5441. L"<dependency>"
  5442. L" <dependentAssembly>"
  5443. L" <assemblyIdentity"
  5444. L" type=\"win32\""
  5445. L" name=\"Microsoft.Windows.CPlusPlusRuntime\""
  5446. L" version=\"7.0.0.0\""
  5447. L" processorArchitecture=\"" LSXS_PROCESSOR_ARCHITECTURE L"\""
  5448. L" publicKeyToken=\"6595b64144ccf1df\""
  5449. L" language=\"*\""
  5450. L" />"
  5451. L" </dependentAssembly>"
  5452. L"</dependency>"
  5453. L"</assembly>"
  5454. ;
  5455. void TestCRuntimeAsms()
  5456. {
  5457. CFusionActCtxHandle WindowsCrtActCtxHandle;
  5458. CFusionActCtxHandle ToolsCrtActCtxHandle;
  5459. WindowsCrtActCtxHandle = ::CreateActivationContextFromStringW(WindowsCrtManifest);
  5460. if (WindowsCrtActCtxHandle == INVALID_HANDLE_VALUE)
  5461. ::Trace("CreateActCtx(WindowsCrtManifest %p) failed %ld\n", WindowsCrtManifest, ::GetLastError());
  5462. ToolsCrtActCtxHandle = ::CreateActivationContextFromStringW(ToolsCrtManifest);
  5463. if (ToolsCrtActCtxHandle == INVALID_HANDLE_VALUE)
  5464. ::Trace("CreateActCtx(WindowsCrtManifest %p) failed %ld\n", WindowsCrtManifest, ::GetLastError());
  5465. CFusionActCtxScope ToolsCrtActCtxScope;
  5466. CFusionActCtxScope WindowsCrtActCtxScope;
  5467. if (!WindowsCrtActCtxScope.Win32Activate(WindowsCrtActCtxHandle))
  5468. ::Trace("Activate(WindowsCrtActCtxHandle %p) failed %ld\n", WindowsCrtActCtxHandle, ::GetLastError());
  5469. if (!ToolsCrtActCtxScope.Win32Activate(ToolsCrtActCtxHandle))
  5470. ::Trace("Activate(ToolsCrtActCtxHandle %p) failed %ld\n", ToolsCrtActCtxHandle, ::GetLastError());
  5471. CStringBuffer MsvcrtBuffer;
  5472. CStringBuffer AtlBuffer;
  5473. //::SearchPathW();
  5474. }
  5475. /*
  5476. <comInterfaceExternalProxyStub
  5477. name="IPropertyPage"
  5478. iid="{B196B28D-BAB4-101A-B69C-00AA00341D07}"
  5479. proxyStubClsid32="{B196B286-BAB4-101A-B69C-00AA00341D07}"
  5480. numMethods="14"
  5481. baseInterface="{00000000-0000-0000-C000-000000000046}"
  5482. >
  5483. <comInterfaceExternalProxyStub
  5484. name="IPropertyPage2"
  5485. iid="{01E44665-24AC-101B-84ED-08002B2EC713}"
  5486. proxyStubClsid32="{B196B286-BAB4-101A-B69C-00AA00341D07}"
  5487. numMethods="15"
  5488. baseInterface="{B196B28D-BAB4-101A-B69C-00AA00341D07}"
  5489. >
  5490. <comInterfaceExternalProxyStub
  5491. name="IPropertyNotifySink"
  5492. iid="{9BFBBC02-EFF1-101A-84ED-00AA00341D07}"
  5493. proxyStubClsid32="{B196B286-BAB4-101A-B69C-00AA00341D07}"
  5494. baseInterface="{00000000-0000-0000-C000-00 00 00 00 00 46}"
  5495. numMethods="5"
  5496. >
  5497. */
  5498. BOOL Win32Append(
  5499. CBaseStringBuffer& s,
  5500. PCWSTR t
  5501. )
  5502. {
  5503. FN_PROLOG_WIN32
  5504. IFW32FALSE_EXIT(s.Win32Append(t, wcslen(t)));
  5505. FN_EPILOG
  5506. }
  5507. typedef struct _FUSIONTESTP_REG_DATA
  5508. {
  5509. #define FUSIONTESTP_REG_TYPE_INTERFACE (1)
  5510. #define FUSIONTESTP_REG_TYPE_CLASS (2)
  5511. ULONG Type;
  5512. PCWSTR Name; // for debugging/tracing purposes (should coincide with InterfaceName)
  5513. PCWSTR Guid;
  5514. union
  5515. {
  5516. struct
  5517. {
  5518. WCHAR InprocServerFilePath[MAX_PATH];
  5519. WCHAR ThreadingModel[64];
  5520. };
  5521. struct
  5522. {
  5523. WCHAR InterfaceName[MAX_PATH];
  5524. WCHAR NumMethods[64];
  5525. WCHAR ProxyStubClsid[64];
  5526. //
  5527. // These usually aren't provided.
  5528. //
  5529. // WCHAR BaseInterface[64];
  5530. // WCHAR OLEViewerIViewerCLSID[64];
  5531. //
  5532. };
  5533. };
  5534. #define FUSIONTESTP_REG_ROOT_CURRENT_USER (1)
  5535. #define FUSIONTESTP_REG_ROOT_LOCAL_MACHINE (2)
  5536. #define FUSIONTESTP_REG_ROOT_CLASSES_ROOT (3)
  5537. ULONG Root;
  5538. //
  5539. // It is perhaps a bit inelegant to put this data here, perhaps not..
  5540. // We are deliberately a bit sloppy on the refcounting of these right now.
  5541. //
  5542. //#define FUSIONTESTP_PLAIN_COM_POINTER(t) CSmartRef<t>
  5543. #define FUSIONTESTP_PLAIN_COM_POINTER(t) t*
  5544. //#define FUSIONTESTP_PLAIN_COM_POINTER(t) void*
  5545. FUSIONTESTP_PLAIN_COM_POINTER(IUnknown) CoCreatedObject;
  5546. //FUSIONTESTP_PLAIN_COM_POINTER(IUnknown) InterfaceIntoObjectInCreatingThread;
  5547. //FUSIONTESTP_PLAIN_COM_POINTER(IUnknown) InterfaceIntoObjectInAnotherThread;
  5548. //WCHAR ModulePathInOtherThread[MAX_PATH]; // expected to be oleaut32.dll, but possibly already unloaded
  5549. //IID InterfaceIdOfObject;
  5550. DWORD GlobalInterfaceTableCookie;
  5551. } FUSIONTESTP_REG_DATA, *PFUSIONTESTP_REG_DATA;
  5552. typedef const FUSIONTESTP_REG_DATA* PCFUSIONTESTP_REG_DATA;
  5553. #define OLEAUT_MARSHALER_CLSID_STRING L"{B196B286-BAB4-101A-B69C-00AA00341D07}"
  5554. FUSIONTESTP_REG_DATA FusionTestpMfcRegData[] =
  5555. {
  5556. { FUSIONTESTP_REG_TYPE_CLASS, L"Font Property Page", L"{0BE35200-8F91-11CE-9DE3-00AA004BB851}" },
  5557. { FUSIONTESTP_REG_TYPE_CLASS, L"Color Property Page", L"{0BE35201-8F91-11CE-9DE3-00AA004BB851}" },
  5558. { FUSIONTESTP_REG_TYPE_CLASS, L"Picture Property Page", L"{0BE35202-8F91-11CE-9DE3-00AA004BB851}" },
  5559. { FUSIONTESTP_REG_TYPE_INTERFACE, L"IPropertyPage", L"{B196B28D-BAB4-101A-B69C-00AA00341D07}" },
  5560. { FUSIONTESTP_REG_TYPE_INTERFACE, L"IPropertyPage2", L"{01E44665-24AC-101B-84ED-08002B2EC713}" },
  5561. { FUSIONTESTP_REG_TYPE_INTERFACE, L"IPropertyNotifySink", L"{9BFBBC02-EFF1-101A-84ED-00AA00341D07}" },
  5562. // Leave this registered, since the manifest does not specify a file.
  5563. //{ FUSIONTESTP_REG_TYPE_CLASS, L"oleaut32 marshaller (PSFactoryBuffer)", OLEAUT_MARSHALER_CLSID_STRING }
  5564. };
  5565. FUSIONTESTP_REG_DATA FusionTestpAtlRegData[1];
  5566. const HKEY FusionTestpHkeyRoots[] = { NULL, HKEY_CURRENT_USER, HKEY_LOCAL_MACHINE, HKEY_CLASSES_ROOT };
  5567. const PCWSTR FusionTestpClassStringRoots[] = { NULL, L"Software\\Classes\\CLSID\\", L"Software\\Classes\\CLSID\\", L"CLSID\\" };
  5568. const PCWSTR FusionTestpInterfaceStringRoots[] = { NULL, L"Software\\Classes\\Interface\\", L"Software\\Classes\\Interface\\", L"Interface\\" };
  5569. const PCWSTR* FusionTestpStringRoots[] = { NULL, FusionTestpInterfaceStringRoots, FusionTestpClassStringRoots};
  5570. #define FUSIONTESTP_REG_DELETE (1)
  5571. #define FUSIONTESTP_REG_RESTORE (2)
  5572. #define FUSIONTESTP_REG_BACKUP (3)
  5573. BOOL FusionTestpEnumerateRegistryData(FUSIONTESTP_REG_DATA* RegData, ULONG Count, ULONG Mode)
  5574. {
  5575. BOOL Success = FALSE;
  5576. FN_PROLOG_WIN32(Success);
  5577. for (ULONG i = 0 ; i != Count ; i += 1)
  5578. {
  5579. FUSIONTESTP_REG_DATA* const p = &RegData[i];
  5580. ULONG MinRoot = 0;
  5581. ULONG MaxRoot = 0;
  5582. switch (Mode)
  5583. {
  5584. case FUSIONTESTP_REG_RESTORE:
  5585. case FUSIONTESTP_REG_DELETE:
  5586. MinRoot = p->Root;
  5587. if (MinRoot == 0)
  5588. continue;
  5589. MaxRoot = MinRoot;
  5590. break;
  5591. case FUSIONTESTP_REG_BACKUP:
  5592. MinRoot = 1;
  5593. MaxRoot = 3;
  5594. break;
  5595. }
  5596. //
  5597. // It'd be nice if you could embed the if within a switch..
  5598. //
  5599. for (ULONG root = MinRoot ; root <= MaxRoot ; root += 1)
  5600. {
  5601. CFusionRegKey regKey;
  5602. CFusionRegKey inprocServerKey;
  5603. CStringBuffer stringBuffer;
  5604. CFusionRegKey numMethodsKey;
  5605. CFusionRegKey proxyStubClsidKey;
  5606. DWORD dwSize = 0;
  5607. DWORD dwType = 0;
  5608. CFusionRegKey rootKey(FusionTestpHkeyRoots[root]);
  5609. IFW32FALSE_EXIT(Win32Append(stringBuffer, FusionTestpStringRoots[p->Type][root]));
  5610. IFW32FALSE_EXIT(Win32Append(stringBuffer, p->Guid));
  5611. switch (Mode)
  5612. {
  5613. case FUSIONTESTP_REG_DELETE:
  5614. case FUSIONTESTP_REG_BACKUP:
  5615. rootKey.OpenSubKey(regKey, stringBuffer);
  5616. break;
  5617. case FUSIONTESTP_REG_RESTORE:
  5618. IFW32FALSE_EXIT(rootKey.OpenOrCreateSubKey(regKey, stringBuffer));
  5619. break;
  5620. }
  5621. if (regKey != regKey.GetInvalidValue())
  5622. {
  5623. switch (Mode)
  5624. {
  5625. case FUSIONTESTP_REG_BACKUP:
  5626. p->Root = root;
  5627. break;
  5628. case FUSIONTESTP_REG_DELETE:
  5629. case FUSIONTESTP_REG_RESTORE:
  5630. break;
  5631. }
  5632. switch (p->Type)
  5633. {
  5634. case FUSIONTESTP_REG_TYPE_CLASS:
  5635. switch (Mode)
  5636. {
  5637. case FUSIONTESTP_REG_BACKUP:
  5638. #define FusionTestpQueryRegString(hkey, name, value) \
  5639. do { dwSize = sizeof(value); \
  5640. RegQueryValueExW(hkey, name, NULL, &dwType, reinterpret_cast<BYTE*>(value), &dwSize); \
  5641. } while(false)
  5642. if (regKey.OpenSubKey(inprocServerKey, L"InprocServer32"))
  5643. {
  5644. FusionTestpQueryRegString(inprocServerKey, NULL, p->InprocServerFilePath);
  5645. FusionTestpQueryRegString(inprocServerKey, L"ThreadingModel", p->ThreadingModel);
  5646. }
  5647. break;
  5648. case FUSIONTESTP_REG_RESTORE:
  5649. if (regKey.OpenOrCreateSubKey(inprocServerKey, L"InprocServer32"))
  5650. {
  5651. #define FusionTestpRegStringSize(x) static_cast<ULONG>(((wcslen(x) + 1)*sizeof((x)[0])))
  5652. #define FusionTestpSetRegString(hkey, name, value) \
  5653. do { if (value[0] != 0) \
  5654. RegSetValueExW(hkey, name, NULL, REG_SZ, reinterpret_cast<const BYTE*>(value), FusionTestpRegStringSize(value)); \
  5655. } while(false)
  5656. FusionTestpSetRegString(inprocServerKey, NULL, p->InprocServerFilePath);
  5657. FusionTestpSetRegString(inprocServerKey, L"ThreadingModel", p->ThreadingModel);
  5658. }
  5659. break;
  5660. case FUSIONTESTP_REG_DELETE:
  5661. break;
  5662. }
  5663. break;
  5664. case FUSIONTESTP_REG_TYPE_INTERFACE:
  5665. switch (Mode)
  5666. {
  5667. case FUSIONTESTP_REG_BACKUP:
  5668. FusionTestpQueryRegString(regKey, NULL, p->InterfaceName);
  5669. if (regKey.OpenSubKey(numMethodsKey, L"NumMethods"))
  5670. FusionTestpQueryRegString(numMethodsKey, NULL, p->NumMethods);
  5671. if (regKey.OpenSubKey(proxyStubClsidKey, L"ProxyStubClsid32"))
  5672. FusionTestpQueryRegString(proxyStubClsidKey, NULL, p->ProxyStubClsid);
  5673. break;
  5674. case FUSIONTESTP_REG_RESTORE:
  5675. FusionTestpSetRegString(regKey, NULL, p->InterfaceName);
  5676. if (regKey.OpenOrCreateSubKey(numMethodsKey, L"NumMethods"))
  5677. FusionTestpSetRegString(numMethodsKey, NULL, p->NumMethods);
  5678. if (regKey.OpenOrCreateSubKey(proxyStubClsidKey, L"ProxyStubClsid32"))
  5679. FusionTestpSetRegString(proxyStubClsidKey, NULL, p->ProxyStubClsid);
  5680. case FUSIONTESTP_REG_DELETE:
  5681. break;
  5682. }
  5683. break;
  5684. }
  5685. switch (Mode)
  5686. {
  5687. case FUSIONTESTP_REG_DELETE:
  5688. regKey.DestroyKeyTree();
  5689. break;
  5690. case FUSIONTESTP_REG_BACKUP:
  5691. case FUSIONTESTP_REG_RESTORE:
  5692. break;
  5693. }
  5694. break;
  5695. }
  5696. }
  5697. }
  5698. FN_EPILOG
  5699. }
  5700. HMODULE FusionTestpHmoduleFromComObject(IUnknown* unk)
  5701. {
  5702. void** ppv = reinterpret_cast<void**>(unk);
  5703. void* pv = *ppv;
  5704. MEMORY_BASIC_INFORMATION MemBasicInfo = { 0 };
  5705. SIZE_T dw = 0;
  5706. if ((dw = Kernel32.VirtualQuery(pv, &MemBasicInfo, sizeof(MemBasicInfo))) == 0
  5707. || (dw < RTL_SIZEOF_THROUGH_FIELD(MEMORY_BASIC_INFORMATION, BaseAddress)))
  5708. {
  5709. ::Trace("VirtualQuery(%p) failed %lu\n", pv, ::GetLastError());
  5710. return NULL;
  5711. }
  5712. return reinterpret_cast<HMODULE>(MemBasicInfo.AllocationBase);
  5713. }
  5714. DWORD WINAPI FusionTestpMfcCreateAndMarshalThreadMain(LPVOID pvShouldBeAbleToMarshal)
  5715. {
  5716. BOOL Success = FALSE;
  5717. FN_PROLOG_WIN32(Success);
  5718. HRESULT hr = 0;
  5719. const bool ShouldBeAbleToMarshal = (pvShouldBeAbleToMarshal != NULL ? true : false);
  5720. Ole32.CoInitialize(NULL);
  5721. //
  5722. // For each interface, make sure we can unmarshal at least one object.
  5723. //
  5724. for (ULONG InterfaceIndex = 0 ; InterfaceIndex != NUMBER_OF(::FusionTestpMfcRegData) ; InterfaceIndex += 1)
  5725. {
  5726. FUSIONTESTP_REG_DATA* const pi = &::FusionTestpMfcRegData[InterfaceIndex];
  5727. switch (pi->Type)
  5728. {
  5729. case FUSIONTESTP_REG_TYPE_CLASS:
  5730. continue;
  5731. case FUSIONTESTP_REG_TYPE_INTERFACE:
  5732. IID InterfaceId = { 0 };
  5733. FUSIONTESTP_PLAIN_COM_POINTER(IUnknown) InterfaceIntoObjectInAnotherThread = NULL;
  5734. IFCOMFAILED_EXIT(hr = Ole32.IIDFromString(const_cast<PWSTR>(pi->Guid), &InterfaceId));
  5735. // nested loop..
  5736. for (ULONG ClassIndex = 0 ;
  5737. ClassIndex != NUMBER_OF(::FusionTestpMfcRegData) ;
  5738. ClassIndex += 1)
  5739. {
  5740. CLSID ClassId = { 0 };
  5741. FUSIONTESTP_REG_DATA* const pc = &::FusionTestpMfcRegData[ClassIndex];
  5742. switch (pc->Type)
  5743. {
  5744. case FUSIONTESTP_REG_TYPE_INTERFACE:
  5745. continue;
  5746. case FUSIONTESTP_REG_TYPE_CLASS:
  5747. WCHAR ModulePathInOtherThread[MAX_PATH];
  5748. ModulePathInOtherThread[0] = 0;
  5749. ASSERT(pc->GlobalInterfaceTableCookie != 0);
  5750. IFCOMFAILED_EXIT(hr = Ole32.CLSIDFromString(const_cast<PWSTR>(pc->Guid), &ClassId));
  5751. hr = g.GlobalInterfaceTable->GetInterfaceFromGlobal(
  5752. pc->GlobalInterfaceTableCookie, InterfaceId,
  5753. reinterpret_cast<void**>(&InterfaceIntoObjectInAnotherThread));
  5754. if (SUCCEEDED(hr))
  5755. {
  5756. IFW32FALSE_EXIT(Kernel32.GetModuleFileNameW(
  5757. ::FusionTestpHmoduleFromComObject(InterfaceIntoObjectInAnotherThread),
  5758. ModulePathInOtherThread, NUMBER_OF(ModulePathInOtherThread)));
  5759. }
  5760. if (SUCCEEDED(hr) && ShouldBeAbleToMarshal)
  5761. {
  5762. Trace("%s SUCCESSfully marshaled interface %ls on class %ls using proxy/stub in %ls\n",
  5763. __FUNCTION__, pi->Name, pc->Name, ModulePathInOtherThread);
  5764. g.Successes += 1;
  5765. }
  5766. else if (SUCCEEDED(hr) && !ShouldBeAbleToMarshal)
  5767. {
  5768. // unexpected success -> ERROR
  5769. Trace("%s FAILED to fail to marshal interface %ls on class %ls (using proxy/stub in %ls)\n",
  5770. __FUNCTION__, pi->Name, pc->Name, ModulePathInOtherThread);
  5771. g.Failures += 1;
  5772. }
  5773. else if (FAILED(hr) && ShouldBeAbleToMarshal)
  5774. {
  5775. // keep looping, try other objects
  5776. }
  5777. else if (FAILED(hr) && !ShouldBeAbleToMarshal)
  5778. {
  5779. // keep looping, make sure none succeed
  5780. //::Trace("%s OK Unable to marshal interface %ls (%ls) 0x%lx (fac 0x%lx code 0x%lx)\n", __FUNCTION__, pi->Name, pi->Guid, hr, HRESULT_FACILITY(hr), HRESULT_CODE(hr));
  5781. }
  5782. break;
  5783. }
  5784. if (InterfaceIntoObjectInAnotherThread != NULL && ShouldBeAbleToMarshal)
  5785. {
  5786. // one successful unmarshal is enough
  5787. break;
  5788. }
  5789. }
  5790. // use the nullness of InterfaceIntoObjectInAnotherThread as a summary of the loop
  5791. if (InterfaceIntoObjectInAnotherThread == NULL && ShouldBeAbleToMarshal)
  5792. {
  5793. ::Trace("%s FAILURE Unable to marshal interface %ls (%ls)\n", __FUNCTION__, pi->Name, pi->Guid);
  5794. g.Failures += 1;
  5795. }
  5796. else if (InterfaceIntoObjectInAnotherThread == NULL && !ShouldBeAbleToMarshal)
  5797. {
  5798. ::Trace("%s GOOD Unable to marshal interface %ls without actctx as expected\n", __FUNCTION__, pi->Name);
  5799. g.Successes += 1;
  5800. }
  5801. break;
  5802. }
  5803. }
  5804. Ole32.CoUninitialize();
  5805. FN_EPILOG
  5806. }
  5807. BOOL TestMfcCreateAndMarshal()
  5808. {
  5809. BOOL Success = FALSE;
  5810. FN_PROLOG_WIN32(Success);
  5811. ULONG i = 0;
  5812. HRESULT hr = 0;
  5813. HANDLE ThreadHandle = 0;
  5814. DWORD Ignored = 0;
  5815. CFusionActCtxHandle ToolsCrtActCtxHandle;
  5816. ::FusionTestpEnumerateRegistryData(::FusionTestpMfcRegData, NUMBER_OF(::FusionTestpMfcRegData), FUSIONTESTP_REG_BACKUP);
  5817. ::FusionTestpEnumerateRegistryData(::FusionTestpMfcRegData, NUMBER_OF(::FusionTestpMfcRegData), FUSIONTESTP_REG_DELETE);
  5818. Ole32.CoInitialize(NULL);
  5819. //
  5820. // Verify that we cannot create any of the classes.
  5821. //
  5822. for (i = 0 ; i != NUMBER_OF(::FusionTestpMfcRegData) ; i += 1)
  5823. {
  5824. CSmartRef<IUnknown> unk;
  5825. CLSID ClassId = { 0 };
  5826. FUSIONTESTP_REG_DATA* const p = &::FusionTestpMfcRegData[i];
  5827. switch (p->Type)
  5828. {
  5829. case FUSIONTESTP_REG_TYPE_INTERFACE:
  5830. break;
  5831. case FUSIONTESTP_REG_TYPE_CLASS:
  5832. IFCOMFAILED_EXIT(hr = Ole32.CLSIDFromString(const_cast<PWSTR>(p->Guid), &ClassId));
  5833. hr = Ole32.CoCreateInstance(ClassId, NULL, CLSCTX_INPROC_SERVER, IID_IUnknown, reinterpret_cast<void**>(&unk));
  5834. if (SUCCEEDED(hr))
  5835. {
  5836. ::Trace("%s BAD, no registry, no actctx CoCreate(%ls) SUCCEEDED, not expected\n", __FUNCTION__, p->Name);
  5837. g.Failures += 1;
  5838. }
  5839. else
  5840. {
  5841. ::Trace("%s GOOD, no registry, no actctx CoCreate(%ls) FAILed 0x%lx, as expected\n", __FUNCTION__, p->Name, hr);
  5842. g.Successes += 1;
  5843. }
  5844. break;
  5845. }
  5846. }
  5847. //
  5848. // Create and activate the context.
  5849. //
  5850. ToolsCrtActCtxHandle = ::CreateActivationContextFromStringW(ToolsCrtManifest);
  5851. if (ToolsCrtActCtxHandle == INVALID_HANDLE_VALUE)
  5852. ::Trace("CreateActCtx(WindowsCrtManifest %p) failed %ld\n", WindowsCrtManifest, ::GetLastError());
  5853. {
  5854. CFusionActCtxScope ToolsCrtActCtxScope;
  5855. if (!ToolsCrtActCtxScope.Win32Activate(ToolsCrtActCtxHandle))
  5856. ::Trace("Activate(ToolsCrtActCtxHandle %p) failed %ld\n", ToolsCrtActCtxHandle, ::GetLastError());
  5857. //
  5858. // Now create each class and print the .dll it came from.
  5859. // And put it in the global interface table for later unmarshalling.
  5860. //
  5861. IFCOMFAILED_EXIT(hr = Ole32.CoCreateInstance(CLSID_StdGlobalInterfaceTable,NULL, CLSCTX_INPROC_SERVER,
  5862. IID_IGlobalInterfaceTable, reinterpret_cast<void**>(&g.GlobalInterfaceTable)));
  5863. for (i = 0 ; i != NUMBER_OF(::FusionTestpMfcRegData) ; i += 1)
  5864. {
  5865. CLSID ClassId = { 0 };
  5866. FUSIONTESTP_REG_DATA* const p = &::FusionTestpMfcRegData[i];
  5867. //
  5868. // We are not supposed to be able to cocreate this here.
  5869. //
  5870. if (FusionpStrCmpI(p->Guid, OLEAUT_MARSHALER_CLSID_STRING) == 0)
  5871. continue;
  5872. switch (p->Type)
  5873. {
  5874. case FUSIONTESTP_REG_TYPE_INTERFACE:
  5875. break;
  5876. case FUSIONTESTP_REG_TYPE_CLASS:
  5877. IFCOMFAILED_EXIT(hr = Ole32.CLSIDFromString(const_cast<PWSTR>(p->Guid), &ClassId));
  5878. hr = Ole32.CoCreateInstance(ClassId, NULL, CLSCTX_INPROC_SERVER, IID_IUnknown,
  5879. reinterpret_cast<void**>(&p->CoCreatedObject));
  5880. if (FAILED(hr))
  5881. {
  5882. Trace("%s Failure: CoCreate(%ls) FAILED\n", __FUNCTION__, p->Name);
  5883. g.Failures += 1;
  5884. }
  5885. else
  5886. {
  5887. WCHAR ComObjectModule[MAX_PATH];
  5888. ComObjectModule[0] = 0;
  5889. IFW32FALSE_EXIT(Kernel32.GetModuleFileNameW(
  5890. ::FusionTestpHmoduleFromComObject(p->CoCreatedObject), ComObjectModule, NUMBER_OF(ComObjectModule)));
  5891. Trace("%s SUCCESSfully cocreated %p of type %ls from %ls with actctx influence\n",
  5892. __FUNCTION__, p->CoCreatedObject, p->Name, ComObjectModule);
  5893. g.Successes += 1;
  5894. //
  5895. // It'll still have to look for the proxy/stub at unmarshal time. This is fine.
  5896. //
  5897. IFCOMFAILED_EXIT(hr = g.GlobalInterfaceTable->RegisterInterfaceInGlobal(
  5898. p->CoCreatedObject,
  5899. IID_IUnknown,
  5900. &p->GlobalInterfaceTableCookie
  5901. ));
  5902. }
  5903. break;
  5904. }
  5905. }
  5906. }
  5907. {
  5908. CFusionActCtxScope ToolsCrtActCtxScope;
  5909. if (!ToolsCrtActCtxScope.Win32Activate(ToolsCrtActCtxHandle))
  5910. ::Trace("Activate(ToolsCrtActCtxHandle %p) failed %ld\n", ToolsCrtActCtxHandle, ::GetLastError());
  5911. //
  5912. // try marshalling with the actctx activated, it should work (not NULL => expected success==TRUE)
  5913. //
  5914. ThreadHandle = CreateThread(NULL, 0, FusionTestpMfcCreateAndMarshalThreadMain, &Ignored, 0, &Ignored);
  5915. CoWaitForMultipleHandles(0, INFINITE, 1, &ThreadHandle, &Ignored);
  5916. CloseHandle(ThreadHandle);
  5917. }
  5918. Ole32.CoUninitialize();
  5919. //::FusionTestpEnumerateRegistryData(::FusionTestpMfcRegData, NUMBER_OF(::FusionTestpMfcRegData), FUSIONTESTP_REG_RESTORE);
  5920. FN_EPILOG
  5921. }
  5922. void TestAtlCreate()
  5923. {
  5924. ::FusionTestpEnumerateRegistryData(FusionTestpAtlRegData, NUMBER_OF(FusionTestpAtlRegData), FUSIONTESTP_REG_BACKUP);
  5925. ::FusionTestpEnumerateRegistryData(FusionTestpAtlRegData, NUMBER_OF(FusionTestpAtlRegData), FUSIONTESTP_REG_DELETE);
  5926. ::FusionTestpEnumerateRegistryData(FusionTestpAtlRegData, NUMBER_OF(FusionTestpAtlRegData), FUSIONTESTP_REG_RESTORE);
  5927. }
  5928. BOOL TestPrivateSha1Impl(
  5929. PCWSTR pcwszDirName
  5930. )
  5931. {
  5932. FN_PROLOG_WIN32
  5933. CFusionArray<BYTE> rgbShaState;
  5934. CSmallStringBuffer sbHashedString;
  5935. CSmallStringBuffer sbFileName;
  5936. IFW32FALSE_EXIT(sbFileName.Win32Assign(pcwszDirName, ::wcslen(pcwszDirName)));
  5937. IFW32FALSE_EXIT(SxspCreateFileHash(0, CALG_SHA1, sbFileName, rgbShaState));
  5938. IFW32FALSE_EXIT(SxspHashBytesToString(rgbShaState.GetArrayPtr(), rgbShaState.GetSize(), sbHashedString));
  5939. wprintf(
  5940. L"%ls hashed via sxspcreatefilehash to %ls\r\n",
  5941. static_cast<PCWSTR>(sbFileName),
  5942. static_cast<PCWSTR>(sbHashedString));
  5943. FN_EPILOG
  5944. }
  5945. void TestAlignment()
  5946. {
  5947. CCleanupBase* p = reinterpret_cast<CCleanupBase*>(ULONG_PTR(0xffff0000));
  5948. SLIST_ENTRY* q = p;
  5949. printf("%p %Ix\n", q, ULONG_PTR(q) % 16);
  5950. }
  5951. void TestCreateActCtx_PE_flags0()
  5952. {
  5953. WCHAR SyssetupDll[MAX_PATH * 2];
  5954. ACTCTXW ActCtx = {sizeof(ActCtx)};
  5955. CFusionActCtxHandle ActCtxHandle;
  5956. GetSystemDirectoryW(SyssetupDll, MAX_PATH);
  5957. wcscat(SyssetupDll, L"\\syssetup.dll");
  5958. ActCtx.lpSource = SyssetupDll;
  5959. printf("%s\n", ActCtxHandle.Win32Create(&ActCtx) ? "true" : "false");
  5960. }
  5961. void
  5962. TestUninstall(
  5963. PCWSTR ManifestPath,
  5964. PCWSTR ReferenceString
  5965. )
  5966. {
  5967. SXS_UNINSTALLW UninstallParameters = {sizeof(UninstallParameters)};
  5968. SXS_INSTALL_REFERENCEW Reference = {sizeof(Reference)};
  5969. DWORD Disposition = 0;
  5970. BOOL Success = FALSE;
  5971. CFusionArray<BYTE> ManifestInformationBuffer;
  5972. if (!ManifestInformationBuffer.Win32SetSize(1UL << 16))
  5973. return;
  5974. const PSXS_MANIFEST_INFORMATION_BASIC ManifestBasicInfo = reinterpret_cast<PSXS_MANIFEST_INFORMATION_BASIC>(&ManifestInformationBuffer[0]);
  5975. LoadSxs();
  5976. Success = (*g_pfnQueryManifestInformation)(0, ManifestPath,
  5977. SXS_QUERY_MANIFEST_INFORMATION_INFOCLASS_BASIC, 0, ManifestInformationBuffer.GetSize(),
  5978. ManifestBasicInfo, NULL);
  5979. printf("QueryManifestInformation(%ls)->(%ls, %ls)\n", ManifestPath, ManifestBasicInfo->lpIdentity, ManifestBasicInfo->lpShortName);
  5980. UninstallParameters.dwFlags |= SXS_UNINSTALL_FLAG_REFERENCE_VALID;
  5981. UninstallParameters.lpInstallReference = &Reference;
  5982. UninstallParameters.lpAssemblyIdentity = ManifestBasicInfo->lpIdentity;
  5983. Reference.lpIdentifier = ReferenceString;
  5984. Reference.guidScheme = SXS_INSTALL_REFERENCE_SCHEME_OPAQUESTRING;
  5985. Success = (*g_pfnSxsUninstallW)(&UninstallParameters, &Disposition);
  5986. printf("TestUninstall(%ls, %ls) : %s, 0x%lx\n", ManifestPath, ReferenceString, Success ? "true" : "false", Disposition);
  5987. }
  5988. BOOL
  5989. TestNewSxsInstallAPI(
  5990. PCWSTR pcwszManifest
  5991. )
  5992. {
  5993. BOOL fSuccess = FALSE;
  5994. SXS_INSTALLW Info = {sizeof(Info)};
  5995. SXS_INSTALL_REFERENCEW Reference = {sizeof(Reference)};
  5996. SXS_UNINSTALLW Uninstall = {sizeof(Uninstall)};
  5997. DWORD dwDisposition;
  5998. Info.dwFlags = SXS_INSTALL_FLAG_REPLACE_EXISTING |
  5999. SXS_INSTALL_FLAG_REFERENCE_VALID |
  6000. SXS_INSTALL_FLAG_CODEBASE_URL_VALID |
  6001. SXS_INSTALL_FLAG_LOG_FILE_NAME_VALID;
  6002. Info.lpManifestPath = pcwszManifest;
  6003. Info.lpCodebaseURL = Info.lpManifestPath;
  6004. Info.lpReference = &Reference;
  6005. Info.lpLogFileName = L"c:\\thelogfile";
  6006. DWORD dwAttribute = ::GetFileAttributesW(pcwszManifest);
  6007. if ( dwAttribute == 0xffffffff) // non-exist
  6008. goto Exit;
  6009. if ( dwAttribute & FILE_ATTRIBUTE_DIRECTORY) // install from a directory recursively
  6010. {
  6011. Info.dwFlags |= SXS_INSTALL_FLAG_FROM_DIRECTORY_RECURSIVE;
  6012. }
  6013. Reference.guidScheme = SXS_INSTALL_REFERENCE_SCHEME_OPAQUESTRING;
  6014. Reference.lpIdentifier = L"Sxs installation";
  6015. // init the log file
  6016. if (::GetFileAttributesW(Info.lpLogFileName) != (DWORD)(-1))
  6017. {
  6018. ::DeleteFileW(Info.lpLogFileName);
  6019. }
  6020. LoadSxs();
  6021. if (!(*g_pfnSxsInstallW)(&Info))
  6022. {
  6023. goto Exit;
  6024. }
  6025. Uninstall.dwFlags = SXS_UNINSTALL_FLAG_USE_INSTALL_LOG;
  6026. Uninstall.lpInstallLogFile = L"c:\\thelogfile";
  6027. if (!(*g_pfnSxsUninstallW)(&Uninstall, &dwDisposition))
  6028. {
  6029. goto Exit;
  6030. }
  6031. fSuccess = TRUE;
  6032. Exit:
  6033. if (!fSuccess)
  6034. {
  6035. fprintf(stderr, "%s failed!\n", __FUNCTION__);
  6036. return EXIT_FAILURE;
  6037. }
  6038. else
  6039. return EXIT_SUCCESS;
  6040. }
  6041. void DumpXmlErrors()
  6042. {
  6043. #define ENTRY(x) printf("%s 0x%lx\n", #x, x);
  6044. ENTRY(XML_E_PARSEERRORBASE)
  6045. ENTRY(XML_E_ENDOFINPUT)
  6046. ENTRY(XML_E_MISSINGEQUALS)
  6047. ENTRY(XML_E_MISSINGQUOTE)
  6048. ENTRY(XML_E_COMMENTSYNTAX)
  6049. ENTRY(XML_E_BADSTARTNAMECHAR)
  6050. ENTRY(XML_E_BADNAMECHAR)
  6051. ENTRY(XML_E_BADCHARINSTRING)
  6052. ENTRY(XML_E_XMLDECLSYNTAX)
  6053. ENTRY(XML_E_BADCHARDATA)
  6054. ENTRY(XML_E_MISSINGWHITESPACE)
  6055. ENTRY(XML_E_EXPECTINGTAGEND)
  6056. ENTRY(XML_E_BADCHARINDTD)
  6057. ENTRY(XML_E_BADCHARINDECL)
  6058. ENTRY(XML_E_MISSINGSEMICOLON)
  6059. ENTRY(XML_E_BADCHARINENTREF)
  6060. ENTRY(XML_E_UNBALANCEDPAREN)
  6061. ENTRY(XML_E_EXPECTINGOPENBRACKET)
  6062. ENTRY(XML_E_BADENDCONDSECT)
  6063. ENTRY(XML_E_INTERNALERROR)
  6064. ENTRY(XML_E_UNEXPECTED_WHITESPACE)
  6065. ENTRY(XML_E_INCOMPLETE_ENCODING)
  6066. ENTRY(XML_E_BADCHARINMIXEDMODEL)
  6067. ENTRY(XML_E_MISSING_STAR)
  6068. ENTRY(XML_E_BADCHARINMODEL)
  6069. ENTRY(XML_E_MISSING_PAREN)
  6070. ENTRY(XML_E_BADCHARINENUMERATION)
  6071. ENTRY(XML_E_PIDECLSYNTAX)
  6072. ENTRY(XML_E_EXPECTINGCLOSEQUOTE)
  6073. ENTRY(XML_E_MULTIPLE_COLONS)
  6074. ENTRY(XML_E_INVALID_DECIMAL)
  6075. ENTRY(XML_E_INVALID_HEXIDECIMAL)
  6076. ENTRY(XML_E_INVALID_UNICODE)
  6077. ENTRY(XML_E_WHITESPACEORQUESTIONMARK)
  6078. ENTRY(XML_E_TOKEN_ERROR)
  6079. ENTRY(XML_E_SUSPENDED)
  6080. ENTRY(XML_E_STOPPED)
  6081. ENTRY(XML_E_UNEXPECTEDENDTAG)
  6082. ENTRY(XML_E_UNCLOSEDTAG)
  6083. ENTRY(XML_E_DUPLICATEATTRIBUTE)
  6084. ENTRY(XML_E_MULTIPLEROOTS)
  6085. ENTRY(XML_E_INVALIDATROOTLEVEL)
  6086. ENTRY(XML_E_BADXMLDECL)
  6087. ENTRY(XML_E_MISSINGROOT)
  6088. ENTRY(XML_E_UNEXPECTEDEOF)
  6089. ENTRY(XML_E_BADPEREFINSUBSET)
  6090. ENTRY(XML_E_PE_NESTING)
  6091. ENTRY(XML_E_INVALID_CDATACLOSINGTAG)
  6092. ENTRY(XML_E_UNCLOSEDPI)
  6093. ENTRY(XML_E_UNCLOSEDSTARTTAG)
  6094. ENTRY(XML_E_UNCLOSEDENDTAG)
  6095. ENTRY(XML_E_UNCLOSEDSTRING)
  6096. ENTRY(XML_E_UNCLOSEDCOMMENT)
  6097. ENTRY(XML_E_UNCLOSEDDECL)
  6098. ENTRY(XML_E_UNCLOSEDMARKUPDECL)
  6099. ENTRY(XML_E_UNCLOSEDCDATA)
  6100. ENTRY(XML_E_BADDECLNAME)
  6101. ENTRY(XML_E_BADEXTERNALID)
  6102. ENTRY(XML_E_BADELEMENTINDTD)
  6103. ENTRY(XML_E_RESERVEDNAMESPACE)
  6104. ENTRY(XML_E_EXPECTING_VERSION)
  6105. ENTRY(XML_E_EXPECTING_ENCODING)
  6106. ENTRY(XML_E_EXPECTING_NAME)
  6107. ENTRY(XML_E_UNEXPECTED_ATTRIBUTE)
  6108. ENTRY(XML_E_ENDTAGMISMATCH)
  6109. ENTRY(XML_E_INVALIDENCODING)
  6110. ENTRY(XML_E_INVALIDSWITCH)
  6111. ENTRY(XML_E_EXPECTING_NDATA)
  6112. ENTRY(XML_E_INVALID_MODEL)
  6113. ENTRY(XML_E_INVALID_TYPE)
  6114. ENTRY(XML_E_INVALIDXMLSPACE)
  6115. ENTRY(XML_E_MULTI_ATTR_VALUE)
  6116. ENTRY(XML_E_INVALID_PRESENCE)
  6117. ENTRY(XML_E_BADXMLCASE)
  6118. ENTRY(XML_E_CONDSECTINSUBSET)
  6119. ENTRY(XML_E_CDATAINVALID)
  6120. ENTRY(XML_E_INVALID_STANDALONE)
  6121. ENTRY(XML_E_UNEXPECTED_STANDALONE)
  6122. ENTRY(XML_E_DOCTYPE_IN_DTD)
  6123. ENTRY(XML_E_MISSING_ENTITY)
  6124. ENTRY(XML_E_ENTITYREF_INNAME)
  6125. ENTRY(XML_E_DOCTYPE_OUTSIDE_PROLOG)
  6126. ENTRY(XML_E_INVALID_VERSION)
  6127. ENTRY(XML_E_DTDELEMENT_OUTSIDE_DTD)
  6128. ENTRY(XML_E_DUPLICATEDOCTYPE)
  6129. ENTRY(XML_E_RESOURCE)
  6130. ENTRY(XML_E_LASTERROR)
  6131. #undef ENTRY
  6132. }
  6133. class CStringGuidPair
  6134. {
  6135. public:
  6136. UNICODE_STRING String;
  6137. const GUID * Guid;
  6138. };
  6139. class CStringIntegerPair
  6140. {
  6141. public:
  6142. UNICODE_STRING String;
  6143. ULONG Integer;
  6144. };
  6145. const CStringGuidPair StringToClassIdMap[] =
  6146. {
  6147. { RTL_CONSTANT_STRING(L"F"), &CLSID_CSxsTest_FreeThreaded },
  6148. { RTL_CONSTANT_STRING(L"S"), &CLSID_CSxsTest_SingleThreaded },
  6149. { RTL_CONSTANT_STRING(L"A"), &CLSID_CSxsTest_ApartmentThreaded },
  6150. { RTL_CONSTANT_STRING(L"B"), &CLSID_CSxsTest_BothThreaded },
  6151. { RTL_CONSTANT_STRING(L"Free"), &CLSID_CSxsTest_FreeThreaded },
  6152. { RTL_CONSTANT_STRING(L"Single"), &CLSID_CSxsTest_SingleThreaded },
  6153. { RTL_CONSTANT_STRING(L"Apartment"), &CLSID_CSxsTest_ApartmentThreaded },
  6154. { RTL_CONSTANT_STRING(L"Apt"), &CLSID_CSxsTest_ApartmentThreaded },
  6155. { RTL_CONSTANT_STRING(L"Both"), &CLSID_CSxsTest_BothThreaded },
  6156. { RTL_CONSTANT_STRING(L"FreeThreaded"), &CLSID_CSxsTest_FreeThreaded },
  6157. { RTL_CONSTANT_STRING(L"SingleThreaded"), &CLSID_CSxsTest_SingleThreaded },
  6158. { RTL_CONSTANT_STRING(L"ApartmentThreaded"), &CLSID_CSxsTest_ApartmentThreaded },
  6159. { RTL_CONSTANT_STRING(L"AptThreaded"), &CLSID_CSxsTest_ApartmentThreaded },
  6160. { RTL_CONSTANT_STRING(L"BothThreaded"), &CLSID_CSxsTest_BothThreaded }
  6161. };
  6162. #define FUSIONP_COINIT_SINGLE_THREADED (ULONG(~(COINIT_APARTMENTTHREADED | COINIT_MULTITHREADED)))
  6163. const CStringIntegerPair StringToCoinitMap[] =
  6164. {
  6165. { RTL_CONSTANT_STRING(L"A"), COINIT_APARTMENTTHREADED },
  6166. { RTL_CONSTANT_STRING(L"M"), COINIT_MULTITHREADED },
  6167. { RTL_CONSTANT_STRING(L"S"), FUSIONP_COINIT_SINGLE_THREADED },
  6168. { RTL_CONSTANT_STRING(L"STA"), FUSIONP_COINIT_SINGLE_THREADED },
  6169. { RTL_CONSTANT_STRING(L"Single"), FUSIONP_COINIT_SINGLE_THREADED },
  6170. { RTL_CONSTANT_STRING(L"SingleThreaded"), FUSIONP_COINIT_SINGLE_THREADED },
  6171. { RTL_CONSTANT_STRING(L"MTA"), COINIT_APARTMENTTHREADED },
  6172. { RTL_CONSTANT_STRING(L"FTA"), COINIT_MULTITHREADED },
  6173. { RTL_CONSTANT_STRING(L"Apartment"), COINIT_APARTMENTTHREADED },
  6174. { RTL_CONSTANT_STRING(L"Multi"), COINIT_MULTITHREADED },
  6175. { RTL_CONSTANT_STRING(L"Multiple"), COINIT_MULTITHREADED },
  6176. { RTL_CONSTANT_STRING(L"ApartmentThreaded"), COINIT_APARTMENTTHREADED },
  6177. { RTL_CONSTANT_STRING(L"MultiThreaded"), COINIT_MULTITHREADED },
  6178. { RTL_CONSTANT_STRING(L"MultipleThreaded"), COINIT_MULTITHREADED }
  6179. };
  6180. BOOL StringToGuid(PCUNICODE_STRING s, const CStringGuidPair * rg, ULONG n, bool & Found, GUID & Value)
  6181. {
  6182. // dumb linear search..
  6183. ULONG i = 0;
  6184. Found = false;
  6185. for ( i = 0 ; i != n ; ++i)
  6186. {
  6187. if (FusionpEqualStringsI(s, &rg[i].String))
  6188. {
  6189. Found = true;
  6190. Value = *rg[i].Guid;
  6191. break;
  6192. }
  6193. }
  6194. return TRUE;
  6195. }
  6196. BOOL StringToClsid(PCUNICODE_STRING s, bool & Found, CLSID & Value)
  6197. {
  6198. return StringToGuid(s, StringToClassIdMap, NUMBER_OF(StringToClassIdMap), Found, Value);
  6199. }
  6200. BOOL StringToInteger(PCUNICODE_STRING s, const CStringIntegerPair * rg, ULONG n, bool & Found, ULONG & Value)
  6201. {
  6202. // dumb linear search..
  6203. ULONG i = 0;
  6204. Found = false;
  6205. for (i = 0 ; i != n ; ++i)
  6206. {
  6207. if (FusionpEqualStringsI(s, &rg[i].String))
  6208. {
  6209. Found = true;
  6210. Value = rg[i].Integer;
  6211. break;
  6212. }
  6213. }
  6214. return TRUE;
  6215. }
  6216. BOOL StringToCoinit(PCUNICODE_STRING s, bool & Found, ULONG & Value)
  6217. {
  6218. return StringToInteger(s, StringToCoinitMap, NUMBER_OF(StringToCoinitMap), Found, Value);
  6219. }
  6220. class CArgvMap
  6221. {
  6222. public:
  6223. UNICODE_STRING ArgName;
  6224. UNICODE_STRING * ArgValue;
  6225. };
  6226. BOOL ProcessArgvMap(wchar_t ** argv, CArgvMap * map, ULONG n)
  6227. {
  6228. for (PCWSTR arg = *argv ; arg = *argv ; ++argv)
  6229. {
  6230. arg += (wcschr(L"-/:", *arg) != NULL); // skip these chars
  6231. CUnicodeString ArgString(arg);
  6232. for (ULONG i = 0 ; i != n ; ++i)
  6233. {
  6234. if (RtlPrefixUnicodeString(&map[i].ArgName, &ArgString, TRUE))
  6235. {
  6236. arg = arg + RTL_STRING_GET_LENGTH_CHARS(&map[i].ArgName);
  6237. arg += (wcschr(L":=", *arg) != NULL); // skip these chars
  6238. FusionpRtlInitUnicodeString(map[i].ArgValue, arg);
  6239. break;
  6240. }
  6241. }
  6242. }
  6243. return TRUE;
  6244. }
  6245. BOOL TestCoCreate(wchar_t ** argv)
  6246. {
  6247. UNICODE_STRING CoinitString = { 0 };
  6248. UNICODE_STRING ClsidString = { 0 };
  6249. CLSID Clsid = GUID_NULL;
  6250. ULONG Coinit = ~0UL;
  6251. bool CoinitFound = false;
  6252. bool ClsidFound = false;
  6253. BOOL Success = FALSE;
  6254. HRESULT hrCoinit = 0;
  6255. HRESULT hrCoCreate = 0;
  6256. ::ATL::CComPtr<IUnknown> Unknown;
  6257. CArgvMap ArgvMap[] =
  6258. {
  6259. { RTL_CONSTANT_STRING(L"coinit"), &CoinitString },
  6260. { RTL_CONSTANT_STRING(L"clsid"), &ClsidString },
  6261. };
  6262. if (!ProcessArgvMap(argv, ArgvMap, NUMBER_OF(ArgvMap)))
  6263. goto Exit;
  6264. if (!StringToCoinit(&CoinitString, CoinitFound, Coinit))
  6265. goto Exit;
  6266. if (!StringToClsid(&ClsidString, ClsidFound, Clsid))
  6267. goto Exit;
  6268. switch (Coinit)
  6269. {
  6270. default:
  6271. goto Exit;
  6272. case FUSIONP_COINIT_SINGLE_THREADED:
  6273. hrCoinit = CoInitialize(NULL);
  6274. case COINIT_APARTMENTTHREADED:
  6275. case COINIT_MULTITHREADED:
  6276. hrCoinit = CoInitializeEx(NULL, Coinit);
  6277. break;
  6278. }
  6279. if (FAILED(hrCoinit))
  6280. goto Exit;
  6281. hrCoCreate = CoCreateInstance(Clsid, NULL, CLSCTX_ALL, IID_IUnknown, reinterpret_cast<void**>(&Unknown));
  6282. if (FAILED(hrCoCreate))
  6283. goto Exit;
  6284. Success = TRUE;
  6285. Exit:
  6286. return Success;
  6287. }
  6288. #define WINFUSIONB_DFS_SERVER_NAME L"\\\\xiaoyuw-1"
  6289. #define WINFUSIONB_DFS_SERVER_SHARE_NAME L"BuildLabRelease"
  6290. #define WINFUSIONB_DFS_SERVER_COMMENT L"test on xiaoyuw-1"
  6291. #define NEWNAME_XIAOYUW_1 L"\\\\xiaoyuw-1\\BuildLabRelease\\release"
  6292. #define NEWNAME_XIAOYUW_DEV L"\\\\xiaoyuw-dev\\release\\1"
  6293. #define X86CHK_SHARELINK_NAME L"x86chk"
  6294. #define X86FRE_SHARELINK_NAME L"x86fre"
  6295. VOID TestDFS()
  6296. {
  6297. //
  6298. // create dfs root at a physical server
  6299. //
  6300. DWORD res;
  6301. res = NetDfsAddStdRoot(
  6302. WINFUSIONB_DFS_SERVER_NAME,
  6303. WINFUSIONB_DFS_SERVER_SHARE_NAME,
  6304. WINFUSIONB_DFS_SERVER_COMMENT,
  6305. 0);
  6306. if ((res != ERROR_SUCCESS) && (res != ERROR_FILE_EXISTS))
  6307. {
  6308. printf("NetDfsAddStdRoot");
  6309. goto Exit;
  6310. }
  6311. res = NetDfsAddStdRoot(
  6312. L"\\\\xiaoyuw-dev",
  6313. L"release",
  6314. NULL,
  6315. 0);
  6316. if ((res != ERROR_SUCCESS) && (res != ERROR_FILE_EXISTS))
  6317. {
  6318. printf("NetDfsAddStdRoot");
  6319. goto Exit;
  6320. }
  6321. //
  6322. // create Links
  6323. //
  6324. res = NetDfsAdd(
  6325. L"\\\\xiaoyuw-dev\\release\\1",
  6326. L"\\\\xiaoyuw-1\\BuildLabRelease",
  6327. L"x86chk",
  6328. NULL, 0);
  6329. if ( res != ERROR_SUCCESS)
  6330. {
  6331. printf("NetDfsAddStdRoot");
  6332. goto Exit;
  6333. }
  6334. printf("GOOD");
  6335. Exit:
  6336. return;
  6337. }
  6338. void FusionpSystemTimeToCrtTm(const SYSTEMTIME & st, struct tm & tm)
  6339. {
  6340. /*
  6341. tm_hour Hours since midnight (0 - 23)
  6342. tm_isdst Positive if daylight saving time is in effect; 0 if daylight saving time is not in effect; negative if status of daylight saving time is unknown. The C run-time library assumes the United Statess rules for implementing the calculation of Dayligh
  6343. t Saving Time (DST).
  6344. tm_mday Day of month (1 - 31)
  6345. tm_min Minutes after hour (0 - 59)
  6346. tm_mon Month (0 - 11; January = 0)
  6347. tm_sec Seconds after minute (0 - 59)
  6348. tm_wday Day of week (0 - 6; Sunday = 0)
  6349. tm_yday Day of year (0 - 365; January 1 = 0)
  6350. tm_year Year (current year minus 1900)
  6351. wYear Specifies the current year.
  6352. wMonth Specifies the current month; January = 1, February = 2, and so on.
  6353. wDayOfWeek Specifies the current day of the week; Sunday = 0, Monday = 1, and so on.
  6354. wDay Specifies the current day of the month.
  6355. wHour Specifies the current hour.
  6356. wMinute Specifies the current minute.
  6357. wSecond Specifies the current second.
  6358. wMilliseconds Specifies the current millisecond
  6359. */
  6360. tm.tm_hour = st.wHour;
  6361. tm.tm_mday = st.wDay;
  6362. tm.tm_min = st.wMinute;
  6363. tm.tm_mon = st.wMonth - 1;
  6364. tm.tm_sec = st.wSecond;
  6365. tm.tm_wday = st.wDayOfWeek;
  6366. tm.tm_year = st.wYear - 1900;
  6367. tm.tm_yday = 0;
  6368. }
  6369. PCSTR
  6370. FusionpLameFormatTime(
  6371. LARGE_INTEGER li
  6372. )
  6373. {
  6374. FILETIME FileTime = { 0 };
  6375. SYSTEMTIME SystemTime = { 0 };
  6376. struct tm tm;
  6377. FileTime.dwLowDateTime = li.LowPart;
  6378. FileTime.dwHighDateTime = li.HighPart;
  6379. FileTimeToSystemTime(&FileTime, &SystemTime);
  6380. FusionpSystemTimeToCrtTm(SystemTime, tm);
  6381. char * s = asctime(&tm);
  6382. if (s && *s)
  6383. {
  6384. char * t = s + strlen(s);
  6385. while (strchr(" \r\n\t", *--t))
  6386. {
  6387. }
  6388. *(t + 1) = 0;
  6389. }
  6390. return s;
  6391. }
  6392. BOOL TestFindActCtx_AssemblyInfo(PCWSTR * args)
  6393. {
  6394. FN_PROLOG_WIN32;
  6395. ACTCTXW ActCtx = {sizeof(ActCtx)};
  6396. ACTCTX_SECTION_KEYED_DATA askd = {sizeof(askd)};
  6397. for ( ; *args != NULL ; args += 2)
  6398. {
  6399. CFusionActCtxHandle ActCtxHandle;
  6400. CFusionActCtxScope ActCtxScope;
  6401. ActCtx.lpSource = args[0];
  6402. IFW32FALSE_EXIT(ActCtxHandle.Win32Create(&ActCtx));
  6403. IFW32FALSE_EXIT(ActCtxScope.Win32Activate(ActCtxHandle));
  6404. if (!IsolationAwareFindActCtxSectionStringW(0, NULL, ACTIVATION_CONTEXT_SECTION_DLL_REDIRECTION, args[1], &askd))
  6405. {
  6406. printf("IsolationAwareFindActCtxSectionStringW failed %ls (%d)\n",
  6407. FusionpThreadUnsafeGetLastWin32ErrorMessageW(),
  6408. FusionpGetLastWin32Error()
  6409. );
  6410. continue;
  6411. }
  6412. const ULONG64 Bases[] = { reinterpret_cast<ULONG_PTR>(askd.AssemblyMetadata.lpSectionBase) };
  6413. const static FUSIONP_DUMP_CALLBACKS Callbacks = { printf, FusionpLameFormatTime };
  6414. #if DBG // until we work out factoring between sxs.dll, sxstest.dll, fusiondbg.dll.
  6415. FusionpDumpStruct(
  6416. &Callbacks,
  6417. &StructInfo_ACTIVATION_CONTEXT_DATA_ASSEMBLY_INFORMATION,
  6418. reinterpret_cast<ULONG_PTR>(askd.AssemblyMetadata.lpInformation),
  6419. "AssemblyInformation",
  6420. Bases
  6421. );
  6422. #endif
  6423. }
  6424. FN_EPILOG;
  6425. }
  6426. void
  6427. FusionpTestOleAut2()
  6428. {
  6429. FusionpTestOleAut1(COINIT_APARTMENTTHREADED);
  6430. }
  6431. void
  6432. FusionpTestOleAut1(DWORD dwCoInit)
  6433. {
  6434. HRESULT hr = 0;
  6435. ::ATL::CComPtr<IUnknown> punk;
  6436. ::ATL::CComQIPtr<ISxsTest_SingleThreadedDual> SingleThreaded;
  6437. hr = Ole32.CoInitializeEx(NULL, dwCoInit);
  6438. printf("line %d, hr 0x%lx\n", int(__LINE__) - 1, hr);
  6439. hr = Ole32.CoCreateInstance(CLSID_CSxsTest_SingleThreadedDual, NULL, CLSCTX_INPROC, __uuidof(punk), reinterpret_cast<void**>(&punk));
  6440. printf("line %d, hr 0x%lx\n", int(__LINE__) - 1, hr);
  6441. printf("line %d, punk %p\n", int(__LINE__) - 2, static_cast<IUnknown*>(punk));
  6442. if (punk == NULL)
  6443. return;
  6444. hr = punk->QueryInterface(__uuidof(SingleThreaded), reinterpret_cast<void**>(&SingleThreaded));
  6445. printf("line %d, hr 0x%lx\n", int(__LINE__) - 1, hr);
  6446. printf("line %d, SingleThreaded %p\n", int(__LINE__) - 2, static_cast<IUnknown*>(SingleThreaded));
  6447. if (SingleThreaded == NULL)
  6448. return;
  6449. SingleThreaded->OutputDebugStringA("foo\n");
  6450. }
  6451. BOOL
  6452. FusionpGetComObjectFileName(
  6453. IUnknown * p,
  6454. CBaseStringBuffer & StringBuffer
  6455. )
  6456. // a bit hacky
  6457. {
  6458. FN_PROLOG_WIN32;
  6459. HMODULE kernel32 = GetModuleHandleW(L"Kernel32");
  6460. PGET_MODULE_HANDLE_EXW GetModuleHandleExW = reinterpret_cast<PGET_MODULE_HANDLE_EXW>(GetProcAddress(kernel32, "GetModuleHandleExW"));
  6461. CDynamicLinkLibrary Dll;
  6462. PVOID * pp = reinterpret_cast<PVOID *>(p); // hacky
  6463. IFW32FALSE_EXIT(GetModuleHandleExW(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, reinterpret_cast<PCWSTR>(*pp), &Dll));
  6464. IFW32FALSE_EXIT(FusionpGetModuleFileName(0/*flags*/, Dll, StringBuffer));
  6465. FN_EPILOG;
  6466. }
  6467. #define FUSIONP_TEST_COM_CACHE_OLE1 (0x00000001)
  6468. #define FUSIONP_TEST_COM_CACHE_NOMANIFEST (0x00000002)
  6469. #define FUSIONP_TEST_COM_CACHE_PROGID1 (0x00000004)
  6470. BOOL
  6471. FusionpTestComCacheCommon(ULONG Flags, ULONG ManifestIndex)
  6472. {
  6473. FN_PROLOG_WIN32;
  6474. HRESULT hr = E_FAIL;
  6475. CLSID Clsid = CLSID_CSxsTest_BothThreaded;
  6476. WCHAR ClsidString[64];
  6477. ::ATL::CComPtr<IUnknown> punk;
  6478. CStringBuffer StringBuffer;
  6479. CFusionActCtxHandle ActCtxHandle;
  6480. WCHAR Manifest[] = L"sxstest_dll1.dll";
  6481. ACTCTXW ActCtx = {sizeof(ActCtx)};
  6482. CFusionActCtxScope ActCtxScope;
  6483. if ((Flags & FUSIONP_TEST_COM_CACHE_NOMANIFEST) == 0)
  6484. {
  6485. *(wcsrchr(Manifest, L'.') - 1) = static_cast<WCHAR>(ManifestIndex + L'0'); // hacky
  6486. ActCtx.lpSource = Manifest;
  6487. ActCtx.lpResourceName = ISOLATIONAWARE_MANIFEST_RESOURCE_ID;
  6488. ActCtx.dwFlags = ACTCTX_FLAG_RESOURCE_NAME_VALID;
  6489. IFW32FALSE_EXIT(ActCtxHandle.Win32Create(&ActCtx));
  6490. IFW32FALSE_EXIT(ActCtxScope.Win32Activate(ActCtxHandle));
  6491. }
  6492. if (Flags & FUSIONP_TEST_COM_CACHE_PROGID1)
  6493. {
  6494. IFCOMFAILED_EXIT(hr = ::CLSIDFromProgID(L"SxS_COM.SxS_COMObject", &Clsid));
  6495. }
  6496. if (Flags & FUSIONP_TEST_COM_CACHE_OLE1)
  6497. {
  6498. IFCOMFAILED_EXIT(hr = ::CoCreateInstance(Clsid, NULL, CLSCTX_ALL, __uuidof(punk), reinterpret_cast<PVOID*>(&punk)));
  6499. }
  6500. IFW32FALSE_EXIT(FusionpGetComObjectFileName(punk, StringBuffer));
  6501. FormatGuid(ClsidString, NUMBER_OF(ClsidString), Clsid);
  6502. ::Trace("%s(0x%lx, 0x%lx, clsid=%ls):%ls\n", __FUNCTION__, Flags, ManifestIndex, ClsidString, static_cast<PCWSTR>(StringBuffer));
  6503. FN_EPILOG;
  6504. }
  6505. void
  6506. FusionpTestOle32Cache()
  6507. {
  6508. const ULONG Flags = FUSIONP_TEST_COM_CACHE_OLE1;
  6509. CoInitialize(NULL);
  6510. FusionpTestComCacheCommon(FUSIONP_TEST_COM_CACHE_NOMANIFEST | Flags, 0);
  6511. FusionpTestComCacheCommon(Flags, 1);
  6512. FusionpTestComCacheCommon(Flags, 2);
  6513. }
  6514. void
  6515. FusionpTestProgidCache()
  6516. {
  6517. const ULONG Flags = FUSIONP_TEST_COM_CACHE_OLE1 | FUSIONP_TEST_COM_CACHE_PROGID1;
  6518. CoInitialize(NULL);
  6519. //FusionpTestComCacheCommon(FUSIONP_TEST_COM_CACHE_NOMANIFEST | Flags, 0);
  6520. FusionpTestComCacheCommon(Flags, 1);
  6521. FusionpTestComCacheCommon(Flags, 2);
  6522. }
  6523. BOOL TestComctl5Comctl6()
  6524. {
  6525. FN_PROLOG_WIN32;
  6526. CFusionActCtxHandle ActCtxHandle;
  6527. WCHAR Manifest[] = L"5.man";
  6528. ACTCTXW ActCtx = {sizeof(ActCtx)};
  6529. CFusionActCtxScope ActCtxScope;
  6530. HWND hWnd = NULL;
  6531. ActCtx.lpSource = Manifest;
  6532. IFW32FALSE_EXIT(ActCtxHandle.Win32Create(&ActCtx));
  6533. IFW32FALSE_EXIT(ActCtxScope.Win32Activate(ActCtxHandle));
  6534. ::Trace("create NoVersioned windowClass : ReBarWindow32 \n");
  6535. hWnd = CreateWindowW(L"ReBarWindow32", L"noVersioned Classes", 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL);
  6536. if (hWnd == NULL){
  6537. DWORD dwLastError = ::GetLastError();
  6538. printf("the last error got for CreateWindow is %d", dwLastError);
  6539. }
  6540. ::Trace("create windowClass : Statci\n");
  6541. hWnd = CreateWindowW(L"Static", L"Classes not in 5.0", 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL);
  6542. if (hWnd == NULL){
  6543. DWORD dwLastError = ::GetLastError();
  6544. printf("the last error got for CreateWindow is %d", dwLastError);
  6545. }
  6546. FN_EPILOG;
  6547. }
  6548. BOOL FusionpTestUniqueValues()
  6549. {
  6550. FN_PROLOG_WIN32
  6551. SXSP_LOCALLY_UNIQUE_ID Luid[4];
  6552. CStringBuffer Buff;
  6553. IFW32FALSE_EXIT(SxspCreateLocallyUniqueId(Luid));
  6554. IFW32FALSE_EXIT(SxspCreateLocallyUniqueId(Luid + 1));
  6555. IFW32FALSE_EXIT(SxspCreateLocallyUniqueId(Luid + 2));
  6556. IFW32FALSE_EXIT(SxspCreateLocallyUniqueId(Luid + 3));
  6557. for (int i = 0; i < NUMBER_OF(Luid); i++)
  6558. {
  6559. IFW32FALSE_EXIT(SxspFormatLocallyUniqueId(Luid[i], Buff));
  6560. wprintf(L"SXSP_LUID: %ls\n", static_cast<PCWSTR>(Buff));
  6561. }
  6562. FN_EPILOG
  6563. }
  6564. BOOL GenerateHashOfFileLikeSxsDoes(PCWSTR pcwszFileName)
  6565. {
  6566. FN_PROLOG_WIN32;
  6567. CStringBuffer FileName;
  6568. CSmallStringBuffer strFileHashText;
  6569. CFusionArray<BYTE> rgsbFileHash;
  6570. IFW32FALSE_EXIT(FileName.Win32Assign(pcwszFileName, ::wcslen(pcwszFileName)));
  6571. IFW32FALSE_EXIT(SxspCreateFileHash(HASHFLAG_AUTODETECT, CALG_SHA1, FileName, rgsbFileHash));
  6572. IFW32FALSE_EXIT(SxspHashBytesToString(rgsbFileHash.GetArrayPtr(), rgsbFileHash.GetSize(), strFileHashText));
  6573. wprintf(L"%ls : %ls\n", pcwszFileName, static_cast<PCWSTR>(strFileHashText));
  6574. FN_EPILOG
  6575. }
  6576. void TestParsePatchInfo(PCWSTR PatchInfoFile)
  6577. {
  6578. BOOL fSuccess = FALSE;
  6579. LoadSxs();
  6580. fSuccess = (*g_pfnSxspDebug)(SXS_DEBUG_PARSE_PATCH_FILE, 0, PatchInfoFile, NULL);
  6581. if (! fSuccess){
  6582. fprintf(stderr, "%s failed!\n", __FUNCTION__);
  6583. }
  6584. }
  6585. void TestExpandCabinet(PCWSTR CabinetPath, PCWSTR TargetPath)
  6586. {
  6587. BOOL fSuccess = FALSE;
  6588. LoadSxs();
  6589. fSuccess = (*g_pfnSxspDebug)(SXS_DEBUG_EXPAND_CAB_FILE, 0, CabinetPath, (PVOID)TargetPath);
  6590. if (! fSuccess){
  6591. fprintf(stderr, "%s failed!\n", __FUNCTION__);
  6592. }
  6593. }
  6594. BOOL GenerateFileHash(PCWSTR pcwszFile)
  6595. {
  6596. FN_PROLOG_WIN32;
  6597. CFusionArray<BYTE> fFileHash;
  6598. CMediumStringBuffer buffFileName;
  6599. CMediumStringBuffer buffHashValue;
  6600. IFW32FALSE_EXIT(buffFileName.Win32Assign(pcwszFile, ::wcslen(pcwszFile)));
  6601. IFW32FALSE_EXIT(::SxspCreateFileHash(0, CALG_SHA1, buffFileName, fFileHash));
  6602. IFW32FALSE_EXIT(::SxspHashBytesToString(
  6603. fFileHash.GetArrayPtr(),
  6604. fFileHash.GetSize(),
  6605. buffHashValue));
  6606. wprintf(L"File %ls hashed to \"%ls\"\n",
  6607. static_cast<PCWSTR>(buffFileName),
  6608. static_cast<PCWSTR>(buffHashValue));
  6609. FN_EPILOG;
  6610. }
  6611. void
  6612. FusionpTestDllLoad(PCWSTR pwzBareDllName)
  6613. {
  6614. HMODULE hm1 = NULL;
  6615. HMODULE hm2 = NULL;
  6616. HMODULE hm3 = NULL;
  6617. CStringBuffer buf;
  6618. WCHAR ModulePath[128];
  6619. hm1 = LoadLibraryW(pwzBareDllName);
  6620. if ( hm1 == NULL)
  6621. {
  6622. printf("load %ls failed!", pwzBareDllName);
  6623. }else {
  6624. if (GetModuleFileNameW(hm1, ModulePath, 128))
  6625. {
  6626. printf("%ls is loaded from %ls\n", pwzBareDllName, ModulePath);
  6627. }
  6628. else
  6629. {
  6630. printf("GetModuleFileNameW for hm1 failed!!!\n");
  6631. }
  6632. }
  6633. printf("\n");
  6634. buf.Win32Assign(L"d:\\windows\\system32\\", wcslen(L"d:\\windows\\system32\\"));
  6635. buf.Win32Append(pwzBareDllName, wcslen(pwzBareDllName));
  6636. hm2 = LoadLibraryW(buf);
  6637. if ( hm2 == NULL)
  6638. {
  6639. printf("load d:\\windows\\system32\\%ls failed!", pwzBareDllName);
  6640. } else {
  6641. if (GetModuleFileNameW(hm2, ModulePath, 128))
  6642. {
  6643. printf("d:\\windows\\system32\\%ls is loaded from %ls\n", pwzBareDllName, ModulePath);
  6644. }
  6645. else
  6646. {
  6647. printf("GetModuleFileNameW for system32 dll failed!!!\n");
  6648. }
  6649. }
  6650. printf("\n");
  6651. buf.Win32Assign(L"d:\\tests\\SystemDefault\\", wcslen(L"d:\\tests\\SystemDefault\\"));
  6652. buf.Win32Append(pwzBareDllName, wcslen(pwzBareDllName));
  6653. hm3 = LoadLibraryW(buf);
  6654. if ( hm3 == NULL)
  6655. {
  6656. printf("load d:\\tests\\SystemDefault\\%ls failed!", pwzBareDllName);
  6657. } else {
  6658. if (GetModuleFileNameW(hm3, ModulePath, 128))
  6659. {
  6660. printf("d:\\tests\\SystemDefault\\%ls is loaded from %ls\n", pwzBareDllName, ModulePath);
  6661. }
  6662. else
  6663. {
  6664. printf("GetModuleFileNameW for d:\\tests\\SystemDefault\\ failed!!!\n");
  6665. }
  6666. }
  6667. printf("\n--------------------------------------------------\n");
  6668. if ( hm1 != NULL) {
  6669. FreeLibrary(hm1);
  6670. }
  6671. if ( hm2 != NULL) {
  6672. FreeLibrary(hm2);
  6673. }
  6674. if ( hm3 != NULL) {
  6675. FreeLibrary(hm3);
  6676. }
  6677. return;
  6678. }
  6679. //
  6680. // this test case should run for testing under 3 situation
  6681. // (1) clean sxstest.exe running:
  6682. // has no manifest about depend on comctl32.dll
  6683. // (2) add a sxstest.exe.local
  6684. // (3) add a sxstest.exe.manifest which depends on 6.0.0.0 comctl32.dll
  6685. //
  6686. void TestSystemDefaultDllRedirection()
  6687. {
  6688. //
  6689. // this test is for xiaoyuw own purpose. If you call this function, I assme:
  6690. // (1) your os is installed at D:\windows
  6691. // (2) you have d:\tests\systemdefault
  6692. // (3) under d:\tests\systemdefault\, you have comctl32.dll, gdiplus.dll, es.dll and a.dll
  6693. //
  6694. FusionpTestDllLoad(L"comctl32.dll");
  6695. FusionpTestDllLoad(L"es.dll");
  6696. FusionpTestDllLoad(L"gdiplus.dll");
  6697. FusionpTestDllLoad(L"a.dll");
  6698. return;
  6699. }
  6700. VOID
  6701. NTAPI
  6702. SimpleContextNotification(
  6703. IN ULONG NotificationType,
  6704. IN PACTIVATION_CONTEXT ActivationContext,
  6705. IN const VOID *ActivationContextData,
  6706. IN PVOID NotificationContext,
  6707. IN PVOID NotificationData,
  6708. IN OUT PBOOLEAN DisableNotification
  6709. )
  6710. {
  6711. switch (NotificationType)
  6712. {
  6713. case ACTIVATION_CONTEXT_NOTIFICATION_DESTROY:
  6714. RTL_SOFT_VERIFY(NT_SUCCESS(NtUnmapViewOfSection(NtCurrentProcess(), (PVOID) ActivationContextData)));
  6715. break;
  6716. default:
  6717. // Otherwise, we don't need to see this notification ever again.
  6718. *DisableNotification = TRUE;
  6719. break;
  6720. }
  6721. }
  6722. BOOL
  6723. MakeActCtxFromCurrentSxsDll(
  6724. PCWSTR pcwszFileName,
  6725. PCWSTR pcwszConfigFileName,
  6726. HANDLE *phActCtx
  6727. )
  6728. {
  6729. FN_PROLOG_WIN32;
  6730. SXS_GENERATE_ACTIVATION_CONTEXT_PARAMETERS Parameters = {0};
  6731. PACTIVATION_CONTEXT pContextCreated = NULL;
  6732. CStringBuffer AssemblyDirectory;
  6733. CStringBuffer PolicyPath;
  6734. CFileStream SourceManifestStream;
  6735. CFileStream PolicyStream;
  6736. PVOID pvMappedSection = NULL;
  6737. NTSTATUS status;
  6738. *phActCtx = INVALID_HANDLE_VALUE;
  6739. LoadSxs();
  6740. IFW32FALSE_EXIT(SourceManifestStream.OpenForRead(pcwszFileName, CImpersonationData(), FILE_SHARE_READ, OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN));
  6741. Parameters.Manifest.Path = pcwszFileName;
  6742. Parameters.Manifest.PathType = ACTIVATION_CONTEXT_PATH_TYPE_WIN32_FILE;
  6743. Parameters.Manifest.Stream = &SourceManifestStream;
  6744. IFW32FALSE_EXIT(AssemblyDirectory.Win32Assign(pcwszFileName, ::wcslen(pcwszFileName)));
  6745. IFW32FALSE_EXIT(AssemblyDirectory.Win32RemoveLastPathElement());
  6746. Parameters.AssemblyDirectory = AssemblyDirectory;
  6747. Parameters.ProcessorArchitecture = 0;
  6748. Parameters.LangId = GetUserDefaultUILanguage();
  6749. if (pcwszConfigFileName != NULL)
  6750. {
  6751. IFW32FALSE_EXIT(PolicyStream.OpenForRead(pcwszConfigFileName, CImpersonationData(), FILE_SHARE_READ, OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN));
  6752. Parameters.Policy.Path = pcwszConfigFileName;
  6753. Parameters.Policy.PathType = ACTIVATION_CONTEXT_PATH_TYPE_WIN32_FILE;
  6754. Parameters.Policy.Stream = &PolicyStream;
  6755. }
  6756. IFW32FALSE_EXIT(g_pfnSxsGenerateActivationContext(&Parameters));
  6757. IFW32NULL_EXIT(pvMappedSection = MapViewOfFile(Parameters.SectionObjectHandle, FILE_MAP_READ, 0, 0, 0));
  6758. status = RtlCreateActivationContext(
  6759. 0,
  6760. (PCACTIVATION_CONTEXT_DATA)pvMappedSection,
  6761. 0,
  6762. SimpleContextNotification,
  6763. NULL,
  6764. &pContextCreated);
  6765. if (!NT_SUCCESS(status)) {
  6766. ORIGINATE_WIN32_FAILURE_AND_EXIT(RtlCreateActivationContext, RtlNtStatusToDosError(status));
  6767. }
  6768. *phActCtx = pContextCreated;
  6769. FN_EPILOG;
  6770. }
  6771. BOOL
  6772. CreateActCtxLocally(
  6773. PCWSTR pcwszManifestFile,
  6774. PCWSTR pcwszConfigFile
  6775. )
  6776. {
  6777. HANDLE hActCtx;
  6778. if (MakeActCtxFromCurrentSxsDll(pcwszManifestFile, pcwszConfigFile, &hActCtx))
  6779. {
  6780. ReleaseActCtx(hActCtx);
  6781. return TRUE;
  6782. }
  6783. return FALSE;
  6784. }
  6785. BOOL
  6786. TestSxsExportedSurrogateStuff(
  6787. PCWSTR pcwszManifest,
  6788. PCWSTR pcwszWhat,
  6789. PCWSTR pcwszData
  6790. )
  6791. {
  6792. FN_PROLOG_WIN32;
  6793. SIZE_T cbRequired = 0;
  6794. BOOL f = false;
  6795. PVOID pvTargetBuffer = NULL;
  6796. PCSXS_CLR_SURROGATE_INFORMATION pSurrogateInfo = NULL;
  6797. PCSXS_CLR_CLASS_INFORMATION pClassInfo = NULL;
  6798. CFusionActCtxHandle hActCtxCreated;
  6799. CFusionActCtxScope ActivationScope;
  6800. ACTCTXW ActCtxStruct = {sizeof(ActCtxStruct)};
  6801. LoadSxs();
  6802. IFW32FALSE_EXIT(MakeActCtxFromCurrentSxsDll(pcwszManifest, NULL, &hActCtxCreated));
  6803. IFW32FALSE_EXIT(ActivationScope.Win32Activate(hActCtxCreated));
  6804. if (lstrcmpiW(pcwszWhat, L"clrprogid") == 0)
  6805. {
  6806. f = g_pfnClrClass(
  6807. SXS_FIND_CLR_CLASS_SEARCH_PROGID | SXS_FIND_CLR_CLASS_GET_ALL,
  6808. (PVOID)pcwszData,
  6809. hActCtxCreated,
  6810. NULL, 0, &cbRequired);
  6811. if (!f)
  6812. {
  6813. SIZE_T cbWritten = 0;
  6814. pvTargetBuffer = HeapAlloc(GetProcessHeap(), 0, cbRequired);
  6815. g_pfnClrClass(
  6816. SXS_FIND_CLR_CLASS_SEARCH_PROGID | SXS_FIND_CLR_CLASS_GET_ALL,
  6817. (PVOID)pcwszData,
  6818. hActCtxCreated,
  6819. pvTargetBuffer,
  6820. cbRequired,
  6821. &cbWritten);
  6822. pClassInfo = (PCSXS_CLR_CLASS_INFORMATION)pvTargetBuffer;
  6823. }
  6824. }
  6825. else if (lstrcmpiW(pcwszWhat, L"clrguid") == 0)
  6826. {
  6827. GUID ParsedGuid;
  6828. IFW32FALSE_EXIT(SxspParseGUID(pcwszData, wcslen(pcwszData), ParsedGuid));
  6829. f = g_pfnClrClass(
  6830. SXS_FIND_CLR_CLASS_SEARCH_GUID | SXS_FIND_CLR_CLASS_GET_ALL,
  6831. (PVOID)&ParsedGuid,
  6832. hActCtxCreated,
  6833. NULL, 0, &cbRequired);
  6834. if (!f)
  6835. {
  6836. SIZE_T cbWritten = 0;
  6837. pvTargetBuffer = HeapAlloc(GetProcessHeap(), 0, cbRequired);
  6838. g_pfnClrClass(
  6839. SXS_FIND_CLR_CLASS_SEARCH_GUID | SXS_FIND_CLR_CLASS_GET_ALL,
  6840. (PVOID)&ParsedGuid,
  6841. hActCtxCreated,
  6842. pvTargetBuffer, cbRequired, &cbWritten);
  6843. pClassInfo = (PCSXS_CLR_CLASS_INFORMATION)pvTargetBuffer;
  6844. }
  6845. }
  6846. else if (lstrcmpiW(pcwszWhat, L"lookup") == 0)
  6847. {
  6848. GUID ParsedGuid;
  6849. PCSXS_GUID_INFORMATION_CLR pGuidInfo = NULL;
  6850. IFW32FALSE_EXIT(SxspParseGUID(pcwszData, wcslen(pcwszData), ParsedGuid));
  6851. f = g_pfnClrLookup(
  6852. SXS_LOOKUP_CLR_GUID_FIND_ANY,
  6853. &ParsedGuid,
  6854. hActCtxCreated,
  6855. NULL,
  6856. 0,
  6857. &cbRequired);
  6858. if (!f)
  6859. {
  6860. SIZE_T cbWritten = 0;
  6861. pvTargetBuffer = HeapAlloc(GetProcessHeap(), 0, cbRequired);
  6862. f = g_pfnClrLookup(
  6863. SXS_LOOKUP_CLR_GUID_FIND_ANY,
  6864. &ParsedGuid,
  6865. hActCtxCreated,
  6866. pvTargetBuffer,
  6867. cbRequired,
  6868. &cbWritten);
  6869. pGuidInfo = (PCSXS_GUID_INFORMATION_CLR)pvTargetBuffer;
  6870. }
  6871. }
  6872. else if (lstrcmpiW(pcwszWhat, L"surrogate") == 0)
  6873. {
  6874. GUID ParsedGuid;
  6875. IFW32FALSE_EXIT(SxspParseGUID(pcwszData, wcslen(pcwszData), ParsedGuid));
  6876. f = g_pfnClrSurrogate(
  6877. SXS_FIND_CLR_SURROGATE_USE_ACTCTX | SXS_FIND_CLR_SURROGATE_GET_ALL,
  6878. &ParsedGuid,
  6879. hActCtxCreated,
  6880. NULL, 0, &cbRequired);
  6881. if (!f)
  6882. {
  6883. SIZE_T cbWritten = 0;
  6884. pvTargetBuffer = HeapAlloc(GetProcessHeap(), 0, cbRequired);
  6885. g_pfnClrSurrogate(
  6886. SXS_FIND_CLR_SURROGATE_USE_ACTCTX | SXS_FIND_CLR_SURROGATE_GET_ALL,
  6887. &ParsedGuid,
  6888. hActCtxCreated,
  6889. pvTargetBuffer, cbRequired, &cbWritten);
  6890. pSurrogateInfo = (PCSXS_CLR_SURROGATE_INFORMATION)pvTargetBuffer;
  6891. }
  6892. }
  6893. FN_EPILOG;
  6894. }