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.

856 lines
21 KiB

  1. //*************************************************************
  2. // File name: profile.c
  3. //
  4. // Description: Fixes hard coded paths in the registry for
  5. // special folder locations. Also fixes security
  6. // on a few registry keys.
  7. //
  8. // Microsoft Confidential
  9. // Copyright (c) Microsoft Corporation 1996
  10. // All rights reserved
  11. //
  12. //*************************************************************
  13. #include <windows.h>
  14. #include <shlobj.h>
  15. #include <shlwapi.h>
  16. #include <xpsp1res.h>
  17. #include <userenv.h>
  18. #include <userenvp.h>
  19. #include <tchar.h>
  20. #include "shmgdefs.h"
  21. //*************************************************************
  22. //
  23. // ApplySecurityToRegistryTree()
  24. //
  25. // Purpose: Applies the passed security descriptor to the passed
  26. // key and all its descendants. Only the parts of
  27. // the descriptor inddicated in the security
  28. // info value are actually applied to each registry key.
  29. //
  30. // Parameters: RootKey - Registry key
  31. // pSD - Security Descriptor
  32. //
  33. // Return: ERROR_SUCCESS if successful
  34. //
  35. // Comments:
  36. //
  37. // History: Date Author Comment
  38. // 7/19/95 ericflo Created
  39. // 6/16/96 bobday Stolen directly from USERENV
  40. //
  41. //*************************************************************
  42. DWORD ApplySecurityToRegistryTree(HKEY RootKey, PSECURITY_DESCRIPTOR pSD)
  43. {
  44. DWORD Error;
  45. DWORD SubKeyIndex;
  46. LPTSTR SubKeyName;
  47. HKEY SubKey;
  48. DWORD cchSubKeySize = MAX_PATH + 1;
  49. //
  50. // First apply security
  51. //
  52. Error = RegSetKeySecurity(RootKey, DACL_SECURITY_INFORMATION, pSD);
  53. if (Error != ERROR_SUCCESS) {
  54. return Error;
  55. }
  56. //
  57. // Open each sub-key and apply security to its sub-tree
  58. //
  59. SubKeyIndex = 0;
  60. SubKeyName = GlobalAlloc (GPTR, cchSubKeySize * sizeof(TCHAR));
  61. if (!SubKeyName) {
  62. return GetLastError();
  63. }
  64. while (TRUE) {
  65. //
  66. // Get the next sub-key name
  67. //
  68. Error = RegEnumKey(RootKey, SubKeyIndex, SubKeyName, cchSubKeySize);
  69. if (Error != ERROR_SUCCESS) {
  70. if (Error == ERROR_NO_MORE_ITEMS) {
  71. //
  72. // Successful end of enumeration
  73. //
  74. Error = ERROR_SUCCESS;
  75. } else {
  76. }
  77. break;
  78. }
  79. //
  80. // Open the sub-key
  81. //
  82. Error = RegOpenKeyEx(RootKey,
  83. SubKeyName,
  84. 0,
  85. WRITE_DAC | KEY_ENUMERATE_SUB_KEYS | READ_CONTROL,
  86. &SubKey);
  87. if (Error != ERROR_SUCCESS) {
  88. break;
  89. }
  90. //
  91. // Apply security to the sub-tree
  92. //
  93. Error = ApplySecurityToRegistryTree(SubKey, pSD);
  94. //
  95. // We're finished with the sub-key
  96. //
  97. RegCloseKey(SubKey);
  98. //
  99. // See if we set the security on the sub-tree successfully.
  100. //
  101. if (Error != ERROR_SUCCESS) {
  102. break;
  103. }
  104. //
  105. // Go enumerate the next sub-key
  106. //
  107. SubKeyIndex ++;
  108. }
  109. GlobalFree (SubKeyName);
  110. return Error;
  111. }
  112. //*************************************************************
  113. //
  114. // MakeKeyOrTreeSecure()
  115. //
  116. // Purpose: Sets the attributes on the registry key and possibly sub-keys
  117. // such that Administrators and the OS can delete it and Everyone
  118. // else has read permission only (OR general read/write access)
  119. //
  120. // Parameters: RootKey - Key to set security on
  121. // fWrite - Allow write (or just read)
  122. //
  123. // Return: (BOOL) TRUE if successful
  124. // FALSE if an error occurs
  125. //
  126. // Comments:
  127. //
  128. // History: Date Author Comment
  129. // 11/6/95 ericflo Created
  130. // 06/16/96 bobday Ported from MakeFileSecure in USERENV
  131. //
  132. //*************************************************************
  133. BOOL MakeKeyOrTreeSecure (HKEY RootKey, BOOL fWrite)
  134. {
  135. SECURITY_DESCRIPTOR sd;
  136. SID_IDENTIFIER_AUTHORITY authNT = SECURITY_NT_AUTHORITY;
  137. SID_IDENTIFIER_AUTHORITY authWorld = SECURITY_WORLD_SID_AUTHORITY;
  138. PACL pAcl = NULL;
  139. PSID psidSystem = NULL, psidAdmin = NULL, psidEveryone = NULL;
  140. DWORD cbAcl, aceIndex;
  141. ACE_HEADER * lpAceHeader;
  142. BOOL bRetVal = FALSE;
  143. DWORD Error;
  144. DWORD dwAccess;
  145. if (fWrite) {
  146. dwAccess = KEY_ALL_ACCESS;
  147. } else {
  148. dwAccess = KEY_READ;
  149. }
  150. //
  151. // Get the system sid
  152. //
  153. if (!AllocateAndInitializeSid(&authNT, 1, SECURITY_LOCAL_SYSTEM_RID,
  154. 0, 0, 0, 0, 0, 0, 0, &psidSystem)) {
  155. goto Exit;
  156. }
  157. //
  158. // Get the Admin sid
  159. //
  160. if (!AllocateAndInitializeSid(&authNT, 2, SECURITY_BUILTIN_DOMAIN_RID,
  161. DOMAIN_ALIAS_RID_ADMINS, 0, 0,
  162. 0, 0, 0, 0, &psidAdmin)) {
  163. goto Exit;
  164. }
  165. //
  166. // Get the World sid
  167. //
  168. if (!AllocateAndInitializeSid(&authWorld, 1, SECURITY_WORLD_RID,
  169. 0, 0, 0, 0, 0, 0, 0, &psidEveryone)) {
  170. goto Exit;
  171. }
  172. //
  173. // Allocate space for the ACL
  174. //
  175. cbAcl = (3 * GetLengthSid (psidSystem)) +
  176. (3 * GetLengthSid (psidAdmin)) + sizeof(ACL) +
  177. (6 * (sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD)));
  178. pAcl = (PACL) GlobalAlloc(GMEM_FIXED, cbAcl);
  179. if (!pAcl) {
  180. goto Exit;
  181. }
  182. if (!InitializeAcl(pAcl, cbAcl, ACL_REVISION)) {
  183. goto Exit;
  184. }
  185. //
  186. // Add Aces. Non-inheritable ACEs first
  187. //
  188. aceIndex = 0;
  189. if (!AddAccessAllowedAce(pAcl, ACL_REVISION, KEY_ALL_ACCESS, psidSystem)) {
  190. goto Exit;
  191. }
  192. aceIndex++;
  193. if (!AddAccessAllowedAce(pAcl, ACL_REVISION, KEY_ALL_ACCESS, psidAdmin)) {
  194. goto Exit;
  195. }
  196. aceIndex++;
  197. if (!AddAccessAllowedAce(pAcl, ACL_REVISION, dwAccess, psidEveryone)) {
  198. goto Exit;
  199. }
  200. //
  201. // Now the inheritable ACEs
  202. //
  203. if (fWrite) {
  204. dwAccess = GENERIC_ALL;
  205. } else {
  206. dwAccess = GENERIC_READ;
  207. }
  208. aceIndex++;
  209. if (!AddAccessAllowedAce(pAcl, ACL_REVISION, GENERIC_ALL, psidSystem)) {
  210. goto Exit;
  211. }
  212. if (!GetAce(pAcl, aceIndex, &lpAceHeader)) {
  213. goto Exit;
  214. }
  215. lpAceHeader->AceFlags |= (OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE | INHERIT_ONLY_ACE);
  216. aceIndex++;
  217. if (!AddAccessAllowedAce(pAcl, ACL_REVISION, GENERIC_ALL, psidAdmin)) {
  218. goto Exit;
  219. }
  220. if (!GetAce(pAcl, aceIndex, &lpAceHeader)) {
  221. goto Exit;
  222. }
  223. lpAceHeader->AceFlags |= (OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE | INHERIT_ONLY_ACE);
  224. aceIndex++;
  225. if (!AddAccessAllowedAce(pAcl, ACL_REVISION, dwAccess, psidEveryone)) {
  226. goto Exit;
  227. }
  228. if (!GetAce(pAcl, aceIndex, &lpAceHeader)) {
  229. goto Exit;
  230. }
  231. lpAceHeader->AceFlags |= (OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE | INHERIT_ONLY_ACE);
  232. //
  233. // Put together the security descriptor
  234. //
  235. if (!InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION)) {
  236. goto Exit;
  237. }
  238. if (!SetSecurityDescriptorDacl(&sd, TRUE, pAcl, FALSE)) {
  239. goto Exit;
  240. }
  241. //
  242. // Set the security
  243. //
  244. Error = ApplySecurityToRegistryTree(RootKey, &sd);
  245. if (Error == ERROR_SUCCESS) {
  246. bRetVal = TRUE;
  247. }
  248. Exit:
  249. if (psidSystem) {
  250. FreeSid(psidSystem);
  251. }
  252. if (psidAdmin) {
  253. FreeSid(psidAdmin);
  254. }
  255. if (psidEveryone) {
  256. FreeSid(psidEveryone);
  257. }
  258. if (pAcl) {
  259. GlobalFree (pAcl);
  260. }
  261. return bRetVal;
  262. }
  263. void FixWindowsProfileSecurity( void )
  264. {
  265. HKEY hkeyWindows;
  266. HKEY hkeyShellExt;
  267. DWORD Error;
  268. Error = RegOpenKeyEx( HKEY_LOCAL_MACHINE,
  269. TEXT("Software\\Microsoft\\Windows"),
  270. 0,
  271. WRITE_DAC | KEY_ENUMERATE_SUB_KEYS | READ_CONTROL,
  272. &hkeyWindows);
  273. if (Error == ERROR_SUCCESS)
  274. {
  275. MakeKeyOrTreeSecure(hkeyWindows, TRUE);
  276. RegCloseKey(hkeyWindows);
  277. }
  278. Error = RegOpenKeyEx( HKEY_LOCAL_MACHINE,
  279. TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Shell Extensions"),
  280. 0,
  281. WRITE_DAC | KEY_ENUMERATE_SUB_KEYS | READ_CONTROL,
  282. &hkeyShellExt);
  283. if (Error == ERROR_SUCCESS)
  284. {
  285. MakeKeyOrTreeSecure(hkeyShellExt, FALSE);
  286. RegCloseKey(hkeyShellExt);
  287. }
  288. }
  289. void FixUserProfileSecurity( void )
  290. {
  291. HKEY hkeyPolicies;
  292. DWORD Error;
  293. Error = RegOpenKeyEx( HKEY_CURRENT_USER,
  294. TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Policies"),
  295. 0,
  296. WRITE_DAC | KEY_ENUMERATE_SUB_KEYS | READ_CONTROL,
  297. &hkeyPolicies);
  298. if (Error == ERROR_SUCCESS)
  299. {
  300. MakeKeyOrTreeSecure(hkeyPolicies, FALSE);
  301. RegCloseKey(hkeyPolicies);
  302. }
  303. }
  304. void FixPoliciesSecurity( void )
  305. {
  306. HKEY hkeyPolicies;
  307. DWORD Error, dwDisp;
  308. Error = RegCreateKeyEx( HKEY_CURRENT_USER,
  309. TEXT("Software\\Policies"),
  310. 0,
  311. NULL,
  312. REG_OPTION_NON_VOLATILE,
  313. WRITE_DAC | KEY_ENUMERATE_SUB_KEYS | READ_CONTROL,
  314. NULL,
  315. &hkeyPolicies,
  316. &dwDisp);
  317. if (Error == ERROR_SUCCESS)
  318. {
  319. MakeKeyOrTreeSecure(hkeyPolicies, FALSE);
  320. RegCloseKey(hkeyPolicies);
  321. }
  322. }
  323. void SetSystemBitOnCAPIDir(void)
  324. {
  325. HRESULT hr;
  326. TCHAR szPath[MAX_PATH];
  327. TCHAR szAppData[MAX_PATH];
  328. DWORD FileAttributes;
  329. if (S_OK == SHGetFolderPath(NULL, CSIDL_APPDATA, NULL, SHGFP_TYPE_CURRENT, szAppData)){
  330. //
  331. // It is better to use tcscpy and tcscat. This is just a temp fix and it is build with
  332. // Unicode anyway. Not worth to include extra header file.
  333. // We do not check error case here. This is just a best effort. If we got error, so what?
  334. // MAX_PATH should be enough for these DIRs. Not worth to take care of \\?\ format.
  335. //
  336. lstrcpyn(szPath, szAppData, ARRAYSIZE(szPath));
  337. StrCatBuff(szPath, TEXT("\\Microsoft\\Protect"), ARRAYSIZE(szPath));
  338. FileAttributes = GetFileAttributes(szPath);
  339. if ((FileAttributes != -1) && ((FileAttributes & FILE_ATTRIBUTE_SYSTEM) == 0)) {
  340. FileAttributes |= FILE_ATTRIBUTE_SYSTEM;
  341. SetFileAttributes(szPath, FileAttributes);
  342. }
  343. lstrcpyn(szPath, szAppData, ARRAYSIZE(szPath));
  344. StrCatBuff(szPath, TEXT("\\Microsoft\\Crypto"), ARRAYSIZE(szPath));
  345. FileAttributes = GetFileAttributes(szPath);
  346. if ((FileAttributes != -1) && ((FileAttributes & FILE_ATTRIBUTE_SYSTEM) == 0)) {
  347. FileAttributes |= FILE_ATTRIBUTE_SYSTEM;
  348. SetFileAttributes(szPath, FileAttributes);
  349. }
  350. }
  351. }
  352. void SetScreensaverOnFriendlyUI()
  353. {
  354. if (IsOS(OS_FRIENDLYLOGONUI) &&
  355. IsOS(OS_FASTUSERSWITCHING))
  356. {
  357. HKEY hkey;
  358. if (RegOpenKeyEx(HKEY_CURRENT_USER, TEXT("Control Panel\\Desktop"), 0, KEY_SET_VALUE, &hkey) == ERROR_SUCCESS)
  359. {
  360. TCHAR szTemp[MAX_PATH];
  361. RegSetValueEx(hkey, TEXT("ScreenSaveActive"), 0, REG_SZ, (BYTE*)TEXT("1"), sizeof(TEXT("1")));
  362. if (RegQueryValueEx(hkey, TEXT("SCRNSAVE.EXE"), NULL, NULL, NULL, NULL) != ERROR_SUCCESS)
  363. {
  364. // if the user dosen't already have a screensaver set, then choose one for them!
  365. if (ExpandEnvironmentStrings(TEXT("%SystemRoot%\\System32\\logon.scr"), szTemp, ARRAYSIZE(szTemp)))
  366. {
  367. RegSetValueEx(hkey, TEXT("SCRNSAVE.EXE"), 0, REG_SZ, (BYTE*)szTemp, (lstrlen(szTemp) + 1) * sizeof(TCHAR));
  368. }
  369. }
  370. RegCloseKey(hkey);
  371. }
  372. }
  373. }
  374. #define OTHERSIDS_EVERYONE 1
  375. #define OTHERSIDS_POWERUSERS 2
  376. BOOL MakeFileSecure (LPTSTR lpFile, DWORD dwOtherSids)
  377. {
  378. SECURITY_DESCRIPTOR sd;
  379. SECURITY_ATTRIBUTES sa;
  380. SID_IDENTIFIER_AUTHORITY authNT = SECURITY_NT_AUTHORITY;
  381. SID_IDENTIFIER_AUTHORITY authWORLD = SECURITY_WORLD_SID_AUTHORITY;
  382. PACL pAcl = NULL;
  383. PSID psidSystem = NULL, psidAdmin = NULL, psidUsers = NULL, psidPowerUsers = NULL;
  384. PSID psidEveryOne = NULL;
  385. DWORD cbAcl, aceIndex;
  386. ACE_HEADER * lpAceHeader;
  387. BOOL bRetVal = FALSE;
  388. BOOL bAddPowerUsersAce=TRUE;
  389. BOOL bAddEveryOneAce=FALSE;
  390. DWORD dwAccMask;
  391. //
  392. // Get the system sid
  393. //
  394. if (!AllocateAndInitializeSid(&authNT, 1, SECURITY_LOCAL_SYSTEM_RID,
  395. 0, 0, 0, 0, 0, 0, 0, &psidSystem)) {
  396. goto Exit;
  397. }
  398. //
  399. // Get the Admin sid
  400. //
  401. if (!AllocateAndInitializeSid(&authNT, 2, SECURITY_BUILTIN_DOMAIN_RID,
  402. DOMAIN_ALIAS_RID_ADMINS, 0, 0,
  403. 0, 0, 0, 0, &psidAdmin)) {
  404. goto Exit;
  405. }
  406. //
  407. // Get the users sid
  408. //
  409. if (!AllocateAndInitializeSid(&authNT, 2, SECURITY_BUILTIN_DOMAIN_RID,
  410. DOMAIN_ALIAS_RID_USERS,
  411. 0, 0, 0, 0, 0, 0, &psidUsers)) {
  412. goto Exit;
  413. }
  414. //
  415. // Allocate space for the ACL
  416. //
  417. cbAcl = (2 * GetLengthSid (psidSystem)) +
  418. (2 * GetLengthSid (psidAdmin)) +
  419. (2 * GetLengthSid (psidUsers)) +
  420. sizeof(ACL) +
  421. (6 * (sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD)));
  422. //
  423. // Get the power users sid, if required.
  424. // Don't fail if you don't get because it might not be available on DCs??
  425. //
  426. bAddPowerUsersAce = TRUE;
  427. if (!AllocateAndInitializeSid(&authNT, 2, SECURITY_BUILTIN_DOMAIN_RID,
  428. DOMAIN_ALIAS_RID_POWER_USERS, 0, 0, 0, 0, 0, 0, &psidPowerUsers)) {
  429. bAddPowerUsersAce = FALSE;
  430. }
  431. if (bAddPowerUsersAce)
  432. cbAcl += (2 * GetLengthSid (psidPowerUsers)) + (2 * (sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD)));
  433. //
  434. // Get the EveryOne sid, if required.
  435. //
  436. if (dwOtherSids & OTHERSIDS_EVERYONE) {
  437. bAddEveryOneAce = TRUE;
  438. if (!AllocateAndInitializeSid(&authWORLD, 1, SECURITY_WORLD_RID,
  439. 0, 0, 0, 0, 0, 0, 0, &psidEveryOne)) {
  440. goto Exit;
  441. }
  442. }
  443. if (bAddEveryOneAce)
  444. cbAcl += (2 * GetLengthSid (psidEveryOne)) + (2 * (sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD)));
  445. pAcl = (PACL) GlobalAlloc(GMEM_FIXED, cbAcl);
  446. if (!pAcl) {
  447. goto Exit;
  448. }
  449. if (!InitializeAcl(pAcl, cbAcl, ACL_REVISION)) {
  450. goto Exit;
  451. }
  452. //
  453. // Add Aces. Non-inheritable ACEs first
  454. //
  455. aceIndex = 0;
  456. if (!AddAccessAllowedAce(pAcl, ACL_REVISION, FILE_ALL_ACCESS, psidSystem)) {
  457. goto Exit;
  458. }
  459. aceIndex++;
  460. if (!AddAccessAllowedAce(pAcl, ACL_REVISION, FILE_ALL_ACCESS, psidAdmin)) {
  461. goto Exit;
  462. }
  463. aceIndex++;
  464. if (!AddAccessAllowedAce(pAcl, ACL_REVISION, FILE_ALL_ACCESS, /*GENERIC_READ | GENERIC_EXECUTE,*/ psidUsers)) {
  465. goto Exit;
  466. }
  467. if (bAddPowerUsersAce) {
  468. //
  469. // By default give read permissions, otherwise give modify permissions
  470. //
  471. dwAccMask = (dwOtherSids & OTHERSIDS_POWERUSERS) ? (FILE_ALL_ACCESS ^ (WRITE_DAC | WRITE_OWNER)):
  472. (GENERIC_READ | GENERIC_EXECUTE);
  473. aceIndex++;
  474. if (!AddAccessAllowedAce(pAcl, ACL_REVISION, FILE_ALL_ACCESS, /*dwAccMask,*/ psidPowerUsers)) {
  475. goto Exit;
  476. }
  477. }
  478. if (bAddEveryOneAce) {
  479. aceIndex++;
  480. if (!AddAccessAllowedAce(pAcl, ACL_REVISION, FILE_ALL_ACCESS, /*GENERIC_READ | GENERIC_EXECUTE,*/ psidEveryOne)) {
  481. goto Exit;
  482. }
  483. }
  484. //
  485. // Now the inheritable ACEs
  486. //
  487. aceIndex++;
  488. if (!AddAccessAllowedAce(pAcl, ACL_REVISION, GENERIC_ALL, psidSystem)) {
  489. goto Exit;
  490. }
  491. if (!GetAce(pAcl, aceIndex, &lpAceHeader)) {
  492. goto Exit;
  493. }
  494. lpAceHeader->AceFlags |= (OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE | INHERIT_ONLY_ACE);
  495. aceIndex++;
  496. if (!AddAccessAllowedAce(pAcl, ACL_REVISION, GENERIC_ALL, psidAdmin)) {
  497. goto Exit;
  498. }
  499. if (!GetAce(pAcl, aceIndex, &lpAceHeader)) {
  500. goto Exit;
  501. }
  502. lpAceHeader->AceFlags |= (OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE | INHERIT_ONLY_ACE);
  503. aceIndex++;
  504. if (!AddAccessAllowedAce(pAcl, ACL_REVISION, FILE_ALL_ACCESS, /*GENERIC_READ | GENERIC_EXECUTE,*/ psidUsers)) {
  505. goto Exit;
  506. }
  507. if (!GetAce(pAcl, aceIndex, &lpAceHeader)) {
  508. goto Exit;
  509. }
  510. lpAceHeader->AceFlags |= (OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE | INHERIT_ONLY_ACE);
  511. if (bAddPowerUsersAce) {
  512. aceIndex++;
  513. dwAccMask = (dwOtherSids & OTHERSIDS_POWERUSERS) ? (FILE_ALL_ACCESS ^ (WRITE_DAC | WRITE_OWNER)):
  514. (GENERIC_READ | GENERIC_EXECUTE);
  515. if (!AddAccessAllowedAce(pAcl, ACL_REVISION, FILE_ALL_ACCESS, /*dwAccMask,*/ psidPowerUsers)) {
  516. goto Exit;
  517. }
  518. if (!GetAce(pAcl, aceIndex, &lpAceHeader)) {
  519. goto Exit;
  520. }
  521. lpAceHeader->AceFlags |= (OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE | INHERIT_ONLY_ACE);
  522. }
  523. if (bAddEveryOneAce) {
  524. aceIndex++;
  525. if (!AddAccessAllowedAce(pAcl, ACL_REVISION, FILE_ALL_ACCESS, /*GENERIC_READ | GENERIC_EXECUTE,*/ psidEveryOne)) {
  526. goto Exit;
  527. }
  528. if (!GetAce(pAcl, aceIndex, &lpAceHeader)) {
  529. goto Exit;
  530. }
  531. lpAceHeader->AceFlags |= (OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE | INHERIT_ONLY_ACE);
  532. }
  533. //
  534. // Put together the security descriptor
  535. //
  536. if (!InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION)) {
  537. goto Exit;
  538. }
  539. if (!SetSecurityDescriptorDacl(&sd, TRUE, pAcl, FALSE)) {
  540. goto Exit;
  541. }
  542. //
  543. // Set the security
  544. //
  545. if (SetFileSecurity (lpFile, DACL_SECURITY_INFORMATION, &sd)) {
  546. bRetVal = TRUE;
  547. } else {
  548. }
  549. Exit:
  550. if (psidSystem) {
  551. FreeSid(psidSystem);
  552. }
  553. if (psidAdmin) {
  554. FreeSid(psidAdmin);
  555. }
  556. if (psidUsers) {
  557. FreeSid(psidUsers);
  558. }
  559. if ((bAddPowerUsersAce) && (psidPowerUsers)) {
  560. FreeSid(psidPowerUsers);
  561. }
  562. if ((bAddEveryOneAce) && (psidEveryOne)) {
  563. FreeSid(psidEveryOne);
  564. }
  565. if (pAcl) {
  566. GlobalFree (pAcl);
  567. }
  568. return bRetVal;
  569. }
  570. #ifdef SHMG_DBG
  571. void SHMGLogErrMsg(char *szErrMsg, DWORD dwError)
  572. {
  573. DWORD dwBytesWritten = 0;
  574. char szMsg[256];
  575. static HANDLE hLogFile = 0;
  576. if (!hLogFile) {
  577. hLogFile = CreateFile(_T("shmgrate.log"), GENERIC_WRITE,
  578. FILE_SHARE_WRITE, 0,
  579. CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0 );
  580. }
  581. sprintf(szMsg, "%s : (%X)\r\n", szErrMsg, dwError);
  582. WriteFile(hLogFile, szMsg, strlen(szMsg), &dwBytesWritten, 0);
  583. }
  584. #endif
  585. void
  586. FixHtmlHelp(
  587. void
  588. )
  589. {
  590. TCHAR AppDataPath[MAX_PATH*2];
  591. TCHAR HtmlHelpPath[MAX_PATH];
  592. SHMGLogErrMsg("FixHtmlHelp Called",0);
  593. if (SHGetFolderPath(NULL, CSIDL_COMMON_APPDATA, NULL, SHGFP_TYPE_CURRENT, AppDataPath) == S_OK &&
  594. LoadString( GetModuleHandle(NULL), IDS_HTML_HELP_DIR, HtmlHelpPath, sizeof(HtmlHelpPath)/sizeof(WCHAR) ) > 0)
  595. {
  596. _tcscat( AppDataPath, HtmlHelpPath );
  597. if (CreateDirectory( AppDataPath, NULL )) {
  598. if (!MakeFileSecure(AppDataPath,OTHERSIDS_EVERYONE|OTHERSIDS_POWERUSERS))
  599. SHMGLogErrMsg("Could not apply security attributes", 0);
  600. }
  601. else
  602. SHMGLogErrMsg("Could not create the directory", GetLastError());
  603. }
  604. else
  605. SHMGLogErrMsg("Could not get APPDATA path", GetLastError());
  606. }
  607. // Add the SP1 "Configure Programs" shortcut to the common start menu
  608. // On a clean install, this is handled by syssetup.inf, but on a
  609. // RTM->SP1 upgrade, we need to do it by hand.
  610. //
  611. void AddConfigurePrograms()
  612. {
  613. if (!IsOS(OS_ANYSERVER))
  614. {
  615. TCHAR szPath[MAX_PATH];
  616. if (GetSystemDirectory(szPath, ARRAYSIZE(szPath)) &&
  617. PathAppend(szPath, TEXT("XPSP1RES.DLL")))
  618. {
  619. HINSTANCE hinstSp1 = LoadLibraryEx(szPath, NULL, LOAD_LIBRARY_AS_DATAFILE);
  620. if (hinstSp1)
  621. {
  622. TCHAR szTitle[MAX_PATH];
  623. LoadString(hinstSp1, IDS_APPWIZ_CONFIGUREPROGRAMS, szTitle, ARRAYSIZE(szTitle));
  624. CreateLinkFile(CSIDL_COMMON_STARTMENU, NULL, szTitle,
  625. TEXT("control.exe appwiz.cpl,,3"),
  626. TEXT("moricons.dll"), -114,
  627. NULL, 0, SW_SHOWNORMAL, TEXT("@xpsp1res.dll,-10078"));
  628. if (S_OK == SHGetFolderPath(NULL, CSIDL_COMMON_STARTMENU, NULL, SHGFP_TYPE_CURRENT, szPath) &&
  629. PathAppend(szPath, szTitle) &&
  630. PathAddExtension(szPath, TEXT(".lnk")))
  631. {
  632. SHSetLocalizedName(szPath, L"xpsp1res.dll", IDS_APPWIZ_CONFIGUREPROGRAMS);
  633. }
  634. }
  635. FreeLibrary(hinstSp1);
  636. }
  637. }
  638. }