/*++ Copyright (c) 2000 Microsoft Corporation Module Name: sxsdebug.cpp Abstract: testing API for sxstest Author: Xiaoyu Wu (xiaoyuw) April 2000 Revision History: --*/ #include "stdinc.h" #include "xmlparser.hxx" #include "xmlparsertest.hxx" #include "sxsinstall.h" #include "sxsprotect.h" #include #include "fusiontrace.h" #include "sxsasmname.h" #include "strongname.h" #include "cassemblyrecoveryinfo.h" #include "protectionui.h" #define CONFIG_FILE_EXTENSION L".config" BOOL TestReparsePointOnFullQualifiedPath(PCWSTR fullpath) { BOOL fSuccess = FALSE; FN_TRACE_WIN32(fSuccess); BOOL CrossesReparsePoint; SIZE_T Start = 0; if ((wcschr(fullpath, '\\') == NULL) && (wcschr(fullpath, '/') == NULL)) { ::FusionpSetLastWin32Error(ERROR_INTERNAL_ERROR); goto Exit; } if (wcschr(fullpath, '\\')) { Start = (SIZE_T)(wcschr(fullpath, '\\') - fullpath); } if (wcschr(fullpath, '/') != NULL) if (Start < (ULONG(wcschr(fullpath, '/') - fullpath))) Start = wcschr(fullpath, '/') - fullpath; IFW32FALSE_EXIT( ::SxspDoesPathCrossReparsePoint( fullpath, Start, CrossesReparsePoint)); fSuccess = TRUE; Exit: return fSuccess; } HRESULT TestDeleteInstalledAssemblyBasedOnAssemblyName() { HRESULT hr = S_OK; FN_TRACE_HR(hr); /* PCWSTR manifest_files[] = {L"Z:\\tests\\footest\\cdfiles\\cards_chn\\cards.manifest", L"Z:\\tests\\footest\\cdfiles\\cards_gen\\cards.manifest", L"Z:\\tests\\footest\\cdfiles\\cards_jan\\cards.manifest", L"Z:\\tests\\footest\\cdfiles\\cards_en\\cards.manifest", L"Z:\\tests\\footest\\cdfiles\\cards_en_us\\cards.manifest" };*/ //PCWSTR manifest_files[] = { L"Z:\\tests\\footest\\cdfiles\\cards_0000\\cards.manifest" }; //PCWSTR manifest_files[] = { L"Z:\\tests\\footest\\cdfiles\\policy\\policy1\\asmpol.MANIFEST" }; PCWSTR manifest_files[] = { L"Z:\\tests\\footest\\cdfiles\\policy\\policy1\\asmpol.MANIFEST" }; CAssemblyInstall * pInstallCookie=NULL; SXS_INSTALL_SOURCE_INFO sinfo; CStringBuffer sbTemp; const static WCHAR pwzFileName[] = L"c:\\install.logfile"; //BOOL fEmpty; ZeroMemory(&sinfo, sizeof(sinfo)); sinfo.cbSize = sizeof(sinfo); sinfo.pcwszLogFileName = pwzFileName; sinfo.dwFlags = SXSINSTALLSOURCE_CREATE_LOGFILE; IFW32FALSE_EXIT(::SxsBeginAssemblyInstall(0, NULL, NULL, NULL, NULL, (PVOID *)&pInstallCookie)); for (DWORD i = 0; i < NUMBER_OF(manifest_files); i++) { IFW32FALSE_EXIT(::SxsInstallAssemblyW(pInstallCookie, SXS_INSTALL_ASSEMBLY_FLAG_CREATE_LOGFILE, manifest_files[i], &sinfo)); } if (!SUCCEEDED(hr)) { HRESULT oldHr = hr ; IFW32FALSE_EXIT(::SxsEndAssemblyInstall(pInstallCookie, SXS_END_ASSEMBLY_INSTALL_FLAG_ABORT, NULL)); hr = oldHr; }else { IFW32FALSE_EXIT(::SxsEndAssemblyInstall(pInstallCookie, SXS_END_ASSEMBLY_INSTALL_FLAG_COMMIT, NULL)); hr = NOERROR; } // IFW32FALSE_EXIT(::SxsUninstallAssembly(SXS_UNINSTALL_ASSEMBLY_FLAG_USING_INSTALL_LOGFILE, pwzFileName, NULL, NULL)); FN_EPILOG } HRESULT TestAssemblyName() { HRESULT hr = NOERROR; FN_TRACE_HR(hr); //const WCHAR super_simple_inputstring[] = L"cards,version=\"1.0.0.0\",processorArchitecture=\"x86\",language=\"0409\",whatever=\"whatever\""; const WCHAR super_simple_inputstring[] = L"cards,version=\"1.0.0.0\",processorArchitecture=\"x86\",language=\"0409\""; //const WCHAR super_simple_inputstring[] = L"cards,,,,,"; // const WCHAR simple_inputstring[] = L"ca,r,d"s,http://fusion:whatever=\"",0,"\",http://fusion:processorarchitecture=\"x86\",http://neptune:language=\"0409\""; // const WCHAR complex_inputstring[] = L"firstcards"secondcards,http://fusion:version=\"1.0.0.0\",http://www.shuku.net/novels/prose/zxfjdsw:whatever=\"what,ever\""; CAssemblyName * pAsmName = NULL; IAssemblyName * pIAsmName = NULL; LPWSTR szDisplayName = NULL ; ULONG ccDisplayName = 0; LPWSTR psz = NULL; CSmartRef pCache; CStringBuffer bufPath; PCWSTR szAssemblyStr = super_simple_inputstring; IFCOMFAILED_EXIT(::CreateAssemblyCache(&pCache, 0)); // parse : convert string from Darwin to Fusion IFCOMFAILED_EXIT(::CreateAssemblyNameObject(&pIAsmName, szAssemblyStr, CANOF_PARSE_DISPLAY_NAME, NULL)); pAsmName = reinterpret_cast(pIAsmName); ccDisplayName = static_cast(wcslen(szAssemblyStr)); ccDisplayName ++; // for worst case szDisplayName = NEW (WCHAR[ccDisplayName]); if (!szDisplayName) goto Exit; // GetDisplayName: convert string from Fusion to Darwin IFCOMFAILED_EXIT(pAsmName->GetDisplayName(szDisplayName, &ccDisplayName, 0)); //ASSERT(wcscmp(szDisplayName, szAssemblyStr) == 0); IFCOMFAILED_EXIT(pAsmName->GetInstalledAssemblyName(0, SXSP_GENERATE_SXS_PATH_PATHTYPE_ASSEMBLY, bufPath)); hr = NOERROR; Exit: if (pAsmName) pAsmName->Release(); delete[] szDisplayName; delete[] psz ; return hr; } BOOL SxspManifestSchemaCheck( PCWSTR parameterstring // this must be a full-qualified filename of a manifest file ) { BOOL fSuccess = FALSE; FN_TRACE_WIN32(fSuccess); ACTCTXGENCTX ActCtxGenCtx; ULONG ManifestFlags; CProbedAssemblyInformation AssemblyInformation; CImpersonationData ImpersonationData; PCWSTR Slash = NULL; PASSEMBLY Asm = NULL; CStringBuffer buffManifestPath; USHORT ProcessorArchitecture = ::SxspGetSystemProcessorArchitecture(); LANGID LangId = ::GetUserDefaultLangID(); // BUGBUG xiaoyuw@09/17/00 : disable to set Name ans version fro mthe command line for simplicity PARAMETER_CHECK(parameterstring != NULL); IFW32FALSE_EXIT(AssemblyInformation.Initialize()); IFW32FALSE_EXIT(buffManifestPath.Win32Assign(parameterstring, ::wcslen(parameterstring))); IFW32FALSE_EXIT( ::SxspInitActCtxGenCtx( &ActCtxGenCtx, // context out MANIFEST_OPERATION_VALIDATE_SYNTAX, 0, 0, ImpersonationData, ProcessorArchitecture, LangId, ACTIVATION_CONTEXT_PATH_TYPE_NONE, 0, NULL)); // get manifestpath, manifestName, manifestVersion Slash = wcsrchr(buffManifestPath, L'\\'); PARAMETER_CHECK(Slash != NULL); IFALLOCFAILED_EXIT(Asm = new ASSEMBLY); ManifestFlags = ASSEMBLY_MANIFEST_FILETYPE_FILE; IFW32FALSE_EXIT(AssemblyInformation.SetManifestPath(ACTIVATION_CONTEXT_PATH_TYPE_WIN32_FILE, buffManifestPath)); IFW32FALSE_EXIT(AssemblyInformation.SetManifestFlags(ManifestFlags)); IFW32FALSE_EXIT(AssemblyInformation.SetManifestLastWriteTime(&ActCtxGenCtx)); // using default parameter-value IFW32FALSE_EXIT(::SxspInitAssembly(Asm, AssemblyInformation)); IFW32FALSE_EXIT(::SxspIncorporateAssembly(&ActCtxGenCtx, Asm)); IFW32FALSE_EXIT(::SxspFireActCtxGenEnding(&ActCtxGenCtx)); fSuccess = TRUE; Exit: if (Asm != NULL) Asm->Release(); return fSuccess; } #if SXS_PRECOMPILED_MANIFESTS_ENABLED HRESULT GetPCMWorkingTime(PCWSTR filename, LARGE_INTEGER* pcmtime) { HRESULT hr = NOERROR; FN_TRACE_HR(hr); CStringBuffer buf ; CSmartRef factory; CSmartRef pPCMReader; LARGE_INTEGER timestart = {0}; ULONG i = 0; ULONG j = 0; buf.Assign(filename, ::wcslen(filename)); buf.Append(L".pcm", 4); factory = new XMLParserTestFactory; if (! factory) { ::FusionpDbgPrintEx( FUSION_DBG_LEVEL_INFO, "SxsDebug:: fail to new XMLParserTestFactory, out of memory\n"); hr = E_OUTOFMEMORY; goto Exit; } pPCMReader = new CPrecompiledManifestReader); if (! pPCMReader) { hr = E_OUTOFMEMORY; goto Exit; } for (j=0; j<10; j++) { ::QueryPerformanceCounter(×tart); for (i = 0 ; i < 10; i++) { hr = pPCMReader->InvokeNodeFactory(buf, factory); if (FAILED(hr)) goto Exit; } ::QueryPerformanceCounter(&pcmtime[j]); pcmtime[j].QuadPart -= timestart.QuadPart; } hr = NOERROR; Exit: return hr; } #endif // SXS_PRECOMPILED_MANIFESTS_ENABLED HRESULT GetParserWorkingTime(PCWSTR filename, LARGE_INTEGER* parsertime) { HRESULT hr = S_OK; FN_TRACE_HR(hr); LARGE_INTEGER t1[10], t2[10]; LARGE_INTEGER timestart; ULONG i, j; CSmartRef pIXMLParser; CSmartRef factory; CSmartRef filestream; filestream = NEW (XMLParserTestFileStream()); if (!filestream) { ::FusionpDbgPrintEx( FUSION_DBG_LEVEL_INFO, "SxsDebug:: fail to new XMLParserTestFileStream, out of memory\n"); hr = E_OUTOFMEMORY; goto Exit; } if (! filestream->open(filename)) { ::FusionpDbgPrintEx( FUSION_DBG_LEVEL_INFO, "SxsDebug:: fail to call XMLParserTestFileStream::open\n"); hr = E_UNEXPECTED; goto Exit; } factory = new XMLParserTestFactory; if (! factory) { ::FusionpDbgPrintEx( FUSION_DBG_LEVEL_INFO, "SxsDebug:: fail to new XMLParserTestFactory, out of memory\n"); hr = E_OUTOFMEMORY; goto Exit; } pIXMLParser = NEW(XMLParser); if (pIXMLParser == NULL) { ::FusionpDbgPrintEx( FUSION_DBG_LEVEL_ERROR, "SXS.DLL: Attempt to instantiate XML parser failed\n"); goto Exit; } hr = pIXMLParser->SetInput(filestream); // filestream's RefCount=2 if (! SUCCEEDED(hr)) goto Exit; hr = pIXMLParser->SetFactory(factory); // factory's RefCount=2 if (! SUCCEEDED(hr)) goto Exit; for (j =0; j<10; j++) { ::QueryPerformanceCounter(×tart); for (i = 0 ; i< 10; i++) { hr = pIXMLParser->Run(-1); if (FAILED(hr)) goto Exit; pIXMLParser->Reset(); pIXMLParser->SetFactory(factory); filestream->close(); filestream->open(filename); pIXMLParser->SetInput(filestream); } ::QueryPerformanceCounter(&t1[j]); t1[j].QuadPart -= timestart.QuadPart; ::QueryPerformanceCounter(×tart); for (i = 0 ; i< 10; i++) { hr = NOERROR; if (FAILED(hr)) goto Exit; pIXMLParser->Reset(); pIXMLParser->SetFactory(factory); filestream->close(); filestream->open(filename); pIXMLParser->SetInput(filestream); } ::QueryPerformanceCounter(&t2[j]); t2[j].QuadPart -= timestart.QuadPart; parsertime[j].QuadPart = t1[j].QuadPart - t2[j].QuadPart; } hr = NOERROR; Exit: return hr; } #if SXS_PRECOMPILED_MANIFESTS_ENABLED HRESULT TestPCMTime(PCWSTR manifestfilename) { HRESULT hr = NOERROR; FN_TRACE_HR(hr); LARGE_INTEGER tmp1 = {0}; LARGE_INTEGER tmp2 = {0}; LARGE_INTEGER parsertime[10] = {0}, pcmtime[10] = {0}; ULONG i = 0; hr = GetParserWorkingTime(manifestfilename, parsertime); if (FAILED(hr)) goto Exit; hr = GetPCMWorkingTime(manifestfilename, pcmtime); if (FAILED(hr)) goto Exit; for (i= 0 ; i < 10; i ++){ tmp1.QuadPart = tmp1.QuadPart + parsertime[i].QuadPart; tmp2.QuadPart = tmp2.QuadPart + pcmtime[i].QuadPart; } tmp1.QuadPart = tmp1.QuadPart/10; tmp2.QuadPart = tmp2.QuadPart/10; ::FusionpDbgPrintEx( FUSION_DBG_LEVEL_INFO, "SxsDebug::TestPCMTime Result:\n\tXMLParser uses %d,\n\tPCM uses %d,\n\tthe difference is %d.\n", tmp1.QuadPart, tmp2.QuadPart, tmp1.QuadPart-tmp2.QuadPart); hr = NOERROR; Exit: return hr; } /* --------------------------------------------------------------------------- Two steps : 1. paring the manifest file, generate the NodeFactory print-out file1, generate the precompiled-manifest 2. using precompiled-manifest and call NodeFactory to generate pcm-printout file2 3. Compare file1 and file2 --------------------------------------------------------------------------- */ HRESULT PrecompiledManifestTest(PCWSTR filename) // this is a manifest file name { HRESULT hr = S_OK; FN_TRACE_HR(hr); CSmartRef pIXMLParser; CSmartRef wfactory; CSmartRef rfactory; CSmartRef filestream; CStringBuffer buf; CSmartRef pPCMWriter; CSmartRef pPCMReader; FILE *fp = NULL; if (!filename) { hr = E_INVALIDARG; goto Exit; } buf.Assign(filename, ::wcslen(filename)); buf.Append(L".pcm", 4); // create filestream for xmlparser ... filestream = NEW (XMLParserTestFileStream()); if (!filestream) { ::FusionpDbgPrintEx( FUSION_DBG_LEVEL_INFO, "SxsDebug:: fail to new XMLParserTestFileStream, out of memory\n"); hr = E_OUTOFMEMORY; goto Exit; } if (! filestream->open(filename)) { ::FusionpDbgPrintEx( FUSION_DBG_LEVEL_INFO, "SxsDebug:: fail to call XMLParserTestFileStream::open\n"); hr = E_UNEXPECTED; goto Exit; } // create PCMWriter for xmlparser wfactory = new PCMTestFactory("e:\\manifest.out")); if (! wfactory) { ::FusionpDbgPrintEx( FUSION_DBG_LEVEL_INFO, "SxsDebug:: fail to new XMLParserTestFactory, out of memory\n"); hr = E_OUTOFMEMORY; goto Exit; } pPCMWriter = new CPrecompiledManifestWriter); if (! pPCMWriter) { hr = E_OUTOFMEMORY; goto Exit; } pPCMWriter->Initialize(buf); pPCMWriter->SetFactory(wfactory); // Create XMLParser pIXMLParser = NEW(XMLParser); if (pIXMLParser == NULL){ ::FusionpDbgPrintEx( FUSION_DBG_LEVEL_ERROR, "SXS.DLL: Attempt to instantiate XML parser failed\n"); goto Exit; } hr = pIXMLParser->SetInput(filestream); // filestream's RefCount=2 if (! SUCCEEDED(hr)) goto Exit; hr = pIXMLParser->SetFactory(pPCMWriter); // wfactory's RefCount=2 if (! SUCCEEDED(hr)) goto Exit; hr = pIXMLParser->Run(-1); if (FAILED(hr)) goto Exit; hr = pPCMWriter->Close(); if (FAILED(hr)) goto Exit; CSimpleFileStream::printf(L"PCM has been generated!!!\n\n"); // PCM Reader pPCMReader = new CPrecompiledManifestReader); if (! pPCMReader) { hr = E_OUTOFMEMORY; goto Exit; } rfactory = new PCMTestFactory("e:\\pcm.out")); if (! rfactory) { ::FusionpDbgPrintEx( FUSION_DBG_LEVEL_INFO, "SxsDebug:: fail to new XMLParserTestFactory, out of memory\n"); hr = E_OUTOFMEMORY; goto Exit; } hr = pPCMReader->InvokeNodeFactory(buf, rfactory); if (FAILED(hr)) goto Exit; hr = NOERROR; Exit: return hr; } #endif // SXS_PRECOMPILED_MANIFESTS_ENABLED BOOL CreateMultiLevelDirectoryTest(PCWSTR pwszNewDirs) { BOOL fSuccess = TRUE; FN_TRACE_WIN32(fSuccess); const static WCHAR CurrentDirectory[]=L"e:\\tmp\\tmp"; IFW32FALSE_EXIT(::SxspCreateMultiLevelDirectory(CurrentDirectory, pwszNewDirs)); fSuccess = TRUE; Exit: return fSuccess; } BOOL TestCopyDirectory() { BOOL fSuccess = FALSE; FN_TRACE_WIN32(fSuccess); CStringBuffer m1; CStringBuffer m2; IFW32FALSE_EXIT(m1.Win32Assign(L"Z:\\tmp\\tmp", NUMBER_OF(L"Z:\\tmp\\tmp")-1)); IFW32FALSE_EXIT(m2.Win32Assign(L"Z:\\tests\\tmp", NUMBER_OF(L"Z:\\tests\\tmp")-1)); IFW32FALSE_EXIT(::SxspInstallMoveFileExW(m1, m2, MOVEFILE_REPLACE_EXISTING)); fSuccess = TRUE; Exit: return fSuccess; } BOOL TestSxsGeneratePath() { // // the result is as below // //path is c:\winnt\winsxs\Manifests\x86_dynamicdll_b54bc117ce08a1e8_1.1.0.0_en-us_fb8e827d.Manifest //path is Manifests\x86_dynamicdll_b54bc117ce08a1e8_1.1.0.0_en-us_fb8e827d.Manifest //path is c:\winnt\winsxs\Manifests\ //path is Manifests\x86_dynamicdll_b54bc117ce08a1e8_en-us_2ffeb063.Manifest //--------------------------------------- //path is c:\winnt\winsxs\x86_policy.1.0.dynamicdll_b54bc117ce08a1e8_1.1.0.0_en-us_d51541cb\ //path is x86_policy.1.0.dynamicdll_b54bc117ce08a1e8_1.1.0.0_en-us_d51541cb\ //path is c:\winnt\winsxs\ //path is x86_policy.1.0.dynamicdll_b54bc117ce08a1e8_en-us_b74d3d95\ //--------------------------------------- //path is c:\winnt\winsxs\Policies\x86_policy.1.0.dynamicdll_b54bc117ce08a1e8_en-us_b74d3d95\1.1.0.0.Policy //path is Policies\x86_policy.1.0.dynamicdll_b54bc117ce08a1e8_en-us_b74d3d95\1.1.0.0.Policy //path is c:\winnt\winsxs\Policies\ //path is Policies\x86_policy.1.0.dynamicdll_b54bc117ce08a1e8_en-us_b74d3d95\1.1.0.0.Policy // if the assembly does not have version, flag=0 and pathType=policy would generate "policy store" // c:\winnt\winsxs\Policies\x86_policy.1.0.dynamicdll_b54bc117ce08a1e8_en-us_b74d3d95 // BOOL fSuccess = FALSE; FN_TRACE_WIN32(fSuccess); CStringBuffer PathBuffer; PASSEMBLY_IDENTITY pAssemblyIdentity = NULL; //WCHAR szDisplayName[]=L"policy.1.0.dynamicdll,type=\"win32-policy\",publicKeyToken=\"b54bc117ce08a1e8\",version=\"1.1.0.0\",language=\"en-us\",processorArchitecture=\"x86\""; PWSTR szDisplayName[]= { L"dynamicdll,type=\"win32\",publicKeyToken=\"b54bc117ce08a1e8\",version=\"1.1.0.0\",language=\"en-us\",processorArchitecture=\"x86\"", L"policy.1.0.dynamicdll,type=\"win32-policy\",publicKeyToken=\"b54bc117ce08a1e8\",version=\"1.1.0.0\",language=\"en-us\",processorArchitecture=\"x86\"", L"policy.1.0.dynamicdll,type=\"win32-policy\",publicKeyToken=\"b54bc117ce08a1e8\",version=\"1.1.0.0\",language=\"en-us\",processorArchitecture=\"x86\"" }; DWORD j, dwPathType; DWORD flags[]={ 0, SXSP_GENERATE_SXS_PATH_FLAG_OMIT_ROOT, SXSP_GENERATE_SXS_PATH_FLAG_PARTIAL_PATH, SXSP_GENERATE_SXS_PATH_FLAG_OMIT_ROOT | SXSP_GENERATE_SXS_PATH_FLAG_OMIT_VERSION}; printf("---------------------------------------\n"); for (dwPathType = SXSP_GENERATE_SXS_PATH_PATHTYPE_MANIFEST; dwPathType <= SXSP_GENERATE_SXS_PATH_PATHTYPE_POLICY; dwPathType++) //for (dwPathType = SXSP_GENERATE_SXS_PATH_PATHTYPE_ASSEMBLY; dwPathType <= SXSP_GENERATE_SXS_PATH_PATHTYPE_POLICY; dwPathType++) { IFW32FALSE_EXIT(SxspCreateAssemblyIdentityFromTextualString( szDisplayName[dwPathType - 1], &pAssemblyIdentity)); for (j = 0 ; j < NUMBER_OF(flags); j++) { IFW32FALSE_EXIT(::SxspGenerateSxsPath( flags[j], dwPathType, L"c:\\winnt\\winsxs", wcslen(L"c:\\winnt\\winsxs"), pAssemblyIdentity, PathBuffer)); printf("path is %S\n", static_cast(PathBuffer)); } printf("---------------------------------------\n"); SxsDestroyAssemblyIdentity(pAssemblyIdentity); pAssemblyIdentity = NULL; } fSuccess = TRUE; Exit: if (pAssemblyIdentity) SxsDestroyAssemblyIdentity(pAssemblyIdentity); return fSuccess; } BOOL ManifestProbeTest() { BOOL fSuccess = FALSE; FN_TRACE_WIN32(fSuccess); DWORD index = 0; CStringBuffer PathBuffer; PASSEMBLY_IDENTITY pAssemblyIdentity = NULL; ASSEMBLY_IDENTITY_ATTRIBUTE AttributeName; ASSEMBLY_IDENTITY_ATTRIBUTE AttributeVersion; ASSEMBLY_IDENTITY_ATTRIBUTE AttributeLangID; ASSEMBLY_IDENTITY_ATTRIBUTE AttributeProcessorArchitecture; PASSEMBLY_IDENTITY_ATTRIBUTE Attributes[] = { &AttributeName, &AttributeVersion, &AttributeLangID, &AttributeProcessorArchitecture}; AttributeName.Flags = 0; // reserved flags : must be 0; AttributeName.NamespaceCch = 0; AttributeName.NameCch = 4; AttributeName.ValueCch = 7; AttributeName.Namespace = NULL; AttributeName.Name = L"name"; AttributeName.Value = L"foo.mui"; AttributeVersion.Flags = 0; // reserved flags : must be 0; AttributeVersion.NamespaceCch = 0; AttributeVersion.NameCch = 7; AttributeVersion.ValueCch = 7; AttributeVersion.Namespace = NULL; AttributeVersion.Name = L"version"; AttributeVersion.Value = L"1.1.1.1"; AttributeLangID.Flags = 0; // reserved flags : must be 0; AttributeLangID.NamespaceCch = 0; AttributeLangID.NameCch = 8; AttributeLangID.ValueCch = 5; AttributeLangID.Namespace = NULL; AttributeLangID.Name = L"language"; AttributeLangID.Value = L"en-us"; AttributeProcessorArchitecture .Flags = 0; // reserved flags : must be 0; AttributeProcessorArchitecture .NamespaceCch = 0; AttributeProcessorArchitecture .NameCch = 21; AttributeProcessorArchitecture .ValueCch = 3; AttributeProcessorArchitecture .Namespace = NULL; AttributeProcessorArchitecture .Name = L"processorArchitecture"; AttributeProcessorArchitecture .Value = L"x86"; IFW32FALSE_EXIT(::SxsCreateAssemblyIdentity( 0, // DWORD Flags, ASSEMBLY_IDENTITY_TYPE_DEFINITION, // ULONG Type, &pAssemblyIdentity, 4, // ULONG AttributeCount, Attributes)); // PCASSEMBLY_IDENTITY_ATTRIBUTE const *Attributes while(1) {// run until we run out of probing-path bool fDone = false; if (!::SxspGenerateManifestPathForProbing( index, 0, NULL, 0, ACTIVATION_CONTEXT_PATH_TYPE_WIN32_FILE, L"E:\\APPBASE\\", 11, pAssemblyIdentity, PathBuffer, NULL, fDone)) { goto Exit; } if (fDone) break; PathBuffer.Clear(); index ++; } fSuccess = TRUE; Exit: if (pAssemblyIdentity) SxsDestroyAssemblyIdentity(pAssemblyIdentity); if (!fSuccess) { DWORD dwLastError = ::FusionpGetLastWin32Error(); if (dwLastError == BASESRV_SXS_RETURN_RESULT_SYSTEM_DEFAULT_DEPENDENCY_ASSEMBLY_NOT_FOUND){ ::FusionpSetLastWin32Error(0); fSuccess = TRUE; } } return fSuccess; } #define WATCHBUCKET_NOTIFYSIZE (1024) typedef struct _tWATCH_BUCKET { HANDLE hFile; HANDLE hCompleteEvent; PCSXS_PROTECT_DIRECTORY pProtectInfo; OVERLAPPED olapInfo; BYTE NotifyInfo[WATCHBUCKET_NOTIFYSIZE]; DWORD dwBytesBack; } WATCH_BUCKET, *PWATCH_BUCKET; HRESULT TryWatchingDirectories() { PCSXS_PROTECT_DIRECTORY pWatchList; SIZE_T cWatchList; DWORD dwWhichSignalled; DWORD dw; PWATCH_BUCKET pWatchBuckets; HANDLE* pHandleList; HRESULT hrSuccess = E_FAIL; FN_TRACE_HR(hrSuccess); IFW32FALSE_EXIT(::SxsProtectionGatherEntriesW(&pWatchList, &cWatchList)); pWatchBuckets = FUSION_NEW_ARRAY(WATCH_BUCKET, cWatchList); pHandleList = FUSION_NEW_ARRAY(HANDLE, cWatchList); // // Fill in the list with handles to directories // for (dw = 0; dw < cWatchList; dw++) { PWATCH_BUCKET pbTemp = pWatchBuckets + dw; ZeroMemory(pbTemp, sizeof(*pbTemp)); pbTemp->pProtectInfo = pWatchList + dw; pbTemp->hFile = ::CreateFileW( pWatchList[dw].pwszDirectory, FILE_LIST_DIRECTORY, FILE_SHARE_READ | FILE_SHARE_DELETE | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OVERLAPPED, NULL); pHandleList[dw] = CreateEventW(NULL, FALSE, FALSE, NULL); pbTemp->hCompleteEvent = pHandleList[dw]; pbTemp->olapInfo.hEvent = pHandleList[dw]; ::ReadDirectoryChangesW( pbTemp->hFile, (PVOID)(&pbTemp->NotifyInfo), WATCHBUCKET_NOTIFYSIZE, pbTemp->pProtectInfo->ulRecursiveFlag & SXS_PROTECT_RECURSIVE, SXS_PROTECT_FILTER_DEFAULT, &pbTemp->dwBytesBack, &pbTemp->olapInfo, NULL); } // // We now have a list of directories that we need to watch for changes. // while (true) { dwWhichSignalled = WaitForMultipleObjects(static_cast(cWatchList), pHandleList, FALSE, INFINITE); dwWhichSignalled -= WAIT_OBJECT_0; if (dwWhichSignalled < cWatchList) { // // Somebody went and fiddled with a directory! // dwWhichSignalled -= WAIT_OBJECT_0; ::FusionpDbgPrintEx( FUSION_DBG_LEVEL_INFO, "Someone changed: %ls\n", pWatchBuckets[dwWhichSignalled].pProtectInfo->pwszDirectory); ResetEvent(pHandleList[dwWhichSignalled]); PFILE_NOTIFY_INFORMATION pCursor; pCursor = (PFILE_NOTIFY_INFORMATION) pWatchBuckets[dwWhichSignalled].NotifyInfo; while (true) { ::SxsProtectionNotifyW( (PVOID)pWatchBuckets[dwWhichSignalled].pProtectInfo, pCursor->FileName, pCursor->FileNameLength / sizeof(pCursor->FileName[0]), pCursor->Action); if (pCursor->NextEntryOffset) pCursor = (PFILE_NOTIFY_INFORMATION)(((PBYTE)pCursor) + pCursor->NextEntryOffset); else break; } ::ReadDirectoryChangesW( pWatchBuckets[dwWhichSignalled].hFile, (PVOID)(&pWatchBuckets[dwWhichSignalled].NotifyInfo), WATCHBUCKET_NOTIFYSIZE, pWatchBuckets[dwWhichSignalled].pProtectInfo->ulRecursiveFlag & SXS_PROTECT_RECURSIVE, SXS_PROTECT_FILTER_DEFAULT, &pWatchBuckets[dwWhichSignalled].dwBytesBack, &pWatchBuckets[dwWhichSignalled].olapInfo, NULL); } } hrSuccess = S_OK; Exit: return hrSuccess; } BOOL DllRedirectionTest( PCWSTR manifestFileName ) { BOOL fSuccess = FALSE; FN_TRACE_WIN32(fSuccess); CFileStream manifestFileStream; CResourceStream ResourceStream; CFileStream policyFileStream; SXS_GENERATE_ACTIVATION_CONTEXT_PARAMETERS parameters = {0}; CUnicodeStringBuffer assemblyDirectory; CStringBuffer CandidatePolicyPathBuffer; BOOL fPolicyExist=FALSE; PWSTR p=NULL; p = wcsrchr(manifestFileName, L'.'); if (p && ((_wcsicmp(p, L".dll") ==0) || (_wcsicmp(p, L".exe") ==0))) // manifest is from a resource of a DLL or EXE { IFW32FALSE_EXIT(ResourceStream.Initialize(manifestFileName, MAKEINTRESOURCEW(RT_MANIFEST))); parameters.Manifest.Path = manifestFileName; parameters.Manifest.Stream = &ResourceStream; parameters.Manifest.PathType = ACTIVATION_CONTEXT_PATH_TYPE_WIN32_FILE; IFW32FALSE_EXIT(assemblyDirectory.Win32Assign(manifestFileName, ::wcslen(manifestFileName))); assemblyDirectory.RemoveLastPathElement(); parameters.AssemblyDirectory = assemblyDirectory; } else { IFW32FALSE_EXIT( manifestFileStream.OpenForRead( manifestFileName, CImpersonationData(), FILE_SHARE_READ, OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN)); parameters.Manifest.Path = manifestFileName; parameters.Manifest.Stream = &manifestFileStream; parameters.Manifest.PathType = ACTIVATION_CONTEXT_PATH_TYPE_WIN32_FILE; IFW32FALSE_EXIT(assemblyDirectory.Win32Assign(manifestFileName, ::wcslen(manifestFileName))); assemblyDirectory.RemoveLastPathElement(); parameters.AssemblyDirectory = assemblyDirectory; } // look for policy file in the same dir as the manifest path IFW32FALSE_EXIT(CandidatePolicyPathBuffer.Win32Assign(manifestFileName, ::wcslen(manifestFileName))); IFW32FALSE_EXIT(CandidatePolicyPathBuffer.Win32ChangePathExtension(CONFIG_FILE_EXTENSION, NUMBER_OF(CONFIG_FILE_EXTENSION) - 1, eErrorIfNoExtension)); if (::GetFileAttributesW(CandidatePolicyPathBuffer) != -1) { // policy file exists fPolicyExist = TRUE; IFW32FALSE_EXIT( policyFileStream.OpenForRead( CandidatePolicyPathBuffer, CImpersonationData(), FILE_SHARE_READ, OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN)); parameters.Policy.Path = CandidatePolicyPathBuffer; parameters.Policy.Stream = &policyFileStream; } parameters.ProcessorArchitecture = 0 ; parameters.LangId = GetUserDefaultUILanguage(); IFW32FALSE_EXIT(::SxsGenerateActivationContext(¶meters)); fSuccess = TRUE; Exit: CSxsPreserveLastError ple; ::CloseHandle(parameters.SectionObjectHandle); ple.Restore(); return fSuccess; } BOOL TestFusionArray(PCWSTR dir1, PCWSTR dir2) { BOOL fSuccess = FALSE; FN_TRACE_WIN32(fSuccess); CStringBuffer sbDir1; CStringBuffer sbDir2; CFusionDirectoryDifference dirResult; IFW32FALSE_EXIT(sbDir1.Win32Assign(dir1, wcslen(dir1))); IFW32FALSE_EXIT(sbDir2.Win32Assign(dir2, wcslen(dir2))); IFCOMFAILED_EXIT( ::FusionpCompareDirectoriesSizewiseRecursively( &dirResult, sbDir1, sbDir2)); fSuccess = TRUE; Exit: return fSuccess; } // // this function is written for Testing team to generate pAssemblyIdentity // there are two ways to generate assemblyIdentity, one is insert one attribute each time, // another way is to make all attributes to be inserted ready in an array and call // SxsCreateAssemblyIdentity. The con and pro for both approaches are obvious, // the input string must be in a format as "ns1:n1=v1;ns2:n2=v2;", // the whole string ending with a trailing ";", ns could be NULL // this fucntion does not deal with complicate case such as ns/name/value string contains // special chars. let me know if you do need deal with it... // // xiaoyuw@09/26/2000 // BOOL SxspGenerateManifestPathOnAssemblyIdentity( PCWSTR str, PWSTR pszOut, ULONG *pCchstr, PASSEMBLY_IDENTITY *ppAssemblyIdentity ) { BOOL fSuccess = FALSE; FN_TRACE_WIN32(fSuccess); PASSEMBLY_IDENTITY pAssemblyIdentity = NULL; CStringBuffer PathBuffer; if (ppAssemblyIdentity) *ppAssemblyIdentity = NULL; PARAMETER_CHECK(str != NULL); PARAMETER_CHECK(pCchstr != NULL); IFW32FALSE_EXIT( ::SxspCreateAssemblyIdentityFromTextualString( str, &pAssemblyIdentity)); // AssemblyIdentity is created, now generate the path IFW32FALSE_EXIT( ::SxspGenerateSxsPath( SXSP_GENERATE_SXS_PATH_FLAG_OMIT_ROOT, SXSP_GENERATE_SXS_PATH_PATHTYPE_ASSEMBLY, NULL, 0, pAssemblyIdentity, PathBuffer)); IFW32FALSE_EXIT(PathBuffer.Win32CopyStringOut(pszOut, pCchstr)); if (ppAssemblyIdentity != NULL) { *ppAssemblyIdentity = pAssemblyIdentity ; pAssemblyIdentity = NULL; } fSuccess = TRUE; Exit: if (pAssemblyIdentity != NULL) SxsDestroyAssemblyIdentity(pAssemblyIdentity); return fSuccess ; } /* -------------------------------------------------------------------------------- POLICY_PATH_FLAG_POLICY_IDENTITY_TEXTUAL_FORMAT : x86_policy.1.0.dynamicdll_b54bc117ce08a1e8_en-us_d51541cb POLICY_PATH_FLAG_FULL_QUALIFIED_POLICIES_DIR : c:\winnt\winsxs\policies POLICY_PATH_FLAG_FULL_QUALIFIED_POLICY_FILE_NAME : c:\winnt\winsxs\policies\x86_policy.1.0.dynamicdll_b54bc117ce08a1e8_en-us_d51541cb\1.1.0.0.policy, for .cat, you have to replace it manually -------------------------------------------------------------------------------- */ BOOL SxspGeneratePolicyPathOnAssemblyIdentity( DWORD dwFlag, PCWSTR str, PWSTR pszOut, ULONG *pCchstr, PASSEMBLY_IDENTITY *ppAssemblyIdentity ) { BOOL fSuccess = FALSE; FN_TRACE_WIN32(fSuccess); PASSEMBLY_IDENTITY pAssemblyIdentity; DWORD dwPathType; DWORD dwGenerateFlag; CStringBuffer PathBuffer; CStringBuffer bufAssemblyRootDirectory; IFW32FALSE_EXIT( ::SxspCreateAssemblyIdentityFromTextualString( str, &pAssemblyIdentity)); switch (dwFlag) { case POLICY_PATH_FLAG_POLICY_IDENTITY_TEXTUAL_FORMAT: dwPathType = SXSP_GENERATE_SXS_PATH_PATHTYPE_ASSEMBLY; dwGenerateFlag = SXSP_GENERATE_SXS_PATH_FLAG_OMIT_ROOT | SXSP_GENERATE_SXS_PATH_FLAG_OMIT_VERSION; break; case POLICY_PATH_FLAG_FULL_QUALIFIED_POLICIES_DIR: { IFW32FALSE_EXIT(SxspGetAssemblyRootDirectory(bufAssemblyRootDirectory)); dwPathType = SXSP_GENERATE_SXS_PATH_PATHTYPE_POLICY; dwGenerateFlag = SXSP_GENERATE_SXS_PATH_FLAG_PARTIAL_PATH; } break; case POLICY_PATH_FLAG_FULL_QUALIFIED_POLICY_FILE_NAME: { IFW32FALSE_EXIT(SxspGetAssemblyRootDirectory(bufAssemblyRootDirectory)); dwPathType = SXSP_GENERATE_SXS_PATH_PATHTYPE_POLICY; dwGenerateFlag = 0; } break; default: ::FusionpSetLastWin32Error(ERROR_INVALID_PARAMETER); goto Exit; } IFW32FALSE_EXIT( ::SxspGenerateSxsPath( dwGenerateFlag, dwPathType, bufAssemblyRootDirectory, bufAssemblyRootDirectory.Cch(), pAssemblyIdentity, PathBuffer)); IFW32FALSE_EXIT(PathBuffer.Win32CopyStringOut(pszOut, pCchstr)); if (ppAssemblyIdentity != NULL) { *ppAssemblyIdentity = pAssemblyIdentity ; pAssemblyIdentity = NULL; } fSuccess = TRUE; Exit: if (pAssemblyIdentity != NULL) SxsDestroyAssemblyIdentity(pAssemblyIdentity); return fSuccess ; } BOOL TestAssemblyIdentityHash() { BOOL fSuccess = FALSE; FN_TRACE_WIN32(fSuccess); ULONG hash1=0, hash2=0; PASSEMBLY_IDENTITY pAssemblyIdentity = NULL; ASSEMBLY_IDENTITY_ATTRIBUTE Attribute; IFW32FALSE_EXIT(::SxsCreateAssemblyIdentity(0, ASSEMBLY_IDENTITY_TYPE_DEFINITION, &pAssemblyIdentity, 0, NULL)); Attribute.Flags = 0; Attribute.NamespaceCch = 18; Attribute.Namespace = L"http://interesting"; Attribute.NameCch = 8; Attribute.Name = L"whatever"; Attribute.ValueCch = 32; Attribute.Value = L"@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_"; IFW32FALSE_EXIT(::SxsInsertAssemblyIdentityAttribute(0, pAssemblyIdentity, &Attribute)); IFW32FALSE_EXIT(SxsHashAssemblyIdentity(0, pAssemblyIdentity, &hash1)); ::SxsDestroyAssemblyIdentity(pAssemblyIdentity); // create second assembly identity IFW32FALSE_EXIT(::SxsCreateAssemblyIdentity(0, ASSEMBLY_IDENTITY_TYPE_DEFINITION, &pAssemblyIdentity, 0, NULL)); Attribute.Flags = 0; Attribute.NamespaceCch = 18; Attribute.Namespace = L"http://interesting"; Attribute.NameCch = 8; Attribute.Name = L"whatever"; Attribute.ValueCch = 32; Attribute.Value = L"/>BABCDGHGHKLMNMNOPSTUVUVYZYZ[\\_`"; IFW32FALSE_EXIT(::SxsInsertAssemblyIdentityAttribute(0, pAssemblyIdentity, &Attribute)); IFW32FALSE_EXIT(SxsHashAssemblyIdentity(0, pAssemblyIdentity, &hash2)); ::SxsDestroyAssemblyIdentity(pAssemblyIdentity); fSuccess = TRUE; Exit: if (pAssemblyIdentity) ::SxsDestroyAssemblyIdentity(pAssemblyIdentity); return fSuccess; } BOOL TestNewCatalogSignerThingy( PCWSTR pcwszCatalog ) { BOOL fSuccess = FALSE; ULONG ulKeyLength; CPublicKeyInformation CatalogInformation; CSmallStringBuffer sbSignerString; CStringBuffer sbCatalogName; FN_TRACE_WIN32(fSuccess); IFW32FALSE_EXIT(sbCatalogName.Win32Assign(pcwszCatalog, ::wcslen(pcwszCatalog))); IFW32FALSE_EXIT(CatalogInformation.Initialize(sbCatalogName)); IFW32FALSE_EXIT(CatalogInformation.GetStrongNameString(sbSignerString)); IFW32FALSE_EXIT(CatalogInformation.GetPublicKeyBitLength(ulKeyLength)); FusionpDbgPrintEx( FUSION_DBG_LEVEL_INFO, "Strong name of catalog signer: %ls\n" "Key: %ls (length %ld)\n", static_cast(sbSignerString), ulKeyLength); fSuccess = TRUE; Exit: return fSuccess; }; BOOL TestSystemDefaultActCtxGeneration() { BOOL fSuccess = FALSE; FN_TRACE_WIN32(fSuccess); SXS_GENERATE_ACTIVATION_CONTEXT_PARAMETERS Parameter = {0}; WCHAR pszTextualAssemblyIdentity[] = L"Microsoft.Windows.SystemCompactAssembly,version=\"1.0.0.0\",type=\"win32\",processorArchitecture=\"x86\"\0"; CStringBuffer AssemblyDirectory; IFW32FALSE_EXIT(::SxspGetAssemblyRootDirectory(AssemblyDirectory)); IFW32FALSE_EXIT(AssemblyDirectory.Win32AppendPathElement( MANIFEST_ROOT_DIRECTORY_NAME, NUMBER_OF(MANIFEST_ROOT_DIRECTORY_NAME)-1)); IFW32FALSE_EXIT(AssemblyDirectory.Win32EnsureTrailingPathSeparator()); Parameter.ProcessorArchitecture = 0 ; Parameter.LangId = 0x0409; Parameter.Flags = SXS_GENERATE_ACTIVATION_CONTEXT_FLAG_SYSTEM_DEFAULT_TEXTUAL_ASSEMBLY_IDENTITY; Parameter.TextualAssemblyIdentity = pszTextualAssemblyIdentity; Parameter.AssemblyDirectory = AssemblyDirectory; IFW32FALSE_EXIT(SxsGenerateActivationContext(&Parameter)); fSuccess = TRUE; Exit: // check LastError if (Parameter.SectionObjectHandle != NULL) ::CloseHandle(Parameter.SectionObjectHandle); if (Parameter.Manifest.Stream) Parameter.Manifest.Stream->Release(); return fSuccess; } BOOL TestSfcUIPopup() { BOOL fSuccess = FALSE; FN_TRACE_WIN32(fSuccess); CAssemblyRecoveryInfo RecoverInfo; CSXSMediaPromptDialog PromptDialog; CStringBuffer sbAssemblyName; static WCHAR wchTestName[] = L"x86_Microsoft.Tools.VisualCPlusPlus.Runtime-Libraries_6595b64144ccf1df_6.0.0.0_x-ww_ff9986d7"; bool fNoAssembly; IFW32FALSE_EXIT(RecoverInfo.Initialize()); IFW32FALSE_EXIT(sbAssemblyName.Win32Assign(wchTestName, NUMBER_OF(wchTestName) - 1)); IFW32FALSE_EXIT(RecoverInfo.AssociateWithAssembly(sbAssemblyName, fNoAssembly)); #if 0 if (fNoAssembly) { IFW32FALSE_EXIT(PromptDialog.Initialize(RecoverInfo, CSXSMediaPromptDialog::Source_FileURL)); IFW32FALSE_EXIT(PromptDialog.ShowSelf()); } #endif // 0 fSuccess = TRUE; Exit: return fSuccess; } BOOL TestPolicyPathGeneration() { WCHAR str[] = L"policy.1.0.ms-sxstest-folder1,processorArchitecture=\"x86\",type=\"win32-policy\",language=\"en\",version=\"2.2.2.2\",publicKeyToken=\"75e377300ab7b886\""; WCHAR pszOut[1024]; ULONG Cchstr =0; for (DWORD dwFlag=0; dwFlag<3; dwFlag++) { SxspGeneratePolicyPathOnAssemblyIdentity( dwFlag, str, pszOut, &Cchstr, NULL); }; return TRUE; } BOOL SxspDebug( ULONG iOperation, DWORD dwFlags, PCWSTR pszParameter1, PVOID pvParameter2) { BOOL fSuccess = FALSE; FN_TRACE_WIN32(fSuccess); switch (iOperation) { case SXS_DEBUG_SYSTEM_DEFAULT_ACTCTX_GENERATION: IFW32FALSE_EXIT(::TestSystemDefaultActCtxGeneration()); break; case SXS_DEBUG_SFC_UI_TEST: IFW32FALSE_EXIT( TestSfcUIPopup() ); break; case SXS_DEBUG_CATALOG_SIGNER_CHECK: IFW32FALSE_EXIT(::TestNewCatalogSignerThingy(pszParameter1)); break; case SXS_DEBUG_ASSEMBLY_IDENTITY_HASH: IFW32FALSE_EXIT(::TestAssemblyIdentityHash()); break; case SXS_DEBUG_ASSEMBLYNAME_CONVERSION: //IFCOMFAILED_EXIT(TestAssemblyName()); //IFCOMFAILED_EXIT(::TestDeleteInstalledAssemblyBasedOnAssemblyName()); IFW32FALSE_EXIT(::TestPolicyPathGeneration()); break; case SXS_DEBUG_GET_STRONGNAME: { CPublicKeyInformation pkInfo; CFusionArray PublicKeyBytes; CStringBuffer *pStringBuffers = (CStringBuffer*) pvParameter2; PCCERT_CONTEXT pContext = (PCCERT_CONTEXT) pszParameter1; PARAMETER_CHECK(pszParameter1 != NULL); PARAMETER_CHECK(pvParameter2 != NULL); IFW32FALSE_EXIT(pkInfo.Initialize(pContext)); IFW32FALSE_EXIT(pkInfo.GetSignerNiceName(pStringBuffers[0])); IFW32FALSE_EXIT(pkInfo.GetStrongNameString(pStringBuffers[1])); IFW32FALSE_EXIT(pkInfo.GetWrappedPublicKeyBytes(PublicKeyBytes)); IFW32FALSE_EXIT(::SxspHashBytesToString(PublicKeyBytes.GetArrayPtr(), PublicKeyBytes.GetSize(), pStringBuffers[2])); break; } case SXS_DEBUG_FUSION_REPARSEPOINT: PARAMETER_CHECK(pszParameter1 != NULL); IFW32FALSE_EXIT(::TestReparsePointOnFullQualifiedPath(pszParameter1)); break; case SXS_DEBUG_FOLDERNAME_FROM_ASSEMBLYIDENTITY_GENERATION: { WCHAR pstr[1024]; ULONG cch = NUMBER_OF(pstr); PARAMETER_CHECK(pszParameter1 != NULL); IFW32FALSE_EXIT(SxspGenerateManifestPathOnAssemblyIdentity(pszParameter1, pstr, &cch, NULL)); } break; case SXS_DEBUG_FUSION_ARRAY: PARAMETER_CHECK(pszParameter1 != NULL); PARAMETER_CHECK(pvParameter2 != NULL); IFW32FALSE_EXIT(TestFusionArray(pszParameter1, reinterpret_cast(pvParameter2))); break; case SXS_DEBUG_FORCE_LEAK: { // // Leaking memory intentionally - do not fix! // - if pvParameter2 is NULL, then leaks one byte // - Otherwise, assumes pvParameter2 is a PDWORD that is now many bytes // should be leaked. // // Uses new[] to interact with the heap; might want to use the flags to // indicate use of the Fusion heap or whatnot. // DWORD dwLeakCount = pvParameter2 ? *((PDWORD)pvParameter2) : 1; PCHAR pLeaked = NEW(CHAR[ dwLeakCount ]); if (pLeaked) { ::FusionpDbgPrintEx( FUSION_DBG_LEVEL_INFO, "SxsDebug::ForceLeak allocates %d bytes\n", dwLeakCount); fSuccess = TRUE; } else { ::FusionpDbgPrintEx( FUSION_DBG_LEVEL_INFO, "SxsDebug::ForceLeak didn't allocate anything, new failed\n"); } break; } case SXS_DEBUG_SFC_SCANNER: IFW32FALSE_EXIT(SxsProtectionPerformScanNow(NULL, TRUE, TRUE)); break; case SXS_DEBUG_DLL_REDIRECTION: PARAMETER_CHECK(pszParameter1 != NULL); IFW32FALSE_EXIT(::DllRedirectionTest(pszParameter1)); break; case SXS_DEBUG_DIRECTORY_WATCHER: IFCOMFAILED_EXIT(TryWatchingDirectories()); break; case SXS_DEBUG_CREAT_MULTILEVEL_DIRECTORY: PARAMETER_CHECK(pszParameter1 != NULL); IFW32FALSE_EXIT(CreateMultiLevelDirectoryTest(pszParameter1)); break; case SXS_DEBUG_PROBE_MANIFST: //IFW32FALSE_EXIT(ManifestProbeTest()); //IFW32FALSE_EXIT(TestSxsGeneratePath()); IFW32FALSE_EXIT(TestCopyDirectory()); break; case SXS_DEBUG_XML_PARSER: PARAMETER_CHECK(pszParameter1 != NULL); IFCOMFAILED_EXIT(::XMLParserTest(pszParameter1)); break; case SXS_DEBUG_CHECK_MANIFEST_SCHEMA: PARAMETER_CHECK(pszParameter1 != NULL); IFW32FALSE_EXIT(::SxspManifestSchemaCheck(pszParameter1)); break; #if SXS_PRECOMPILED_MANIFESTS_ENABLED case SXS_DEBUG_PRECOMPILED_MANIFEST: PARAMETER_CHECK(pszParameter1 != NULL); IFCOMFAILED_EXIT(::PrecompiledManifestTest(pszParameter1)); break; case SXS_DEBUG_TIME_PCM: PARAMETER_CHECK(pszParameter1 != NULL); IFCOMFAILED_EXIT(::TestPCMTime(const_cast(pszParameter1))); break; #endif // SXS_PRECOMPILED_MANIFESTS_ENABLED case SXS_DEBUG_SET_ASSEMBLY_STORE_ROOT: { PWSTR pszTemp = NULL; PCWSTR pszTemp2 = NULL; PARAMETER_CHECK(pszParameter1 != NULL); // Make a copy of the input string IFW32FALSE_EXIT(::FusionDupString(&pszTemp, pszParameter1, ::wcslen(pszParameter1))); pszTemp2 = ::SxspInterlockedExchange(&g_AlternateAssemblyStoreRoot, pszTemp); if (pszTemp2 != NULL) FUSION_DELETE_ARRAY(pszTemp2); break; } case SXS_DEBUG_EXIT_PROCESS: ExitProcess(123); break; case SXS_DEBUG_TERMINATE_PROCESS: TerminateProcess(GetCurrentProcess(), 456); break; } // end of switch fSuccess = TRUE; Exit: return fSuccess; }// end of SxspDebug