Leaked source code of windows server 2003
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.

775 lines
21 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation 1996-2001.
  5. //
  6. // File: addgrp.cpp
  7. //
  8. // Contents: implementation of CSCEAddGroup
  9. //
  10. //----------------------------------------------------------------------------
  11. #include "stdafx.h"
  12. #include "wsecmgr.h"
  13. #include "AddGrp.h"
  14. #include "snapmgr.h"
  15. #include "GetUser.h"
  16. #include "resource.h"
  17. #include "util.h"
  18. #ifdef _DEBUG
  19. #define new DEBUG_NEW
  20. #undef THIS_FILE
  21. static char THIS_FILE[] = __FILE__;
  22. #endif
  23. /////////////////////////////////////////////////////////////////////////////
  24. // CSCEAddGroup dialog
  25. CSCEAddGroup::CSCEAddGroup(CWnd* pParent /*=NULL*/)
  26. : CHelpDialog(a212HelpIDs, IDD, pParent)
  27. {
  28. m_dwFlags = SCE_SHOW_GROUPS | SCE_SHOW_ALIASES | SCE_SHOW_SINGLESEL;
  29. m_pnlGroup = NULL;
  30. m_pKnownNames = NULL;
  31. m_fCheckName = TRUE;
  32. //{{AFX_DATA_INIT(CSCEAddGroup)
  33. // NOTE: the ClassWizard will add member initialization here
  34. //}}AFX_DATA_INIT
  35. }
  36. CSCEAddGroup::~CSCEAddGroup()
  37. {
  38. SceFreeMemory( m_pnlGroup, SCE_STRUCT_NAME_LIST );
  39. m_pnlGroup = NULL;
  40. SceFreeMemory( m_pKnownNames, SCE_STRUCT_NAME_LIST );
  41. m_pKnownNames = NULL;
  42. }
  43. void CSCEAddGroup::DoDataExchange(CDataExchange* pDX)
  44. {
  45. CDialog::DoDataExchange(pDX);
  46. //{{AFX_DATA_MAP(CSCEAddGroup)
  47. // NOTE: the ClassWizard will add DDX and DDV calls here
  48. //}}AFX_DATA_MAP
  49. }
  50. DWORD CSCEAddGroup::GetModeFlags() {
  51. if (m_dwModeBits & MB_GROUP_POLICY) {
  52. return (SCE_SHOW_SCOPE_DOMAIN | SCE_SHOW_SCOPE_DIRECTORY);
  53. }
  54. if (m_dwModeBits & MB_LOCAL_POLICY) {
  55. return (SCE_SHOW_SCOPE_ALL | SCE_SHOW_DIFF_MODE_OFF_DC);
  56. }
  57. if (m_dwModeBits & MB_ANALYSIS_VIEWER) {
  58. return (SCE_SHOW_SCOPE_ALL | SCE_SHOW_DIFF_MODE_OFF_DC);
  59. }
  60. if (m_dwModeBits & MB_TEMPLATE_EDITOR) {
  61. return (SCE_SHOW_SCOPE_ALL);
  62. }
  63. return 0;
  64. }
  65. BEGIN_MESSAGE_MAP(CSCEAddGroup, CHelpDialog)
  66. //{{AFX_MSG_MAP(CSCEAddGroup)
  67. ON_BN_CLICKED(IDC_BROWSE, OnBrowse)
  68. ON_EN_CHANGE(IDC_LOG_FILE, OnChangeLogFile)
  69. ON_NOTIFY( EN_MSGFILTER, IDC_LOG_FILE, OnEditMsgFilter )
  70. //}}AFX_MSG_MAP
  71. END_MESSAGE_MAP()
  72. /////////////////////////////////////////////////////////////////////////////
  73. // CSCEAddGroup message handlers
  74. /*-------------------------------------------------------------------------------------
  75. CSCEAddGroup::IsKnownAccount
  76. Synopsis: This functions searches throught m_pKnownNames and does a case
  77. insensitive match on [pszAccount]. If [pszAccount] exists in the
  78. array then this function returns TRUE.
  79. Arguments: [pszAccount] - The account to look for.
  80. Returns: TRUE if [pszAccount] is in the list false otherwise
  81. -------------------------------------------------------------------------------------*/
  82. BOOL CSCEAddGroup::IsKnownAccount( LPCTSTR pszAccount )
  83. {
  84. if ( pszAccount == NULL ) return FALSE;
  85. PSCE_NAME_LIST pNew = m_pKnownNames;
  86. while(pNew){
  87. if( !lstrcmpi( pszAccount, pNew->Name ) ){
  88. return TRUE;
  89. }
  90. pNew = pNew->Next;
  91. }
  92. return FALSE;
  93. }
  94. /*------------------------------------------------------------------------------------
  95. CSCEAddGroup::CleanName
  96. Synopsis: Removes leading and trailing spaces from the string. This function
  97. places the string into the same buffer as is passed in.
  98. Arguments: [pszAccount] - The buffer to clean.
  99. ------------------------------------------------------------------------------------*/
  100. void CSCEAddGroup::CleanName( LPTSTR pszAccount )
  101. {
  102. if ( pszAccount == NULL ) return;
  103. int i = 0;
  104. while( IsSpace( pszAccount[i] ) ){
  105. i++;
  106. }
  107. int iLen = lstrlen(pszAccount) - 1;
  108. while(iLen > i && IsSpace( pszAccount[iLen] ) ){
  109. iLen--;
  110. }
  111. iLen -= i;
  112. while(iLen >= 0){
  113. *pszAccount = *(pszAccount + i);
  114. pszAccount++;
  115. iLen--;
  116. }
  117. *pszAccount = 0;
  118. }
  119. /*------------------------------------------------------------------------------------
  120. CSCEAddGroup::AddKnownAccount
  121. Synopsis: Adds a string to the Known accounts link list. This list is later
  122. used to underline strings that are contained in this list
  123. Arguments: [pszAccount] - The account to remeber.
  124. ------------------------------------------------------------------------------------*/
  125. BOOL CSCEAddGroup::AddKnownAccount( LPCTSTR pszAccount )
  126. {
  127. PSCE_NAME_LIST pNew = NULL;
  128. if ( pszAccount == NULL ) return FALSE;
  129. if(IsKnownAccount( pszAccount ) ){
  130. return TRUE;
  131. }
  132. pNew = (PSCE_NAME_LIST)LocalAlloc(0, sizeof(SCE_NAME_LIST));
  133. if(!pNew){
  134. return FALSE;
  135. }
  136. pNew->Name = (LPTSTR)LocalAlloc( 0, sizeof(TCHAR) * (1 + lstrlen(pszAccount)) );
  137. if(!pNew->Name){
  138. LocalFree(pNew);
  139. return FALSE;
  140. }
  141. //This may not be a safe usage. Using WCHAR instead of TCHAR for pNew->Name. Consider fix.
  142. lstrcpy(pNew->Name, pszAccount);
  143. pNew->Next = m_pKnownNames;
  144. m_pKnownNames = pNew;
  145. return TRUE;
  146. }
  147. /*------------------------------------------------------------------------------------
  148. CSCEAddGroup::OnBrowse
  149. Synopsis: Calls the CGetUser dialog box to create the object picker and display
  150. real choices. Since we wan't to underline all names returned by
  151. object picker, this function also places all names returned by
  152. CGetUser into the known accounts array.
  153. ------------------------------------------------------------------------------------*/
  154. void CSCEAddGroup::OnBrowse()
  155. {
  156. CGetUser gu;
  157. BOOL bFailed = TRUE;
  158. //
  159. // Get the rich edit control.
  160. //
  161. CRichEditCtrl *ed = (CRichEditCtrl *)GetDlgItem(IDC_LOG_FILE);
  162. if ( ed ) {
  163. //
  164. // Always multi select mode.
  165. //
  166. m_dwFlags &= ~SCE_SHOW_SINGLESEL;
  167. if (gu.Create( GetSafeHwnd(), m_dwFlags | GetModeFlags()) ) {
  168. //
  169. // Set the dialog text.
  170. // pAccount is a pointer to a member in getuser.cpp which will be freed there
  171. //
  172. PSCE_NAME_LIST pAccount = gu.GetUsers();
  173. //
  174. // Set the charformat, because we need to set it not to underline
  175. // things that we will paste into the edit control.
  176. //
  177. CHARFORMAT cf;
  178. ZeroMemory(&cf, sizeof( CHARFORMAT ));
  179. cf.cbSize = sizeof(CHARFORMAT);
  180. cf.dwMask = CFM_UNDERLINE;
  181. //
  182. // Enumerate through the account list and past them into the edit control.
  183. //
  184. int iLen;
  185. bFailed = FALSE;
  186. while (pAccount) {
  187. if(pAccount->Name){
  188. iLen = ed->GetTextLength();
  189. ed->SetSel( iLen, iLen);
  190. if(iLen){
  191. ed->SetSelectionCharFormat( cf );
  192. ed->ReplaceSel( L";" );
  193. iLen ++;
  194. }
  195. if ( AddKnownAccount( pAccount->Name ) ) {
  196. ed->ReplaceSel( pAccount->Name );
  197. } else {
  198. bFailed = TRUE;
  199. }
  200. }
  201. pAccount = pAccount->Next;
  202. }
  203. //
  204. // Everything we pasted will be underlined.
  205. //
  206. UnderlineNames();
  207. }
  208. }
  209. if ( bFailed ) {
  210. //
  211. // something is wrong creating the object picker or pasting the account into the control
  212. // popup a message
  213. //
  214. CString strErr;
  215. strErr.LoadString( IDS_ERR_INVALIDACCOUNT );
  216. AfxMessageBox( strErr );
  217. }
  218. }
  219. /*-------------------------------------------------------------------------------------
  220. CSCEAddGroup::OnInitDialog()
  221. Synopsis: Change the text for title and group static box. To "Add Group" and
  222. "Group"
  223. -------------------------------------------------------------------------------------*/
  224. BOOL CSCEAddGroup::OnInitDialog()
  225. {
  226. CDialog::OnInitDialog();
  227. CString str;
  228. //
  229. // Set the window title. If the caller has already set the title then
  230. // we don't need to load the resource.
  231. //
  232. if(m_sTitle.IsEmpty()){
  233. // Set window text of dialog.
  234. m_sTitle.LoadString(IDS_ADDGROUP_TITLE);
  235. }
  236. if(m_sDescription.IsEmpty()){
  237. m_sDescription.LoadString(IDS_ADDGROUP_GROUP);
  238. }
  239. SetWindowText( m_sTitle );
  240. // Set group static text.
  241. CWnd *pWnd = GetDlgItem(IDC_STATIC_FILENAME);
  242. if (pWnd) {
  243. pWnd->SetWindowText(m_sDescription);
  244. }
  245. pWnd = GetDlgItem(IDC_LOG_FILE);
  246. if ( pWnd )
  247. {
  248. pWnd->SendMessage(EM_SETEVENTMASK, 0, ENM_CHANGE | ENM_KEYEVENTS);
  249. pWnd->SendMessage(EM_LIMITTEXT, 4096, 0); //Raid #271219
  250. }
  251. // disable OK button.
  252. pWnd = GetDlgItem(IDOK);
  253. if ( pWnd )
  254. pWnd->EnableWindow( FALSE );
  255. return TRUE; // return TRUE unless you set the focus to a control
  256. // EXCEPTION: OCX Property Pages should return FALSE
  257. }
  258. /*-------------------------------------------------------------------------------------
  259. CSCEAddGroup::OnChangeLogFile()
  260. Synopsis: Check to see if any text is available in edit control, and disable the
  261. OK button if no text is available.
  262. -------------------------------------------------------------------------------------*/
  263. void CSCEAddGroup::OnChangeLogFile()
  264. {
  265. // Enable disable edit OK button depending on edit control content.
  266. CRichEditCtrl *pWnd = reinterpret_cast<CRichEditCtrl *>(GetDlgItem(IDC_LOG_FILE));
  267. CString str;
  268. str.Empty();
  269. if (pWnd) {
  270. pWnd->GetWindowText(str);
  271. }
  272. CWnd *pControl = GetDlgItem(IDOK);
  273. if ( pControl )
  274. {
  275. //Raid #446391, Yang Gao, 7/30/2001
  276. if( str.IsEmpty() )
  277. pControl->EnableWindow( FALSE );
  278. else
  279. {
  280. str.Remove(L' ');
  281. str.Remove(L';');
  282. pControl->EnableWindow( !str.IsEmpty() );
  283. }
  284. }
  285. }
  286. /*-------------------------------------------------------------------------------------
  287. CSCEAddGroup::UnderlineNames
  288. Synopsis: Underlines all names that are in the KnownAccounts list.
  289. -------------------------------------------------------------------------------------*/
  290. void CSCEAddGroup::UnderlineNames()
  291. {
  292. LONG nStart, nEnd;
  293. //
  294. // Get the edit control.
  295. //
  296. CRichEditCtrl *pWnd = reinterpret_cast<CRichEditCtrl *>(GetDlgItem(IDC_LOG_FILE));
  297. if(!pWnd){
  298. return;
  299. }
  300. LPTSTR pszText = NULL;
  301. int iPos, iLen, i;
  302. //
  303. // Retrieve the edit control text.
  304. //
  305. iLen = pWnd->GetWindowTextLength();
  306. pszText = (LPTSTR)LocalAlloc(LPTR, sizeof(TCHAR) * (2 + iLen) );
  307. if(!pszText){
  308. return;
  309. }
  310. pWnd->GetWindowText(pszText, iLen+1);
  311. iPos = 0;
  312. //
  313. // Get the current selection (the position of the caret)
  314. //
  315. pWnd->GetSel(nStart, nEnd );
  316. //
  317. // Hide the window so it doesn't flicker.
  318. //
  319. pWnd->SetWindowPos( NULL, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_NOZORDER | SWP_HIDEWINDOW | SWP_NOOWNERZORDER | SWP_NOREDRAW | SWP_NOSENDCHANGING);
  320. for(i = 0; i < iLen + 1; i++){
  321. //
  322. // Simi colon deliminated list.
  323. //
  324. if( pszText[i] == L';' ){
  325. pszText[i] = 0;
  326. }
  327. if(!pszText[i]){
  328. //
  329. // Format known names with underline.
  330. //
  331. CHARFORMAT cf;
  332. cf.cbSize = sizeof( CHARFORMAT );
  333. cf.dwMask = CFM_UNDERLINE;
  334. int isUn, ieUn;
  335. isUn = iPos;
  336. while( IsSpace(pszText[isUn]) ){
  337. isUn++;
  338. }
  339. ieUn = lstrlen( &(pszText[isUn]) ) - 1 + isUn;
  340. while( ieUn > 0 && IsSpace( pszText[ieUn] ) ){
  341. ieUn--;
  342. }
  343. //
  344. // See if we need to underline the name or not.
  345. //
  346. CleanName( &(pszText[isUn]) );
  347. if( IsKnownAccount( &(pszText[isUn]) ) ){
  348. cf.dwEffects = CFE_UNDERLINE;
  349. } else {
  350. cf.dwEffects &= ~CFE_UNDERLINE;
  351. }
  352. //
  353. // Make sure leading space characters aren't underlined.
  354. //
  355. if(isUn != iPos && cf.dwEffects & CFE_UNDERLINE){
  356. pWnd->SetSel( iPos, isUn);
  357. cf.dwEffects = 0;
  358. pWnd->SetSelectionCharFormat( cf );
  359. cf.dwEffects = CFE_UNDERLINE;
  360. } else {
  361. isUn = iPos;
  362. }
  363. //
  364. // trailing space characters are also not underlined.
  365. //
  366. if(cf.dwEffects & CFE_UNDERLINE){
  367. pWnd->SetSel(ieUn, i + 1);
  368. cf.dwEffects = 0;
  369. pWnd->SetSelectionCharFormat( cf );
  370. cf.dwEffects = CFE_UNDERLINE;
  371. } else {
  372. ieUn = i;
  373. }
  374. pWnd->SetSel( isUn, ieUn + 1);
  375. pWnd->SetSelectionCharFormat( cf );
  376. iPos = i + 1;
  377. }
  378. }
  379. //
  380. // Show the window without redrawing. We will call RedrawWindow to redraw.
  381. //
  382. pWnd->SetWindowPos( NULL, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_NOZORDER | SWP_SHOWWINDOW | SWP_NOOWNERZORDER | SWP_NOSENDCHANGING | SWP_NOREDRAW);
  383. pWnd->RedrawWindow(NULL, NULL, RDW_INVALIDATE);
  384. //
  385. // Reset selection.
  386. //
  387. pWnd->SetSel(nStart, nEnd);
  388. }
  389. /*------------------------------------------------------------------------------------
  390. CSCEAddGroup::OnEditMsgFilter
  391. Synopsis: Captures input message events from the RichEdit control. We want,
  392. to underline things as the user types them.
  393. Arguments: [pNM] - [in] Pointer to a MSGFILTER structure.
  394. [pResult]- [out] Pointer to a LRESULT type. Always set to 0
  395. ------------------------------------------------------------------------------------*/
  396. void CSCEAddGroup::OnEditMsgFilter( NMHDR *pNM, LRESULT *pResult)
  397. {
  398. *pResult = 0;
  399. #define pmf ((MSGFILTER *)pNM)
  400. switch( pmf->msg ){
  401. case WM_LBUTTONUP:
  402. case WM_KEYUP:
  403. //
  404. // If the caret is being moved around in the window then we don't want
  405. // to proccess the string since it isn't being changed.
  406. //
  407. if( pmf->msg == WM_KEYUP && pmf->wParam == VK_RIGHT ||
  408. pmf->wParam == VK_LEFT || pmf->wParam == VK_UP || pmf->wParam == VK_DOWN){
  409. break;
  410. }
  411. UnderlineNames();
  412. break;
  413. }
  414. #undef pmf
  415. }
  416. /*-------------------------------------------------------------------------------------
  417. CSCEAddGroup::CSCEAddGroup::OnOK()
  418. Synopsis: Copy the text the user input into the SCE_NAME_LIST structure.
  419. -------------------------------------------------------------------------------------*/
  420. void CSCEAddGroup::OnOK()
  421. {
  422. if( !CheckNames() ){
  423. return;
  424. }
  425. CreateNameList( &m_pnlGroup );
  426. CDialog::OnOK();
  427. }
  428. /*------------------------------------------------------------------------------------
  429. CSCEAddGroup::CreateNameList
  430. Synopsis: Creates the name list from the edit window. The function will ensure
  431. that each name is only in the list once.
  432. Arguments: [pNameList] -[out] Pointer a PSCE_NAME_LIST;
  433. Returns: The number of items added.
  434. ------------------------------------------------------------------------------------*/
  435. int CSCEAddGroup::CreateNameList( PSCE_NAME_LIST *pNameList )
  436. {
  437. if(!pNameList){
  438. return 0;
  439. }
  440. CWnd *pWnd = GetDlgItem(IDC_LOG_FILE);
  441. LPTSTR pszAccounts = NULL;
  442. //
  443. // Retrieve the window text.
  444. //
  445. int iLen = 0;
  446. if (pWnd) {
  447. iLen = pWnd->GetWindowTextLength();
  448. if(iLen){
  449. pszAccounts = (LPTSTR)LocalAlloc(LPTR, sizeof(TCHAR) * (iLen + 2));
  450. if(pszAccounts){
  451. pWnd->GetWindowText( pszAccounts, iLen+1);
  452. }
  453. }
  454. }
  455. //
  456. // Create an account name for each string daliminated by a semi colon.
  457. //
  458. int iCount = 0;
  459. if (pszAccounts) {
  460. LPTSTR pszCur = pszAccounts;
  461. int Len=0;
  462. for(int i = 0; i < iLen + 1; i++){
  463. if( pszAccounts[i] == L';' ){
  464. pszAccounts[i] = 0;
  465. }
  466. if( !pszAccounts[i] ){
  467. CleanName(pszCur);
  468. if((Len = lstrlen(pszCur))){
  469. //
  470. // Ensure that we don't already have this string in our link list.
  471. //
  472. PSCE_NAME_LIST pNew = NULL;
  473. pNew = *pNameList;
  474. while(pNew){
  475. if(!lstrcmpi( pNew->Name, pszCur ) ){
  476. pszCur[0] = 0;
  477. break;
  478. }
  479. pNew = pNew->Next;
  480. }
  481. if(pszCur[0]){
  482. //
  483. // Create a new link.
  484. //
  485. SceAddToNameList( pNameList, pszCur, Len);
  486. }
  487. }
  488. //
  489. // Next string to check.
  490. //
  491. pszCur = pszAccounts + i + 1;
  492. }
  493. }
  494. }
  495. return TRUE;
  496. }
  497. /*------------------------------------------------------------------------------------
  498. CSCEAddGroup::CheckNames
  499. Synopsis: Verifies the account the user has added. This function will display an
  500. error message box if any accounts are found to be in err. .
  501. Returns: TRUE if all names are valid, FALSE otherwise.
  502. ------------------------------------------------------------------------------------*/
  503. BOOL CSCEAddGroup::CheckNames()
  504. {
  505. PSCE_NAME_LIST pNameList = NULL;
  506. PSCE_NAME_LIST pErrList = NULL;
  507. BOOL bErr = TRUE;
  508. if( !CreateNameList( &pNameList ) ){
  509. return TRUE;
  510. }
  511. if( pNameList == NULL ) //Raid #446391, Yang Gao, 7/27/2001
  512. {
  513. (GetDlgItem(IDC_LOG_FILE))->SetWindowText(L"");
  514. (GetDlgItem(IDC_LOG_FILE))->SetFocus();
  515. return FALSE;
  516. }
  517. CString tempstr; //raid #387570, #387739
  518. int iCount = 0;
  519. int iFind = -1;
  520. PSCE_NAME_LIST pNext = pNameList;
  521. while(pNext)
  522. {
  523. tempstr = pNext->Name;
  524. //Raid #647716, yanggao, 6/28/2002
  525. if( !pNext->Name )
  526. {
  527. pNext = pNext->Next;
  528. continue;
  529. }
  530. int i = 0;
  531. while( *(pNext->Name+i) ) //count "\" in the name.
  532. {
  533. if( *(pNext->Name+i) == L'\\')
  534. {
  535. iCount++;
  536. }
  537. i++;
  538. }
  539. BOOL fFullName = FALSE;
  540. if( iCount == 1 ) //there is only one "\" in the name.
  541. {
  542. iFind = tempstr.FindOneOf(L"\\");
  543. if( iFind != 0 && iFind+1 != tempstr.GetLength() ) //it is a full name.
  544. {
  545. iFind = -1;
  546. fFullName = TRUE;
  547. }
  548. iCount = 0;
  549. }
  550. if( iCount == 0 ) //find invalid characters in the name.
  551. {
  552. iFind = tempstr.FindOneOf(IDS_INVALID_USERNAME_CHARS);
  553. }
  554. if( iFind >= 0 || iCount > 0 ) //found invalid characters in the name.
  555. {
  556. CString charsWithSpaces;
  557. PCWSTR szInvalidCharSet = IDS_INVALID_USERNAME_CHARS;
  558. UINT nIndex = 0;
  559. while (szInvalidCharSet[nIndex])
  560. {
  561. charsWithSpaces += szInvalidCharSet[nIndex];
  562. charsWithSpaces += L" ";
  563. nIndex++;
  564. }
  565. if( !fFullName )
  566. {
  567. charsWithSpaces = charsWithSpaces + L"\\";
  568. }
  569. //This is a safe usage.
  570. tempstr.FormatMessage (IDS_INVALID_STRING, charsWithSpaces);
  571. AfxMessageBox(tempstr);
  572. GetDlgItem(IDC_LOG_FILE)->SetFocus();
  573. return FALSE;
  574. }
  575. pNext = pNext->Next;
  576. }
  577. if( !m_fCheckName ) //Raid #404989
  578. {
  579. return TRUE;
  580. }
  581. //Raid #503853, 12/11/2001, yanggao, Only check full name user account.
  582. pNext = pNameList;
  583. while(pNext){
  584. LPTSTR pszStr = pNext->Name;
  585. if(!IsKnownAccount(pNext->Name)){
  586. while( pszStr && *pszStr ){
  587. if( *pszStr == L'\\' ){
  588. SID_NAME_USE su = CGetUser::GetAccountType( pNext->Name );
  589. if( su == SidTypeInvalid || su == SidTypeUnknown ||
  590. !AddKnownAccount(pNext->Name) ){
  591. PSCE_NAME_LIST pNew = (PSCE_NAME_LIST)LocalAlloc( 0, sizeof(SCE_NAME_LIST));
  592. if(pNew){
  593. pNew->Name = pNext->Name;
  594. pNew->Next = pErrList;
  595. pErrList = pNew;
  596. }
  597. } else {
  598. UnderlineNames();
  599. }
  600. break;
  601. }
  602. pszStr++;
  603. }
  604. }
  605. pNext = pNext->Next;
  606. }
  607. if( pErrList ){
  608. CString strErr;
  609. strErr.LoadString( IDS_ERR_INVALIDACCOUNT );
  610. pNext = pErrList;
  611. while(pNext){
  612. pErrList = pNext->Next;
  613. strErr += pNext->Name;
  614. if(pErrList){
  615. strErr += L',';
  616. }
  617. LocalFree(pNext);
  618. pNext = pErrList;
  619. }
  620. AfxMessageBox( strErr );
  621. bErr = FALSE;
  622. }
  623. SceFreeMemory( pNameList, SCE_STRUCT_NAME_LIST );
  624. return bErr;
  625. }
  626. void CSCEAddGroup::OnChecknames()
  627. {
  628. PSCE_NAME_LIST pNameList = NULL;
  629. if( CreateNameList( &pNameList ) ){
  630. PSCE_NAME_LIST pNext = pNameList;
  631. while(pNext){
  632. SID_NAME_USE su = CGetUser::GetAccountType( pNext->Name );
  633. if( su != SidTypeInvalid && su != SidTypeUnknown ){
  634. //
  635. // Add the name.
  636. //
  637. AddKnownAccount( pNext->Name );
  638. }
  639. pNext = pNext->Next;
  640. }
  641. SceFreeMemory( pNameList, SCE_STRUCT_NAME_LIST );
  642. UnderlineNames();
  643. }
  644. }