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.

1454 lines
40 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation 1996-2001.
  5. //
  6. // File: command.cpp
  7. //
  8. // Contents: implementation of CComponentDataImpl
  9. //
  10. //----------------------------------------------------------------------------
  11. #include "stdafx.h"
  12. #include "wrapper.h"
  13. #include "snapmgr.h"
  14. #include "asgncnfg.h"
  15. #include "util.h"
  16. #include <io.h>
  17. static BOOL RecursiveCreateDirectory(
  18. IN LPCTSTR pszDir
  19. )
  20. {
  21. DWORD dwAttr;
  22. DWORD dwErr;
  23. LPCTSTR psz;
  24. DWORD cch;
  25. WCHAR wch;
  26. LPTSTR pszParent = NULL;
  27. BOOL fResult = FALSE;
  28. dwAttr = GetFileAttributes(pszDir);
  29. if (0xFFFFFFFF != dwAttr)
  30. {
  31. if (FILE_ATTRIBUTE_DIRECTORY & dwAttr)
  32. fResult = TRUE;
  33. goto CommonReturn;
  34. }
  35. dwErr = GetLastError();
  36. if (!(ERROR_PATH_NOT_FOUND == dwErr || ERROR_FILE_NOT_FOUND == dwErr))
  37. return FALSE;
  38. if (CreateDirectory(pszDir, NULL)) // lpSecurityAttributes
  39. {
  40. fResult = TRUE;
  41. goto CommonReturn;
  42. }
  43. dwErr = GetLastError();
  44. if (!(ERROR_PATH_NOT_FOUND == dwErr || ERROR_FILE_NOT_FOUND == dwErr))
  45. goto CommonReturn;
  46. // Peal off the last path name component
  47. cch = _tcslen(pszDir);
  48. psz = pszDir + cch;
  49. while (TEXT('\\') != *psz)
  50. {
  51. if (psz == pszDir)
  52. // Path didn't have a \.
  53. goto CommonReturn;
  54. psz--;
  55. }
  56. cch = (DWORD)(psz - pszDir);
  57. if (0 == cch)
  58. // Detected leading \Path
  59. goto CommonReturn;
  60. // Check for leading \\ or x:\.
  61. wch = *(psz - 1);
  62. if ((1 == cch && TEXT('\\') == wch) || (2 == cch && TEXT(':') == wch))
  63. goto CommonReturn;
  64. if (NULL == (pszParent = (LPWSTR) LocalAlloc(0, (cch + 1) * sizeof(WCHAR))))
  65. goto CommonReturn;
  66. memcpy(pszParent, pszDir, cch * sizeof(TCHAR));
  67. pszParent[cch] = TEXT('\0');
  68. if (!RecursiveCreateDirectory(pszParent))
  69. goto CommonReturn;
  70. if (!CreateDirectory(pszDir, NULL)) // lpSecurityAttributes
  71. {
  72. dwErr = GetLastError();
  73. goto CommonReturn;
  74. }
  75. fResult = TRUE;
  76. CommonReturn:
  77. if (pszParent != NULL)
  78. LocalFree(pszParent);
  79. return fResult;
  80. }
  81. //+------------------------------------------------------------------------------------
  82. // CComponentDataImpl::GetWorkingDir
  83. //
  84. // Gets the default or last set directory used for the uIDDir.
  85. // Some defaults defined by this function are.
  86. //
  87. // %windir%\security\database - ANALYSIS
  88. // %windir%\security\Templates - Default profile location.
  89. //
  90. // Arguments: [uIDDir] - The ID of the working directory to set or retrieve.
  91. // [pStr] - Either the source or the return value. When the
  92. // function returns this value will be set to a directory
  93. // location.
  94. //
  95. // [bSet] - TRUE if [pStr] is to be set as the new working directory.
  96. // [bFile] - [pStr] contains a file name.
  97. //
  98. // Returns: TRUE - If the function succees.
  99. // FALSE - if something went wrong.
  100. // We don't really need to much granularity because this is not a critical
  101. // function.
  102. //+------------------------------------------------------------------------------------
  103. BOOL
  104. CComponentDataImpl::GetWorkingDir(
  105. GWD_TYPES uIDDir,
  106. LPTSTR *pStr,
  107. BOOL bSet,
  108. BOOL bFile
  109. )
  110. {
  111. BOOL fRet = FALSE;
  112. if(!pStr)
  113. {
  114. return FALSE;
  115. }
  116. LPTSTR szLocationValue = NULL;
  117. switch(uIDDir)
  118. {
  119. case GWD_CONFIGURE_LOG:
  120. szLocationValue = CONFIGURE_LOG_LOCATIONS_KEY;
  121. break;
  122. case GWD_ANALYSIS_LOG:
  123. szLocationValue = ANALYSIS_LOG_LOCATIONS_KEY;
  124. break;
  125. case GWD_OPEN_DATABASE:
  126. szLocationValue = OPEN_DATABASE_LOCATIONS_KEY;
  127. break;
  128. case GWD_IMPORT_TEMPLATE:
  129. szLocationValue = IMPORT_TEMPLATE_LOCATIONS_KEY;
  130. break;
  131. case GWD_EXPORT_TEMPLATE:
  132. szLocationValue = IMPORT_TEMPLATE_LOCATIONS_KEY; //104152, yanggao, 3/21/2001
  133. break;
  134. }
  135. LPTSTR pszPath = NULL;
  136. int i = 0;
  137. if( bSet )
  138. {
  139. if(!pStr || !(*pStr))
  140. return FALSE;
  141. i = lstrlen( *pStr );
  142. if(bFile)
  143. {
  144. //
  145. // Remove the file from the end of the string.
  146. //
  147. while(i && (*pStr)[i] != '\\')
  148. i--;
  149. }
  150. //
  151. // Create space for the new path and copy what we want.
  152. //
  153. pszPath = (LPTSTR)LocalAlloc( 0, (i + 1) * sizeof(TCHAR));
  154. if(!pszPath)
  155. return FALSE;
  156. memcpy(pszPath, *pStr, (i * sizeof(TCHAR)));
  157. pszPath[i] = 0;
  158. MyRegSetValue(HKEY_CURRENT_USER,
  159. DEFAULT_LOCATIONS_KEY,
  160. szLocationValue,
  161. (BYTE*)pszPath,
  162. (i+1)*sizeof(TCHAR),
  163. REG_SZ);
  164. LocalFree(pszPath);
  165. return TRUE;
  166. }
  167. DWORD dwType = REG_SZ;
  168. if (MyRegQueryValue(HKEY_CURRENT_USER,
  169. DEFAULT_LOCATIONS_KEY,
  170. szLocationValue,
  171. (PVOID*)&pszPath,
  172. &dwType) == ERROR_SUCCESS)
  173. {
  174. *pStr = pszPath;
  175. return TRUE;
  176. }
  177. CString sAppend;
  178. DWORD dwRet;
  179. pszPath = NULL;
  180. switch ( uIDDir )
  181. {
  182. case GWD_CONFIGURE_LOG:
  183. case GWD_ANALYSIS_LOG:
  184. sAppend.LoadString(IDS_LOGFILE_DEFAULT);
  185. // fall through
  186. case GWD_OPEN_DATABASE:
  187. //
  188. // Used for open DB.
  189. //
  190. if (sAppend.IsEmpty())
  191. {
  192. sAppend.LoadString( IDS_DB_DEFAULT );
  193. } // else fell through
  194. //
  195. // Default directory for analysis.
  196. //
  197. pszPath = (LPTSTR)LocalAlloc( 0, (MAX_PATH + sAppend.GetLength() + 1) * sizeof(TCHAR));
  198. if (pszPath == NULL)
  199. return FALSE;
  200. if (SUCCEEDED(SHGetFolderPath(NULL, CSIDL_PERSONAL, NULL, 0, pszPath)))
  201. {
  202. lstrcpy( &(pszPath[lstrlen(pszPath)]), sAppend );
  203. //
  204. // Check to see if the directory does not exist, it may need
  205. // to be created if this is the first time this user has
  206. // opened a database.
  207. //
  208. TCHAR szTempFile[MAX_PATH];
  209. CString str;
  210. str.LoadString(IDS_TEMP_FILENAME);
  211. if (!GetTempFileName(pszPath,str,0,szTempFile))
  212. {
  213. if ((GetLastError() == ERROR_DIRECTORY) && (RecursiveCreateDirectory(pszPath)))
  214. {
  215. fRet = TRUE;
  216. }
  217. else
  218. {
  219. LocalFree(pszPath);
  220. fRet = FALSE;
  221. }
  222. }
  223. else
  224. {
  225. DeleteFile(szTempFile);
  226. fRet = TRUE;
  227. }
  228. }
  229. else
  230. {
  231. LocalFree(pszPath);
  232. pszPath = NULL;
  233. }
  234. break;
  235. case GWD_IMPORT_TEMPLATE:
  236. case GWD_EXPORT_TEMPLATE:
  237. sAppend.LoadString( IDS_DEFAULT_TEMPLATE_DIR );
  238. //
  239. // Default directory for analysis.
  240. //
  241. dwRet = GetSystemWindowsDirectory( NULL, 0);
  242. if (dwRet)
  243. {
  244. pszPath = (LPTSTR)LocalAlloc( 0, (dwRet + sAppend.GetLength() + 1) * sizeof(TCHAR));
  245. if (!pszPath)
  246. return FALSE;
  247. GetSystemWindowsDirectory( pszPath, dwRet + 1);
  248. lstrcpy( &(pszPath[lstrlen(pszPath)]), sAppend );
  249. i = lstrlen(pszPath);
  250. //
  251. // Make sure the user can write to this directory:
  252. //
  253. TCHAR szTempFile[MAX_PATH];
  254. HANDLE hTempFile=NULL;
  255. CString str;
  256. str.LoadString(IDS_TEMP_FILENAME);
  257. szTempFile[0] = L'\0';
  258. if (GetTempFileName(pszPath,str,0,szTempFile))
  259. {
  260. hTempFile = ExpandAndCreateFile(szTempFile,
  261. GENERIC_READ|GENERIC_WRITE,
  262. 0,
  263. NULL,
  264. CREATE_NEW,
  265. FILE_ATTRIBUTE_TEMPORARY,
  266. NULL);
  267. }
  268. if (hTempFile)
  269. {
  270. //
  271. // We have write access to this directory
  272. //
  273. ::CloseHandle(hTempFile);
  274. DeleteFile(szTempFile);
  275. fRet = TRUE;
  276. }
  277. else
  278. {
  279. //
  280. // We don't have write access to this directory. Find another
  281. // or we can't get a temp file name
  282. //
  283. LPTSTR szPath;
  284. LPITEMIDLIST pidl;
  285. LPMALLOC pMalloc;
  286. //
  287. // For some reason this won't compile with SHGetFolderPath()
  288. // Therefore go the long way around and deal with the pidl.
  289. //
  290. if (NOERROR == SHGetSpecialFolderLocation(m_hwndParent,CSIDL_PERSONAL,&pidl))
  291. {
  292. if (SHGetPathFromIDList(pidl,szTempFile))
  293. {
  294. szPath = (LPTSTR)LocalAlloc(LPTR, (lstrlen(szTempFile)+ 1) * sizeof(TCHAR));
  295. if (szPath)
  296. {
  297. //
  298. // If we can't create a new path then use the old one so the user
  299. // at least has a starting place to browse from
  300. //
  301. lstrcpy(szPath,szTempFile);
  302. LocalFree(pszPath);
  303. pszPath = szPath;
  304. fRet = TRUE;
  305. }
  306. }
  307. if (SUCCEEDED(SHGetMalloc(&pMalloc)))
  308. {
  309. pMalloc->Free(pidl);
  310. pMalloc->Release();
  311. }
  312. }
  313. //
  314. // If we can't write here the user will have to browse for something
  315. //
  316. }
  317. }
  318. break;
  319. }
  320. *pStr = pszPath;
  321. return fRet;
  322. }
  323. UINT_PTR CALLBACK OFNHookProc(
  324. HWND hdlg, // handle to child dialog box
  325. UINT uiMsg, // message identifier
  326. WPARAM wParam, // message parameter
  327. LPARAM lParam // message parameter
  328. )
  329. {
  330. if ( WM_NOTIFY == uiMsg )
  331. {
  332. OFNOTIFY* pOFNotify = (OFNOTIFY*) lParam;
  333. if ( pOFNotify && CDN_FILEOK == pOFNotify->hdr.code )
  334. {
  335. //
  336. // Don't accept filenames with DBCS characters that are greater then 255 in them
  337. //
  338. //Raid #263854, 4/3/2001
  339. BOOL ferr = TRUE;
  340. CString strErr;
  341. if(WideCharToMultiByte(CP_ACP, 0, pOFNotify->lpOFN->lpstrFile,
  342. -1, NULL, 0, NULL, &ferr))
  343. {
  344. return 0;
  345. }
  346. strErr.LoadString(IDS_NO_DBCS);
  347. strErr += L"\r\n\r\n";
  348. strErr += pOFNotify->lpOFN->lpstrFile;
  349. AfxMessageBox(strErr);
  350. ::SetWindowLongPtr(hdlg, DWLP_MSGRESULT, TRUE);
  351. return 1;
  352. }
  353. }
  354. return 0;
  355. }
  356. //+--------------------------------------------------------------------------
  357. //
  358. // Method: OnOpenDataBase()
  359. //
  360. // Synopsis: Picks a new database for SAV to work on
  361. //
  362. //---------------------------------------------------------------------------
  363. HRESULT
  364. CComponentDataImpl::OnOpenDataBase()
  365. {
  366. //
  367. // Find the desired new database
  368. //
  369. CString strDefExtension;
  370. CString strFilter;
  371. CString strOfnTitle;
  372. CString strDir;
  373. strDefExtension.LoadString(IDS_DEFAULT_DB_EXTENSION);
  374. strFilter.LoadString(IDS_DB_FILTER);
  375. strOfnTitle.LoadString(IDS_OPEN_DB_OFN_TITLE);
  376. LPTSTR pszDir = NULL;
  377. //
  378. // Build a working directory for this object,
  379. //
  380. if (GetWorkingDir( GWD_OPEN_DATABASE, &pszDir ) )
  381. {
  382. strDir = pszDir;
  383. LocalFree(pszDir);
  384. pszDir = NULL;
  385. }
  386. WCHAR szFile[MAX_PATH];
  387. ::ZeroMemory (szFile, MAX_PATH * sizeof(WCHAR));
  388. OPENFILENAME ofn;
  389. ::ZeroMemory (&ofn, sizeof (OPENFILENAME));
  390. ofn.lStructSize = sizeof (OPENFILENAME);
  391. ofn.hwndOwner = m_hwndParent;
  392. //HINSTANCE hInstance;
  393. // Translate filter into commdlg format (lots of \0)
  394. LPTSTR szFilter = strFilter.GetBuffer(0); // modify the buffer in place
  395. // MFC delimits with '|' not '\0'
  396. LPTSTR pch = szFilter;
  397. while ((pch = _tcschr(pch, '|')) != NULL)
  398. *pch++ = '\0';
  399. // do not call ReleaseBuffer() since the string contains '\0' characters
  400. ofn.lpstrFilter = szFilter;
  401. ofn.lpstrFile = szFile;
  402. ofn.nMaxFile = MAX_PATH * sizeof(WCHAR);
  403. ofn.lpstrInitialDir = (PCWSTR) strDir;
  404. ofn.lpstrTitle = strOfnTitle;
  405. ofn.Flags = OFN_HIDEREADONLY| // Don't show the read only prompt
  406. OFN_SHAREAWARE|
  407. OFN_NOREADONLYRETURN|
  408. OFN_EXPLORER | // Explorer style dialog;
  409. OFN_DONTADDTORECENT|
  410. OFN_ENABLEHOOK;
  411. ofn.lpstrDefExt = (PCWSTR) strDefExtension;
  412. ofn.lpfnHook = OFNHookProc;
  413. if ( GetOpenFileName (&ofn) )
  414. {
  415. //
  416. // Set the working directory of the database.
  417. //
  418. pszDir = szFile;
  419. GetWorkingDir( GWD_OPEN_DATABASE, &pszDir, TRUE, TRUE );
  420. if( IsSystemDatabase( ofn.lpstrFile /*fo.GetPathName()*/) )
  421. {
  422. AfxMessageBox( IDS_CANT_OPEN_SYSTEM_DB, MB_OK);
  423. return S_FALSE;
  424. }
  425. SadName = ofn.lpstrFile; //fo.GetPathName();
  426. SetErroredLogFile(NULL);
  427. //
  428. // If new database doesn't exist then ask for a configuration to import
  429. //
  430. DWORD dwAttr = GetFileAttributes(SadName);
  431. if (0xFFFFFFFF == dwAttr)
  432. {
  433. SCESTATUS sceStatus = SCESTATUS_SUCCESS;
  434. //
  435. // New database, so assign a configuration
  436. //
  437. if( OnAssignConfiguration( &sceStatus ) == S_FALSE)
  438. {
  439. //
  440. // If the user decides to cancel the import of a configuration, then,
  441. // we need to unload the sad information and display the correct
  442. // error message. Set the sad errored to PROFILE_NOT_FOUND so error,
  443. // is correct. There is no need to call LoadSadinfo.
  444. //
  445. UnloadSadInfo();
  446. if( sceStatus != SCESTATUS_SUCCESS )
  447. SadErrored = sceStatus;
  448. else
  449. SadErrored = SCESTATUS_PROFILE_NOT_FOUND;
  450. if(m_AnalFolder)
  451. {
  452. m_pConsole->SelectScopeItem(m_AnalFolder->GetScopeItem()->ID);
  453. }
  454. return S_OK;
  455. }
  456. }
  457. //
  458. // Invalidiate currently open database
  459. //
  460. RefreshSadInfo();
  461. return S_OK;
  462. }
  463. else
  464. {
  465. DWORD dwErr = CommDlgExtendedError();
  466. }
  467. return S_FALSE;
  468. }
  469. //+--------------------------------------------------------------------------
  470. //
  471. // Method: OnNewDataBase()
  472. //
  473. // Synopsis: Picks a new database for SAV to work on
  474. //
  475. //---------------------------------------------------------------------------
  476. HRESULT
  477. CComponentDataImpl::OnNewDatabase()
  478. {
  479. //
  480. // Find the desired new database
  481. //
  482. CString strDefExtension;
  483. CString strFilter;
  484. CString strOfnTitle;
  485. CWnd cwndParent;
  486. strDefExtension.LoadString(IDS_DEFAULT_DB_EXTENSION);
  487. strFilter.LoadString(IDS_DB_FILTER);
  488. strOfnTitle.LoadString(IDS_NEW_DB_OFN_TITLE);
  489. // Translate filter into commdlg format (lots of \0)
  490. LPTSTR szFilter = strFilter.GetBuffer(0); // modify the buffer in place
  491. LPTSTR pch = szFilter;
  492. // MFC delimits with '|' not '\0'
  493. while ((pch = _tcschr(pch, '|')) != NULL)
  494. *pch++ = '\0';
  495. // do not call ReleaseBuffer() since the string contains '\0' characters
  496. OPENFILENAME ofn;
  497. ::ZeroMemory (&ofn, sizeof (OPENFILENAME));
  498. ofn.lStructSize = sizeof(OPENFILENAME);
  499. ofn.lpstrFilter = szFilter;
  500. ofn.lpstrFile = SadName.GetBuffer(MAX_PATH);
  501. ofn.nMaxFile = MAX_PATH;
  502. ofn.lpstrDefExt = strDefExtension,
  503. ofn.hwndOwner = m_hwndParent;
  504. ofn.Flags = OFN_HIDEREADONLY |
  505. OFN_SHAREAWARE |
  506. OFN_EXPLORER |
  507. OFN_DONTADDTORECENT;
  508. ofn.lpstrTitle = strOfnTitle;
  509. if (GetOpenFileName(&ofn))
  510. {
  511. PVOID pHandle = NULL;
  512. SadName.ReleaseBuffer();
  513. //
  514. // If new database doesn't exist then ask for a configuration to import
  515. //
  516. DWORD dwAttr = GetFileAttributes(SadName);
  517. if (0xFFFFFFFF == dwAttr)
  518. {
  519. //
  520. // New database, so assign a configuration
  521. //
  522. SCESTATUS sceStatus;
  523. OnAssignConfiguration(&sceStatus);
  524. }
  525. //
  526. // Invalidiate currently open database
  527. //
  528. SetErroredLogFile(NULL);
  529. RefreshSadInfo();
  530. return S_OK;
  531. }
  532. return S_FALSE;
  533. }
  534. //+--------------------------------------------------------------------------
  535. //
  536. // Method: OnAssignConfiguration()
  537. //
  538. // Synopsis: Assigns a configuration template to SAV's currently selected
  539. // database
  540. //
  541. //---------------------------------------------------------------------------
  542. HRESULT
  543. CComponentDataImpl::OnAssignConfiguration( SCESTATUS *pSceStatus )
  544. {
  545. //
  546. //Currently pSceStatus is only used for passing back the error
  547. //when user presses cancel on select template diaglog.
  548. //
  549. // Find the desired new database
  550. //
  551. CString strDefExtension; // Default extension
  552. CString strCurFile;
  553. CString strFilter; // Extension filter
  554. CString strOfnTitle;
  555. CWnd cwndParent;
  556. BOOL bIncremental;
  557. SCESTATUS status;
  558. HKEY hKey; // HKEY of TemplateUsed.
  559. DWORD dwBufSize = 0; // Size of szTemplateUsed in bytes
  560. DWORD dwType = 0; // Type of registry item, return by query
  561. DWORD dwStatus;
  562. *pSceStatus = 0;
  563. //
  564. // Display a warning and give a chance to cancel
  565. // if they try to configure a non-system database
  566. //
  567. if (IsSystemDatabase(SadName))
  568. {
  569. BOOL bImportAnyway;
  570. bImportAnyway = AfxMessageBox(IDS_IMPORT_WARNING,MB_OKCANCEL);
  571. if (IDCANCEL == bImportAnyway)
  572. {
  573. return S_FALSE;
  574. }
  575. }
  576. strDefExtension.LoadString(IDS_PROFILE_DEF_EXT);
  577. strFilter.LoadString(IDS_PROFILE_FILTER);
  578. strOfnTitle.LoadString(IDS_ASSIGN_CONFIG_OFN_TITLE);
  579. //
  580. // Get the last directory used by templates.
  581. //
  582. LPTSTR pszDir = NULL;
  583. if(strCurFile.IsEmpty())
  584. {
  585. if (GetWorkingDir( GWD_EXPORT_TEMPLATE, &pszDir ) )
  586. {
  587. strCurFile = pszDir;
  588. LocalFree(pszDir);
  589. pszDir = NULL;
  590. }
  591. }
  592. strCurFile += TEXT("\\*.");
  593. strCurFile += strDefExtension;
  594. cwndParent.Attach(m_hwndParent);
  595. CAssignConfiguration ac(TRUE, // File Open, not file save
  596. strDefExtension, // Default Extension
  597. strCurFile, // Initial File Name == current DB
  598. OFN_HIDEREADONLY| // Don't show the read only prompt
  599. OFN_EXPLORER| // Explorer style dialog
  600. OFN_ENABLETEMPLATE| // custom template
  601. OFN_SHAREAWARE| // We're not going to need exclusive
  602. OFN_DONTADDTORECENT|
  603. OFN_PATHMUSTEXIST, // The Template must exist for us to assign it.
  604. strFilter, // Filter for allowed extensions
  605. &cwndParent); // Dialog's Parent window
  606. cwndParent.Detach();
  607. ac.m_ofn.lpstrTitle = strOfnTitle.GetBuffer(1);
  608. ac.m_ofn.lpTemplateName = MAKEINTRESOURCE(IDD_ASSIGN_CONFIG_CHECK);
  609. if (IDOK == ac.DoModal())
  610. {
  611. CThemeContextActivator activator;
  612. strCurFile = ac.GetPathName();
  613. bIncremental = ac.m_bIncremental;
  614. //
  615. // Set the working dir to this file.
  616. //
  617. pszDir = strCurFile.GetBuffer(0);
  618. GetWorkingDir( GWD_IMPORT_TEMPLATE, &pszDir, TRUE, TRUE);
  619. strCurFile.ReleaseBuffer();
  620. CWaitCursor wc;
  621. //
  622. // Unload the sad info before we choose to do an import.
  623. //
  624. UnloadSadInfo();
  625. status = AssignTemplate(
  626. strCurFile.IsEmpty() ? NULL:(LPCTSTR)strCurFile,
  627. SadName,
  628. bIncremental
  629. );
  630. if (SCESTATUS_SUCCESS != status)
  631. {
  632. CString strErr;
  633. MyFormatResMessage(status,IDS_IMPORT_FAILED,NULL,strErr);
  634. AfxMessageBox(strErr);
  635. //
  636. // We don't know if the database is still OK to read so open it anyways.
  637. //
  638. LoadSadInfo(TRUE);
  639. if( SCESTATUS_SPECIAL_ACCOUNT == SadErrored ) //Raid #589139,XPSP1 DCR, yanggao, 4/12/2002.
  640. *pSceStatus = SadErrored;
  641. return S_FALSE;
  642. }
  643. RefreshSadInfo();
  644. return S_OK;
  645. }
  646. *pSceStatus = SCESTATUS_NO_TEMPLATE_GIVEN;
  647. return S_FALSE;
  648. }
  649. //+--------------------------------------------------------------------------
  650. //
  651. // Method: OnSecureWizard()
  652. //
  653. // Synopsis: Launch the secure wizard (registered)
  654. //
  655. //---------------------------------------------------------------------------
  656. HRESULT
  657. CComponentDataImpl::OnSecureWizard()
  658. {
  659. HRESULT hr=S_FALSE;
  660. PWSTR pstrWizardName=NULL;
  661. if ( GetSecureWizardName(&pstrWizardName, NULL) )
  662. {
  663. PROCESS_INFORMATION ProcInfo;
  664. STARTUPINFO StartInfo;
  665. BOOL fOk;
  666. RtlZeroMemory(&StartInfo,sizeof(StartInfo));
  667. StartInfo.cb = sizeof(StartInfo);
  668. StartInfo.dwFlags = STARTF_USESHOWWINDOW;
  669. StartInfo.wShowWindow = (WORD)SW_SHOWNORMAL;
  670. fOk = CreateProcess(pstrWizardName, NULL,
  671. NULL, NULL, FALSE,
  672. 0,
  673. NULL,
  674. NULL,
  675. &StartInfo,
  676. &ProcInfo
  677. );
  678. if ( fOk )
  679. {
  680. ::CloseHandle(ProcInfo.hProcess);
  681. ::CloseHandle(ProcInfo.hThread);
  682. hr = S_OK;
  683. }
  684. LocalFree(pstrWizardName);
  685. }
  686. return hr;
  687. }
  688. //+--------------------------------------------------------------------------
  689. //
  690. // Method: OnSaveConfiguration()
  691. //
  692. // Synopsis: Saves the assigned computer template to an INF file
  693. //
  694. //---------------------------------------------------------------------------
  695. HRESULT
  696. CComponentDataImpl::OnSaveConfiguration()
  697. {
  698. //
  699. // Find the desired new database
  700. //
  701. CString strDefExtension;
  702. CString strFilter;
  703. CWnd cwndParent;
  704. CString strDefName;
  705. CString strName;
  706. SCESTATUS status = SCESTATUS_SUCCESS;
  707. CString strOfnTitle;
  708. strDefExtension.LoadString(IDS_PROFILE_DEF_EXT);
  709. strFilter.LoadString(IDS_PROFILE_FILTER);
  710. strOfnTitle.LoadString(IDS_EXPORT_CONFIG_OFN_TITLE);
  711. //
  712. // Get the working directory for INF files.
  713. //
  714. LPTSTR pszDir = NULL;
  715. if( GetWorkingDir( GWD_EXPORT_TEMPLATE, &pszDir ) )
  716. {
  717. strDefName = pszDir;
  718. LocalFree(pszDir);
  719. pszDir = NULL;
  720. }
  721. strDefName += TEXT("\\*.");
  722. strDefName += strDefExtension;
  723. // Translate filter into commdlg format (lots of \0)
  724. LPTSTR szFilter = strFilter.GetBuffer(0); // modify the buffer in place
  725. LPTSTR pch = szFilter;
  726. // MFC delimits with '|' not '\0'
  727. while ((pch = _tcschr(pch, '|')) != NULL)
  728. *pch++ = '\0';
  729. // do not call ReleaseBuffer() since the string contains '\0' characters
  730. OPENFILENAME ofn;
  731. ::ZeroMemory (&ofn, sizeof (OPENFILENAME));
  732. ofn.lStructSize = sizeof(OPENFILENAME);
  733. ofn.lpstrFilter = szFilter;
  734. ofn.lpstrFile = strDefName.GetBuffer(MAX_PATH),
  735. ofn.nMaxFile = MAX_PATH;
  736. ofn.lpstrDefExt = strDefExtension,
  737. ofn.hwndOwner = m_hwndParent;
  738. ofn.Flags = OFN_HIDEREADONLY |
  739. OFN_SHAREAWARE |
  740. OFN_EXPLORER |
  741. OFN_DONTADDTORECENT;
  742. ofn.lpstrTitle = strOfnTitle;
  743. if (GetSaveFileName(&ofn))
  744. {
  745. strDefName.ReleaseBuffer();
  746. strName = ofn.lpstrFile;
  747. //
  748. // Set the working directory for inf files.
  749. //
  750. pszDir = strName.GetBuffer(0);
  751. GetWorkingDir( GWD_EXPORT_TEMPLATE, &pszDir, TRUE, TRUE );
  752. strName.ReleaseBuffer();
  753. //
  754. // Generate new inf file
  755. //
  756. status = SceCopyBaseProfile(GetSadHandle(),
  757. SCE_ENGINE_SCP,
  758. (LPTSTR)(LPCTSTR)strName,
  759. AREA_ALL,
  760. NULL );
  761. if (SCESTATUS_SUCCESS != status)
  762. {
  763. CString str;
  764. CString strErr;
  765. GetSceStatusString(status, &strErr);
  766. AfxFormatString2(str,IDS_EXPORT_FAILED,strName,strErr);
  767. AfxMessageBox(str);
  768. return S_FALSE;
  769. }
  770. return S_OK;
  771. }
  772. return S_FALSE;
  773. }
  774. //+--------------------------------------------------------------------------
  775. //
  776. // Method: OnExportPolicy()
  777. //
  778. // Synopsis: This function exports either the effective or local table
  779. // from the system security database to a file.
  780. //
  781. // The function asks the user for a file through the CFileOpen
  782. // class, then writes out the contents of either the effective
  783. // or local policy table in the system database.
  784. //
  785. // Arguments: [bEffective] - Either to export the effect or local table.
  786. //
  787. // Returns: S_OK - if everything went well.
  788. // S_FALSE - something failed.
  789. //---------------------------------------------------------------------------
  790. HRESULT
  791. CComponentDataImpl::OnExportPolicy( BOOL bEffective )
  792. {
  793. CString strDefExtension;
  794. CString strFilter;
  795. CString strOfnTitle;
  796. CString strDefName;
  797. CString strName;
  798. DWORD dwErr = 0;
  799. BOOL bCopySuccess = FALSE;
  800. strDefExtension.LoadString(IDS_PROFILE_DEF_EXT);
  801. strFilter.LoadString(IDS_PROFILE_FILTER);
  802. strOfnTitle.LoadString(IDS_EXPORT_POLICY_OFN_TITLE);
  803. //
  804. // Get the working directory for locations.
  805. //
  806. LPTSTR pszDir = NULL;
  807. if( GetWorkingDir( GWD_EXPORT_TEMPLATE, &pszDir ) )
  808. {
  809. strDefName = pszDir;
  810. LocalFree(pszDir);
  811. pszDir = NULL;
  812. }
  813. strDefName += TEXT("\\*.");
  814. strDefName += strDefExtension;
  815. // Translate filter into commdlg format (lots of \0)
  816. LPTSTR szFilter = strFilter.GetBuffer(0); // modify the buffer in place
  817. LPTSTR pch = szFilter;
  818. // MFC delimits with '|' not '\0'
  819. while ((pch = _tcschr(pch, '|')) != NULL)
  820. *pch++ = '\0';
  821. // do not call ReleaseBuffer() since the string contains '\0' characters
  822. OPENFILENAME ofn;
  823. ::ZeroMemory (&ofn, sizeof (OPENFILENAME));
  824. ofn.lStructSize = sizeof(OPENFILENAME);
  825. ofn.lpstrFilter = szFilter;
  826. ofn.lpstrFile = strDefName.GetBuffer(MAX_PATH),
  827. ofn.nMaxFile = MAX_PATH;
  828. ofn.lpstrDefExt = strDefExtension,
  829. ofn.hwndOwner = m_hwndParent;
  830. ofn.Flags = OFN_HIDEREADONLY |
  831. OFN_SHAREAWARE |
  832. OFN_EXPLORER |
  833. OFN_DONTADDTORECENT;
  834. ofn.lpstrTitle = strOfnTitle;
  835. if (GetSaveFileName(&ofn))
  836. {
  837. strDefName.ReleaseBuffer();
  838. strName = ofn.lpstrFile;
  839. //
  840. // Set the working directory for locations.
  841. //
  842. pszDir = strName.GetBuffer(0);
  843. GetWorkingDir( GWD_EXPORT_TEMPLATE, &pszDir, TRUE, TRUE );
  844. strName.ReleaseBuffer();
  845. //
  846. // Make sure we can make the file.
  847. //
  848. DWORD dwErr = FileCreateError( strName, 0 );
  849. if(dwErr == IDNO)
  850. {
  851. return S_FALSE;
  852. }
  853. //
  854. // Generate the template
  855. //
  856. SCESTATUS sceStatus;
  857. CWaitCursor wc;
  858. sceStatus = SceSetupGenerateTemplate(
  859. NULL, // Computer name
  860. NULL, // The system database
  861. bEffective, // For right now just the Local Pol table.
  862. strName.GetBuffer(0),
  863. NULL,
  864. AREA_ALL
  865. );
  866. strName.ReleaseBuffer();
  867. if(sceStatus != SCESTATUS_SUCCESS)
  868. {
  869. //
  870. // Display the error message
  871. //
  872. DWORD dwError = SceStatusToDosError( sceStatus );
  873. CString strErr;
  874. MyFormatMessage( sceStatus, NULL, NULL, strErr );
  875. strErr += strName;
  876. AfxMessageBox( strErr, MB_ICONEXCLAMATION | MB_OK );
  877. return S_FALSE;
  878. }
  879. return S_OK;
  880. }
  881. return S_FALSE;
  882. }
  883. //+--------------------------------------------------------------------------------------------
  884. // CComponentDataImpl::OnImportPolicy
  885. //
  886. // Import policy opens a file open dialog box in which the user is allowed to choose
  887. // a security configuration INF file to import into security policy.
  888. //
  889. //
  890. // Arguments: [pDataObject] - The data object associated with the folder calling
  891. // this function.
  892. // Returns: S_OK - Import was successful.
  893. // S_FALSE - Something went wrong.
  894. //---------------------------------------------------------------------------------------------
  895. HRESULT
  896. CComponentDataImpl::OnImportPolicy(LPDATAOBJECT pDataObject)
  897. {
  898. CEditTemplate *pet = NULL;
  899. CString strDefExtension;
  900. CString strFilter;
  901. CString strOfnTitle;
  902. CWnd cwndParent;
  903. CString strDefName;
  904. CString strName;
  905. strDefExtension.LoadString(IDS_PROFILE_DEF_EXT);
  906. strFilter.LoadString(IDS_PROFILE_FILTER);
  907. strOfnTitle.LoadString(IDS_IMPORT_POLICY_OFN_TITLE);
  908. LPTSTR pszDir = NULL;
  909. if( GetWorkingDir( GWD_IMPORT_TEMPLATE, &pszDir ) )
  910. {
  911. strDefName = pszDir;
  912. LocalFree(pszDir);
  913. pszDir = NULL;
  914. }
  915. strDefName += TEXT("\\*.");
  916. strDefName += strDefExtension;
  917. cwndParent.Attach(m_hwndParent);
  918. CAssignConfiguration fo(TRUE, // File open
  919. strDefExtension, // Default Extension
  920. strDefName, // Initial File Name == current DB
  921. OFN_HIDEREADONLY| // Don't show the read only prompt
  922. OFN_SHAREAWARE|
  923. OFN_EXPLORER| // Explorer style dialog
  924. OFN_ENABLETEMPLATE| // custom template
  925. OFN_DONTADDTORECENT|
  926. OFN_PATHMUSTEXIST, // The Template must exist for us to assign it.
  927. strFilter, // Filter for allowed extensions
  928. &cwndParent); // Dialog's Parent window
  929. cwndParent.Detach();
  930. fo.m_ofn.lpstrTitle = strOfnTitle.GetBuffer(1);
  931. fo.m_ofn.lpTemplateName = MAKEINTRESOURCE(IDD_ASSIGN_CONFIG_CHECK);
  932. CThemeContextActivator activator;
  933. if (IDOK == fo.DoModal())
  934. {
  935. PVOID pHandle = NULL;
  936. BOOL bIncremental = fo.m_bIncremental;
  937. strName = fo.GetPathName();
  938. pszDir = strName.GetBuffer(0);
  939. GetWorkingDir( GWD_IMPORT_TEMPLATE, &pszDir, TRUE, TRUE );
  940. strName.ReleaseBuffer();
  941. CWaitCursor wc;
  942. CEditTemplate *pet;
  943. //
  944. // pet will be freed in m_Templates in DeleteTemplate
  945. //
  946. pet = GetTemplate(strName,AREA_ALL);
  947. CString strErr;
  948. CString strSCE;
  949. int ret=0;
  950. if ( pet == NULL )
  951. {
  952. //
  953. // this is an invalid template or something is wrong reading the data out
  954. //
  955. strSCE.LoadString(IDS_EXTENSION_NAME);
  956. strErr.Format(IDS_IMPORT_POLICY_INVALID,strName);
  957. m_pConsole->MessageBox(strErr,strSCE,MB_OK,&ret);
  958. return S_FALSE;
  959. }
  960. else
  961. {
  962. if ( ( bIncremental &&
  963. (SCESTATUS_SUCCESS != SceAppendSecurityProfileInfo(m_szSingleTemplateName,
  964. AREA_ALL,
  965. pet->pTemplate,
  966. NULL))) ||
  967. (!bIncremental && !CopyFile(strName,m_szSingleTemplateName,FALSE) ) )
  968. {
  969. //
  970. // Import Failed
  971. //
  972. strSCE.LoadString(IDS_EXTENSION_NAME);
  973. strErr.Format(IDS_IMPORT_POLICY_FAIL,strName);
  974. m_pConsole->MessageBox(strErr,strSCE,MB_OK,&ret);
  975. DeleteTemplate(strName);
  976. return S_FALSE;
  977. }
  978. DeleteTemplate(strName);
  979. }
  980. DeleteTemplate(m_szSingleTemplateName);
  981. //
  982. // Update the window.
  983. //
  984. pet = GetTemplate(m_szSingleTemplateName);
  985. if(pet)
  986. {
  987. DWORD dwErr = pet->RefreshTemplate();
  988. if ( 0 != dwErr )
  989. {
  990. CString strErr;
  991. MyFormatResMessage (SCESTATUS_SUCCESS, dwErr, NULL, strErr);
  992. AfxMessageBox(strErr);
  993. return S_FALSE;
  994. }
  995. }
  996. RefreshAllFolders();
  997. return S_OK;
  998. }
  999. return S_FALSE;
  1000. }
  1001. //+--------------------------------------------------------------------------------------------
  1002. // CComponentDataImpl::OnImportLocalPolicy
  1003. //
  1004. // Import policy opens a file open dialog box in which the user is allowed to choose
  1005. // a security configuration INF file to import into local policy.
  1006. //
  1007. // The function asks for the file name then calls SceConfigureSystem() with the
  1008. // SCE_NO_CONFIG option. This imports the specifide file into the local policy
  1009. // database.
  1010. //
  1011. // After the database is updated, we refresh the local policy template held in memory.
  1012. //
  1013. // Arguments: [pDataObject] - The data object associated with the folder calling
  1014. // this function.
  1015. // Returns: S_OK - Import was successful.
  1016. // S_FALSE - Something went wrong.
  1017. //---------------------------------------------------------------------------------------------
  1018. HRESULT
  1019. CComponentDataImpl::OnImportLocalPolicy(LPDATAOBJECT pDataObject)
  1020. {
  1021. CString strDefExtension;
  1022. CString strFilter;
  1023. CString strOfnTitle;
  1024. CString strDefName;
  1025. CString strName;
  1026. DWORD dwErr = 0;
  1027. SCESTATUS sceStatus = SCESTATUS_SUCCESS;
  1028. CString strErr;
  1029. CString strY;
  1030. strDefExtension.LoadString(IDS_PROFILE_DEF_EXT);
  1031. strFilter.LoadString(IDS_PROFILE_FILTER);
  1032. strOfnTitle.LoadString(IDS_IMPORT_POLICY_OFN_TITLE);
  1033. // Translate filter into commdlg format (lots of \0)
  1034. LPTSTR szFilter = strFilter.GetBuffer(0); // modify the buffer in place
  1035. LPTSTR pch = szFilter;
  1036. // MFC delimits with '|' not '\0'
  1037. while ((pch = _tcschr(pch, TEXT('|'))) != NULL)
  1038. *pch++ = TEXT('\0');
  1039. // do not call ReleaseBuffer() since the string contains '\0' characters
  1040. LPTSTR pszDir = NULL;
  1041. if( GetWorkingDir( GWD_IMPORT_TEMPLATE, &pszDir ) )
  1042. {
  1043. strDefName = pszDir;
  1044. LocalFree(pszDir);
  1045. pszDir = NULL;
  1046. }
  1047. strDefName += TEXT("\\*.");
  1048. strDefName += strDefExtension;
  1049. OPENFILENAME ofn;
  1050. ::ZeroMemory (&ofn, sizeof (OPENFILENAME));
  1051. ofn.lStructSize = sizeof(OPENFILENAME);
  1052. ofn.lpstrFilter = szFilter;
  1053. ofn.lpstrFile = strDefName.GetBuffer(MAX_PATH),
  1054. ofn.nMaxFile = MAX_PATH;
  1055. ofn.lpstrDefExt = strDefExtension,
  1056. ofn.hwndOwner = m_hwndParent;
  1057. ofn.Flags = OFN_HIDEREADONLY |
  1058. OFN_SHAREAWARE |
  1059. OFN_EXPLORER |
  1060. OFN_DONTADDTORECENT;
  1061. ofn.lpstrTitle = strOfnTitle;
  1062. if (GetOpenFileName(&ofn))
  1063. {
  1064. PVOID pHandle = NULL;
  1065. strName = ofn.lpstrFile;
  1066. pszDir = strName.GetBuffer(0);
  1067. GetWorkingDir( GWD_IMPORT_TEMPLATE, &pszDir, TRUE, TRUE );
  1068. strName.ReleaseBuffer();
  1069. CWaitCursor wc;
  1070. CEditTemplate *pet;
  1071. pet = GetTemplate(strName,AREA_SECURITY_POLICY|AREA_PRIVILEGES);
  1072. if (!pet)
  1073. {
  1074. goto ret_error;
  1075. }
  1076. //
  1077. // We're going to alter this one so make sure it doesn't save out
  1078. //
  1079. pet->SetNoSave(TRUE);
  1080. //
  1081. // Remove entries that are set by domain policy since they'll be overwritten
  1082. // anyway and we don't allow setting things that'll be overwritten.
  1083. //
  1084. RemovePolicyEntries(pet);
  1085. //
  1086. // 120502 - SceUpdateSecurityProfile doesn't work with SCE_STRUCT_INF,
  1087. // but the AREA_SECURITY_POLICY and AREA_PRIVILEGES sections are
  1088. // compatable so we can call it SCE_ENGINE_SYSTEM, which will work.
  1089. //
  1090. SCETYPE origType = pet->pTemplate->Type;
  1091. pet->pTemplate->Type = SCE_ENGINE_SYSTEM;
  1092. sceStatus = SceUpdateSecurityProfile(NULL,
  1093. AREA_SECURITY_POLICY|AREA_PRIVILEGES,
  1094. pet->pTemplate,
  1095. SCE_UPDATE_SYSTEM
  1096. );
  1097. //
  1098. // Set the type back so the engine knows how to delete it properly
  1099. //
  1100. pet->pTemplate->Type = origType;
  1101. if (SCESTATUS_SUCCESS != sceStatus)
  1102. {
  1103. goto ret_error;
  1104. }
  1105. //
  1106. // Update the window.
  1107. //
  1108. pet = GetTemplate(GT_LOCAL_POLICY);
  1109. if(pet)
  1110. {
  1111. DWORD dwErr = pet->RefreshTemplate();
  1112. if ( 0 != dwErr )
  1113. {
  1114. CString strErr;
  1115. MyFormatResMessage (SCESTATUS_SUCCESS, dwErr, NULL, strErr);
  1116. AfxMessageBox(strErr);
  1117. return S_FALSE;
  1118. }
  1119. }
  1120. RefreshAllFolders();
  1121. return S_OK;
  1122. }
  1123. strDefName.ReleaseBuffer();
  1124. return S_FALSE;
  1125. ret_error:
  1126. strDefName.ReleaseBuffer();
  1127. MyFormatMessage( sceStatus, NULL, NULL, strErr);
  1128. strErr += strName;
  1129. strErr += L"\n";
  1130. strErr += strY;
  1131. AfxMessageBox( strErr, MB_OK);
  1132. return S_FALSE;
  1133. }
  1134. HRESULT
  1135. CComponentDataImpl::OnAnalyze()
  1136. {
  1137. PEDITTEMPLATE pet;
  1138. //
  1139. // If the computer template has been changed then save it before
  1140. // we can inspect against it
  1141. //
  1142. pet = GetTemplate(GT_COMPUTER_TEMPLATE);
  1143. if (pet && pet->IsDirty())
  1144. {
  1145. pet->Save();
  1146. }
  1147. m_pUIThread->PostThreadMessage(SCEM_ANALYZE_PROFILE,(WPARAM)(LPCTSTR)SadName,(LPARAM)this);
  1148. return S_OK;
  1149. }
  1150. BOOL
  1151. CComponentDataImpl::RemovePolicyEntries(PEDITTEMPLATE pet)
  1152. {
  1153. PEDITTEMPLATE petPol = GetTemplate(GT_EFFECTIVE_POLICY);
  1154. if (!petPol)
  1155. {
  1156. return FALSE;
  1157. }
  1158. #define CD(X) if (petPol->pTemplate->X != SCE_NO_VALUE) { pet->pTemplate->X = SCE_NO_VALUE; };
  1159. CD(MinimumPasswordAge);
  1160. CD(MaximumPasswordAge);
  1161. CD(MinimumPasswordLength);
  1162. CD(PasswordComplexity);
  1163. CD(PasswordHistorySize);
  1164. CD(LockoutBadCount);
  1165. CD(ResetLockoutCount);
  1166. CD(LockoutDuration);
  1167. CD(RequireLogonToChangePassword);
  1168. CD(ForceLogoffWhenHourExpire);
  1169. CD(EnableAdminAccount);
  1170. CD(EnableGuestAccount);
  1171. // These members aren't declared in NT4
  1172. CD(ClearTextPassword);
  1173. CD(AuditDSAccess);
  1174. CD(AuditAccountLogon);
  1175. CD(LSAAnonymousNameLookup);
  1176. CD(MaximumLogSize[0]);
  1177. CD(MaximumLogSize[1]);
  1178. CD(MaximumLogSize[2]);
  1179. CD(AuditLogRetentionPeriod[0]);
  1180. CD(AuditLogRetentionPeriod[1]);
  1181. CD(AuditLogRetentionPeriod[2]);
  1182. CD(RetentionDays[0]);
  1183. CD(RetentionDays[1]);
  1184. CD(RetentionDays[2]);
  1185. CD(RestrictGuestAccess[0]);
  1186. CD(RestrictGuestAccess[1]);
  1187. CD(RestrictGuestAccess[2]);
  1188. CD(AuditSystemEvents);
  1189. CD(AuditLogonEvents);
  1190. CD(AuditObjectAccess);
  1191. CD(AuditPrivilegeUse);
  1192. CD(AuditPolicyChange);
  1193. CD(AuditAccountManage);
  1194. CD(AuditProcessTracking);
  1195. //
  1196. // These two are strings rather than DWORDs
  1197. //
  1198. if (petPol->pTemplate->NewAdministratorName && pet->pTemplate->NewAdministratorName)
  1199. {
  1200. LocalFree(pet->pTemplate->NewAdministratorName);
  1201. pet->pTemplate->NewAdministratorName = NULL;
  1202. }
  1203. if (petPol->pTemplate->NewGuestName && pet->pTemplate->NewGuestName)
  1204. {
  1205. LocalFree(pet->pTemplate->NewGuestName);
  1206. pet->pTemplate->NewGuestName = NULL;
  1207. }
  1208. #undef CD
  1209. //
  1210. // Clear privileges set in PetPol out of pet
  1211. //
  1212. SCE_PRIVILEGE_ASSIGNMENT *ppaPet = pet->pTemplate->OtherInfo.smp.pPrivilegeAssignedTo;
  1213. SCE_PRIVILEGE_ASSIGNMENT *ppaPol = petPol->pTemplate->OtherInfo.smp.pPrivilegeAssignedTo;
  1214. SCE_PRIVILEGE_ASSIGNMENT *ppaLast = NULL;
  1215. for(SCE_PRIVILEGE_ASSIGNMENT *ppa = ppaPol; ppa != NULL ; ppa = ppa->Next)
  1216. {
  1217. for (SCE_PRIVILEGE_ASSIGNMENT *ppa2 = ppaPet;
  1218. ppa2 != NULL;
  1219. ppaLast = ppa2, ppa2 = ppa2->Next) {
  1220. if (0 == lstrcmpi(ppa->Name,ppa2->Name))
  1221. {
  1222. if (ppaLast)
  1223. {
  1224. ppaLast->Next = ppa2->Next;
  1225. }
  1226. else
  1227. {
  1228. // Front of list
  1229. ppaPet = ppa2->Next;
  1230. }
  1231. ppa2->Next = NULL;
  1232. SceFreeMemory(ppa2,SCE_STRUCT_PRIVILEGE);
  1233. ppa2 = ppaLast;
  1234. //
  1235. // Found it, so don't bother checking the rest
  1236. //
  1237. break;
  1238. }
  1239. }
  1240. }
  1241. //
  1242. // Clear reg values set in PetPol out of pet
  1243. //
  1244. SCE_REGISTRY_VALUE_INFO *rvPet = pet->pTemplate->aRegValues;
  1245. SCE_REGISTRY_VALUE_INFO *rvPol = petPol->pTemplate->aRegValues;
  1246. for(DWORD i=0;i< petPol->pTemplate->RegValueCount;i++)
  1247. {
  1248. for (DWORD j=0;j<pet->pTemplate->RegValueCount;j++)
  1249. {
  1250. if (0 == lstrcmpi(rvPol[i].FullValueName,rvPet[j].FullValueName))
  1251. {
  1252. // Match. Delete Value from pet
  1253. if (rvPet[j].Value)
  1254. {
  1255. LocalFree(rvPet[j].Value);
  1256. rvPet[j].Value = NULL;
  1257. }
  1258. //
  1259. // Found it, so don't bother checking rest
  1260. //
  1261. break;
  1262. }
  1263. }
  1264. }
  1265. return TRUE;
  1266. }