Leaked source code of windows server 2003
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

  1. /*
  2. This uses the DOM.
  3. */
  4. #include "stdinc.h"
  5. #include "lhport.h"
  6. #include "sxshimlib.h"
  7. #include "regtoxml.h"
  8. #include "fusioncoinitialize.h"
  9. #include "fusionhandle.h"
  10. #include "fusionreg.h"
  11. #include "fusionregkey2.h"
  12. #include "fusionregenumvalues.h"
  13. #include "fusionregenumkeys.h"
  14. #include "delayimp.h"
  15. #include "debmacro.h"
  16. #include "fusionbuffer.h"
  17. #define DO(x) x
  18. void F::CRegToXml::Usage()
  19. {
  20. fprintf(stderr, "usage : regtoxml.exe configfile.xml outpuutfile.xml\n");
  21. ::TerminateProcess(::GetCurrentProcess(), ~0u);
  22. }
  23. class CRegToXmlRegistryRoot
  24. {
  25. public:
  26. HKEY PseudoHandle;
  27. PCWSTR Name;
  28. };
  29. const CRegToXmlRegistryRoot RegistryRoots[] =
  30. {
  31. { HKEY_LOCAL_MACHINE, L"HKEY_LOCAL_MACHINE" },
  32. //{ HKEY_USERS, L"HKEY_USERS" },
  33. //HKEY_CURRENT_USER, L"HKEY_CURRENT_USER",
  34. //
  35. // Danger: The registry is full of symbolic links that are not or are just
  36. // barely exposed at the Win32 layer. We could discover them, or buildin some
  37. // knowledge.
  38. //
  39. };
  40. _variant_t make_variant(MSXML2::tagDOMNodeType x)
  41. {
  42. VARIANT v;
  43. v.vt = VT_I2;
  44. v.iVal = static_cast<SHORT>(x);
  45. return v;
  46. }
  47. _variant_t make_variant(const F::CBaseStringBuffer & x)
  48. {
  49. return static_cast<PCWSTR>(x);
  50. }
  51. void ThrConvertRegistryDataToText(DWORD Type, const BYTE * Data, DWORD Size, F::CBaseStringBuffer & TextBuffer)
  52. {
  53. FN_PROLOG_VOID_THROW
  54. TextBuffer.Clear();
  55. switch (Type)
  56. {
  57. case REG_SZ:
  58. // UNDONE escape quotes
  59. DO(TextBuffer.ThrAppend(L"\"", 1));
  60. DO(TextBuffer.ThrAppend(reinterpret_cast<PCWSTR>(Data), Size / sizeof(WCHAR)));
  61. DO(TextBuffer.ThrAppend(L"\"", 1));
  62. break;
  63. default:
  64. // UNDONE
  65. break;
  66. }
  67. FN_EPILOG_THROW;
  68. }
  69. const CHAR IndentBlah[] =
  70. " "
  71. " ";
  72. const PCSTR Indent = IndentBlah + RTL_NUMBER_OF(IndentBlah) - 1;
  73. #define INDENT 2
  74. void F::CRegToXml::ThrDumpKey(ULONG Depth, MSXML2::IXMLDOMNodePtr ParentNode, HKEY ParentKey, PCWSTR Name)
  75. {
  76. FN_PROLOG_VOID_THROW
  77. if (Depth < 3)
  78. FusionpDbgPrint("FUSION: %s 1 %s(%ls)\n", Indent - INDENT * Depth, __FUNCTION__, Name);
  79. if (Depth > 100)
  80. FUSION_DEBUG_BREAK();
  81. {
  82. MSXML2::IXMLDOMNodePtr ChildNode;
  83. MSXML2::IXMLDOMElementPtr Element;
  84. DO(ChildNode = this->Document->createNode(make_variant(MSXML2::NODE_ELEMENT), L"key", L""));
  85. DO(Element = ChildNode);
  86. DO(Element->setAttribute(L"name", Name));
  87. DO(ParentNode->appendChild(ChildNode));
  88. ParentNode = ChildNode;
  89. }
  90. for (
  91. CRegEnumValues EnumValues(ParentKey);
  92. EnumValues;
  93. ++EnumValues
  94. )
  95. {
  96. MSXML2::IXMLDOMNodePtr ChildNode;
  97. MSXML2::IXMLDOMElementPtr Element;
  98. PCWSTR TypeAsString = L"";
  99. DO(ChildNode = this->Document->createNode(make_variant(MSXML2::NODE_ELEMENT), L"value", L""));
  100. DO(Element = ChildNode);
  101. DO(Element->setAttribute(L"name", make_variant(EnumValues.GetValueName())));
  102. IFW32FALSE_EXIT(RegistryTypeDwordToString(EnumValues.GetType(), TypeAsString));
  103. DO(Element->setAttribute(L"type", TypeAsString));
  104. DO(ThrConvertRegistryDataToText(
  105. EnumValues.GetType(),
  106. EnumValues.GetValueData(),
  107. EnumValues.GetValueDataSize(),
  108. this->ValueDataTextBuffer
  109. ));
  110. DO(Element->setAttribute(L"data", make_variant(this->ValueDataTextBuffer)));
  111. DO(ParentNode->appendChild(ChildNode));
  112. }
  113. //if (Depth < 4)
  114. // FusionpDbgPrint("FUSION: %s 2 %s(%ls)\n", Indent - INDENT * Depth, __FUNCTION__, Name);
  115. for (
  116. CRegEnumKeys EnumKeys(ParentKey);
  117. EnumKeys;
  118. ++EnumKeys
  119. )
  120. {
  121. F::CRegKey2 ChildKey;
  122. DO(ChildKey.ThrOpen(ParentKey, static_cast<PCWSTR>(EnumKeys)));
  123. DO(ThrDumpKey(Depth + 1, ParentNode, ChildKey, static_cast<PCWSTR>(EnumKeys)));
  124. //if (Depth < 4)
  125. // FusionpDbgPrint("FUSION: %s 3 %s(%ls)\n", Indent - INDENT * Depth, __FUNCTION__, Name);
  126. }
  127. FN_EPILOG_THROW;
  128. }
  129. void F::CRegToXml::ThrDumpBuiltinRoot(HKEY PseudoHandle, PCWSTR Name)
  130. {
  131. FN_PROLOG_VOID_THROW
  132. /*
  133. F::CRegKey2 Handle;
  134. HKEY RawHandle = NULL;
  135. IFREGFAILED_EXIT(::RegOpenKeyExW(PseudoHandle, NULL, 0, KEY_READ, &RawHandle));
  136. Handle = RawHandle;
  137. DO(ThrDumpKey(this->Document, Handle, Name));
  138. */
  139. DO(ThrDumpKey(0, this->Document, PseudoHandle, Name));
  140. FN_EPILOG_THROW;
  141. }
  142. void F::CRegToXml::ThrDumpBuiltinRoots()
  143. {
  144. ULONG i = 0;
  145. for ( i = 0 ; i != RTL_NUMBER_OF(RegistryRoots) ; ++i)
  146. {
  147. DO(ThrDumpBuiltinRoot(RegistryRoots[i].PseudoHandle, RegistryRoots[i].Name));
  148. }
  149. }
  150. void F::CRegToXml::ThrRegToXml()
  151. {
  152. //
  153. // argv[1] guides what we output
  154. // argv[2] is where we output
  155. //
  156. FN_PROLOG_VOID_THROW
  157. if (argc != 3)
  158. Usage();
  159. //F::CFile infile;
  160. //F::CFile outfile;
  161. F::CCoInitialize coinit;
  162. IFW32FALSE_EXIT(coinit.Win32Initialize());
  163. IFCOMFAILED_EXIT(this->Document.CreateInstance(L"msxml2.domdocument"));
  164. DO(ThrDumpBuiltinRoots());
  165. this->Document->save(this->argv[2]);
  166. FN_EPILOG_THROW;
  167. }
  168. int __cdecl wmain(int argc, PWSTR* argv)
  169. {
  170. F::g_hInstance = reinterpret_cast<HINSTANCE>(&__ImageBase);
  171. F::InitializeHeap();
  172. F::CRegToXml t;
  173. t.argc = argc;
  174. t.argv = argv;
  175. t.ThrRegToXml();
  176. F::UninitializeHeap();
  177. return 0;
  178. }