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.

300 lines
10 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 2001.
  5. //
  6. // File: EFSGeneralPropertyPage.cpp
  7. //
  8. // Contents: Implementation of CEFSGeneralPropertyPage
  9. //
  10. //----------------------------------------------------------------------------
  11. // EFSGeneralPropertyPage.cpp : implementation file
  12. //
  13. #include "stdafx.h"
  14. #include <gpedit.h>
  15. #include "EFSGeneralPropertyPage.h"
  16. #include "compdata.h"
  17. #ifdef _DEBUG
  18. #define new DEBUG_NEW
  19. #undef THIS_FILE
  20. static char THIS_FILE[] = __FILE__;
  21. #endif
  22. extern GUID g_guidExtension;
  23. extern GUID g_guidRegExt;
  24. extern GUID g_guidSnapin;
  25. /////////////////////////////////////////////////////////////////////////////
  26. // CEFSGeneralPropertyPage property page
  27. CEFSGeneralPropertyPage::CEFSGeneralPropertyPage(CCertMgrComponentData* pCompData, bool bIsMachine)
  28. : CHelpPropertyPage(CEFSGeneralPropertyPage::IDD),
  29. m_bIsMachine (bIsMachine),
  30. m_hGroupPolicyKey (0),
  31. m_pGPEInformation (pCompData ? pCompData->GetGPEInformation () : 0),
  32. m_pCompData (pCompData),
  33. m_bDirty (false)
  34. {
  35. //{{AFX_DATA_INIT(CEFSGeneralPropertyPage)
  36. // NOTE: the ClassWizard will add member initialization here
  37. //}}AFX_DATA_INIT
  38. if ( m_pCompData )
  39. m_pCompData->AddRef ();
  40. if ( m_pGPEInformation )
  41. {
  42. HRESULT hResult = m_pGPEInformation->GetRegistryKey (m_bIsMachine ?
  43. GPO_SECTION_MACHINE : GPO_SECTION_USER,
  44. &m_hGroupPolicyKey);
  45. ASSERT (SUCCEEDED (hResult));
  46. }
  47. }
  48. CEFSGeneralPropertyPage::~CEFSGeneralPropertyPage()
  49. {
  50. if ( m_pCompData )
  51. m_pCompData->Release ();
  52. }
  53. void CEFSGeneralPropertyPage::DoDataExchange(CDataExchange* pDX)
  54. {
  55. CHelpPropertyPage::DoDataExchange(pDX);
  56. //{{AFX_DATA_MAP(CEFSGeneralPropertyPage)
  57. // NOTE: the ClassWizard will add DDX and DDV calls here
  58. //}}AFX_DATA_MAP
  59. }
  60. BEGIN_MESSAGE_MAP(CEFSGeneralPropertyPage, CHelpPropertyPage)
  61. //{{AFX_MSG_MAP(CEFSGeneralPropertyPage)
  62. ON_BN_CLICKED(IDC_TURN_ON_EFS, OnTurnOnEfs)
  63. //}}AFX_MSG_MAP
  64. END_MESSAGE_MAP()
  65. /////////////////////////////////////////////////////////////////////////////
  66. // CEFSGeneralPropertyPage message handlers
  67. BOOL CEFSGeneralPropertyPage::OnInitDialog()
  68. {
  69. CHelpPropertyPage::OnInitDialog();
  70. // The regkey to disable EFS is:
  71. // HKLM\Software\Policies\Microsoft\Windows NT\CurrentVersion\EFS\EfsConfiguration DWORD 0x00000001 =>Disable EFS
  72. // If this is the RSOP, make it read-only
  73. if ( !m_pGPEInformation )
  74. {
  75. // Make the page read-only
  76. GetDlgItem (IDC_TURN_ON_EFS)->EnableWindow (FALSE);
  77. RSOPGetEFSFlags ();
  78. }
  79. else
  80. {
  81. GPEGetEFSFlags ();
  82. }
  83. return TRUE; // return TRUE unless you set the focus to a control
  84. // EXCEPTION: OCX Property Pages should return FALSE
  85. }
  86. void CEFSGeneralPropertyPage::GPEGetEFSFlags()
  87. {
  88. HKEY hKey = 0;
  89. LONG lResult = ::RegOpenKeyEx (m_hGroupPolicyKey, // handle to open key
  90. EFS_SETTINGS_REGPATH, // subkey name
  91. 0, // reserved
  92. KEY_READ, // security access mask
  93. &hKey); // handle to open key
  94. if ( ERROR_SUCCESS == lResult )
  95. {
  96. // Read value
  97. DWORD dwType = REG_DWORD;
  98. DWORD dwData = 0;
  99. DWORD cbData = sizeof (dwData);
  100. lResult = ::RegQueryValueEx (hKey, // handle of key to query
  101. EFS_SETTINGS_REGVALUE, // address of name of value to query
  102. 0, // reserved
  103. &dwType, // address of buffer for value type
  104. (LPBYTE) &dwData, // address of data buffer
  105. &cbData); // address of data buffer size);
  106. ASSERT (ERROR_SUCCESS == lResult || ERROR_FILE_NOT_FOUND == lResult);
  107. if ( ERROR_SUCCESS == lResult || ERROR_FILE_NOT_FOUND == lResult )
  108. {
  109. if ( 0 == dwData ) // 0 means enable EFS
  110. SendDlgItemMessage (IDC_TURN_ON_EFS, BM_SETCHECK, BST_CHECKED);
  111. }
  112. else
  113. DisplaySystemError (NULL, lResult);
  114. ::RegCloseKey (hKey);
  115. }
  116. else // no key means EFS enabled
  117. SendDlgItemMessage (IDC_TURN_ON_EFS, BM_SETCHECK, BST_CHECKED);
  118. }
  119. void CEFSGeneralPropertyPage::DoContextHelp (HWND hWndControl)
  120. {
  121. _TRACE (1, L"Entering CEFSGeneralPropertyPage::DoContextHelp\n");
  122. static const DWORD help_map[] =
  123. {
  124. IDC_TURN_ON_EFS, IDH_TURN_ON_EFS,
  125. 0, 0
  126. };
  127. if ( !::WinHelp (
  128. hWndControl,
  129. GetF1HelpFilename(),
  130. HELP_WM_HELP,
  131. (DWORD_PTR) help_map) )
  132. {
  133. _TRACE (0, L"WinHelp () failed: 0x%x\n", GetLastError ());
  134. }
  135. _TRACE (-1, L"Leaving CEFSGeneralPropertyPage::DoContextHelp\n");
  136. }
  137. void CEFSGeneralPropertyPage::RSOPGetEFSFlags()
  138. {
  139. if ( m_pCompData )
  140. {
  141. const CRSOPObjectArray* pObjectArray =
  142. m_bIsMachine ? m_pCompData->GetRSOPObjectArrayComputer () :
  143. m_pCompData->GetRSOPObjectArrayUser ();
  144. int nIndex = 0;
  145. bool bFound = false;
  146. // NOTE: rsop object array is sorted first by registry key, then by precedence
  147. INT_PTR nUpperBound = pObjectArray->GetUpperBound ();
  148. while ( nUpperBound >= nIndex )
  149. {
  150. CRSOPObject* pObject = pObjectArray->GetAt (nIndex);
  151. if ( pObject )
  152. {
  153. // Consider only entries from this store
  154. if ( !_wcsicmp (EFS_SETTINGS_REGPATH, pObject->GetRegistryKey ()) &&
  155. !_wcsicmp (EFS_SETTINGS_REGVALUE, pObject->GetValueName ()) )
  156. {
  157. ASSERT (1 == pObject->GetPrecedence ());
  158. if ( 0 == pObject->GetDWORDValue () ) // 0 means enable EFS
  159. SendDlgItemMessage (IDC_TURN_ON_EFS, BM_SETCHECK, BST_CHECKED);
  160. bFound = true;
  161. break;
  162. }
  163. }
  164. else
  165. break;
  166. nIndex++;
  167. }
  168. if ( !bFound ) // not found means EFS enabled
  169. SendDlgItemMessage (IDC_TURN_ON_EFS, BM_SETCHECK, BST_CHECKED);
  170. }
  171. }
  172. BOOL CEFSGeneralPropertyPage::OnApply()
  173. {
  174. if ( m_bDirty && m_pGPEInformation )
  175. {
  176. // Unchecked means disable EFS - set flag to 1
  177. if ( BST_UNCHECKED == SendDlgItemMessage (IDC_TURN_ON_EFS, BM_GETCHECK) )
  178. {
  179. // Create Key
  180. HKEY hKey = 0;
  181. DWORD dwDisposition = 0;
  182. LONG lResult = ::RegCreateKeyEx (m_hGroupPolicyKey, // handle of an open key
  183. EFS_SETTINGS_REGPATH, // address of subkey name
  184. 0, // reserved
  185. L"", // address of class string
  186. REG_OPTION_NON_VOLATILE, // special options flag
  187. KEY_ALL_ACCESS, // desired security access
  188. NULL, // address of key security structure
  189. &hKey, // address of buffer for opened handle
  190. &dwDisposition); // address of disposition value buffer
  191. ASSERT (lResult == ERROR_SUCCESS);
  192. if ( lResult == ERROR_SUCCESS )
  193. {
  194. DWORD dwData = 0x01; // 0 means disable EFS
  195. DWORD cbData = sizeof (dwData);
  196. lResult = ::RegSetValueEx (hKey,
  197. EFS_SETTINGS_REGVALUE, // address of value to set
  198. 0, // reserved
  199. REG_DWORD, // flag for value type
  200. (CONST BYTE *) &dwData, // address of value data
  201. cbData); // size of value data);
  202. ASSERT (ERROR_SUCCESS == lResult);
  203. if ( ERROR_SUCCESS == lResult )
  204. {
  205. // TRUE means we're changing the machine policy only
  206. m_pGPEInformation->PolicyChanged (m_bIsMachine ? TRUE : FALSE,
  207. TRUE, &g_guidExtension, &g_guidSnapin);
  208. m_pGPEInformation->PolicyChanged (m_bIsMachine ? TRUE : FALSE,
  209. TRUE, &g_guidRegExt, &g_guidSnapin);
  210. }
  211. else
  212. DisplaySystemError (m_hWnd, lResult);
  213. ::RegCloseKey (hKey);
  214. }
  215. }
  216. else
  217. {
  218. // Delete Key
  219. HKEY hKey = 0;
  220. LONG lResult = ::RegOpenKeyEx (m_hGroupPolicyKey, // handle to open key
  221. EFS_SETTINGS_REGPATH, // subkey name
  222. 0, // reserved
  223. KEY_ALL_ACCESS, // security access mask
  224. &hKey); // handle to open key
  225. if ( ERROR_SUCCESS == lResult )
  226. {
  227. lResult = ::RegDeleteValue (hKey, // handle of key to query
  228. EFS_SETTINGS_REGVALUE);
  229. ASSERT (ERROR_SUCCESS == lResult);
  230. if ( ERROR_SUCCESS == lResult )
  231. {
  232. // TRUE means we're changing the machine policy only
  233. m_pGPEInformation->PolicyChanged (m_bIsMachine ? TRUE : FALSE,
  234. TRUE, &g_guidExtension, &g_guidSnapin);
  235. m_pGPEInformation->PolicyChanged (m_bIsMachine ? TRUE : FALSE,
  236. TRUE, &g_guidRegExt, &g_guidSnapin);
  237. }
  238. else if ( ERROR_FILE_NOT_FOUND != lResult )
  239. {
  240. CString text;
  241. CString caption;
  242. text.FormatMessage (IDS_CANNOT_SET_EFS_VALUE, lResult);
  243. VERIFY (caption.LoadString (IDS_PUBLIC_KEY_POLICIES_NODE_NAME));
  244. MessageBox (text, caption, MB_OK | MB_ICONWARNING);
  245. return FALSE;
  246. }
  247. ::RegCloseKey (hKey);
  248. }
  249. else if ( ERROR_FILE_NOT_FOUND != lResult ) // expected error
  250. {
  251. CString text;
  252. CString caption;
  253. text.FormatMessage (IDS_CANNOT_SET_EFS_VALUE, lResult);
  254. VERIFY (caption.LoadString (IDS_PUBLIC_KEY_POLICIES_NODE_NAME));
  255. MessageBox (text, caption, MB_OK | MB_ICONWARNING);
  256. return FALSE;
  257. }
  258. }
  259. }
  260. return CHelpPropertyPage::OnApply();
  261. }
  262. void CEFSGeneralPropertyPage::OnTurnOnEfs()
  263. {
  264. SetModified ();
  265. m_bDirty = true;
  266. }