Source code of Windows XP (NT5)
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.

351 lines
7.3 KiB

  1. // Copyright (C) 1997 Microsoft Corporation
  2. //
  3. // paths, part 2 page
  4. //
  5. // 1-8-97 sburns
  6. #include "headers.hxx"
  7. #include "page.hpp"
  8. #include "Paths2Page.hpp"
  9. #include "resource.h"
  10. #include "state.hpp"
  11. #include "common.hpp"
  12. Paths2Page::Paths2Page()
  13. :
  14. DCPromoWizardPage(
  15. IDD_PATHS2,
  16. IDS_PATHS2_PAGE_TITLE,
  17. IDS_PATHS2_PAGE_SUBTITLE),
  18. touchWizButtons(true)
  19. {
  20. LOG_CTOR(Paths2Page);
  21. }
  22. Paths2Page::~Paths2Page()
  23. {
  24. LOG_DTOR(Paths2Page);
  25. }
  26. String
  27. DetermineDefaultSysvolPath()
  28. {
  29. LOG_FUNCTION(DetermineDefaultSysvolPath);
  30. // prefer windir, but if that's not ntfs 5, find one that is.
  31. String result = Win::GetSystemWindowsDirectory();
  32. if (FS::GetFileSystemType(result) != FS::NTFS5)
  33. {
  34. result = GetFirstNtfs5HardDrive();
  35. }
  36. else
  37. {
  38. result += L"\\";
  39. }
  40. LOG(result);
  41. return result;
  42. }
  43. void
  44. Paths2Page::OnInit()
  45. {
  46. LOG_FUNCTION(Paths2Page::OnInit);
  47. Win::Edit_LimitText(Win::GetDlgItem(hwnd, IDC_SYSVOL), MAX_PATH);
  48. State& state = State::GetInstance();
  49. if (state.UsingAnswerFile())
  50. {
  51. Win::SetDlgItemText(
  52. hwnd,
  53. IDC_SYSVOL,
  54. Win::ExpandEnvironmentStrings(
  55. state.GetAnswerFileOption(State::OPTION_SYSVOL_PATH)));
  56. }
  57. String root = DetermineDefaultSysvolPath();
  58. if (Win::GetTrimmedDlgItemText(hwnd, IDC_SYSVOL).empty())
  59. {
  60. Win::SetDlgItemText(
  61. hwnd,
  62. IDC_SYSVOL,
  63. root + String::load(IDS_SYSVOL_SUFFIX));
  64. }
  65. }
  66. void
  67. Paths2Page::Enable()
  68. {
  69. // touchWizButtons is managed in the OnCommand handler for EN_KILLFOCUS.
  70. // Turns out that if you call PropSheet_SetWizButtons while handling a kill
  71. // focus event, you mess up the tab processing so that the focus jumps to
  72. // the default wizard button. That's really cool -- NOT!
  73. if (touchWizButtons)
  74. {
  75. int next =
  76. !Win::GetTrimmedDlgItemText(hwnd, IDC_SYSVOL).empty()
  77. ? PSWIZB_NEXT : 0;
  78. Win::PropSheet_SetWizButtons(Win::GetParent(hwnd), PSWIZB_BACK | next);
  79. }
  80. }
  81. bool
  82. Paths2Page::OnCommand(
  83. HWND /* windowFrom */ ,
  84. unsigned controlIdFrom,
  85. unsigned code)
  86. {
  87. // LOG_FUNCTION(Paths2Page::OnCommand);
  88. bool result = false;
  89. switch (controlIdFrom)
  90. {
  91. case IDC_BROWSE:
  92. {
  93. if (code == BN_CLICKED)
  94. {
  95. String path = BrowseForFolder(hwnd, IDS_SYSVOL_BROWSE_TITLE);
  96. if (!path.empty())
  97. {
  98. Win::SetDlgItemText(hwnd, IDC_SYSVOL, path);
  99. }
  100. result = true;
  101. }
  102. break;
  103. }
  104. case IDC_SYSVOL:
  105. {
  106. switch (code)
  107. {
  108. case EN_CHANGE:
  109. {
  110. SetChanged(controlIdFrom);
  111. Enable();
  112. result = true;
  113. break;
  114. }
  115. case EN_KILLFOCUS:
  116. {
  117. // Since the normalization fully-expands relative paths, the
  118. // full pathname may not match what the user entered. So we
  119. // update the edit box contents to make sure they realize what
  120. // the relative path expands to.
  121. // NTRAID#NTBUG9-216148-2000/11/01-sburns
  122. String text = Win::GetTrimmedDlgItemText(hwnd, controlIdFrom);
  123. if (!text.empty())
  124. {
  125. // turn off setting of wizard buttons so that the call to
  126. // Enable made by the EN_CHANGE handler (which will be
  127. // called when we set the edit box text) will not call
  128. // PropSheet_SetWizButtons, which will mess up the tab
  129. // processing.
  130. touchWizButtons = false;
  131. Win::SetDlgItemText(
  132. hwnd,
  133. controlIdFrom,
  134. FS::NormalizePath(text));
  135. touchWizButtons = true;
  136. }
  137. result = true;
  138. break;
  139. }
  140. default:
  141. {
  142. // do nothing
  143. break;
  144. }
  145. }
  146. break;
  147. }
  148. default:
  149. {
  150. // do nothing
  151. break;
  152. }
  153. }
  154. return false;
  155. }
  156. bool
  157. Paths2Page::OnSetActive()
  158. {
  159. LOG_FUNCTION(Paths2Page::OnSetActive);
  160. Win::PropSheet_SetWizButtons(
  161. Win::GetParent(hwnd),
  162. PSWIZB_BACK);
  163. State& state = State::GetInstance();
  164. if (state.RunHiddenUnattended())
  165. {
  166. int nextPage = Validate();
  167. if (nextPage != -1)
  168. {
  169. GetWizard().SetNextPageID(hwnd, nextPage);
  170. }
  171. else
  172. {
  173. state.ClearHiddenWhileUnattended();
  174. }
  175. }
  176. Enable();
  177. return true;
  178. }
  179. // returns true if the path is valid, false if not. Pesters the user on
  180. // validation failures.
  181. bool
  182. ValidateSYSVOLPath(const String& path, HWND parent, unsigned editResID)
  183. {
  184. LOG_FUNCTION(validateSysvolPath);
  185. ASSERT(Win::IsWindow(parent));
  186. ASSERT(!path.empty());
  187. // check that the path is not the same as the database or log paths
  188. // previously entered. 313059
  189. State& state = State::GetInstance();
  190. String db = state.GetDatabasePath();
  191. if (db.icompare(path) == 0)
  192. {
  193. popup.Gripe(
  194. parent,
  195. editResID,
  196. String::format(IDS_SYSVOL_CANT_MATCH_DB, db.c_str()));
  197. return false;
  198. }
  199. String log = state.GetLogPath();
  200. if (log.icompare(path) == 0)
  201. {
  202. popup.Gripe(
  203. parent,
  204. editResID,
  205. String::format(IDS_SYSVOL_CANT_MATCH_LOG, log.c_str()));
  206. return false;
  207. }
  208. // check that the path is not a parent folder of the database or log
  209. // paths previously entered. 320685
  210. if (FS::IsParentFolder(path, db))
  211. {
  212. popup.Gripe(
  213. parent,
  214. editResID,
  215. String::format(IDS_SYSVOL_CANT_BE_DB_PARENT, db.c_str()));
  216. return false;
  217. }
  218. if (FS::IsParentFolder(path, log))
  219. {
  220. popup.Gripe(
  221. parent,
  222. editResID,
  223. String::format(IDS_SYSVOL_CANT_BE_LOG_PARENT, log.c_str()));
  224. return false;
  225. }
  226. // // if replicating from media, destination sysvol folder may not be any
  227. // // of the source paths.
  228. //
  229. // if (state.ReplicateFromMedia())
  230. // {
  231. // String p = state.GetReplicationSourcePath();
  232. // if (p.icompare(path) == 0)
  233. // {
  234. // popup.Gripe(
  235. // parent,
  236. // editResID,
  237. // String::format(IDS_SYSVOL_CANT_MATCH_SOURCE_PATH, p.c_str()));
  238. // return false;
  239. // }
  240. // }
  241. // if you change this, change the error message resource too.
  242. static const unsigned SYSVOL_MIN_SPACE_MB = 100;
  243. if (!CheckDiskSpace(path, SYSVOL_MIN_SPACE_MB))
  244. {
  245. popup.Gripe(
  246. parent,
  247. editResID,
  248. String::format(IDS_SYSVOL_LOW_SPACE, log.c_str()));
  249. return false;
  250. }
  251. return true;
  252. }
  253. int
  254. Paths2Page::Validate()
  255. {
  256. LOG_FUNCTION(Paths2Page::Validate);
  257. int nextPage = -1;
  258. String path =
  259. FS::NormalizePath(Win::GetTrimmedDlgItemText(hwnd, IDC_SYSVOL));
  260. if (
  261. ValidateDcInstallPath(path, hwnd, IDC_SYSVOL, true)
  262. && ValidateSYSVOLPath(path, hwnd, IDC_SYSVOL) )
  263. {
  264. State& state = State::GetInstance();
  265. state.SetSYSVOLPath(path);
  266. if (state.GetOperation() == State::FOREST)
  267. {
  268. nextPage = IDD_NEW_SITE;
  269. }
  270. else
  271. {
  272. nextPage = IDD_PICK_SITE;
  273. }
  274. }
  275. return nextPage;
  276. }