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.

884 lines
24 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation 1996-2001.
  5. //
  6. // File: AMember.cpp
  7. //
  8. // Contents: implementation of CAttrMember
  9. //
  10. //----------------------------------------------------------------------------
  11. #include "stdafx.h"
  12. #include "wsecmgr.h"
  13. #include "snapmgr.h"
  14. #include "resource.h"
  15. #include "chklist.h"
  16. #include "util.h"
  17. #include "getuser.h"
  18. #include "snapmgr.h"
  19. #include "resource.h"
  20. #include "AMember.h"
  21. #include "wrapper.h"
  22. #ifdef _DEBUG
  23. #define new DEBUG_NEW
  24. #undef THIS_FILE
  25. static char THIS_FILE[] = __FILE__;
  26. #endif
  27. /////////////////////////////////////////////////////////////////////////////
  28. // CAttrMember property page
  29. IMPLEMENT_DYNCREATE(CAttrMember, CSelfDeletingPropertyPage)
  30. CAttrMember::CAttrMember() : CSelfDeletingPropertyPage(CAttrMember::IDD)
  31. {
  32. //{{AFX_DATA_INIT(CAttrMember)
  33. m_fDefineInDatabase = FALSE;
  34. m_strHeader = _T("");
  35. //}}AFX_DATA_INIT
  36. m_psp.pszTemplate = MAKEINTRESOURCE(IDD_ATTR_GROUP);
  37. m_psp.dwFlags |= PSP_PREMATURE;
  38. m_pMergeList = NULL;
  39. m_fProcessing = FALSE;
  40. m_fInitialized = FALSE;
  41. m_bNoMembers = FALSE;
  42. m_bDirty=false;
  43. m_fOriginalDefineInDatabase=FALSE;
  44. m_bAlias=FALSE;
  45. m_dwType=0;
  46. CAttribute::m_nDialogs++;
  47. }
  48. CAttrMember::~CAttrMember()
  49. {
  50. if ( m_pMergeList ) {
  51. SceFreeMemory(m_pMergeList, SCE_STRUCT_NAME_STATUS_LIST);
  52. m_pMergeList = NULL;
  53. }
  54. m_pData->Release();
  55. CAttribute::m_nDialogs--;
  56. }
  57. void CAttrMember::DoDataExchange(CDataExchange* pDX)
  58. {
  59. CSelfDeletingPropertyPage::DoDataExchange(pDX);
  60. //{{AFX_DATA_MAP(CAttrMember)
  61. DDX_Check(pDX, IDC_DEFINE_GROUP, m_fDefineInDatabase);
  62. DDX_Text(pDX, IDC_HEADER, m_strHeader);
  63. DDX_Control(pDX, IDC_NO_MEMBERS,m_eNoMembers);
  64. //}}AFX_DATA_MAP
  65. }
  66. BEGIN_MESSAGE_MAP(CAttrMember, CSelfDeletingPropertyPage)
  67. //{{AFX_MSG_MAP(CAttrMember)
  68. ON_BN_CLICKED(IDC_DEFINE_GROUP, OnDefineInDatabase)
  69. ON_BN_CLICKED(IDC_ADD, OnAdd)
  70. //}}AFX_MSG_MAP
  71. ON_NOTIFY(CLN_CLICK, IDC_MEMBERS, OnClickMembers)
  72. ON_MESSAGE(WM_HELP, OnHelp)
  73. END_MESSAGE_MAP()
  74. /////////////////////////////////////////////////////////////////////////////
  75. // CAttrMember message handlers
  76. void CAttrMember::OnDefineInDatabase()
  77. {
  78. if (m_fProcessing)
  79. return;
  80. m_fProcessing = TRUE;
  81. //
  82. // for some strange reason the DDX isn't getting this BOOL set, so just do it
  83. // here which is basically the same thing
  84. //
  85. m_fDefineInDatabase = ( ((CButton *)GetDlgItem(IDC_DEFINE_GROUP))->GetCheck() == 1 );
  86. if (m_fDefineInDatabase) {
  87. (GetDlgItem(IDC_ADD))->EnableWindow(TRUE);
  88. //
  89. // use non CWnd calls for the checklist control
  90. //
  91. ::SendMessage(::GetDlgItem(this->m_hWnd, IDC_MEMBERS), WM_ENABLE, (WPARAM) TRUE, (LPARAM) 0);
  92. } else {
  93. (GetDlgItem(IDC_ADD))->EnableWindow(FALSE);
  94. //
  95. // use non CWnd calls for the checklist control
  96. //
  97. ::SendMessage(::GetDlgItem(this->m_hWnd, IDC_MEMBERS), WM_ENABLE, (WPARAM) FALSE, (LPARAM) 0);
  98. }
  99. SetModified(TRUE);
  100. //
  101. // Tell our siblings the m_fDefineInDatabase has changed
  102. //
  103. if (m_pAttrMember) {
  104. m_pAttrMember->SetDefineInDatabase(m_fDefineInDatabase);
  105. }
  106. m_fProcessing = FALSE;
  107. }
  108. void CAttrMember::OnAdd()
  109. {
  110. CGetUser gu;
  111. HRESULT hr=S_OK;
  112. DWORD nFlag;
  113. if ( GROUP_MEMBERS == m_dwType )
  114. nFlag = SCE_SHOW_USERS | SCE_SHOW_DOMAINGROUPS;
  115. else {
  116. nFlag = SCE_SHOW_GROUPS | SCE_SHOW_ALIASES; // NT5 DS, nested groups
  117. }
  118. nFlag |= SCE_SHOW_SCOPE_ALL | SCE_SHOW_DIFF_MODE_OFF_DC;
  119. if (gu.Create(GetSafeHwnd(),nFlag)) {
  120. PSCE_NAME_STATUS_LIST pList, pLast=NULL;
  121. LRESULT iItem;
  122. bool bFound;
  123. PSCE_NAME_LIST pName = gu.GetUsers();
  124. CWnd *pCheckList;
  125. pCheckList = GetDlgItem(IDC_MEMBERS);
  126. if (pName && m_bNoMembers) {
  127. m_bNoMembers = FALSE;
  128. m_eNoMembers.ShowWindow(SW_HIDE);
  129. pCheckList->ShowWindow(SW_SHOW);
  130. }
  131. while(pName) {
  132. if ( pName->Name ) {
  133. // Is the new name in m_pMerged yet?
  134. pList = m_pMergeList;
  135. pLast = NULL;
  136. iItem = 0;
  137. bFound = false;
  138. while(pList) {
  139. // If so, then make sure its "Template" box is checked
  140. if (lstrcmp(pList->Name,pName->Name) == 0) {
  141. if (!(pCheckList->SendMessage(CLM_GETSTATE,MAKELONG(iItem,1)) & CLST_CHECKED)) {
  142. m_bDirty = true;
  143. pCheckList->SendMessage(CLM_SETSTATE,MAKELONG(iItem,1),CLST_CHECKED);
  144. }
  145. bFound = true;
  146. break;
  147. }
  148. pLast = pList;
  149. pList = pList->Next;
  150. iItem++;
  151. }
  152. // Otherwise add it both to m_pMerged and to the CheckList
  153. if (!bFound) {
  154. PSCE_NAME_STATUS_LIST pNewNode;
  155. pNewNode = (PSCE_NAME_STATUS_LIST)LocalAlloc(0,sizeof(SCE_NAME_STATUS_LIST));
  156. if ( pNewNode ) {
  157. pNewNode->Name = (LPTSTR)LocalAlloc(0, (lstrlen(pName->Name)+1)*sizeof(TCHAR));
  158. if ( pNewNode->Name ) {
  159. lstrcpy(pNewNode->Name, pName->Name);
  160. pNewNode->Next = NULL;
  161. pNewNode->Status = MERGED_TEMPLATE;
  162. } else {
  163. LocalFree(pNewNode);
  164. pNewNode = NULL;
  165. }
  166. }
  167. if ( pNewNode ) {
  168. if ( pLast )
  169. pLast->Next = pNewNode;
  170. else
  171. m_pMergeList = pNewNode;
  172. pLast = pNewNode;
  173. iItem = pCheckList->SendMessage(CLM_ADDITEM,(WPARAM)pLast->Name,(LPARAM)pLast->Name);
  174. pCheckList->SendMessage(CLM_SETSTATE,MAKELONG(iItem,1),CLST_CHECKED);
  175. pCheckList->SendMessage(CLM_SETSTATE,MAKELONG(iItem,2),CLST_DISABLED);
  176. m_bDirty = true;
  177. } else {
  178. hr = E_OUTOFMEMORY;
  179. ASSERT(FALSE);
  180. break;
  181. }
  182. }
  183. SetModified(TRUE);
  184. }
  185. pName = pName->Next;
  186. }
  187. }
  188. if (m_bDirty) {
  189. SetModified(TRUE);
  190. }
  191. if ( FAILED(hr) ) {
  192. CString str;
  193. str.LoadString(IDS_CANT_ADD_MEMBER);
  194. AfxMessageBox(str);
  195. }
  196. }
  197. /*---------------------------------------------------------------------
  198. Method: OnInitDialog
  199. Synopsis: Initialize the check list with members/memberof data
  200. Arguments: None
  201. Returns: TRUE = initialized successfully
  202. ----------------------------------------------------------------------*/
  203. BOOL CAttrMember::OnInitDialog()
  204. {
  205. CSelfDeletingPropertyPage::OnInitDialog();
  206. PSCE_NAME_STATUS_LIST pItem;
  207. HWND hCheckList;
  208. LRESULT nItem;
  209. PSCE_GROUP_MEMBERSHIP pgmTemplate;
  210. PSCE_GROUP_MEMBERSHIP pgmInspect;
  211. PSCE_NAME_LIST pnlTemplate=NULL;
  212. PSCE_NAME_LIST pnlInspect=NULL;
  213. PEDITTEMPLATE pet = NULL;
  214. CString str;
  215. UpdateData(TRUE);
  216. if (GROUP_MEMBER_OF == m_dwType) {
  217. str.LoadString(IDS_NO_MEMBER_OF);
  218. } else {
  219. str.LoadString(IDS_NO_MEMBERS);
  220. }
  221. m_eNoMembers.SetWindowText(str);
  222. pgmInspect = (PSCE_GROUP_MEMBERSHIP) m_pData->GetID(); // last inspection saved in ID field
  223. if ( NULL == pgmInspect ) { // last inspection can't be NULL
  224. return TRUE;
  225. }
  226. m_fOriginalDefineInDatabase = m_fDefineInDatabase = FALSE;
  227. //
  228. // Try to find the base group in the template
  229. //
  230. pet = m_pSnapin->GetTemplate(GT_COMPUTER_TEMPLATE);
  231. if ( NULL == pet ) {
  232. return TRUE;
  233. }
  234. for (pgmTemplate=pet->pTemplate->pGroupMembership;
  235. pgmTemplate!=NULL;
  236. pgmTemplate=pgmTemplate->Next) {
  237. if ( _wcsicmp(pgmTemplate->GroupName, pgmInspect->GroupName) == 0 ) {
  238. //
  239. // If the group is in the template that means it is defined.... duh
  240. //
  241. m_fOriginalDefineInDatabase = m_fDefineInDatabase = TRUE;
  242. break;
  243. }
  244. }
  245. //
  246. // find the name lists to display
  247. //
  248. if ( pgmTemplate ) {
  249. if (GROUP_MEMBER_OF == m_dwType) {
  250. pnlTemplate = pgmTemplate->pMemberOf;
  251. } else {
  252. pnlTemplate = pgmTemplate->pMembers;
  253. }
  254. }
  255. if ((LONG_PTR)ULongToPtr(SCE_NO_VALUE) != (LONG_PTR) pgmInspect &&
  256. pgmInspect ) {
  257. if (GROUP_MEMBER_OF == m_dwType) {
  258. pnlInspect = pgmInspect->pMemberOf;
  259. } else {
  260. pnlInspect = pgmInspect->pMembers;
  261. }
  262. }
  263. m_pMergeList = MergeNameStatusList(pnlTemplate, pnlInspect);
  264. pItem = m_pMergeList;
  265. hCheckList = ::GetDlgItem(m_hWnd,IDC_MEMBERS);
  266. ::SendMessage(hCheckList, CLM_RESETCONTENT, 0, 0 );
  267. ::SendMessage(hCheckList,CLM_SETCOLUMNWIDTH,0,60);
  268. if (!pItem) {
  269. m_bNoMembers = TRUE;
  270. m_eNoMembers.ShowWindow(SW_SHOW);
  271. ::ShowWindow(hCheckList,SW_HIDE);
  272. }
  273. while(pItem) {
  274. //
  275. // Store the name of the item in the item data so we can retrieve it later
  276. //
  277. nItem = ::SendMessage(hCheckList,CLM_ADDITEM,(WPARAM) pItem->Name,(LPARAM) pItem->Name);
  278. ::SendMessage(hCheckList,CLM_SETSTATE,MAKELONG(nItem,1),
  279. ((pItem->Status & MERGED_TEMPLATE) ? CLST_CHECKED : CLST_UNCHECKED));
  280. ::SendMessage(hCheckList,CLM_SETSTATE,MAKELONG(nItem,2),
  281. ((pItem->Status & MERGED_INSPECT) ? CLST_CHECKDISABLED : CLST_DISABLED));
  282. pItem = pItem->Next;
  283. }
  284. if ( GROUP_MEMBER_OF == m_dwType ) {
  285. m_bAlias = TRUE;
  286. } else {
  287. m_bAlias = FALSE;
  288. }
  289. CWnd *cwnd = GetDlgItem(IDC_ADD);
  290. if ( cwnd ) {
  291. cwnd->EnableWindow(!m_bAlias);
  292. }
  293. CButton *pButton = (CButton *) GetDlgItem(IDC_DEFINE_GROUP);
  294. if (pButton) {
  295. pButton->SetCheck(m_fDefineInDatabase);
  296. }
  297. OnDefineInDatabase();
  298. SetModified(FALSE);
  299. m_fInitialized = TRUE;
  300. return TRUE; // return TRUE unless you set the focus to a control
  301. // EXCEPTION: OCX Property Pages should return FALSE
  302. }
  303. /*---------------------------------------------------------------------
  304. Method: SetDefineInDatabase
  305. Synopsis: Sets the m_fDefineInDatabase member var, and UI accorsingly
  306. Arguments: fDefineInDatabase
  307. Returns: None
  308. ----------------------------------------------------------------------*/
  309. void CAttrMember::SetDefineInDatabase(BOOL fDefineInDatabase)
  310. {
  311. if (!m_fInitialized)
  312. return;
  313. if (m_fProcessing)
  314. return;
  315. m_fDefineInDatabase = fDefineInDatabase;
  316. CButton *pButton = (CButton *) GetDlgItem(IDC_DEFINE_GROUP);
  317. if (pButton) {
  318. pButton->SetCheck(fDefineInDatabase);
  319. }
  320. OnDefineInDatabase();
  321. }
  322. /*---------------------------------------------------------------------
  323. Method: SetSibling
  324. Synopsis: Sets the pointer to the Sibling class
  325. Arguments: pAttrMember
  326. Returns: None
  327. ----------------------------------------------------------------------*/
  328. void CAttrMember::SetSibling(CAttrMember *pAttrMember)
  329. {
  330. m_pAttrMember = pAttrMember;
  331. }
  332. /*---------------------------------------------------------------------
  333. Method: Initialize
  334. Synopsis: Initialize member data
  335. Arguments: pData - the CResult data record
  336. Returns: None
  337. ----------------------------------------------------------------------*/
  338. void CAttrMember::Initialize(CResult * pData)
  339. {
  340. m_pData = pData;
  341. pData->AddRef();
  342. m_bDirty=false;
  343. }
  344. /*---------------------------------------------------------------------
  345. Method: GetGroupInTemplate
  346. Synopsis: Returns a pointer to the SCE_GROUP_MEMBERSHIP structure
  347. that is being changed within the template
  348. Arguments: None
  349. Returns: Pointer the group being modified.
  350. ----------------------------------------------------------------------*/
  351. PSCE_GROUP_MEMBERSHIP CAttrMember::GetGroupInTemplate()
  352. {
  353. PSCE_GROUP_MEMBERSHIP pgmTemplate;
  354. PSCE_GROUP_MEMBERSHIP pgmInspect;
  355. PEDITTEMPLATE pet;
  356. pgmInspect = (PSCE_GROUP_MEMBERSHIP) m_pData->GetID(); // last inspection saved in ID field
  357. if ( NULL == pgmInspect ) { // last inspection can't be NULL
  358. return NULL;
  359. }
  360. pet = m_pSnapin->GetTemplate(GT_COMPUTER_TEMPLATE);
  361. if ( NULL == pet ) {
  362. return NULL;
  363. }
  364. for (pgmTemplate=pet->pTemplate->pGroupMembership;
  365. pgmTemplate!=NULL;
  366. pgmTemplate=pgmTemplate->Next) {
  367. if ( _wcsicmp(pgmTemplate->GroupName, pgmInspect->GroupName) == 0 ) {
  368. return pgmTemplate;
  369. }
  370. }
  371. return NULL;
  372. }
  373. /*---------------------------------------------------------------------
  374. Method: SetMemberType
  375. Synopsis: Initialize page data depending on the type
  376. Arguments: nType - the page type for members of memberof
  377. Returns: None
  378. ----------------------------------------------------------------------*/
  379. void CAttrMember::SetMemberType(DWORD nType)
  380. {
  381. m_dwType = nType;
  382. if (GROUP_MEMBERS == nType) {
  383. m_strHeader.LoadString(IDS_GROUP_MEMBERS_HEADER);
  384. m_strPageTitle.LoadString(IDS_GROUP_MEMBERS_PAGE_TITLE);
  385. } else {
  386. m_strHeader.LoadString(IDS_GROUP_MEMBER_OF_HEADER);
  387. m_strPageTitle.LoadString(IDS_GROUP_MEMBER_OF_PAGE_TITLE);
  388. }
  389. m_psp.dwFlags |= PSP_USETITLE;
  390. m_psp.pszTitle = (LPCTSTR) m_strPageTitle;
  391. }
  392. void CAttrMember::SetSnapin(CSnapin * pSnapin)
  393. {
  394. m_pSnapin = pSnapin;
  395. }
  396. void CAttrMember::OnCancel()
  397. {
  398. if ( m_pMergeList ) {
  399. SceFreeMemory(m_pMergeList,SCE_STRUCT_NAME_STATUS_LIST);
  400. }
  401. m_pMergeList = NULL;
  402. }
  403. void CAttrMember::OnClickMembers(NMHDR *pNM, LRESULT *pResult)
  404. {
  405. SetModified(TRUE);
  406. //
  407. // If no items are checked then show the no members edit box instead
  408. //
  409. CWnd *pCheckList;
  410. int iItem;
  411. int nItem;
  412. PNM_CHECKLIST pNMCheckList;
  413. pNMCheckList = (PNM_CHECKLIST) pNM;
  414. if (pNMCheckList->dwState & CLST_CHECKED) {
  415. //
  416. // They checked something, so obviously something is checked
  417. //
  418. return;
  419. }
  420. pCheckList = GetDlgItem(IDC_MEMBERS);
  421. nItem = (int) pCheckList->SendMessage(CLM_GETITEMCOUNT);
  422. for(iItem=0;iItem<nItem;iItem++) {
  423. if ((pCheckList->SendMessage(CLM_GETSTATE,MAKELONG(iItem,1)) & CLST_CHECKED) ||
  424. (pCheckList->SendMessage(CLM_GETSTATE,MAKELONG(iItem,2)) & CLST_CHECKED)) {
  425. //
  426. // Something's checked, so abort
  427. //
  428. return;
  429. }
  430. }
  431. //
  432. // Nothing checked. Swap to the no members edit box
  433. //
  434. m_bNoMembers = TRUE;
  435. m_eNoMembers.ShowWindow(SW_SHOW);
  436. pCheckList->ShowWindow(SW_HIDE);
  437. }
  438. BOOL CAttrMember::OnApply()
  439. {
  440. int iItem;
  441. PEDITTEMPLATE pet=NULL;
  442. PSCE_PROFILE_INFO pspi=NULL;
  443. PSCE_NAME_STATUS_LIST pIndex;
  444. CWnd *pCheckList;
  445. PSCE_NAME_LIST pTemplate=NULL;
  446. PSCE_NAME_LIST pInspect=NULL;
  447. PSCE_NAME_LIST pDeleteNameList = NULL;
  448. PSCE_GROUP_MEMBERSHIP pSetting = NULL;
  449. PSCE_GROUP_MEMBERSHIP pBaseGroup = NULL;
  450. PSCE_GROUP_MEMBERSHIP pFindGroup = NULL;
  451. PSCE_GROUP_MEMBERSHIP pModifiedGroup = NULL;
  452. LPCTSTR szGroupName = (LPCTSTR) (m_pData->GetAttr());
  453. pCheckList = GetDlgItem(IDC_MEMBERS);
  454. pIndex = m_pMergeList;
  455. iItem = 0;
  456. HRESULT hr=S_OK;
  457. //
  458. // if the fDefineInDatabase has changed it is definitely dirty
  459. //
  460. m_bDirty = ( m_bDirty || (m_fOriginalDefineInDatabase != m_fDefineInDatabase) );
  461. //
  462. // only create the name list if the group is going to be defined in the database
  463. //
  464. if (m_fDefineInDatabase) {
  465. while(pIndex) {
  466. if (pCheckList->SendMessage(CLM_GETSTATE,MAKELONG(iItem,1)) & CLST_CHECKED) {
  467. if ( !(pIndex->Status & MERGED_TEMPLATE) ) {
  468. m_bDirty = true;
  469. }
  470. if ( SCESTATUS_SUCCESS != SceAddToNameList(&pTemplate, pIndex->Name, lstrlen(pIndex->Name))) {
  471. hr = E_FAIL;
  472. break;
  473. }
  474. } else if ( pIndex->Status & MERGED_TEMPLATE ) {
  475. m_bDirty = true;
  476. }
  477. pIndex = pIndex->Next;
  478. iItem++;
  479. }
  480. }
  481. if ( SUCCEEDED(hr) && m_bDirty) {
  482. pBaseGroup = GetGroupInTemplate();
  483. //
  484. // Need to add the group to the template
  485. //
  486. if ( (!pBaseGroup || (LONG_PTR)pBaseGroup == (LONG_PTR)ULongToPtr(SCE_NO_VALUE)) &&
  487. m_fDefineInDatabase) {
  488. pBaseGroup = (PSCE_GROUP_MEMBERSHIP) LocalAlloc(LMEM_ZEROINIT,sizeof(SCE_GROUP_MEMBERSHIP));
  489. if ( pBaseGroup && szGroupName ) {
  490. pBaseGroup->GroupName = (PWSTR)LocalAlloc(0, (lstrlen(szGroupName)+1)*sizeof(TCHAR));
  491. if ( pBaseGroup->GroupName ) {
  492. lstrcpy(pBaseGroup->GroupName,szGroupName);
  493. //
  494. // link the new structure to the pGroupMembership list
  495. //
  496. pet = m_pSnapin->GetTemplate(GT_COMPUTER_TEMPLATE,AREA_GROUP_MEMBERSHIP);
  497. if (pet) {
  498. pspi = pet->pTemplate;
  499. } else {
  500. pspi = NULL;
  501. }
  502. if ( pspi ) {
  503. pBaseGroup->Next = pspi->pGroupMembership;
  504. pspi->pGroupMembership = pBaseGroup;
  505. pBaseGroup->pMembers = NULL;
  506. pBaseGroup->pMemberOf = NULL;
  507. } else {
  508. //
  509. // error
  510. ASSERT(FALSE);
  511. LocalFree(pBaseGroup->GroupName);
  512. hr = E_FAIL;
  513. }
  514. } else {
  515. //
  516. // no memory
  517. //
  518. hr = E_OUTOFMEMORY;
  519. }
  520. } else {
  521. hr = E_OUTOFMEMORY;
  522. }
  523. if ( FAILED(hr) && pBaseGroup ) {
  524. LocalFree(pBaseGroup);
  525. pBaseGroup = NULL;
  526. }
  527. pModifiedGroup = pBaseGroup;
  528. //
  529. // Need to remove the group from the template
  530. //
  531. } else if (pBaseGroup && !m_fDefineInDatabase) {
  532. CString szGroupName;
  533. szGroupName = pBaseGroup->GroupName;
  534. pBaseGroup = NULL;
  535. DeleteGroup(szGroupName);
  536. //
  537. // An existing group was modified
  538. //
  539. } else {
  540. pModifiedGroup = pBaseGroup;
  541. }
  542. //
  543. // get group address to change the status field in the last inspection
  544. //
  545. pSetting = (PSCE_GROUP_MEMBERSHIP)(m_pData->GetID());
  546. int status;
  547. if (GROUP_MEMBERS == m_dwType) {
  548. if (pModifiedGroup != NULL) {
  549. pDeleteNameList = pModifiedGroup->pMembers;
  550. pModifiedGroup->pMembers = pTemplate;
  551. }
  552. if (NULL != pSetting ) {
  553. if ( !((pSetting->Status & SCE_GROUP_STATUS_NOT_ANALYZED) ||
  554. (pSetting->Status & SCE_GROUP_STATUS_ERROR_ANALYZED))) {
  555. //
  556. // set good, not configured, or mismatch
  557. //
  558. pSetting->Status &= ~SCE_GROUP_STATUS_NC_MEMBERS;
  559. pSetting->Status &= ~SCE_GROUP_STATUS_MEMBERS_MISMATCH;
  560. if (pModifiedGroup == NULL) {
  561. pSetting->Status |= SCE_GROUP_STATUS_NC_MEMBERS;
  562. } else if ( !SceCompareNameList(pTemplate, pSetting->pMembers) ) {
  563. pSetting->Status |= SCE_GROUP_STATUS_MEMBERS_MISMATCH;
  564. }
  565. }
  566. } else {
  567. //
  568. // else should NEVER occur
  569. //
  570. status = SCE_GROUP_STATUS_MEMBERS_MISMATCH;
  571. }
  572. } else {
  573. //
  574. // memberof
  575. //
  576. if (pModifiedGroup != NULL) {
  577. pDeleteNameList = pModifiedGroup->pMemberOf;
  578. pModifiedGroup->pMemberOf = pTemplate;
  579. }
  580. if ( pSetting ) {
  581. if ( !((pSetting->Status & SCE_GROUP_STATUS_NOT_ANALYZED) ||
  582. (pSetting->Status & SCE_GROUP_STATUS_ERROR_ANALYZED))) {
  583. //
  584. // set good, not configured, or mismatch
  585. //
  586. pSetting->Status &= ~SCE_GROUP_STATUS_NC_MEMBEROF;
  587. pSetting->Status &= ~SCE_GROUP_STATUS_MEMBEROF_MISMATCH;
  588. if (pModifiedGroup == NULL) {
  589. pSetting->Status |= SCE_GROUP_STATUS_NC_MEMBEROF;
  590. } else if ( !SceCompareNameList(pTemplate, pSetting->pMemberOf) ) {
  591. pSetting->Status |= SCE_GROUP_STATUS_MEMBEROF_MISMATCH;
  592. }
  593. }
  594. } else {
  595. // else should NEVER occur
  596. status = SCE_GROUP_STATUS_MEMBEROF_MISMATCH;
  597. }
  598. }
  599. pTemplate = NULL;
  600. SceFreeMemory(pDeleteNameList,SCE_STRUCT_NAME_LIST);
  601. if ( pSetting ) {
  602. status = pSetting->Status;
  603. }
  604. //
  605. // update current record
  606. //
  607. // status
  608. m_pData->SetStatus(GetGroupStatus(status, STATUS_GROUP_RECORD));
  609. // members status
  610. m_pData->SetBase(GetGroupStatus(status, STATUS_GROUP_MEMBERS));
  611. // memberof status
  612. m_pData->SetSetting(GetGroupStatus(status, STATUS_GROUP_MEMBEROF));
  613. m_pData->Update(m_pSnapin);
  614. //
  615. // update the dirty flag in the template
  616. //
  617. PEDITTEMPLATE pet;
  618. pet = m_pSnapin->GetTemplate(GT_COMPUTER_TEMPLATE,AREA_GROUP_MEMBERSHIP);
  619. if (pet) {
  620. pet->SetDirty(AREA_GROUP_MEMBERSHIP);
  621. }
  622. } // failed
  623. SceFreeMemory(pTemplate,SCE_STRUCT_NAME_LIST);
  624. if ( FAILED(hr) ) {
  625. CString str;
  626. str.LoadString(IDS_SAVE_FAILED);
  627. AfxMessageBox(str);
  628. } else {
  629. CancelToClose();
  630. SetModified(TRUE);
  631. return TRUE;
  632. }
  633. return FALSE;
  634. }
  635. BOOL CAttrMember::OnHelp(WPARAM wParam, LPARAM lParam)
  636. {
  637. const LPHELPINFO pHelpInfo = (LPHELPINFO)lParam;
  638. if (pHelpInfo && pHelpInfo->iContextType == HELPINFO_WINDOW)
  639. {
  640. this->DoContextHelp ((HWND) pHelpInfo->hItemHandle);
  641. }
  642. return TRUE;
  643. }
  644. void CAttrMember::DoContextHelp (HWND hWndControl)
  645. {
  646. // Display context help for a control
  647. if ( !::WinHelp (
  648. hWndControl,
  649. GetSeceditHelpFilename(),
  650. HELP_WM_HELP,
  651. (DWORD_PTR) a214HelpIDs) )
  652. {
  653. }
  654. }
  655. void CAttrMember::DeleteGroup(const CString &szGroupName)
  656. {
  657. CSingleLock cSL(&m_CS, FALSE);
  658. cSL.Lock();
  659. PEDITTEMPLATE pet = NULL;
  660. PSCE_PROFILE_INFO pspi = NULL;
  661. PSCE_GROUP_MEMBERSHIP pFindGroup = NULL;
  662. PSCE_GROUP_MEMBERSHIP pDeleteGroup = NULL;
  663. pet = m_pSnapin->GetTemplate(GT_COMPUTER_TEMPLATE,AREA_GROUP_MEMBERSHIP);
  664. if (pet) {
  665. pspi = pet->pTemplate;
  666. } else {
  667. pspi = NULL;
  668. }
  669. if ( pspi ) {
  670. //
  671. // find the group in the template and remove it
  672. //
  673. pFindGroup = pspi->pGroupMembership;
  674. if (pFindGroup == NULL)
  675. return;
  676. if (pFindGroup->GroupName == szGroupName) {
  677. pspi->pGroupMembership = pFindGroup->Next;
  678. pDeleteGroup = pFindGroup;
  679. } else {
  680. while (pFindGroup->Next && (pFindGroup->Next->GroupName != szGroupName)) {
  681. pFindGroup = pFindGroup->Next;
  682. }
  683. if (pFindGroup->Next) {
  684. pDeleteGroup = pFindGroup->Next;
  685. pFindGroup->Next = pDeleteGroup->Next;
  686. }
  687. }
  688. if (pDeleteGroup) {
  689. LocalFree(pDeleteGroup->GroupName);
  690. SceFreeMemory(pDeleteGroup->pMembers,SCE_STRUCT_NAME_LIST);
  691. SceFreeMemory(pDeleteGroup->pMemberOf,SCE_STRUCT_NAME_LIST);
  692. LocalFree(pDeleteGroup);
  693. }
  694. } else {
  695. //
  696. // error
  697. //
  698. ASSERT(FALSE);
  699. }
  700. }