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.

561 lines
16 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation 1996-2001.
  5. //
  6. // File: aservice.cpp
  7. //
  8. // Contents: implementation of CAnalysisService
  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 "Aservice.h"
  18. #include "util.h"
  19. #include "servperm.h"
  20. #ifdef _DEBUG
  21. #define new DEBUG_NEW
  22. #undef THIS_FILE
  23. static char THIS_FILE[] = __FILE__;
  24. #endif
  25. BYTE
  26. CompareServiceNode(
  27. PSCE_SERVICES pBaseService,
  28. PSCE_SERVICES pAnalService
  29. )
  30. {
  31. if ( NULL == pBaseService ||
  32. NULL == pAnalService ) {
  33. // one or both are not configured
  34. return SCE_STATUS_NOT_CONFIGURED;
  35. }
  36. if ( pBaseService == pAnalService ) {
  37. // same address
  38. pAnalService->Status = SCE_STATUS_GOOD;
  39. return SCE_STATUS_GOOD;
  40. }
  41. if ( pBaseService->Startup != pAnalService->Startup ) {
  42. // startup type is different
  43. pAnalService->Status = SCE_STATUS_MISMATCH;
  44. return SCE_STATUS_MISMATCH;
  45. }
  46. if ( NULL == pBaseService->General.pSecurityDescriptor &&
  47. NULL == pAnalService->General.pSecurityDescriptor ) {
  48. // both do not have SD - everyone full control
  49. pAnalService->Status = SCE_STATUS_GOOD;
  50. return SCE_STATUS_GOOD;
  51. }
  52. if ( NULL == pBaseService->General.pSecurityDescriptor ||
  53. NULL == pAnalService->General.pSecurityDescriptor ) {
  54. // one SD is NULL
  55. pAnalService->Status = SCE_STATUS_MISMATCH;
  56. return SCE_STATUS_MISMATCH;
  57. }
  58. BOOL bIsDif=FALSE;
  59. SCESTATUS rc = SceCompareSecurityDescriptors(
  60. AREA_SYSTEM_SERVICE,
  61. pBaseService->General.pSecurityDescriptor,
  62. pAnalService->General.pSecurityDescriptor,
  63. pBaseService->SeInfo | pAnalService->SeInfo,
  64. &bIsDif
  65. );
  66. if ( SCESTATUS_SUCCESS == rc &&
  67. bIsDif == FALSE ) {
  68. pAnalService->Status = SCE_STATUS_GOOD;
  69. return SCE_STATUS_GOOD;
  70. }
  71. pAnalService->Status = SCE_STATUS_MISMATCH;
  72. return SCE_STATUS_MISMATCH;
  73. }
  74. /////////////////////////////////////////////////////////////////////////////
  75. // CAnalysisService dialog
  76. CAnalysisService::CAnalysisService()
  77. : CAttribute(IDD),
  78. m_pNewSD(NULL),
  79. m_NewSeInfo(0),
  80. m_pAnalSD(NULL),
  81. m_hwndShow(NULL),
  82. m_hwndChange(NULL),
  83. m_SecInfo(DACL_SECURITY_INFORMATION | SACL_SECURITY_INFORMATION),
  84. m_pEditSec(NULL),
  85. m_pShowSec(NULL)
  86. {
  87. //{{AFX_DATA_INIT(CAnalysisService)
  88. m_nStartupRadio = -1;
  89. m_CurrentStr = _T("");
  90. //}}AFX_DATA_INIT
  91. m_pHelpIDs = (DWORD_PTR)a194HelpIDs;
  92. m_uTemplateResID = IDD;
  93. }
  94. CAnalysisService::~CAnalysisService()
  95. {
  96. if (::IsWindow(m_hwndShow))
  97. {
  98. m_pShowSec->Destroy(m_hwndShow);
  99. m_hwndShow = NULL;
  100. }
  101. delete m_pShowSec;
  102. m_pShowSec = NULL;
  103. if (::IsWindow(m_hwndChange))
  104. {
  105. m_pEditSec->Destroy(m_hwndChange);
  106. m_hwndChange = NULL;
  107. }
  108. delete m_pEditSec;
  109. m_pEditSec = NULL;
  110. }
  111. void CAnalysisService::DoDataExchange(CDataExchange* pDX)
  112. {
  113. CAttribute::DoDataExchange(pDX);
  114. //{{AFX_DATA_MAP(CAnalysisService)
  115. DDX_Text(pDX, IDC_CURRENT, m_CurrentStr);
  116. DDX_Radio(pDX, IDC_ENABLED, m_nStartupRadio);
  117. DDX_Control(pDX, IDC_BASESD, m_bPermission);
  118. //}}AFX_DATA_MAP
  119. }
  120. BEGIN_MESSAGE_MAP(CAnalysisService, CAttribute)
  121. //{{AFX_MSG_MAP(CAnalysisService)
  122. ON_BN_CLICKED(IDC_BASESD, OnChangeSecurity)
  123. ON_BN_CLICKED(IDC_CURRENTSD, OnShowSecurity)
  124. ON_BN_CLICKED(IDC_CONFIGURE, OnConfigure)
  125. //}}AFX_MSG_MAP
  126. END_MESSAGE_MAP()
  127. /////////////////////////////////////////////////////////////////////////////
  128. // CAnalysisService message handlers
  129. BOOL CAnalysisService::OnApply()
  130. {
  131. if ( !m_bReadOnly )
  132. {
  133. // OnQueryCancel does all gestures and returns false if child windows are up
  134. if (!OnQueryCancel())
  135. return FALSE;
  136. DWORD dw = 0;
  137. int status = 0;
  138. PEDITTEMPLATE pet = 0;
  139. UpdateData(TRUE);
  140. PSCE_SERVICES pNode = (PSCE_SERVICES)(m_pData->GetBase());
  141. if (!m_bConfigure )
  142. {
  143. if ( NULL != pNode )
  144. {
  145. m_pSnapin->SetupLinkServiceNodeToBase(FALSE, m_pData->GetBase());
  146. if ( m_pData->GetBase() != m_pData->GetSetting() )
  147. {
  148. //
  149. // analysis is not using the same node, free it
  150. //
  151. pNode->Next = NULL;
  152. SceFreeMemory(pNode, SCE_STRUCT_SERVICES);
  153. }
  154. else
  155. {
  156. //
  157. // add the node to analysis
  158. //
  159. pNode->Status = SCE_STATUS_NOT_CONFIGURED;
  160. m_pSnapin->AddServiceNodeToProfile(pNode);
  161. }
  162. m_pData->SetBase(0);
  163. }
  164. m_pData->SetStatus(SCE_STATUS_NOT_CONFIGURED);
  165. if ( m_pNewSD )
  166. {
  167. LocalFree(m_pNewSD);
  168. m_pNewSD = NULL;
  169. }
  170. }
  171. else
  172. {
  173. switch(m_nStartupRadio)
  174. {
  175. case 0:
  176. // Automatic
  177. dw = SCE_STARTUP_AUTOMATIC;
  178. break;
  179. case 1:
  180. // Manual
  181. dw = SCE_STARTUP_MANUAL;
  182. break;
  183. default:
  184. // DISABLED
  185. dw = SCE_STARTUP_DISABLED;
  186. break;
  187. }
  188. if ( NULL != pNode &&
  189. m_pData->GetBase() == m_pData->GetSetting() )
  190. {
  191. //
  192. // a matched item is changed to mismatch
  193. // needs to create a new node
  194. //
  195. m_pSnapin->SetupLinkServiceNodeToBase(FALSE, m_pData->GetBase());
  196. m_pData->SetBase(0);
  197. //
  198. // add to analysis profile
  199. //
  200. pNode->Status = SCE_STATUS_MISMATCH;
  201. m_pSnapin->AddServiceNodeToProfile(pNode);
  202. pNode = NULL;
  203. }
  204. PSCE_SERVICES pSetting = (PSCE_SERVICES)(m_pData->GetSetting());
  205. BYTE status = 0;
  206. if ( NULL == pNode )
  207. {
  208. //
  209. // a node is changed from not configured to configured
  210. // or from match to mismatch
  211. //
  212. pNode = CreateServiceNode(m_pData->GetUnits(),
  213. m_pData->GetAttr(),
  214. dw,
  215. m_pNewSD,
  216. m_NewSeInfo);
  217. if ( pNode != NULL )
  218. {
  219. //
  220. // add to the service list
  221. //
  222. m_pSnapin->SetupLinkServiceNodeToBase(TRUE, (LONG_PTR)pNode);
  223. m_pData->SetBase((LONG_PTR)pNode);
  224. if ( pSetting )
  225. {
  226. status = CompareServiceNode(pNode, pSetting);
  227. m_pData->SetStatus(status);
  228. }
  229. else
  230. {
  231. //
  232. // this is a new configured service
  233. // should create a "dump" analysis node to indictae
  234. // this service is not a "matched" item
  235. //
  236. pSetting = CreateServiceNode(m_pData->GetUnits(),
  237. m_pData->GetAttr(),
  238. 0,
  239. NULL,
  240. 0);
  241. if ( pSetting )
  242. {
  243. //
  244. // link it to analysis profile
  245. //
  246. PEDITTEMPLATE pet = 0;
  247. PSCE_PROFILE_INFO pInfo=NULL;
  248. pet = m_pSnapin->GetTemplate(GT_LAST_INSPECTION, AREA_SYSTEM_SERVICE);
  249. if (NULL != pet )
  250. pInfo = pet->pTemplate;
  251. if ( pInfo )
  252. {
  253. pSetting->Status = SCE_STATUS_NOT_CONFIGURED;
  254. pSetting->Next = pInfo->pServices;
  255. pInfo->pServices = pSetting;
  256. m_pData->SetSetting( (LONG_PTR)pSetting);
  257. }
  258. else
  259. {
  260. //
  261. // free pSetting
  262. //
  263. LocalFree(pSetting->DisplayName);
  264. LocalFree(pSetting->ServiceName);
  265. LocalFree(pSetting);
  266. pSetting = NULL;
  267. }
  268. }
  269. m_pData->SetStatus(SCE_STATUS_NOT_CONFIGURED);
  270. }
  271. }
  272. else
  273. {
  274. //
  275. // no memory, error out
  276. //
  277. if ( m_pNewSD )
  278. {
  279. LocalFree(m_pNewSD);
  280. m_pNewSD = NULL;
  281. }
  282. }
  283. }
  284. else
  285. {
  286. //
  287. // an existing service
  288. //
  289. pNode->Startup = (BYTE)dw;
  290. if ( m_pNewSD != NULL )
  291. {
  292. if ( pNode->General.pSecurityDescriptor != m_pNewSD &&
  293. pNode->General.pSecurityDescriptor != NULL )
  294. {
  295. LocalFree(pNode->General.pSecurityDescriptor);
  296. }
  297. pNode->General.pSecurityDescriptor = m_pNewSD;
  298. m_pNewSD = NULL;
  299. pNode->SeInfo = m_NewSeInfo;
  300. }
  301. //
  302. // update status field in the analysis node
  303. //
  304. if ( pSetting )
  305. {
  306. status = CompareServiceNode(pNode, pSetting);
  307. m_pData->SetStatus(status);
  308. }
  309. else
  310. {
  311. // this is a new configured service
  312. m_pData->SetStatus(SCE_STATUS_NOT_CONFIGURED);
  313. }
  314. }
  315. }
  316. pet = m_pData->GetBaseProfile();
  317. pet->SetDirty(AREA_SYSTEM_SERVICE);
  318. m_pData->Update(m_pSnapin);
  319. m_NewSeInfo = 0;
  320. m_hwndParent = NULL;
  321. m_hwndShow = NULL;
  322. m_hwndChange = NULL;
  323. }
  324. return CAttribute::OnApply();
  325. }
  326. void CAnalysisService::OnCancel()
  327. {
  328. if ( m_pNewSD )
  329. {
  330. LocalFree(m_pNewSD);
  331. m_pNewSD = NULL;
  332. }
  333. m_NewSeInfo = 0;
  334. m_hwndParent = NULL;
  335. m_pAnalSD = NULL;
  336. m_hwndShow = NULL;
  337. m_hwndChange = NULL;
  338. CAttribute::OnCancel();
  339. }
  340. BOOL CAnalysisService::OnInitDialog()
  341. {
  342. CAttribute::OnInitDialog();
  343. if ( 0 == m_pData->GetSetting() ) {
  344. CButton *rb = (CButton *)GetDlgItem(IDC_CURRENTSD);
  345. rb->EnableWindow(FALSE);
  346. }
  347. AddUserControl(IDC_ENABLED);
  348. AddUserControl(IDC_DISABLED);
  349. AddUserControl(IDC_IGNORE);
  350. AddUserControl(IDC_BASESD);
  351. OnConfigure();
  352. return TRUE; // return TRUE unless you set the focus to a control
  353. // EXCEPTION: OCX Property Pages should return FALSE
  354. }
  355. void CAnalysisService::Initialize(CResult * pResult)
  356. {
  357. CAttribute::Initialize(pResult);
  358. //
  359. // initialize setting
  360. //
  361. m_pNewSD = NULL;
  362. m_NewSeInfo = 0;
  363. m_pAnalSD = NULL;
  364. //
  365. // Never start up with do not configure set. If they're coming
  366. // here it is probably to set a value
  367. //
  368. m_bConfigure = TRUE;
  369. if ( 0 != pResult->GetSetting() ) {
  370. PSCE_SERVICES pServSetting = (PSCE_SERVICES)(pResult->GetSetting());
  371. switch ( pServSetting->Startup ) {
  372. case SCE_STARTUP_AUTOMATIC:
  373. m_CurrentStr.LoadString(IDS_AUTOMATIC);
  374. break;
  375. case SCE_STARTUP_MANUAL:
  376. m_CurrentStr.LoadString(IDS_MANUAL);
  377. break;
  378. default: // disabled
  379. m_CurrentStr.LoadString(IDS_DISABLED);
  380. break;
  381. }
  382. m_pAnalSD = pServSetting->General.pSecurityDescriptor;
  383. }
  384. PSCE_SERVICES pService;
  385. pService = (PSCE_SERVICES)(pResult->GetBase());
  386. if ( NULL == pService ) {
  387. m_bConfigure = FALSE;
  388. pService = (PSCE_SERVICES)(pResult->GetSetting());
  389. }
  390. if ( pService != NULL ) {
  391. switch ( pService->Startup ) {
  392. case SCE_STARTUP_AUTOMATIC:
  393. m_nStartupRadio = 0;
  394. break;
  395. case SCE_STARTUP_MANUAL:
  396. m_nStartupRadio = 1;
  397. break;
  398. default: // disabled
  399. m_nStartupRadio = 2;
  400. break;
  401. }
  402. if ( pService->General.pSecurityDescriptor ) {
  403. MyMakeSelfRelativeSD(pService->General.pSecurityDescriptor,
  404. &m_pNewSD);
  405. }
  406. m_NewSeInfo = pService->SeInfo;
  407. }
  408. }
  409. void CAnalysisService::OnShowSecurity()
  410. {
  411. if ( IsWindow(m_hwndShow) ) {
  412. ::BringWindowToTop(m_hwndShow);
  413. return;
  414. }
  415. PSCE_SERVICES pService = (PSCE_SERVICES)(m_pData->GetSetting());
  416. SECURITY_INFORMATION SeInfo;
  417. if (pService)
  418. m_SecInfo = pService->SeInfo;
  419. // prepare the modeless property page data for the thread to create
  420. // the property sheet.
  421. if (NULL == m_pShowSec)
  422. {
  423. m_pShowSec = new CModelessSceEditor(false,
  424. ANALYSIS_SECURITY_PAGE_RO_NP,
  425. GetSafeHwnd(),
  426. SE_SERVICE,
  427. m_pData->GetAttr());
  428. }
  429. if (NULL != m_pShowSec)
  430. m_pShowSec->Create(&m_pAnalSD, &m_SecInfo, &m_hwndShow);
  431. }
  432. void CAnalysisService::OnConfigure()
  433. {
  434. CAttribute::OnConfigure();
  435. if (m_bConfigure && !m_pNewSD) {
  436. OnChangeSecurity();
  437. }
  438. else if (!m_bConfigure && IsWindow(m_hwndChange))
  439. {
  440. m_pEditSec->Destroy(m_hwndChange);
  441. m_hwndChange = NULL;
  442. }
  443. }
  444. void CAnalysisService::OnChangeSecurity()
  445. {
  446. if ( IsWindow(m_hwndChange) ) {
  447. ::BringWindowToTop(m_hwndChange);
  448. return;
  449. }
  450. if ( !m_pNewSD ) {
  451. GetDefaultServiceSecurity(&m_pNewSD,&m_NewSeInfo);
  452. }
  453. // if it comes to this point, the m_hwndChange must not be a valid Window
  454. // so the can ask to create a modeless dialog
  455. if (NULL == m_pEditSec)
  456. {
  457. m_pEditSec = new CModelessSceEditor(false,
  458. CONFIG_SECURITY_PAGE_NO_PROTECT,
  459. GetSafeHwnd(),
  460. SE_SERVICE,
  461. m_pData->GetAttr());
  462. }
  463. if (NULL != m_pEditSec)
  464. m_pEditSec->Create(&m_pNewSD, &m_NewSeInfo, &m_hwndChange);
  465. }
  466. //------------------------------------------------------------------
  467. // override to prevent the sheet from being destroyed when there is
  468. // child dialogs still up and running.
  469. //------------------------------------------------------------------
  470. BOOL CAnalysisService::OnQueryCancel()
  471. {
  472. if (::IsWindow(m_hwndChange) || ::IsWindow(m_hwndShow))
  473. {
  474. CString strMsg;
  475. strMsg.LoadString(IDS_CLOSESUBSHEET_BEFORE_APPLY);
  476. AfxMessageBox(strMsg);
  477. return FALSE;
  478. }
  479. else
  480. return TRUE;
  481. }