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.

370 lines
7.6 KiB

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