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.
222 lines
5.7 KiB
222 lines
5.7 KiB
/*
|
|
This uses the DOM.
|
|
*/
|
|
#include "stdinc.h"
|
|
#include "lhport.h"
|
|
#include "sxshimlib.h"
|
|
#include "regtoxml.h"
|
|
#include "fusioncoinitialize.h"
|
|
#include "fusionhandle.h"
|
|
#include "fusionreg.h"
|
|
#include "fusionregkey2.h"
|
|
#include "fusionregenumvalues.h"
|
|
#include "fusionregenumkeys.h"
|
|
#include "delayimp.h"
|
|
#include "debmacro.h"
|
|
#include "fusionbuffer.h"
|
|
|
|
#define DO(x) x
|
|
|
|
void F::CRegToXml::Usage()
|
|
{
|
|
fprintf(stderr, "usage : regtoxml.exe configfile.xml outpuutfile.xml\n");
|
|
::TerminateProcess(::GetCurrentProcess(), ~0u);
|
|
}
|
|
|
|
class CRegToXmlRegistryRoot
|
|
{
|
|
public:
|
|
HKEY PseudoHandle;
|
|
PCWSTR Name;
|
|
};
|
|
|
|
const CRegToXmlRegistryRoot RegistryRoots[] =
|
|
{
|
|
{ HKEY_LOCAL_MACHINE, L"HKEY_LOCAL_MACHINE" },
|
|
//{ HKEY_USERS, L"HKEY_USERS" },
|
|
//HKEY_CURRENT_USER, L"HKEY_CURRENT_USER",
|
|
//
|
|
// Danger: The registry is full of symbolic links that are not or are just
|
|
// barely exposed at the Win32 layer. We could discover them, or buildin some
|
|
// knowledge.
|
|
//
|
|
};
|
|
|
|
_variant_t make_variant(MSXML2::tagDOMNodeType x)
|
|
{
|
|
VARIANT v;
|
|
v.vt = VT_I2;
|
|
v.iVal = static_cast<SHORT>(x);
|
|
return v;
|
|
}
|
|
|
|
_variant_t make_variant(const F::CBaseStringBuffer & x)
|
|
{
|
|
return static_cast<PCWSTR>(x);
|
|
}
|
|
|
|
void ThrConvertRegistryDataToText(DWORD Type, const BYTE * Data, DWORD Size, F::CBaseStringBuffer & TextBuffer)
|
|
{
|
|
FN_PROLOG_VOID_THROW
|
|
TextBuffer.Clear();
|
|
switch (Type)
|
|
{
|
|
case REG_SZ:
|
|
// UNDONE escape quotes
|
|
DO(TextBuffer.ThrAppend(L"\"", 1));
|
|
DO(TextBuffer.ThrAppend(reinterpret_cast<PCWSTR>(Data), Size / sizeof(WCHAR)));
|
|
DO(TextBuffer.ThrAppend(L"\"", 1));
|
|
break;
|
|
|
|
default:
|
|
// UNDONE
|
|
break;
|
|
}
|
|
FN_EPILOG_THROW;
|
|
|
|
}
|
|
|
|
const CHAR IndentBlah[] =
|
|
" "
|
|
" ";
|
|
const PCSTR Indent = IndentBlah + RTL_NUMBER_OF(IndentBlah) - 1;
|
|
#define INDENT 2
|
|
|
|
void F::CRegToXml::ThrDumpKey(ULONG Depth, MSXML2::IXMLDOMNodePtr ParentNode, HKEY ParentKey, PCWSTR Name)
|
|
{
|
|
FN_PROLOG_VOID_THROW
|
|
|
|
if (Depth < 3)
|
|
FusionpDbgPrint("FUSION: %s 1 %s(%ls)\n", Indent - INDENT * Depth, __FUNCTION__, Name);
|
|
if (Depth > 100)
|
|
FUSION_DEBUG_BREAK();
|
|
|
|
{
|
|
MSXML2::IXMLDOMNodePtr ChildNode;
|
|
MSXML2::IXMLDOMElementPtr Element;
|
|
|
|
DO(ChildNode = this->Document->createNode(make_variant(MSXML2::NODE_ELEMENT), L"key", L""));
|
|
DO(Element = ChildNode);
|
|
|
|
DO(Element->setAttribute(L"name", Name));
|
|
DO(ParentNode->appendChild(ChildNode));
|
|
|
|
ParentNode = ChildNode;
|
|
}
|
|
|
|
for (
|
|
CRegEnumValues EnumValues(ParentKey);
|
|
EnumValues;
|
|
++EnumValues
|
|
)
|
|
{
|
|
MSXML2::IXMLDOMNodePtr ChildNode;
|
|
MSXML2::IXMLDOMElementPtr Element;
|
|
PCWSTR TypeAsString = L"";
|
|
|
|
DO(ChildNode = this->Document->createNode(make_variant(MSXML2::NODE_ELEMENT), L"value", L""));
|
|
DO(Element = ChildNode);
|
|
|
|
DO(Element->setAttribute(L"name", make_variant(EnumValues.GetValueName())));
|
|
|
|
IFW32FALSE_EXIT(RegistryTypeDwordToString(EnumValues.GetType(), TypeAsString));
|
|
DO(Element->setAttribute(L"type", TypeAsString));
|
|
|
|
DO(ThrConvertRegistryDataToText(
|
|
EnumValues.GetType(),
|
|
EnumValues.GetValueData(),
|
|
EnumValues.GetValueDataSize(),
|
|
this->ValueDataTextBuffer
|
|
));
|
|
DO(Element->setAttribute(L"data", make_variant(this->ValueDataTextBuffer)));
|
|
|
|
DO(ParentNode->appendChild(ChildNode));
|
|
}
|
|
|
|
//if (Depth < 4)
|
|
// FusionpDbgPrint("FUSION: %s 2 %s(%ls)\n", Indent - INDENT * Depth, __FUNCTION__, Name);
|
|
|
|
for (
|
|
CRegEnumKeys EnumKeys(ParentKey);
|
|
EnumKeys;
|
|
++EnumKeys
|
|
)
|
|
{
|
|
F::CRegKey2 ChildKey;
|
|
DO(ChildKey.ThrOpen(ParentKey, static_cast<PCWSTR>(EnumKeys)));
|
|
DO(ThrDumpKey(Depth + 1, ParentNode, ChildKey, static_cast<PCWSTR>(EnumKeys)));
|
|
//if (Depth < 4)
|
|
// FusionpDbgPrint("FUSION: %s 3 %s(%ls)\n", Indent - INDENT * Depth, __FUNCTION__, Name);
|
|
}
|
|
|
|
FN_EPILOG_THROW;
|
|
}
|
|
|
|
void F::CRegToXml::ThrDumpBuiltinRoot(HKEY PseudoHandle, PCWSTR Name)
|
|
{
|
|
FN_PROLOG_VOID_THROW
|
|
|
|
/*
|
|
F::CRegKey2 Handle;
|
|
HKEY RawHandle = NULL;
|
|
|
|
IFREGFAILED_EXIT(::RegOpenKeyExW(PseudoHandle, NULL, 0, KEY_READ, &RawHandle));
|
|
Handle = RawHandle;
|
|
|
|
DO(ThrDumpKey(this->Document, Handle, Name));
|
|
*/
|
|
DO(ThrDumpKey(0, this->Document, PseudoHandle, Name));
|
|
|
|
FN_EPILOG_THROW;
|
|
}
|
|
|
|
void F::CRegToXml::ThrDumpBuiltinRoots()
|
|
{
|
|
ULONG i = 0;
|
|
|
|
for ( i = 0 ; i != RTL_NUMBER_OF(RegistryRoots) ; ++i)
|
|
{
|
|
DO(ThrDumpBuiltinRoot(RegistryRoots[i].PseudoHandle, RegistryRoots[i].Name));
|
|
}
|
|
}
|
|
|
|
void F::CRegToXml::ThrRegToXml()
|
|
{
|
|
//
|
|
// argv[1] guides what we output
|
|
// argv[2] is where we output
|
|
//
|
|
FN_PROLOG_VOID_THROW
|
|
|
|
if (argc != 3)
|
|
Usage();
|
|
|
|
//F::CFile infile;
|
|
//F::CFile outfile;
|
|
|
|
F::CCoInitialize coinit;
|
|
IFW32FALSE_EXIT(coinit.Win32Initialize());
|
|
|
|
IFCOMFAILED_EXIT(this->Document.CreateInstance(L"msxml2.domdocument"));
|
|
DO(ThrDumpBuiltinRoots());
|
|
|
|
this->Document->save(this->argv[2]);
|
|
|
|
FN_EPILOG_THROW;
|
|
}
|
|
|
|
int __cdecl wmain(int argc, PWSTR* argv)
|
|
{
|
|
F::g_hInstance = reinterpret_cast<HINSTANCE>(&__ImageBase);
|
|
F::InitializeHeap();
|
|
|
|
F::CRegToXml t;
|
|
t.argc = argc;
|
|
t.argv = argv;
|
|
|
|
t.ThrRegToXml();
|
|
|
|
F::UninitializeHeap();
|
|
|
|
return 0;
|
|
}
|