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.

346 lines
8.8 KiB

  1. //*************************************************************
  2. //
  3. // Personal Classes Profile management routines
  4. //
  5. // Microsoft Confidential
  6. // Copyright (c) Microsoft Corporation 1995
  7. // All rights reserved
  8. //
  9. //*************************************************************
  10. #include "uenv.h"
  11. LPTSTR GetSidString(HANDLE UserToken);
  12. VOID DeleteSidString(LPTSTR SidString);
  13. PSID GetUserSid (HANDLE UserToken);
  14. VOID DeleteUserSid(PSID Sid);
  15. BOOL
  16. MergeUserClasses(
  17. HKEY UserClassStore,
  18. HKEY CommonClassStore,
  19. HKEY MergedClassStore,
  20. BOOL ForceNew);
  21. BOOL
  22. CloneRegistryTree(
  23. HKEY hkSourceTree,
  24. HKEY hkDestinationTree,
  25. LPTSTR lpDestTreeName );
  26. BOOL
  27. AddSharedValuesToSubkeys( HKEY hkShared, LPTSTR pszSubtree );
  28. BOOL
  29. AddSharedValues( HKEY hkShared );
  30. void CreateMachineClassHive( )
  31. {
  32. HKEY hkUser = NULL;
  33. HKEY hkMachine = NULL;
  34. LONG result;
  35. DWORD dwDisp;
  36. result =
  37. RegOpenKeyEx(HKEY_LOCAL_MACHINE,
  38. TEXT("Software\\Classes"),
  39. 0,
  40. KEY_READ,
  41. &hkUser);
  42. if (ERROR_SUCCESS != result)
  43. {
  44. return;
  45. }
  46. result =
  47. RegCreateKeyEx(HKEY_LOCAL_MACHINE,
  48. TEXT("Software\\MachineClasses"),
  49. 0,
  50. NULL,
  51. REG_OPTION_NON_VOLATILE,
  52. KEY_ALL_ACCESS,
  53. NULL,
  54. &hkMachine,
  55. &dwDisp );
  56. if (ERROR_SUCCESS != result)
  57. {
  58. RegCloseKey( hkUser );
  59. return;
  60. }
  61. CloneRegistryTree(hkUser, hkMachine, NULL);
  62. AddSharedValues( hkMachine );
  63. RegCloseKey( hkUser );
  64. RegCloseKey( hkMachine );
  65. }
  66. LPTSTR
  67. GetUserMergedHivePath(
  68. LPTSTR SidString )
  69. {
  70. // open HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\ProfileList
  71. // open ...\SidString
  72. // get value for ProfileImagePath, and if it is reg_expand_sz, expand it
  73. // append Classes as the last component of the hive file name
  74. long result;
  75. HKEY hkProfileListKey;
  76. HKEY hkProfileKey;
  77. TCHAR ProfilePath[256];
  78. TCHAR ExpandedProfilePath[256];
  79. LPTSTR pszProfileDirectory = NULL;
  80. LPTSTR pszReturnedHivePath = NULL;
  81. DWORD dwType;
  82. DWORD dwSize = sizeof( ProfilePath );
  83. result = RegOpenKeyEx( HKEY_LOCAL_MACHINE,
  84. L"Software\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList",
  85. 0,
  86. KEY_READ,
  87. &hkProfileListKey );
  88. // Bug 45992
  89. if (ERROR_SUCCESS != result) {
  90. return NULL;
  91. }
  92. result = RegOpenKeyEx( hkProfileListKey,
  93. SidString,
  94. 0,
  95. KEY_READ,
  96. &hkProfileKey );
  97. if (ERROR_SUCCESS != result) {
  98. RegCloseKey(hkProfileListKey);
  99. return NULL;
  100. }
  101. result = RegQueryValueEx( hkProfileKey,
  102. L"ProfileImagePath",
  103. NULL,
  104. &dwType,
  105. (BYTE*)&ProfilePath,
  106. &dwSize );
  107. // Close them keys
  108. RegCloseKey(hkProfileListKey);
  109. RegCloseKey(hkProfileKey);
  110. if (ERROR_SUCCESS != result) {
  111. return NULL;
  112. }
  113. if ( dwType == REG_EXPAND_SZ )
  114. {
  115. ExpandEnvironmentStrings( ProfilePath,
  116. ExpandedProfilePath,
  117. sizeof(ExpandedProfilePath)/sizeof(TCHAR) );
  118. pszProfileDirectory = ExpandedProfilePath;
  119. }
  120. else
  121. {
  122. pszProfileDirectory = ProfilePath;
  123. }
  124. pszReturnedHivePath = (LPTSTR) LocalAlloc( LPTR,
  125. (lstrlenW( pszProfileDirectory )+1) * sizeof(TCHAR) +
  126. sizeof( L"\\ClsRoot" ) );
  127. // Bug 45993
  128. if (pszReturnedHivePath)
  129. {
  130. // make up the returned string as the profile directory with \ClsRoot on the end
  131. lstrcpyW( pszReturnedHivePath, pszProfileDirectory );
  132. lstrcatW( pszReturnedHivePath, L"\\ClsRoot" );
  133. }
  134. return pszReturnedHivePath;
  135. }
  136. void
  137. FreeUserMergedHivePath( LPTSTR hivepath )
  138. {
  139. LocalFree( hivepath );
  140. }
  141. // see if the desired hive file already exists. If so, load it and return
  142. // otherwise, create a hive containing a single key, load it and return
  143. BOOL
  144. CreateUserMergedClasses(
  145. LPTSTR SidString,
  146. LPTSTR MergedClassesString,
  147. HKEY * phkMerged )
  148. {
  149. LPTSTR HivePath;
  150. long result;
  151. HKEY DummyKey = NULL;
  152. DWORD dwDisp;
  153. NTSTATUS Status;
  154. BOOLEAN WasEnabled;
  155. HivePath = GetUserMergedHivePath( SidString );
  156. if (!HivePath)
  157. {
  158. return FALSE;
  159. }
  160. // see if the desired hive file already exists. If so, load it and return
  161. if ( 0xFFFFFFFF == GetFileAttributes( HivePath ) )
  162. {
  163. // create a hive containing a single key, load it and return
  164. result = RegCreateKeyEx( HKEY_LOCAL_MACHINE,
  165. L"Software\\Microsoft\\DummyKey",
  166. 0,
  167. NULL,
  168. REG_OPTION_NON_VOLATILE,
  169. KEY_ALL_ACCESS,
  170. NULL,
  171. &DummyKey,
  172. &dwDisp );
  173. if (ERROR_SUCCESS != result)
  174. {
  175. FreeUserMergedHivePath( HivePath );
  176. return FALSE;
  177. }
  178. //
  179. // Enable the backup privilege
  180. //
  181. Status = RtlAdjustPrivilege(SE_BACKUP_PRIVILEGE, TRUE, FALSE, &WasEnabled);
  182. // do this by doing a RegSaveKey of a small subtree
  183. result = RegSaveKey( DummyKey,
  184. HivePath,
  185. NULL );
  186. result = RegCloseKey( DummyKey );
  187. //
  188. // Restore the privilege to its previous state
  189. //
  190. Status = RtlAdjustPrivilege(SE_BACKUP_PRIVILEGE, WasEnabled, FALSE, &WasEnabled);
  191. }
  192. //
  193. // Enable the restore privilege
  194. //
  195. Status = RtlAdjustPrivilege(SE_RESTORE_PRIVILEGE, TRUE, FALSE, &WasEnabled);
  196. result = RegLoadKey( HKEY_USERS,
  197. MergedClassesString,
  198. HivePath );
  199. // if result is OK, then open the subkey and return it
  200. result = RegOpenKeyEx( HKEY_USERS,
  201. MergedClassesString,
  202. 0,
  203. KEY_ALL_ACCESS,
  204. phkMerged );
  205. FreeUserMergedHivePath( HivePath );
  206. // close keys?
  207. //
  208. // Restore the privilege to its previous state
  209. //
  210. Status = RtlAdjustPrivilege(SE_RESTORE_PRIVILEGE, WasEnabled, FALSE, &WasEnabled);
  211. return TRUE;
  212. }
  213. void MergeUserClassHives( HANDLE Token )
  214. {
  215. HKEY hkUser = NULL;
  216. HKEY hkMachine = NULL;
  217. HKEY hkMerged = NULL;
  218. LONG result;
  219. LPTSTR SidString;
  220. LPTSTR MergedClassesString;
  221. DWORD dwDisp;
  222. BOOL ForceNew = FALSE;
  223. result =
  224. RegCreateKeyEx(HKEY_CURRENT_USER,
  225. TEXT("Software\\Classes"),
  226. 0,
  227. NULL,
  228. REG_OPTION_NON_VOLATILE,
  229. KEY_READ,
  230. NULL,
  231. &hkUser,
  232. &dwDisp);
  233. result =
  234. RegOpenKeyEx(HKEY_LOCAL_MACHINE,
  235. TEXT("Software\\MachineClasses"),
  236. 0,
  237. KEY_READ,
  238. &hkMachine);
  239. if ( result == ERROR_FILE_NOT_FOUND )
  240. {
  241. CreateMachineClassHive();
  242. result =
  243. RegOpenKeyEx(HKEY_LOCAL_MACHINE,
  244. TEXT("Software\\MachineClasses"),
  245. 0,
  246. KEY_READ,
  247. &hkMachine);
  248. }
  249. // Bugs 45996 and 45997
  250. SidString = GetSidString( Token );
  251. if (SidString)
  252. {
  253. MergedClassesString = (LPTSTR) LocalAlloc( LPTR,
  254. (lstrlenW( SidString ) + 1) * sizeof(WCHAR) +
  255. sizeof(L"_MergedClasses" ) );
  256. if (MergedClassesString)
  257. {
  258. lstrcpyW( MergedClassesString, SidString );
  259. lstrcatW( MergedClassesString, L"_MergedClasses" );
  260. result = RegOpenKeyEx( HKEY_USERS,
  261. MergedClassesString,
  262. 0,
  263. KEY_ALL_ACCESS,
  264. &hkMerged );
  265. if ( result == ERROR_FILE_NOT_FOUND )
  266. {
  267. CreateUserMergedClasses(SidString, MergedClassesString, &hkMerged );
  268. ForceNew = TRUE;
  269. }
  270. MergeUserClasses(hkUser, hkMachine, hkMerged, ForceNew );
  271. LocalFree( MergedClassesString );
  272. }
  273. }
  274. RegCloseKey( hkUser );
  275. RegCloseKey( hkMachine );
  276. RegCloseKey( hkMerged );
  277. DeleteSidString( SidString );
  278. }
  279. void MergeHives( )
  280. {
  281. HANDLE Token;
  282. NTSTATUS Status;
  283. Status = NtOpenProcessToken( NtCurrentProcess(), TOKEN_QUERY, &Token );
  284. MergeUserClassHives( Token );
  285. NtClose( Token );
  286. }