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.

205 lines
4.6 KiB

  1. // Copyright (c) 1997-1999 Microsoft Corporation
  2. //
  3. // domain controller promotion wizard helper
  4. //
  5. // 8-13-99 sburns
  6. #include "headers.hxx"
  7. HINSTANCE hResourceModuleHandle = 0;
  8. const wchar_t* HELPFILE_NAME = 0;
  9. const wchar_t* RUNTIME_NAME = L"dcpromohelp";
  10. DWORD DEFAULT_LOGGING_OPTIONS =
  11. Log::OUTPUT_TO_FILE
  12. | Log::OUTPUT_FUNCCALLS
  13. | Log::OUTPUT_LOGS
  14. | Log::OUTPUT_ERRORS
  15. | Log::OUTPUT_HEADER;
  16. // Template function that actually calls ADsGetObject.
  17. //
  18. // Interface - The IADsXXX interface of the object to be bound.
  19. //
  20. // path - The ADSI path of the object to be bound.
  21. //
  22. // ptr - A null smart pointer to be bound to the interface of the object.
  23. template <class Interface>
  24. static
  25. HRESULT
  26. TemplateGetObject(
  27. const String& path,
  28. SmartInterface<Interface>& ptr)
  29. {
  30. LOG_FUNCTION2(TemplateGetObject, path);
  31. ASSERT(!path.empty());
  32. Interface* p = 0;
  33. HRESULT hr =
  34. ::ADsGetObject(
  35. path.c_str(),
  36. __uuidof(Interface),
  37. reinterpret_cast<void**>(&p));
  38. if (SUCCEEDED(hr))
  39. {
  40. ptr.Acquire(p);
  41. }
  42. return hr;
  43. }
  44. // Start csvde.exe with appropriate parameters, running without a window
  45. //
  46. // domainDn - full DN of the domain into which the display specifiers are
  47. // to be imported. e.g. DC=foo,DC=bar,DC=com
  48. HRESULT
  49. StartCsvde(const String& domainDn)
  50. {
  51. LOG_FUNCTION2(StartCsvde, domainDn);
  52. ASSERT(!domainDn.empty());
  53. // REVIEWED-2002/02/27-sburns we're passing full paths
  54. String windir = Win::GetSystemWindowsDirectory();
  55. String logPath = windir + L"\\debug";
  56. String sys32dir = Win::GetSystemDirectory();
  57. String csvPath = sys32dir + L"\\mui\\dispspec\\dcpromo.csv";
  58. String exePath = sys32dir + L"\\csvde.exe";
  59. String commandLine =
  60. String::format(
  61. L" -i -f %1 -c DOMAINPLACEHOLDER %2 -j %3",
  62. csvPath.c_str(),
  63. domainDn.c_str(),
  64. logPath.c_str());
  65. STARTUPINFO startupInfo;
  66. // REVIEWED-2002/02/27-sburns correct byte count passed
  67. ::ZeroMemory(&startupInfo, sizeof startupInfo);
  68. startupInfo.cb = sizeof(startupInfo);
  69. PROCESS_INFORMATION procInfo;
  70. // REVIEWED-2002/02/27-sburns correct byte count passed
  71. ::ZeroMemory(&procInfo, sizeof procInfo);
  72. LOG(L"Calling CreateProcess");
  73. LOG(exePath);
  74. LOG(commandLine);
  75. HRESULT hr =
  76. Win::CreateProcess(
  77. exePath,
  78. commandLine,
  79. CREATE_NO_WINDOW,
  80. String(),
  81. startupInfo,
  82. procInfo);
  83. LOG_HRESULT(hr);
  84. return hr;
  85. }
  86. HRESULT
  87. DoIt()
  88. {
  89. LOG_FUNCTION(DoIt);
  90. HRESULT hr = S_OK;
  91. do
  92. {
  93. AutoCoInitialize coInit;
  94. hr = coInit.Result();
  95. BREAK_ON_FAILED_HRESULT2(hr, L"CoInitialize failed");
  96. // make sure the DS is running. If it is, then this implies that the
  97. // local machine is a DC, the local machine is not in safe boot mode,
  98. // and the local machine is at least version >= 5
  99. if (!IsDSRunning())
  100. {
  101. LOG(L"Active Directory is not running -- unable to proceed");
  102. hr = E_FAIL;
  103. break;
  104. }
  105. // bind to the RootDse on the local machine
  106. SmartInterface<IADs> iads(0);
  107. hr = TemplateGetObject<IADs>(L"LDAP://RootDse", iads);
  108. BREAK_ON_FAILED_HRESULT2(hr, L"bind to rootdse failed");
  109. // read the default naming context. This is the DN of the domain for
  110. // which the machine is a domain controller.
  111. _variant_t variant;
  112. hr = iads->Get(AutoBstr(L"defaultNamingContext"), &variant);
  113. BREAK_ON_FAILED_HRESULT2(hr, L"bind to default naming context failed");
  114. String domainDn = V_BSTR(&variant);
  115. LOG(domainDn);
  116. ASSERT(!domainDn.empty());
  117. hr = StartCsvde(domainDn);
  118. BREAK_ON_FAILED_HRESULT(hr);
  119. }
  120. while (0);
  121. return hr;
  122. }
  123. int
  124. _cdecl
  125. main(int, char **)
  126. {
  127. LOG_FUNCTION(main);
  128. int exitCode = 0;
  129. HANDLE mutex = 0;
  130. // REVIEWED-2002/02/27-sburns This is a global named object, and subject to
  131. // squatting, but the consquenences of that are administrative annoyance
  132. // (the admin will have to manually import the display specifiers).
  133. HRESULT hr = Win::CreateMutex(0, true, RUNTIME_NAME, mutex);
  134. if (hr == Win32ToHresult(ERROR_ALREADY_EXISTS))
  135. {
  136. LOG(L"already running. That's weird.");
  137. exitCode = 1;
  138. }
  139. else
  140. {
  141. hr = DoIt();
  142. if (FAILED(hr))
  143. {
  144. LOG(GetErrorMessage(hr));
  145. exitCode = 2;
  146. }
  147. }
  148. return exitCode;
  149. }