1059 lines
42 KiB
C++
1059 lines
42 KiB
C++
|
/*++
|
||
|
|
||
|
Copyright (c) 2000 Microsoft Corporation
|
||
|
|
||
|
Module Name:
|
||
|
|
||
|
comclass.cpp
|
||
|
|
||
|
Abstract:
|
||
|
|
||
|
Activation context section contributor for COM servers.
|
||
|
|
||
|
Author:
|
||
|
|
||
|
Michael J. Grier (MGrier) 23-Feb-2000
|
||
|
|
||
|
Revision History:
|
||
|
|
||
|
--*/
|
||
|
|
||
|
#include "stdinc.h"
|
||
|
#include <windows.h>
|
||
|
#include "sxsp.h"
|
||
|
|
||
|
DECLARE_STD_ATTRIBUTE_NAME_DESCRIPTOR(clsid);
|
||
|
DECLARE_STD_ATTRIBUTE_NAME_DESCRIPTOR(iid);
|
||
|
DECLARE_STD_ATTRIBUTE_NAME_DESCRIPTOR(name);
|
||
|
DECLARE_STD_ATTRIBUTE_NAME_DESCRIPTOR(progid);
|
||
|
DECLARE_STD_ATTRIBUTE_NAME_DESCRIPTOR(proxyStubClsid32);
|
||
|
DECLARE_STD_ATTRIBUTE_NAME_DESCRIPTOR(runtimeVersion);
|
||
|
DECLARE_STD_ATTRIBUTE_NAME_DESCRIPTOR(threadingModel);
|
||
|
DECLARE_STD_ATTRIBUTE_NAME_DESCRIPTOR(tlbid);
|
||
|
|
||
|
#define ALLOCATE_BUFFER_SPACE(_bytesNeeded, _bufferCursor, _bytesLeft, _bytesWritten, _typeName, _ptr) \
|
||
|
do { \
|
||
|
if ((_bytesLeft) < (_bytesNeeded)) \
|
||
|
ORIGINATE_WIN32_FAILURE_AND_EXIT(NoRoom, ERROR_INSUFFICIENT_BUFFER); \
|
||
|
(_bytesLeft) -= (_bytesNeeded); \
|
||
|
(_bytesWritten) += (_bytesNeeded); \
|
||
|
(_ptr) = (_typeName)(_bufferCursor); \
|
||
|
(_bufferCursor) = (PVOID) (((ULONG_PTR) (_bufferCursor)) + (_bytesNeeded)); \
|
||
|
} while (0)
|
||
|
|
||
|
#define ALLOCATE_BUFFER_SPACE_TYPE(_typeName, _bufferCursor, _bytesLeft, _bytesWritten, _ptr) \
|
||
|
ALLOCATE_BUFFER_SPACE(sizeof(_typeName), _bufferCursor, _bytesLeft, _bytesWritten, _typeName *, _ptr)
|
||
|
|
||
|
|
||
|
typedef struct _COM_GLOBAL_CONTEXT *PCOM_GLOBAL_CONTEXT;
|
||
|
typedef struct _COM_FILE_CONTEXT *PCOM_FILE_CONTEXT;
|
||
|
typedef struct _COM_SERVER_ENTRY *PCOM_SERVER_ENTRY;
|
||
|
|
||
|
typedef struct _COM_GLOBAL_CONTEXT
|
||
|
{
|
||
|
_COM_GLOBAL_CONTEXT() { }
|
||
|
|
||
|
// Temporary holding buffer for the filename until the first COM server entry is
|
||
|
// found, at which time a COM_FILE_CONTEXT is allocated and the filename moved to it.
|
||
|
CSmallStringBuffer m_FileNameBuffer;
|
||
|
PCOM_FILE_CONTEXT m_FileContextListHead;
|
||
|
ULONG m_FileContextListCount;
|
||
|
CTinyStringBuffer m_FirstShimNameBuffer;
|
||
|
ULONG m_FirstShimNameOffset;
|
||
|
ULONG m_FirstShimNameLength;
|
||
|
|
||
|
// When the first clrClass entry is created, its file context is written here for
|
||
|
// easy access in the future. It will exist in the normal list of files as well,
|
||
|
// however, and will get cleaned up when the file list goes away.
|
||
|
PCOM_FILE_CONTEXT m_MscoreeFileContext;
|
||
|
|
||
|
private:
|
||
|
_COM_GLOBAL_CONTEXT(const _COM_GLOBAL_CONTEXT &);
|
||
|
void operator =(const _COM_GLOBAL_CONTEXT &);
|
||
|
} COM_GLOBAL_CONTEXT;
|
||
|
|
||
|
typedef struct _COM_FILE_CONTEXT
|
||
|
{
|
||
|
public:
|
||
|
_COM_FILE_CONTEXT() { }
|
||
|
|
||
|
PCOM_FILE_CONTEXT m_Next;
|
||
|
CSmallStringBuffer m_FileNameBuffer;
|
||
|
PCOM_SERVER_ENTRY m_ServerListHead;
|
||
|
ULONG m_ServerListCount;
|
||
|
ULONG m_Offset; // populated during section generation
|
||
|
PCOM_GLOBAL_CONTEXT m_GlobalContext;
|
||
|
|
||
|
private:
|
||
|
_COM_FILE_CONTEXT(const _COM_FILE_CONTEXT &);
|
||
|
void operator =(const _COM_FILE_CONTEXT &);
|
||
|
} COM_FILE_CONTEXT;
|
||
|
|
||
|
typedef struct _COM_SERVER_ENTRY
|
||
|
{
|
||
|
public:
|
||
|
_COM_SERVER_ENTRY() { }
|
||
|
|
||
|
PCOM_SERVER_ENTRY m_Next;
|
||
|
PCOM_FILE_CONTEXT m_FileContext;
|
||
|
GUID m_ReferenceClsid;
|
||
|
GUID m_ConfiguredClsid;
|
||
|
GUID m_ImplementedClsid;
|
||
|
GUID m_TypeLibraryId;
|
||
|
ULONG m_ThreadingModel;
|
||
|
CSmallStringBuffer m_ProgIdBuffer;
|
||
|
CTinyStringBuffer m_TypeNameBuffer;
|
||
|
CTinyStringBuffer m_ShimNameBuffer;
|
||
|
CTinyStringBuffer m_RuntimeVersionBuffer;
|
||
|
ULONG m_ShimType;
|
||
|
bool m_IsFirstShim;
|
||
|
private:
|
||
|
_COM_SERVER_ENTRY(const _COM_SERVER_ENTRY &);
|
||
|
void operator =(const _COM_SERVER_ENTRY &);
|
||
|
} COM_SERVER_ENTRY;
|
||
|
|
||
|
VOID
|
||
|
WINAPI
|
||
|
SxspComClassRedirectionContributorCallback(
|
||
|
PACTCTXCTB_CALLBACK_DATA Data
|
||
|
)
|
||
|
{
|
||
|
FN_TRACE();
|
||
|
|
||
|
PGUID_SECTION_GENERATION_CONTEXT GSGenContext = (PGUID_SECTION_GENERATION_CONTEXT) Data->Header.ActCtxGenContext;
|
||
|
PCOM_GLOBAL_CONTEXT ComGlobalContext = NULL;
|
||
|
|
||
|
if (GSGenContext != NULL)
|
||
|
ComGlobalContext = (PCOM_GLOBAL_CONTEXT) ::SxsGetGuidSectionGenerationContextCallbackContext(GSGenContext);
|
||
|
|
||
|
switch (Data->Header.Reason)
|
||
|
{
|
||
|
case ACTCTXCTB_CBREASON_ACTCTXGENBEGINNING:
|
||
|
Data->GenBeginning.Success = FALSE;
|
||
|
|
||
|
INTERNAL_ERROR_CHECK(ComGlobalContext == NULL);
|
||
|
INTERNAL_ERROR_CHECK(GSGenContext == NULL);
|
||
|
|
||
|
IFALLOCFAILED_EXIT(ComGlobalContext = new COM_GLOBAL_CONTEXT);
|
||
|
|
||
|
ComGlobalContext->m_FileContextListHead = NULL;
|
||
|
ComGlobalContext->m_FileContextListCount = 0;
|
||
|
ComGlobalContext->m_FirstShimNameOffset = 0;
|
||
|
ComGlobalContext->m_FirstShimNameLength = 0;
|
||
|
ComGlobalContext->m_MscoreeFileContext = NULL;
|
||
|
|
||
|
if (!::SxsInitGuidSectionGenerationContext(
|
||
|
&GSGenContext,
|
||
|
ACTIVATION_CONTEXT_DATA_COM_SERVER_REDIRECTION_FORMAT_WHISTLER,
|
||
|
&::SxspComClassRedirectionGuidSectionGenerationCallback,
|
||
|
ComGlobalContext))
|
||
|
{
|
||
|
FUSION_DELETE_SINGLETON(ComGlobalContext);
|
||
|
goto Exit;
|
||
|
}
|
||
|
|
||
|
Data->Header.ActCtxGenContext = GSGenContext;
|
||
|
Data->GenBeginning.Success = TRUE;
|
||
|
|
||
|
break;
|
||
|
|
||
|
case ACTCTXCTB_CBREASON_ACTCTXGENENDED:
|
||
|
if (GSGenContext != NULL)
|
||
|
::SxsDestroyGuidSectionGenerationContext(GSGenContext);
|
||
|
|
||
|
FUSION_DELETE_SINGLETON(ComGlobalContext);
|
||
|
break;
|
||
|
|
||
|
case ACTCTXCTB_CBREASON_ALLPARSINGDONE:
|
||
|
Data->AllParsingDone.Success = FALSE;
|
||
|
|
||
|
#if 0 // guid section optimiziation not yet implemented
|
||
|
if ((GSGenContext != NULL) && !::SxsDoneModifyingGuidSectionGenerationContext(GSGenContext))
|
||
|
goto Exit;
|
||
|
#endif
|
||
|
|
||
|
Data->AllParsingDone.Success = TRUE;
|
||
|
break;
|
||
|
|
||
|
case ACTCTXCTB_CBREASON_GETSECTIONSIZE:
|
||
|
Data->GetSectionSize.Success = FALSE;
|
||
|
// Someone shouldn't be asking for the section size if this is a parse-only
|
||
|
// run. These two asserts should be equivalent...
|
||
|
INTERNAL_ERROR_CHECK(Data->Header.ManifestOperation == MANIFEST_OPERATION_GENERATE_ACTIVATION_CONTEXT);
|
||
|
INTERNAL_ERROR_CHECK(GSGenContext != NULL);
|
||
|
IFW32FALSE_EXIT(::SxsGetGuidSectionGenerationContextSectionSize(GSGenContext, &Data->GetSectionSize.SectionSize));
|
||
|
Data->GetSectionSize.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 cbBytesWritten = 0;
|
||
|
|
||
|
// capture the name of the file
|
||
|
IFW32FALSE_EXIT(::SxspGetAttributeValue(
|
||
|
0,
|
||
|
&s_AttributeName_name,
|
||
|
&Data->ElementParsed,
|
||
|
fFound,
|
||
|
sizeof(FileNameBuffer),
|
||
|
&FileNameBuffer,
|
||
|
cbBytesWritten,
|
||
|
NULL,
|
||
|
NULL));
|
||
|
|
||
|
// If there's no NAME attribute, someone else will puke; we'll handle it
|
||
|
// gracefully.
|
||
|
if (fFound || (FileNameBuffer.Cch() == 0))
|
||
|
{
|
||
|
INTERNAL_ERROR_CHECK2(
|
||
|
ComGlobalContext != NULL,
|
||
|
"Window class context NULL while processing file element's name attribute.");
|
||
|
|
||
|
IFW32FALSE_EXIT(ComGlobalContext->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^comClass",
|
||
|
NUMBER_OF(L"urn:schemas-microsoft-com:asm.v1^assembly!urn:schemas-microsoft-com:asm.v1^file!urn:schemas-microsoft-com:asm.v1^comClass") - 1,
|
||
|
false) == 0))
|
||
|
{
|
||
|
bool fFound = false;
|
||
|
SIZE_T cb;
|
||
|
CSmallStringBuffer VersionIndependentComClassIdBuffer;
|
||
|
PCOM_SERVER_ENTRY Entry = NULL;
|
||
|
PCOM_FILE_CONTEXT FileContext = NULL;
|
||
|
CStringBuffer TempBuffer;
|
||
|
CSmallStringBuffer ProgIdBuffer;
|
||
|
ULONG ThreadingModel;
|
||
|
GUID ReferenceClsid, ConfiguredClsid, ImplementedClsid;
|
||
|
GUID TypeLibraryId;
|
||
|
|
||
|
TypeLibraryId = GUID_NULL;
|
||
|
|
||
|
INTERNAL_ERROR_CHECK2(
|
||
|
ComGlobalContext != NULL,
|
||
|
"COM global context NULL while processing comClass tag");
|
||
|
|
||
|
IFW32FALSE_EXIT(
|
||
|
::SxspGetAttributeValue(
|
||
|
SXSP_GET_ATTRIBUTE_VALUE_FLAG_REQUIRED_ATTRIBUTE,
|
||
|
&s_AttributeName_clsid,
|
||
|
&Data->ElementParsed,
|
||
|
fFound,
|
||
|
sizeof(VersionIndependentComClassIdBuffer),
|
||
|
&VersionIndependentComClassIdBuffer,
|
||
|
cb,
|
||
|
NULL,
|
||
|
0));
|
||
|
|
||
|
INTERNAL_ERROR_CHECK(fFound);
|
||
|
|
||
|
IFW32FALSE_EXIT(::SxspParseGUID(VersionIndependentComClassIdBuffer,
|
||
|
VersionIndependentComClassIdBuffer.Cch(),
|
||
|
ReferenceClsid));
|
||
|
|
||
|
IFW32FALSE_EXIT(
|
||
|
::SxspGetAttributeValue(
|
||
|
0,
|
||
|
&s_AttributeName_threadingModel,
|
||
|
&Data->ElementParsed,
|
||
|
fFound,
|
||
|
sizeof(TempBuffer),
|
||
|
&TempBuffer,
|
||
|
cb,
|
||
|
NULL,
|
||
|
0));
|
||
|
|
||
|
if (fFound)
|
||
|
IFW32FALSE_EXIT(::SxspParseThreadingModel(TempBuffer, TempBuffer.Cch(), &ThreadingModel));
|
||
|
else
|
||
|
ThreadingModel = ACTIVATION_CONTEXT_DATA_COM_SERVER_REDIRECTION_THREADING_MODEL_SINGLE;
|
||
|
|
||
|
IFW32FALSE_EXIT(
|
||
|
::SxspGetAttributeValue(
|
||
|
0,
|
||
|
&s_AttributeName_progid,
|
||
|
&Data->ElementParsed,
|
||
|
fFound,
|
||
|
sizeof(ProgIdBuffer),
|
||
|
&ProgIdBuffer,
|
||
|
cb,
|
||
|
NULL,
|
||
|
0));
|
||
|
|
||
|
IFW32FALSE_EXIT(
|
||
|
::SxspGetAttributeValue(
|
||
|
0,
|
||
|
&s_AttributeName_tlbid,
|
||
|
&Data->ElementParsed,
|
||
|
fFound,
|
||
|
sizeof(TempBuffer),
|
||
|
&TempBuffer,
|
||
|
cb,
|
||
|
NULL,
|
||
|
0));
|
||
|
|
||
|
if (fFound)
|
||
|
IFW32FALSE_EXIT(::SxspParseGUID(TempBuffer, TempBuffer.Cch(), TypeLibraryId));
|
||
|
else
|
||
|
TypeLibraryId = GUID_NULL;
|
||
|
|
||
|
// That was sufficient if we are generating a context.
|
||
|
if (Data->Header.ManifestOperation == MANIFEST_OPERATION_GENERATE_ACTIVATION_CONTEXT)
|
||
|
{
|
||
|
BOOL fNewAllocate = FALSE;
|
||
|
IFW32FALSE_EXIT(Data->Header.ClsidMappingContext->Map->MapReferenceClsidToConfiguredClsid(
|
||
|
&ReferenceClsid,
|
||
|
Data->ElementParsed.AssemblyContext,
|
||
|
&ConfiguredClsid,
|
||
|
&ImplementedClsid));
|
||
|
|
||
|
// See if we already have a file context; if we do not, allocate one.
|
||
|
if (ComGlobalContext->m_FileNameBuffer.Cch() != 0)
|
||
|
{
|
||
|
IFALLOCFAILED_EXIT(FileContext = new COM_FILE_CONTEXT);
|
||
|
fNewAllocate = TRUE;
|
||
|
|
||
|
IFW32FALSE_EXIT(FileContext->m_FileNameBuffer.Win32Assign(ComGlobalContext->m_FileNameBuffer));
|
||
|
|
||
|
FileContext->m_Next = ComGlobalContext->m_FileContextListHead;
|
||
|
ComGlobalContext->m_FileContextListHead = FileContext;
|
||
|
ComGlobalContext->m_FileContextListCount++;
|
||
|
FileContext->m_ServerListHead = NULL;
|
||
|
FileContext->m_ServerListCount = 0;
|
||
|
FileContext->m_GlobalContext = ComGlobalContext;
|
||
|
}
|
||
|
else
|
||
|
FileContext = ComGlobalContext->m_FileContextListHead;
|
||
|
|
||
|
ASSERT(FileContext != NULL);
|
||
|
|
||
|
IFALLOCFAILED_EXIT(Entry = new COM_SERVER_ENTRY);
|
||
|
|
||
|
Entry->m_ShimType = ACTIVATION_CONTEXT_DATA_COM_SERVER_REDIRECTION_SHIM_TYPE_OTHER;
|
||
|
Entry->m_Next = FileContext->m_ServerListHead;
|
||
|
Entry->m_ReferenceClsid = ReferenceClsid;
|
||
|
Entry->m_ConfiguredClsid = ConfiguredClsid;
|
||
|
Entry->m_ImplementedClsid = ImplementedClsid;
|
||
|
Entry->m_TypeLibraryId = TypeLibraryId;
|
||
|
Entry->m_ThreadingModel = ThreadingModel;
|
||
|
Entry->m_FileContext = FileContext;
|
||
|
IFW32FALSE_EXIT(Entry->m_ProgIdBuffer.Win32Assign(ProgIdBuffer));
|
||
|
|
||
|
if (!::SxsAddGuidToGuidSectionGenerationContext(
|
||
|
(PGUID_SECTION_GENERATION_CONTEXT) Data->ElementParsed.Header.ActCtxGenContext,
|
||
|
&ReferenceClsid,
|
||
|
Entry,
|
||
|
Data->ElementParsed.AssemblyContext->AssemblyRosterIndex,
|
||
|
ERROR_SXS_DUPLICATE_CLSID))
|
||
|
{
|
||
|
if (fNewAllocate)
|
||
|
FUSION_DELETE_SINGLETON(FileContext);
|
||
|
FUSION_DELETE_SINGLETON(Entry);
|
||
|
goto Exit;
|
||
|
}
|
||
|
|
||
|
FileContext->m_ServerListHead = Entry;
|
||
|
FileContext->m_ServerListCount++;
|
||
|
|
||
|
// And we add another, indexed by the configured clsid
|
||
|
IFALLOCFAILED_EXIT(Entry = new COM_SERVER_ENTRY);
|
||
|
|
||
|
Entry->m_Next = FileContext->m_ServerListHead;
|
||
|
Entry->m_ReferenceClsid = ReferenceClsid;
|
||
|
Entry->m_ConfiguredClsid = ConfiguredClsid;
|
||
|
Entry->m_ImplementedClsid = ImplementedClsid;
|
||
|
Entry->m_TypeLibraryId = TypeLibraryId;
|
||
|
Entry->m_ThreadingModel = ThreadingModel;
|
||
|
Entry->m_FileContext = FileContext;
|
||
|
IFW32FALSE_EXIT(Entry->m_ProgIdBuffer.Win32Assign(ProgIdBuffer));
|
||
|
|
||
|
if (!::SxsAddGuidToGuidSectionGenerationContext(
|
||
|
(PGUID_SECTION_GENERATION_CONTEXT) Data->ElementParsed.Header.ActCtxGenContext,
|
||
|
&ConfiguredClsid,
|
||
|
Entry,
|
||
|
Data->ElementParsed.AssemblyContext->AssemblyRosterIndex,
|
||
|
ERROR_SXS_DUPLICATE_CLSID))
|
||
|
{
|
||
|
//if (fNewAllocate) // should not deleted here.
|
||
|
// FUSION_DELETE_SINGLETON(FileContext);
|
||
|
|
||
|
FUSION_DELETE_SINGLETON(Entry);
|
||
|
goto Exit;
|
||
|
}
|
||
|
|
||
|
FileContext->m_ServerListHead = Entry;
|
||
|
FileContext->m_ServerListCount++;
|
||
|
}
|
||
|
}
|
||
|
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^comInterfaceProxyStub",
|
||
|
NUMBER_OF(L"urn:schemas-microsoft-com:asm.v1^assembly!urn:schemas-microsoft-com:asm.v1^file!urn:schemas-microsoft-com:asm.v1^comInterfaceProxyStub") - 1,
|
||
|
false) == 0))
|
||
|
{
|
||
|
bool fFound = false;
|
||
|
SIZE_T cb;
|
||
|
PCOM_SERVER_ENTRY Entry = NULL;
|
||
|
PCOM_FILE_CONTEXT FileContext = NULL;
|
||
|
CStringBuffer TempBuffer;
|
||
|
ULONG ThreadingModel;
|
||
|
GUID ReferenceClsid, ConfiguredClsid, ImplementedClsid;
|
||
|
GUID TypeLibraryId, iid;
|
||
|
|
||
|
TypeLibraryId = GUID_NULL;
|
||
|
|
||
|
INTERNAL_ERROR_CHECK2(
|
||
|
ComGlobalContext != NULL,
|
||
|
"COM global context NULL while processing comInterfaceProxyStub tag");
|
||
|
|
||
|
IFW32FALSE_EXIT(
|
||
|
::SxspGetAttributeValue(
|
||
|
SXSP_GET_ATTRIBUTE_VALUE_FLAG_REQUIRED_ATTRIBUTE,
|
||
|
&s_AttributeName_iid,
|
||
|
&Data->ElementParsed,
|
||
|
fFound,
|
||
|
sizeof(iid),
|
||
|
&iid,
|
||
|
cb,
|
||
|
&::SxspValidateGuidAttribute,
|
||
|
0));
|
||
|
|
||
|
IFW32FALSE_EXIT(
|
||
|
::SxspGetAttributeValue(
|
||
|
0,
|
||
|
&s_AttributeName_proxyStubClsid32,
|
||
|
&Data->ElementParsed,
|
||
|
fFound,
|
||
|
sizeof(ReferenceClsid),
|
||
|
&ReferenceClsid,
|
||
|
cb,
|
||
|
&::SxspValidateGuidAttribute,
|
||
|
0));
|
||
|
|
||
|
if (!fFound)
|
||
|
ReferenceClsid = iid;
|
||
|
|
||
|
IFW32FALSE_EXIT(
|
||
|
::SxspGetAttributeValue(
|
||
|
0,
|
||
|
&s_AttributeName_threadingModel,
|
||
|
&Data->ElementParsed,
|
||
|
fFound,
|
||
|
sizeof(TempBuffer),
|
||
|
&TempBuffer,
|
||
|
cb,
|
||
|
NULL,
|
||
|
0));
|
||
|
|
||
|
if (fFound)
|
||
|
IFW32FALSE_EXIT(::SxspParseThreadingModel(TempBuffer, TempBuffer.Cch(), &ThreadingModel));
|
||
|
else
|
||
|
ThreadingModel = ACTIVATION_CONTEXT_DATA_COM_SERVER_REDIRECTION_THREADING_MODEL_SINGLE;
|
||
|
|
||
|
|
||
|
// That was sufficient if we are generating a context.
|
||
|
if (Data->Header.ManifestOperation == MANIFEST_OPERATION_GENERATE_ACTIVATION_CONTEXT)
|
||
|
{
|
||
|
BOOL fNewAllocate = FALSE;
|
||
|
IFW32FALSE_EXIT(Data->Header.ClsidMappingContext->Map->MapReferenceClsidToConfiguredClsid(
|
||
|
&ReferenceClsid,
|
||
|
Data->ElementParsed.AssemblyContext,
|
||
|
&ConfiguredClsid,
|
||
|
&ImplementedClsid));
|
||
|
|
||
|
// See if we already have a file context; if we do not, allocate one.
|
||
|
if (ComGlobalContext->m_FileNameBuffer.Cch() != 0)
|
||
|
{
|
||
|
IFALLOCFAILED_EXIT(FileContext = new COM_FILE_CONTEXT);
|
||
|
fNewAllocate = TRUE;
|
||
|
|
||
|
IFW32FALSE_EXIT(FileContext->m_FileNameBuffer.Win32Assign(ComGlobalContext->m_FileNameBuffer));
|
||
|
FileContext->m_Next = ComGlobalContext->m_FileContextListHead;
|
||
|
ComGlobalContext->m_FileContextListHead = FileContext;
|
||
|
ComGlobalContext->m_FileContextListCount++;
|
||
|
FileContext->m_ServerListHead = NULL;
|
||
|
FileContext->m_ServerListCount = 0;
|
||
|
FileContext->m_GlobalContext = ComGlobalContext;
|
||
|
}
|
||
|
else
|
||
|
FileContext = ComGlobalContext->m_FileContextListHead;
|
||
|
|
||
|
ASSERT(FileContext != NULL);
|
||
|
|
||
|
IFALLOCFAILED_EXIT(Entry = new COM_SERVER_ENTRY);
|
||
|
|
||
|
|
||
|
INTERNAL_ERROR_CHECK(FileContext != NULL);
|
||
|
|
||
|
Entry->m_ShimType = ACTIVATION_CONTEXT_DATA_COM_SERVER_REDIRECTION_SHIM_TYPE_OTHER;
|
||
|
Entry->m_Next = FileContext->m_ServerListHead;
|
||
|
Entry->m_ReferenceClsid = ReferenceClsid;
|
||
|
Entry->m_ConfiguredClsid = ConfiguredClsid;
|
||
|
Entry->m_ImplementedClsid = ImplementedClsid;
|
||
|
Entry->m_TypeLibraryId = GUID_NULL;
|
||
|
Entry->m_ThreadingModel = ThreadingModel;
|
||
|
Entry->m_FileContext = FileContext;
|
||
|
Entry->m_ProgIdBuffer.Clear();
|
||
|
|
||
|
if (!::SxsAddGuidToGuidSectionGenerationContext(
|
||
|
(PGUID_SECTION_GENERATION_CONTEXT) Data->ElementParsed.Header.ActCtxGenContext,
|
||
|
&ReferenceClsid,
|
||
|
Entry,
|
||
|
Data->ElementParsed.AssemblyContext->AssemblyRosterIndex,
|
||
|
ERROR_SXS_DUPLICATE_CLSID))
|
||
|
{
|
||
|
if (fNewAllocate)
|
||
|
FUSION_DELETE_SINGLETON(FileContext);
|
||
|
FUSION_DELETE_SINGLETON(Entry);
|
||
|
goto Exit;
|
||
|
}
|
||
|
|
||
|
FileContext->m_ServerListHead = Entry;
|
||
|
FileContext->m_ServerListCount++;
|
||
|
|
||
|
// And we add another, indexed by the configured clsid
|
||
|
IFALLOCFAILED_EXIT(Entry = new COM_SERVER_ENTRY);
|
||
|
|
||
|
Entry->m_Next = FileContext->m_ServerListHead;
|
||
|
Entry->m_ReferenceClsid = ReferenceClsid;
|
||
|
Entry->m_ConfiguredClsid = ConfiguredClsid;
|
||
|
Entry->m_ImplementedClsid = ImplementedClsid;
|
||
|
Entry->m_TypeLibraryId = GUID_NULL;
|
||
|
Entry->m_ThreadingModel = ThreadingModel;
|
||
|
Entry->m_FileContext = FileContext;
|
||
|
Entry->m_ProgIdBuffer.Clear();
|
||
|
|
||
|
if (!::SxsAddGuidToGuidSectionGenerationContext(
|
||
|
(PGUID_SECTION_GENERATION_CONTEXT) Data->ElementParsed.Header.ActCtxGenContext,
|
||
|
&ConfiguredClsid,
|
||
|
Entry,
|
||
|
Data->ElementParsed.AssemblyContext->AssemblyRosterIndex,
|
||
|
ERROR_SXS_DUPLICATE_CLSID))
|
||
|
{
|
||
|
//if (fNewAllocate) // should not deleted here.
|
||
|
// FUSION_DELETE_SINGLETON(FileContext);
|
||
|
|
||
|
FUSION_DELETE_SINGLETON(Entry);
|
||
|
goto Exit;
|
||
|
}
|
||
|
|
||
|
FileContext->m_ServerListHead = Entry;
|
||
|
FileContext->m_ServerListCount++;
|
||
|
}
|
||
|
}
|
||
|
else 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^clrClass",
|
||
|
NUMBER_OF(L"urn:schemas-microsoft-com:asm.v1^assembly!urn:schemas-microsoft-com:asm.v1^clrClass") - 1,
|
||
|
false) == 0))
|
||
|
{
|
||
|
bool fFound = false;
|
||
|
SIZE_T cb;
|
||
|
CSmallStringBuffer VersionIndependentComClassIdBuffer;
|
||
|
PCOM_SERVER_ENTRY Entry;
|
||
|
PCOM_FILE_CONTEXT FileContext;
|
||
|
CSmallStringBuffer TempBuffer;
|
||
|
CSmallStringBuffer ProgIdBuffer;
|
||
|
CSmallStringBuffer RuntimeVersionBuffer;
|
||
|
CSmallStringBuffer NameBuffer;
|
||
|
ULONG ThreadingModel;
|
||
|
GUID ReferenceClsid, ConfiguredClsid, ImplementedClsid;
|
||
|
GUID TypeLibraryId;
|
||
|
bool fIsFirstShim = false;
|
||
|
|
||
|
TypeLibraryId = GUID_NULL;
|
||
|
|
||
|
INTERNAL_ERROR_CHECK2(
|
||
|
ComGlobalContext != NULL,
|
||
|
"COM global context NULL while processing ndpClass tag");
|
||
|
|
||
|
IFW32FALSE_EXIT(
|
||
|
::SxspGetAttributeValue(
|
||
|
SXSP_GET_ATTRIBUTE_VALUE_FLAG_REQUIRED_ATTRIBUTE,
|
||
|
&s_AttributeName_name,
|
||
|
&Data->ElementParsed,
|
||
|
fFound,
|
||
|
sizeof(NameBuffer),
|
||
|
&NameBuffer,
|
||
|
cb,
|
||
|
NULL,
|
||
|
0));
|
||
|
|
||
|
INTERNAL_ERROR_CHECK(fFound);
|
||
|
|
||
|
IFW32FALSE_EXIT(
|
||
|
::SxspGetAttributeValue(
|
||
|
SXSP_GET_ATTRIBUTE_VALUE_FLAG_REQUIRED_ATTRIBUTE,
|
||
|
&s_AttributeName_clsid,
|
||
|
&Data->ElementParsed,
|
||
|
fFound,
|
||
|
sizeof(VersionIndependentComClassIdBuffer),
|
||
|
&VersionIndependentComClassIdBuffer,
|
||
|
cb,
|
||
|
NULL,
|
||
|
0));
|
||
|
|
||
|
INTERNAL_ERROR_CHECK(fFound);
|
||
|
|
||
|
IFW32FALSE_EXIT(
|
||
|
::SxspParseGUID(
|
||
|
VersionIndependentComClassIdBuffer,
|
||
|
VersionIndependentComClassIdBuffer.Cch(),
|
||
|
ReferenceClsid));
|
||
|
|
||
|
IFW32FALSE_EXIT(
|
||
|
::SxspGetAttributeValue(
|
||
|
0,
|
||
|
&s_AttributeName_threadingModel,
|
||
|
&Data->ElementParsed,
|
||
|
fFound,
|
||
|
sizeof(TempBuffer),
|
||
|
&TempBuffer,
|
||
|
cb,
|
||
|
NULL,
|
||
|
0));
|
||
|
|
||
|
if (fFound)
|
||
|
IFW32FALSE_EXIT(::SxspParseThreadingModel(TempBuffer, TempBuffer.Cch(), &ThreadingModel));
|
||
|
else
|
||
|
ThreadingModel = ACTIVATION_CONTEXT_DATA_COM_SERVER_REDIRECTION_THREADING_MODEL_BOTH;
|
||
|
|
||
|
IFW32FALSE_EXIT(
|
||
|
::SxspGetAttributeValue(
|
||
|
0,
|
||
|
&s_AttributeName_progid,
|
||
|
&Data->ElementParsed,
|
||
|
fFound,
|
||
|
sizeof(ProgIdBuffer),
|
||
|
&ProgIdBuffer,
|
||
|
cb,
|
||
|
NULL,
|
||
|
0));
|
||
|
|
||
|
IFW32FALSE_EXIT(
|
||
|
::SxspGetAttributeValue(
|
||
|
0,
|
||
|
&s_AttributeName_tlbid,
|
||
|
&Data->ElementParsed,
|
||
|
fFound,
|
||
|
sizeof(TempBuffer),
|
||
|
&TempBuffer,
|
||
|
cb,
|
||
|
NULL,
|
||
|
0));
|
||
|
|
||
|
if (fFound)
|
||
|
IFW32FALSE_EXIT(::SxspParseGUID(TempBuffer, TempBuffer.Cch(), TypeLibraryId));
|
||
|
else
|
||
|
TypeLibraryId = GUID_NULL;
|
||
|
|
||
|
IFW32FALSE_EXIT(
|
||
|
::SxspGetAttributeValue(
|
||
|
0,
|
||
|
&s_AttributeName_runtimeVersion,
|
||
|
&Data->ElementParsed,
|
||
|
fFound,
|
||
|
sizeof(RuntimeVersionBuffer),
|
||
|
&RuntimeVersionBuffer,
|
||
|
cb,
|
||
|
NULL,
|
||
|
0));
|
||
|
|
||
|
// That was sufficient if we are generating a context.
|
||
|
if (Data->Header.ManifestOperation == MANIFEST_OPERATION_GENERATE_ACTIVATION_CONTEXT)
|
||
|
{
|
||
|
if (ComGlobalContext->m_FirstShimNameBuffer.Cch() == 0)
|
||
|
{
|
||
|
fIsFirstShim = true;
|
||
|
IFW32FALSE_EXIT(ComGlobalContext->m_FirstShimNameBuffer.Win32Assign(L"MSCOREE.DLL", 11));
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
IFW32FALSE_EXIT(
|
||
|
ComGlobalContext->m_FirstShimNameBuffer.Win32Equals(
|
||
|
L"MSCOREE.DLL", 11,
|
||
|
fIsFirstShim,
|
||
|
true));
|
||
|
}
|
||
|
|
||
|
IFW32FALSE_EXIT(
|
||
|
Data->Header.ClsidMappingContext->Map->MapReferenceClsidToConfiguredClsid(
|
||
|
&ReferenceClsid,
|
||
|
Data->ElementParsed.AssemblyContext,
|
||
|
&ConfiguredClsid,
|
||
|
&ImplementedClsid));
|
||
|
|
||
|
|
||
|
|
||
|
// If we don't already have a file context for mscoree, then we have to create a new one.
|
||
|
if (ComGlobalContext->m_MscoreeFileContext == NULL)
|
||
|
{
|
||
|
IFALLOCFAILED_EXIT(FileContext = FUSION_NEW_SINGLETON(COM_FILE_CONTEXT));
|
||
|
IFW32FALSE_EXIT(FileContext->m_FileNameBuffer.Win32Assign("mscoree.dll", 11));
|
||
|
|
||
|
FileContext->m_Next = ComGlobalContext->m_FileContextListHead;
|
||
|
ComGlobalContext->m_FileContextListHead = FileContext;
|
||
|
ComGlobalContext->m_FileContextListCount++;
|
||
|
ComGlobalContext->m_MscoreeFileContext = FileContext;
|
||
|
FileContext->m_ServerListHead = NULL;
|
||
|
FileContext->m_ServerListCount = 0;
|
||
|
FileContext->m_GlobalContext = ComGlobalContext;
|
||
|
}
|
||
|
else
|
||
|
FileContext = ComGlobalContext->m_MscoreeFileContext;
|
||
|
|
||
|
|
||
|
#if 0
|
||
|
// See if we already have a file context; if we do not, allocate one.
|
||
|
if (ComGlobalContext->m_FileNameBuffer.Cch() != 0)
|
||
|
{
|
||
|
IFALLOCFAILED_EXIT(FileContext = FUSION_NEW_SINGLETON(COM_FILE_CONTEXT));
|
||
|
IFW32FALSE_EXIT(FileContext->m_FileNameBuffer.Win32Assign(ComGlobalContext->m_FileNameBuffer));
|
||
|
|
||
|
FileContext->m_Next = ComGlobalContext->m_FileContextListHead;
|
||
|
ComGlobalContext->m_FileContextListHead = FileContext;
|
||
|
ComGlobalContext->m_FileContextListCount++;
|
||
|
FileContext->m_ServerListHead = NULL;
|
||
|
FileContext->m_ServerListCount = 0;
|
||
|
FileContext->m_GlobalContext = ComGlobalContext;
|
||
|
}
|
||
|
else
|
||
|
FileContext = ComGlobalContext->m_FileContextListHead;
|
||
|
#endif
|
||
|
INTERNAL_ERROR_CHECK(FileContext != NULL);
|
||
|
|
||
|
IFALLOCFAILED_EXIT(Entry = FUSION_NEW_SINGLETON(COM_SERVER_ENTRY));
|
||
|
|
||
|
Entry->m_ShimType = ACTIVATION_CONTEXT_DATA_COM_SERVER_REDIRECTION_SHIM_TYPE_CLR_CLASS;
|
||
|
Entry->m_Next = FileContext->m_ServerListHead;
|
||
|
Entry->m_ReferenceClsid = ReferenceClsid;
|
||
|
Entry->m_ConfiguredClsid = ConfiguredClsid;
|
||
|
Entry->m_ImplementedClsid = ImplementedClsid;
|
||
|
Entry->m_TypeLibraryId = TypeLibraryId;
|
||
|
Entry->m_ThreadingModel = ThreadingModel;
|
||
|
Entry->m_FileContext = FileContext;
|
||
|
IFW32FALSE_EXIT(Entry->m_ProgIdBuffer.Win32Assign(ProgIdBuffer));
|
||
|
IFW32FALSE_EXIT(Entry->m_ShimNameBuffer.Win32Assign(L"MSCOREE.DLL", 11));
|
||
|
IFW32FALSE_EXIT(Entry->m_RuntimeVersionBuffer.Win32Assign(RuntimeVersionBuffer));
|
||
|
IFW32FALSE_EXIT(Entry->m_TypeNameBuffer.Win32Assign(NameBuffer));
|
||
|
Entry->m_IsFirstShim = fIsFirstShim;
|
||
|
|
||
|
IFW32FALSE_EXIT(
|
||
|
::SxsAddGuidToGuidSectionGenerationContext(
|
||
|
(PGUID_SECTION_GENERATION_CONTEXT) Data->ElementParsed.Header.ActCtxGenContext,
|
||
|
&ReferenceClsid,
|
||
|
Entry,
|
||
|
Data->ElementParsed.AssemblyContext->AssemblyRosterIndex,
|
||
|
ERROR_SXS_DUPLICATE_CLSID));
|
||
|
|
||
|
FileContext->m_ServerListHead = Entry;
|
||
|
FileContext->m_ServerListCount++;
|
||
|
|
||
|
// And we add another, indexed by the configured clsid
|
||
|
IFALLOCFAILED_EXIT(Entry = FUSION_NEW_SINGLETON(COM_SERVER_ENTRY));
|
||
|
|
||
|
Entry->m_ShimType = ACTIVATION_CONTEXT_DATA_COM_SERVER_REDIRECTION_SHIM_TYPE_CLR_CLASS;
|
||
|
Entry->m_Next = FileContext->m_ServerListHead;
|
||
|
Entry->m_ReferenceClsid = ReferenceClsid;
|
||
|
Entry->m_ConfiguredClsid = ConfiguredClsid;
|
||
|
Entry->m_ImplementedClsid = ImplementedClsid;
|
||
|
Entry->m_TypeLibraryId = TypeLibraryId;
|
||
|
Entry->m_ThreadingModel = ThreadingModel;
|
||
|
Entry->m_FileContext = FileContext;
|
||
|
IFW32FALSE_EXIT(Entry->m_ProgIdBuffer.Win32Assign(ProgIdBuffer));
|
||
|
IFW32FALSE_EXIT(Entry->m_ShimNameBuffer.Win32Assign(L"MSCOREE.DLL", 11));
|
||
|
IFW32FALSE_EXIT(Entry->m_TypeNameBuffer.Win32Assign(NameBuffer));
|
||
|
IFW32FALSE_EXIT(Entry->m_RuntimeVersionBuffer.Win32Assign(RuntimeVersionBuffer));
|
||
|
Entry->m_IsFirstShim = fIsFirstShim;
|
||
|
|
||
|
IFW32FALSE_EXIT(
|
||
|
::SxsAddGuidToGuidSectionGenerationContext(
|
||
|
(PGUID_SECTION_GENERATION_CONTEXT) Data->ElementParsed.Header.ActCtxGenContext,
|
||
|
&ConfiguredClsid,
|
||
|
Entry,
|
||
|
Data->ElementParsed.AssemblyContext->AssemblyRosterIndex,
|
||
|
ERROR_SXS_DUPLICATE_CLSID));
|
||
|
|
||
|
FileContext->m_ServerListHead = Entry;
|
||
|
FileContext->m_ServerListCount++;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Everything's groovy!
|
||
|
Data->ElementParsed.Success = TRUE;
|
||
|
break;
|
||
|
|
||
|
case ACTCTXCTB_CBREASON_GETSECTIONDATA:
|
||
|
Data->GetSectionData.Success = FALSE;
|
||
|
INTERNAL_ERROR_CHECK(GSGenContext != NULL);
|
||
|
INTERNAL_ERROR_CHECK(Data->Header.ManifestOperation == MANIFEST_OPERATION_GENERATE_ACTIVATION_CONTEXT);
|
||
|
IFW32FALSE_EXIT(::SxsGetGuidSectionGenerationContextSectionData(GSGenContext, Data->GetSectionData.SectionSize, Data->GetSectionData.SectionDataStart, NULL));
|
||
|
Data->GetSectionData.Success = TRUE;
|
||
|
break;
|
||
|
}
|
||
|
Exit:
|
||
|
;
|
||
|
}
|
||
|
|
||
|
BOOL
|
||
|
SxspComClassRedirectionGuidSectionGenerationCallback(
|
||
|
PVOID Context,
|
||
|
ULONG Reason,
|
||
|
PVOID CallbackData
|
||
|
)
|
||
|
{
|
||
|
BOOL fSuccess = FALSE;
|
||
|
|
||
|
FN_TRACE_WIN32(fSuccess);
|
||
|
|
||
|
PCOM_GLOBAL_CONTEXT ComGlobalContext = (PCOM_GLOBAL_CONTEXT) Context;
|
||
|
|
||
|
INTERNAL_ERROR_CHECK(CallbackData != NULL);
|
||
|
|
||
|
switch (Reason)
|
||
|
{
|
||
|
case GUID_SECTION_GENERATION_CONTEXT_CALLBACK_REASON_GETUSERDATASIZE:
|
||
|
{
|
||
|
INTERNAL_ERROR_CHECK(ComGlobalContext != NULL);
|
||
|
|
||
|
PGUID_SECTION_GENERATION_CONTEXT_CBDATA_GETUSERDATASIZE CBData =
|
||
|
(PGUID_SECTION_GENERATION_CONTEXT_CBDATA_GETUSERDATASIZE) CallbackData;
|
||
|
PCOM_FILE_CONTEXT FileContext = ComGlobalContext->m_FileContextListHead;
|
||
|
|
||
|
CBData->DataSize = 0;
|
||
|
|
||
|
// If we have a mscoree shim, add its size to the user data buffer area.
|
||
|
if (ComGlobalContext->m_FirstShimNameBuffer.Cch() != 0)
|
||
|
CBData->DataSize += ((ComGlobalContext->m_FirstShimNameBuffer.Cch() + 1) * sizeof(WCHAR));
|
||
|
|
||
|
while (FileContext != NULL)
|
||
|
{
|
||
|
CBData->DataSize += ((FileContext->m_FileNameBuffer.Cch() + 1) * sizeof(WCHAR));
|
||
|
FileContext = FileContext->m_Next;
|
||
|
}
|
||
|
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
case GUID_SECTION_GENERATION_CONTEXT_CALLBACK_REASON_GETUSERDATA:
|
||
|
{
|
||
|
INTERNAL_ERROR_CHECK( ComGlobalContext != NULL );
|
||
|
|
||
|
PGUID_SECTION_GENERATION_CONTEXT_CBDATA_GETUSERDATA CBData =
|
||
|
(PGUID_SECTION_GENERATION_CONTEXT_CBDATA_GETUSERDATA) CallbackData;
|
||
|
SIZE_T BytesWritten = 0;
|
||
|
SIZE_T BytesLeft = CBData->BufferSize;
|
||
|
PWSTR Cursor = (PWSTR) CBData->Buffer;
|
||
|
PCOM_FILE_CONTEXT FileContext = ComGlobalContext->m_FileContextListHead;
|
||
|
|
||
|
if (ComGlobalContext->m_FirstShimNameBuffer.Cch() != 0)
|
||
|
{
|
||
|
IFW32FALSE_EXIT(
|
||
|
ComGlobalContext->m_FirstShimNameBuffer.Win32CopyIntoBuffer(
|
||
|
&Cursor,
|
||
|
&BytesLeft,
|
||
|
&BytesWritten,
|
||
|
CBData->SectionHeader,
|
||
|
&ComGlobalContext->m_FirstShimNameOffset,
|
||
|
&ComGlobalContext->m_FirstShimNameLength));
|
||
|
}
|
||
|
|
||
|
while (FileContext != NULL)
|
||
|
{
|
||
|
IFW32FALSE_EXIT(
|
||
|
FileContext->m_FileNameBuffer.Win32CopyIntoBuffer(
|
||
|
&Cursor,
|
||
|
&BytesLeft,
|
||
|
&BytesWritten,
|
||
|
CBData->SectionHeader,
|
||
|
&FileContext->m_Offset,
|
||
|
NULL)); // the length is tracked elsewhere
|
||
|
|
||
|
FileContext = FileContext->m_Next;
|
||
|
}
|
||
|
|
||
|
CBData->BytesWritten = BytesWritten;
|
||
|
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
case GUID_SECTION_GENERATION_CONTEXT_CALLBACK_REASON_ENTRYDELETED:
|
||
|
{
|
||
|
INTERNAL_ERROR_CHECK( ComGlobalContext != NULL );
|
||
|
|
||
|
PGUID_SECTION_GENERATION_CONTEXT_CBDATA_ENTRYDELETED CBData =
|
||
|
(PGUID_SECTION_GENERATION_CONTEXT_CBDATA_ENTRYDELETED) CallbackData;
|
||
|
PCOM_SERVER_ENTRY Entry = (PCOM_SERVER_ENTRY) CBData->DataContext;
|
||
|
|
||
|
if (Entry != NULL)
|
||
|
{
|
||
|
if (Entry->m_FileContext != NULL)
|
||
|
{
|
||
|
Entry->m_FileContext->m_ServerListCount--;
|
||
|
|
||
|
if (Entry->m_FileContext->m_ServerListCount == 0)
|
||
|
FUSION_DELETE_SINGLETON(Entry->m_FileContext);
|
||
|
}
|
||
|
|
||
|
FUSION_DELETE_SINGLETON(Entry);
|
||
|
}
|
||
|
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
case GUID_SECTION_GENERATION_CONTEXT_CALLBACK_REASON_GETDATASIZE:
|
||
|
{
|
||
|
PGUID_SECTION_GENERATION_CONTEXT_CBDATA_GETDATASIZE CBData =
|
||
|
(PGUID_SECTION_GENERATION_CONTEXT_CBDATA_GETDATASIZE) CallbackData;
|
||
|
PCOM_SERVER_ENTRY Entry = (PCOM_SERVER_ENTRY) CBData->DataContext;
|
||
|
|
||
|
CBData->DataSize = sizeof(ACTIVATION_CONTEXT_DATA_COM_SERVER_REDIRECTION);
|
||
|
|
||
|
if (Entry->m_ProgIdBuffer.Cch() != 0)
|
||
|
CBData->DataSize += ((Entry->m_ProgIdBuffer.Cch() + 1) * sizeof(WCHAR));
|
||
|
|
||
|
if (Entry->m_ShimNameBuffer.Cch() != 0)
|
||
|
{
|
||
|
CBData->DataSize += sizeof(ACTIVATION_CONTEXT_DATA_COM_SERVER_REDIRECTION_SHIM);
|
||
|
|
||
|
if (Entry->m_RuntimeVersionBuffer.Cch() != 0)
|
||
|
CBData->DataSize += ((Entry->m_RuntimeVersionBuffer.Cch() + 1) * sizeof(WCHAR));
|
||
|
|
||
|
if (!Entry->m_IsFirstShim)
|
||
|
CBData->DataSize += ((Entry->m_ShimNameBuffer.Cch() + 1) * sizeof(WCHAR));
|
||
|
|
||
|
if (Entry->m_TypeNameBuffer.Cch() != 0)
|
||
|
CBData->DataSize += ((Entry->m_TypeNameBuffer.Cch() + 1) * sizeof(WCHAR));
|
||
|
}
|
||
|
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
case GUID_SECTION_GENERATION_CONTEXT_CALLBACK_REASON_GETDATA:
|
||
|
{
|
||
|
PGUID_SECTION_GENERATION_CONTEXT_CBDATA_GETDATA CBData =
|
||
|
(PGUID_SECTION_GENERATION_CONTEXT_CBDATA_GETDATA) CallbackData;
|
||
|
PCOM_SERVER_ENTRY Entry = (PCOM_SERVER_ENTRY) CBData->DataContext;
|
||
|
PACTIVATION_CONTEXT_DATA_COM_SERVER_REDIRECTION Info;
|
||
|
PACTIVATION_CONTEXT_DATA_COM_SERVER_REDIRECTION_SHIM ShimInfo = NULL;
|
||
|
PVOID Cursor = CBData->Buffer;
|
||
|
|
||
|
SIZE_T BytesLeft = CBData->BufferSize;
|
||
|
SIZE_T BytesWritten = 0;
|
||
|
|
||
|
ALLOCATE_BUFFER_SPACE_TYPE(ACTIVATION_CONTEXT_DATA_COM_SERVER_REDIRECTION, Cursor, BytesLeft, BytesWritten, Info);
|
||
|
|
||
|
Info->Size = sizeof(ACTIVATION_CONTEXT_DATA_COM_SERVER_REDIRECTION);
|
||
|
Info->Flags = 0;
|
||
|
Info->ThreadingModel = Entry->m_ThreadingModel;
|
||
|
Info->ReferenceClsid = Entry->m_ReferenceClsid;
|
||
|
Info->ConfiguredClsid = Entry->m_ConfiguredClsid;
|
||
|
Info->ImplementedClsid = Entry->m_ImplementedClsid;
|
||
|
Info->TypeLibraryId = Entry->m_TypeLibraryId;
|
||
|
|
||
|
if (Entry->m_ShimNameBuffer.Cch() != 0)
|
||
|
{
|
||
|
PWSTR ShimName = NULL;
|
||
|
SIZE_T OldBytesWritten = BytesWritten;
|
||
|
SIZE_T ShimDataSize = 0;
|
||
|
|
||
|
ALLOCATE_BUFFER_SPACE_TYPE(ACTIVATION_CONTEXT_DATA_COM_SERVER_REDIRECTION_SHIM, Cursor, BytesLeft, BytesWritten, ShimInfo);
|
||
|
|
||
|
IFW32FALSE_EXIT(
|
||
|
Entry->m_TypeNameBuffer.Win32CopyIntoBuffer(
|
||
|
(PWSTR *) &Cursor,
|
||
|
&BytesLeft,
|
||
|
&BytesWritten,
|
||
|
ShimInfo,
|
||
|
&ShimInfo->TypeOffset,
|
||
|
&ShimInfo->TypeLength));
|
||
|
|
||
|
ShimInfo->ModuleLength = static_cast<ULONG>(Entry->m_FileContext->m_FileNameBuffer.Cch() * sizeof(WCHAR));
|
||
|
ShimInfo->ModuleOffset = Entry->m_FileContext->m_Offset;
|
||
|
|
||
|
IFW32FALSE_EXIT(
|
||
|
Entry->m_RuntimeVersionBuffer.Win32CopyIntoBuffer(
|
||
|
(PWSTR *) &Cursor,
|
||
|
&BytesLeft,
|
||
|
&BytesWritten,
|
||
|
ShimInfo,
|
||
|
&ShimInfo->ShimVersionOffset,
|
||
|
&ShimInfo->ShimVersionLength));
|
||
|
|
||
|
ShimDataSize = BytesWritten - OldBytesWritten;
|
||
|
|
||
|
if (Entry->m_IsFirstShim)
|
||
|
{
|
||
|
Info->ModuleOffset = Entry->m_FileContext->m_GlobalContext->m_FirstShimNameOffset;
|
||
|
Info->ModuleLength = Entry->m_FileContext->m_GlobalContext->m_FirstShimNameLength;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
IFW32FALSE_EXIT(
|
||
|
Entry->m_ShimNameBuffer.Win32CopyIntoBuffer(
|
||
|
(PWSTR *) &Cursor,
|
||
|
&BytesLeft,
|
||
|
&BytesWritten,
|
||
|
CBData->SectionHeader,
|
||
|
&Info->ModuleOffset,
|
||
|
&Info->ModuleLength));
|
||
|
}
|
||
|
|
||
|
ShimInfo->Size = sizeof(ACTIVATION_CONTEXT_DATA_COM_SERVER_REDIRECTION_SHIM);
|
||
|
ShimInfo->Flags = 0;
|
||
|
ShimInfo->Type = Entry->m_ShimType;
|
||
|
|
||
|
ShimInfo->DataLength = 0;
|
||
|
ShimInfo->DataOffset = 0;
|
||
|
|
||
|
Info->ShimDataLength = static_cast<ULONG>(ShimDataSize);
|
||
|
Info->ShimDataOffset = static_cast<ULONG>(((ULONG_PTR) ShimInfo) - ((ULONG_PTR) Info));
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
Info->ModuleLength = static_cast<ULONG>(Entry->m_FileContext->m_FileNameBuffer.Cch() * sizeof(WCHAR));
|
||
|
Info->ModuleOffset = Entry->m_FileContext->m_Offset;
|
||
|
Info->ShimDataLength = 0;
|
||
|
Info->ShimDataOffset = 0;
|
||
|
}
|
||
|
|
||
|
IFW32FALSE_EXIT(Entry->m_ProgIdBuffer.Win32CopyIntoBuffer(
|
||
|
(PWSTR *) &Cursor,
|
||
|
&BytesLeft,
|
||
|
&BytesWritten,
|
||
|
Info,
|
||
|
&Info->ProgIdOffset,
|
||
|
&Info->ProgIdLength));
|
||
|
|
||
|
CBData->BytesWritten = BytesWritten;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
fSuccess = TRUE;
|
||
|
Exit:
|
||
|
return fSuccess;
|
||
|
}
|
||
|
|