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.

459 lines
14 KiB

  1. /*++
  2. Copyright (C) Microsoft Corporation
  3. Module Name:
  4. genpage.cpp
  5. Abstract:
  6. This module implements CGeneralPage -- the snapin startup wizard page
  7. Author:
  8. William Hsieh (williamh) created
  9. Revision History:
  10. --*/
  11. #include "devmgr.h"
  12. #include "genpage.h"
  13. UINT g_cfDsObjectPicker = RegisterClipboardFormat(CFSTR_DSOP_DS_SELECTION_LIST);
  14. const DWORD g_a102HelpIDs[]=
  15. {
  16. IDC_GENERAL_SELECT_TEXT, IDH_DISABLEHELP,
  17. IDC_GENERAL_SELECTGROUP, IDH_DISABLEHELP,
  18. IDC_GENERAL_OVERRIDE_MACHINENAME, idh_devmgr_manage_command_line, // Device Manager: "Allo&w the selected computer to be changed when launching from the command line. This only applies if you save the console." (Button)
  19. IDC_GENERAL_LOCALMACHINE, idh_devmgr_manage_local, // Device Manager: "&Local computer: (the computer this console is running on)" (Button)
  20. IDC_GENERAL_OTHERMACHINE, idh_devmgr_manage_remote, // Device Manager: "&Another computer:" (Button)
  21. IDC_GENERAL_MACHINENAME, idh_devmgr_manage_remote_name, // Device Manager: "" (Edit)
  22. IDC_GENERAL_BROWSE_MACHINENAMES, idh_devmgr_manage_remote_browse, // Device Manager: "B&rowse..." (Button)
  23. 0, 0
  24. };
  25. CGeneralPage::CGeneralPage() : CPropSheetPage(g_hInstance, IDD_GENERAL_PAGE)
  26. {
  27. m_lConsoleHandle = 0;
  28. m_pstrMachineName = NULL;
  29. m_pct = NULL;
  30. m_MachineName[0] = _T('\0');
  31. m_IsLocalMachine = TRUE;
  32. m_ct = COOKIE_TYPE_SCOPEITEM_DEVMGR;
  33. }
  34. HPROPSHEETPAGE
  35. CGeneralPage::Create(
  36. LONG_PTR lConsoleHandle
  37. )
  38. {
  39. m_lConsoleHandle = lConsoleHandle;
  40. // override PROPSHEETPAGE structure here...
  41. m_psp.lParam = (LPARAM)this;
  42. return CPropSheetPage::CreatePage();
  43. }
  44. BOOL
  45. CGeneralPage::OnInitDialog(
  46. LPPROPSHEETPAGE ppsp
  47. )
  48. {
  49. UNREFERENCED_PARAMETER(ppsp);
  50. ASSERT(m_hDlg);
  51. //
  52. // Intiallly, enable the local machine and disable the
  53. // "Another" machine.
  54. //
  55. ::CheckDlgButton(m_hDlg, IDC_GENERAL_LOCALMACHINE, BST_CHECKED);
  56. ::CheckDlgButton(m_hDlg, IDC_GENERAL_OTHERMACHINE, BST_UNCHECKED);
  57. ::EnableWindow(GetControl(IDC_GENERAL_MACHINENAME), FALSE);
  58. //
  59. // Default is local machine. Since everything is valid at the beginning,
  60. // we have to enable the finish button.
  61. //
  62. ::SendMessage(::GetParent(m_hDlg), PSM_SETWIZBUTTONS, 0, PSWIZB_FINISH);
  63. ::ShowWindow(GetControl(IDC_GENERAL_OVERRIDE_MACHINENAME), SW_HIDE);
  64. ::EnableWindow(GetControl(IDC_GENERAL_BROWSE_MACHINENAMES), FALSE);
  65. return TRUE;
  66. }
  67. BOOL
  68. CGeneralPage::OnReset(
  69. void
  70. )
  71. {
  72. m_MachineName[0] = _T('\0');
  73. m_ct = COOKIE_TYPE_SCOPEITEM_DEVMGR;
  74. SetWindowLongPtr(m_hDlg, DWLP_MSGRESULT, 0L);
  75. return FALSE;
  76. }
  77. BOOL
  78. CGeneralPage::OnCommand(
  79. WPARAM wParam,
  80. LPARAM lParam
  81. )
  82. {
  83. switch (LOWORD(wParam)) {
  84. case IDC_GENERAL_LOCALMACHINE:
  85. if (BN_CLICKED == HIWORD(wParam)) {
  86. ::EnableWindow(GetControl(IDC_GENERAL_BROWSE_MACHINENAMES), FALSE);
  87. ::EnableWindow(GetControl(IDC_GENERAL_MACHINENAME), FALSE);
  88. ::SendMessage(::GetParent(m_hDlg), PSM_SETWIZBUTTONS, 0, PSWIZB_FINISH);
  89. m_IsLocalMachine = TRUE;
  90. return TRUE;
  91. }
  92. break;
  93. case IDC_GENERAL_OTHERMACHINE:
  94. if (BN_CLICKED == HIWORD(wParam)) {
  95. ::EnableWindow(GetControl(IDC_GENERAL_BROWSE_MACHINENAMES), TRUE);
  96. ::EnableWindow(GetControl(IDC_GENERAL_MACHINENAME), TRUE);
  97. if (GetWindowTextLength(GetControl(IDC_GENERAL_MACHINENAME))) {
  98. ::SendMessage(::GetParent(m_hDlg), PSM_SETWIZBUTTONS, 0, PSWIZB_FINISH);
  99. } else {
  100. ::SendMessage(::GetParent(m_hDlg), PSM_SETWIZBUTTONS, 0, PSWIZB_DISABLEDFINISH);
  101. }
  102. m_IsLocalMachine = FALSE;
  103. return TRUE;
  104. }
  105. break;
  106. case IDC_GENERAL_MACHINENAME:
  107. if (EN_CHANGE == HIWORD(wParam)) {
  108. //
  109. // Edit control change, see if there is any text in the
  110. // control at all. It there is, enable the finish button,
  111. // otherwise, disable it.
  112. //
  113. if (GetWindowTextLength((HWND)lParam)) {
  114. //
  115. // There is some text in the edit control enable the finish
  116. // button
  117. //
  118. ::SendMessage(::GetParent(m_hDlg), PSM_SETWIZBUTTONS, 0, PSWIZB_FINISH);
  119. } else {
  120. //
  121. // No text in the edit control disable the finish button
  122. //
  123. ::SendMessage(::GetParent(m_hDlg), PSM_SETWIZBUTTONS, 0, PSWIZB_DISABLEDFINISH);
  124. }
  125. }
  126. break;
  127. case IDC_GENERAL_BROWSE_MACHINENAMES:
  128. DoBrowse();
  129. return TRUE;
  130. break;
  131. }
  132. return FALSE;
  133. }
  134. BOOL
  135. CGeneralPage::OnWizFinish(
  136. void
  137. )
  138. {
  139. BOOL bSuccess = TRUE;
  140. //
  141. // First figure out the machine name
  142. //
  143. m_MachineName[0] = _T('\0');
  144. if (!m_IsLocalMachine)
  145. {
  146. GetWindowText(GetControl(IDC_GENERAL_MACHINENAME), m_MachineName,
  147. ARRAYLEN(m_MachineName));
  148. if (_T('\0') != m_MachineName[0])
  149. {
  150. if (_T('\\') != m_MachineName[0])
  151. {
  152. //
  153. // Insert machine name signature to the fron of the name
  154. //
  155. int len = lstrlen(m_MachineName);
  156. if (len + 2 < ARRAYLEN(m_MachineName))
  157. {
  158. //
  159. // Move the existing string so that we can insert
  160. // the signature in the first two locations.
  161. // the move includes the terminated null char.
  162. // Note: when moving characters two places we need to make
  163. // sure we don't blow out the buffer.
  164. //
  165. for (int i = len + 2; i >= 2; i--) {
  166. m_MachineName[i] = m_MachineName[i - 2];
  167. }
  168. m_MachineName[0] = _T('\\');
  169. m_MachineName[1] = _T('\\');
  170. }
  171. }
  172. //
  173. // Now verify the machine name. If the machine name is invalid
  174. // or can be reached, use the local computer;
  175. //
  176. if (!VerifyMachineName(m_MachineName))
  177. {
  178. String strWarningFormat;
  179. String strWarningMessage;
  180. LPVOID lpLastError = NULL;
  181. bSuccess = FALSE;
  182. if (strWarningFormat.LoadString(g_hInstance, IDS_INVALID_COMPUTER_NAME) &&
  183. FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
  184. FORMAT_MESSAGE_FROM_SYSTEM |
  185. FORMAT_MESSAGE_IGNORE_INSERTS,
  186. NULL,
  187. HRESULT_FROM_SETUPAPI(GetLastError()),
  188. MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
  189. (LPTSTR)&lpLastError,
  190. 0,
  191. NULL)) {
  192. strWarningMessage.Format((LPTSTR)strWarningFormat,
  193. m_MachineName,
  194. lpLastError);
  195. MessageBox(m_hDlg,
  196. (LPTSTR)strWarningMessage,
  197. (LPCTSTR)g_strDevMgr,
  198. MB_ICONERROR | MB_OK
  199. );
  200. }
  201. if (lpLastError) {
  202. LocalFree(lpLastError);
  203. }
  204. }
  205. }
  206. }
  207. try
  208. {
  209. //
  210. // Only tell the console, or the caller, about the new machine name,
  211. // if we were able to successfully get one, it was valid, and we
  212. // have access to it.
  213. //
  214. if (bSuccess) {
  215. if (m_lConsoleHandle)
  216. {
  217. //
  218. // A console handle is created for the property sheet,
  219. // use the handle to notify the snapin about the new
  220. // startup information.
  221. //
  222. BufferPtr<BYTE> Buffer(sizeof(PROPERTY_CHANGE_INFO) + sizeof(STARTUP_INFODATA));
  223. PPROPERTY_CHANGE_INFO pPCI = (PPROPERTY_CHANGE_INFO)(BYTE*)Buffer;
  224. PSTARTUP_INFODATA pSI = (PSTARTUP_INFODATA)&pPCI->InfoData;
  225. if ((_T('\0') != m_MachineName[0]) &&
  226. FAILED(StringCchCopy(pSI->MachineName, ARRAYLEN(pSI->MachineName), m_MachineName))) {
  227. //
  228. // This shouldn't happen, since everywhere else in this code
  229. // machine names can't be larger than MAX_PATH, but we'll
  230. // assert, and handle this case, just in case.
  231. //
  232. ASSERT(lstrlen(m_MachineName) < ARRAYLEN(pSI->MachineName));
  233. bSuccess = FALSE;
  234. }
  235. if (bSuccess) {
  236. pSI->ct = m_ct;
  237. pSI->Size = sizeof(STARTUP_INFODATA);
  238. pPCI->Type = PCT_STARTUP_INFODATA;
  239. //
  240. // Notify IComponentData about what we have here.
  241. //
  242. MMCPropertyChangeNotify(m_lConsoleHandle, reinterpret_cast<LONG_PTR>(&pPCI));
  243. }
  244. }
  245. else if (m_pstrMachineName && m_pct)
  246. {
  247. //
  248. // No console is provided for the property sheet.
  249. // send the new startup info in the given buffer if it is
  250. // provided.
  251. //
  252. *m_pstrMachineName = m_MachineName;
  253. *m_pct = m_ct;
  254. }
  255. else
  256. {
  257. //
  258. // Nobody is listening to what we have to say. Something must be
  259. // wrong!
  260. //
  261. ASSERT(FALSE);
  262. }
  263. }
  264. }
  265. catch (CMemoryException* e)
  266. {
  267. e->Delete();
  268. MsgBoxParam(m_hDlg, 0, 0, 0);
  269. }
  270. SetWindowLongPtr(m_hDlg, DWLP_MSGRESULT, bSuccess ? 0L : -1L);
  271. return TRUE;
  272. }
  273. BOOL
  274. CGeneralPage::OnHelp(
  275. LPHELPINFO pHelpInfo
  276. )
  277. {
  278. WinHelp((HWND)pHelpInfo->hItemHandle, DEVMGR_HELP_FILE_NAME, HELP_WM_HELP,
  279. (ULONG_PTR)g_a102HelpIDs);
  280. return FALSE;
  281. }
  282. BOOL
  283. CGeneralPage::OnContextMenu(
  284. HWND hWnd,
  285. WORD xPos,
  286. WORD yPos
  287. )
  288. {
  289. UNREFERENCED_PARAMETER(xPos);
  290. UNREFERENCED_PARAMETER(yPos);
  291. WinHelp(hWnd, DEVMGR_HELP_FILE_NAME, HELP_CONTEXTMENU,
  292. (ULONG_PTR)g_a102HelpIDs);
  293. return FALSE;
  294. }
  295. void
  296. CGeneralPage::DoBrowse(
  297. void
  298. )
  299. {
  300. HRESULT hr;
  301. static const int SCOPE_INIT_COUNT = 1;
  302. DSOP_SCOPE_INIT_INFO aScopeInit[SCOPE_INIT_COUNT];
  303. ZeroMemory(aScopeInit, sizeof(DSOP_SCOPE_INIT_INFO) * SCOPE_INIT_COUNT);
  304. //
  305. // Since we just want computer objects from every scope, combine them
  306. // all in a single scope initializer.
  307. //
  308. aScopeInit[0].cbSize = sizeof(DSOP_SCOPE_INIT_INFO);
  309. aScopeInit[0].flType = DSOP_SCOPE_TYPE_ENTERPRISE_DOMAIN
  310. | DSOP_SCOPE_TYPE_GLOBAL_CATALOG
  311. | DSOP_SCOPE_TYPE_EXTERNAL_UPLEVEL_DOMAIN
  312. | DSOP_SCOPE_TYPE_EXTERNAL_DOWNLEVEL_DOMAIN
  313. | DSOP_SCOPE_TYPE_WORKGROUP
  314. | DSOP_SCOPE_TYPE_USER_ENTERED_UPLEVEL_SCOPE
  315. | DSOP_SCOPE_TYPE_USER_ENTERED_DOWNLEVEL_SCOPE;
  316. aScopeInit[0].FilterFlags.Uplevel.flBothModes =
  317. DSOP_FILTER_COMPUTERS;
  318. aScopeInit[0].FilterFlags.flDownlevel = DSOP_DOWNLEVEL_FILTER_COMPUTERS;
  319. //
  320. // Put the scope init array into the object picker init array
  321. //
  322. DSOP_INIT_INFO InitInfo;
  323. ZeroMemory(&InitInfo, sizeof(InitInfo));
  324. InitInfo.cbSize = sizeof(InitInfo);
  325. InitInfo.pwzTargetComputer = NULL; // NULL == local machine
  326. InitInfo.cDsScopeInfos = SCOPE_INIT_COUNT;
  327. InitInfo.aDsScopeInfos = aScopeInit;
  328. //
  329. // Note object picker makes its own copy of InitInfo. Also note
  330. // that Initialize may be called multiple times, last call wins.
  331. //
  332. IDsObjectPicker *pDsObjectPicker = NULL;
  333. IDataObject *pdo = NULL;
  334. bool fGotStgMedium = false;
  335. STGMEDIUM stgmedium =
  336. {
  337. TYMED_HGLOBAL,
  338. NULL,
  339. NULL
  340. };
  341. hr = CoCreateInstance(CLSID_DsObjectPicker,
  342. NULL,
  343. CLSCTX_INPROC_SERVER,
  344. IID_IDsObjectPicker,
  345. (void **) &pDsObjectPicker);
  346. hr = pDsObjectPicker->Initialize(&InitInfo);
  347. hr = pDsObjectPicker->InvokeDialog(m_hDlg, &pdo);
  348. if (hr != S_FALSE)
  349. {
  350. FORMATETC formatetc =
  351. {
  352. (CLIPFORMAT)g_cfDsObjectPicker,
  353. NULL,
  354. DVASPECT_CONTENT,
  355. -1,
  356. TYMED_HGLOBAL
  357. };
  358. hr = pdo->GetData(&formatetc, &stgmedium);
  359. fGotStgMedium = true;
  360. PDS_SELECTION_LIST pDsSelList =
  361. (PDS_SELECTION_LIST) GlobalLock(stgmedium.hGlobal);
  362. if (pDsSelList)
  363. {
  364. ASSERT(pDsSelList->cItems == 1);
  365. //
  366. // Put the machine name in the edit control
  367. //
  368. ::SetDlgItemText(m_hDlg, IDC_GENERAL_MACHINENAME, pDsSelList->aDsSelection[0].pwzName);
  369. GlobalUnlock(stgmedium.hGlobal);
  370. }
  371. }
  372. if (fGotStgMedium)
  373. {
  374. ReleaseStgMedium(&stgmedium);
  375. }
  376. if (pDsObjectPicker)
  377. {
  378. pDsObjectPicker->Release();
  379. }
  380. }