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.

410 lines
10 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. //
  5. // Copyright (C) Microsoft Corporation, 1998 - 1999
  6. //
  7. // File: proppage.cpp
  8. //
  9. //--------------------------------------------------------------------------
  10. #include "stdafx.h"
  11. #include "resource.h"
  12. #include "proppage.h"
  13. #include "domobj.h"
  14. #include "cdomain.h"
  15. #include "helparr.h"
  16. ////////////////////////////////////////////////////////////////////////////////
  17. // CUpnSuffixPropertyPage
  18. // hook the property sheet callback to allow
  19. // C++ object destruction
  20. // static callback override function
  21. UINT CALLBACK CUpnSuffixPropertyPage::PropSheetPageProc(
  22. HWND hwnd,
  23. UINT uMsg,
  24. LPPROPSHEETPAGE ppsp)
  25. {
  26. CUpnSuffixPropertyPage* pPage = (CUpnSuffixPropertyPage*)(ppsp->lParam);
  27. ASSERT(pPage != NULL);
  28. UINT nResult = (*(pPage->m_pfnOldPropCallback))(hwnd, uMsg, ppsp);
  29. if (uMsg == PSPCB_RELEASE)
  30. {
  31. delete pPage;
  32. }
  33. return nResult;
  34. }
  35. BEGIN_MESSAGE_MAP(CUpnSuffixPropertyPage, CPropertyPage)
  36. ON_BN_CLICKED(IDC_ADD_BTN, OnAddButton)
  37. ON_BN_CLICKED(IDC_DELETE_BTN, OnDeleteButton)
  38. ON_EN_CHANGE(IDC_EDIT, OnEditChange)
  39. ON_WM_HELPINFO()
  40. END_MESSAGE_MAP()
  41. CUpnSuffixPropertyPage::CUpnSuffixPropertyPage(CString & strPartitions) :
  42. CPropertyPage(IDD_UPN_SUFFIX),
  43. m_nPreviousDefaultButtonID(0),
  44. _strPartitions(strPartitions)
  45. {
  46. m_pfnOldPropCallback = m_psp.pfnCallback;
  47. m_psp.pfnCallback = PropSheetPageProc;
  48. m_bDirty = FALSE;
  49. m_pIADsPartitionsCont = NULL;
  50. }
  51. CUpnSuffixPropertyPage::~CUpnSuffixPropertyPage()
  52. {
  53. if (m_pIADsPartitionsCont != NULL)
  54. {
  55. m_pIADsPartitionsCont->Release();
  56. m_pIADsPartitionsCont = NULL;
  57. }
  58. }
  59. BOOL CUpnSuffixPropertyPage::OnInitDialog()
  60. {
  61. CPropertyPage::OnInitDialog();
  62. VERIFY(m_listBox.SubclassDlgItem(IDC_LIST, this));
  63. ((CEdit*)GetDlgItem(IDC_EDIT))->SetLimitText(MAX_UPN_SUFFIX_LEN);
  64. HRESULT hr = _GetPartitionsContainer();
  65. if (SUCCEEDED(hr))
  66. {
  67. _Read();
  68. GetDlgItem(IDC_ADD_BTN)->EnableWindow(FALSE);
  69. }
  70. else
  71. {
  72. // failed to contact DC, disable the whole UI
  73. GetDlgItem(IDC_ADD_BTN)->EnableWindow(FALSE);
  74. GetDlgItem(IDC_DELETE_BTN)->EnableWindow(FALSE);
  75. GetDlgItem(IDC_LIST)->EnableWindow(FALSE);
  76. GetDlgItem(IDC_EDIT)->EnableWindow(FALSE);
  77. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  78. ReportError(::GetParent(m_hWnd), IDS_CANT_GET_PARTITIONS_INFORMATION, hr);
  79. }
  80. LRESULT lDefID = ::SendMessage(GetParent()->GetSafeHwnd(), DM_GETDEFID, 0, 0);
  81. if (lDefID != 0)
  82. {
  83. m_nPreviousDefaultButtonID = LOWORD(lDefID);
  84. }
  85. _SetDirty(FALSE);
  86. return TRUE;
  87. }
  88. BOOL CUpnSuffixPropertyPage::OnApply()
  89. {
  90. if (!_IsDirty())
  91. return TRUE;
  92. HRESULT hr = _Write();
  93. if (SUCCEEDED(hr))
  94. {
  95. _SetDirty(FALSE);
  96. return TRUE;
  97. }
  98. ReportError(::GetParent(m_hWnd),IDS_ERROR_WRITE_UPN_SUFFIXES, hr);
  99. return FALSE;
  100. }
  101. void CUpnSuffixPropertyPage::OnEditChange()
  102. {
  103. GetDlgItemText(IDC_EDIT, m_szEditText);
  104. m_szEditText.TrimRight();
  105. m_szEditText.TrimLeft();
  106. BOOL bEnable = !m_szEditText.IsEmpty();
  107. CWnd* pWndFocus = CWnd::GetFocus();
  108. CWnd* pAddBtnWnd = GetDlgItem(IDC_ADD_BTN);
  109. if (!bEnable && (pAddBtnWnd == pWndFocus) )
  110. {
  111. GetDlgItem(IDC_EDIT)->SetFocus();
  112. }
  113. GetDlgItem(IDC_ADD_BTN)->EnableWindow(bEnable);
  114. if (bEnable)
  115. {
  116. //
  117. // Set the add button as the default button
  118. //
  119. ::SendMessage(GetParent()->GetSafeHwnd(), DM_SETDEFID, (WPARAM)IDC_ADD_BTN, 0);
  120. //
  121. // Force the Add button to redraw itself
  122. //
  123. ::SendDlgItemMessage(GetSafeHwnd(),
  124. IDC_ADD_BTN,
  125. BM_SETSTYLE,
  126. BS_DEFPUSHBUTTON,
  127. MAKELPARAM(TRUE, 0));
  128. //
  129. // Force the previous default button to redraw itself
  130. //
  131. ::SendDlgItemMessage(GetParent()->GetSafeHwnd(),
  132. m_nPreviousDefaultButtonID,
  133. BM_SETSTYLE,
  134. BS_PUSHBUTTON,
  135. MAKELPARAM(TRUE, 0));
  136. }
  137. else
  138. {
  139. //
  140. // Set the previous button as the default button
  141. //
  142. ::SendMessage(GetParent()->GetSafeHwnd(), DM_SETDEFID, (WPARAM)m_nPreviousDefaultButtonID, 0);
  143. //
  144. // Force the previous default button to redraw itself
  145. //
  146. ::SendDlgItemMessage(GetParent()->GetSafeHwnd(),
  147. m_nPreviousDefaultButtonID,
  148. BM_SETSTYLE,
  149. BS_DEFPUSHBUTTON,
  150. MAKELPARAM(TRUE, 0));
  151. //
  152. // Force the Add button to redraw itself
  153. //
  154. ::SendDlgItemMessage(GetParent()->GetSafeHwnd(),
  155. IDC_ADD_BTN,
  156. BM_SETSTYLE,
  157. BS_PUSHBUTTON,
  158. MAKELPARAM(TRUE, 0));
  159. }
  160. }
  161. void CUpnSuffixPropertyPage::OnAddButton()
  162. {
  163. // cannot add duplicated items
  164. int nCount = m_listBox.GetCount();
  165. CString szItem;
  166. for (int i=0; i<nCount; i++)
  167. {
  168. m_listBox.GetItem(i, szItem);
  169. if (szItem.IsEmpty() || m_szEditText.IsEmpty())
  170. {
  171. ASSERT(!szItem.IsEmpty());
  172. ASSERT(!m_szEditText.IsEmpty());
  173. return;
  174. }
  175. if (_wcsicmp((LPCWSTR)szItem, (LPCWSTR)m_szEditText) == 0)
  176. {
  177. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  178. CThemeContextActivator activator;
  179. AfxMessageBox(IDS_ERROR_ADD_UPN_NO_DUPLICATE, MB_OK|MB_ICONINFORMATION);
  180. return;
  181. }
  182. }
  183. m_listBox.AddItem(m_szEditText);
  184. m_listBox.UpdateHorizontalExtent();
  185. SetDlgItemText(IDC_EDIT, NULL);
  186. if (1 == m_listBox.GetCount())
  187. {
  188. // we did not have any item in the list
  189. // need to set the selection on the first one
  190. VERIFY(m_listBox.SetSelection(0));
  191. // need to enable buttons
  192. GetDlgItem(IDC_DELETE_BTN)->EnableWindow(TRUE);
  193. }
  194. _SetDirty(TRUE);
  195. }
  196. void CUpnSuffixPropertyPage::OnDeleteButton()
  197. {
  198. int nCount = m_listBox.GetCount();
  199. int nSel = m_listBox.GetSelection();
  200. ASSERT(nCount > 0);
  201. ASSERT((nSel >= 0) && (nSel < nCount));
  202. // ask the user for confirmation
  203. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  204. CThemeContextActivator activator;
  205. if (IDNO == AfxMessageBox(IDS_WARNING_DELETE_UPN_SUFFIX, MB_YESNO|MB_ICONQUESTION))
  206. return;
  207. // save the value and put it back in the edit control
  208. CString szText;
  209. m_listBox.GetItem(nSel, szText);
  210. GetDlgItem(IDC_EDIT)->SetWindowText(szText);
  211. // delete the item in the list
  212. VERIFY(m_listBox.DeleteItem(nSel));
  213. m_listBox.UpdateHorizontalExtent();
  214. // handle UI changes
  215. if (nCount == 1)
  216. {
  217. // removed the last one, lost the selection
  218. CWnd* pWndFocus = CWnd::GetFocus();
  219. CWnd* pDelBtnWnd = GetDlgItem(IDC_DELETE_BTN);
  220. if (pDelBtnWnd == pWndFocus)
  221. {
  222. GetDlgItem(IDC_EDIT)->SetFocus();
  223. }
  224. GetDlgItem(IDC_DELETE_BTN)->EnableWindow(FALSE);
  225. }
  226. else
  227. {
  228. // need to select again: is it the last one or not
  229. int nNewSel = (nSel == nCount-1) ? nSel-1 : nSel;
  230. VERIFY(m_listBox.SetSelection(nNewSel));
  231. ASSERT(m_listBox.GetSelection() == nNewSel);
  232. }
  233. _SetDirty(TRUE);
  234. }
  235. BOOL CUpnSuffixPropertyPage::OnHelpInfo(HELPINFO* pHelpInfo)
  236. {
  237. DialogContextHelp((DWORD*)&g_aHelpIDs_IDD_UPN_SUFFIX, pHelpInfo);
  238. return TRUE;
  239. }
  240. //////////////////////////////////////////////////////////
  241. // CUpnSuffixPropertyPage internal implementation methods
  242. LPWSTR g_lpszUpnSuffixes = L"uPNSuffixes";
  243. HRESULT CUpnSuffixPropertyPage::_GetPartitionsContainer()
  244. {
  245. if (!_strPartitions)
  246. {
  247. ASSERT(FALSE);
  248. return E_FAIL;
  249. }
  250. if (m_pIADsPartitionsCont != NULL)
  251. {
  252. m_pIADsPartitionsCont->Release();
  253. m_pIADsPartitionsCont = NULL;
  254. }
  255. HRESULT hr = S_OK;
  256. hr = DSAdminOpenObject(_strPartitions,
  257. IID_IDirectoryObject,
  258. (void **)&m_pIADsPartitionsCont,
  259. TRUE
  260. );
  261. if (hr == E_INVALIDARG )
  262. {
  263. // Trying again without the ADS_SERVER_BIND flag
  264. //
  265. hr = DSAdminOpenObject(_strPartitions,
  266. IID_IDirectoryObject,
  267. (void **)&m_pIADsPartitionsCont);
  268. }
  269. return hr;
  270. }
  271. void CUpnSuffixPropertyPage::_Read()
  272. {
  273. ASSERT(m_pIADsPartitionsCont != NULL);
  274. PADS_ATTR_INFO pAttrs = NULL;
  275. LPWSTR lpszArr[1];
  276. DWORD cAttrs;
  277. BOOL bHaveItems = FALSE;
  278. HRESULT hr = m_pIADsPartitionsCont->GetObjectAttributes(
  279. &g_lpszUpnSuffixes, 1, &pAttrs, &cAttrs);
  280. if (SUCCEEDED(hr) && (pAttrs != NULL) && (cAttrs == 1) )
  281. {
  282. ASSERT(pAttrs->dwADsType == ADSTYPE_CASE_IGNORE_STRING);
  283. ASSERT(cAttrs == 1);
  284. for (DWORD i=0; i<pAttrs->dwNumValues; i++)
  285. {
  286. m_listBox.AddItem(pAttrs->pADsValues[i].CaseIgnoreString);
  287. //TRACE(_T("i=%d, %s\n"), i, pAttrs->pADsValues[i].CaseIgnoreString);
  288. }
  289. bHaveItems = pAttrs->dwNumValues > 0;
  290. }
  291. if (bHaveItems)
  292. {
  293. m_listBox.UpdateHorizontalExtent();
  294. VERIFY(m_listBox.SetSelection(0));
  295. }
  296. GetDlgItem(IDC_DELETE_BTN)->EnableWindow(bHaveItems);
  297. if (pAttrs != NULL)
  298. {
  299. ::FreeADsMem(pAttrs);
  300. }
  301. }
  302. HRESULT CUpnSuffixPropertyPage::_Write()
  303. {
  304. ASSERT(m_pIADsPartitionsCont != NULL);
  305. DWORD cModified;
  306. CString* pStringArr = NULL;
  307. ADSVALUE* pValues = NULL;
  308. // set the update struct
  309. ADS_ATTR_INFO info;
  310. info.pszAttrName = g_lpszUpnSuffixes;
  311. info.dwADsType = ADSTYPE_CASE_IGNORE_STRING;
  312. info.dwControlCode = ADS_ATTR_CLEAR;
  313. info.pADsValues = NULL;
  314. info.dwNumValues = 0;
  315. int nCount = m_listBox.GetCount();
  316. if (nCount > 0)
  317. {
  318. info.dwControlCode = ADS_ATTR_UPDATE;
  319. info.dwNumValues = (DWORD)nCount;
  320. pStringArr = new CString[nCount];
  321. pValues = new ADSVALUE[nCount];
  322. info.pADsValues = pValues;
  323. for (int i=0; i<nCount; i++)
  324. {
  325. m_listBox.GetItem(i,pStringArr[i]);
  326. pValues[i].dwType = ADSTYPE_CASE_IGNORE_STRING;
  327. pValues[i].CaseIgnoreString = (LPWSTR)(LPCWSTR)pStringArr[i];
  328. }
  329. }
  330. HRESULT hr = m_pIADsPartitionsCont->SetObjectAttributes(
  331. &info, 1, &cModified);
  332. if (pStringArr != NULL)
  333. delete[] pStringArr;
  334. if (pValues != NULL)
  335. delete[] pValues;
  336. return hr;
  337. }