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.

438 lines
13 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. //
  5. // Copyright (C) Microsoft Corporation, 1997 - 1999
  6. //
  7. // File: chooser.cpp
  8. //
  9. //--------------------------------------------------------------------------
  10. /////////////////////////////////////////////////////////////////////
  11. // Chooser.cpp
  12. //
  13. // Dialog to choose a machine name.
  14. //
  15. // PURPOSE
  16. // What you have to do is to copy all the files from the
  17. // snapin\chooser\ directory into your project (you may add
  18. // \nt\private\admin\snapin\chooser\ to your include directory if
  19. // you prefer not copying the code).
  20. // If you decide to copy the code to your project, please send mail
  21. // to Dan Morin (T-DanM) and cc to Jon Newman (JonN) so we can
  22. // mail you when we have updates available. The next update will
  23. // be the "Browse" button to select a machine name.
  24. //
  25. //
  26. // DYNALOADED LIBRARIES
  27. //
  28. // HISTORY
  29. // 13-May-1997 t-danm Creation.
  30. // 23-May-1997 t-danm Checkin into public tree. Comments updates.
  31. // 25-May-1997 t-danm Added MMCPropPageCallback().
  32. // 31-Oct-1997 mattt Added dynaload, fixed user <CANCEL> logic
  33. // 1-Oct-1998 mattt Removed reliance on MFC, changed default look to enable certsvr picker
  34. //
  35. /////////////////////////////////////////////////////////////////////
  36. #include <stdafx.h>
  37. #include "chooser.h"
  38. #include "csdisp.h" // certsrv picker
  39. #ifdef _DEBUG
  40. #undef THIS_FILE
  41. #define THIS_FILE __FILE__
  42. #endif
  43. #ifndef INOUT
  44. // The following defines are found in \nt\private\admin\snapin\filemgmt\stdafx.h
  45. #define INOUT
  46. #define Endorse(f) // Dummy macro
  47. #define LENGTH(x) (sizeof(x)/sizeof(x[0]))
  48. #define Assert(f) ASSERT(f)
  49. #endif
  50. /////////////////////////////////////////////////////////////////////
  51. /////////////////////////////////////////////////////////////////////
  52. // Replacement for BEGIN_MESSAGE_MAP
  53. BOOL CAutoDeletePropPage::OnCommand(WPARAM wParam, LPARAM lParam)
  54. {
  55. /*
  56. switch(LOWORD(wParam))
  57. {
  58. }
  59. */
  60. return FALSE;
  61. }
  62. /////////////////////////////////////////////////////////////////////
  63. // Constructor
  64. CAutoDeletePropPage::CAutoDeletePropPage(UINT uIDD) : PropertyPage(uIDD)
  65. {
  66. m_prgzHelpIDs = NULL;
  67. m_autodeleteStuff.cWizPages = 1; // Number of pages in wizard
  68. m_autodeleteStuff.pfnOriginalPropSheetPageProc = m_psp.pfnCallback;
  69. m_psp.dwFlags |= PSP_USECALLBACK;
  70. m_psp.pfnCallback = S_PropSheetPageProc;
  71. m_psp.lParam = reinterpret_cast<LPARAM>(this);
  72. }
  73. CAutoDeletePropPage::~CAutoDeletePropPage()
  74. {
  75. }
  76. /////////////////////////////////////////////////////////////////////
  77. void CAutoDeletePropPage::SetCaption(LPCTSTR pszCaption)
  78. {
  79. m_strCaption = pszCaption; // Copy the caption
  80. m_psp.pszTitle = m_strCaption; // Set the title
  81. m_psp.dwFlags |= PSP_USETITLE;
  82. }
  83. /////////////////////////////////////////////////////////////////////
  84. void CAutoDeletePropPage::SetCaption(UINT uStringID)
  85. {
  86. VERIFY(m_strCaption.LoadString(uStringID));
  87. SetCaption(m_strCaption);
  88. }
  89. /////////////////////////////////////////////////////////////////////
  90. void CAutoDeletePropPage::SetHelp(LPCTSTR szHelpFile, const DWORD rgzHelpIDs[])
  91. {
  92. m_strHelpFile = szHelpFile;
  93. m_prgzHelpIDs = rgzHelpIDs;
  94. }
  95. /////////////////////////////////////////////////////////////////////
  96. void CAutoDeletePropPage::EnableDlgItem(INT nIdDlgItem, BOOL fEnable)
  97. {
  98. Assert(IsWindow(::GetDlgItem(m_hWnd, nIdDlgItem)));
  99. ::EnableWindow(::GetDlgItem(m_hWnd, nIdDlgItem), fEnable);
  100. }
  101. /////////////////////////////////////////////////////////////////////
  102. BOOL CAutoDeletePropPage::OnSetActive()
  103. {
  104. HWND hwndParent = ::GetParent(m_hWnd);
  105. Assert(IsWindow(hwndParent));
  106. ::PropSheet_SetWizButtons(hwndParent, PSWIZB_FINISH);
  107. return PropertyPage::OnSetActive();
  108. }
  109. /////////////////////////////////////////////////////////////////////
  110. void CAutoDeletePropPage::OnHelp(LPHELPINFO pHelpInfo)
  111. {
  112. if (m_prgzHelpIDs == NULL || m_strHelpFile.IsEmpty())
  113. return;
  114. if (pHelpInfo != NULL && pHelpInfo->iContextType == HELPINFO_WINDOW)
  115. {
  116. // Display context help for a control
  117. ::WinHelp((HWND)pHelpInfo->hItemHandle, m_strHelpFile,
  118. HELP_WM_HELP, (ULONG_PTR)(LPVOID)m_prgzHelpIDs);
  119. }
  120. return;
  121. }
  122. /////////////////////////////////////////////////////////////////////
  123. void CAutoDeletePropPage::OnContextHelp(HWND hwnd)
  124. {
  125. if (m_prgzHelpIDs == NULL || m_strHelpFile.IsEmpty())
  126. return;
  127. Assert(IsWindow(hwnd));
  128. ::WinHelp(hwnd, m_strHelpFile, HELP_CONTEXTMENU, (ULONG_PTR)(LPVOID)m_prgzHelpIDs);
  129. return;
  130. }
  131. /////////////////////////////////////////////////////////////////////
  132. // S_PropSheetPageProc()
  133. //
  134. // Static member function used to delete the CAutoDeletePropPage object
  135. // when wizard terminates
  136. //
  137. UINT CALLBACK CAutoDeletePropPage::S_PropSheetPageProc(
  138. HWND hwnd,
  139. UINT uMsg,
  140. LPPROPSHEETPAGE ppsp)
  141. {
  142. Assert(ppsp != NULL);
  143. CAutoDeletePropPage * pThis;
  144. pThis = reinterpret_cast<CAutoDeletePropPage*>(ppsp->lParam);
  145. Assert(pThis != NULL);
  146. BOOL fDefaultRet;
  147. switch (uMsg)
  148. {
  149. case PSPCB_RELEASE:
  150. fDefaultRet = FALSE;
  151. if (--(pThis->m_autodeleteStuff.cWizPages) <= 0)
  152. {
  153. // Remember callback on stack since "this" will be deleted
  154. LPFNPSPCALLBACK pfnOrig = pThis->m_autodeleteStuff.pfnOriginalPropSheetPageProc;
  155. delete pThis;
  156. if (pfnOrig)
  157. return (pfnOrig)(hwnd, uMsg, ppsp);
  158. else
  159. return fDefaultRet;
  160. }
  161. break;
  162. case PSPCB_CREATE:
  163. fDefaultRet = TRUE;
  164. // do not increase refcount, PSPCB_CREATE may or may not be called
  165. // depending on whether the page was created. PSPCB_RELEASE can be
  166. // depended upon to be called exactly once per page however.
  167. break;
  168. } // switch
  169. if (pThis->m_autodeleteStuff.pfnOriginalPropSheetPageProc)
  170. return (pThis->m_autodeleteStuff.pfnOriginalPropSheetPageProc)(hwnd, uMsg, ppsp);
  171. else
  172. return fDefaultRet;
  173. } // CAutoDeletePropPage::S_PropSheetPageProc()
  174. /////////////////////////////////////////////////////////////////////
  175. /////////////////////////////////////////////////////////////////////
  176. // Replacement for BEGIN_MESSAGE_MAP
  177. BOOL CChooseMachinePropPage::OnCommand(WPARAM wParam, LPARAM lParam)
  178. {
  179. switch(LOWORD(wParam))
  180. {
  181. case IDC_CHOOSER_RADIO_LOCAL_MACHINE:
  182. OnRadioLocalMachine();
  183. break;
  184. case IDC_CHOOSER_RADIO_SPECIFIC_MACHINE:
  185. OnRadioSpecificMachine();
  186. break;
  187. case IDC_CHOOSER_BUTTON_BROWSE_MACHINENAMES:
  188. OnBrowse();
  189. break;
  190. default:
  191. return FALSE;
  192. break;
  193. }
  194. return TRUE;
  195. }
  196. #ifdef _DEBUG
  197. static void AssertValidDialogTemplate(HWND hwnd)
  198. {
  199. ASSERT(::IsWindow(hwnd));
  200. // Mandatory controls for a valid dialog template
  201. static const UINT rgzidDialogControl[] =
  202. {
  203. IDC_CHOOSER_RADIO_LOCAL_MACHINE,
  204. IDC_CHOOSER_RADIO_SPECIFIC_MACHINE,
  205. IDC_CHOOSER_EDIT_MACHINE_NAME,
  206. 0
  207. };
  208. for (int i = 0; rgzidDialogControl[i] != 0; i++)
  209. {
  210. ASSERT(NULL != GetDlgItem(hwnd, rgzidDialogControl[i]) &&
  211. "Control ID not found in dialog template.");
  212. }
  213. } // AssertValidDialogTemplate()
  214. #else
  215. #define AssertValidDialogTemplate(hwnd)
  216. #endif // ~_DEBUG
  217. /////////////////////////////////////////////////////////////////////
  218. // Constructor
  219. CChooseMachinePropPage::CChooseMachinePropPage(UINT uIDD) : CAutoDeletePropPage(uIDD)
  220. {
  221. m_fIsRadioLocalMachine = TRUE;
  222. m_fEnableMachineBrowse = FALSE;
  223. m_pstrMachineNameOut = NULL;
  224. m_pstrMachineNameEffectiveOut = NULL;
  225. m_pdwFlags = NULL;
  226. }
  227. /////////////////////////////////////////////////////////////////////
  228. CChooseMachinePropPage::~CChooseMachinePropPage()
  229. {
  230. }
  231. /////////////////////////////////////////////////////////////////////
  232. // Load the initial state of CChooseMachinePropPage
  233. void CChooseMachinePropPage::InitMachineName(LPCTSTR pszMachineName)
  234. {
  235. m_strMachineName = pszMachineName;
  236. m_fIsRadioLocalMachine = m_strMachineName.IsEmpty();
  237. }
  238. /////////////////////////////////////////////////////////////////////
  239. // SetOutputBuffers()
  240. //
  241. // - Set the pointer to the CString object to store the machine name.
  242. // - Set the pointer to the boolean flag for command line override.
  243. // - Set the pointer pointer to store the overriden machine name.
  244. //
  245. void CChooseMachinePropPage::SetOutputBuffers(
  246. OUT CString * pstrMachineNamePersist, // Machine name the user typed. Empty string == local machine.
  247. OUT CString * pstrMachineNameEffective,
  248. OUT DWORD* pdwFlags)
  249. {
  250. Assert(pstrMachineNamePersist != NULL && "Invalid output buffer");
  251. // point members at params
  252. m_pstrMachineNameOut = pstrMachineNamePersist;
  253. m_pstrMachineNameEffectiveOut = pstrMachineNameEffective;
  254. m_pdwFlags = pdwFlags;
  255. *m_pdwFlags = 0;
  256. }
  257. /////////////////////////////////////////////////////////////////////
  258. // Replacement for DoDataExchange
  259. BOOL CChooseMachinePropPage::UpdateData(BOOL fSuckFromDlg /*= TRUE*/)
  260. {
  261. if (fSuckFromDlg)
  262. {
  263. m_strMachineName.FromWindow(GetDlgItem(m_hWnd, IDC_CHOOSER_EDIT_MACHINE_NAME));
  264. int iCheck = (int)SendMessage(GetDlgItem(m_hWnd, IDC_CHOOSER_MACHINE_OVERRIDE), BM_GETCHECK, 0, 0);
  265. if (iCheck == BST_CHECKED)
  266. *m_pdwFlags |= CCOMPDATAIMPL_FLAGS_ALLOW_MACHINE_OVERRIDE;
  267. else
  268. *m_pdwFlags &= ~CCOMPDATAIMPL_FLAGS_ALLOW_MACHINE_OVERRIDE;
  269. }
  270. else
  271. {
  272. m_strMachineName.ToWindow(GetDlgItem(m_hWnd, IDC_CHOOSER_EDIT_MACHINE_NAME));
  273. int iCheck;
  274. iCheck = (*m_pdwFlags & CCOMPDATAIMPL_FLAGS_ALLOW_MACHINE_OVERRIDE) ? BST_CHECKED : BST_UNCHECKED;
  275. SendMessage(GetDlgItem(m_hWnd, IDC_CHOOSER_MACHINE_OVERRIDE), BM_SETCHECK, iCheck, 0);
  276. }
  277. return TRUE;
  278. }
  279. /////////////////////////////////////////////////////////////////////
  280. BOOL CChooseMachinePropPage::OnInitDialog()
  281. {
  282. AssertValidDialogTemplate(m_hWnd);
  283. CAutoDeletePropPage::OnInitDialog();
  284. InitChooserControls();
  285. PropSheet_SetWizButtons(GetParent(), PSWIZB_FINISH);
  286. return TRUE;
  287. }
  288. /////////////////////////////////////////////////////////////////////
  289. BOOL CChooseMachinePropPage::OnWizardFinish()
  290. {
  291. if (!UpdateData()) // Do the data exchange to collect data
  292. return FALSE; // don't destroy on error
  293. if (m_fIsRadioLocalMachine)
  294. m_strMachineName.Empty();
  295. else
  296. if (m_strMachineName.IsEmpty())
  297. {
  298. DisplayCertSrvErrorWithContext(m_hWnd, S_OK, IDS_MUST_CHOOSE_MACHINE);
  299. return FALSE;
  300. }
  301. if (m_pstrMachineNameOut != NULL)
  302. {
  303. // Store the machine name into its output buffer
  304. *m_pstrMachineNameOut = m_strMachineName;
  305. if (m_pstrMachineNameEffectiveOut != NULL)
  306. {
  307. *m_pstrMachineNameEffectiveOut = m_strMachineName;
  308. } // if
  309. }
  310. else
  311. Assert(FALSE && "FYI: You have not specified any output buffer to store the machine name.");
  312. return CAutoDeletePropPage::OnWizardFinish();
  313. }
  314. void CChooseMachinePropPage::InitChooserControls()
  315. {
  316. SendDlgItemMessage(IDC_CHOOSER_RADIO_LOCAL_MACHINE, BM_SETCHECK, m_fIsRadioLocalMachine);
  317. SendDlgItemMessage(IDC_CHOOSER_RADIO_SPECIFIC_MACHINE, BM_SETCHECK, !m_fIsRadioLocalMachine);
  318. EnableDlgItem(IDC_CHOOSER_EDIT_MACHINE_NAME, !m_fIsRadioLocalMachine);
  319. PCCRYPTUI_CA_CONTEXT pCAContext = NULL;
  320. DWORD dwCACount;
  321. HRESULT hr = myGetConfigFromPicker(
  322. m_hWnd,
  323. NULL, //sub title
  324. NULL, //title
  325. NULL,
  326. TRUE, //use ds
  327. TRUE, // count only
  328. &dwCACount,
  329. &pCAContext);
  330. if (S_OK != hr && HRESULT_FROM_WIN32(ERROR_CANCELLED) != hr)
  331. {
  332. _PrintError(hr, "myGetConfigFromPicker");
  333. goto done;
  334. }
  335. m_fEnableMachineBrowse = (0 == dwCACount) ? FALSE : TRUE;
  336. if (NULL != pCAContext)
  337. {
  338. CryptUIDlgFreeCAContext(pCAContext);
  339. }
  340. done:
  341. EnableDlgItem(IDC_CHOOSER_BUTTON_BROWSE_MACHINENAMES,
  342. !m_fIsRadioLocalMachine && m_fEnableMachineBrowse);
  343. }
  344. void CChooseMachinePropPage::OnRadioLocalMachine()
  345. {
  346. m_fIsRadioLocalMachine = TRUE;
  347. EnableDlgItem(IDC_CHOOSER_EDIT_MACHINE_NAME, FALSE);
  348. EnableDlgItem(IDC_CHOOSER_BUTTON_BROWSE_MACHINENAMES, FALSE);
  349. }
  350. void CChooseMachinePropPage::OnRadioSpecificMachine()
  351. {
  352. m_fIsRadioLocalMachine = FALSE;
  353. EnableDlgItem(IDC_CHOOSER_EDIT_MACHINE_NAME, TRUE);
  354. EnableDlgItem(IDC_CHOOSER_BUTTON_BROWSE_MACHINENAMES, m_fEnableMachineBrowse);
  355. }
  356. void CChooseMachinePropPage::OnBrowse()
  357. {
  358. HRESULT hr;
  359. WCHAR *szConfig = NULL;
  360. CWaitCursor cwait;
  361. // UNDONE: expand config picker to non-published (DS chooser dlg)
  362. hr = myGetConfigStringFromPicker(m_hWnd,
  363. NULL, //use default prompt
  364. NULL, //use default title
  365. NULL, //use default shared folder
  366. TRUE, //use DS
  367. &szConfig);
  368. if (hr == S_OK)
  369. {
  370. LPWSTR szWhack = wcschr(szConfig, L'\\');
  371. if (szWhack != NULL)
  372. szWhack[0] = L'\0';
  373. m_strMachineName = szConfig;
  374. LocalFree(szConfig);
  375. }
  376. // push result back to ui
  377. UpdateData(FALSE);
  378. }