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.

798 lines
21 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation 1996-2001.
  5. //
  6. // File: AObject.cpp
  7. //
  8. // Contents: Implementation of CAttrObject
  9. //
  10. //----------------------------------------------------------------------------
  11. #include "stdafx.h"
  12. #include "wsecmgr.h"
  13. #include "attr.h"
  14. #include "resource.h"
  15. #include "snapmgr.h"
  16. #include "util.h"
  17. #include <accctrl.h>
  18. #include "servperm.h"
  19. #include "AObject.h"
  20. #include <aclapi.h>
  21. #ifdef _DEBUG
  22. #define new DEBUG_NEW
  23. #undef THIS_FILE
  24. static char THIS_FILE[] = __FILE__;
  25. #endif
  26. /////////////////////////////////////////////////////////////////////////////
  27. // CAttrObject dialog
  28. CAttrObject::CAttrObject()
  29. : CAttribute(IDD),
  30. m_pSceInspect(NULL),
  31. m_pSceTemplate(NULL),
  32. posInspect(NULL),
  33. posTemplate(NULL),
  34. m_bNotAnalyzed(FALSE), m_pfnCreateDsPage(NULL), m_pSI(NULL), m_pNewSD(NULL), m_pAnalSD(NULL),
  35. m_pCDI(NULL), m_AnalInfo(0), m_NewSeInfo(0), m_hwndTemplate(NULL), m_hwndInspect(NULL), m_pFolder(NULL)
  36. {
  37. //{{AFX_DATA_INIT(CAttrObject)
  38. m_strLastInspect = _T("");
  39. m_radConfigPrevent = 0;
  40. m_radInheritOverwrite = 0;
  41. //}}AFX_DATA_INIT
  42. m_pHelpIDs = (DWORD_PTR)a198HelpIDs;
  43. m_uTemplateResID = IDD;
  44. }
  45. CAttrObject::~CAttrObject()
  46. {
  47. if (::IsWindow(m_hwndInspect))
  48. {
  49. m_pSceInspect->Destroy(m_hwndInspect);
  50. m_hwndInspect = NULL;
  51. }
  52. delete m_pSceInspect;
  53. m_pSceInspect = NULL;
  54. if (::IsWindow(m_hwndTemplate))
  55. {
  56. m_pSceTemplate->Destroy(m_hwndTemplate);
  57. m_hwndTemplate = NULL;
  58. }
  59. delete m_pSceTemplate;
  60. m_pSceTemplate = NULL;
  61. }
  62. void CAttrObject::DoDataExchange(CDataExchange* pDX)
  63. {
  64. CAttribute::DoDataExchange(pDX);
  65. //{{AFX_DATA_MAP(CAttrObject)
  66. DDX_Text(pDX, IDC_INSPECTED, m_strLastInspect);
  67. DDX_Radio(pDX, IDC_CONFIG, m_radConfigPrevent);
  68. DDX_Radio(pDX, IDC_INHERIT, m_radInheritOverwrite);
  69. //}}AFX_DATA_MAP
  70. }
  71. BEGIN_MESSAGE_MAP(CAttrObject, CAttribute)
  72. //{{AFX_MSG_MAP(CAttrObject)
  73. ON_BN_CLICKED(IDC_TEMPLATE_SECURITY, OnTemplateSecurity)
  74. ON_BN_CLICKED(IDC_INSPECTED_SECURITY, OnInspectedSecurity)
  75. ON_BN_CLICKED(IDC_CONFIGURE, OnConfigure)
  76. ON_BN_CLICKED(IDC_CONFIG, OnConfig)
  77. ON_BN_CLICKED(IDC_PREVENT, OnPrevent)
  78. ON_BN_CLICKED(IDC_OVERWRITE, OnOverwrite)
  79. ON_BN_CLICKED(IDC_INHERIT, OnInherit)
  80. //}}AFX_MSG_MAP
  81. END_MESSAGE_MAP()
  82. /////////////////////////////////////////////////////////////////////////////
  83. // CAttrObject message handlers
  84. void CAttrObject::OnConfigure()
  85. {
  86. CAttribute::OnConfigure();
  87. if ( m_bConfigure ) {
  88. //
  89. // Ensure that the security descriptor is set.
  90. //
  91. if( !m_pNewSD ){
  92. OnTemplateSecurity();
  93. }
  94. UpdateData(FALSE);
  95. }
  96. BOOL bEnable = TRUE;
  97. if(m_pFolder){
  98. DWORD dwStatus = 0;
  99. m_pFolder->GetObjectInfo( &dwStatus, NULL );
  100. switch( dwStatus ){
  101. case SCE_STATUS_NOT_ANALYZED:
  102. case SCE_STATUS_ERROR_NOT_AVAILABLE:
  103. case SCE_STATUS_NOT_CONFIGURED:
  104. bEnable = FALSE;
  105. break;
  106. default:
  107. bEnable = m_pAnalSD || m_AnalInfo;
  108. }
  109. } else {
  110. bEnable = m_pAnalSD || m_AnalInfo;
  111. }
  112. if (m_bConfigure) {
  113. if (0 == m_radConfigPrevent) {
  114. OnConfig();
  115. } else {
  116. OnPrevent();
  117. }
  118. }
  119. }
  120. void CAttrObject::Initialize(CFolder *pFolder,
  121. CComponentDataImpl *pCDI) {
  122. CAttribute::Initialize(NULL);
  123. m_strName = pFolder->GetName();
  124. m_strPath = pFolder->GetName();
  125. m_dwType = pFolder->GetType();
  126. switch (pFolder->GetType()) {
  127. case REG_OBJECTS:
  128. m_dwType = ITEM_REGSD;
  129. break;
  130. case FILE_OBJECTS:
  131. m_dwType = ITEM_FILESD;
  132. break;
  133. default:
  134. m_dwType = 0;
  135. break;
  136. }
  137. m_pObject = (PSCE_OBJECT_LIST)pFolder->GetData();
  138. m_pHandle = pCDI->GetSadHandle();
  139. m_pCDI = pCDI;
  140. m_pFolder = pFolder;
  141. Initialize2();
  142. }
  143. void CAttrObject::Initialize(CResult *pResult) {
  144. CAttribute::Initialize(pResult);
  145. m_strName = pResult->GetAttr();
  146. m_strPath = pResult->GetUnits();
  147. m_pHandle = (HANDLE)pResult->GetID();
  148. m_dwType = pResult->GetType();
  149. m_pObject = (PSCE_OBJECT_LIST)pResult->GetBaseProfile();
  150. m_pCDI = NULL;
  151. Initialize2();
  152. }
  153. void CAttrObject::Initialize2()
  154. {
  155. LPTSTR szPath;
  156. SCESTATUS status;
  157. AREA_INFORMATION Area;
  158. switch (m_dwType) {
  159. case ITEM_REGSD:
  160. Area = AREA_REGISTRY_SECURITY;
  161. break;
  162. case ITEM_FILESD:
  163. Area = AREA_FILE_SECURITY;
  164. break;
  165. default:
  166. ASSERT(FALSE);
  167. return;
  168. }
  169. m_pNewSD = NULL;
  170. m_NewSeInfo = 0;
  171. if ( m_pSI ) {
  172. m_pSI->Release();
  173. m_pSI = NULL;
  174. }
  175. m_pfnCreateDsPage=NULL;
  176. szPath = m_strPath.GetBuffer(1);
  177. status = SceGetObjectSecurity(m_pHandle,
  178. SCE_ENGINE_SMP,
  179. Area,
  180. szPath,
  181. &posTemplate);
  182. m_strPath.ReleaseBuffer();
  183. if (SCESTATUS_SUCCESS == status && posTemplate ) {
  184. switch (posTemplate-> Status) {
  185. case SCE_STATUS_IGNORE:
  186. m_radConfigPrevent = 1;
  187. m_radInheritOverwrite = 0;
  188. break;
  189. case SCE_STATUS_OVERWRITE:
  190. m_radConfigPrevent = 0;
  191. m_radInheritOverwrite = 1;
  192. break;
  193. case SCE_STATUS_CHECK:
  194. m_radConfigPrevent = 0;
  195. m_radInheritOverwrite = 0;
  196. break;
  197. default:
  198. case SCE_STATUS_NO_AUTO_INHERIT:
  199. m_radConfigPrevent = 1;
  200. m_radInheritOverwrite = 0;
  201. break;
  202. }
  203. if ( posTemplate->pSecurityDescriptor ) {
  204. MyMakeSelfRelativeSD(posTemplate->pSecurityDescriptor,
  205. &m_pNewSD);
  206. }
  207. m_NewSeInfo = posTemplate->SeInfo;
  208. } else {
  209. m_bConfigure = FALSE;
  210. }
  211. szPath = m_strPath.GetBuffer(1);
  212. status = SceGetObjectSecurity(m_pHandle,
  213. SCE_ENGINE_SAP,
  214. Area,
  215. szPath,
  216. &posInspect);
  217. m_strPath.ReleaseBuffer();
  218. //
  219. // Display the same thing we displayed on the result pane
  220. //
  221. if (m_pFolder) {
  222. m_pFolder->GetDisplayName( m_strLastInspect, 1 );
  223. } else if (m_pData) {
  224. m_pData->GetDisplayName(0, m_strLastInspect, 1);
  225. } else {
  226. ASSERT(0);
  227. m_strLastInspect.LoadString(IDS_ERROR_VALUE);
  228. }
  229. //
  230. // if the item is good, there will be no SAP record, but a template record exists.
  231. //
  232. if ( posInspect ) {
  233. m_pAnalSD = posInspect->pSecurityDescriptor;
  234. m_AnalInfo = posInspect->SeInfo;
  235. //
  236. // We don't need to display children not configured in the dialog box.
  237. // Instead display the actual status of the item.
  238. //
  239. if( posInspect->Status == SCE_STATUS_CHILDREN_CONFIGURED) {
  240. m_strLastInspect.LoadString(IDS_NOT_CONFIGURED);
  241. }
  242. switch(posInspect->Status &
  243. ~(SCE_STATUS_PERMISSION_MISMATCH | SCE_STATUS_AUDIT_MISMATCH)) {
  244. case SCE_STATUS_CHILDREN_CONFIGURED:
  245. case SCE_STATUS_NOT_CONFIGURED:
  246. case SCE_STATUS_ERROR_NOT_AVAILABLE:
  247. case SCE_STATUS_NEW_SERVICE:
  248. case SCE_STATUS_NOT_ANALYZED:
  249. m_bNotAnalyzed = TRUE;
  250. break;
  251. }
  252. } else if ( posTemplate ) {
  253. m_pAnalSD = posTemplate->pSecurityDescriptor;
  254. m_AnalInfo = posTemplate->SeInfo;
  255. } else {
  256. m_bNotAnalyzed = TRUE;
  257. }
  258. }
  259. void CAttrObject::OnInspectedSecurity()
  260. {
  261. SE_OBJECT_TYPE SeType;
  262. //
  263. // If we already have the inspected security window up then
  264. // don't bring up a second.
  265. //
  266. if (IsWindow(m_hwndInspect)) {
  267. ::BringWindowToTop(m_hwndInspect);
  268. return;
  269. }
  270. switch (m_dwType) {
  271. case ITEM_REGSD:
  272. SeType = SE_REGISTRY_KEY;
  273. break;
  274. case ITEM_FILESD:
  275. SeType = SE_FILE_OBJECT;
  276. break;
  277. default:
  278. ASSERT(FALSE);
  279. return;
  280. }
  281. if ( m_pAnalSD || m_AnalInfo ) {
  282. INT_PTR nRet;
  283. if ( SE_DS_OBJECT == SeType ) {
  284. if ( !m_pfnCreateDsPage ) {
  285. if (!g_hDsSecDll)
  286. g_hDsSecDll = LoadLibrary(TEXT("dssec.dll"));
  287. if ( g_hDsSecDll) {
  288. m_pfnCreateDsPage = (PFNDSCREATEISECINFO)GetProcAddress(g_hDsSecDll,
  289. "DSCreateISecurityInfoObject");
  290. }
  291. }
  292. if ( m_pfnCreateDsPage ) {
  293. nRet= MyCreateDsSecurityPage(&m_pSI,
  294. m_pfnCreateDsPage,
  295. &m_pAnalSD,
  296. &m_AnalInfo,
  297. (LPCTSTR)(m_strName),
  298. ANALYSIS_SECURITY_PAGE_READ_ONLY,
  299. GetSafeHwnd());
  300. } else
  301. nRet = -1;
  302. } else {
  303. BOOL bContainer;
  304. if ( SE_FILE_OBJECT == SeType ) {
  305. if ( m_pObject )
  306. bContainer = m_pObject->IsContainer;
  307. else
  308. bContainer = TRUE;
  309. } else
  310. bContainer = TRUE;
  311. if (NULL == m_pSceInspect)
  312. {
  313. m_pSceInspect = new CModelessSceEditor(bContainer ? true : false,
  314. ANALYSIS_SECURITY_PAGE_READ_ONLY,
  315. GetSafeHwnd(),
  316. SeType,
  317. m_strName);
  318. }
  319. if (NULL != m_pSceInspect)
  320. m_pSceInspect->Create(&m_pAnalSD, &m_AnalInfo, &m_hwndInspect);
  321. }
  322. /*
  323. BUG 147087 - don't display message, since this may have been canceled
  324. if (NULL == m_hwndInspect) {
  325. CString str;
  326. str.LoadString(IDS_CANT_SHOW_SECURITY);
  327. AfxMessageBox(str);
  328. }
  329. */
  330. }
  331. }
  332. void CAttrObject::OnTemplateSecurity()
  333. {
  334. SE_OBJECT_TYPE SeType;
  335. //
  336. // If we already have the inspected security window up then
  337. // don't bring up a second.
  338. //
  339. if (IsWindow(m_hwndTemplate)) {
  340. ::BringWindowToTop(m_hwndTemplate);
  341. return;
  342. }
  343. switch (m_dwType) {
  344. case ITEM_REGSD:
  345. SeType = SE_REGISTRY_KEY;
  346. break;
  347. case ITEM_FILESD:
  348. SeType = SE_FILE_OBJECT;
  349. break;
  350. default:
  351. ASSERT(FALSE);
  352. return;
  353. }
  354. INT_PTR nRet;
  355. nRet = -1;
  356. if ( SE_DS_OBJECT == SeType ) {
  357. if ( !m_pfnCreateDsPage ) {
  358. if (!g_hDsSecDll)
  359. g_hDsSecDll = LoadLibrary(TEXT("dssec.dll"));
  360. if ( g_hDsSecDll) {
  361. m_pfnCreateDsPage = (PFNDSCREATEISECINFO)GetProcAddress(g_hDsSecDll,
  362. "DSCreateISecurityInfoObject");
  363. }
  364. }
  365. if ( m_pfnCreateDsPage ) {
  366. nRet= MyCreateDsSecurityPage(&m_pSI,
  367. m_pfnCreateDsPage,
  368. &m_pNewSD,
  369. &m_NewSeInfo,
  370. (LPCTSTR)(m_strName),
  371. CONFIG_SECURITY_PAGE,
  372. GetSafeHwnd());
  373. } else
  374. nRet = -1;
  375. } else {
  376. BOOL bContainer = TRUE;
  377. if ( !m_pNewSD ) {
  378. //
  379. // if SD is NULL, then inherit is set.
  380. //
  381. DWORD SDSize;
  382. if ( SE_FILE_OBJECT == SeType ) {
  383. GetDefaultFileSecurity(&m_pNewSD,&m_NewSeInfo);
  384. } else {
  385. GetDefaultRegKeySecurity(&m_pNewSD,&m_NewSeInfo);
  386. }
  387. }
  388. // use m_pSceTemplate to create a modeless
  389. if (NULL == m_pSceTemplate)
  390. {
  391. m_pSceTemplate = new CModelessSceEditor(TRUE,
  392. CONFIG_SECURITY_PAGE,
  393. GetSafeHwnd(),
  394. SeType,
  395. m_strName);
  396. }
  397. if (NULL != m_pSceTemplate)
  398. m_pSceTemplate->Create(&m_pNewSD, &m_NewSeInfo, &m_hwndTemplate);
  399. }
  400. if (NULL == m_hwndTemplate ) {
  401. /*
  402. BUG 147098 - don't display message, since this may have been canceled
  403. CString str;
  404. str.LoadString(IDS_CANT_ASSIGN_SECURITY);
  405. AfxMessageBox(str);
  406. */
  407. } else {
  408. SetModified(TRUE);
  409. }
  410. }
  411. BOOL CAttrObject::OnInitDialog()
  412. {
  413. CAttribute::OnInitDialog();
  414. GetDlgItem(IDC_INSPECTED_SECURITY)->EnableWindow(!m_bNotAnalyzed);
  415. UpdateData(FALSE);
  416. AddUserControl(IDC_OVERWRITE);
  417. AddUserControl(IDC_INHERIT);
  418. AddUserControl(IDC_CONFIG);
  419. AddUserControl(IDC_PREVENT);
  420. AddUserControl(IDC_TEMPLATE_SECURITY);
  421. // AddUserControl(IDC_INSPECTED_SECURITY);
  422. OnConfigure();
  423. if (ITEM_REGSD == m_dwType) {
  424. CString str;
  425. str.LoadString(IDS_REGISTRY_CONFIGURE);
  426. SetDlgItemText(IDC_CONFIG,str);
  427. str.LoadString(IDS_REGISTRY_APPLY);
  428. SetDlgItemText(IDC_OVERWRITE,str);
  429. str.LoadString(IDS_REGISTRY_INHERIT);
  430. SetDlgItemText(IDC_INHERIT,str);
  431. str.LoadString(IDS_REGISTRY_PREVENT);
  432. SetDlgItemText(IDC_PREVENT,str);
  433. }
  434. if (m_bConfigure) {
  435. if (0 == m_radConfigPrevent) {
  436. OnConfig();
  437. } else {
  438. OnPrevent();
  439. }
  440. }
  441. return TRUE; // return TRUE unless you set the focus to a control
  442. // EXCEPTION: OCX Property Pages should return FALSE
  443. }
  444. BOOL CAttrObject::OnApply()
  445. {
  446. // OnQueryCancel does all gestures and returns false if child windows are up
  447. if (!OnQueryCancel())
  448. return FALSE;
  449. if ( !m_bReadOnly )
  450. {
  451. LPTSTR szPath;
  452. UpdateData(TRUE);
  453. AREA_INFORMATION Area = 0;
  454. switch (m_dwType) {
  455. case ITEM_REGSD:
  456. Area = AREA_REGISTRY_SECURITY;
  457. break;
  458. case ITEM_FILESD:
  459. Area = AREA_FILE_SECURITY;
  460. break;
  461. default:
  462. ASSERT(FALSE);
  463. }
  464. if ( (NULL != m_pHandle) && (0 != Area) ) {
  465. SCESTATUS sceStatus=SCESTATUS_SUCCESS;
  466. BYTE status;
  467. if ( (m_pSnapin && m_pSnapin->CheckEngineTransaction()) ||
  468. (m_pCDI && m_pCDI->EngineTransactionStarted()) ) {
  469. if (!m_bConfigure ) {
  470. if ( NULL != posTemplate ) {
  471. BOOL bContainer;
  472. if ( m_pObject ) {
  473. bContainer = m_pObject->IsContainer;
  474. } else {
  475. bContainer = TRUE;
  476. }
  477. //
  478. // delete the SMP entry
  479. //
  480. szPath = m_strPath.GetBuffer(1);
  481. sceStatus = SceUpdateObjectInfo(
  482. m_pHandle,
  483. Area,
  484. szPath,
  485. wcslen(szPath),
  486. (BYTE)SCE_NO_VALUE,
  487. bContainer,
  488. NULL,
  489. 0,
  490. &status
  491. );
  492. m_strPath.ReleaseBuffer();
  493. /*
  494. if ( SCESTATUS_SUCCESS == sceStatus &&
  495. (BYTE)SCE_NO_VALUE != status &&
  496. (DWORD)SCE_NO_VALUE != (DWORD)status ) {
  497. */
  498. if (SCESTATUS_SUCCESS == sceStatus) {
  499. if ((BYTE) SCE_NO_VALUE == status) {
  500. status = SCE_STATUS_NOT_CONFIGURED;
  501. }
  502. if (m_pData) {
  503. m_pData->SetStatus(status);
  504. }
  505. if ( m_pObject ) {
  506. m_pObject->Status = status;
  507. }
  508. }
  509. }
  510. } else {
  511. BYTE dw;
  512. switch (m_radConfigPrevent) {
  513. case 0:
  514. // config
  515. switch(m_radInheritOverwrite) {
  516. case 0:
  517. // inherit
  518. dw = SCE_STATUS_CHECK;
  519. break;
  520. case 1:
  521. // overwrite
  522. dw = SCE_STATUS_OVERWRITE;
  523. break;
  524. }
  525. break;
  526. case 1:
  527. // prevent
  528. dw = SCE_STATUS_IGNORE;
  529. break;
  530. }
  531. szPath = m_strPath.GetBuffer(1);
  532. sceStatus = SceUpdateObjectInfo(
  533. m_pHandle,
  534. Area,
  535. szPath,
  536. wcslen(szPath),
  537. dw,
  538. TRUE, //IsContainer
  539. m_pNewSD,
  540. m_NewSeInfo,
  541. &status
  542. );
  543. status = SCE_STATUS_NOT_ANALYZED;
  544. m_strPath.ReleaseBuffer();
  545. //
  546. // This should never happen, but does because
  547. // of engine bugs
  548. //
  549. if ((BYTE) SCE_NO_VALUE == status) {
  550. status = SCE_STATUS_NOT_CONFIGURED;
  551. }
  552. if (SCESTATUS_SUCCESS == sceStatus) {
  553. if (m_pData) {
  554. m_pData->SetStatus(status);
  555. }
  556. if ( m_pObject ) {
  557. m_pObject->Status = status;
  558. }
  559. }
  560. }
  561. if(m_pFolder){
  562. //
  563. // Update status information.
  564. //
  565. m_pCDI->UpdateObjectStatus( m_pFolder, TRUE );
  566. }
  567. } else {
  568. sceStatus = SCESTATUS_OTHER_ERROR;
  569. }
  570. if ( SCESTATUS_SUCCESS == sceStatus ) {
  571. PEDITTEMPLATE pet=NULL;
  572. if (m_pSnapin) {
  573. pet = m_pSnapin->GetTemplate(GT_COMPUTER_TEMPLATE,Area);
  574. } else if (m_pCDI) {
  575. pet = m_pCDI->GetTemplate(GT_COMPUTER_TEMPLATE,Area);
  576. }
  577. if ( pet ) {
  578. pet->SetDirty(Area);
  579. }
  580. if (m_pData) {
  581. m_pData->Update(m_pSnapin);
  582. }
  583. } else {
  584. CString str;
  585. MyFormatResMessage(sceStatus,IDS_SAVE_FAILED,NULL,str);
  586. AfxMessageBox(str);
  587. return FALSE;
  588. }
  589. }
  590. SceFreeMemory((PVOID)posTemplate, SCE_STRUCT_OBJECT_SECURITY);
  591. posTemplate = NULL;
  592. SceFreeMemory((PVOID)posInspect, SCE_STRUCT_OBJECT_SECURITY);
  593. posInspect = NULL;
  594. if ( m_pNewSD ) {
  595. LocalFree(m_pNewSD);
  596. m_pNewSD = NULL;
  597. }
  598. m_NewSeInfo = 0;
  599. m_pAnalSD=NULL;
  600. m_AnalInfo=0;
  601. m_hwndParent = NULL;
  602. if ( m_pSI ) {
  603. m_pSI->Release();
  604. m_pSI = NULL;
  605. }
  606. m_pfnCreateDsPage=NULL;
  607. }
  608. return CAttribute::OnApply();
  609. }
  610. void CAttrObject::OnCancel()
  611. {
  612. SceFreeMemory((PVOID)posTemplate, SCE_STRUCT_OBJECT_SECURITY);
  613. posTemplate = NULL;
  614. SceFreeMemory((PVOID)posInspect, SCE_STRUCT_OBJECT_SECURITY);
  615. posInspect = NULL;
  616. if ( m_pNewSD ) {
  617. LocalFree(m_pNewSD);
  618. m_pNewSD = NULL;
  619. }
  620. m_NewSeInfo = 0;
  621. m_pAnalSD=NULL;
  622. m_AnalInfo=0;
  623. m_hwndParent = NULL;
  624. if ( m_pSI ) {
  625. m_pSI->Release();
  626. m_pSI = NULL;
  627. }
  628. m_pfnCreateDsPage=NULL;
  629. CAttribute::OnCancel();
  630. }
  631. void CAttrObject::OnConfig()
  632. {
  633. CWnd *pRadio;
  634. pRadio = GetDlgItem(IDC_INHERIT);
  635. pRadio->EnableWindow(TRUE);
  636. pRadio = GetDlgItem(IDC_OVERWRITE);
  637. pRadio->EnableWindow(TRUE);
  638. SetModified(TRUE);
  639. }
  640. void CAttrObject::OnPrevent()
  641. {
  642. CWnd *pRadio;
  643. pRadio = GetDlgItem(IDC_INHERIT);
  644. pRadio->EnableWindow(FALSE);
  645. pRadio = GetDlgItem(IDC_OVERWRITE);
  646. pRadio->EnableWindow(FALSE);
  647. SetModified(TRUE);
  648. }
  649. void CAttrObject::OnOverwrite()
  650. {
  651. SetModified(TRUE);
  652. }
  653. void CAttrObject::OnInherit()
  654. {
  655. SetModified(TRUE);
  656. }
  657. //------------------------------------------------------------------
  658. // override to prevent the sheet from being destroyed when there is
  659. // child dialogs still up and running.
  660. //------------------------------------------------------------------
  661. BOOL CAttrObject::OnQueryCancel()
  662. {
  663. if (::IsWindow(m_hwndInspect) || ::IsWindow(m_hwndTemplate))
  664. {
  665. CString strMsg;
  666. strMsg.LoadString(IDS_CLOSESUBSHEET_BEFORE_APPLY);
  667. AfxMessageBox(strMsg);
  668. return FALSE;
  669. }
  670. else
  671. return TRUE;
  672. }