#include "stdinc.h" #include "util.h" #include "fusionbuffer.h" #include "xmlparser.h" #include "fusionhandle.h" // deliberately no surrounding parens or trailing comma #define STRING_AND_LENGTH(x) (x), (NUMBER_OF(x) - 1) #define MAXIMUM_PROCESSOR_ARCHITECTURE_NAME_LENGTH (sizeof("Alpha64") - 1) const static struct { USHORT ProcessorArchitecture; WCHAR String[MAXIMUM_PROCESSOR_ARCHITECTURE_NAME_LENGTH+1]; SIZE_T Cch; } gs_rgPAMap[] = { { PROCESSOR_ARCHITECTURE_INTEL, STRING_AND_LENGTH(L"x86") }, { PROCESSOR_ARCHITECTURE_AMD64, STRING_AND_LENGTH(L"AMD64") }, { PROCESSOR_ARCHITECTURE_IA64, STRING_AND_LENGTH(L"IA64") }, { PROCESSOR_ARCHITECTURE_ALPHA, STRING_AND_LENGTH(L"Alpha") }, { PROCESSOR_ARCHITECTURE_MIPS, STRING_AND_LENGTH(L"Mips") }, { PROCESSOR_ARCHITECTURE_PPC, STRING_AND_LENGTH(L"PPC") }, { PROCESSOR_ARCHITECTURE_ALPHA64, STRING_AND_LENGTH(L"Alpha64") }, { PROCESSOR_ARCHITECTURE_SHX, STRING_AND_LENGTH(L"SHX") }, { PROCESSOR_ARCHITECTURE_ARM, STRING_AND_LENGTH(L"ARM") }, { PROCESSOR_ARCHITECTURE_MSIL, STRING_AND_LENGTH(L"MSIL") }, { PROCESSOR_ARCHITECTURE_IA32_ON_WIN64, STRING_AND_LENGTH(L"WOW64") }, { PROCESSOR_ARCHITECTURE_UNKNOWN, STRING_AND_LENGTH(L"Data") }, }; static BOOL FusionpGetLocaleInfo( LANGID LangID, CBaseStringBuffer *Buffer, LCTYPE lcType, SIZE_T *CchWritten = NULL ) { LCID locale = MAKELCID(LangID, SORT_DEFAULT); CStringBufferAccessor BufferAccessor; BufferAccessor.Attach(Buffer); INT i = GetLocaleInfoW(locale, lcType, BufferAccessor.GetBufferPtr(), static_cast(BufferAccessor.GetBufferCch())); if (i != 0) { goto Exit; } if (::FusionpGetLastWin32Error() != ERROR_INSUFFICIENT_BUFFER) { goto Exit; } i = GetLocaleInfoW(locale, lcType, NULL, 0); if (i == 0) { goto Exit; } if (!Buffer->Win32ResizeBuffer(i, eDoNotPreserveBufferContents)) { i = 0; goto Exit; } i = GetLocaleInfoW(locale, lcType, BufferAccessor.GetBufferPtr(), static_cast(BufferAccessor.GetBufferCch())); Exit: if (i != 0 && CchWritten != NULL) { *CchWritten = i; } return TRUE; } BOOL FusionpFormatEnglishLanguageName( LANGID LangID, CBaseStringBuffer *Buffer, SIZE_T *CchWritten ) { return ::FusionpGetLocaleInfo(LangID, Buffer, LOCALE_SENGLANGUAGE, CchWritten); } BOOL FusionpParseProcessorArchitecture( PCWSTR String, SIZE_T Cch, USHORT *ProcessorArchitecture, bool &rfValid ) { ULONG i; BOOL fSuccess = FALSE; rfValid = false; // We'll let ProcessorArchitecture be NULL if the caller just wants to // test whether there is a match. for (i=0; icbSize, hActCtx)); PARAMETER_CHECK(RTL_CONTAINS_FIELD(askd, askd->cbSize, ulFlags)); hActCtx = askd->hActCtx; if (hActCtx == ACTCTX_PROCESS_DEFAULT) { switch (askd->ulFlags & ( ACTIVATION_CONTEXT_SECTION_KEYED_DATA_FLAG_FOUND_IN_PROCESS_DEFAULT | ACTIVATION_CONTEXT_SECTION_KEYED_DATA_FLAG_FOUND_IN_SYSTEM_DEFAULT )) { case ACTIVATION_CONTEXT_SECTION_KEYED_DATA_FLAG_FOUND_IN_PROCESS_DEFAULT: break; case ACTIVATION_CONTEXT_SECTION_KEYED_DATA_FLAG_FOUND_IN_SYSTEM_DEFAULT: hActCtx = ACTCTX_SYSTEM_DEFAULT; break; default: TRACE_PARAMETER_CHECK(askd->ulFlags); break; } } *phActCtx = hActCtx; FN_EPILOG; } BOOL FusionpSearchPath( ULONG ulFusionFlags, LPCWSTR lpPath, LPCWSTR lpFileName, // file name LPCWSTR lpExtension, // file extension CBaseStringBuffer & StringBuffer, SIZE_T * lpFilePartOffset, // file component HANDLE hActCtx ) { FN_PROLOG_WIN32; ULONG_PTR ulActCookie = 0; PWSTR lpFilePart = NULL; CFusionActCtxScope ActCtxScope; if (lpFilePartOffset != NULL) *lpFilePartOffset = 0; PARAMETER_CHECK((ulFusionFlags & ~(FUSIONP_SEARCH_PATH_ACTCTX)) == 0); if ((ulFusionFlags & FUSIONP_SEARCH_PATH_ACTCTX) != 0) { IFW32FALSE_EXIT(ActCtxScope.Win32Activate(hActCtx)); } if (StringBuffer.GetBufferCch() == 0) IFW32FALSE_EXIT(StringBuffer.Win32ResizeBuffer(MAX_PATH, eDoNotPreserveBufferContents)); for (;;) { DWORD dw = 0; { CStringBufferAccessor StringBufferAccessor(&StringBuffer); IFW32FALSE_EXIT((dw = ::SearchPathW( lpPath, lpFileName, lpExtension, StringBufferAccessor.GetBufferCchAsDWORD(), StringBufferAccessor, &lpFilePart )) != 0); if (dw < StringBuffer.GetBufferCch()) { // lpFilePart equals NULL if filename ends in a slash, or somesuch.. if (lpFilePartOffset != NULL && lpFilePart != NULL) { *lpFilePartOffset = (lpFilePart - static_cast(StringBufferAccessor)); } break; } } IFW32FALSE_EXIT(StringBuffer.Win32ResizeBuffer(dw + 1, eDoNotPreserveBufferContents)); } FN_EPILOG; } BOOL FusionpGetModuleFileName( ULONG ulFusionFlags, HMODULE hmodDll, CBaseStringBuffer & StringBuffer ) /* note that GetModuleFileName is an unusual truncating API, that's why we fudge the buffer size if GetModuleFileName returns buffersize - 1, it may be a truncated result */ { FN_PROLOG_WIN32; PARAMETER_CHECK(ulFusionFlags == 0); if (StringBuffer.GetBufferCch() < 2) IFW32FALSE_EXIT(StringBuffer.Win32ResizeBuffer(MAX_PATH, eDoNotPreserveBufferContents)); for (;;) { DWORD dw = 0; { CStringBufferAccessor StringBufferAccessor(&StringBuffer); IFW32FALSE_EXIT((dw = ::GetModuleFileNameW( hmodDll, StringBufferAccessor, StringBufferAccessor.GetBufferCchAsDWORD() )) != 0); if (dw < (StringBuffer.GetBufferCch() - 1)) { break; } } /* we don't know what to grow to, so grow by a slightly big chunk */ IFW32FALSE_EXIT(StringBuffer.Win32ResizeBuffer(dw + 64, eDoNotPreserveBufferContents)); } FN_EPILOG; }