You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1176 lines
36 KiB
1176 lines
36 KiB
#include <windows.h>
|
|
#include <fusenetincludes.h>
|
|
#include <msxml2.h>
|
|
#include <stdio.h>
|
|
#include <md5.h>
|
|
#include "list.h"
|
|
#include "manifestnode.h"
|
|
#include "xmlutil.h"
|
|
#include "version.h"
|
|
|
|
#define ASSEMBLY L"assembly"
|
|
#define NAMESPACE_TITLE L"xmlns:asm_namespace_v1"
|
|
#define NAMESPACE_VALUE L"urn:schemas-microsoft-com:asm.v1"
|
|
#define MANIFEST_VERSION_TITLE L"manifestVersion"
|
|
#define MANIFEST_VERSION_VALUE L"1.0"
|
|
#define DESCRIPTION L"description"
|
|
#define ASSEMBLY_IDENTITY L"assemblyIdentity"
|
|
#define DEPENDENCY L"dependency"
|
|
#define DEPENDENCY_QUERY L"/assembly/dependency"
|
|
#define DEPENDANT_ASSEMBLY L"dependentAssembly"
|
|
#define INSTALL L"install"
|
|
#define CODEBASE L"codebase"
|
|
#define APPLICATION L"application"
|
|
#define SHELL_STATE L"shellState"
|
|
#define ACTIVATION L"activation"
|
|
#define FILE L"file"
|
|
#define FILE_NAME L"name"
|
|
#define FILE_HASH L"hash"
|
|
|
|
|
|
|
|
class __declspec(uuid("f6d90f11-9c73-11d3-b32e-00c04f990bb4")) private_MSXML_DOMDocument30;
|
|
|
|
#define HASHLENGTH 32
|
|
#define HASHSTRINGLENGTH HASHLENGTH+1
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////
|
|
// FowardSlash
|
|
/////////////////////////////////////////////////////////////////////////
|
|
VOID FowardSlash(LPWSTR pwz)
|
|
{
|
|
LPWSTR ptr = pwz;
|
|
|
|
while (*ptr)
|
|
{
|
|
if (*ptr == L'\\')
|
|
*ptr = L'/';
|
|
ptr++;
|
|
}
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////
|
|
// GetHash
|
|
/////////////////////////////////////////////////////////////////////////
|
|
HRESULT GetHash(LPCWSTR pwzFilename, LPWSTR *ppwzHash)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
HANDLE hFile = INVALID_HANDLE_VALUE;
|
|
DWORD dwLength = 0; // cblength
|
|
LPWSTR pwzHash = new WCHAR[HASHSTRINGLENGTH];
|
|
|
|
// BUGBUG - heap allocate large buffers like this.
|
|
unsigned char buffer[16384];
|
|
MD5_CTX md5c;
|
|
int i;
|
|
WCHAR* p;
|
|
|
|
if(!pwzHash)
|
|
{
|
|
hr = E_OUTOFMEMORY;
|
|
goto exit;
|
|
}
|
|
|
|
MD5Init(&md5c);
|
|
|
|
hFile = CreateFile(pwzFilename, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
|
|
|
|
if(hFile == INVALID_HANDLE_VALUE)
|
|
{
|
|
|
|
hr = HRESULT_FROM_WIN32(GetLastError());
|
|
printf("Open file error during hashing\n");
|
|
goto exit;
|
|
}
|
|
|
|
ZeroMemory(buffer, sizeof(buffer));
|
|
|
|
// BUGBUG - error checking here.
|
|
while(ReadFile(hFile, buffer, sizeof(buffer), &dwLength, NULL) && dwLength)
|
|
MD5Update(&md5c, buffer, (unsigned) dwLength);
|
|
|
|
CloseHandle(hFile);
|
|
MD5Final(&md5c);
|
|
|
|
// convert hash from byte array to hex
|
|
p = pwzHash;
|
|
for (int i = 0; i < sizeof(md5c.digest); i++)
|
|
{
|
|
wsprintf(p, L"%02X", md5c.digest[i]);
|
|
p += 2;
|
|
}
|
|
|
|
*ppwzHash = pwzHash;
|
|
pwzHash = NULL;
|
|
|
|
exit:
|
|
SAFEDELETEARRAY(pwzHash);
|
|
return hr;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////
|
|
// CreateXMLElement
|
|
/////////////////////////////////////////////////////////////////////////
|
|
HRESULT CreateXMLTextNode(IXMLDOMDocument2 *pXMLDoc, LPWSTR pwzText, IXMLDOMNode **ppNode)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
IXMLDOMNode *pNode = NULL;
|
|
BSTR bstrText = NULL;
|
|
|
|
bstrText = ::SysAllocString(pwzText);
|
|
if (!bstrText)
|
|
{
|
|
hr = E_OUTOFMEMORY;
|
|
goto exit;
|
|
}
|
|
|
|
if(FAILED(pXMLDoc->createTextNode(bstrText, (IXMLDOMText**)&pNode)))
|
|
goto exit;
|
|
|
|
*ppNode = pNode;
|
|
(*ppNode)->AddRef();
|
|
|
|
exit:
|
|
if (bstrText)
|
|
::SysFreeString(bstrText);
|
|
|
|
SAFERELEASE (pNode);
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////
|
|
// CreateXMLComment
|
|
/////////////////////////////////////////////////////////////////////////
|
|
HRESULT CreateXMLComment(IXMLDOMDocument2 *pXMLDoc, LPWSTR pwzComment,
|
|
IXMLDOMComment **ppComment)
|
|
{
|
|
HRESULT hr=S_OK;
|
|
BSTR bstrComment = NULL;
|
|
IXMLDOMComment *pComment = NULL;
|
|
|
|
bstrComment = ::SysAllocString(pwzComment);
|
|
if (!bstrComment)
|
|
{
|
|
hr = E_OUTOFMEMORY;
|
|
goto exit;
|
|
}
|
|
|
|
if(FAILED(hr = pXMLDoc->createComment(bstrComment, &pComment)))
|
|
goto exit;
|
|
|
|
*ppComment = pComment;
|
|
(*ppComment)->AddRef();
|
|
|
|
exit:
|
|
|
|
if (bstrComment)
|
|
::SysFreeString(bstrComment);
|
|
|
|
SAFERELEASE(pComment);
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////
|
|
// AddMgVersionAsComment
|
|
/////////////////////////////////////////////////////////////////////////
|
|
HRESULT AddMgVersionAsComment(IXMLDOMDocument2 *pXMLDoc, IXMLDOMNode **ppRoot)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
CString sComment;
|
|
IXMLDOMComment *pComment = NULL;
|
|
IXMLDOMNode *pNewNode = NULL;
|
|
|
|
// ASSERT(pXMLDoc && ppRoot);
|
|
|
|
sComment.Assign(L"Created using mg version ");
|
|
sComment.Append(VER_PRODUCTVERSION_STR_L);
|
|
|
|
if(FAILED(hr = CreateXMLComment(pXMLDoc, sComment._pwz, &pComment)))
|
|
goto exit;
|
|
|
|
if(*ppRoot)
|
|
{
|
|
if (FAILED(hr = (*ppRoot)->appendChild((IXMLDOMNode *)pComment, &pNewNode)))
|
|
goto exit;
|
|
}
|
|
else
|
|
{
|
|
if (FAILED(hr = pXMLDoc->appendChild((IXMLDOMNode *)pComment, ppRoot)))
|
|
goto exit;
|
|
}
|
|
|
|
exit:
|
|
|
|
SAFERELEASE(pNewNode);
|
|
SAFERELEASE(pComment);
|
|
return hr;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////
|
|
// CreateXMLElement
|
|
/////////////////////////////////////////////////////////////////////////
|
|
HRESULT CreateXMLElement(IXMLDOMDocument2 *pXMLDoc, LPWSTR pwzElementName,
|
|
IXMLDOMElement **ppElement)
|
|
{
|
|
HRESULT hr=S_OK;
|
|
BSTR bstrElementName = NULL;
|
|
IXMLDOMElement *pElement = NULL;
|
|
IXMLDOMNode *pNode =NULL, *pNewNode = NULL;
|
|
|
|
bstrElementName = ::SysAllocString(pwzElementName);
|
|
if (!bstrElementName)
|
|
{
|
|
hr = E_OUTOFMEMORY;
|
|
goto exit;
|
|
}
|
|
|
|
// NOTENOTE - createElement doesn't append the node to the doc
|
|
// so we're just using pXMLDoc for convenience of calling create.
|
|
if(FAILED(hr = pXMLDoc->createElement(bstrElementName, &pElement)))
|
|
goto exit;
|
|
|
|
*ppElement = pElement;
|
|
(*ppElement)->AddRef();
|
|
|
|
exit:
|
|
|
|
if (bstrElementName)
|
|
::SysFreeString(bstrElementName);
|
|
|
|
SAFERELEASE(pNode);
|
|
SAFERELEASE(pNewNode);
|
|
SAFERELEASE(pElement);
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////
|
|
// SetXMLElementAttribute
|
|
/////////////////////////////////////////////////////////////////////////
|
|
HRESULT SetXMLElementAttribute(IXMLDOMElement *pElement, LPWSTR pwzAttributeName,
|
|
LPWSTR pwzAttributeValue)
|
|
{
|
|
HRESULT hr=S_OK;
|
|
BSTR bstrAttributeName = NULL, bstrAttributeValue = NULL;
|
|
VARIANT varAttributeValue;
|
|
|
|
bstrAttributeName = ::SysAllocString(pwzAttributeName);
|
|
bstrAttributeValue = ::SysAllocString(pwzAttributeValue);
|
|
if (!bstrAttributeName || (!bstrAttributeValue && pwzAttributeValue))
|
|
{
|
|
hr = E_OUTOFMEMORY;
|
|
goto exit;
|
|
}
|
|
|
|
VariantInit(&varAttributeValue);
|
|
varAttributeValue.vt = VT_BSTR;
|
|
V_BSTR(&varAttributeValue) = bstrAttributeValue;
|
|
|
|
hr = pElement->setAttribute(bstrAttributeName, varAttributeValue);
|
|
|
|
exit:
|
|
|
|
if (bstrAttributeName)
|
|
::SysFreeString(bstrAttributeName);
|
|
|
|
if (bstrAttributeValue)
|
|
::SysFreeString(bstrAttributeValue);
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////
|
|
// CreateXMLAssemblyIdElement
|
|
/////////////////////////////////////////////////////////////////////////
|
|
HRESULT CreateXMLAssemblyIdElement(IXMLDOMDocument2 *pXMLDoc, IAssemblyIdentity *pAssemblyId,
|
|
IXMLDOMElement **ppElement)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
IXMLDOMElement *pASMIdElement = NULL;
|
|
LPWSTR pwzBuf = NULL;
|
|
DWORD ccBuf = 0;
|
|
CString sBuffer;
|
|
|
|
LPWSTR rpwzAttrNames[6] =
|
|
{
|
|
SXS_ASSEMBLY_IDENTITY_STD_ATTRIBUTE_NAME_TYPE,
|
|
SXS_ASSEMBLY_IDENTITY_STD_ATTRIBUTE_NAME_NAME,
|
|
SXS_ASSEMBLY_IDENTITY_STD_ATTRIBUTE_NAME_VERSION,
|
|
SXS_ASSEMBLY_IDENTITY_STD_ATTRIBUTE_NAME_PUBLIC_KEY_TOKEN,
|
|
SXS_ASSEMBLY_IDENTITY_STD_ATTRIBUTE_NAME_PROCESSOR_ARCHITECTURE,
|
|
SXS_ASSEMBLY_IDENTITY_STD_ATTRIBUTE_NAME_LANGUAGE,
|
|
};
|
|
|
|
//Create assemblyIdentity Element
|
|
if(FAILED(hr=CreateXMLElement(pXMLDoc, ASSEMBLY_IDENTITY, &pASMIdElement)))
|
|
goto exit;
|
|
|
|
for (int i = 0; i < 6; i++)
|
|
{
|
|
// BUGBUG - eventually, when we add support for type the only guy which
|
|
// is optional is the public key token.
|
|
if (FAILED(hr = pAssemblyId->GetAttribute(rpwzAttrNames[i], &pwzBuf, &ccBuf))
|
|
&& hr != HRESULT_FROM_WIN32(ERROR_NOT_FOUND))
|
|
goto exit;
|
|
else if (hr == S_OK)
|
|
{
|
|
sBuffer.TakeOwnership(pwzBuf, ccBuf);
|
|
hr = SetXMLElementAttribute(pASMIdElement, rpwzAttrNames[i], sBuffer._pwz);
|
|
}
|
|
else
|
|
hr = S_OK;
|
|
}
|
|
|
|
|
|
*ppElement = pASMIdElement;
|
|
(*ppElement)->AddRef();
|
|
|
|
|
|
exit:
|
|
SAFERELEASE(pASMIdElement);
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////
|
|
// CreateDependantAssemblyNode
|
|
/////////////////////////////////////////////////////////////////////////
|
|
HRESULT CreateDependantAssemblyNode(IXMLDOMDocument2 *pXMLDoc, ManifestNode*pManifestNode, IXMLDOMNode **ppDependantAssemblyNode)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
LPWSTR pwzBuf = NULL;
|
|
DWORD dwType;
|
|
IAssemblyIdentity *pAssemblyId = NULL;
|
|
IXMLDOMElement *pDependantAssemblyNode = NULL, *pElement = NULL;
|
|
IXMLDOMNode *pNewNode = NULL;
|
|
|
|
CString sCodeBase;
|
|
|
|
//Get ASMId for Unique Dependency
|
|
if(FAILED(hr = pManifestNode->GetAssemblyIdentity(&pAssemblyId)))
|
|
goto exit;
|
|
|
|
//Get the type of manifest
|
|
// - Private or GAC, for GACs you don't put the codebase.
|
|
if(FAILED(hr = pManifestNode->GetManifestType(&dwType)))
|
|
goto exit;
|
|
|
|
//Get Codebase of the Unique Dependancy
|
|
if(FAILED(hr = pManifestNode->GetManifestFilePath(&pwzBuf)))
|
|
goto exit;
|
|
sCodeBase.TakeOwnership(pwzBuf);
|
|
|
|
//Create a dependentAssembly node
|
|
if(FAILED(hr = CreateXMLElement(pXMLDoc, DEPENDANT_ASSEMBLY, &pDependantAssemblyNode)))
|
|
goto exit;
|
|
|
|
//Create the AssemblyId for the Dependant Assembly
|
|
if (FAILED(CreateXMLAssemblyIdElement(pXMLDoc, pAssemblyId, &pElement)))
|
|
goto exit;
|
|
|
|
if (FAILED(hr=pDependantAssemblyNode->appendChild((IXMLDOMNode *)pElement, &pNewNode)))
|
|
goto exit;
|
|
|
|
// Node is added and element, node can be released.
|
|
SAFERELEASE(pElement);
|
|
SAFERELEASE(pNewNode);
|
|
|
|
//read the codebase for this DependantAssembly
|
|
// GACs don't have a codebase.
|
|
if (1) // we need codebase for all assemblies (dwType == PRIVATE_ASSEMBLY)
|
|
{
|
|
if(FAILED(hr = CreateXMLElement(pXMLDoc, INSTALL, &pElement)))
|
|
goto exit;
|
|
|
|
FowardSlash(sCodeBase._pwz);
|
|
if(FAILED(hr = SetXMLElementAttribute(pElement, CODEBASE, sCodeBase._pwz)))
|
|
goto exit;
|
|
|
|
if (FAILED(hr=pDependantAssemblyNode->appendChild((IXMLDOMNode *)pElement, &pNewNode)))
|
|
goto exit;
|
|
|
|
SAFERELEASE(pElement);
|
|
SAFERELEASE(pNewNode);
|
|
}
|
|
|
|
*ppDependantAssemblyNode = pDependantAssemblyNode;
|
|
(*ppDependantAssemblyNode)->AddRef();
|
|
|
|
exit:
|
|
SAFERELEASE(pAssemblyId);
|
|
SAFERELEASE(pDependantAssemblyNode);
|
|
return hr;
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////
|
|
// GetNode
|
|
/////////////////////////////////////////////////////////////////////////
|
|
HRESULT GetNode(IXMLDOMDocument2 *pXMLDoc, LPCWSTR pwzNode, IXMLDOMNode **ppNode)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
BSTR bstrtQueryString;
|
|
|
|
IXMLDOMNode *pNode=NULL;
|
|
IXMLDOMNodeList *pNodeList = NULL;
|
|
LONG nNodes = 0;
|
|
|
|
bstrtQueryString = ::SysAllocString(pwzNode);
|
|
if (!bstrtQueryString)
|
|
{
|
|
hr = E_OUTOFMEMORY;
|
|
goto exit;
|
|
}
|
|
|
|
if ((hr = pXMLDoc->selectNodes(bstrtQueryString, &pNodeList)) != S_OK)
|
|
goto exit;
|
|
|
|
// NOTENOTE - nNodes > 1 should never happen because only one root node in doc.
|
|
hr = pNodeList->get_length(&nNodes);
|
|
if (nNodes > 1)
|
|
{
|
|
// multiple file callouts having the exact same file name/path within a single source assembly
|
|
hr = HRESULT_FROM_WIN32(ERROR_BAD_FORMAT);
|
|
goto exit;
|
|
}
|
|
else if (nNodes < 1)
|
|
{
|
|
hr = S_FALSE;
|
|
goto exit;
|
|
}
|
|
|
|
if ((hr = pNodeList->get_item(0, &pNode)) != S_OK)
|
|
{
|
|
hr = S_FALSE ? E_FAIL : hr;
|
|
goto exit;
|
|
}
|
|
|
|
*ppNode=pNode;
|
|
(*ppNode)->AddRef();
|
|
|
|
exit:
|
|
if(bstrtQueryString)
|
|
::SysFreeString(bstrtQueryString);
|
|
|
|
SAFERELEASE(pNodeList);
|
|
SAFERELEASE(pNode);
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////
|
|
// FormatXML
|
|
// Called recursively.
|
|
// BUGBUG - t-peterf to document why selectNodes should not be used when
|
|
// adding nodes to an existing document.
|
|
/////////////////////////////////////////////////////////////////////////
|
|
HRESULT FormatXML(IXMLDOMDocument2 *pXMLDoc, IXMLDOMNode *pRootNode, LONG dwLevel)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
IXMLDOMNode *pNode=NULL, *pNewNode=NULL;
|
|
IXMLDOMNode *pTextNode1=NULL, *pTextNode2=NULL;
|
|
CString sWhiteSpace1, sWhiteSpace2;
|
|
BOOL bHasChildren = FALSE;
|
|
int i = 0;
|
|
|
|
sWhiteSpace1.Assign(L"\n");
|
|
for (i = 0; i < (dwLevel-1); i++)
|
|
sWhiteSpace1.Append(L"\t");
|
|
|
|
sWhiteSpace2.Assign(L"\n");
|
|
for (i = 0; i < dwLevel; i++)
|
|
sWhiteSpace2.Append(L"\t");
|
|
|
|
hr = pRootNode->get_firstChild(&pNode);
|
|
while(pNode != NULL)
|
|
{
|
|
bHasChildren = TRUE;
|
|
|
|
// create whitespace with one extra tab.
|
|
if(FAILED(CreateXMLTextNode(pXMLDoc, sWhiteSpace2._pwz, &pTextNode2)))
|
|
goto exit;
|
|
|
|
VARIANT varRefNode;
|
|
VariantInit(&varRefNode);
|
|
varRefNode.vt = VT_UNKNOWN;
|
|
V_UNKNOWN(&varRefNode) = pNode;
|
|
|
|
if (FAILED(hr = pRootNode->insertBefore(pTextNode2, varRefNode, &pNewNode)))
|
|
goto exit;
|
|
SAFERELEASE(pNewNode);
|
|
SAFERELEASE(pTextNode2);
|
|
|
|
// Recursively call format on the node.
|
|
if (FAILED(FormatXML(pXMLDoc, pNode, dwLevel+1)))
|
|
goto exit;
|
|
|
|
pNode->get_nextSibling(&pNewNode);
|
|
|
|
SAFERELEASE(pNode);
|
|
pNode = pNewNode;
|
|
|
|
}
|
|
|
|
if (bHasChildren)
|
|
{
|
|
if(FAILED(CreateXMLTextNode(pXMLDoc, sWhiteSpace1._pwz, &pTextNode1)))
|
|
goto exit;
|
|
|
|
if (FAILED(hr = pRootNode->appendChild(pTextNode1, &pNewNode)))
|
|
goto exit;
|
|
}
|
|
|
|
exit:
|
|
return hr;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////
|
|
// CreateManifestFromAssembly
|
|
/////////////////////////////////////////////////////////////////////////
|
|
HRESULT CreateAppManifestTemplate(LPWSTR pwzTempFile)
|
|
{
|
|
HRESULT hr=S_OK;
|
|
IXMLDOMDocument2 *pXMLDoc = NULL;
|
|
IXMLDOMElement *pElement=NULL, *pChildElement=NULL, *pChildElement2=NULL, *pChildElement3=NULL;
|
|
IXMLDOMNode *pNewNode=NULL, *pRoot=NULL, *pTextNode = NULL;
|
|
|
|
if(FAILED(hr = CoCreateInstance(__uuidof(private_MSXML_DOMDocument30),
|
|
NULL, CLSCTX_INPROC_SERVER, IID_IXMLDOMDocument2, (void**)&pXMLDoc)))
|
|
goto exit;
|
|
|
|
/*
|
|
if(FAILED(hr = AddMgVersionAsComment(pXMLDoc, &pRoot)))
|
|
goto exit;
|
|
*/
|
|
|
|
//create the root assembly node and add the default properties
|
|
if(FAILED(hr = CreateXMLElement(pXMLDoc, ASSEMBLY, &pElement)))
|
|
goto exit;
|
|
|
|
if(FAILED(hr = SetXMLElementAttribute(pElement, NAMESPACE_TITLE, NAMESPACE_VALUE)))
|
|
goto exit;
|
|
|
|
if(FAILED(hr = SetXMLElementAttribute(pElement, MANIFEST_VERSION_TITLE, MANIFEST_VERSION_VALUE)))
|
|
goto exit;
|
|
|
|
//append the root to the DOMDocument
|
|
if (FAILED(hr = pXMLDoc->appendChild((IXMLDOMNode *)pElement, &pRoot)))
|
|
goto exit;
|
|
SAFERELEASE(pElement);
|
|
|
|
//create the tempate assemblyIdentity node with blank attributes
|
|
if(FAILED(hr = CreateXMLElement(pXMLDoc, ASSEMBLY_IDENTITY, &pElement)))
|
|
goto exit;
|
|
|
|
hr = SetXMLElementAttribute(pElement, L"type", L"application");
|
|
hr = SetXMLElementAttribute(pElement, L"name", L"");
|
|
hr = SetXMLElementAttribute(pElement, L"version", L"");
|
|
hr = SetXMLElementAttribute(pElement, L"processorArchitecture", L"");
|
|
hr = SetXMLElementAttribute(pElement, L"publicKeyToken", L"");
|
|
hr = SetXMLElementAttribute(pElement, L"language", L"");
|
|
|
|
//append this to the root node
|
|
if (FAILED(hr=pRoot->appendChild((IXMLDOMNode *)pElement, &pNewNode)))
|
|
goto exit;
|
|
SAFERELEASE(pElement);
|
|
SAFERELEASE(pNewNode);
|
|
|
|
//create a sample description
|
|
if(FAILED(hr = CreateXMLElement(pXMLDoc, DESCRIPTION, &pElement)))
|
|
goto exit;
|
|
|
|
if(FAILED(hr = CreateXMLTextNode(pXMLDoc, L"Put a description of your application here", &pTextNode)))
|
|
goto exit;
|
|
|
|
if (FAILED(hr=pElement->appendChild(pTextNode, &pNewNode)))
|
|
goto exit;
|
|
|
|
SAFERELEASE(pNewNode);
|
|
SAFERELEASE(pTextNode);
|
|
|
|
if (FAILED(hr=pRoot->appendChild((IXMLDOMNode *)pElement, &pNewNode)))
|
|
goto exit;
|
|
|
|
SAFERELEASE(pNewNode);
|
|
SAFERELEASE(pElement);
|
|
|
|
//Create the shellState tag and enter in default information
|
|
if(FAILED(hr = CreateXMLElement(pXMLDoc, APPLICATION, &pElement)))
|
|
goto exit;
|
|
|
|
if(FAILED(hr = CreateXMLElement(pXMLDoc, SHELL_STATE, &pChildElement)))
|
|
goto exit;
|
|
|
|
if(FAILED(hr = SetXMLElementAttribute(pChildElement, L"friendlyName", L"")))
|
|
goto exit;
|
|
if(FAILED(hr = SetXMLElementAttribute(pChildElement, L"entryPoint", L"")))
|
|
goto exit;
|
|
if(FAILED(hr = SetXMLElementAttribute(pChildElement, L"entryImageType", L"")))
|
|
goto exit;
|
|
if(FAILED(hr = SetXMLElementAttribute(pChildElement, L"showCommand", L"")))
|
|
goto exit;
|
|
if(FAILED(hr = SetXMLElementAttribute(pChildElement, L"hotKey", L"")))
|
|
goto exit;
|
|
|
|
if (FAILED(hr=pElement->appendChild((IXMLDOMNode *)pChildElement, &pNewNode)))
|
|
goto exit;
|
|
SAFERELEASE (pNewNode);
|
|
SAFERELEASE(pChildElement);
|
|
|
|
if(FAILED(hr = CreateXMLElement(pXMLDoc, ACTIVATION, &pChildElement)))
|
|
goto exit;
|
|
|
|
if(FAILED(hr = SetXMLElementAttribute(pChildElement, L"assemblyName", L"")))
|
|
goto exit;
|
|
if(FAILED(hr = SetXMLElementAttribute(pChildElement, L"assemblyClass", L"")))
|
|
goto exit;
|
|
if(FAILED(hr = SetXMLElementAttribute(pChildElement, L"assemblyMethod", L"")))
|
|
goto exit;
|
|
if(FAILED(hr = SetXMLElementAttribute(pChildElement, L"assemblyMethodArgs", L"")))
|
|
goto exit;
|
|
|
|
if (FAILED(hr=pElement->appendChild((IXMLDOMNode *)pChildElement, &pNewNode)))
|
|
goto exit;
|
|
SAFERELEASE (pNewNode);
|
|
SAFERELEASE(pChildElement);
|
|
|
|
if (FAILED(hr=pRoot->appendChild((IXMLDOMNode *)pElement, &pNewNode)))
|
|
goto exit;
|
|
|
|
SAFERELEASE(pElement);
|
|
SAFERELEASE (pNewNode);
|
|
|
|
//Create the dependency platform tag and enter in default information
|
|
if(FAILED(hr = CreateXMLElement(pXMLDoc, L"dependency", &pElement)))
|
|
goto exit;
|
|
|
|
if(FAILED(hr = CreateXMLElement(pXMLDoc, L"platform", &pChildElement)))
|
|
goto exit;
|
|
|
|
if(FAILED(hr = CreateXMLElement(pXMLDoc, L"osVersionInfo", &pChildElement2)))
|
|
goto exit;
|
|
|
|
if(FAILED(hr = CreateXMLElement(pXMLDoc, L"os", &pChildElement3)))
|
|
goto exit;
|
|
|
|
if(FAILED(hr = SetXMLElementAttribute(pChildElement3, L"majorVersion", L"5")))
|
|
goto exit;
|
|
if(FAILED(hr = SetXMLElementAttribute(pChildElement3, L"minorVersion", L"1")))
|
|
goto exit;
|
|
if(FAILED(hr = SetXMLElementAttribute(pChildElement3, L"buildNumber", L"2600")))
|
|
goto exit;
|
|
if(FAILED(hr = SetXMLElementAttribute(pChildElement3, L"servicePackMajor", L"0")))
|
|
goto exit;
|
|
if(FAILED(hr = SetXMLElementAttribute(pChildElement3, L"servicePackMinor", L"0")))
|
|
goto exit;
|
|
|
|
if (FAILED(hr=pChildElement2->appendChild((IXMLDOMNode *)pChildElement3, NULL)))
|
|
goto exit;
|
|
SAFERELEASE (pChildElement3);
|
|
|
|
if (FAILED(hr=pChildElement->appendChild((IXMLDOMNode *)pChildElement2, NULL)))
|
|
goto exit;
|
|
SAFERELEASE (pChildElement2);
|
|
|
|
if(FAILED(hr = CreateXMLElement(pXMLDoc, L"platformInfo", &pChildElement2)))
|
|
goto exit;
|
|
|
|
if(FAILED(hr = SetXMLElementAttribute(pChildElement2, L"friendlyName", L"Microsoft Windows XP")))
|
|
goto exit;
|
|
if(FAILED(hr = SetXMLElementAttribute(pChildElement2, L"href", L"http://www.microsoft.com/windows")))
|
|
goto exit;
|
|
|
|
if (FAILED(hr=pChildElement->appendChild((IXMLDOMNode *)pChildElement2, NULL)))
|
|
goto exit;
|
|
SAFERELEASE (pChildElement2);
|
|
|
|
if (FAILED(hr=pElement->appendChild((IXMLDOMNode *)pChildElement, NULL)))
|
|
goto exit;
|
|
SAFERELEASE(pChildElement);
|
|
|
|
if(FAILED(hr = CreateXMLElement(pXMLDoc, L"platform", &pChildElement)))
|
|
goto exit;
|
|
|
|
if(FAILED(hr = CreateXMLElement(pXMLDoc, L"dotNetVersionInfo", &pChildElement2)))
|
|
goto exit;
|
|
|
|
if(FAILED(hr = CreateXMLElement(pXMLDoc, L"supportedRuntime", &pChildElement3)))
|
|
goto exit;
|
|
|
|
if(FAILED(hr = SetXMLElementAttribute(pChildElement3, L"version", L"v1.0.3705")))
|
|
goto exit;
|
|
|
|
if (FAILED(hr=pChildElement2->appendChild((IXMLDOMNode *)pChildElement3, NULL)))
|
|
goto exit;
|
|
SAFERELEASE (pChildElement3);
|
|
|
|
if (FAILED(hr=pChildElement->appendChild((IXMLDOMNode *)pChildElement2, NULL)))
|
|
goto exit;
|
|
SAFERELEASE (pChildElement2);
|
|
|
|
if(FAILED(hr = CreateXMLElement(pXMLDoc, L"platformInfo", &pChildElement2)))
|
|
goto exit;
|
|
|
|
if(FAILED(hr = SetXMLElementAttribute(pChildElement2, L"friendlyName", L"Microsoft .Net Frameworks")))
|
|
goto exit;
|
|
if(FAILED(hr = SetXMLElementAttribute(pChildElement2, L"href", L"http://www.microsoft.com/net")))
|
|
goto exit;
|
|
|
|
if (FAILED(hr=pChildElement->appendChild((IXMLDOMNode *)pChildElement2, NULL)))
|
|
goto exit;
|
|
SAFERELEASE (pChildElement2);
|
|
|
|
if (FAILED(hr=pElement->appendChild((IXMLDOMNode *)pChildElement, NULL)))
|
|
goto exit;
|
|
SAFERELEASE(pChildElement);
|
|
|
|
if (FAILED(hr=pRoot->appendChild((IXMLDOMNode *)pElement, NULL)))
|
|
goto exit;
|
|
|
|
SAFERELEASE(pElement);
|
|
|
|
//Format and save the document
|
|
if(FAILED(hr = FormatXML(pXMLDoc, pRoot, 1)))
|
|
goto exit;
|
|
|
|
if(FAILED(hr = SaveXMLDocument(pXMLDoc, pwzTempFile)))
|
|
goto exit;
|
|
|
|
printf("\nTemplate file created succesfully\n%ws\n", pwzTempFile);
|
|
exit:
|
|
|
|
SAFERELEASE(pXMLDoc);
|
|
SAFERELEASE(pElement);
|
|
SAFERELEASE(pChildElement3);
|
|
SAFERELEASE(pChildElement2);
|
|
SAFERELEASE(pChildElement);
|
|
SAFERELEASE(pNewNode);
|
|
SAFERELEASE(pTextNode);
|
|
SAFERELEASE(pRoot);
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////
|
|
// CreateSubscriptionManifest
|
|
/////////////////////////////////////////////////////////////////////////
|
|
HRESULT CreateXMLSubscriptionManifest(LPWSTR pwzSubscriptionPath,
|
|
IAssemblyIdentity *pApplictionAssemblyId, LPWSTR pwzUrl, LPWSTR pwzPollingInterval)
|
|
{
|
|
HRESULT hr=S_OK;
|
|
IXMLDOMDocument2 *pXMLDoc = NULL;
|
|
IXMLDOMElement *pElement=NULL, *pChildElement=NULL, *pDependantAssemblyNode=NULL;
|
|
IXMLDOMNode *pNewNode=NULL, *pRoot=NULL, *pTextNode = NULL, *pDependancyNode = NULL;
|
|
CString sSubscriptionPath, sSubscriptionName;
|
|
|
|
sSubscriptionPath.Assign(pwzSubscriptionPath);
|
|
sSubscriptionPath.LastElement(sSubscriptionName);
|
|
sSubscriptionPath.Append(L".manifest");
|
|
if(FAILED(hr = CoCreateInstance(__uuidof(private_MSXML_DOMDocument30),
|
|
NULL, CLSCTX_INPROC_SERVER, IID_IXMLDOMDocument2, (void**)&pXMLDoc)))
|
|
goto exit;
|
|
|
|
if(FAILED(hr = AddMgVersionAsComment(pXMLDoc, &pRoot)))
|
|
goto exit;
|
|
|
|
//create the root assembly node and add the default properties
|
|
if(FAILED(hr = CreateXMLElement(pXMLDoc, ASSEMBLY, &pElement)))
|
|
goto exit;
|
|
|
|
if(FAILED(hr = SetXMLElementAttribute(pElement, NAMESPACE_TITLE, NAMESPACE_VALUE)))
|
|
goto exit;
|
|
|
|
if(FAILED(hr = SetXMLElementAttribute(pElement, MANIFEST_VERSION_TITLE, MANIFEST_VERSION_VALUE)))
|
|
goto exit;
|
|
|
|
//append the root to the DOMDocument
|
|
if (FAILED(hr = pXMLDoc->appendChild((IXMLDOMNode *)pElement, &pRoot)))
|
|
goto exit;
|
|
SAFERELEASE(pElement);
|
|
|
|
//Create the AssemblyId for the Subscription
|
|
//Use the AssemblyId of the application, but change the name and type
|
|
if (FAILED(CreateXMLAssemblyIdElement(pXMLDoc, pApplictionAssemblyId, &pElement)))
|
|
goto exit;
|
|
// bugbug - check return code for consistency.
|
|
hr = SetXMLElementAttribute(pElement, L"type", L"subscription");
|
|
hr = SetXMLElementAttribute(pElement, L"name", sSubscriptionName._pwz);
|
|
|
|
if (FAILED(hr=pRoot->appendChild((IXMLDOMNode *)pElement, &pNewNode)))
|
|
goto exit;
|
|
|
|
SAFERELEASE(pElement);
|
|
SAFERELEASE(pNewNode);
|
|
|
|
//create a sample description
|
|
//bugbug, should grab description for original manifest and paste it here
|
|
if(FAILED(hr = CreateXMLElement(pXMLDoc, L"description", &pElement)))
|
|
goto exit;
|
|
|
|
if(FAILED(hr = CreateXMLTextNode(pXMLDoc, L"Put a description of your application here", &pTextNode)))
|
|
goto exit;
|
|
|
|
if (FAILED(hr=pElement->appendChild(pTextNode, &pNewNode)))
|
|
goto exit;
|
|
|
|
SAFERELEASE(pNewNode);
|
|
SAFERELEASE(pTextNode);
|
|
|
|
if (FAILED(hr=pRoot->appendChild((IXMLDOMNode *)pElement, &pNewNode)))
|
|
goto exit;
|
|
|
|
SAFERELEASE(pNewNode);
|
|
SAFERELEASE(pElement);
|
|
|
|
|
|
//Create the Dependancy Node
|
|
if(FAILED(hr = CreateXMLElement(pXMLDoc, DEPENDENCY, &pElement)))
|
|
goto exit;
|
|
if (FAILED(hr=pRoot->appendChild((IXMLDOMNode *)pElement, &pDependancyNode)))
|
|
goto exit;
|
|
SAFERELEASE(pElement);
|
|
|
|
|
|
//Create a dependentAssembly node
|
|
if(FAILED(hr = CreateXMLElement(pXMLDoc, DEPENDANT_ASSEMBLY, &pDependantAssemblyNode)))
|
|
goto exit;
|
|
|
|
//Create the AssemblyId for the Dependant Assembly
|
|
if (FAILED(CreateXMLAssemblyIdElement(pXMLDoc, pApplictionAssemblyId, &pElement)))
|
|
goto exit;
|
|
|
|
//Append the AssemblyId to the dependantAssemblyNode
|
|
if (FAILED(hr=pDependantAssemblyNode->appendChild((IXMLDOMNode *)pElement, &pNewNode)))
|
|
goto exit;
|
|
|
|
SAFERELEASE(pElement);
|
|
SAFERELEASE(pNewNode);
|
|
|
|
//Add the install codebase to the dependantAssemblyNode
|
|
if(FAILED(hr = CreateXMLElement(pXMLDoc, INSTALL, &pElement)))
|
|
goto exit;
|
|
|
|
if(FAILED(hr = SetXMLElementAttribute(pElement, CODEBASE, pwzUrl)))
|
|
goto exit;
|
|
|
|
if(FAILED(hr = SetXMLElementAttribute(pElement, L"type", L"required")))
|
|
goto exit;
|
|
|
|
if (FAILED(hr=pDependantAssemblyNode->appendChild((IXMLDOMNode *)pElement, &pNewNode)))
|
|
goto exit;
|
|
|
|
SAFERELEASE(pElement);
|
|
SAFERELEASE(pNewNode);
|
|
|
|
//Add the install codebase to the dependantAssemblyNode
|
|
if(FAILED(hr = CreateXMLElement(pXMLDoc, L"subscription", &pElement)))
|
|
goto exit;
|
|
|
|
if(FAILED(hr = SetXMLElementAttribute(pElement, L"synchronizeInterval", pwzPollingInterval)))
|
|
goto exit;
|
|
|
|
if(FAILED(hr = SetXMLElementAttribute(pElement, L"intervalUnit", L"hours")))
|
|
goto exit;
|
|
|
|
if(FAILED(hr = SetXMLElementAttribute(pElement, L"synchronizeEvent", L"onApplicationStartup")))
|
|
goto exit;
|
|
|
|
if(FAILED(hr = SetXMLElementAttribute(pElement, L"eventDemandConnection", L"no")))
|
|
goto exit;
|
|
|
|
if (FAILED(hr=pDependantAssemblyNode->appendChild((IXMLDOMNode *)pElement, &pNewNode)))
|
|
goto exit;
|
|
|
|
SAFERELEASE(pElement);
|
|
SAFERELEASE(pNewNode);
|
|
|
|
//Append the dependantAssemblyNode to the dependancy node
|
|
if (FAILED(hr=pDependancyNode->appendChild(pDependantAssemblyNode, &pNewNode)))
|
|
goto exit;
|
|
|
|
SAFERELEASE(pDependantAssemblyNode);
|
|
SAFERELEASE(pNewNode);
|
|
|
|
//Format and save the document
|
|
hr = FormatXML(pXMLDoc, pRoot, 1);
|
|
if(FAILED(hr = SaveXMLDocument(pXMLDoc, sSubscriptionPath._pwz)))
|
|
goto exit;
|
|
|
|
printf("Subscription manifest succesfully created\n%ws\n", sSubscriptionPath._pwz);
|
|
|
|
exit:
|
|
|
|
|
|
SAFERELEASE(pXMLDoc);
|
|
SAFERELEASE(pElement);
|
|
SAFERELEASE(pChildElement);
|
|
SAFERELEASE(pNewNode);
|
|
SAFERELEASE(pTextNode);
|
|
SAFERELEASE(pRoot);
|
|
SAFERELEASE(pDependancyNode);
|
|
SAFERELEASE(pDependantAssemblyNode);
|
|
|
|
return hr;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////
|
|
// CreateXMLAppManifest
|
|
// Creates the app manifest - may want to rename.
|
|
/////////////////////////////////////////////////////////////////////////
|
|
// NOTENOTE: rename pList -> pAsmList ?
|
|
HRESULT CreateXMLAppManifest(LPWSTR pwzAppBase, LPWSTR pwzTemplateFilePath, List<ManifestNode *> *pList, List<LPWSTR> *pFileList)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
DWORD cc = 0, cb = 0, ccName = 0;
|
|
LPWSTR pwz=NULL, pwzCodeBase = NULL, pwzName = NULL;
|
|
IAssemblyIdentity *pASMId= NULL;
|
|
IXMLDOMDocument2 *pXMLDoc=NULL;
|
|
IXMLDOMElement *pElement=NULL, *pAssemblyIdElement = NULL;
|
|
IXMLDOMNode *pRoot=NULL, *pDependancyNode = NULL, *pNewNode = NULL;
|
|
IXMLDOMNode *pAssemblyIdNode = NULL, *pDependantAssemblyNode=NULL;
|
|
BSTR bstrAttribute = NULL;
|
|
VARIANT varAttribute;
|
|
ManifestNode *pManNode = NULL;
|
|
CString sAppName, sFileName, sFileHash, sAbsoluteFilePath, sManifestFilePath;
|
|
LISTNODE pos = NULL;
|
|
|
|
VariantInit(&varAttribute);
|
|
//Load the template
|
|
if(FAILED(hr = LoadXMLDocument(pwzTemplateFilePath, &pXMLDoc)))
|
|
goto exit;
|
|
|
|
//grab the first child(the only child) as the root node
|
|
if(FAILED(hr = GetNode(pXMLDoc, ASSEMBLY, &pRoot)))
|
|
goto exit;
|
|
|
|
if (hr == S_FALSE)
|
|
{
|
|
hr = E_INVALIDARG;
|
|
goto exit;
|
|
}
|
|
|
|
//Get the name from the assemblyId, this will be the manifests file name
|
|
if(FAILED(hr = pRoot->get_firstChild(&pAssemblyIdNode)))
|
|
goto exit;
|
|
|
|
//Query for the Element interface
|
|
if (FAILED(hr = pAssemblyIdNode->QueryInterface(IID_IXMLDOMElement, (void**) &pAssemblyIdElement)))
|
|
goto exit;
|
|
|
|
bstrAttribute = ::SysAllocString(L"name");
|
|
if (!bstrAttribute)
|
|
{
|
|
hr = E_OUTOFMEMORY;
|
|
goto exit;
|
|
}
|
|
|
|
if ((hr = pAssemblyIdElement->getAttribute(bstrAttribute, &varAttribute)) != S_OK)
|
|
goto exit;
|
|
|
|
ccName = ::SysStringLen(varAttribute.bstrVal) + 1;
|
|
pwzName = new WCHAR[ccName];
|
|
if (!pwzName)
|
|
{
|
|
hr = E_OUTOFMEMORY;
|
|
goto exit;
|
|
}
|
|
memcpy(pwzName, varAttribute.bstrVal, ccName * sizeof(WCHAR));
|
|
|
|
if((*pwzName)== NULL)
|
|
{
|
|
hr = E_FAIL;
|
|
printf("Invalid Template Format. Template must have a name attribute in the assemblyIdentity tag\n");
|
|
goto exit;
|
|
}
|
|
|
|
::SysFreeString(varAttribute.bstrVal);
|
|
::SysFreeString(bstrAttribute);
|
|
SAFERELEASE(pAssemblyIdElement);
|
|
SAFERELEASE(pAssemblyIdNode);
|
|
|
|
|
|
if(FAILED(hr = AddMgVersionAsComment(pXMLDoc, &pRoot)))
|
|
goto exit;
|
|
|
|
// Add all the raw files to the manifest
|
|
pos = pFileList->GetHeadPosition();
|
|
while (pos)
|
|
{
|
|
pwz = pFileList->GetNext(pos);
|
|
sFileName.Assign(pwz);
|
|
|
|
if(FAILED(hr = CreateXMLElement(pXMLDoc, FILE, &pElement)))
|
|
goto exit;
|
|
|
|
if(FAILED(hr = SetXMLElementAttribute(pElement, FILE_NAME, sFileName._pwz)))
|
|
goto exit;
|
|
|
|
if (FAILED(hr=pRoot->appendChild((IXMLDOMNode *)pElement, &pNewNode)))
|
|
goto exit;
|
|
|
|
//Get Absolute File Path of file
|
|
sAbsoluteFilePath.Assign(pwzAppBase);
|
|
sAbsoluteFilePath.Append(sFileName);
|
|
|
|
//get the hash of the file
|
|
if(FAILED(hr = GetHash(sAbsoluteFilePath._pwz, &pwz)))
|
|
goto exit;
|
|
sFileHash.TakeOwnership(pwz);
|
|
|
|
if(FAILED(hr = SetXMLElementAttribute(pElement, FILE_HASH, sFileHash._pwz)))
|
|
goto exit;
|
|
|
|
SAFERELEASE(pNewNode);
|
|
}
|
|
|
|
// Get Dependency Node if exists
|
|
if (FAILED(hr = GetNode(pXMLDoc, DEPENDENCY_QUERY, &pDependancyNode)))
|
|
goto exit;
|
|
|
|
if (hr == S_FALSE)
|
|
{
|
|
//Create the Dependancy Node
|
|
if(FAILED(hr = CreateXMLElement(pXMLDoc, DEPENDENCY, &pElement)))
|
|
goto exit;
|
|
if (FAILED(hr=pRoot->appendChild((IXMLDOMNode *)pElement, &pDependancyNode)))
|
|
goto exit;
|
|
SAFERELEASE(pElement);
|
|
}
|
|
|
|
//Walk thorugh the list of dependant assemblies and add them to the App Manifest
|
|
pos = pList->GetHeadPosition();
|
|
while (pos)
|
|
{
|
|
//Get next Dependant Assembly from list
|
|
pManNode = pList->GetNext(pos);
|
|
if (FAILED(hr = CreateDependantAssemblyNode(pXMLDoc, pManNode, &pDependantAssemblyNode)))
|
|
goto exit;
|
|
|
|
if (FAILED(hr=pDependancyNode->appendChild(pDependantAssemblyNode, &pNewNode)))
|
|
goto exit;
|
|
|
|
SAFERELEASE(pDependantAssemblyNode);
|
|
SAFERELEASE(pNewNode);
|
|
}
|
|
|
|
//Indent the manifest
|
|
hr = FormatXML(pXMLDoc, pRoot, 1);
|
|
|
|
// Save the manifest to a file
|
|
sManifestFilePath.Assign(pwzAppBase);
|
|
sManifestFilePath.Append(pwzName);
|
|
sManifestFilePath.Append(L".manifest");
|
|
|
|
if(FAILED(hr = SaveXMLDocument(pXMLDoc, sManifestFilePath._pwz)))
|
|
goto exit;
|
|
|
|
printf("\nManifest created succesfully\n%ws\n", sManifestFilePath._pwz);
|
|
|
|
exit:
|
|
if (varAttribute.bstrVal)
|
|
::SysFreeString(varAttribute.bstrVal);
|
|
|
|
SAFEDELETEARRAY(pwzName);
|
|
|
|
SAFERELEASE(pXMLDoc);
|
|
SAFERELEASE(pElement);
|
|
SAFERELEASE(pAssemblyIdElement);
|
|
SAFERELEASE(pNewNode);
|
|
SAFERELEASE(pAssemblyIdNode);
|
|
SAFERELEASE(pRoot);
|
|
SAFERELEASE(pDependancyNode);
|
|
SAFERELEASE(pDependantAssemblyNode);
|
|
|
|
|
|
return hr;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////
|
|
// SaveXMLDocument
|
|
/////////////////////////////////////////////////////////////////////////
|
|
HRESULT SaveXMLDocument(IXMLDOMDocument2 *pXMLDoc, LPWSTR pwzDocumentName)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
CString sDocumentName;
|
|
BSTR bstrFileName = NULL;
|
|
VARIANT varFileName;
|
|
|
|
// Save the manifest to a file
|
|
sDocumentName.Assign(pwzDocumentName);
|
|
|
|
bstrFileName = ::SysAllocString(sDocumentName._pwz);
|
|
if (!bstrFileName)
|
|
{
|
|
hr = E_OUTOFMEMORY;
|
|
goto exit;
|
|
}
|
|
|
|
VariantInit(&varFileName);
|
|
varFileName.vt = VT_BSTR;
|
|
V_BSTR(&varFileName) = bstrFileName;
|
|
|
|
hr = pXMLDoc->save(varFileName);
|
|
|
|
exit:
|
|
if(bstrFileName)
|
|
::SysFreeString(bstrFileName);
|
|
|
|
return hr;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////
|
|
//LoadXMLDocument
|
|
/////////////////////////////////////////////////////////////////////////
|
|
HRESULT LoadXMLDocument(LPWSTR pwzDocumentPath, IXMLDOMDocument2 **ppXMLDoc)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
IXMLDOMDocument2 *pXMLDoc;
|
|
VARIANT varFileName;
|
|
VARIANT_BOOL varBool;
|
|
BSTR bstrFileName = NULL;
|
|
|
|
bstrFileName = ::SysAllocString(pwzDocumentPath);
|
|
if (!bstrFileName)
|
|
{
|
|
hr = E_OUTOFMEMORY;
|
|
goto exit;
|
|
}
|
|
|
|
VariantInit(&varFileName);
|
|
varFileName.vt = VT_BSTR;
|
|
V_BSTR(&varFileName) = bstrFileName;
|
|
|
|
if(FAILED(hr = CoCreateInstance(__uuidof(private_MSXML_DOMDocument30),
|
|
NULL, CLSCTX_INPROC_SERVER, IID_IXMLDOMDocument2, (void**)&pXMLDoc)))
|
|
goto exit;
|
|
|
|
// Load synchronously
|
|
if (FAILED(hr = pXMLDoc->put_async(VARIANT_FALSE)))
|
|
goto exit;
|
|
|
|
if ((hr = pXMLDoc->load(varFileName, &varBool)) != S_OK)
|
|
{
|
|
if(!varBool)
|
|
hr = E_INVALIDARG;
|
|
goto exit;
|
|
}
|
|
*ppXMLDoc=pXMLDoc;
|
|
(*ppXMLDoc)->AddRef();
|
|
|
|
exit:
|
|
if(bstrFileName)
|
|
::SysFreeString(bstrFileName);
|
|
SAFERELEASE(pXMLDoc);
|
|
return hr;
|
|
}
|