|
|
/*
Copyright (c) Microsoft Corporation */ #include "stdinc.h"
#include "sxsp.h"
DECLARE_STD_ATTRIBUTE_NAME_DESCRIPTOR(name); DECLARE_STD_ATTRIBUTE_NAME_DESCRIPTOR(versioned);
typedef struct _WINDOW_CLASS_CONTEXT { _WINDOW_CLASS_CONTEXT() { }
CSmallStringBuffer m_FileNameBuffer; bool m_Versioned; private: _WINDOW_CLASS_CONTEXT(const _WINDOW_CLASS_CONTEXT &); void operator =(const _WINDOW_CLASS_CONTEXT &);
} WINDOW_CLASS_CONTEXT, *PWINDOW_CLASS_CONTEXT;
typedef struct _WINDOW_CLASS_ENTRY { _WINDOW_CLASS_ENTRY() { }
CSmallStringBuffer m_FileNameBuffer; CSmallStringBuffer m_VersionSpecificWindowClassNameBuffer;
private: _WINDOW_CLASS_ENTRY(const _WINDOW_CLASS_ENTRY &); void operator =(const _WINDOW_CLASS_ENTRY &); } WINDOW_CLASS_ENTRY, *PWINDOW_CLASS_ENTRY;
VOID __fastcall SxspWindowClassRedirectionContributorCallback( PACTCTXCTB_CALLBACK_DATA Data ) { FN_TRACE(); PSTRING_SECTION_GENERATION_CONTEXT SSGenContext = (PSTRING_SECTION_GENERATION_CONTEXT) Data->Header.ActCtxGenContext; PWINDOW_CLASS_CONTEXT WindowClassContext = NULL; PWINDOW_CLASS_ENTRY Entry = NULL; // deleted on exit if not NULL
if (SSGenContext != NULL) WindowClassContext = (PWINDOW_CLASS_CONTEXT) ::SxsGetStringSectionGenerationContextCallbackContext(SSGenContext);
switch (Data->Header.Reason) { case ACTCTXCTB_CBREASON_ACTCTXGENBEGINNING: { Data->GenBeginning.Success = FALSE;
INTERNAL_ERROR_CHECK(WindowClassContext == NULL);
if (Data->Header.ManifestOperation == MANIFEST_OPERATION_GENERATE_ACTIVATION_CONTEXT) { // NTRAID#NTBUG9 - 590977 - 2002/03/30 - mgrier - use smart pointer class here
IFALLOCFAILED_EXIT(WindowClassContext = new WINDOW_CLASS_CONTEXT);
if (!::SxsInitStringSectionGenerationContext( &SSGenContext, ACTIVATION_CONTEXT_DATA_WINDOW_CLASS_REDIRECTION_FORMAT_WHISTLER, TRUE, &::SxspWindowClassRedirectionStringSectionGenerationCallback, WindowClassContext)) { FUSION_DELETE_SINGLETON(WindowClassContext); WindowClassContext = NULL; goto Exit; }
Data->Header.ActCtxGenContext = SSGenContext; }
Data->GenBeginning.Success = TRUE; break; }
case ACTCTXCTB_CBREASON_ACTCTXGENENDED: if (SSGenContext != NULL) { ::SxsDestroyStringSectionGenerationContext(SSGenContext); SSGenContext = NULL; } FUSION_DELETE_SINGLETON(WindowClassContext); WindowClassContext = NULL; break;
case ACTCTXCTB_CBREASON_ALLPARSINGDONE: { Data->AllParsingDone.Success = FALSE; if (SSGenContext != NULL) IFW32FALSE_EXIT(::SxsDoneModifyingStringSectionGenerationContext(SSGenContext)); Data->AllParsingDone.Success = TRUE; break; }
case ACTCTXCTB_CBREASON_GETSECTIONSIZE: { Data->GetSectionSize.Success = FALSE; INTERNAL_ERROR_CHECK(SSGenContext != NULL); IFW32FALSE_EXIT(::SxsGetStringSectionGenerationContextSectionSize(SSGenContext, &Data->GetSectionSize.SectionSize)); Data->GetSectionSize.Success = TRUE; break; }
case ACTCTXCTB_CBREASON_PCDATAPARSED: { Data->PCDATAParsed.Success = FALSE;
if ((Data->Header.ManifestOperation == MANIFEST_OPERATION_GENERATE_ACTIVATION_CONTEXT) && (Data->PCDATAParsed.ParseContext->XMLElementDepth == 3) && (::FusionpCompareStrings( Data->PCDATAParsed.ParseContext->ElementPath, Data->PCDATAParsed.ParseContext->ElementPathCch, L"urn:schemas-microsoft-com:asm.v1^assembly!urn:schemas-microsoft-com:asm.v1^file!urn:schemas-microsoft-com:asm.v1^windowClass", NUMBER_OF(L"urn:schemas-microsoft-com:asm.v1^assembly!urn:schemas-microsoft-com:asm.v1^file!urn:schemas-microsoft-com:asm.v1^windowClass") - 1, false) == 0)) { SIZE_T VersionCch; PCWSTR pwszVersion = NULL;
INTERNAL_ERROR_CHECK(SSGenContext != NULL); INTERNAL_ERROR_CHECK(WindowClassContext != NULL);
// NTRAID#NTBUG9 - 590977 - 2002/03/30 - mgrier - use smart pointer class here
IFALLOCFAILED_EXIT(Entry = new WINDOW_CLASS_ENTRY);
IFW32FALSE_EXIT(Entry->m_FileNameBuffer.Win32Assign(WindowClassContext->m_FileNameBuffer));
IFW32FALSE_EXIT(::SxspGetAssemblyIdentityAttributeValue(0, Data->ElementParsed.AssemblyContext->AssemblyIdentity, &s_IdentityAttribute_version, &pwszVersion, &VersionCch));
if (WindowClassContext->m_Versioned) { IFW32FALSE_EXIT(Entry->m_VersionSpecificWindowClassNameBuffer.Win32Assign(pwszVersion, VersionCch)); IFW32FALSE_EXIT(Entry->m_VersionSpecificWindowClassNameBuffer.Win32Append(L"!", 1)); }
IFW32FALSE_EXIT(Entry->m_VersionSpecificWindowClassNameBuffer.Win32Append(Data->PCDATAParsed.Text, Data->PCDATAParsed.TextCch));
IFW32FALSE_EXIT( ::SxsAddStringToStringSectionGenerationContext( (PSTRING_SECTION_GENERATION_CONTEXT) Data->Header.ActCtxGenContext, Data->PCDATAParsed.Text, Data->PCDATAParsed.TextCch, Entry, Data->PCDATAParsed.AssemblyContext->AssemblyRosterIndex, ERROR_SXS_DUPLICATE_WINDOWCLASS_NAME));
// Prevent deletion in exit path...
Entry = NULL; }
// Everything's groovy!
Data->PCDATAParsed.Success = TRUE; break; }
case ACTCTXCTB_CBREASON_ELEMENTPARSED: { Data->ElementParsed.Success = FALSE;
if ((Data->ElementParsed.ParseContext->XMLElementDepth == 2) && (::FusionpCompareStrings( Data->ElementParsed.ParseContext->ElementPath, Data->ElementParsed.ParseContext->ElementPathCch, L"urn:schemas-microsoft-com:asm.v1^assembly!urn:schemas-microsoft-com:asm.v1^file", NUMBER_OF(L"urn:schemas-microsoft-com:asm.v1^assembly!urn:schemas-microsoft-com:asm.v1^file") - 1, false) == 0)) { CStringBuffer FileNameBuffer; bool fFound = false; SIZE_T cb;
// capture the name of the file we're parsing...
IFW32FALSE_EXIT( ::SxspGetAttributeValue( 0, &s_AttributeName_name, &Data->ElementParsed, fFound, sizeof(FileNameBuffer), &FileNameBuffer, cb, NULL, 0));
// If there's no NAME attribute, someone else will puke; we'll handle it
// gracefully.
if (fFound) { if (Data->Header.ManifestOperation == MANIFEST_OPERATION_GENERATE_ACTIVATION_CONTEXT) { INTERNAL_ERROR_CHECK(WindowClassContext != NULL); IFW32FALSE_EXIT(WindowClassContext->m_FileNameBuffer.Win32Assign(FileNameBuffer)); } } } else if ((Data->ElementParsed.ParseContext->XMLElementDepth == 3) && (::FusionpCompareStrings( Data->ElementParsed.ParseContext->ElementPath, Data->ElementParsed.ParseContext->ElementPathCch, L"urn:schemas-microsoft-com:asm.v1^assembly!urn:schemas-microsoft-com:asm.v1^file!urn:schemas-microsoft-com:asm.v1^windowClass", NUMBER_OF(L"urn:schemas-microsoft-com:asm.v1^assembly!urn:schemas-microsoft-com:asm.v1^file!urn:schemas-microsoft-com:asm.v1^windowClass") - 1, false) == 0)) { bool fVersioned = true; bool fFound = false; SIZE_T cbBytesWritten;
IFW32FALSE_EXIT( ::SxspGetAttributeValue( 0, &s_AttributeName_versioned, &Data->ElementParsed, fFound, sizeof(fVersioned), &fVersioned, cbBytesWritten, &::SxspValidateBoolAttribute, 0));
if (!fFound) fVersioned = true;
if (Data->Header.ManifestOperation == MANIFEST_OPERATION_GENERATE_ACTIVATION_CONTEXT) { INTERNAL_ERROR_CHECK(WindowClassContext != NULL); WindowClassContext->m_Versioned = fVersioned; }
}
// Everything's groovy!
Data->ElementParsed.Success = TRUE; break; }
case ACTCTXCTB_CBREASON_GETSECTIONDATA: Data->GetSectionData.Success = FALSE; INTERNAL_ERROR_CHECK(SSGenContext != NULL); IFW32FALSE_EXIT( ::SxsGetStringSectionGenerationContextSectionData( SSGenContext, Data->GetSectionData.SectionSize, Data->GetSectionData.SectionDataStart, NULL)); Data->GetSectionData.Success = TRUE; break; }
Exit: ; }
BOOL SxspWindowClassRedirectionStringSectionGenerationCallback( PVOID Context, ULONG Reason, PVOID CallbackData ) { BOOL fSuccess = FALSE; FN_TRACE_WIN32(fSuccess);
switch (Reason) { case STRING_SECTION_GENERATION_CONTEXT_CALLBACK_REASON_ENTRYDELETED: { PSTRING_SECTION_GENERATION_CONTEXT_CBDATA_ENTRYDELETED CBData = (PSTRING_SECTION_GENERATION_CONTEXT_CBDATA_ENTRYDELETED) CallbackData; PWINDOW_CLASS_ENTRY Entry = (PWINDOW_CLASS_ENTRY) CBData->DataContext; FUSION_DELETE_SINGLETON(Entry); break; }
case STRING_SECTION_GENERATION_CONTEXT_CALLBACK_REASON_GETDATASIZE: { PSTRING_SECTION_GENERATION_CONTEXT_CBDATA_GETDATASIZE CBData = (PSTRING_SECTION_GENERATION_CONTEXT_CBDATA_GETDATASIZE) CallbackData; PWINDOW_CLASS_ENTRY Entry = (PWINDOW_CLASS_ENTRY) CBData->DataContext;
CBData->DataSize = sizeof(ACTIVATION_CONTEXT_DATA_WINDOW_CLASS_REDIRECTION); CBData->DataSize += ((Entry->m_FileNameBuffer.Cch() + 1 + Entry->m_VersionSpecificWindowClassNameBuffer.Cch() + 1) * sizeof(WCHAR)); break; }
case STRING_SECTION_GENERATION_CONTEXT_CALLBACK_REASON_GETDATA: { PSTRING_SECTION_GENERATION_CONTEXT_CBDATA_GETDATA CBData = (PSTRING_SECTION_GENERATION_CONTEXT_CBDATA_GETDATA) CallbackData; PWINDOW_CLASS_ENTRY Entry = (PWINDOW_CLASS_ENTRY) CBData->DataContext; PACTIVATION_CONTEXT_DATA_WINDOW_CLASS_REDIRECTION Info;
SIZE_T BytesLeft = CBData->BufferSize; SIZE_T BytesWritten = 0; PWSTR Cursor;
Info = (PACTIVATION_CONTEXT_DATA_WINDOW_CLASS_REDIRECTION) CBData->Buffer; Cursor = (PWSTR) (Info + 1);
if (BytesLeft < sizeof(ACTIVATION_CONTEXT_DATA_WINDOW_CLASS_REDIRECTION)) { ::FusionpSetLastWin32Error(ERROR_INSUFFICIENT_BUFFER); goto Exit; }
BytesWritten += sizeof(ACTIVATION_CONTEXT_DATA_WINDOW_CLASS_REDIRECTION); BytesLeft -= sizeof(ACTIVATION_CONTEXT_DATA_WINDOW_CLASS_REDIRECTION);
Info->Size = sizeof(ACTIVATION_CONTEXT_DATA_WINDOW_CLASS_REDIRECTION); Info->Flags = 0;
IFW32FALSE_EXIT(Entry->m_VersionSpecificWindowClassNameBuffer.Win32CopyIntoBuffer( &Cursor, &BytesLeft, &BytesWritten, Info, &Info->VersionSpecificClassNameOffset, &Info->VersionSpecificClassNameLength));
IFW32FALSE_EXIT(Entry->m_FileNameBuffer.Win32CopyIntoBuffer( &Cursor, &BytesLeft, &BytesWritten, CBData->SectionHeader, &Info->DllNameOffset, &Info->DllNameLength));
CBData->BytesWritten = BytesWritten; } }
fSuccess = TRUE; Exit: return fSuccess; }
|