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.

1771 lines
54 KiB

  1. //+--------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1994 - 2001.
  5. //
  6. // File: scopane.cpp
  7. //
  8. // Contents: Functions for handling the scope pane folder structure
  9. //
  10. // History: 12-12-1997 RobCap Split out from snapmgr.cpp
  11. //
  12. //---------------------------------------------------------------------------
  13. #include "stdafx.h"
  14. #include "cookie.h"
  15. #include "snapmgr.h"
  16. #include "resource.h"
  17. #include "wrapper.h"
  18. #include "util.h"
  19. #include <sceattch.h>
  20. #include <io.h>
  21. #ifdef INITGUID
  22. #undef INITGUID
  23. #include <gpedit.h>
  24. #define INITGUID
  25. #include "userenv.h"
  26. #endif
  27. //
  28. // Array of folders to list in the scope pane
  29. // The order of this array is important:
  30. // All folders which appear at the same level must be adjacent
  31. // to each other and the array and #defines need to be kept in
  32. // sync
  33. //
  34. //
  35. #define USE_KERBEROS 1
  36. //
  37. // Top level folders
  38. //
  39. #define ANALYSIS_FOLDER 0
  40. #define CONFIGURATION_FOLDER (ANALYSIS_FOLDER +1)
  41. //
  42. // Profile level folders
  43. //
  44. #define PROFILE_ACCOUNT_FOLDER (CONFIGURATION_FOLDER +1)
  45. #define PROFILE_LOCAL_FOLDER (PROFILE_ACCOUNT_FOLDER +1)
  46. #define PROFILE_EVENTLOG_FOLDER (PROFILE_LOCAL_FOLDER +1)
  47. #define PROFILE_GROUPS_FOLDER (PROFILE_EVENTLOG_FOLDER +1)
  48. #define PROFILE_SERVICE_FOLDER (PROFILE_GROUPS_FOLDER +1)
  49. #define PROFILE_REGISTRY_FOLDER (PROFILE_SERVICE_FOLDER +1)
  50. #define PROFILE_FILESTORE_FOLDER (PROFILE_REGISTRY_FOLDER +1)
  51. //
  52. // Profile/Account level folders
  53. //
  54. #define ACCOUNT_PASSWORD_FOLDER (PROFILE_FILESTORE_FOLDER +1)
  55. #define ACCOUNT_LOCKOUT_FOLDER (ACCOUNT_PASSWORD_FOLDER +1)
  56. #define ACCOUNT_KERBEROS_FOLDER (ACCOUNT_LOCKOUT_FOLDER +1)
  57. //
  58. // Profile/Local level folders
  59. //
  60. #define LOCAL_AUDIT_FOLDER (ACCOUNT_KERBEROS_FOLDER +1)
  61. #define LOCAL_PRIVILEGE_FOLDER (LOCAL_AUDIT_FOLDER +1)
  62. #define LOCAL_OTHER_FOLDER (LOCAL_PRIVILEGE_FOLDER +1)
  63. //
  64. // Profile/Eventlog level folders
  65. //
  66. #define EVENTLOG_LOG_FOLDER (LOCAL_OTHER_FOLDER +1)
  67. #define NUM_FOLDERS (LOCAL_OTHER_FOLDER +1)
  68. //#define NUM_FOLDERS (EVENTLOG_LOG_FOLDER +1)
  69. //
  70. // #defines to identify which folders belong in which sections
  71. //
  72. #define FIRST_STATIC_FOLDER ANALYSIS_FOLDER
  73. #define LAST_STATIC_FOLDER CONFIGURATION_FOLDER
  74. #define FIRST_PROFILE_FOLDER PROFILE_ACCOUNT_FOLDER
  75. #define LAST_PROFILE_FOLDER PROFILE_DSOBJECT_FOLDER
  76. #define LAST_PROFILE_NODS_FOLDER PROFILE_FILESTORE_FOLDER
  77. #define LAST_LOCALPOL_FOLDER PROFILE_LOCAL_FOLDER
  78. #define FIRST_ACCOUNT_FOLDER ACCOUNT_PASSWORD_FOLDER
  79. #define LAST_ACCOUNT_NODS_FOLDER ACCOUNT_LOCKOUT_FOLDER
  80. //
  81. // remove kerberos section from NT5 for now
  82. //
  83. #if defined(_NT4BACK_PORT) || !defined(USE_KERBEROS)
  84. #define LAST_ACCOUNT_FOLDER ACCOUNT_LOCKOUT_FOLDER
  85. #else
  86. #define LAST_ACCOUNT_FOLDER ACCOUNT_KERBEROS_FOLDER
  87. #endif
  88. #define FIRST_LOCAL_FOLDER LOCAL_AUDIT_FOLDER
  89. #define LAST_LOCAL_FOLDER LOCAL_OTHER_FOLDER
  90. #define FIRST_EVENTLOG_FOLDER EVENTLOG_LOG_FOLDER
  91. #define LAST_EVENTLOG_FOLDER EVENTLOG_LOG_FOLDER
  92. //
  93. // The actual folder data
  94. // This must be kept in sync with the above #defines
  95. // should be initialized based on the #defines rather than
  96. // independantly on them. Let the compiler keep things
  97. // accurate for us
  98. //
  99. FOLDER_DATA SecmgrFolders[NUM_FOLDERS] =
  100. {
  101. { IDS_ANALYZE, IDS_ANALYZE_DESC, ANALYSIS},
  102. { IDS_CONFIGURE, IDS_CONFIGURE_DESC, CONFIGURATION},
  103. { IDS_ACCOUNT_POLICY, IDS_ACCOUNT_DESC, POLICY_ACCOUNT},
  104. { IDS_LOCAL_POLICY, IDS_LOCAL_DESC, POLICY_LOCAL},
  105. { IDS_EVENT_LOG, IDS_EVENT_LOG, POLICY_LOG},
  106. { IDS_GROUPS, IDS_GROUPS_DESC, AREA_GROUPS},
  107. { IDS_SERVICE, IDS_SERVICE_DESC, AREA_SERVICE},
  108. { IDS_REGISTRY, IDS_REGISTRY_DESC, AREA_REGISTRY},
  109. { IDS_FILESTORE, IDS_FILESTORE_DESC, AREA_FILESTORE},
  110. { IDS_PASSWORD_CATEGORY, IDS_PASSWORD_CATEGORY, POLICY_PASSWORD},
  111. { IDS_LOCKOUT_CATEGORY, IDS_LOCKOUT_CATEGORY, POLICY_LOCKOUT},
  112. { IDS_KERBEROS_CATEGORY, IDS_KERBEROS_CATEGORY, POLICY_KERBEROS},
  113. { IDS_EVENT_AUDIT, IDS_EVENT_AUDIT, POLICY_AUDIT},
  114. { IDS_PRIVILEGE, IDS_PRIVILEGE_DESC, AREA_PRIVILEGE},
  115. { IDS_OTHER_CATEGORY, IDS_OTHER_CATEGORY, POLICY_OTHER},
  116. };
  117. #define ARRAYLEN(x) (sizeof(x) / sizeof((x)[0]))
  118. //+--------------------------------------------------------------------------
  119. //
  120. // Function: AddLocationsToFolderList
  121. //
  122. // Synopsis: Adds the locations from a given registry key to the
  123. // folder list. Returns the number of locations added.
  124. // Helper function for CreateFolderList
  125. //
  126. // Arguments: [hKey] - the key holding the locations
  127. // [dwMode] - the mode SCAT is running in
  128. // [bCheckForDupes] - TRUE to check for duplicates before adding
  129. // [pPos] - output only
  130. //
  131. // Returns: *[pPos] - the position in m_pScopeItemList of the first
  132. // folder created
  133. // the number of child folders created
  134. //
  135. // Modifies: CComponentDataImpl::m_pScopeItemList
  136. //
  137. // History: 7-26-l999 RobCap broken out from CreateFolderList
  138. //
  139. //---------------------------------------------------------------------------
  140. INT
  141. CComponentDataImpl::AddLocationsToFolderList(HKEY hKey,
  142. DWORD dwMode,
  143. BOOL bCheckForDupes,
  144. POSITION *pPos) {
  145. LPTSTR tmpstr=NULL;
  146. WCHAR pBuf[MAX_PATH];
  147. DWORD BufSize = MAX_PATH;
  148. WCHAR pExpanded[MAX_PATH];
  149. FILETIME LastWriteTime;
  150. PWSTR Desc=NULL;
  151. CFolder *folder =NULL;
  152. INT nCount = 0;
  153. DWORD status = 0;
  154. HRESULT hr = S_OK;
  155. //
  156. // enumerate all subkeys of the key
  157. //
  158. int iTotal = 0;
  159. do {
  160. memset(pBuf, '\0', MAX_PATH*sizeof(WCHAR));
  161. BufSize = MAX_PATH;
  162. status = RegEnumKeyEx(hKey,
  163. nCount,
  164. pBuf,
  165. &BufSize,
  166. NULL,
  167. NULL,
  168. NULL,
  169. &LastWriteTime);
  170. if ( NO_ERROR == status ) {
  171. //
  172. // get description of this location (subkey)
  173. //
  174. MyRegQueryValue( hKey,
  175. pBuf,
  176. L"Description", // Value name (not localized)
  177. (PVOID*)&Desc,
  178. &BufSize );
  179. //
  180. // replace '/' with '\' because Registry does not
  181. // take '\' in a single key
  182. //
  183. tmpstr = wcschr(pBuf, L'/');
  184. while (tmpstr) {
  185. *tmpstr = L'\\';
  186. tmpstr = wcschr(tmpstr, L'/');
  187. }
  188. if (!ExpandEnvironmentStrings(pBuf,pExpanded,MAX_PATH)) {
  189. wcsncpy(pExpanded,pBuf,BufSize);
  190. }
  191. if (bCheckForDupes) {
  192. //
  193. // Make sure we haven't already added this directory
  194. //
  195. POSITION pos;
  196. BOOL bDuplicate = FALSE;
  197. pos = m_scopeItemList.GetHeadPosition();
  198. for (int i=0;i < m_scopeItemList.GetCount(); i++) {
  199. folder = m_scopeItemList.GetAt(pos);
  200. if (folder && (0 == lstrcmp(folder->GetName(),pExpanded))) {
  201. bDuplicate = TRUE;
  202. break;
  203. }
  204. }
  205. if (bDuplicate) {
  206. if ( Desc )
  207. LocalFree(Desc);
  208. Desc = NULL;
  209. continue;
  210. }
  211. }
  212. folder = new CFolder();
  213. if (folder) {
  214. if( _wchdir( pExpanded ) ){
  215. folder->SetState( CFolder::state_InvalidTemplate );
  216. }
  217. //
  218. // Create the folder objects with static data
  219. //
  220. hr = folder->Create(pExpanded, // Name
  221. Desc, // Description
  222. NULL, // inf file name
  223. CONFIG_FOLDER_IDX, // closed icon index
  224. CONFIG_FOLDER_IDX, // open icon index
  225. LOCATIONS, // folder type
  226. TRUE, // has children
  227. dwMode, // SCE mode
  228. NULL); // Extra Data
  229. if (SUCCEEDED(hr)) {
  230. m_scopeItemList.AddTail(folder);
  231. if ( iTotal == 0 && NULL != pPos && !bCheckForDupes) {
  232. *pPos = m_scopeItemList.GetTailPosition();
  233. }
  234. } else { // if can't create, then quit doing it anymore, no more reason to continue
  235. delete folder;
  236. if ( Desc )
  237. LocalFree(Desc);
  238. Desc = NULL;
  239. break;
  240. }
  241. } else {
  242. hr = E_OUTOFMEMORY;
  243. if ( Desc )
  244. LocalFree(Desc);
  245. Desc = NULL;
  246. break;
  247. }
  248. if ( Desc ) {
  249. LocalFree(Desc);
  250. }
  251. Desc = NULL;
  252. nCount++;
  253. iTotal++;
  254. }
  255. } while ( status != ERROR_NO_MORE_ITEMS );
  256. return nCount;
  257. }
  258. //+--------------------------------------------------------------------------
  259. //
  260. // Function: CreateFolderList
  261. //
  262. // Synopsis: Adds the children folders of pFolder to m_pScopeItemList
  263. // and returns the location of the first such folder and the
  264. // number added
  265. //
  266. // Arguments: [pFolder] - the folder whose children we want to find
  267. // [type] - the type of that folder
  268. // [pPos] - output only
  269. // [Count] - output only
  270. //
  271. // Returns: *[pPos] - the position in m_pScopeItemList of the first
  272. // folder created
  273. // *[Count] - the number of child folders created
  274. //
  275. // Modifies: CComponentDataImpl::m_pScopeItemList
  276. //
  277. // History: 12-15-1997 RobCap made dynamic based on mode
  278. //
  279. //---------------------------------------------------------------------------
  280. HRESULT
  281. CComponentDataImpl::CreateFolderList(CFolder *pFolder, // Optional, In
  282. FOLDER_TYPES type, // In
  283. POSITION *pPos, // Optional, Out
  284. INT *Count) // Optional, Out,
  285. {
  286. CFolder* folder = 0;
  287. INT nStart = 0;
  288. INT nCount = 0;
  289. BOOL bHasChildren = FALSE;
  290. struct _wfinddata_t findData;
  291. intptr_t hFile = 0;
  292. WCHAR pBuf[MAX_PATH];
  293. HKEY hKey = 0;
  294. DWORD BufSize = 0;
  295. DWORD status = 0;
  296. PWSTR Desc=NULL;
  297. LPTSTR tmpstr=NULL;
  298. HRESULT hr = S_OK;
  299. DWORD dwErr = 0;
  300. SCESTATUS rc = 0;
  301. PSCE_OBJECT_CHILDREN ObjectList=NULL;
  302. PSCE_OBJECT_LIST pObject = 0;
  303. PSCE_ERROR_LOG_INFO ErrBuf=NULL;
  304. CString StrErr;
  305. PSCE_PROFILE_INFO pProfileInfo=NULL;
  306. FOLDER_TYPES newType;
  307. PEDITTEMPLATE pet = 0;
  308. //
  309. // initialize dwMode and ModeBits
  310. //
  311. DWORD dwMode=0;
  312. DWORD ModeBits=0;
  313. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  314. if (Count)
  315. *Count = 0;
  316. if (pFolder)
  317. {
  318. dwMode = pFolder->GetMode();
  319. ModeBits = pFolder->GetModeBits();
  320. }
  321. //
  322. // This could take some time, so create a wait curser
  323. //
  324. CWaitCursor wc;
  325. switch ( type )
  326. {
  327. case ROOT:
  328. //
  329. // Initial standalone mode root mode
  330. //
  331. folder = new CFolder();
  332. if (!folder)
  333. return E_OUTOFMEMORY;
  334. if ( GetImplType() == SCE_IMPL_TYPE_SAV )
  335. {
  336. dwMode = SCE_MODE_VIEWER;
  337. newType = ANALYSIS;
  338. }
  339. else if ( GetImplType() == SCE_IMPL_TYPE_SCE )
  340. {
  341. dwMode = SCE_MODE_EDITOR;
  342. newType = CONFIGURATION;
  343. }
  344. else if ( GetImplType() == SCE_IMPL_TYPE_LS)
  345. {
  346. dwMode = SCE_MODE_LOCALSEC;
  347. newType = LOCALPOL;
  348. }
  349. else
  350. {
  351. dwMode = 0;
  352. newType = CONFIGURATION;
  353. }
  354. //
  355. // Create the folder objects with static data
  356. // MMC pulls in the name from the data object
  357. //
  358. hr = folder->Create(L"", // Name
  359. L"", // Description
  360. NULL, // inf file name
  361. SCE_IMAGE_IDX, // closed icon index
  362. SCE_IMAGE_IDX, // open icon index
  363. newType, // folder type
  364. TRUE, // has children
  365. dwMode, // SCE Mode
  366. NULL); // Extra Data
  367. if (SUCCEEDED(hr))
  368. {
  369. folder->SetCookie(NULL);
  370. switch (m_Mode)
  371. {
  372. case SCE_MODE_DOMAIN_COMPUTER:
  373. case SCE_MODE_OU_COMPUTER:
  374. case SCE_MODE_LOCAL_COMPUTER:
  375. case SCE_MODE_REMOTE_COMPUTER:
  376. m_computerModeBits = folder->GetModeBits();
  377. break;
  378. case SCE_MODE_REMOTE_USER:
  379. case SCE_MODE_LOCAL_USER:
  380. case SCE_MODE_DOMAIN_USER:
  381. case SCE_MODE_OU_USER:
  382. m_userModeBits = folder->GetModeBits();
  383. break;
  384. default:
  385. m_computerModeBits = folder->GetModeBits();
  386. break;
  387. }
  388. m_scopeItemList.AddTail(folder);
  389. return S_OK;
  390. }
  391. else
  392. {
  393. delete folder;
  394. return hr;
  395. }
  396. case ANALYSIS:
  397. pFolder->SetInfFile(GT_COMPUTER_TEMPLATE);
  398. m_AnalFolder = pFolder;
  399. //
  400. // Very first time initialization of the sad name.
  401. // Ask the user to get a sad name if none exists.
  402. //
  403. if(!m_AnalFolder && SadName.IsEmpty() )
  404. OnOpenDataBase();
  405. //
  406. // enumerate security areas for analysis
  407. //
  408. if ( !SadHandle )
  409. LoadSadInfo(TRUE);
  410. //
  411. // The data under the Analysis node is not valid right now,
  412. // so don't display any folders
  413. //
  414. if (m_bIsLocked)
  415. return S_OK;
  416. //
  417. // We weren't able to load the Analysis data even though we're
  418. // not in the middle of an action that should be blocking it
  419. //
  420. if ( SadErrored != ERROR_SUCCESS || !SadHandle)
  421. return E_FAIL;
  422. nStart = FIRST_PROFILE_FOLDER;
  423. //
  424. // Display all but the DS Objects folder
  425. //
  426. nCount = LAST_PROFILE_NODS_FOLDER - FIRST_PROFILE_FOLDER +1;
  427. bHasChildren = FALSE;
  428. break;
  429. case AREA_REGISTRY_ANALYSIS:
  430. case AREA_FILESTORE_ANALYSIS:
  431. if ( SadHandle == NULL )
  432. {
  433. //
  434. // We shouldn't be able to get this far without a SadHandle
  435. //
  436. ASSERT(FALSE);
  437. return E_FAIL;
  438. }
  439. if (m_bIsLocked)
  440. {
  441. //
  442. // We shouldn't be able to get this far if we're locked
  443. //
  444. ASSERT(FALSE);
  445. return E_FAIL;
  446. }
  447. switch ( type )
  448. {
  449. case AREA_REGISTRY_ANALYSIS:
  450. status = AREA_REGISTRY_SECURITY; // use status temporatorily
  451. newType = REG_OBJECTS;
  452. break;
  453. case AREA_FILESTORE_ANALYSIS:
  454. status = AREA_FILE_SECURITY;
  455. newType = FILE_OBJECTS;
  456. break;
  457. default:
  458. break;
  459. }
  460. //
  461. // get the object roots
  462. //
  463. pet = GetTemplate(GT_LAST_INSPECTION,status,&dwErr);
  464. if (!pet)
  465. {
  466. CString strErr;
  467. strErr.LoadString(dwErr);
  468. AfxMessageBox(strErr);
  469. return E_FAIL;
  470. }
  471. pProfileInfo = pet->pTemplate;
  472. if ( pProfileInfo )
  473. {
  474. //
  475. // add the object roots
  476. //
  477. if ( type == AREA_REGISTRY_ANALYSIS)
  478. pObject = pProfileInfo->pRegistryKeys.pOneLevel;
  479. else if ( type == AREA_FILESTORE_ANALYSIS )
  480. pObject = pProfileInfo->pFiles.pOneLevel;
  481. else
  482. pObject = pProfileInfo->pDsObjects.pOneLevel;
  483. for (; pObject!=NULL; pObject=pObject->Next)
  484. {
  485. CString strRoot;
  486. strRoot = (LPCTSTR)pObject->Name;
  487. if (AREA_FILESTORE_ANALYSIS == type)
  488. {
  489. //
  490. // We want c:\, not c: here.
  491. //
  492. strRoot += L"\\";
  493. }
  494. //
  495. // These are the roots of the objects.
  496. // They are always containers
  497. //
  498. if (SCE_STATUS_NO_ACL_SUPPORT == pObject->Status)
  499. {
  500. folder = CreateAndAddOneNode(pFolder,
  501. // pObject->Name,
  502. strRoot,
  503. pBuf,
  504. newType,
  505. FALSE,
  506. GT_COMPUTER_TEMPLATE,
  507. pObject,
  508. pObject->Status);
  509. }
  510. else
  511. {
  512. folder = CreateAndAddOneNode(
  513. pFolder, // Parent folder
  514. // pObject->Name, // Name
  515. strRoot,
  516. pBuf, // Description
  517. newType, // Folder Type
  518. TRUE, // Has Children?
  519. GT_COMPUTER_TEMPLATE, // INF File
  520. pObject, // Extra Data: the object
  521. pObject->Status); // Status
  522. }
  523. if(folder)
  524. folder->SetDesc( pObject->Status, pObject->Count );
  525. }
  526. }
  527. return S_OK;
  528. case REG_OBJECTS:
  529. case FILE_OBJECTS:
  530. if ( SadHandle == NULL )
  531. {
  532. //
  533. // We shouldn't be able to get this far without a SadHandle
  534. //
  535. ASSERT(FALSE);
  536. return E_FAIL;
  537. }
  538. if ( type == REG_OBJECTS)
  539. status = AREA_REGISTRY_SECURITY;
  540. else if ( type == FILE_OBJECTS )
  541. status = AREA_FILE_SECURITY;
  542. else
  543. {
  544. ASSERT(FALSE);
  545. return E_FAIL;
  546. }
  547. //
  548. // get the next level objects
  549. //
  550. rc = SceGetObjectChildren(SadHandle, // hProfile
  551. SCE_ENGINE_SAP, // Profile type
  552. (AREA_INFORMATION)status, // Area
  553. (LPTSTR)(pFolder->GetName()),// Object prefix
  554. &ObjectList, // Object list [out]
  555. &ErrBuf); // Error list [out]
  556. if ( ErrBuf )
  557. { // rc != SCESTATUS_SUCCESS ) {
  558. MyFormatResMessage(rc, IDS_ERROR_GETTING_LAST_ANALYSIS, ErrBuf, StrErr);
  559. SceFreeMemory((PVOID)ErrBuf, SCE_STRUCT_ERROR_LOG_INFO);
  560. ErrBuf = NULL;
  561. }
  562. if ( rc == SCESTATUS_SUCCESS &&
  563. ObjectList )
  564. {
  565. BOOL bContainer = FALSE;
  566. //
  567. // add the objects
  568. //
  569. PSCE_OBJECT_CHILDREN_NODE *pObjNode = &(ObjectList->arrObject);
  570. for (DWORD i=0; i<ObjectList->nCount;i++)
  571. {
  572. //
  573. // These are the next level objects
  574. //
  575. if ( pObjNode[i] == NULL ||
  576. pObjNode[i]->Name == NULL )
  577. {
  578. continue;
  579. }
  580. if (SCE_STATUS_NO_ACL_SUPPORT == pObjNode[i]->Status)
  581. {
  582. // No ACL support, so don't add sub objects
  583. continue;
  584. }
  585. //
  586. // If there are any mismatched child objects then we know
  587. // that this is a container, otherwise we have to check the
  588. // object on the system to find out if it is a container
  589. //
  590. if ( pObjNode[i]->Count > 0 )
  591. bContainer = TRUE;
  592. else
  593. {
  594. if (FILE_OBJECTS == type)
  595. {
  596. //
  597. // Check if a file object is a container
  598. //
  599. CString strPath;
  600. DWORD dwAttr = 0;
  601. strPath = pFolder->GetName();
  602. if (strPath.Right(1) != L"\\")
  603. {
  604. strPath += L"\\";
  605. }
  606. strPath += pObjNode[i]->Name;
  607. dwAttr = GetFileAttributes(strPath);
  608. if (0xFFFFFFFF == dwAttr)
  609. bContainer = FALSE;
  610. else
  611. bContainer = dwAttr & FILE_ATTRIBUTE_DIRECTORY;
  612. }
  613. else
  614. {
  615. //
  616. // Always treat Registry Keys and DS Objects as containers
  617. //
  618. bContainer = TRUE;
  619. }
  620. }
  621. if (bContainer)
  622. {
  623. StrErr = pFolder->GetName();
  624. if (StrErr.Right(1) != L"\\")
  625. StrErr += L"\\";
  626. StrErr += pObjNode[i]->Name;
  627. folder = CreateAndAddOneNode(
  628. pFolder, // Parent folder
  629. (LPTSTR)((LPCTSTR)StrErr), // Name
  630. pBuf, // Description
  631. type, // Folder Type
  632. TRUE, // Has Children?
  633. GT_COMPUTER_TEMPLATE, // INF File
  634. NULL,
  635. pObjNode[i]->Status); // Object Status
  636. if(folder)
  637. {
  638. folder->SetDesc( pObjNode[i]->Status,
  639. pObjNode[i]->Count );
  640. }
  641. }
  642. }
  643. }
  644. if ( ObjectList )
  645. SceFreeMemory((PVOID)ObjectList, SCE_STRUCT_OBJECT_CHILDREN );
  646. return S_OK;
  647. case CONFIGURATION:
  648. {
  649. //
  650. // enumerate profile locations in registry
  651. //
  652. CString strLocations;
  653. m_ConfigFolder = pFolder;
  654. nCount = 0;
  655. if (strLocations.LoadString(IDS_TEMPLATE_LOCATION_KEY))
  656. {
  657. //
  658. // Bug 375324 - Merge HKCU locations with HKLM locations
  659. //
  660. status = RegOpenKeyEx( HKEY_CURRENT_USER,
  661. strLocations,
  662. 0, KEY_READ, &hKey);
  663. if ( NO_ERROR == status )
  664. {
  665. nCount += AddLocationsToFolderList(hKey,dwMode,FALSE,pPos);
  666. RegCloseKey(hKey);
  667. }
  668. if ( 0 == nCount )
  669. {
  670. //
  671. // Empty location list, so add a default
  672. //
  673. CString strDefLoc;
  674. CString strDefLocEx;
  675. strDefLoc.LoadString(IDS_DEFAULT_LOCATION);
  676. int iLen = strDefLoc.GetLength()+MAX_PATH;
  677. LPWSTR pBuffer = strDefLocEx.GetBuffer(iLen);
  678. if (ExpandEnvironmentStrings(strDefLoc, pBuffer, iLen))
  679. {
  680. //
  681. // must use pBuffer here since strDefLocEx has not been released
  682. //
  683. AddTemplateLocation(pFolder,pBuffer,FALSE,TRUE);
  684. }
  685. else
  686. AddTemplateLocation(pFolder,strDefLoc,FALSE,TRUE);
  687. strDefLocEx.ReleaseBuffer();
  688. }
  689. }
  690. if ( Count != NULL )
  691. *Count = nCount;
  692. return hr;
  693. }
  694. case LOCATIONS:
  695. //
  696. // enumerate available profiles under the location (*.inf files)
  697. //
  698. //
  699. // pFolder is required in this case
  700. //
  701. if (!pFolder)
  702. return E_INVALIDARG;
  703. swprintf(pBuf, L"%s\\*.inf",
  704. (LPTSTR)(pFolder->GetName()));
  705. bHasChildren = FALSE;
  706. hFile = _wfindfirst(pBuf, &findData);
  707. if ( hFile != -1)
  708. {
  709. do {
  710. //
  711. // Don't add this item to the node if it is a subdirectory.
  712. //
  713. CString strDisplay;
  714. strDisplay.Format(
  715. TEXT("%s\\%s"),
  716. (LPCTSTR)(pFolder->GetName()),
  717. findData.name);
  718. if( findData.attrib & _A_SUBDIR )
  719. continue;
  720. //
  721. // get template's description
  722. //
  723. strDisplay = findData.name;
  724. //
  725. // GetLength has to be at least 4, since we searched on *.inf
  726. //
  727. strDisplay = strDisplay.Left(strDisplay.GetLength() - 4);
  728. swprintf(pBuf,
  729. L"%s\\%s",
  730. (LPTSTR)(pFolder->GetName()),
  731. findData.name);
  732. if (! GetProfileDescription(pBuf, &Desc) )
  733. Desc = NULL;
  734. else
  735. {
  736. //
  737. // No problem; we just won't display a description
  738. //
  739. }
  740. nCount++;
  741. folder = new CFolder();
  742. if (folder)
  743. {
  744. //
  745. // Create the folder objects
  746. // save full file name her
  747. //
  748. hr = folder->Create((LPCTSTR)strDisplay, // Name
  749. Desc, // Description
  750. pBuf, // inf file name
  751. TEMPLATES_IDX, // closed icon index
  752. TEMPLATES_IDX, // open icon index
  753. PROFILE, // folder type
  754. bHasChildren, // has children
  755. dwMode, // SCE Mode
  756. NULL); // Extra Data
  757. if (SUCCEEDED(hr))
  758. {
  759. m_scopeItemList.AddTail(folder);
  760. if ( nCount == 1 && NULL != pPos )
  761. {
  762. *pPos = m_scopeItemList.GetTailPosition();
  763. }
  764. }
  765. else
  766. {
  767. delete folder;
  768. folder = NULL;
  769. }
  770. }
  771. else
  772. hr = E_OUTOFMEMORY;
  773. if (Desc)
  774. {
  775. LocalFree(Desc);
  776. Desc = NULL;
  777. }
  778. } while ( _wfindnext(hFile, &findData) == 0 );
  779. }
  780. _findclose(hFile);
  781. if ( Count != NULL )
  782. *Count = nCount;
  783. return hr;
  784. case PROFILE:
  785. {
  786. TCHAR pszGPTPath[MAX_PATH*5];
  787. SCESTATUS scestatus = 0;
  788. //
  789. // enumerate security areas for this profile
  790. //
  791. if (ModeBits & MB_NO_NATIVE_NODES)
  792. {
  793. //
  794. //
  795. //
  796. nStart = nCount = 0;
  797. break;
  798. }
  799. //
  800. // Find the path to the SCE template within the GPT template
  801. //
  802. if (ModeBits & MB_GROUP_POLICY)
  803. {
  804. //
  805. // get GPT root path
  806. //
  807. hr = m_pGPTInfo->GetFileSysPath(GPO_SECTION_MACHINE,
  808. pszGPTPath,
  809. ARRAYSIZE(pszGPTPath));
  810. if (SUCCEEDED(hr))
  811. {
  812. if (NULL == m_szSingleTemplateName)
  813. {
  814. //
  815. // Allocate memory for the pszGPTPath + <backslash> + GPTSCE_TEMPLATE + <trailing nul>
  816. //
  817. m_szSingleTemplateName = (LPTSTR) LocalAlloc(LPTR,(lstrlen(pszGPTPath)+lstrlen(GPTSCE_TEMPLATE)+2)*sizeof(TCHAR));
  818. }
  819. if (NULL != m_szSingleTemplateName)
  820. {
  821. lstrcpy(m_szSingleTemplateName,pszGPTPath);
  822. lstrcat(m_szSingleTemplateName,L"\\" GPTSCE_TEMPLATE);
  823. PSCE_PROFILE_INFO spi = NULL;
  824. //
  825. // Create a new template there if there isn't one already
  826. //
  827. if (!CreateNewProfile(m_szSingleTemplateName,&spi))
  828. {
  829. hr = E_FAIL;
  830. }
  831. else
  832. {
  833. if (!GetTemplate(m_szSingleTemplateName) && spi)
  834. {
  835. //
  836. // bug 265996
  837. //
  838. // The first time a GPO's Security Settings are opened we create
  839. // the file, but if it's on a remote machine it may not have been
  840. // created yet when we try to open it
  841. //
  842. // Since we know what's going to be in it once it's created we
  843. // can skip the open step and just shove our template into the
  844. // cache
  845. //
  846. // Allocate space for key.
  847. //
  848. LPTSTR szKey = new TCHAR[ lstrlen( m_szSingleTemplateName ) + 1];
  849. if(!szKey)
  850. {
  851. return NULL;
  852. }
  853. lstrcpy(szKey, m_szSingleTemplateName);
  854. _wcslwr( szKey );
  855. //
  856. // Create a new CEditTemplate
  857. //
  858. CEditTemplate *pTemplateInfo = new CEditTemplate;
  859. if (pTemplateInfo)
  860. {
  861. pTemplateInfo->SetInfFile(m_szSingleTemplateName);
  862. pTemplateInfo->SetNotificationWindow(m_pNotifier);
  863. pTemplateInfo->pTemplate = spi;
  864. //
  865. // This is a brand new template; ergo everything's loaded
  866. //
  867. pTemplateInfo->AddArea(AREA_ALL);
  868. //
  869. // Stick it in the cache
  870. //
  871. m_Templates.SetAt(szKey, pTemplateInfo);
  872. //
  873. // expand registry value section based on registry values list on local machine
  874. //
  875. SceRegEnumAllValues(
  876. &(pTemplateInfo->pTemplate->RegValueCount),
  877. &(pTemplateInfo->pTemplate->aRegValues));
  878. }
  879. if (szKey)
  880. delete[] szKey;
  881. }
  882. }
  883. }
  884. else
  885. hr = E_OUTOFMEMORY;
  886. }
  887. }
  888. nStart = FIRST_PROFILE_FOLDER;
  889. //
  890. // Display all but the DS Objects folder
  891. //
  892. nCount = LAST_PROFILE_NODS_FOLDER - FIRST_PROFILE_FOLDER +1;
  893. bHasChildren = FALSE;
  894. tmpstr = pFolder->GetInfFile(); // inf file full path name
  895. //
  896. // If this folder is in a write-through mode then set that
  897. // on the template
  898. //
  899. PEDITTEMPLATE pie;
  900. pie = GetTemplate(tmpstr);
  901. if ( pie )
  902. {
  903. if (ModeBits & MB_WRITE_THROUGH)
  904. {
  905. pie->SetWriteThrough(TRUE);
  906. }
  907. }
  908. else
  909. {
  910. //
  911. // Mark as bad template.
  912. //
  913. pFolder->SetState( CFolder::state_InvalidTemplate );
  914. nCount = 0;
  915. }
  916. break;
  917. }
  918. case LOCALPOL:
  919. {
  920. nStart = FIRST_PROFILE_FOLDER;
  921. nCount = LAST_LOCALPOL_FOLDER - FIRST_PROFILE_FOLDER +1;
  922. bHasChildren = FALSE;
  923. pFolder->SetInfFile(GT_LOCAL_POLICY);
  924. break;
  925. }
  926. case POLICY_ACCOUNT:
  927. if (!pFolder)
  928. {
  929. return E_INVALIDARG;
  930. }
  931. else
  932. {
  933. tmpstr = pFolder->GetInfFile();
  934. }
  935. // fall through;
  936. case LOCALPOL_ACCOUNT:
  937. case POLICY_ACCOUNT_ANALYSIS:
  938. nStart = FIRST_ACCOUNT_FOLDER;
  939. if (ModeBits & MB_DS_OBJECTS_SECTION)
  940. {
  941. //
  942. // Include the DC Specific folders
  943. //
  944. nCount = LAST_ACCOUNT_FOLDER - FIRST_ACCOUNT_FOLDER + 1;
  945. }
  946. else
  947. {
  948. //
  949. // Display all but the DC Specific folders
  950. //
  951. nCount = LAST_ACCOUNT_NODS_FOLDER - FIRST_ACCOUNT_FOLDER +1;
  952. }
  953. bHasChildren = FALSE;
  954. break;
  955. case POLICY_LOCAL:
  956. if (!pFolder)
  957. {
  958. return E_INVALIDARG;
  959. }
  960. else
  961. {
  962. tmpstr = pFolder->GetInfFile();
  963. }
  964. // fall through;
  965. case LOCALPOL_LOCAL:
  966. case POLICY_LOCAL_ANALYSIS:
  967. nStart = FIRST_LOCAL_FOLDER;
  968. nCount = LAST_LOCAL_FOLDER - FIRST_LOCAL_FOLDER +1;
  969. bHasChildren = FALSE;
  970. break;
  971. case POLICY_EVENTLOG:
  972. if (!pFolder)
  973. return E_INVALIDARG;
  974. else
  975. tmpstr = pFolder->GetInfFile();
  976. // fall through;
  977. case LOCALPOL_EVENTLOG:
  978. case POLICY_EVENTLOG_ANALYSIS:
  979. nStart = FIRST_EVENTLOG_FOLDER;
  980. nCount = LAST_EVENTLOG_FOLDER - FIRST_EVENTLOG_FOLDER +1;
  981. bHasChildren = FALSE;
  982. break;
  983. default:
  984. break;
  985. }
  986. if ( Count != NULL )
  987. *Count = nCount;
  988. CString cStrName;
  989. CString cStrDesc;
  990. for (int i=nStart; i < nStart+nCount; i++)
  991. {
  992. folder = new CFolder();
  993. if (!folder)
  994. {
  995. //
  996. // What about other folders that we've created?
  997. //
  998. return E_OUTOFMEMORY;
  999. }
  1000. if (!cStrName.LoadString(SecmgrFolders[i].ResID) ||
  1001. !cStrDesc.LoadString(SecmgrFolders[i].DescID))
  1002. {
  1003. delete folder;
  1004. return E_FAIL;
  1005. }
  1006. //
  1007. // Create the folder objects with static data
  1008. //
  1009. if (type == ANALYSIS ||
  1010. type == AREA_POLICY_ANALYSIS ||
  1011. type == POLICY_ACCOUNT_ANALYSIS ||
  1012. type == POLICY_LOCAL_ANALYSIS ||
  1013. type == POLICY_EVENTLOG_ANALYSIS )
  1014. {
  1015. if (m_bIsLocked)
  1016. {
  1017. nCount = 0;
  1018. delete folder;
  1019. // Should display an "in use" message in result pane
  1020. //
  1021. // We're not adding anything, but we're not actually failing
  1022. //
  1023. return S_OK;
  1024. }
  1025. switch (SecmgrFolders[i].type)
  1026. {
  1027. case AREA_POLICY:
  1028. newType = AREA_POLICY_ANALYSIS;
  1029. break;
  1030. case AREA_PRIVILEGE:
  1031. newType = AREA_PRIVILEGE_ANALYSIS;
  1032. break;
  1033. case AREA_GROUPS:
  1034. newType = AREA_GROUPS_ANALYSIS;
  1035. break;
  1036. case AREA_SERVICE:
  1037. newType = AREA_SERVICE_ANALYSIS;
  1038. tmpstr = GT_COMPUTER_TEMPLATE;
  1039. break;
  1040. case AREA_REGISTRY:
  1041. newType = AREA_REGISTRY_ANALYSIS;
  1042. break;
  1043. case AREA_FILESTORE:
  1044. newType = AREA_FILESTORE_ANALYSIS;
  1045. break;
  1046. case POLICY_ACCOUNT:
  1047. newType = POLICY_ACCOUNT_ANALYSIS;
  1048. break;
  1049. case POLICY_LOCAL:
  1050. newType = POLICY_LOCAL_ANALYSIS;
  1051. break;
  1052. case POLICY_EVENTLOG:
  1053. newType = POLICY_EVENTLOG_ANALYSIS;
  1054. break;
  1055. case POLICY_PASSWORD:
  1056. newType = POLICY_PASSWORD_ANALYSIS;
  1057. break;
  1058. case POLICY_KERBEROS:
  1059. newType = POLICY_KERBEROS_ANALYSIS;
  1060. break;
  1061. case POLICY_LOCKOUT:
  1062. newType = POLICY_LOCKOUT_ANALYSIS;
  1063. break;
  1064. case POLICY_AUDIT:
  1065. newType = POLICY_AUDIT_ANALYSIS;
  1066. break;
  1067. case POLICY_OTHER:
  1068. newType = POLICY_OTHER_ANALYSIS;
  1069. break;
  1070. case POLICY_LOG:
  1071. newType = POLICY_LOG_ANALYSIS;
  1072. break;
  1073. default:
  1074. newType = SecmgrFolders[i].type;
  1075. break;
  1076. }
  1077. int nImage = GetScopeImageIndex(newType);
  1078. hr = folder->Create(cStrName.GetBuffer(2), // Name
  1079. cStrDesc.GetBuffer(2), // Description
  1080. tmpstr, // inf file name
  1081. nImage, // closed icon index
  1082. nImage, // open icon index
  1083. newType, // folder type
  1084. bHasChildren, // has children
  1085. dwMode, // SCE Mode
  1086. NULL); // Extra Data
  1087. }
  1088. else if (type == LOCALPOL ||
  1089. type == AREA_LOCALPOL ||
  1090. type == LOCALPOL_ACCOUNT ||
  1091. type == LOCALPOL_LOCAL ||
  1092. type == LOCALPOL_EVENTLOG )
  1093. {
  1094. if (m_bIsLocked)
  1095. {
  1096. nCount = 0;
  1097. delete folder;
  1098. // Should display an "in use" message in result pane
  1099. //
  1100. // We're not adding anything, but we're not actually failing
  1101. //
  1102. return S_OK;
  1103. }
  1104. tmpstr = GT_LOCAL_POLICY;
  1105. switch (SecmgrFolders[i].type)
  1106. {
  1107. case AREA_POLICY:
  1108. newType = AREA_LOCALPOL;
  1109. break;
  1110. case POLICY_ACCOUNT:
  1111. newType = LOCALPOL_ACCOUNT;
  1112. break;
  1113. case POLICY_LOCAL:
  1114. newType = LOCALPOL_LOCAL;
  1115. break;
  1116. case POLICY_EVENTLOG:
  1117. newType = LOCALPOL_EVENTLOG;
  1118. break;
  1119. case POLICY_PASSWORD:
  1120. newType = LOCALPOL_PASSWORD;
  1121. break;
  1122. case POLICY_KERBEROS:
  1123. newType = LOCALPOL_KERBEROS;
  1124. break;
  1125. case POLICY_LOCKOUT:
  1126. newType = LOCALPOL_LOCKOUT;
  1127. break;
  1128. case POLICY_AUDIT:
  1129. newType = LOCALPOL_AUDIT;
  1130. break;
  1131. case POLICY_OTHER:
  1132. newType = LOCALPOL_OTHER;
  1133. break;
  1134. case POLICY_LOG:
  1135. newType = LOCALPOL_LOG;
  1136. break;
  1137. case AREA_PRIVILEGE:
  1138. newType = LOCALPOL_PRIVILEGE;
  1139. break;
  1140. default:
  1141. newType = SecmgrFolders[i].type;
  1142. break;
  1143. }
  1144. int nImage = GetScopeImageIndex(newType);
  1145. hr = folder->Create(cStrName.GetBuffer(2), // Name
  1146. cStrDesc.GetBuffer(2), // Description
  1147. tmpstr, // inf file name
  1148. nImage, // closed icon index
  1149. nImage, // open icon index
  1150. newType, // folder type
  1151. bHasChildren, // has children
  1152. dwMode, // SCE Mode
  1153. NULL); // Extra Data
  1154. }
  1155. else
  1156. {
  1157. int nImage = GetScopeImageIndex(SecmgrFolders[i].type);
  1158. hr = folder->Create(cStrName.GetBuffer(2), // Name
  1159. cStrDesc.GetBuffer(2), // Description
  1160. tmpstr, // inf file name
  1161. nImage, // closed icon index
  1162. nImage, // open icon index
  1163. SecmgrFolders[i].type, // folder type
  1164. bHasChildren, // has children
  1165. dwMode, // SCE Mode
  1166. NULL); // Extra Data
  1167. }
  1168. if (SUCCEEDED(hr))
  1169. {
  1170. m_scopeItemList.AddTail(folder);
  1171. if ( i == nStart && NULL != pPos )
  1172. {
  1173. *pPos = m_scopeItemList.GetTailPosition();
  1174. }
  1175. }
  1176. else
  1177. {
  1178. delete folder;
  1179. return hr;
  1180. }
  1181. }
  1182. return S_OK;
  1183. }
  1184. //+--------------------------------------------------------------------------
  1185. //
  1186. // Method: EnumerateScopePane
  1187. //
  1188. // Synopsis: Add the child folders of cookie/pParent to MMC's scope pane tree
  1189. //
  1190. // Arguments: [cookie] - The cookie representing the node's who we
  1191. // are enumerating
  1192. // [pParent] - The id of the node we are enumerating
  1193. // [dwMode] - The mode SCE is operating under (only allowed for
  1194. // initial enumeration)
  1195. //
  1196. // Returns: none
  1197. //
  1198. // Modifies: m_ScopeItemList (via CreateFolderList)
  1199. //
  1200. // History: 12-15-1997 Robcap
  1201. //
  1202. //---------------------------------------------------------------------------
  1203. void CComponentDataImpl::EnumerateScopePane(MMC_COOKIE cookie, HSCOPEITEM pParent)
  1204. {
  1205. int i = 0;
  1206. ASSERT(m_pScope != NULL); // make sure we QI'ed for the interface
  1207. if (NULL == m_pScope)
  1208. return;
  1209. m_bEnumerateScopePaneCalled = true;
  1210. //
  1211. // Enumerate the scope pane
  1212. //
  1213. // Note - Each cookie in the scope pane represents a folder.
  1214. // A released product may have more then one level of children.
  1215. // This sample assumes the parent node is one level deep.
  1216. ASSERT(pParent != 0);
  1217. if (0 == pParent)
  1218. return;
  1219. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  1220. if (m_scopeItemList.GetCount() == 0 )
  1221. {
  1222. CreateFolderList(NULL, ROOT, NULL, NULL);
  1223. }
  1224. //
  1225. // Enumerate the scope pane
  1226. // return the folder object that represents the cookie
  1227. // Note - for large list, use dictionary
  1228. //
  1229. CFolder* pThis = FindObject(cookie, NULL);
  1230. if (NULL == pThis)
  1231. pThis = m_AnalFolder;
  1232. ASSERT(pThis);
  1233. if ( NULL == pThis )
  1234. return;
  1235. //
  1236. // Note - Each cookie in the scope pane represents a folder.
  1237. //
  1238. //
  1239. // If we've already enumerated this folder then don't do it again
  1240. //
  1241. if ( pThis->IsEnumerated() )
  1242. return;
  1243. POSITION pos = NULL;
  1244. int nCount = 0;
  1245. CFolder *pFolder = 0;
  1246. //
  1247. // the pParent is the enumerated node's item ID, not its parent ID
  1248. //
  1249. pThis->GetScopeItem()->ID = pParent;
  1250. if (SUCCEEDED(CreateFolderList( pThis,
  1251. pThis->GetType(),
  1252. &pos,
  1253. &nCount )))
  1254. {
  1255. for (i=0; (i < nCount) && (pos != NULL); i++ )
  1256. {
  1257. pFolder = m_scopeItemList.GetNext(pos);
  1258. ASSERT(NULL != pFolder);
  1259. if ( pFolder == NULL )
  1260. {
  1261. continue;
  1262. }
  1263. LPSCOPEDATAITEM pScope;
  1264. pScope = pFolder->GetScopeItem();
  1265. ASSERT(NULL != pScope);
  1266. //
  1267. // Set the parent
  1268. //
  1269. pScope->relativeID = pParent;
  1270. //
  1271. // Set the folder as the cookie
  1272. //
  1273. pScope->mask |= SDI_PARAM;
  1274. pScope->lParam = reinterpret_cast<LPARAM>(pFolder);
  1275. pFolder->SetCookie(reinterpret_cast<MMC_COOKIE>(pFolder));
  1276. m_pScope->InsertItem(pScope);
  1277. //
  1278. // Note - On return, the ID member of 'm_pScopeItem'
  1279. // contains the handle to the newly inserted item!
  1280. //
  1281. ASSERT(pScope->ID != NULL);
  1282. }
  1283. // This was commented out, but is needed to fix
  1284. // 249158: SCE UI: Every time analysis is performed, another set of node appears
  1285. // This flag will prevent the nodes from being re-enumerated.
  1286. // If this doesn't work, then all the child nodes should be deleted before
  1287. // reenumeration
  1288. pThis->Set(TRUE); // folder has been enumerated
  1289. }
  1290. else
  1291. {
  1292. //
  1293. // Error creating folder list. Make sure the folder isn't
  1294. // marked as opened so that we can try to expand it again later
  1295. //
  1296. SCOPEDATAITEM item;
  1297. ZeroMemory (&item, sizeof (item));
  1298. item.mask = SDI_STATE;
  1299. item.nState = 0;
  1300. item.ID = pThis->GetScopeItem()->ID;
  1301. //
  1302. // Nothing else we can do if this returns a failure, so
  1303. // don't worry about it
  1304. //
  1305. (void)m_pScope->SetItem (&item);
  1306. }
  1307. }
  1308. /*------------------------------------------------------------------------------------------
  1309. CComponentDataImpl::GetColumnInfo
  1310. Synopsis: Returns the column info for a folder type.
  1311. Arguments: [fType] - The type of the CFolder item.
  1312. Returns: a pointer to an int * where int[0] = the resource descritption into g_columnInfo.
  1313. int[1] = the number of columns this array describes.
  1314. NULL - If there is no matching key.
  1315. ------------------------------------------------------------------------------------------*/
  1316. PSCE_COLINFOARRAY CComponentDataImpl::GetColumnInfo( FOLDER_TYPES fType )
  1317. {
  1318. PSCE_COLINFOARRAY pRet = NULL;
  1319. if( m_mapColumns.Lookup(fType, pRet) )
  1320. {
  1321. return pRet;
  1322. }
  1323. return NULL;
  1324. }
  1325. /*------------------------------------------------------------------------------------------
  1326. CComponentDataImpl::SetColumnInfo
  1327. Synopsis: Sets the column info for a certain type of folder.
  1328. Arguments: [fType] - The type of the CFolder item.
  1329. [pInfo] - The new column info.
  1330. ------------------------------------------------------------------------------------------*/
  1331. void CComponentDataImpl::SetColumnInfo( FOLDER_TYPES fType, PSCE_COLINFOARRAY pInfo)
  1332. {
  1333. PSCE_COLINFOARRAY pCur = GetColumnInfo(fType);
  1334. if(pCur)
  1335. {
  1336. LocalFree(pCur);
  1337. }
  1338. m_mapColumns.SetAt(fType, pInfo);
  1339. }
  1340. /*------------------------------------------------------------------------------------------
  1341. CComponentDataImpl::UpdateObjectStatus
  1342. Synopsis: Updates the status of all objects under the child and parents if bUpdateThis
  1343. is TRUE.
  1344. Arguments: [pParent] - The Object to set status on
  1345. [bUpdateThis] - Weather to update the object or not.
  1346. ------------------------------------------------------------------------------------------*/
  1347. DWORD CComponentDataImpl::UpdateObjectStatus(
  1348. CFolder *pParent,
  1349. BOOL bUpdateThis)
  1350. {
  1351. if(!pParent)
  1352. return ERROR_INVALID_PARAMETER;
  1353. DWORD status = 0;
  1354. TCHAR szBuf[50];
  1355. switch(pParent->GetType())
  1356. {
  1357. case REG_OBJECTS:
  1358. status = AREA_REGISTRY_SECURITY;
  1359. break;
  1360. case FILE_OBJECTS:
  1361. status = AREA_FILE_SECURITY;
  1362. break;
  1363. default:
  1364. return ERROR_INVALID_PARAMETER;
  1365. }
  1366. PSCE_OBJECT_CHILDREN ObjectList = NULL;
  1367. PSCE_ERROR_LOG_INFO ErrBuf = NULL;
  1368. SCESTATUS rc = 0;
  1369. CString StrErr;
  1370. SCOPEDATAITEM sci;
  1371. HSCOPEITEM hItem = NULL;
  1372. LONG_PTR pCookie = NULL;
  1373. ZeroMemory(&sci, sizeof(SCOPEDATAITEM));
  1374. sci.mask = SDI_STR | SDI_PARAM;
  1375. #define UPDATE_STATUS( X, O ) X->SetDesc( O->Status, O->Count );\
  1376. X->GetScopeItem()->nImage = GetScopeImageIndex( X->GetType(), O->Status);\
  1377. X->GetScopeItem()->nOpenImage = X->GetScopeItem()->nImage;
  1378. LPCTSTR pszParent = NULL;
  1379. if (bUpdateThis)
  1380. {
  1381. CFolder *pCurrent = pParent;
  1382. pParent->RemoveAllResultItems();
  1383. m_pConsole->UpdateAllViews(NULL, (MMC_COOKIE)pParent, UAV_RESULTITEM_UPDATEALL);
  1384. hItem = pCurrent->GetScopeItem()->ID;
  1385. do {
  1386. //
  1387. // Walk up the items parent and update the items status.
  1388. //
  1389. if( m_pScope->GetParentItem( hItem, &hItem, &pCookie) == S_OK)
  1390. {
  1391. pszParent = (LPCTSTR)((CFolder *)pCookie)->GetName();
  1392. }
  1393. else
  1394. break;
  1395. if(!pCookie)
  1396. break;
  1397. //
  1398. // We are finished going up the parent.
  1399. //
  1400. switch( ((CFolder *)pCookie)->GetType() )
  1401. {
  1402. case AREA_REGISTRY_ANALYSIS:
  1403. case AREA_FILESTORE_ANALYSIS:
  1404. pszParent = NULL;
  1405. break;
  1406. default:
  1407. break;
  1408. }
  1409. //
  1410. // We have to get object information from the parent to the count parameter.
  1411. //
  1412. rc = SceGetObjectChildren(SadHandle, // hProfile
  1413. SCE_ENGINE_SAP, // Profile type
  1414. (AREA_INFORMATION)status, // Area
  1415. (LPTSTR)pszParent, // Object prefix
  1416. &ObjectList, // Object list [out]
  1417. &ErrBuf);
  1418. if(ErrBuf)
  1419. {
  1420. SceFreeMemory((PVOID)ErrBuf, SCE_STRUCT_ERROR_LOG_INFO);
  1421. ErrBuf = NULL;
  1422. }
  1423. if(SCESTATUS_SUCCESS != rc)
  1424. break;
  1425. //
  1426. // Find object in link list.
  1427. //
  1428. DWORD i=0;
  1429. sci.lParam = (LONG_PTR)pCurrent;
  1430. GetDisplayInfo( &sci );
  1431. PSCE_OBJECT_CHILDREN_NODE *pObjNode = &(ObjectList->arrObject);
  1432. while(ObjectList && i<ObjectList->nCount)
  1433. {
  1434. if( pObjNode[i] &&
  1435. pObjNode[i]->Name &&
  1436. !lstrcmpi(sci.displayname, pObjNode[i]->Name) )
  1437. {
  1438. UPDATE_STATUS(pCurrent, pObjNode[i]);
  1439. //
  1440. // Update scopeItem.
  1441. //
  1442. m_pScope->SetItem(pCurrent->GetScopeItem());
  1443. break;
  1444. }
  1445. i++;
  1446. }
  1447. if ( ObjectList )
  1448. {
  1449. SceFreeMemory((PVOID)ObjectList, SCE_STRUCT_OBJECT_CHILDREN );
  1450. ObjectList = NULL;
  1451. }
  1452. pCurrent = (CFolder *)pCookie;
  1453. } while( pszParent && hItem );
  1454. }
  1455. ObjectList = NULL;
  1456. ErrBuf = NULL;
  1457. //
  1458. // Get Object children.
  1459. //
  1460. pszParent = pParent->GetName();
  1461. rc = SceGetObjectChildren(SadHandle, // hProfile
  1462. SCE_ENGINE_SAP, // Profile type
  1463. (AREA_INFORMATION)status, // Area
  1464. (LPTSTR)pszParent, // Object prefix
  1465. &ObjectList, // Object list [out]
  1466. &ErrBuf);
  1467. //
  1468. // Error list [out]
  1469. //
  1470. if ( ErrBuf )
  1471. {
  1472. MyFormatResMessage(rc, IDS_ERROR_GETTING_LAST_ANALYSIS, ErrBuf, StrErr);
  1473. SceFreeMemory((PVOID)ErrBuf, SCE_STRUCT_ERROR_LOG_INFO);
  1474. ErrBuf = NULL;
  1475. }
  1476. if ( SCESTATUS_SUCCESS == rc)
  1477. {
  1478. //
  1479. // Update all the children.
  1480. //
  1481. if( m_pScope->GetChildItem(pParent->GetScopeItem()->ID, &hItem, &pCookie) == S_OK && pCookie)
  1482. {
  1483. sci.lParam = (LONG_PTR)pCookie;
  1484. GetDisplayInfo(&sci);
  1485. while(hItem)
  1486. {
  1487. pParent = reinterpret_cast<CFolder *>(pCookie);
  1488. //
  1489. // Find object in object list.
  1490. //
  1491. DWORD i=0;
  1492. while( ObjectList && i<ObjectList->nCount )
  1493. {
  1494. if( (&(ObjectList->arrObject))[i] &&
  1495. (&(ObjectList->arrObject))[i]->Name &&
  1496. !lstrcmpi((&(ObjectList->arrObject))[i]->Name, (LPCTSTR)sci.displayname) )
  1497. {
  1498. UPDATE_STATUS(pParent, (&(ObjectList->arrObject))[i]);
  1499. //
  1500. // Update this objects children.
  1501. //
  1502. UpdateObjectStatus( pParent, FALSE );
  1503. //
  1504. // Update the name space
  1505. //
  1506. pParent->RemoveAllResultItems();
  1507. m_pConsole->UpdateAllViews(NULL, (MMC_COOKIE)pParent, UAV_RESULTITEM_UPDATEALL);
  1508. m_pScope->SetItem(pParent->GetScopeItem());
  1509. break;
  1510. }
  1511. i++;
  1512. }
  1513. if(ObjectList == NULL || i >= ObjectList->nCount)
  1514. {
  1515. //
  1516. // Couldn't find the item, so just stop.
  1517. //
  1518. break;
  1519. }
  1520. //
  1521. // Next Scope item
  1522. //
  1523. if( m_pScope->GetNextItem(hItem, &hItem, &pCookie) != S_OK)
  1524. {
  1525. break;
  1526. }
  1527. }
  1528. }
  1529. }
  1530. if ( ObjectList )
  1531. SceFreeMemory((PVOID)ObjectList, SCE_STRUCT_OBJECT_CHILDREN );
  1532. return ERROR_SUCCESS;
  1533. }