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.

987 lines
28 KiB

  1. //+--------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1994 - 2001.
  5. //
  6. // File: edittemp.cpp
  7. //
  8. // Contents: CEditTemplate class to handle editing of SCE's INF files
  9. //
  10. // History:
  11. //
  12. //---------------------------------------------------------------------------
  13. #include "stdafx.h"
  14. #include "resource.h"
  15. #include "edittemp.h"
  16. #include "util.h"
  17. #include "snapmgr.h"
  18. #include <secedit.h>
  19. #include "wrapper.h"
  20. #include "wmihooks.h"
  21. #include <sceattch.h>
  22. #include <locale.h>
  23. //+--------------------------------------------------------------------------
  24. //
  25. // Method: AddService
  26. //
  27. // Synopsis: Adds a service attachment to the template
  28. //
  29. // Arguments: [szService] - [in] the name of the new service
  30. // [pPersistInfo] - [in] A pointer to the service extensions'
  31. // persistance interface
  32. //
  33. // Returns: TRUE if successfull, FALSE if either argument is null
  34. //
  35. // Modifies: m_Services
  36. //
  37. // History:
  38. //
  39. //---------------------------------------------------------------------------
  40. BOOL
  41. CEditTemplate::AddService(LPCTSTR szService, LPSCESVCATTACHMENTPERSISTINFO pPersistInfo) {
  42. if (!szService || !pPersistInfo) {
  43. return FALSE;
  44. }
  45. m_Services.SetAt(szService,pPersistInfo);
  46. return TRUE;
  47. }
  48. //+--------------------------------------------------------------------------
  49. //
  50. // Method: IsDirty
  51. //
  52. // Synopsis: Queries whether or not there is unsaved data in the template
  53. //
  54. // Returns: TRUE if there is unsaved information, FALSE otherwise
  55. //
  56. // Modifies:
  57. //
  58. // History:
  59. //
  60. //---------------------------------------------------------------------------
  61. BOOL
  62. CEditTemplate::IsDirty() {
  63. //
  64. // Some area is dirty
  65. //
  66. if (0 != m_AreaDirty) {
  67. return TRUE;
  68. }
  69. //
  70. // Loop through services until we find one that is dirty
  71. // or there are no more to check.
  72. //
  73. CString strService;
  74. LPSCESVCATTACHMENTPERSISTINFO pAttachPI;
  75. POSITION pos;
  76. pos = m_Services.GetStartPosition();
  77. while (pos) {
  78. m_Services.GetNextAssoc(pos,strService,pAttachPI);
  79. if (pAttachPI && (S_OK == pAttachPI->IsDirty(m_szInfFile))) {
  80. return TRUE;
  81. }
  82. }
  83. //
  84. // We didn't find anything dirty
  85. //
  86. return FALSE;
  87. }
  88. //+--------------------------------------------------------------------------
  89. //
  90. // Method: SetDirty
  91. //
  92. // Synopsis: Notify the template that some data within it has been changed.
  93. //
  94. // Returns: TRUE if successful, FALSE otherwise
  95. //
  96. // Modifies:
  97. //
  98. // History:
  99. //
  100. //---------------------------------------------------------------------------
  101. BOOL
  102. CEditTemplate::SetDirty(AREA_INFORMATION Area) {
  103. DWORD AreaDirtyOld;
  104. AreaDirtyOld = m_AreaDirty;
  105. m_AreaDirty |= Area;
  106. //
  107. // If the template is supposed to immediately save any changes then
  108. // do so.
  109. //
  110. if (QueryWriteThrough() && !m_bLocked) {
  111. SetWriteThroughDirty(TRUE);
  112. if (Save()) {
  113. //
  114. // #204628 - don't call PolicyChanged twiced when writing through
  115. // Call it in SetDirty and then skip it in Save, so we don't call it
  116. // once in SetDirty's call to Save and a second time when Save is called
  117. // on its own
  118. //
  119. // #204779 - call the notification window rather than directly calling
  120. // the IGPEInformation interface
  121. //
  122. if (m_pNotify && QueryPolicy()) {
  123. m_pNotify->RefreshPolicy();
  124. }
  125. } else {
  126. m_AreaDirty = AreaDirtyOld;
  127. return FALSE;
  128. }
  129. }
  130. return TRUE;
  131. }
  132. //+--------------------------------------------------------------------------------------
  133. // CEditTemplate::SetTemplateDefaults
  134. //
  135. // The caller will have to remove all memory objects used by this template if
  136. // this function
  137. // is called. Everything becomes NULL and nothing is freed.
  138. //+--------------------------------------------------------------------------------------
  139. void CEditTemplate::SetTemplateDefaults()
  140. {
  141. //
  142. // Local Policy Changes. Initialize everything to not changed
  143. //
  144. SCE_PROFILE_INFO *ppi = pTemplate;
  145. m_AreaLoaded = 0;
  146. m_AreaDirty = 0;
  147. if(!ppi){
  148. ppi = pTemplate = (PSCE_PROFILE_INFO) LocalAlloc(LPTR,sizeof(SCE_PROFILE_INFO));
  149. if (!pTemplate) {
  150. return;
  151. }
  152. }
  153. //
  154. // Must keep to type of this template.
  155. //
  156. SCETYPE dwType = ppi->Type;
  157. PSCE_KERBEROS_TICKET_INFO pKerberosInfo = ppi->pKerberosInfo;
  158. ZeroMemory( ppi, sizeof(SCE_PROFILE_INFO));
  159. ppi->Type = dwType;
  160. //
  161. // Set defaults to the rest of the template.
  162. //
  163. ppi->MinimumPasswordAge=SCE_NO_VALUE;
  164. ppi->MaximumPasswordAge=SCE_NO_VALUE;
  165. ppi->MinimumPasswordLength=SCE_NO_VALUE;
  166. ppi->PasswordComplexity=SCE_NO_VALUE;
  167. ppi->PasswordHistorySize=SCE_NO_VALUE;
  168. ppi->LockoutBadCount=SCE_NO_VALUE;
  169. ppi->ResetLockoutCount=SCE_NO_VALUE;
  170. ppi->LockoutDuration=SCE_NO_VALUE;
  171. ppi->RequireLogonToChangePassword=SCE_NO_VALUE;
  172. ppi->ForceLogoffWhenHourExpire=SCE_NO_VALUE;
  173. ppi->EnableAdminAccount=SCE_NO_VALUE;
  174. ppi->EnableGuestAccount=SCE_NO_VALUE;
  175. ppi->ClearTextPassword=SCE_NO_VALUE;
  176. ppi->LSAAnonymousNameLookup=SCE_NO_VALUE;
  177. for (int i=0;i<3;i++) {
  178. ppi->MaximumLogSize[i]=SCE_NO_VALUE;
  179. ppi->AuditLogRetentionPeriod[i]=SCE_NO_VALUE;
  180. ppi->RetentionDays[i]=SCE_NO_VALUE;
  181. ppi->RestrictGuestAccess[i]=SCE_NO_VALUE;
  182. }
  183. ppi->AuditSystemEvents=SCE_NO_VALUE;
  184. ppi->AuditLogonEvents=SCE_NO_VALUE;
  185. ppi->AuditObjectAccess=SCE_NO_VALUE;
  186. ppi->AuditPrivilegeUse=SCE_NO_VALUE;
  187. ppi->AuditPolicyChange=SCE_NO_VALUE;
  188. ppi->AuditAccountManage=SCE_NO_VALUE;
  189. ppi->AuditProcessTracking=SCE_NO_VALUE;
  190. ppi->AuditDSAccess=SCE_NO_VALUE;
  191. ppi->AuditAccountLogon=SCE_NO_VALUE;
  192. //
  193. // String values
  194. //
  195. ppi->NewAdministratorName=NULL;
  196. ppi->NewGuestName=NULL;
  197. //
  198. // registry values
  199. //
  200. ppi->RegValueCount= 0;
  201. ppi->aRegValues = NULL;
  202. //
  203. // Kerberos information, if it was created then set the values.
  204. //
  205. if(pKerberosInfo){
  206. pKerberosInfo->MaxTicketAge = SCE_NO_VALUE;
  207. pKerberosInfo->MaxRenewAge = SCE_NO_VALUE;
  208. pKerberosInfo->MaxServiceAge = SCE_NO_VALUE;
  209. pKerberosInfo->MaxClockSkew = SCE_NO_VALUE;
  210. pKerberosInfo->TicketValidateClient = SCE_NO_VALUE;
  211. ppi->pKerberosInfo = pKerberosInfo;
  212. }
  213. }
  214. //+--------------------------------------------------------------------------
  215. //
  216. // Method: Save
  217. //
  218. // Synopsis: Save the template to disk
  219. //
  220. // Arguments: [szName] - [in] [optional] the name of the INF file to save to
  221. //
  222. // Returns: TRUE if the save is successful, False otherwise
  223. //
  224. // Modifies: m_AreaDirty
  225. //
  226. // History:
  227. //
  228. //---------------------------------------------------------------------------
  229. BOOL
  230. CEditTemplate::Save(LPCTSTR szName) {
  231. DWORD AreaDirty;
  232. BOOL bSaveAs = FALSE;
  233. BOOL bSaveDescription = FALSE;
  234. setlocale(LC_ALL, ".OCP");
  235. SCESTATUS status = SCESTATUS_OTHER_ERROR;
  236. PSCE_ERROR_LOG_INFO errBuf = NULL;
  237. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  238. if (QueryNoSave()) {
  239. m_AreaDirty = 0;
  240. return TRUE;
  241. }
  242. AreaDirty = m_AreaDirty;
  243. //
  244. // If szName isn't given then default to m_szInfFile
  245. //
  246. if (!szName) {
  247. szName = m_szInfFile;
  248. //
  249. // We should never be able to get into a situation where
  250. // szName still isn't set, but just in case somebody called
  251. // us without szName or m_szInfFile
  252. //
  253. ASSERT(szName);
  254. if (!szName) {
  255. return FALSE;
  256. }
  257. } else {
  258. if (lstrcmp(szName,m_szInfFile) != 0) {
  259. //
  260. // Saving to a different name (Save As)
  261. //
  262. //
  263. // Make sure the path to that filename exists:
  264. //
  265. if (SCESTATUS_SUCCESS != SceCreateDirectory( m_szInfFile, FALSE, NULL )) {
  266. return FALSE;
  267. }
  268. AreaDirty = AREA_ALL|AREA_DESCRIPTION;
  269. bSaveAs = TRUE;
  270. }
  271. }
  272. if (AreaDirty & AREA_DESCRIPTION) {
  273. bSaveDescription = TRUE;
  274. AreaDirty &= ~AREA_DESCRIPTION;
  275. if (!AreaDirty) {
  276. //
  277. // Make sure we have something else to save and
  278. // create the file. AREA_SECURITY_POLICY is cheap.
  279. //
  280. AreaDirty |= AREA_SECURITY_POLICY;
  281. }
  282. //
  283. // Bug 365485 - make sure we only write this to an already
  284. // existing temp file so that we don't accidentally create
  285. // an ansi one instead of unicode. We can easily do this
  286. // by writing the description section last since we can
  287. // depend on the engine getting the rest right
  288. //
  289. }
  290. if (AreaDirty) {
  291. //
  292. // Save the dirty areas of the profile
  293. //
  294. if (lstrcmpi(GT_COMPUTER_TEMPLATE,szName) == 0) {
  295. if (m_hProfile) {
  296. //
  297. // do not update object area
  298. //
  299. status = SceUpdateSecurityProfile(m_hProfile,
  300. AreaDirty & ~(AREA_FILE_SECURITY | AREA_REGISTRY_SECURITY | AREA_DS_OBJECTS),
  301. pTemplate,
  302. 0
  303. );
  304. }
  305. ASSERT(m_pCDI);
  306. if (m_pCDI) {
  307. m_pCDI->EngineCommitTransaction();
  308. }
  309. } else if (lstrcmp(GT_LOCAL_POLICY_DELTA,szName) == 0) {
  310. //
  311. // Save Changes only to Local Policy
  312. //
  313. status = SceUpdateSecurityProfile(NULL,
  314. AreaDirty & ~(AREA_FILE_SECURITY | AREA_REGISTRY_SECURITY | AREA_DS_OBJECTS),
  315. pTemplate,
  316. SCE_UPDATE_SYSTEM
  317. );
  318. SetTemplateDefaults();
  319. if (!bSaveAs) {
  320. m_AreaDirty = 0;
  321. m_AreaLoaded = 0;
  322. }
  323. } else if ((lstrcmp(GT_LAST_INSPECTION,szName) != 0) &&
  324. (lstrcmp(GT_RSOP_TEMPLATE,szName) != 0) &&
  325. (lstrcmp(GT_LOCAL_POLICY,szName) != 0) &&
  326. (lstrcmp(GT_EFFECTIVE_POLICY,szName) != 0)) {
  327. status = SceWriteSecurityProfileInfo(szName,
  328. AreaDirty,
  329. pTemplate,
  330. &errBuf);
  331. } else {
  332. //
  333. // No need (or way) to save the last inspection area
  334. //
  335. status = SCESTATUS_SUCCESS;
  336. }
  337. if (SCESTATUS_SUCCESS == status) {
  338. //
  339. // Those areas are no longer dirty.
  340. //
  341. if (!bSaveAs) {
  342. m_AreaDirty = 0;
  343. }
  344. } else {
  345. //
  346. // Save failed; Notify the user & return false
  347. //
  348. CString strTitle,strMsg,strBase;
  349. strTitle.LoadString(IDS_NODENAME);
  350. strBase.LoadString(IDS_SAVE_FAILED);
  351. strBase += GetFriendlyName();
  352. //MyFormatMessage(status, (LPCTSTR)strBase, errBuf,strMsg);
  353. AfxMessageBox(strBase);
  354. return FALSE;
  355. }
  356. }
  357. if (bSaveDescription) {
  358. if (m_szDesc) {
  359. if (WritePrivateProfileSection(
  360. szDescription,
  361. NULL,
  362. szName)) {
  363. WritePrivateProfileString(
  364. szDescription,
  365. L"Description",
  366. m_szDesc,
  367. szName);
  368. }
  369. }
  370. }
  371. //
  372. // Save any dirty services
  373. //
  374. CString strService;
  375. LPSCESVCATTACHMENTPERSISTINFO pAttachPI;
  376. POSITION pos;
  377. SCESVCP_HANDLE *scesvcHandle;
  378. PVOID pvData;
  379. BOOL bOverwriteAll;
  380. pos = m_Services.GetStartPosition();
  381. while (pos) {
  382. m_Services.GetNextAssoc(pos,strService,pAttachPI);
  383. if (S_OK == pAttachPI->IsDirty( (LPTSTR)szName )) {
  384. if (SUCCEEDED(pAttachPI->Save( (LPTSTR)szName,(SCESVC_HANDLE *)&scesvcHandle,&pvData,&bOverwriteAll ))) {
  385. if (scesvcHandle) {
  386. if (lstrcmp(GT_COMPUTER_TEMPLATE,szName) == 0) {
  387. //
  388. // database
  389. //
  390. status = SceSvcUpdateInfo(
  391. m_hProfile,
  392. scesvcHandle->ServiceName,
  393. (PSCESVC_CONFIGURATION_INFO)pvData
  394. );
  395. } else {
  396. //
  397. // inf templates
  398. //
  399. status = SceSvcSetInformationTemplate(scesvcHandle->TemplateName,
  400. scesvcHandle->ServiceName,
  401. bOverwriteAll,
  402. (PSCESVC_CONFIGURATION_INFO)pvData);
  403. }
  404. if (SCESTATUS_SUCCESS != status) {
  405. CString strTitle,strMsg,strBase;
  406. strTitle.LoadString(IDS_NODENAME);
  407. strBase.LoadString(IDS_SAVE_FAILED);
  408. strBase += scesvcHandle->ServiceName; //szName;
  409. MyFormatMessage(status, (LPCTSTR)strBase, errBuf,strMsg);
  410. AfxMessageBox(strMsg);
  411. }
  412. }
  413. }
  414. }
  415. }
  416. return TRUE;
  417. }
  418. //+--------------------------------------------------------------------------
  419. //
  420. // Method: SetInfFile
  421. //
  422. // Synopsis: Set the name of the INF file this template is associated with
  423. //
  424. // Arguments: [szFile] - [in] the name of the INF file to associate with
  425. //
  426. // Returns: TRUE if the filename is set successfully, FALSE otherwise
  427. //
  428. // Modifies: m_szInfFile
  429. //
  430. // History:
  431. //
  432. //---------------------------------------------------------------------------
  433. BOOL
  434. CEditTemplate::SetInfFile(LPCTSTR szFile) {
  435. LPTSTR szInfFile;
  436. if (szFile) {
  437. szInfFile = new TCHAR[lstrlen(szFile)+1];
  438. if (szInfFile) {
  439. lstrcpy(szInfFile,szFile);
  440. if (m_szInfFile) {
  441. delete[] m_szInfFile;
  442. }
  443. m_szInfFile = szInfFile;
  444. } else {
  445. return FALSE;
  446. }
  447. }
  448. return szFile != 0;
  449. }
  450. //+--------------------------------------------------------------------------
  451. //
  452. // Method: SetDescription
  453. //
  454. // Synopsis: Set the description for this template file
  455. //
  456. // Arguments: [szDesc] [in] the description for the template
  457. //
  458. // Returns: TRUE if the description is set successfully, FALSE otherwise
  459. //
  460. // Modifies: m_szDesc
  461. //
  462. // History:
  463. //
  464. //---------------------------------------------------------------------------
  465. BOOL
  466. CEditTemplate::SetDescription(LPCTSTR szDesc) {
  467. LPTSTR szDescription;
  468. if (szDesc) {
  469. szDescription = new TCHAR[lstrlen(szDesc)+1];
  470. if (szDescription) {
  471. lstrcpy(szDescription,szDesc);
  472. if (m_szDesc) {
  473. delete[] m_szDesc;
  474. }
  475. m_szDesc = szDescription;
  476. SetDirty(AREA_DESCRIPTION);
  477. } else {
  478. return FALSE;
  479. }
  480. }
  481. return szDesc != 0;
  482. }
  483. //+--------------------------------------------------------------------------
  484. //
  485. // Method: CEditTemplate
  486. //
  487. // Synopsis: Constructor for CEditTemplate
  488. //
  489. // History:
  490. //
  491. //---------------------------------------------------------------------------
  492. CEditTemplate::CEditTemplate() {
  493. m_AreaDirty = 0;
  494. m_AreaLoaded = 0;
  495. m_bWriteThrough = FALSE;
  496. m_bWriteThroughDirty = FALSE;
  497. m_hProfile = NULL;
  498. m_szInfFile = NULL;
  499. m_pNotify = NULL;
  500. m_pCDI = NULL;
  501. m_bNoSave = FALSE;
  502. m_strFriendlyName.Empty();
  503. m_szDesc = NULL;
  504. m_bWMI = NULL;
  505. m_bPolicy = FALSE;
  506. m_bLocked = FALSE;
  507. pTemplate = NULL;
  508. }
  509. //+--------------------------------------------------------------------------
  510. //
  511. // Method: ~CEditTemplate
  512. //
  513. // Synopsis: Destructor for CEditTemplate
  514. //
  515. // History:
  516. //
  517. //---------------------------------------------------------------------------
  518. CEditTemplate::~CEditTemplate() {
  519. POSITION pos;
  520. CString strKey;
  521. pos = m_Services.GetStartPosition();
  522. LPSCESVCATTACHMENTPERSISTINFO pAttachPI;
  523. while (pos) {
  524. m_Services.GetNextAssoc(pos,strKey,pAttachPI);
  525. delete pAttachPI;
  526. }
  527. if (m_szInfFile) {
  528. delete[] m_szInfFile;
  529. }
  530. if (m_szDesc) {
  531. delete[] m_szDesc;
  532. }
  533. if (pTemplate) {
  534. if (m_bWMI) {
  535. FreeWMI_SCE_PROFILE_INFO((PWMI_SCE_PROFILE_INFO)pTemplate);
  536. } else {
  537. SceFreeProfileMemory(pTemplate);
  538. }
  539. pTemplate = NULL;
  540. }
  541. m_AreaDirty = 0;
  542. }
  543. //+--------------------------------------------------------------------------
  544. //
  545. // Method: RefreshTemplate
  546. //
  547. // Synopsis: Reload the loaded parts of the template
  548. //
  549. // Arguments: [aiArea] - Areas to load even if not previously loaded
  550. //
  551. // Returns: 0 if the template is reloaded successfully, an error code otherwise
  552. //
  553. // Modifies: pTemplate;
  554. //---------------------------------------------------------------------------
  555. DWORD
  556. CEditTemplate::RefreshTemplate(AREA_INFORMATION aiAreaToAdd) {
  557. AREA_INFORMATION aiArea;
  558. PVOID pHandle = NULL;
  559. SCESTATUS rc;
  560. aiArea = m_AreaLoaded | aiAreaToAdd;
  561. if (!m_szInfFile) {
  562. return 1;
  563. }
  564. m_AreaDirty = 0;
  565. if (pTemplate) {
  566. if (m_bWMI) {
  567. FreeWMI_SCE_PROFILE_INFO((PWMI_SCE_PROFILE_INFO)pTemplate);
  568. } else {
  569. SceFreeProfileMemory(pTemplate);
  570. }
  571. pTemplate = NULL;
  572. }
  573. if ((lstrcmpi(GT_COMPUTER_TEMPLATE,m_szInfFile) == 0) ||
  574. (lstrcmpi(GT_LAST_INSPECTION,m_szInfFile) == 0) ||
  575. (lstrcmpi(GT_LOCAL_POLICY, m_szInfFile) == 0) ||
  576. (lstrcmpi(GT_EFFECTIVE_POLICY, m_szInfFile) == 0) ) {
  577. //
  578. // Analysis pane areas from jet database, not INF files
  579. //
  580. SCETYPE sceType;
  581. PSCE_ERROR_LOG_INFO perr = NULL;
  582. if (lstrcmpi(GT_COMPUTER_TEMPLATE,m_szInfFile) == 0) {
  583. sceType = SCE_ENGINE_SMP;
  584. } else if (lstrcmpi(GT_LOCAL_POLICY, m_szInfFile) == 0) {
  585. sceType = SCE_ENGINE_SYSTEM;
  586. if (!IsAdmin()) {
  587. m_hProfile = NULL;
  588. }
  589. } else if (lstrcmpi(GT_EFFECTIVE_POLICY,m_szInfFile) == 0){
  590. sceType = SCE_ENGINE_GPO;
  591. } else {
  592. sceType = SCE_ENGINE_SAP;
  593. }
  594. rc = SceGetSecurityProfileInfo(m_hProfile, // hProfile
  595. sceType, // Profile type
  596. aiArea, // Area
  597. &pTemplate, // SCE_PROFILE_INFO [out]
  598. &perr); // Error List [out]
  599. if (SCESTATUS_SUCCESS != rc) {
  600. if ((SCE_ENGINE_GPO == sceType) &&
  601. (0 == lstrcmpi(GT_EFFECTIVE_POLICY,m_szInfFile))) {
  602. SetTemplateDefaults();
  603. return 0;
  604. } else {
  605. return IDS_ERROR_CANT_GET_PROFILE_INFO;
  606. }
  607. }
  608. } else if (lstrcmpi(GT_RSOP_TEMPLATE, m_szInfFile) == 0) {
  609. if (!m_pCDI) {
  610. return IDS_ERROR_CANT_GET_PROFILE_INFO;
  611. }
  612. m_bWMI = TRUE;
  613. CWMIRsop Rsop(m_pCDI->m_pRSOPInfo);
  614. HRESULT hr;
  615. PWMI_SCE_PROFILE_INFO pProfileInfo;
  616. //
  617. // GetPrecedenceOneRSOPInfo should (but doesn't) support
  618. // getting just the requested area.
  619. //
  620. hr = Rsop.GetPrecedenceOneRSOPInfo(&pProfileInfo);
  621. if (FAILED(hr)) {
  622. return IDS_ERROR_CANT_GET_PROFILE_INFO;
  623. }
  624. pTemplate = pProfileInfo;
  625. //
  626. // Since it doesn't, set all areas not just the ones that
  627. // were asked for
  628. //
  629. AddArea(AREA_ALL);
  630. return 0;
  631. } else {
  632. LPTSTR szInfFile=NULL;
  633. if (lstrcmpi(GT_DEFAULT_TEMPLATE,m_szInfFile) == 0) {
  634. DWORD RegType;
  635. rc = MyRegQueryValue(HKEY_LOCAL_MACHINE,
  636. SCE_REGISTRY_KEY,
  637. SCE_REGISTRY_DEFAULT_TEMPLATE,
  638. (PVOID *)&szInfFile,
  639. &RegType );
  640. if (ERROR_SUCCESS != rc) {
  641. if (szInfFile) {
  642. LocalFree(szInfFile);
  643. szInfFile = NULL;
  644. }
  645. return IDS_ERROR_CANT_GET_PROFILE_INFO;
  646. }
  647. if (EngineOpenProfile(szInfFile,OPEN_PROFILE_CONFIGURE,&pHandle) != SCESTATUS_SUCCESS) {
  648. SetTemplateDefaults();
  649. LocalFree(szInfFile);
  650. szInfFile = NULL;
  651. return 0;
  652. }
  653. LocalFree(szInfFile);
  654. szInfFile = NULL;
  655. } else {
  656. if (EngineOpenProfile(m_szInfFile,OPEN_PROFILE_CONFIGURE,&pHandle) != SCESTATUS_SUCCESS) {
  657. return IDS_ERROR_CANT_OPEN_PROFILE;
  658. }
  659. }
  660. ASSERT(pHandle);
  661. //
  662. // get information from this template
  663. //
  664. PSCE_ERROR_LOG_INFO perr = NULL;
  665. rc = SceGetSecurityProfileInfo(pHandle,
  666. SCE_ENGINE_SCP,
  667. aiArea,
  668. &pTemplate,
  669. &perr //NULL // &ErrBuf do not care errors
  670. );
  671. if (SCESTATUS_SUCCESS != rc) {
  672. // Oops!
  673. }
  674. SceCloseProfile(&pHandle);
  675. pHandle = NULL;
  676. }
  677. /*
  678. if do not care errors, no need to use this buffer
  679. if ( ErrBuf ) {
  680. SceFreeMemory((PVOID)ErrBuf, SCE_STRUCT_ERROR_LOG_INFO);
  681. ErrBuf = NULL;
  682. }
  683. */
  684. if (rc != SCESTATUS_SUCCESS) {
  685. return IDS_ERROR_CANT_GET_PROFILE_INFO;
  686. }
  687. //
  688. // Set the area in the template
  689. //
  690. AddArea(aiArea);
  691. if ( aiArea & AREA_SECURITY_POLICY && pTemplate ) {
  692. //
  693. // expand registry value section based on registry values list on local machine
  694. //
  695. SceRegEnumAllValues(
  696. &(pTemplate->RegValueCount),
  697. &(pTemplate->aRegValues)
  698. );
  699. }
  700. return 0;
  701. }
  702. //+----------------------------------------------------------------------------------
  703. //Method: UpdatePrivilegeAssignedTo
  704. //
  705. //Synopsis: Updates a priviledge item, depending on the [bRemove] argument.
  706. // if [bRemove] is
  707. // FALSE - A new link is created and the pointer is returned through
  708. // ppaLink
  709. // TRUE - The link is removed from the list.
  710. //
  711. //Arguments: [bRemove] - Weither to remove or add an item.
  712. // [ppaLink] - The link to be removed or added. This paramter is
  713. // set to NULL if remove is successful or a pointer
  714. // to a new SCE_PRIVILEGE_ASSIGNMENT item.
  715. // [pszName] - Only used when adding a new item.
  716. //
  717. //Returns: ERROR_INVALID_PARAMETER - [ppaLink] is NULL or if removing
  718. // [*ppaLink] is NULL.
  719. // if adding then if [pszName] is NULL
  720. // ERROR_RESOURCE_NOT_FOUND - If the link could not be found
  721. // in this template.
  722. // E_POINTER - If [pszName] is a bad pointer or
  723. // [ppaLink] is bad.
  724. // E_OUTOFMEMORY - Not enough resources to complete the
  725. // operation.
  726. // ERROR_SUCCESS - The opration was successful.
  727. //----------------------------------------------------------------------------------+
  728. DWORD
  729. CEditTemplate::UpdatePrivilegeAssignedTo(
  730. BOOL bRemove,
  731. PSCE_PRIVILEGE_ASSIGNMENT *ppaLink,
  732. LPCTSTR pszName
  733. )
  734. {
  735. if(!ppaLink){
  736. return ERROR_INVALID_PARAMETER;
  737. }
  738. PSCE_PRIVILEGE_ASSIGNMENT *pNext = NULL;
  739. PSCE_PRIVILEGE_ASSIGNMENT pCurrent = NULL;
  740. if(bRemove) {
  741. __try {
  742. if(!*ppaLink){
  743. return ERROR_INVALID_PARAMETER;
  744. }
  745. } __except(EXCEPTION_CONTINUE_EXECUTION) {
  746. return (DWORD)E_POINTER;
  747. }
  748. //
  749. // Remove the link from the list.
  750. //
  751. pCurrent = pTemplate->OtherInfo.smp.pPrivilegeAssignedTo;
  752. if(pCurrent == (*ppaLink) ){
  753. pNext = &(pTemplate->OtherInfo.smp.pPrivilegeAssignedTo);
  754. } else if(pCurrent && pCurrent != (PSCE_PRIVILEGE_ASSIGNMENT)ULongToPtr(SCE_NO_VALUE)) {
  755. while( pCurrent->Next ){
  756. if(pCurrent->Next == *ppaLink){
  757. pNext = &(pCurrent->Next);
  758. break;
  759. }
  760. pCurrent = pCurrent->Next;
  761. }
  762. }
  763. if(pNext && pCurrent){
  764. (*pNext) = (*ppaLink)->Next;
  765. if( (*ppaLink)->Name){
  766. LocalFree( (*ppaLink)->Name);
  767. (*ppaLink)->Name = NULL;
  768. }
  769. SceFreeMemory( (*ppaLink)->AssignedTo, SCE_STRUCT_NAME_LIST);
  770. LocalFree( *ppaLink );
  771. *ppaLink = NULL;
  772. } else {
  773. return ERROR_RESOURCE_NOT_FOUND;
  774. }
  775. } else {
  776. int iLen;
  777. if(!pszName){
  778. return ERROR_INVALID_PARAMETER;
  779. }
  780. __try {
  781. iLen = lstrlen( pszName );
  782. } __except(EXCEPTION_CONTINUE_EXECUTION){
  783. return (DWORD)E_POINTER;
  784. }
  785. //
  786. // Create a new link.
  787. //
  788. pCurrent = (PSCE_PRIVILEGE_ASSIGNMENT)LocalAlloc( 0, sizeof(SCE_PRIVILEGE_ASSIGNMENT));
  789. if(!pCurrent){
  790. return (DWORD)E_OUTOFMEMORY;
  791. }
  792. ZeroMemory(pCurrent, sizeof(SCE_PRIVILEGE_ASSIGNMENT));
  793. //
  794. // Allocate space for the name.
  795. //
  796. pCurrent->Name = (LPTSTR)LocalAlloc( 0, sizeof(TCHAR) * (iLen + 1));
  797. if(!pCurrent->Name){
  798. LocalFree(pCurrent);
  799. return (DWORD)E_OUTOFMEMORY;
  800. }
  801. lstrcpy(pCurrent->Name, pszName);
  802. if (*ppaLink) {
  803. pCurrent->Status = (*ppaLink)->Status;
  804. pCurrent->AssignedTo = (*ppaLink)->AssignedTo;
  805. }
  806. //
  807. // Assign it to the link.
  808. //
  809. pCurrent->Next = pTemplate->OtherInfo.smp.pPrivilegeAssignedTo;
  810. pTemplate->OtherInfo.smp.pPrivilegeAssignedTo = pCurrent;
  811. *ppaLink = pCurrent;
  812. }
  813. return ERROR_SUCCESS;
  814. }
  815. DWORD
  816. CEditTemplate::ComputeStatus(
  817. PSCE_PRIVILEGE_ASSIGNMENT pEdit,
  818. PSCE_PRIVILEGE_ASSIGNMENT pAnal
  819. )
  820. {
  821. if (!pEdit || (PSCE_PRIVILEGE_ASSIGNMENT)ULongToPtr(SCE_NO_VALUE) == pEdit) {
  822. return SCE_STATUS_NOT_CONFIGURED;
  823. } else if (pEdit->Status == SCE_STATUS_NOT_CONFIGURED) {
  824. return SCE_STATUS_NOT_CONFIGURED;
  825. } else if (!pAnal || (PSCE_PRIVILEGE_ASSIGNMENT)ULongToPtr(SCE_NO_VALUE) == pAnal) {
  826. return SCE_STATUS_MISMATCH;
  827. } else if (SceCompareNameList(pEdit->AssignedTo, pAnal->AssignedTo)) {
  828. return SCE_STATUS_GOOD;
  829. }
  830. return pAnal->Status;
  831. }
  832. DWORD
  833. CEditTemplate::ComputeStatus(
  834. PSCE_REGISTRY_VALUE_INFO prvEdit,
  835. PSCE_REGISTRY_VALUE_INFO prvAnal
  836. )
  837. {
  838. //
  839. // Calculate information.
  840. //
  841. if(!prvEdit){
  842. return SCE_STATUS_NOT_CONFIGURED;
  843. }
  844. if(!prvAnal || (PSCE_REGISTRY_VALUE_INFO)ULongToPtr(SCE_NO_VALUE) == prvAnal){
  845. return SCE_STATUS_ERROR_NOT_AVAILABLE;
  846. }
  847. //
  848. // Calulate base on other information
  849. //
  850. if ( !(prvEdit->Value) ) {
  851. return SCE_STATUS_NOT_CONFIGURED;
  852. } else if ( (prvAnal->Value == NULL || prvAnal->Value == (LPTSTR)ULongToPtr(SCE_ERROR_VALUE))) {
  853. return prvAnal->Status;
  854. } else if ( _wcsicmp(prvEdit->Value, prvAnal->Value) != 0 ) {
  855. return SCE_STATUS_MISMATCH;
  856. }
  857. return SCE_STATUS_GOOD;
  858. }
  859. void
  860. CEditTemplate::LockWriteThrough() {
  861. ASSERT(!m_bLocked);
  862. m_bLocked = TRUE;
  863. }
  864. void
  865. CEditTemplate::UnLockWriteThrough() {
  866. ASSERT(m_bLocked);
  867. BOOL bSave = m_bLocked;
  868. m_bLocked = FALSE;
  869. //
  870. // Set dirty to save out any still dirty changes that
  871. // would have been written out had we not been locked
  872. //
  873. if ( bSave ) {
  874. SetDirty(0);
  875. SetTemplateDefaults();
  876. }
  877. }
  878. //Bug 212287, Yanggao, 3/20/2001
  879. LPCTSTR CEditTemplate::GetDesc() const
  880. {
  881. return m_szDesc;
  882. }