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.

577 lines
18 KiB

  1. //+--------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1994 - 2001.
  5. //
  6. // File: copyutil.cpp
  7. //
  8. // Contents: Utility routines for copying SCE sections to the clipboard
  9. //
  10. // HISTORY: 10-Nov-97 robcap Created
  11. //
  12. //---------------------------------------------------------------------------
  13. #include "stdafx.h"
  14. #include "snapmgr.h"
  15. #include "wrapper.h"
  16. #include "util.h"
  17. #include <secedit.h>
  18. //+--------------------------------------------------------------------------
  19. //
  20. // Method: GetFolderCopyPasteInfo
  21. //
  22. // Synopsis: Finds the SCE area and clipboard format that correspond
  23. // to the folder type given in [Folder]
  24. //
  25. // Arguments: [Folder] - the folder type to find the area and cf for
  26. // [*Area] - output only
  27. // [*cf] - output only
  28. //
  29. // Returns: *[Area] - the SCE area that corresponds to [Folder]
  30. // *[cf] - the clipboard format that corresponds to [Folder]
  31. //
  32. //
  33. // History: 10-Nov-1997 RobCap created
  34. //
  35. //---------------------------------------------------------------------------
  36. BOOL
  37. CComponentDataImpl::GetFolderCopyPasteInfo(FOLDER_TYPES Folder, // In
  38. AREA_INFORMATION *Area, // Out
  39. UINT *cf) { // Out
  40. switch (Folder) {
  41. case POLICY_ACCOUNT:
  42. case POLICY_PASSWORD:
  43. case POLICY_KERBEROS:
  44. case POLICY_LOCKOUT:
  45. case POLICY_AUDIT:
  46. *Area = AREA_SECURITY_POLICY;
  47. *cf = cfSceAccountArea;
  48. break;
  49. case POLICY_LOCAL:
  50. case POLICY_OTHER:
  51. case AREA_PRIVILEGE:
  52. *Area = AREA_SECURITY_POLICY | AREA_PRIVILEGES;
  53. *cf = cfSceLocalArea;
  54. break;
  55. case POLICY_EVENTLOG:
  56. case POLICY_LOG:
  57. *Area = AREA_SECURITY_POLICY;
  58. *cf = cfSceEventLogArea;
  59. break;
  60. case AREA_GROUPS:
  61. *Area = AREA_GROUP_MEMBERSHIP;
  62. *cf = cfSceGroupsArea;
  63. break;
  64. case AREA_SERVICE:
  65. *Area = AREA_SYSTEM_SERVICE;
  66. *cf = cfSceServiceArea;
  67. break;
  68. case AREA_REGISTRY:
  69. *Area = AREA_REGISTRY_SECURITY;
  70. *cf = cfSceRegistryArea;
  71. break;
  72. case AREA_FILESTORE:
  73. *Area = AREA_FILE_SECURITY;
  74. *cf = cfSceFileArea;
  75. break;
  76. default:
  77. return FALSE;
  78. }
  79. return TRUE;
  80. }
  81. //+--------------------------------------------------------------------------
  82. //
  83. // Method: OnCopyArea
  84. //
  85. // Synopsis: Copy a folder to the clipboard
  86. //
  87. // Arguments: [szTemplate] - the name of the template file to copy from
  88. // [ft] - the type of folder to copy
  89. //
  90. // Returns: HRESULT
  91. //
  92. // History: 10-Nov-1997 RobCap created
  93. //
  94. //---------------------------------------------------------------------------
  95. HRESULT
  96. CComponentDataImpl::OnCopyArea(LPCTSTR szTemplate,FOLDER_TYPES ft) {
  97. HRESULT hr;
  98. SCESTATUS status;
  99. PEDITTEMPLATE pTemp;
  100. CString strPath,strFile;
  101. LPTSTR szPath,szFile;
  102. DWORD dw;
  103. CFile pFile;
  104. HANDLE hBuf;
  105. PVOID pBuf;
  106. PSCE_ERROR_LOG_INFO ErrLog;
  107. AREA_INFORMATION Area;
  108. UINT cf;
  109. hr = S_OK;
  110. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  111. CWaitCursor wc;
  112. //
  113. // Get a temporary directory path in strPath
  114. // If our buffer isn't large enough then keep reallocating until it is
  115. //
  116. dw = MAX_PATH;
  117. do {
  118. szPath = strPath.GetBuffer(dw);
  119. dw = GetTempPath(MAX_PATH,szPath);
  120. strPath.ReleaseBuffer();
  121. } while (dw > (DWORD)strPath.GetLength() );
  122. //
  123. // Can't get a path to the temporary directory
  124. //
  125. if (!dw) {
  126. return E_FAIL;
  127. }
  128. //
  129. // Get a temporary file in that directory
  130. //
  131. szFile = strFile.GetBuffer(dw+MAX_PATH);
  132. if (!GetTempFileName(szPath,L"SCE",0,szFile)) {
  133. strFile.ReleaseBuffer();
  134. return E_FAIL;
  135. }
  136. strFile.ReleaseBuffer();
  137. //
  138. // Get the template that we're trying to copy
  139. //
  140. pTemp = GetTemplate(szTemplate);
  141. if (!pTemp) {
  142. return E_FAIL;
  143. }
  144. if (!GetFolderCopyPasteInfo(ft,&Area,&cf)) {
  145. return E_FAIL;
  146. }
  147. status = SceWriteSecurityProfileInfo(szFile,
  148. Area,
  149. pTemp->pTemplate,
  150. NULL);
  151. if (SCESTATUS_SUCCESS == status) {
  152. if (!pFile.Open(szFile,CFile::modeRead)) {
  153. return E_FAIL;
  154. }
  155. dw = pFile.GetLength();
  156. hBuf = GlobalAlloc(GMEM_MOVEABLE|GMEM_DDESHARE,dw);
  157. if (!hBuf) {
  158. return E_OUTOFMEMORY;
  159. }
  160. pBuf = GlobalLock(hBuf);
  161. if (!pBuf) {
  162. GlobalFree(hBuf);
  163. return E_FAIL;
  164. }
  165. pFile.Read(pBuf,dw);
  166. GlobalUnlock(pBuf);
  167. if (OpenClipboard(NULL)) {
  168. EmptyClipboard();
  169. //
  170. // Add the data to the clipboard in CF_TEXT format, so it
  171. // can be pasted to Notepad
  172. //
  173. SetClipboardData(CF_TEXT,hBuf);
  174. //
  175. // Add the data to the clipboard in our custom format, so
  176. // we can read it back in on paste
  177. //
  178. SetClipboardData(cf,hBuf);
  179. CloseClipboard();
  180. } else {
  181. hr = E_FAIL;
  182. }
  183. pFile.Close();
  184. pFile.Remove(szFile);
  185. GlobalFree(hBuf);
  186. } else {
  187. return E_FAIL;
  188. }
  189. return hr;
  190. }
  191. //+--------------------------------------------------------------------------
  192. //
  193. // Method: OnPasteArea
  194. //
  195. // Synopsis: Paste an area from the clipboard
  196. //
  197. // Arguments: [szTemplate] - the name of the template file to paste from
  198. // [ft] - the type of folder to paste
  199. //
  200. // Returns: HRESULT
  201. //
  202. // History: 10-Nov-1997 RobCap created
  203. //
  204. //---------------------------------------------------------------------------
  205. HRESULT
  206. CComponentDataImpl::OnPasteArea(LPCTSTR szTemplate,FOLDER_TYPES ft) {
  207. SCESTATUS status;
  208. PEDITTEMPLATE pTemp;
  209. PSCE_PROFILE_INFO spi;
  210. CString strPath;
  211. CString strFile;
  212. LPTSTR szPath,szFile;
  213. AREA_INFORMATION Area;
  214. UINT cf;
  215. int k;
  216. DWORD dw;
  217. CFile *pFile;
  218. CFile pFileOut;
  219. PVOID pBuf;
  220. PVOID pHandle;
  221. HRESULT hr = S_OK;
  222. COleDataObject DataObject;
  223. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  224. CWaitCursor wc;
  225. //
  226. // Find the SCE Area and clipboard format for ft
  227. //
  228. if (!GetFolderCopyPasteInfo(ft,&Area,&cf)) {
  229. return E_FAIL;
  230. }
  231. //
  232. // Get a temporary directory path in strPath
  233. // If our buffer isn't large enough then keep reallocating until it is
  234. //
  235. dw = MAX_PATH;
  236. do {
  237. szPath = strPath.GetBuffer(dw);
  238. dw = GetTempPath(MAX_PATH,szPath);
  239. strPath.ReleaseBuffer();
  240. } while (dw > (DWORD)strPath.GetLength() );
  241. //
  242. // Can't get a path to the temporary directory
  243. //
  244. if (!dw) {
  245. return E_FAIL;
  246. }
  247. //
  248. // Get a temporary file in that directory
  249. //
  250. szFile = strFile.GetBuffer(dw+MAX_PATH);
  251. if (!GetTempFileName(szPath,L"SCE",0,szFile)) {
  252. strFile.ReleaseBuffer();
  253. return E_FAIL;
  254. }
  255. strFile.ReleaseBuffer();
  256. //
  257. // Get the template we're pasting into
  258. //
  259. pTemp = GetTemplate(szTemplate);
  260. if (!pTemp) {
  261. return E_FAIL;
  262. }
  263. //
  264. // Attach the data object to the clipboard; we don't need
  265. // to worry about releasing it since that will be done in
  266. // DataObject's destructor
  267. //
  268. if (!DataObject.AttachClipboard()) {
  269. return E_FAIL;
  270. }
  271. if (!DataObject.IsDataAvailable((CLIPFORMAT)cf)) {
  272. return E_FAIL;
  273. }
  274. pFile = DataObject.GetFileData((CLIPFORMAT)cf);
  275. if (pFile) {
  276. //
  277. // Write the data from the clipboard to a temporary file
  278. //
  279. if ( pFileOut.Open(szFile,CFile::modeWrite) ) {
  280. dw = pFile->GetLength();
  281. pBuf = new BYTE [dw];
  282. if (NULL != pBuf) {
  283. pFile->Read(pBuf,dw);
  284. pFileOut.Write(pBuf,dw);
  285. } else {
  286. hr = E_FAIL;
  287. }
  288. pFileOut.Close();
  289. }
  290. pFile->Close();
  291. } else {
  292. return E_FAIL;
  293. }
  294. if (S_OK == hr) {
  295. //
  296. // Have the engine open the temporary file as a template
  297. //
  298. if (EngineOpenProfile(szFile,OPEN_PROFILE_CONFIGURE,&pHandle) != SCESTATUS_SUCCESS) {
  299. delete pBuf;
  300. return E_FAIL;
  301. }
  302. //
  303. // Load the temporary template area into our scratch SCE_PROFILE_INFO
  304. //
  305. //
  306. // SceGetSecurityProfileInfo will allocate an SCE_PROFILE_INFO struct
  307. // if a pointer to a NULL one is passed in
  308. //
  309. spi = NULL;
  310. status = SceGetSecurityProfileInfo(pHandle,
  311. SCE_ENGINE_SCP,
  312. Area,
  313. &spi,
  314. NULL);
  315. SceCloseProfile(&pHandle);
  316. pHandle = NULL;
  317. if (SCESTATUS_SUCCESS == status) {
  318. PSCE_REGISTRY_VALUE_INFO pRegValues;
  319. //
  320. // The load succeeded, so free the appropriate old area and copy the
  321. // new version from the scratch SCE_PROFILE_INFO
  322. //
  323. switch(ft) {
  324. case POLICY_ACCOUNT:
  325. pTemp->pTemplate->MinimumPasswordAge = spi->MinimumPasswordAge;
  326. pTemp->pTemplate->MaximumPasswordAge = spi->MaximumPasswordAge;
  327. pTemp->pTemplate->PasswordComplexity = spi->PasswordComplexity;
  328. pTemp->pTemplate->ClearTextPassword = spi->ClearTextPassword;
  329. pTemp->pTemplate->PasswordHistorySize = spi->PasswordHistorySize;
  330. pTemp->pTemplate->RequireLogonToChangePassword = spi->RequireLogonToChangePassword;
  331. pTemp->pTemplate->MinimumPasswordLength = spi->MinimumPasswordLength;
  332. pTemp->pTemplate->LockoutBadCount = spi->LockoutBadCount;
  333. pTemp->pTemplate->ResetLockoutCount = spi->ResetLockoutCount;
  334. pTemp->pTemplate->LockoutDuration = spi->LockoutDuration;
  335. if (spi->pKerberosInfo) {
  336. if (!pTemp->pTemplate->pKerberosInfo) {
  337. pTemp->pTemplate->pKerberosInfo = (PSCE_KERBEROS_TICKET_INFO) LocalAlloc(LPTR,sizeof(SCE_KERBEROS_TICKET_INFO));
  338. }
  339. if (pTemp->pTemplate->pKerberosInfo) {
  340. pTemp->pTemplate->pKerberosInfo->MaxTicketAge = spi->pKerberosInfo->MaxTicketAge;
  341. pTemp->pTemplate->pKerberosInfo->MaxServiceAge = spi->pKerberosInfo->MaxServiceAge;
  342. pTemp->pTemplate->pKerberosInfo->MaxClockSkew = spi->pKerberosInfo->MaxClockSkew;
  343. pTemp->pTemplate->pKerberosInfo->MaxRenewAge = spi->pKerberosInfo->MaxRenewAge;
  344. pTemp->pTemplate->pKerberosInfo->TicketValidateClient = spi->pKerberosInfo->TicketValidateClient;
  345. }
  346. } else if (pTemp->pTemplate->pKerberosInfo) {
  347. LocalFree(pTemp->pTemplate->pKerberosInfo);
  348. pTemp->pTemplate->pKerberosInfo = NULL;
  349. }
  350. break;
  351. case POLICY_LOCAL:
  352. pTemp->pTemplate->AuditAccountManage = spi->AuditAccountManage;
  353. pTemp->pTemplate->AuditLogonEvents = spi->AuditLogonEvents;
  354. pTemp->pTemplate->AuditObjectAccess = spi->AuditObjectAccess;
  355. pTemp->pTemplate->AuditPolicyChange = spi->AuditPolicyChange;
  356. pTemp->pTemplate->AuditPrivilegeUse = spi->AuditPrivilegeUse;
  357. pTemp->pTemplate->AuditProcessTracking = spi->AuditProcessTracking;
  358. pTemp->pTemplate->AuditSystemEvents = spi->AuditSystemEvents;
  359. pTemp->pTemplate->AuditDSAccess = spi->AuditDSAccess;
  360. pTemp->pTemplate->AuditAccountLogon = spi->AuditAccountLogon;
  361. pTemp->pTemplate->LSAAnonymousNameLookup = spi->LSAAnonymousNameLookup;
  362. pTemp->pTemplate->ForceLogoffWhenHourExpire = spi->ForceLogoffWhenHourExpire;
  363. pTemp->pTemplate->EnableAdminAccount = spi->EnableAdminAccount;
  364. pTemp->pTemplate->EnableGuestAccount = spi->EnableGuestAccount;
  365. pTemp->pTemplate->NewAdministratorName = spi->NewAdministratorName;
  366. pTemp->pTemplate->NewGuestName = spi->NewGuestName;
  367. spi->NewAdministratorName = NULL;
  368. spi->NewGuestName = NULL;
  369. //
  370. // copy reg value section too
  371. //
  372. dw = pTemp->pTemplate->RegValueCount;
  373. pRegValues = pTemp->pTemplate->aRegValues;
  374. pTemp->pTemplate->RegValueCount = spi->RegValueCount;
  375. pTemp->pTemplate->aRegValues = spi->aRegValues;
  376. spi->RegValueCount = dw;
  377. spi->aRegValues = pRegValues;
  378. SceRegEnumAllValues(
  379. &(pTemp->pTemplate->RegValueCount),
  380. &(pTemp->pTemplate->aRegValues)
  381. );
  382. //
  383. // copy user rights
  384. //
  385. SceFreeMemory(pTemp->pTemplate->OtherInfo.scp.u.pPrivilegeAssignedTo,SCE_STRUCT_PRIVILEGE);
  386. pTemp->pTemplate->OtherInfo.scp.u.pPrivilegeAssignedTo = spi->OtherInfo.scp.u.pPrivilegeAssignedTo;
  387. spi->OtherInfo.scp.u.pPrivilegeAssignedTo = NULL;
  388. break;
  389. case POLICY_PASSWORD:
  390. pTemp->pTemplate->MinimumPasswordAge = spi->MinimumPasswordAge;
  391. pTemp->pTemplate->MaximumPasswordAge = spi->MaximumPasswordAge;
  392. pTemp->pTemplate->PasswordComplexity = spi->PasswordComplexity;
  393. pTemp->pTemplate->ClearTextPassword = spi->ClearTextPassword;
  394. pTemp->pTemplate->PasswordHistorySize = spi->PasswordHistorySize;
  395. pTemp->pTemplate->RequireLogonToChangePassword = spi->RequireLogonToChangePassword;
  396. pTemp->pTemplate->MinimumPasswordLength = spi->MinimumPasswordLength;
  397. break;
  398. case POLICY_LOCKOUT:
  399. pTemp->pTemplate->LockoutBadCount = spi->LockoutBadCount;
  400. pTemp->pTemplate->ResetLockoutCount = spi->ResetLockoutCount;
  401. pTemp->pTemplate->LockoutDuration = spi->LockoutDuration;
  402. break;
  403. case POLICY_KERBEROS:
  404. pTemp->pTemplate->pKerberosInfo->MaxTicketAge = spi->pKerberosInfo->MaxTicketAge;
  405. pTemp->pTemplate->pKerberosInfo->MaxServiceAge = spi->pKerberosInfo->MaxServiceAge;
  406. pTemp->pTemplate->pKerberosInfo->MaxClockSkew = spi->pKerberosInfo->MaxClockSkew;
  407. pTemp->pTemplate->pKerberosInfo->MaxRenewAge = spi->pKerberosInfo->MaxRenewAge;
  408. pTemp->pTemplate->pKerberosInfo->TicketValidateClient = spi->pKerberosInfo->TicketValidateClient;
  409. break;
  410. case POLICY_AUDIT:
  411. pTemp->pTemplate->AuditAccountManage = spi->AuditAccountManage;
  412. pTemp->pTemplate->AuditLogonEvents = spi->AuditLogonEvents;
  413. pTemp->pTemplate->AuditObjectAccess = spi->AuditObjectAccess;
  414. pTemp->pTemplate->AuditPolicyChange = spi->AuditPolicyChange;
  415. pTemp->pTemplate->AuditPrivilegeUse = spi->AuditPrivilegeUse;
  416. pTemp->pTemplate->AuditProcessTracking = spi->AuditProcessTracking;
  417. pTemp->pTemplate->AuditSystemEvents = spi->AuditSystemEvents;
  418. pTemp->pTemplate->AuditDSAccess = spi->AuditDSAccess;
  419. pTemp->pTemplate->AuditAccountLogon = spi->AuditAccountLogon;
  420. break;
  421. case POLICY_OTHER:
  422. pTemp->pTemplate->ForceLogoffWhenHourExpire = spi->ForceLogoffWhenHourExpire;
  423. pTemp->pTemplate->EnableGuestAccount = spi->EnableGuestAccount;
  424. pTemp->pTemplate->EnableAdminAccount = spi->EnableAdminAccount;
  425. pTemp->pTemplate->LSAAnonymousNameLookup = spi->LSAAnonymousNameLookup;
  426. pTemp->pTemplate->NewAdministratorName = spi->NewAdministratorName;
  427. pTemp->pTemplate->NewGuestName = spi->NewGuestName;
  428. spi->NewAdministratorName = NULL;
  429. spi->NewGuestName = NULL;
  430. //
  431. // copy reg value section too
  432. //
  433. dw = pTemp->pTemplate->RegValueCount;
  434. pRegValues = pTemp->pTemplate->aRegValues;
  435. pTemp->pTemplate->RegValueCount = spi->RegValueCount;
  436. pTemp->pTemplate->aRegValues = spi->aRegValues;
  437. spi->RegValueCount = dw;
  438. spi->aRegValues = pRegValues;
  439. SceRegEnumAllValues(
  440. &(pTemp->pTemplate->RegValueCount),
  441. &(pTemp->pTemplate->aRegValues)
  442. );
  443. break;
  444. case AREA_PRIVILEGE:
  445. SceFreeMemory(pTemp->pTemplate->OtherInfo.scp.u.pPrivilegeAssignedTo,SCE_STRUCT_PRIVILEGE);
  446. pTemp->pTemplate->OtherInfo.scp.u.pPrivilegeAssignedTo = spi->OtherInfo.scp.u.pPrivilegeAssignedTo;
  447. spi->OtherInfo.scp.u.pPrivilegeAssignedTo = NULL;
  448. break;
  449. case POLICY_EVENTLOG:
  450. case POLICY_LOG:
  451. for(k=0;k<3;k++) {
  452. pTemp->pTemplate->MaximumLogSize[k] = spi->MaximumLogSize[k];
  453. pTemp->pTemplate->AuditLogRetentionPeriod[k] = spi->AuditLogRetentionPeriod[k];
  454. pTemp->pTemplate->RetentionDays[k] = spi->RetentionDays[k];
  455. pTemp->pTemplate->RestrictGuestAccess[k] = spi->RestrictGuestAccess[k];
  456. }
  457. break;
  458. case AREA_GROUPS:
  459. SceFreeMemory(pTemp->pTemplate->pGroupMembership,SCE_STRUCT_GROUP);
  460. pTemp->pTemplate->pGroupMembership = spi->pGroupMembership;
  461. spi->pGroupMembership = NULL;
  462. break;
  463. case AREA_SERVICE:
  464. SceFreeMemory(pTemp->pTemplate->pServices,SCE_STRUCT_SERVICES);
  465. pTemp->pTemplate->pServices = spi->pServices;
  466. spi->pServices = NULL;
  467. break;
  468. case AREA_REGISTRY:
  469. SceFreeMemory(pTemp->pTemplate->pRegistryKeys.pAllNodes,SCE_STRUCT_OBJECT_ARRAY);
  470. pTemp->pTemplate->pRegistryKeys = spi->pRegistryKeys;
  471. spi->pRegistryKeys.pAllNodes = NULL;
  472. break;
  473. case AREA_FILESTORE:
  474. SceFreeMemory(pTemp->pTemplate->pFiles.pAllNodes,SCE_STRUCT_OBJECT_ARRAY);
  475. pTemp->pTemplate->pFiles = spi->pFiles;
  476. spi->pFiles.pAllNodes = NULL;
  477. break;
  478. default:
  479. break;
  480. }
  481. }
  482. SceFreeProfileMemory(spi);
  483. pTemp->SetDirty(Area);
  484. RefreshAllFolders();
  485. } else {
  486. //
  487. // Don't do anything special, just be sure to clean up below....
  488. //
  489. }
  490. //
  491. // Delete the temporary file
  492. //
  493. pFileOut.Remove(szFile);
  494. if (pBuf) {
  495. delete pBuf;
  496. }
  497. if (pFile) {
  498. delete pFile;
  499. }
  500. return hr;
  501. }