|
|
#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<INT>(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<INT>(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; i<NUMBER_OF(gs_rgPAMap); i++) { if (::FusionpCompareStrings( gs_rgPAMap[i].String, gs_rgPAMap[i].Cch, String, Cch, true) == 0) { if (ProcessorArchitecture != NULL) *ProcessorArchitecture = gs_rgPAMap[i].ProcessorArchitecture;
break; } }
if (i != NUMBER_OF(gs_rgPAMap)) rfValid = true;
fSuccess = TRUE;
// Exit:
return fSuccess; }
/*
BOOL FusionpFormatLocalizedLanguageName( LANGID LangID, CBaseStringBuffer *Buffer, SIZE_T *CchWritten ) { LOCALE_SNATIVELANGNAME -- I think this is the one want, the language's name in its own language LOCALE_SLANGUAGE -- I think this is the language's name in the language of the installed OS return SxspFormatLanguageName(LangID, Buffer, ?); } */
BOOL FusionpFormatProcessorArchitecture( USHORT ProcessorArchitecture, CBaseStringBuffer &rBuffer ) { BOOL fSuccess = FALSE; FN_TRACE_WIN32(fSuccess); ULONG i;
for (i=0; i<NUMBER_OF(gs_rgPAMap); i++) { if (gs_rgPAMap[i].ProcessorArchitecture == ProcessorArchitecture) break; }
PARAMETER_CHECK(i != NUMBER_OF(gs_rgPAMap));
IFW32FALSE_EXIT(rBuffer.Win32Assign(gs_rgPAMap[i].String, gs_rgPAMap[i].Cch));
fSuccess = TRUE; Exit: return fSuccess; }
DWORD FusionpHRESULTToWin32( HRESULT hr ) { DWORD dwWin32ErrorCode = ERROR_INTERNAL_ERROR;
if ((HRESULT_FACILITY(hr) != FACILITY_WIN32) && (FAILED(hr))) { switch (hr) { default: break; #define X(x,y) case x: hr = HRESULT_FROM_WIN32(y); break;
X(E_UNEXPECTED, ERROR_INTERNAL_ERROR) X(E_FAIL, ERROR_FUNCTION_FAILED)
X(STG_E_PATHNOTFOUND, ERROR_PATH_NOT_FOUND) X(STG_E_FILENOTFOUND, ERROR_FILE_NOT_FOUND) X(STG_E_ACCESSDENIED, ERROR_ACCESS_DENIED) X(STG_E_INVALIDHANDLE, ERROR_INVALID_HANDLE) X(STG_E_INSUFFICIENTMEMORY, ERROR_NOT_ENOUGH_MEMORY) // or ERROR_OUTOFMEMORY
X(STG_E_TOOMANYOPENFILES, ERROR_TOO_MANY_OPEN_FILES) X(STG_E_NOMOREFILES, ERROR_NO_MORE_FILES) X(STG_E_WRITEFAULT, ERROR_WRITE_FAULT) X(STG_E_READFAULT, ERROR_READ_FAULT) X(STG_E_SHAREVIOLATION, ERROR_SHARING_VIOLATION) X(STG_E_LOCKVIOLATION, ERROR_LOCK_VIOLATION) X(STG_E_INVALIDPARAMETER, ERROR_INVALID_PARAMETER) X(STG_E_MEDIUMFULL, ERROR_DISK_FULL) // or ERROR_HANDLE_DISK_FULL
// There's more, but I doubt we really need most of this.
#undef X
} } if ((HRESULT_FACILITY(hr) == FACILITY_WIN32) && (FAILED(hr))) { dwWin32ErrorCode = HRESULT_CODE(hr);
if (FAILED(hr) && (dwWin32ErrorCode == ERROR_SUCCESS)) { dwWin32ErrorCode = ERROR_INTERNAL_ERROR; } } else { ::FusionpDbgPrintEx( FUSION_DBG_LEVEL_INFO, "SXS.DLL: " __FUNCTION__ " HRESULT 0x%08x - facility is not Win32; setting to ERROR_SXS_UNTRANSLATABLE_HRESULT\n", hr); dwWin32ErrorCode = ERROR_SXS_UNTRANSLATABLE_HRESULT; }
return dwWin32ErrorCode; }
VOID FusionpSetLastErrorFromHRESULT( HRESULT hr ) { ::SetLastError(::FusionpHRESULTToWin32(hr)); }
VOID FusionpConvertCOMFailure(HRESULT & __hr) { /*
XML_E_PARSEERRORBASE = 0xC00CE500L,
// character level error codes.
XML_E_ENDOFINPUT = XML_E_PARSEERRORBASE, XML_E_MISSINGEQUALS, // 1
XML_E_MISSINGQUOTE, // 2
XML_E_COMMENTSYNTAX, // 3
XML_E_BADSTARTNAMECHAR, // 4
XML_E_BADNAMECHAR, // 5
XML_E_BADCHARINSTRING, // 6
// under 256
*/ if ((__hr & XML_E_PARSEERRORBASE) == XML_E_PARSEERRORBASE) { //
// for normal XML ERROR,we convert hresult to a better-understanding hresult
// xiaoyuw@01/08/2001
//
#define MAP_XML_HRESULT(x) case(x) : dwWin32Error = ERROR_SXS_## x; break
DWORD dwWin32Error;
switch (__hr) { MAP_XML_HRESULT(XML_E_MISSINGEQUALS); MAP_XML_HRESULT(XML_E_MISSINGQUOTE); MAP_XML_HRESULT(XML_E_COMMENTSYNTAX); MAP_XML_HRESULT(XML_E_BADSTARTNAMECHAR); MAP_XML_HRESULT(XML_E_BADNAMECHAR); MAP_XML_HRESULT(XML_E_BADCHARINSTRING); MAP_XML_HRESULT(XML_E_XMLDECLSYNTAX); MAP_XML_HRESULT(XML_E_BADCHARDATA); MAP_XML_HRESULT(XML_E_MISSINGWHITESPACE); MAP_XML_HRESULT(XML_E_EXPECTINGTAGEND); MAP_XML_HRESULT(XML_E_MISSINGSEMICOLON); MAP_XML_HRESULT(XML_E_UNBALANCEDPAREN); MAP_XML_HRESULT(XML_E_INTERNALERROR); MAP_XML_HRESULT(XML_E_UNEXPECTED_WHITESPACE); MAP_XML_HRESULT(XML_E_INCOMPLETE_ENCODING); MAP_XML_HRESULT(XML_E_MISSING_PAREN); MAP_XML_HRESULT(XML_E_EXPECTINGCLOSEQUOTE); MAP_XML_HRESULT(XML_E_MULTIPLE_COLONS); MAP_XML_HRESULT(XML_E_INVALID_DECIMAL); MAP_XML_HRESULT(XML_E_INVALID_HEXIDECIMAL); MAP_XML_HRESULT(XML_E_INVALID_UNICODE); MAP_XML_HRESULT(XML_E_WHITESPACEORQUESTIONMARK); MAP_XML_HRESULT(XML_E_UNEXPECTEDENDTAG); MAP_XML_HRESULT(XML_E_UNCLOSEDTAG); MAP_XML_HRESULT(XML_E_DUPLICATEATTRIBUTE); MAP_XML_HRESULT(XML_E_MULTIPLEROOTS); MAP_XML_HRESULT(XML_E_INVALIDATROOTLEVEL); MAP_XML_HRESULT(XML_E_BADXMLDECL); MAP_XML_HRESULT(XML_E_MISSINGROOT); MAP_XML_HRESULT(XML_E_UNEXPECTEDEOF); MAP_XML_HRESULT(XML_E_BADPEREFINSUBSET); MAP_XML_HRESULT(XML_E_UNCLOSEDSTARTTAG); MAP_XML_HRESULT(XML_E_UNCLOSEDENDTAG); MAP_XML_HRESULT(XML_E_UNCLOSEDSTRING); MAP_XML_HRESULT(XML_E_UNCLOSEDCOMMENT); MAP_XML_HRESULT(XML_E_UNCLOSEDDECL); MAP_XML_HRESULT(XML_E_UNCLOSEDCDATA); MAP_XML_HRESULT(XML_E_RESERVEDNAMESPACE); MAP_XML_HRESULT(XML_E_INVALIDENCODING); MAP_XML_HRESULT(XML_E_INVALIDSWITCH); MAP_XML_HRESULT(XML_E_BADXMLCASE); MAP_XML_HRESULT(XML_E_INVALID_STANDALONE); MAP_XML_HRESULT(XML_E_UNEXPECTED_STANDALONE); MAP_XML_HRESULT(XML_E_INVALID_VERSION); default: dwWin32Error=(ERROR_SXS_MANIFEST_PARSE_ERROR); break; } // end of switch
__hr = HRESULT_FROM_WIN32(dwWin32Error); } //end of if
return; }
BOOL FusionpGetActivationContextFromFindResult( PCACTCTX_SECTION_KEYED_DATA askd, HANDLE * phActCtx ) { FN_PROLOG_WIN32; HANDLE hActCtx = NULL;
if (phActCtx != NULL) *phActCtx = NULL; PARAMETER_CHECK(askd != NULL); PARAMETER_CHECK(phActCtx != NULL); PARAMETER_CHECK(RTL_CONTAINS_FIELD(askd, askd->cbSize, 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<PWSTR>(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; }
|