/* 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(x); return v; } _variant_t make_variant(const F::CBaseStringBuffer & x) { return static_cast(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(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(EnumKeys))); DO(ThrDumpKey(Depth + 1, ParentNode, ChildKey, static_cast(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(&__ImageBase); F::InitializeHeap(); F::CRegToXml t; t.argc = argc; t.argv = argv; t.ThrRegToXml(); F::UninitializeHeap(); return 0; }