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.

440 lines
11 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation 1996-2001.
  5. //
  6. // File: cservice.cpp
  7. //
  8. // Contents: implementation of CConfigService
  9. //
  10. //----------------------------------------------------------------------------
  11. #include "stdafx.h"
  12. #include "wsecmgr.h"
  13. #include "resource.h"
  14. #include "snapmgr.h"
  15. #include "attr.h"
  16. #include "Cservice.h"
  17. #include "util.h"
  18. #include "servperm.h"
  19. #ifdef _DEBUG
  20. #define new DEBUG_NEW
  21. #undef THIS_FILE
  22. static char THIS_FILE[] = __FILE__;
  23. #endif
  24. /////////////////////////////////////////////////////////////////////////////
  25. // CConfigService dialog
  26. CConfigService::CConfigService(UINT nTemplateID)
  27. : CAttribute(nTemplateID ? nTemplateID : IDD),
  28. m_hwndSecurity(NULL),
  29. m_pNewSD(NULL),
  30. m_NewSeInfo(0)
  31. {
  32. //{{AFX_DATA_INIT(CConfigService)
  33. m_nStartupRadio = -1;
  34. //}}AFX_DATA_INIT
  35. m_pHelpIDs = (DWORD_PTR) a195HelpIDs;
  36. m_uTemplateResID = IDD;
  37. }
  38. void CConfigService::DoDataExchange(CDataExchange* pDX)
  39. {
  40. CAttribute::DoDataExchange(pDX);
  41. //{{AFX_DATA_MAP(CConfigService)
  42. DDX_Radio(pDX, IDC_ENABLED, m_nStartupRadio);
  43. DDX_Control(pDX, IDC_BASESD, m_bPermission);
  44. //}}AFX_DATA_MAP
  45. }
  46. BEGIN_MESSAGE_MAP(CConfigService, CAttribute)
  47. //{{AFX_MSG_MAP(CConfigService)
  48. ON_BN_CLICKED(IDC_CONFIGURE, OnConfigure)
  49. ON_BN_CLICKED(IDC_BASESD, OnChangeSecurity)
  50. ON_BN_CLICKED(IDC_DISABLED, OnDisabled)
  51. ON_BN_CLICKED(IDC_IGNORE, OnIgnore)
  52. ON_BN_CLICKED(IDC_ENABLED, OnEnabled)
  53. //}}AFX_MSG_MAP
  54. END_MESSAGE_MAP()
  55. /////////////////////////////////////////////////////////////////////////////
  56. // CConfigService message handlers
  57. BOOL CConfigService::OnApply()
  58. {
  59. if ( !m_bReadOnly )
  60. {
  61. DWORD dw = 0;
  62. int status = 0;
  63. UpdateData(TRUE);
  64. PEDITTEMPLATE pTemp = m_pData->GetBaseProfile();
  65. if (!m_bConfigure )
  66. {
  67. if ( m_pData->GetBase() != 0 )
  68. {
  69. if ( pTemp != NULL && pTemp->pTemplate != NULL )
  70. {
  71. //
  72. // look for the address stored in m_pData->GetBase()
  73. // if found it, delete it.
  74. //
  75. PSCE_SERVICES pServParent, pService;
  76. for ( pService=pTemp->pTemplate->pServices, pServParent=NULL;
  77. pService != NULL; pServParent=pService, pService=pService->Next )
  78. {
  79. if (pService == (PSCE_SERVICES)m_pData->GetBase() )
  80. {
  81. //
  82. // a configured service becomes not configured
  83. //
  84. if ( pServParent == NULL )
  85. {
  86. // the first service
  87. pTemp->pTemplate->pServices = pService->Next;
  88. }
  89. else
  90. pServParent->Next = pService->Next;
  91. pService->Next = NULL;
  92. break;
  93. }
  94. }
  95. m_pData->SetBase(NULL); //Raid #378271, 4/27/2001
  96. }
  97. else
  98. {
  99. // should never happen
  100. //
  101. // free the service node
  102. //
  103. SceFreeMemory((PVOID)(m_pData->GetBase()), SCE_STRUCT_SERVICES);
  104. m_pData->SetBase(0);
  105. }
  106. }
  107. if ( m_pNewSD )
  108. {
  109. LocalFree(m_pNewSD);
  110. m_pNewSD = NULL;
  111. }
  112. }
  113. else
  114. {
  115. switch(m_nStartupRadio)
  116. {
  117. case 0:
  118. // Automatic
  119. dw = SCE_STARTUP_AUTOMATIC;
  120. break;
  121. case 1:
  122. // Manual
  123. dw = SCE_STARTUP_MANUAL;
  124. break;
  125. default:
  126. // DISABLED
  127. dw = SCE_STARTUP_DISABLED;
  128. break;
  129. }
  130. PSCE_SERVICES pNode=(PSCE_SERVICES)(m_pData->GetBase());
  131. if ( NULL == pNode )
  132. {
  133. //
  134. // a node is changed from not configured to configured
  135. //
  136. pNode = CreateServiceNode(m_pData->GetUnits(),
  137. m_pData->GetAttr(),
  138. dw,
  139. m_pNewSD,
  140. m_NewSeInfo);
  141. if ( pNode != NULL )
  142. {
  143. //
  144. // add to the service list
  145. //
  146. pNode->Next = pTemp->pTemplate->pServices;
  147. pTemp->pTemplate->pServices = pNode;
  148. m_pData->SetBase((LONG_PTR)pNode);
  149. m_pNewSD = NULL;
  150. }
  151. else
  152. {
  153. //
  154. // no memory, error out
  155. //
  156. if ( m_pNewSD )
  157. {
  158. LocalFree(m_pNewSD);
  159. m_pNewSD = NULL;
  160. }
  161. }
  162. }
  163. else
  164. {
  165. //
  166. // an existing service
  167. //
  168. pNode->Startup = (BYTE)dw;
  169. if ( m_pNewSD != NULL )
  170. {
  171. if ( pNode->General.pSecurityDescriptor != m_pNewSD &&
  172. pNode->General.pSecurityDescriptor != NULL )
  173. {
  174. LocalFree(pNode->General.pSecurityDescriptor);
  175. }
  176. pNode->General.pSecurityDescriptor = m_pNewSD;
  177. m_pNewSD = NULL;
  178. pNode->SeInfo = m_NewSeInfo;
  179. }
  180. }
  181. }
  182. m_pData->Update(m_pSnapin);
  183. m_NewSeInfo = 0;
  184. m_hwndParent = NULL;
  185. }
  186. return CAttribute::OnApply();
  187. }
  188. void CConfigService::OnCancel()
  189. {
  190. if ( m_pNewSD )
  191. {
  192. LocalFree(m_pNewSD);
  193. m_pNewSD = NULL;
  194. }
  195. m_NewSeInfo = 0;
  196. m_hwndParent = NULL;
  197. m_bConfigure = m_bOriginalConfigure;
  198. CAttribute::OnCancel();
  199. }
  200. BOOL CConfigService::OnInitDialog()
  201. {
  202. CAttribute::OnInitDialog();
  203. m_bOriginalConfigure = m_bConfigure;
  204. AddUserControl(IDC_ENABLED);
  205. AddUserControl(IDC_DISABLED);
  206. AddUserControl(IDC_IGNORE);
  207. AddUserControl(IDC_BASESD);
  208. if (QueryReadOnly())
  209. {
  210. CString str;
  211. str.LoadString(IDS_VIEW_SECURITY);
  212. if ( GetDlgItem(IDC_SECURITY) )
  213. SetDlgItemText(IDC_SECURITY,str);
  214. else if ( GetDlgItem(IDC_BASESD) )
  215. SetDlgItemText(IDC_BASESD,str);
  216. }
  217. OnConfigure();
  218. return TRUE; // return TRUE unless you set the focus to a control
  219. // EXCEPTION: OCX Property Pages should return FALSE
  220. }
  221. void CConfigService::Initialize(CResult * pResult)
  222. {
  223. CAttribute::Initialize(pResult);
  224. PSCE_SERVICES pService;
  225. pService = (PSCE_SERVICES)(pResult->GetBase());
  226. if ( NULL == pService ) {
  227. m_bConfigure = FALSE;
  228. pService = (PSCE_SERVICES)(pResult->GetSetting());
  229. }
  230. m_pNewSD = NULL;
  231. m_NewSeInfo = 0;
  232. if ( pService != NULL ) {
  233. switch ( pService->Startup ) {
  234. case SCE_STARTUP_AUTOMATIC:
  235. m_nStartupRadio = 0;
  236. break;
  237. case SCE_STARTUP_MANUAL:
  238. m_nStartupRadio = 1;
  239. break;
  240. default: // disabled
  241. m_nStartupRadio = 2;
  242. break;
  243. }
  244. //
  245. // initialize SD and SeInfo
  246. //
  247. if ( pService->General.pSecurityDescriptor ) {
  248. MyMakeSelfRelativeSD(pService->General.pSecurityDescriptor,
  249. &m_pNewSD);
  250. }
  251. m_NewSeInfo = pService->SeInfo;
  252. }
  253. }
  254. PSCE_SERVICES
  255. CreateServiceNode(LPTSTR ServiceName,
  256. LPTSTR DisplayName,
  257. DWORD Startup,
  258. PSECURITY_DESCRIPTOR pSD,
  259. SECURITY_INFORMATION SeInfo)
  260. {
  261. if ( NULL == ServiceName ) {
  262. return NULL;
  263. }
  264. PSCE_SERVICES pTemp;
  265. pTemp = (PSCE_SERVICES)LocalAlloc(0,sizeof(SCE_SERVICES));
  266. if ( pTemp != NULL ) {
  267. pTemp->ServiceName = (LPTSTR)LocalAlloc(0, (wcslen(ServiceName)+1)*sizeof(TCHAR));
  268. if ( pTemp->ServiceName != NULL ) {
  269. if ( DisplayName != NULL ) {
  270. pTemp->DisplayName = (LPTSTR)LocalAlloc(0, (wcslen(DisplayName)+1)*sizeof(TCHAR));
  271. if ( pTemp->DisplayName != NULL ) {
  272. wcscpy(pTemp->DisplayName, DisplayName);
  273. } else {
  274. // no memory to allocate
  275. LocalFree(pTemp->ServiceName);
  276. LocalFree(pTemp);
  277. return NULL;
  278. }
  279. } else
  280. pTemp->DisplayName = NULL;
  281. wcscpy(pTemp->ServiceName, ServiceName);
  282. pTemp->Status = 0;
  283. pTemp->Startup = (BYTE)Startup;
  284. pTemp->General.pSecurityDescriptor = pSD;
  285. pTemp->SeInfo = SeInfo;
  286. pTemp->Next = NULL;
  287. return pTemp;
  288. } else {
  289. // no memory to allocate
  290. LocalFree(pTemp);
  291. return NULL;
  292. }
  293. }
  294. return NULL;
  295. }
  296. void CConfigService::OnConfigure()
  297. {
  298. CAttribute::OnConfigure();
  299. if (m_bConfigure && !m_pNewSD)
  300. {
  301. OnChangeSecurity();
  302. }
  303. }
  304. void CConfigService::OnChangeSecurity()
  305. {
  306. if (IsWindow(m_hwndSecurity))
  307. {
  308. ::BringWindowToTop(m_hwndSecurity);
  309. return;
  310. }
  311. PSECURITY_DESCRIPTOR m_pOldSD = m_pNewSD; //Raid #358244, 4/5/2001
  312. SECURITY_INFORMATION m_OldSeInfo = m_NewSeInfo;
  313. if (!m_pNewSD)
  314. {
  315. GetDefaultServiceSecurity(&m_pNewSD,&m_NewSeInfo);
  316. }
  317. INT_PTR nRet = MyCreateSecurityPage2(FALSE,
  318. &m_pNewSD,
  319. &m_NewSeInfo,
  320. (LPCTSTR)(m_pData->GetAttr()),
  321. SE_SERVICE,
  322. QueryReadOnly() ? SECURITY_PAGE_RO_NP : SECURITY_PAGE_NO_PROTECT,
  323. GetSafeHwnd(),
  324. FALSE); // not modeless
  325. if ( -1 == nRet )
  326. {
  327. CString str;
  328. str.LoadString(IDS_CANT_ASSIGN_SECURITY);
  329. AfxMessageBox(str);
  330. }
  331. SetModified(TRUE);
  332. }
  333. void CConfigService::OnDisabled()
  334. {
  335. SetModified(TRUE);
  336. }
  337. void CConfigService::OnIgnore()
  338. {
  339. SetModified(TRUE);
  340. }
  341. void CConfigService::OnEnabled()
  342. {
  343. SetModified(TRUE);
  344. }
  345. void
  346. CConfigService::EnableUserControls( BOOL bEnable ) {
  347. CAttribute::EnableUserControls(bEnable);
  348. //
  349. // IDC_SECURITY needs to be available even in read only
  350. // mode so that the security page can be viewed.
  351. //
  352. // The page itself will be read only if necessary
  353. //
  354. if (QueryReadOnly() && bEnable)
  355. {
  356. CWnd* pWnd = GetDlgItem(IDC_SECURITY);
  357. if (pWnd)
  358. {
  359. pWnd->EnableWindow(TRUE);
  360. }
  361. else
  362. {
  363. pWnd = GetDlgItem(IDC_BASESD);
  364. if (pWnd)
  365. {
  366. pWnd->EnableWindow(TRUE);
  367. }
  368. }
  369. }
  370. }