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.

416 lines
8.1 KiB

  1. // Copyright (c) 1997-1999 Microsoft Corporation
  2. //
  3. // netbios domain name page
  4. //
  5. // 1-6-98 sburns
  6. #include "headers.hxx"
  7. #include "page.hpp"
  8. #include "NetbiosNamePage.hpp"
  9. #include "common.hpp"
  10. #include "resource.h"
  11. #include "state.hpp"
  12. #include "ds.hpp"
  13. NetbiosNamePage::NetbiosNamePage()
  14. :
  15. DCPromoWizardPage(
  16. IDD_NETBIOS_NAME,
  17. IDS_NETBIOS_NAME_PAGE_TITLE,
  18. IDS_NETBIOS_NAME_PAGE_SUBTITLE)
  19. {
  20. LOG_CTOR(NetbiosNamePage);
  21. }
  22. NetbiosNamePage::~NetbiosNamePage()
  23. {
  24. LOG_DTOR(NetbiosNamePage);
  25. }
  26. void
  27. NetbiosNamePage::OnInit()
  28. {
  29. LOG_FUNCTION(NetbiosNamePage::OnInit);
  30. Win::Edit_LimitText(
  31. Win::GetDlgItem(hwnd, IDC_NETBIOS),
  32. DS::MAX_NETBIOS_NAME_LENGTH);
  33. State& state = State::GetInstance();
  34. if (state.UsingAnswerFile())
  35. {
  36. Win::SetDlgItemText(
  37. hwnd,
  38. IDC_NETBIOS,
  39. state.GetAnswerFileOption(State::OPTION_NEW_DOMAIN_NETBIOS_NAME));
  40. }
  41. }
  42. static
  43. void
  44. enable(HWND dialog)
  45. {
  46. ASSERT(Win::IsWindow(dialog));
  47. int next =
  48. !Win::GetTrimmedDlgItemText(dialog, IDC_NETBIOS).empty()
  49. ? PSWIZB_NEXT : 0;
  50. Win::PropSheet_SetWizButtons(
  51. Win::GetParent(dialog),
  52. PSWIZB_BACK | next);
  53. }
  54. bool
  55. NetbiosNamePage::OnCommand(
  56. HWND /* windowFrom */ ,
  57. unsigned controlIDFrom,
  58. unsigned code)
  59. {
  60. // LOG_FUNCTION(NetbiosNamePage::OnCommand);
  61. switch (controlIDFrom)
  62. {
  63. case IDC_NETBIOS:
  64. {
  65. if (code == EN_CHANGE)
  66. {
  67. SetChanged(controlIDFrom);
  68. enable(hwnd);
  69. }
  70. break;
  71. }
  72. default:
  73. {
  74. // do nothing
  75. break;
  76. }
  77. }
  78. return false;
  79. }
  80. HRESULT
  81. MyDsRoleDnsNameToFlatName(
  82. const String& domainDNSName,
  83. String& result,
  84. bool& nameWasTweaked)
  85. {
  86. LOG_FUNCTION(MyDsRoleDnsNameToFlatName);
  87. ASSERT(!domainDNSName.empty());
  88. nameWasTweaked = false;
  89. result.erase();
  90. LOG(L"Calling DsRoleDnsNameToFlatName");
  91. LOG( L"lpServer : (null)");
  92. LOG(String::format(L"lpDnsName : %1", domainDNSName.c_str()));
  93. PWSTR flatName = 0;
  94. ULONG flags = 0;
  95. HRESULT hr =
  96. Win32ToHresult(
  97. ::DsRoleDnsNameToFlatName(
  98. 0, // this server
  99. domainDNSName.c_str(),
  100. &flatName,
  101. &flags));
  102. LOG_HRESULT(hr);
  103. if (SUCCEEDED(hr) && flatName)
  104. {
  105. LOG(String::format(L"lpFlatName : %1", flatName));
  106. LOG(String::format(L"lpStatusFlag : %1!X!", flags));
  107. result = flatName;
  108. if (result.length() > DNLEN)
  109. {
  110. result.resize(DNLEN);
  111. }
  112. ::DsRoleFreeMemory(flatName);
  113. // the name was tweaked if it is not the default. 338443
  114. nameWasTweaked = !(flags & DSROLE_FLATNAME_DEFAULT);
  115. }
  116. return hr;
  117. }
  118. // return true if the name generated has already been validated, false
  119. // if not.
  120. bool
  121. GenerateDefaultNetbiosName(HWND parent)
  122. {
  123. LOG_FUNCTION(GenerateDefaultNetbiosName);
  124. ASSERT(Win::IsWindow(parent));
  125. Win::CursorSetting cursor(IDC_WAIT);
  126. bool result = false;
  127. String dnsDomainName = State::GetInstance().GetNewDomainDNSName();
  128. bool nameWasTweaked = false;
  129. String generatedName;
  130. HRESULT hr =
  131. MyDsRoleDnsNameToFlatName(
  132. dnsDomainName,
  133. generatedName,
  134. nameWasTweaked);
  135. if (FAILED(hr))
  136. {
  137. // if the api call failed, the name could not have been validated.
  138. result = false;
  139. // fall back to just the first 15 characters of the first label
  140. generatedName =
  141. dnsDomainName.substr(0, min(DNLEN, dnsDomainName.find(L'.')));
  142. LOG(String::format(L"falling back to %1", generatedName.c_str()));
  143. }
  144. else
  145. {
  146. // the api validated the name for us.
  147. result = true;
  148. }
  149. generatedName.to_upper();
  150. if (generatedName.is_numeric())
  151. {
  152. // the generated name is all-numeric. This is not allowed. So we
  153. // toss it out. 368777 bis
  154. generatedName.erase();
  155. nameWasTweaked = false;
  156. }
  157. Win::SetDlgItemText(
  158. parent,
  159. IDC_NETBIOS,
  160. generatedName);
  161. // inform the user that the default NetBIOS name was adjusted due
  162. // to name collision on the network
  163. if (nameWasTweaked)
  164. {
  165. popup.Info(
  166. parent,
  167. String::format(
  168. IDS_GENERATED_NAME_WAS_TWEAKED,
  169. generatedName.c_str()));
  170. }
  171. return result;
  172. }
  173. bool
  174. NetbiosNamePage::OnSetActive()
  175. {
  176. LOG_FUNCTION(NetbiosNamePage::OnSetActive);
  177. Win::PropSheet_SetWizButtons(
  178. Win::GetParent(hwnd),
  179. PSWIZB_BACK);
  180. State& state = State::GetInstance();
  181. if (state.RunHiddenUnattended())
  182. {
  183. int nextPage = Validate();
  184. if (nextPage != -1)
  185. {
  186. GetWizard().SetNextPageID(hwnd, nextPage);
  187. }
  188. else
  189. {
  190. state.ClearHiddenWhileUnattended();
  191. }
  192. }
  193. // do this here instead of in init to regenerate a default name if the
  194. // user has not annointed one already.
  195. if (
  196. !state.UsingAnswerFile()
  197. && state.GetNewDomainNetbiosName().empty())
  198. {
  199. // 338443
  200. if (GenerateDefaultNetbiosName(hwnd))
  201. {
  202. // Clear the changes so we don't validate the generated name: it's
  203. // supposed to already be valid.
  204. ClearChanges();
  205. }
  206. }
  207. enable(hwnd);
  208. return true;
  209. }
  210. bool
  211. ValidateDomainNetbiosName(HWND dialog, int editResID)
  212. {
  213. LOG_FUNCTION(ValidateDomainNetbiosName);
  214. ASSERT(Win::IsWindow(dialog));
  215. ASSERT(editResID > 0);
  216. Win::CursorSetting cursor(IDC_WAIT);
  217. String name = Win::GetTrimmedDlgItemText(dialog, editResID);
  218. if (name.empty())
  219. {
  220. return false;
  221. }
  222. if (name.find(L".") != String::npos)
  223. {
  224. popup.Gripe(
  225. dialog,
  226. editResID,
  227. IDS_NO_DOTS_IN_NETBIOS_NAME);
  228. return false;
  229. }
  230. // Check that the name is not a number. 368777
  231. if (name.is_numeric())
  232. {
  233. popup.Gripe(
  234. dialog,
  235. editResID,
  236. String::format(IDS_NUMERIC_NETBIOS_NAME, name.c_str()));
  237. return false;
  238. }
  239. // we pretend that the candidate name is a hostname, and attempt to
  240. // generate a netbios name from it. If that can't be done, then the
  241. // candidate name can't be a legal netbios name.
  242. HRESULT hr = S_OK;
  243. String s = Dns::HostnameToNetbiosName(name, &hr);
  244. if (FAILED(hr))
  245. {
  246. popup.Gripe(
  247. dialog,
  248. editResID,
  249. hr,
  250. String::format(IDS_BAD_NETBIOS_NAME, name.c_str()));
  251. return false;
  252. }
  253. if (s.length() < name.length())
  254. {
  255. // the name was truncated.
  256. popup.Gripe(
  257. dialog,
  258. editResID,
  259. String::format(
  260. IDS_NETBIOS_NAME_TOO_LONG,
  261. name.c_str(),
  262. DS::MAX_NETBIOS_NAME_LENGTH));
  263. return false;
  264. }
  265. if (ValidateNetbiosDomainName(s) != VALID_NAME)
  266. {
  267. popup.Gripe(
  268. dialog,
  269. editResID,
  270. String::format(
  271. IDS_BAD_NETBIOS_CHARACTERS,
  272. s.c_str()));
  273. return false;
  274. }
  275. hr = MyNetValidateName(name, ::NetSetupNonExistentDomain);
  276. if (hr == Win32ToHresult(ERROR_DUP_NAME))
  277. {
  278. popup.Gripe(
  279. dialog,
  280. editResID,
  281. String::format(IDS_FLATNAME_IN_USE, name.c_str()));
  282. return false;
  283. }
  284. if (hr == Win32ToHresult(ERROR_NETWORK_UNREACHABLE))
  285. {
  286. // 25968
  287. if (
  288. popup.MessageBox(
  289. dialog,
  290. String::format(
  291. IDS_NET_NOT_REACHABLE,
  292. name.c_str()),
  293. MB_YESNO | MB_ICONWARNING) != IDYES)
  294. {
  295. HWND edit = Win::GetDlgItem(dialog, editResID);
  296. Win::SendMessage(edit, EM_SETSEL, 0, -1);
  297. Win::SetFocus(edit);
  298. return false;
  299. }
  300. }
  301. return true;
  302. }
  303. int
  304. NetbiosNamePage::Validate()
  305. {
  306. LOG_FUNCTION(NetbiosNamePage::Validate);
  307. int nextPage = IDD_PATHS;
  308. if (WasChanged(IDC_NETBIOS))
  309. {
  310. if (!ValidateDomainNetbiosName(hwnd, IDC_NETBIOS))
  311. {
  312. nextPage = -1;
  313. }
  314. }
  315. if (nextPage != -1)
  316. {
  317. ClearChanges();
  318. State& state = State::GetInstance();
  319. state.SetNewDomainNetbiosName(
  320. Win::GetTrimmedDlgItemText(hwnd, IDC_NETBIOS));
  321. }
  322. return nextPage;
  323. }