windows-nt/Source/XPSP1/NT/base/win32/fusion/sxs/parsepolicy.cpp
2020-09-26 16:20:57 +08:00

302 lines
8.5 KiB
C++

/*++
Copyright (c) 2000 Microsoft Corporation
Module Name:
parsepolicy.cpp
Abstract:
Functions to parse configuration (policy) manifests.
Author:
Michael J. Grier (MGrier) January 12, 2001
Revision History:
--*/
#include "stdinc.h"
#include <windows.h>
#include "sxsp.h"
#include "probedassemblyinformation.h"
#include "fusionparser.h"
#include "cteestream.h"
#include "cresourcestream.h"
#include "nodefactory.h"
#include "fusioneventlog.h"
#include "actctxgenctx.h"
extern CHAR NodefactoryTypeName[] = "CNodeFactory";
SxspComponentParsePolicyCore(
ULONG Flags,
PACTCTXGENCTX pGenContext,
const CProbedAssemblyInformation &PolicyAssemblyInformation,
CPolicyStatement *&rpPolicyStatement,
IStream *pSourceStream,
ACTCTXCTB_ASSEMBLY_CONTEXT *pAssemblyContext = NULL
)
{
BOOL fSuccess = FALSE;
FN_TRACE_WIN32(fSuccess);
CSxsPointer<CNodeFactory, NodefactoryTypeName> NodeFactory;
CSmartRef<IXMLParser> pIXmlParser;
PASSEMBLY Assembly = NULL;
CSxsPointerWithNamedDestructor<ASSEMBLY_IDENTITY, &::SxsDestroyAssemblyIdentity> AssemblyIdentity;
ACTCTXCTB_ASSEMBLY_CONTEXT LocalAssemblyContext;
STATSTG Stats;
ULONG i;
rpPolicyStatement = NULL;
PARAMETER_CHECK(pGenContext != NULL);
PARAMETER_CHECK(pSourceStream != NULL);
if (pAssemblyContext == NULL)
{
pAssemblyContext = &LocalAssemblyContext;
}
IFALLOCFAILED_EXIT(Assembly = new ASSEMBLY);
IFW32FALSE_EXIT(Assembly->m_Information.Initialize(PolicyAssemblyInformation));
//
// Copy the assembly identity, stick it into the callback structure
//
IFW32FALSE_EXIT(
::SxsDuplicateAssemblyIdentity(
0,
PolicyAssemblyInformation.GetAssemblyIdentity(),
&AssemblyIdentity));
//
// Set up the structure in general
//
pAssemblyContext->AssemblyIdentity = AssemblyIdentity.Detach();
IFW32FALSE_EXIT(
PolicyAssemblyInformation.GetManifestPath(
&pAssemblyContext->ManifestPath,
&pAssemblyContext->ManifestPathCch));
IFCOMFAILED_ORIGINATE_AND_EXIT(pSourceStream->Stat(&Stats, STATFLAG_NONAME));
//
// Set up the node factory
//
IFW32FALSE_EXIT(NodeFactory.Win32Allocate(__FILE__, __LINE__));
IFW32FALSE_EXIT(NodeFactory->Initialize(pGenContext, Assembly, pAssemblyContext));
IFCOMFAILED_ORIGINATE_AND_EXIT(NodeFactory->SetParseType(
XML_FILE_TYPE_COMPONENT_CONFIGURATION,
PolicyAssemblyInformation.GetManifestPathType(),
PolicyAssemblyInformation.GetManifestPath(),
Stats.mtime));
//
// Obtain the parser
//
IFW32FALSE_EXIT(::SxspGetXMLParser(IID_IXMLParser, (PVOID*)&pIXmlParser));
IFCOMFAILED_ORIGINATE_AND_EXIT(pIXmlParser->SetFactory(NodeFactory));
IFCOMFAILED_ORIGINATE_AND_EXIT(pIXmlParser->SetInput(pSourceStream));
//
// And they're off!
//
IFCOMFAILED_ORIGINATE_AND_EXIT(pIXmlParser->Run(-1));
//
// Tell the contributors we want to be done with this file...
//
for (i = 0; i < pGenContext->m_ContributorCount; i++)
{
IFW32FALSE_EXIT(pGenContext->m_Contributors[i].Fire_ParseEnding(pGenContext, pAssemblyContext));
}
rpPolicyStatement = NodeFactory->m_CurrentPolicyStatement;
NodeFactory->m_CurrentPolicyStatement = NULL;
fSuccess = TRUE;
Exit:
{
CSxsPreserveLastError ple;
for (i = 0; i < pGenContext->m_ContributorCount; i++)
{
pGenContext->m_Contributors[i].Fire_ParseEnded(pGenContext, pAssemblyContext);
}
if (Assembly != NULL)
Assembly->Release();
ple.Restore();
}
return fSuccess;
}
BOOL
SxspParseNdpGacComponentPolicy(
ULONG Flags,
PACTCTXGENCTX pGenContext,
const CProbedAssemblyInformation &PolicyAssemblyInformation,
CPolicyStatement *&rpPolicyStatement
)
{
FN_PROLOG_WIN32;
CResourceStream DllStream;
IFW32FALSE_EXIT(
DllStream.Initialize(
PolicyAssemblyInformation.GetManifestPath(),
MAKEINTRESOURCEW(RT_MANIFEST)));
IFW32FALSE_EXIT(SxspComponentParsePolicyCore(
Flags,
pGenContext,
PolicyAssemblyInformation,
rpPolicyStatement,
&DllStream));
FN_EPILOG;
}
BOOL
SxspParseComponentPolicy(
DWORD Flags,
PACTCTXGENCTX pActCtxGenCtx,
const CProbedAssemblyInformation &PolicyAssemblyInformation,
CPolicyStatement *&rpPolicyStatement
)
{
FN_PROLOG_WIN32;
CFileStream FileStream;
IFW32FALSE_EXIT(
FileStream.OpenForRead(
PolicyAssemblyInformation.GetManifestPath(),
CImpersonationData(),
FILE_SHARE_READ,
OPEN_EXISTING,
FILE_FLAG_SEQUENTIAL_SCAN));
IFW32FALSE_EXIT(SxspComponentParsePolicyCore(
Flags,
pActCtxGenCtx,
PolicyAssemblyInformation,
rpPolicyStatement,
&FileStream));
FN_EPILOG;
}
BOOL
SxspParseApplicationPolicy(
DWORD Flags,
PACTCTXGENCTX pActCtxGenCtx,
ULONG ulPolicyPathType,
PCWSTR pszPolicyPath,
SIZE_T cchPolicyPath,
IStream *pIStream
)
{
BOOL fSuccess = FALSE;
FN_TRACE_WIN32(fSuccess);
// declaration order here is partially deliberate, to control cleanup order.
// normally, declaration order is determined by not declaring until you have
// the data to initialize with the ctor, but the use of goto messes that up
CSxsPointer<CNodeFactory, NodefactoryTypeName> NodeFactory;
CSmartRef<IXMLParser> pIXMLParser;
ACTCTXCTB_ASSEMBLY_CONTEXT AssemblyContext;
ULONG i;
PASSEMBLY Assembly = NULL;
CStringBuffer buffPath;
STATSTG statstg;
PARAMETER_CHECK(Flags == 0);
PARAMETER_CHECK(pActCtxGenCtx != NULL);
PARAMETER_CHECK(ulPolicyPathType == ACTIVATION_CONTEXT_PATH_TYPE_WIN32_FILE);
IFALLOCFAILED_EXIT(Assembly = new ASSEMBLY);
IFW32FALSE_EXIT(buffPath.Win32Assign(pszPolicyPath, cchPolicyPath));
IFW32FALSE_EXIT(Assembly->m_Information.Initialize());
AssemblyContext.AssemblyIdentity = NULL;
AssemblyContext.Flags = 0;
AssemblyContext.AssemblyRosterIndex = 1; // hack alert
AssemblyContext.PolicyPathType = ulPolicyPathType;
AssemblyContext.PolicyPath = pszPolicyPath;
AssemblyContext.PolicyPathCch = cchPolicyPath;
AssemblyContext.ManifestPathType = ACTIVATION_CONTEXT_PATH_TYPE_NONE;
AssemblyContext.ManifestPath = NULL;
AssemblyContext.ManifestPathCch = 0;
AssemblyContext.TeeStreamForManifestInstall = NULL;
AssemblyContext.pcmWriterStream = NULL;
AssemblyContext.InstallationInfo = NULL;
AssemblyContext.AssemblySecurityContext = NULL;
AssemblyContext.TextuallyEncodedIdentity = NULL;
AssemblyContext.TextuallyEncodedIdentityCch = 0;
IFW32FALSE_EXIT(NodeFactory.Win32Allocate(__FILE__, __LINE__));
IFW32FALSE_EXIT(NodeFactory->Initialize(pActCtxGenCtx, Assembly, &AssemblyContext));
NodeFactory->m_pApplicationPolicyTable = &pActCtxGenCtx->m_ApplicationPolicyTable;
// Everyone's ready; let's get the XML parser:
IFW32FALSE_EXIT(::SxspGetXMLParser(IID_IXMLParser, (LPVOID *) &pIXMLParser));
IFCOMFAILED_ORIGINATE_AND_EXIT(pIXMLParser->SetFactory(NodeFactory));
IFCOMFAILED_EXIT(pIStream->Stat(&statstg, STATFLAG_NONAME));
// Open up the policy file and try parsing it...
IFW32FALSE_EXIT(
NodeFactory->SetParseType(
XML_FILE_TYPE_APPLICATION_CONFIGURATION,
ulPolicyPathType,
buffPath,
statstg.mtime));
IFCOMFAILED_ORIGINATE_AND_EXIT(pIXMLParser->SetInput(pIStream));
IFCOMFAILED_ORIGINATE_AND_EXIT(pIXMLParser->Run(-1));
NodeFactory->m_CurrentPolicyStatement = NULL;
// Tell the contributors we want to be done with this file...
for (i=0; i<pActCtxGenCtx->m_ContributorCount; i++)
IFW32FALSE_EXIT(pActCtxGenCtx->m_Contributors[i].Fire_ParseEnding(pActCtxGenCtx, &AssemblyContext));
fSuccess = TRUE;
Exit:
CSxsPreserveLastError ple;
// And tell them we're done.
for (i=0; i<pActCtxGenCtx->m_ContributorCount; i++)
pActCtxGenCtx->m_Contributors[i].Fire_ParseEnded(pActCtxGenCtx, &AssemblyContext);
if ( ple.LastError() == ERROR_SXS_MANIFEST_PARSE_ERROR || ple.LastError() == ERROR_SXS_MANIFEST_FORMAT_ERROR)
{ // log a general failure eventlog
::FusionpLogError(MSG_SXS_PARSE_MANIFEST_FAILED);
}
if (Assembly != NULL)
Assembly->Release();
ple.Restore();
return fSuccess;
}