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.

996 lines
30 KiB

  1. //*************************************************************
  2. //
  3. // User Profile migration routines
  4. //
  5. // Microsoft Confidential
  6. // Copyright (c) Microsoft Corporation 1998
  7. // All rights reserved
  8. //
  9. //*************************************************************
  10. #include "uenv.h"
  11. UINT CountItems (LPTSTR lpDirectory);
  12. BOOL SearchAndReplaceIEHistory(LPTSTR szIEHistKeyRoot, LPTSTR szHistOld, LPTSTR szHistNew);
  13. //*************************************************************
  14. //
  15. // DetermineLocalSettingsLocation()
  16. //
  17. // Purpose: Determines where to put the local settings
  18. //
  19. // Parameters: none
  20. //
  21. // Return: TRUE if successful
  22. // FALSE if an error occurs
  23. //
  24. // Look at all the shell folders and see which of them are expected to go to
  25. // local settings on nt5. Some of them might already be moved to random
  26. // locations based on the localisations. We should figure out where it is
  27. // pointing to by looking at these locations and make a call
  28. //*************************************************************
  29. BOOL DetermineLocalSettingsLocation(LPTSTR szLocalSettings)
  30. {
  31. TCHAR szPath[MAX_PATH];
  32. LPTSTR lpEnd, lpBgn;
  33. HKEY hKey, hKeyRoot;
  34. DWORD dwDisp, dwSize, dwType, i;
  35. if (RegOpenCurrentUser(KEY_READ | KEY_WRITE, &hKeyRoot) == ERROR_SUCCESS) {
  36. if (RegOpenKeyEx(hKeyRoot, USER_SHELL_FOLDERS,
  37. 0, KEY_READ, &hKey) == ERROR_SUCCESS) {
  38. for (i=0; i < g_dwNumShellFolders; i++) {
  39. if (c_ShellFolders[i].bNewNT5 && c_ShellFolders[i].bLocalSettings) {
  40. dwSize = sizeof(szPath);
  41. if (RegQueryValueEx(hKey, c_ShellFolders[i].lpFolderName,
  42. 0, &dwType, (LPBYTE)szPath, &dwSize) == ERROR_SUCCESS) {
  43. if (lstrlen(szPath) > lstrlen(TEXT("%userprofile%"))) {
  44. DebugMsg((DM_VERBOSE, TEXT("DetermineLocalSettingsLocation: Considering shell folder %s"), szPath));
  45. //
  46. // Move the pointer upto the next slash
  47. //
  48. lpBgn = szPath + lstrlen(TEXT("%userprofile%"))+1;
  49. lpEnd = lpBgn;
  50. for (;(*lpEnd != TEXT('\0'));lpEnd++) {
  51. //
  52. // we have found a shellfolder of the form %userprofile%\subdir\xxx
  53. // assume this subdir as the localsettings path
  54. //
  55. if (( (*lpEnd) == TEXT('\\') ) && ( (*(lpEnd+1)) != TEXT('\0')) )
  56. break;
  57. }
  58. if ((*lpEnd == TEXT('\\')) && (*(lpEnd+1) != TEXT('\0'))) {
  59. *lpEnd = TEXT('\0');
  60. lstrcpy(szLocalSettings, lpBgn);
  61. DebugMsg((DM_VERBOSE, TEXT("DetermineLocalSettingsLocation: Assuming %s to be the local settings directory"), lpBgn));
  62. RegCloseKey(hKey);
  63. RegCloseKey(hKeyRoot);
  64. return TRUE;
  65. }
  66. }
  67. }
  68. }
  69. }
  70. RegCloseKey(hKey);
  71. }
  72. RegCloseKey(hKeyRoot);
  73. }
  74. //
  75. // otherwise load it from the rc file
  76. //
  77. LoadString (g_hDllInstance, IDS_SH_LOCALSETTINGS, szLocalSettings, MAX_FOLDER_SIZE);
  78. DebugMsg((DM_VERBOSE, TEXT("DetermineLocalSettingsLocation: No Local Settings was found, using %s"), szLocalSettings));
  79. return TRUE;
  80. }
  81. //*************************************************************
  82. //
  83. // MigrateNT4ToNT5()
  84. //
  85. // Purpose: Migrates a user profile from NT4 to NT5
  86. //
  87. // Parameters: none
  88. //
  89. // Return: TRUE if successful
  90. // FALSE if an error occurs
  91. //
  92. //*************************************************************
  93. BOOL WINAPI MigrateNT4ToNT5 (void)
  94. {
  95. TCHAR szTemp[MAX_PATH];
  96. TCHAR szTemp2[MAX_PATH];
  97. TCHAR szTemp3[MAX_PATH];
  98. TCHAR szLocalSettings[MAX_PATH];
  99. LPTSTR lpEnd, lpEnd1, lpBgn=NULL;
  100. HKEY hKey = NULL, hKeyRoot = NULL;
  101. DWORD dwDisp, dwSize, dwType, i;
  102. BOOL bSetTemp = TRUE;
  103. BOOL bCleanUpTemp = FALSE;
  104. WIN32_FILE_ATTRIBUTE_DATA fad;
  105. const LPTSTR szUserProfile = TEXT("%USERPROFILE%\\");
  106. DWORD dwUserProfile = lstrlen(szUserProfile);
  107. DWORD dwString = 0;
  108. int StringLen;
  109. //
  110. // Get the root registry key handle
  111. //
  112. if (RegOpenCurrentUser(KEY_READ | KEY_WRITE, &hKeyRoot) != ERROR_SUCCESS) {
  113. DebugMsg((DM_WARNING, TEXT("MigrateNT4ToNT5: Failed to get root registry key with %d"),
  114. GetLastError()));
  115. }
  116. //
  117. // Convert Personal to My Documents
  118. //
  119. // We have to be careful with this directory. We'll rename
  120. // Personal to My Documents only if the Personal directory
  121. // is empty. After this, we'll fix up the registry special folder
  122. // location only if it is still pointing at the default Personal location.
  123. //
  124. lstrcpy (szTemp, szUserProfile);
  125. if ( LoadString (g_hDllInstance, IDS_SH_PERSONAL2, szTemp2, ARRAYSIZE(szTemp2)) )
  126. {
  127. lstrcpyn (szTemp + dwUserProfile, szTemp2, ARRAYSIZE(szTemp) - dwUserProfile);
  128. ExpandEnvironmentStrings (szTemp, szTemp2, ARRAYSIZE(szTemp2));
  129. //
  130. // Check if the personal directory exists
  131. //
  132. if (GetFileAttributesEx (szTemp2, GetFileExInfoStandard, &fad)) {
  133. //
  134. // Check if the personal directory is empty
  135. //
  136. if (!CountItems (szTemp2)) {
  137. //
  138. // The directory is empty, so rename it to My Documents
  139. //
  140. LoadString (g_hDllInstance, IDS_SH_PERSONAL, szTemp3, ARRAYSIZE(szTemp3));
  141. lstrcpy (szTemp, szUserProfile);
  142. lstrcpyn (szTemp + dwUserProfile, szTemp3, ARRAYSIZE(szTemp) - dwUserProfile);
  143. ExpandEnvironmentStrings (szTemp, szTemp3, ARRAYSIZE(szTemp3));
  144. if (MoveFileEx(szTemp2, szTemp3, 0)) {
  145. //
  146. // Now we need to fix up the registry value if it is still set
  147. // to the default of %USERPROFILE%\Personal
  148. //
  149. if (RegOpenKeyEx (hKeyRoot, USER_SHELL_FOLDERS,
  150. 0, KEY_READ | KEY_WRITE, &hKey) == ERROR_SUCCESS) {
  151. dwSize = sizeof(szTemp3);
  152. szTemp3[0] = TEXT('\0');
  153. if (RegQueryValueEx (hKey, TEXT("Personal"), NULL, &dwType,
  154. (LPBYTE) szTemp3, &dwSize) == ERROR_SUCCESS) {
  155. LoadString (g_hDllInstance, IDS_SH_PERSONAL2, szTemp2, ARRAYSIZE(szTemp2));
  156. lstrcpy (szTemp, szUserProfile);
  157. lstrcpyn (szTemp + dwUserProfile, szTemp2, ARRAYSIZE(szTemp) - dwUserProfile);
  158. if (lstrcmpi(szTemp, szTemp3) == 0) {
  159. LoadString (g_hDllInstance, IDS_SH_PERSONAL, szTemp3, ARRAYSIZE(szTemp3));
  160. lstrcpy (szTemp, szUserProfile);
  161. lstrcpyn (szTemp + dwUserProfile, szTemp3, ARRAYSIZE(szTemp) - dwUserProfile);
  162. RegSetValueEx (hKey, TEXT("Personal"), 0, REG_EXPAND_SZ,
  163. (LPBYTE) szTemp, (lstrlen(szTemp) + 1) * sizeof(TCHAR));
  164. //
  165. // We need to reinitialize the global variables now because
  166. // the path to the My Documents and My Pictures folder has changed.
  167. //
  168. InitializeGlobals(g_hDllInstance);
  169. }
  170. }
  171. RegCloseKey (hKey);
  172. hKey = NULL;
  173. }
  174. }
  175. }
  176. }
  177. }
  178. //
  179. // Get the user profile directory
  180. //
  181. dwString = GetEnvironmentVariable (TEXT("USERPROFILE"), szTemp, ARRAYSIZE (szTemp));
  182. DebugMsg((DM_VERBOSE, TEXT("MigrateNT4ToNT5: Upgrading <%s> from NT4 to NT5"),
  183. szTemp));
  184. //
  185. // Hide ntuser.dat and ntuser.dat.log
  186. //
  187. if(dwString < ARRAYSIZE(szTemp) - 1) {
  188. lpEnd = CheckSlash (szTemp);
  189. lstrcpyn (lpEnd, TEXT("ntuser.dat"), (int)(ARRAYSIZE (szTemp) + szTemp - lpEnd));
  190. }
  191. else {
  192. goto Exit;
  193. }
  194. SetFileAttributes (szTemp, FILE_ATTRIBUTE_HIDDEN);
  195. lstrcpyn (lpEnd, TEXT("ntuser.dat.log"), (int)(ARRAYSIZE (szTemp) + szTemp - lpEnd));
  196. SetFileAttributes (szTemp, FILE_ATTRIBUTE_HIDDEN);
  197. DetermineLocalSettingsLocation(szLocalSettings);
  198. //
  199. // Check if Temporary Internet Files exists in the root of the
  200. // user's profile. If so, move it to the new location
  201. //
  202. // migrate these stuff before we nuke the old User_shell_folders
  203. //
  204. if (RegOpenKeyEx(hKeyRoot, USER_SHELL_FOLDERS,
  205. 0, KEY_READ, &hKey) == ERROR_SUCCESS) {
  206. dwSize = sizeof(szTemp);
  207. if (RegQueryValueEx(hKey, TEXT("Cache"), 0, &dwType, (LPBYTE)szTemp, &dwSize) != ERROR_SUCCESS) {
  208. //
  209. // if this value is not there go by the default location from the
  210. // resources
  211. //
  212. LoadString (g_hDllInstance, IDS_TEMPINTERNETFILES, szTemp2, ARRAYSIZE(szTemp2));
  213. lstrcpy (szTemp, szUserProfile);
  214. lstrcpyn (szTemp + dwUserProfile, szTemp2, ARRAYSIZE (szTemp) - dwUserProfile);
  215. }
  216. ExpandEnvironmentStrings (szTemp, szTemp2, ARRAYSIZE(szTemp2));
  217. if (GetFileAttributesEx (szTemp2, GetFileExInfoStandard, &fad)) {
  218. LoadString (g_hDllInstance, IDS_SH_CACHE, szTemp3, ARRAYSIZE(szTemp3));
  219. lstrcpy (szTemp, szUserProfile);
  220. //
  221. // append the newly found localsettings
  222. //
  223. lstrcpyn (szTemp + dwUserProfile, szLocalSettings, ARRAYSIZE(szTemp) - dwUserProfile);
  224. if(lstrlen(szTemp) < ARRAYSIZE(szTemp) - 1) {
  225. lpEnd = CheckSlash(szTemp);
  226. lstrcpyn (lpEnd, szTemp3, (int)(ARRAYSIZE (szTemp) + szTemp - lpEnd));
  227. }
  228. else {
  229. goto Exit;
  230. }
  231. ExpandEnvironmentStrings (szTemp, szTemp3, ARRAYSIZE(szTemp3));
  232. DebugMsg((DM_VERBOSE, TEXT("MigrateNT4ToNT5: New temp int files folder (expand path) %s"), szTemp3));
  233. DebugMsg((DM_VERBOSE, TEXT("MigrateNT4ToNT5: Old temp int files folder (expand path) %s"), szTemp2));
  234. if (lstrcmpi(szTemp2, szTemp3) != 0) {
  235. if (CopyProfileDirectory (szTemp2, szTemp3, CPD_IGNOREHIVE)) {
  236. Delnode (szTemp2);
  237. }
  238. }
  239. }
  240. //
  241. // Check if History exists in the root of the user's profile.
  242. // If so, move it to the new location
  243. //
  244. dwSize = sizeof(szTemp);
  245. if (RegQueryValueEx(hKey, TEXT("History"), 0, &dwType, (LPBYTE)szTemp, &dwSize) != ERROR_SUCCESS) {
  246. //
  247. // if this value is not there go by the default location from the
  248. // resources
  249. //
  250. LoadString (g_hDllInstance, IDS_HISTORY, szTemp2, ARRAYSIZE(szTemp2));
  251. lstrcpy (szTemp, szUserProfile);
  252. lstrcpyn (szTemp + dwUserProfile, szTemp2, ARRAYSIZE (szTemp) - dwUserProfile);
  253. }
  254. ExpandEnvironmentStrings (szTemp, szTemp2, ARRAYSIZE(szTemp2));
  255. if (GetFileAttributesEx (szTemp2, GetFileExInfoStandard, &fad)) {
  256. LoadString (g_hDllInstance, IDS_SH_HISTORY, szTemp3, ARRAYSIZE(szTemp3));
  257. lstrcpy (szTemp, szUserProfile);
  258. //
  259. // append the newly found localsettings
  260. //
  261. lstrcpyn (szTemp + dwUserProfile, szLocalSettings, ARRAYSIZE(szTemp) - dwUserProfile);
  262. if(lstrlen(szTemp) < ARRAYSIZE(szTemp) - 1) {
  263. lpEnd = CheckSlash(szTemp);
  264. }
  265. else {
  266. goto Exit;
  267. }
  268. lstrcpyn (lpEnd, szTemp3, (int)(ARRAYSIZE (szTemp) + szTemp - lpEnd));
  269. ExpandEnvironmentStrings (szTemp, szTemp3, ARRAYSIZE(szTemp3));
  270. DebugMsg((DM_VERBOSE, TEXT("MigrateNT4ToNT5: New histroy folder (expand path) %s"), szTemp3));
  271. DebugMsg((DM_VERBOSE, TEXT("MigrateNT4ToNT5: Old histroy folder (expand path) %s"), szTemp2));
  272. if (lstrcmpi(szTemp2, szTemp3) != 0) {
  273. if (CopyProfileDirectory (szTemp2, szTemp3, CPD_IGNOREHIVE)) {
  274. Delnode (szTemp2);
  275. SearchAndReplaceIEHistory(IE4_CACHE_KEY, szTemp2, szTemp3);
  276. SearchAndReplaceIEHistory(IE5_CACHE_KEY, szTemp2, szTemp3);
  277. }
  278. }
  279. }
  280. RegCloseKey(hKey);
  281. hKey = NULL;
  282. }
  283. //
  284. // Update the local settings key with the new value
  285. //
  286. lstrcpy (szTemp, szUserProfile);
  287. if(lstrlen(szTemp) < ARRAYSIZE(szTemp) - 1) {
  288. lpEnd = CheckSlash (szTemp);
  289. }
  290. else {
  291. goto Exit;
  292. }
  293. if (RegCreateKeyEx (hKeyRoot, USER_SHELL_FOLDERS,
  294. 0, NULL, REG_OPTION_NON_VOLATILE,
  295. KEY_READ | KEY_WRITE, NULL, &hKey,
  296. &dwDisp) == ERROR_SUCCESS) {
  297. lstrcpyn(lpEnd, szLocalSettings, (int)(ARRAYSIZE(szTemp) + szTemp - lpEnd));
  298. RegSetValueEx (hKey, TEXT("Local Settings"),
  299. 0, REG_EXPAND_SZ, (LPBYTE) szTemp,
  300. ((lstrlen(szTemp) + 1) * sizeof(TCHAR)));
  301. RegCloseKey (hKey);
  302. hKey = NULL;
  303. }
  304. DebugMsg((DM_VERBOSE, TEXT("MigrateNT4ToNT5: Update the local settings folder with %s"), szTemp));
  305. //
  306. // Globals needs to reinitialised because LocalSettings might be different from
  307. // the one specified in the rc file
  308. //
  309. InitializeGlobals(g_hDllInstance);
  310. //
  311. // Get the user profile directory
  312. //
  313. dwString = GetEnvironmentVariable (TEXT("USERPROFILE"), szTemp, ARRAYSIZE (szTemp));
  314. DebugMsg((DM_VERBOSE, TEXT("MigrateNT4ToNT5: Upgrading <%s> from NT4 to NT5"),
  315. szTemp));
  316. if(dwString < ARRAYSIZE(szTemp) - 1) {
  317. lpEnd = CheckSlash (szTemp);
  318. }
  319. else {
  320. goto Exit;
  321. }
  322. //
  323. // Create the new special folders
  324. //
  325. for (i=0; i < g_dwNumShellFolders; i++) {
  326. if (c_ShellFolders[i].bNewNT5) {
  327. lstrcpyn (lpEnd, c_ShellFolders[i].szFolderLocation, (int)(ARRAYSIZE(szTemp) + szTemp - lpEnd));
  328. if (!CreateNestedDirectory(szTemp, NULL)) {
  329. DebugMsg((DM_WARNING, TEXT("MigrateNT4ToNT5: Failed to create the destination directory <%s>. Error = %d"),
  330. szTemp, GetLastError()));
  331. }
  332. if (c_ShellFolders[i].bHidden) {
  333. SetFileAttributes(szTemp, FILE_ATTRIBUTE_HIDDEN);
  334. } else {
  335. SetFileAttributes(szTemp, FILE_ATTRIBUTE_NORMAL);
  336. }
  337. }
  338. }
  339. //
  340. // Set the new special folders in the User Shell Folder registry key
  341. //
  342. lstrcpy (szTemp, szUserProfile);
  343. if(lstrlen(szTemp) < ARRAYSIZE(szTemp) - 1) {
  344. lpEnd = CheckSlash (szTemp);
  345. }
  346. else {
  347. goto Exit;
  348. }
  349. if (RegCreateKeyEx (hKeyRoot, USER_SHELL_FOLDERS,
  350. 0, NULL, REG_OPTION_NON_VOLATILE,
  351. KEY_READ | KEY_WRITE, NULL, &hKey,
  352. &dwDisp) == ERROR_SUCCESS) {
  353. for (i=0; i < g_dwNumShellFolders; i++) {
  354. if (c_ShellFolders[i].bNewNT5 && c_ShellFolders[i].bAddCSIDL) {
  355. lstrcpyn (lpEnd, c_ShellFolders[i].szFolderLocation, (int)(ARRAYSIZE(szTemp) + szTemp - lpEnd));
  356. RegSetValueEx (hKey, c_ShellFolders[i].lpFolderName,
  357. 0, REG_EXPAND_SZ, (LPBYTE) szTemp,
  358. ((lstrlen(szTemp) + 1) * sizeof(TCHAR)));
  359. }
  360. }
  361. RegCloseKey (hKey);
  362. hKey = NULL;
  363. }
  364. //
  365. // Query the user's environment for a TEMP environment variable.
  366. //
  367. if (RegCreateKeyEx (hKeyRoot, TEXT("Environment"), 0,
  368. NULL, REG_OPTION_NON_VOLATILE,
  369. KEY_READ | KEY_WRITE, NULL, &hKey,
  370. &dwDisp) == ERROR_SUCCESS) {
  371. szTemp2[0] = TEXT('\0');
  372. dwSize = sizeof(szTemp2);
  373. RegQueryValueEx (hKey, TEXT("TEMP"), NULL, &dwType,
  374. (LPBYTE) szTemp2, &dwSize);
  375. //
  376. // Decide if we should set the temp and tmp environment variables.
  377. // We need to be careful to not blast someone's custom temp variable
  378. // if it already exists, but at the same time it's ok to remap this if
  379. // temp is still set to the NT4 default of %SystemDrive%\TEMP.
  380. //
  381. if (szTemp2[0] != TEXT('\0')) {
  382. if (lstrcmpi (szTemp2, TEXT("%SystemDrive%\\TEMP")) != 0) {
  383. bSetTemp = FALSE;
  384. }
  385. if (lstrcmpi (szTemp2, TEXT("%USERPROFILE%\\TEMP")) == 0) {
  386. bSetTemp = TRUE;
  387. bCleanUpTemp = TRUE;
  388. }
  389. }
  390. if (bSetTemp) {
  391. LoadString (g_hDllInstance, IDS_SH_TEMP, szTemp2, ARRAYSIZE(szTemp2));
  392. lstrcpyn(lpEnd, szLocalSettings, (int)(ARRAYSIZE(szTemp) + szTemp - lpEnd));
  393. if(lstrlen(szTemp) < ARRAYSIZE(szTemp) - 1) {
  394. lpEnd = CheckSlash(lpEnd);
  395. lstrcpyn (lpEnd, szTemp2, (int)(ARRAYSIZE(szTemp) + szTemp - lpEnd));
  396. }
  397. else {
  398. goto Exit;
  399. }
  400. DebugMsg((DM_VERBOSE, TEXT("MigrateNT4ToNT5: Setting the Temp directory to <%s>"), szTemp));
  401. RegSetValueEx (hKey, TEXT("TEMP"), 0, REG_EXPAND_SZ,
  402. (LPBYTE) szTemp, (lstrlen (szTemp) + 1) * sizeof(TCHAR));
  403. RegSetValueEx (hKey, TEXT("TMP"), 0, REG_EXPAND_SZ,
  404. (LPBYTE) szTemp, (lstrlen (szTemp) + 1) * sizeof(TCHAR));
  405. }
  406. if (bCleanUpTemp) {
  407. ExpandEnvironmentStrings (szTemp, szTemp2, ARRAYSIZE(szTemp2));
  408. ExpandEnvironmentStrings (TEXT("%USERPROFILE%\\TEMP"), szTemp, ARRAYSIZE(szTemp));
  409. if (CopyProfileDirectory (szTemp, szTemp2, CPD_IGNOREHIVE)) {
  410. Delnode (szTemp);
  411. }
  412. }
  413. RegCloseKey (hKey);
  414. hKey = NULL;
  415. }
  416. //
  417. // Migrate the Template Directory if it exists. Copy it from %systemroot%\shellnew
  418. // to Templates directory userprofile..
  419. //
  420. if ((LoadString (g_hDllInstance, IDS_SH_TEMPLATES2, szTemp2, ARRAYSIZE(szTemp2))) &&
  421. (ExpandEnvironmentStrings (szTemp2, szTemp3, ARRAYSIZE(szTemp3))) &&
  422. (LoadString (g_hDllInstance, IDS_SH_TEMPLATES, szTemp2, ARRAYSIZE(szTemp2)))) {
  423. //
  424. // if all of the above succeeded
  425. // szTemp3 will have the full path for the old templates dir..
  426. //
  427. lstrcpy (szTemp, szUserProfile);
  428. lstrcpyn (szTemp + dwUserProfile, szTemp2, ARRAYSIZE(szTemp) - dwUserProfile);
  429. ExpandEnvironmentStrings (szTemp, szTemp2, ARRAYSIZE(szTemp2));
  430. if (GetFileAttributesEx (szTemp3, GetFileExInfoStandard, &fad)) {
  431. DebugMsg((DM_VERBOSE, TEXT("MigrateNT4ToNT5: Copying Template files from %s to %s"), szTemp3, szTemp2));
  432. CopyProfileDirectory(szTemp3, szTemp2, CPD_IGNORECOPYERRORS | CPD_IGNOREHIVE);
  433. }
  434. }
  435. //
  436. // Set the user preference exclusion list. This will
  437. // prevent the Local Settings folder from roaming
  438. //
  439. if (LoadString (g_hDllInstance, IDS_EXCLUSIONLIST,
  440. szTemp, ARRAYSIZE(szTemp))) {
  441. if (RegCreateKeyEx (hKeyRoot, WINLOGON_KEY,
  442. 0, NULL, REG_OPTION_NON_VOLATILE,
  443. KEY_READ | KEY_WRITE, NULL, &hKey,
  444. &dwDisp) == ERROR_SUCCESS) {
  445. dwSize = sizeof(szTemp);
  446. RegQueryValueEx (hKey, TEXT("ExcludeProfileDirs"),
  447. NULL, &dwType, (LPBYTE) szTemp,
  448. &dwSize);
  449. //
  450. // Read in the value of the local settings
  451. //
  452. LoadString (g_hDllInstance, IDS_SH_LOCALSETTINGS,
  453. szTemp2, ARRAYSIZE(szTemp2));
  454. //
  455. // Loop through the list
  456. //
  457. lpBgn = lpEnd = szTemp;
  458. *szTemp3 = TEXT('\0');
  459. while (*lpEnd) {
  460. //
  461. // Look for the semicolon separator
  462. //
  463. while (*lpEnd && ((*lpEnd) != TEXT(';'))) {
  464. lpEnd++;
  465. }
  466. //
  467. // Remove any leading spaces
  468. //
  469. while (*lpBgn == TEXT(' ')) {
  470. lpBgn++;
  471. }
  472. //
  473. // if it has come here we are going to attach something
  474. // to the end of szTmp3
  475. //
  476. StringLen = (int)(lpEnd - lpBgn);
  477. if (*szTemp3)
  478. lstrcpyn(szTemp3 + lstrlen(szTemp3), TEXT(";"), ARRAYSIZE(szTemp3) - lstrlen(szTemp3));
  479. if (CompareString (LOCALE_USER_DEFAULT, NORM_IGNORECASE,
  480. lpBgn, StringLen, szTemp2, lstrlen(szTemp2)) != CSTR_EQUAL) {
  481. int sz = MIN((int)(ARRAYSIZE(szTemp3) - lstrlen(szTemp3)), (StringLen+1));
  482. lstrcpyn(szTemp3+lstrlen(szTemp3), lpBgn, sz);
  483. }
  484. else {
  485. lstrcpyn(szTemp3 + lstrlen(szTemp3), szLocalSettings, ARRAYSIZE(szTemp3) - lstrlen(szTemp3));
  486. }
  487. //
  488. // If we are at the end of the exclusion list, we're done
  489. //
  490. if (!(*lpEnd)) {
  491. break;
  492. }
  493. //
  494. // Prep for the next entry
  495. //
  496. lpEnd++;
  497. lpBgn = lpEnd;
  498. }
  499. RegSetValueEx (hKey, TEXT("ExcludeProfileDirs"),
  500. 0, REG_SZ, (LPBYTE) szTemp3,
  501. ((lstrlen(szTemp3) + 1) * sizeof(TCHAR)));
  502. DebugMsg((DM_VERBOSE, TEXT("MigrateNT4ToNT5: Set the exclusionlist value to default")));
  503. RegCloseKey (hKey);
  504. hKey = NULL;
  505. }
  506. }
  507. //
  508. // Make sure the hidden bit is set correctly for each special folder
  509. //
  510. if (RegOpenKeyEx (hKeyRoot, USER_SHELL_FOLDERS,
  511. 0, KEY_READ, &hKey) == ERROR_SUCCESS) {
  512. for (i=0; i < g_dwNumShellFolders; i++) {
  513. dwSize = sizeof(szTemp);
  514. szTemp[0] = TEXT('\0');
  515. if (RegQueryValueEx (hKey, c_ShellFolders[i].lpFolderName,
  516. NULL, &dwType, (LPBYTE) szTemp,
  517. &dwSize) == ERROR_SUCCESS) {
  518. ExpandEnvironmentStrings (szTemp, szTemp2, ARRAYSIZE(szTemp2));
  519. if (c_ShellFolders[i].bHidden) {
  520. SetFileAttributes(szTemp2, FILE_ATTRIBUTE_HIDDEN);
  521. } else {
  522. SetFileAttributes(szTemp2, FILE_ATTRIBUTE_NORMAL);
  523. }
  524. }
  525. }
  526. RegCloseKey (hKey);
  527. hKey = NULL;
  528. }
  529. Exit:
  530. if(hKey != NULL) {
  531. RegCloseKey(hKey);
  532. }
  533. if (hKeyRoot != NULL) {
  534. RegCloseKey (hKeyRoot);
  535. }
  536. DebugMsg((DM_VERBOSE, TEXT("MigrateNT4ToNT5: Finished.")));
  537. return TRUE;
  538. }
  539. //*************************************************************
  540. //
  541. // ResetUserSpecialFolderPaths()
  542. //
  543. // Purpose: Sets all of the user special folder paths back
  544. // to their defaults
  545. //
  546. // Parameters: none
  547. //
  548. //
  549. // Return: TRUE if successful
  550. // FALSE if an error occurs
  551. //
  552. //*************************************************************
  553. BOOL WINAPI ResetUserSpecialFolderPaths(void)
  554. {
  555. TCHAR szDirectory [MAX_PATH];
  556. HKEY hKey, hKeyRoot;
  557. DWORD dwDisp, i;
  558. LPTSTR lpEnd;
  559. //
  560. // Set the User Shell Folder paths in the registry
  561. //
  562. lstrcpy (szDirectory, TEXT("%USERPROFILE%"));
  563. lpEnd = CheckSlash (szDirectory);
  564. if (RegOpenCurrentUser(KEY_WRITE, &hKeyRoot) == ERROR_SUCCESS) {
  565. if (RegCreateKeyEx (hKeyRoot, USER_SHELL_FOLDERS,
  566. 0, NULL, REG_OPTION_NON_VOLATILE,
  567. KEY_READ | KEY_WRITE, NULL, &hKey,
  568. &dwDisp) == ERROR_SUCCESS) {
  569. for (i=0; i < g_dwNumShellFolders; i++) {
  570. if (c_ShellFolders[i].bAddCSIDL) {
  571. lstrcpy (lpEnd, c_ShellFolders[i].szFolderLocation);
  572. RegSetValueEx (hKey, c_ShellFolders[i].lpFolderName,
  573. 0, REG_EXPAND_SZ, (LPBYTE) szDirectory,
  574. ((lstrlen(szDirectory) + 1) * sizeof(TCHAR)));
  575. }
  576. }
  577. RegCloseKey (hKey);
  578. }
  579. RegCloseKey (hKeyRoot);
  580. }
  581. return TRUE;
  582. }
  583. //*************************************************************
  584. //
  585. // CountItems()
  586. //
  587. // Purpose: Counts the number of files and subdirectories
  588. // in the given subdirectory
  589. //
  590. // Parameters: lpDirectory - parent directory
  591. //
  592. // Return: Item count
  593. //
  594. //*************************************************************
  595. UINT CountItems (LPTSTR lpDirectory)
  596. {
  597. TCHAR szDirectory[MAX_PATH];
  598. HANDLE hFile;
  599. WIN32_FIND_DATA fd;
  600. UINT uiCount = 0;
  601. //
  602. // Search through the directory
  603. //
  604. lstrcpy (szDirectory, lpDirectory);
  605. lstrcat (szDirectory, TEXT("\\*.*"));
  606. hFile = FindFirstFile(szDirectory, &fd);
  607. if (hFile == INVALID_HANDLE_VALUE) {
  608. return uiCount;
  609. }
  610. do {
  611. //
  612. // Check for "." and ".."
  613. //
  614. if (!lstrcmpi(fd.cFileName, TEXT("."))) {
  615. continue;
  616. }
  617. if (!lstrcmpi(fd.cFileName, TEXT(".."))) {
  618. continue;
  619. }
  620. uiCount++;
  621. //
  622. // Find the next entry
  623. //
  624. } while (FindNextFile(hFile, &fd));
  625. FindClose(hFile);
  626. return uiCount;
  627. }
  628. //*************************************************************
  629. //
  630. // SearchAndReplaceIEHistory()
  631. //
  632. // Purpose: Searches and Replaces the registry kesy pointing to
  633. // the old location in IE Cahe to point to New Location
  634. //
  635. // Parameters:
  636. // szIEHistKeyRoot - Root of the history key
  637. // szHistOld - Old History Key
  638. // szHistNew - New Location of History Key
  639. //
  640. // Return: TRUE if success, else False
  641. //
  642. // Created:
  643. //
  644. // Notes:
  645. // Change the "HKCU\S\M\W\CV\Internet Settings\Cache\Extensible Cache\"MSHist***\CachePath" and
  646. // Change the "HKCU\S\M\W\CV\Internet Settings\5.0\Cache\Extensible Cache\MSHis***\CachePath"
  647. // value to the new place
  648. //*************************************************************
  649. BOOL SearchAndReplaceIEHistory(LPTSTR szIEHistKeyRoot, LPTSTR szHistOld, LPTSTR szHistNew)
  650. {
  651. DWORD dwIndex = 0, dwMsHistLen, dwLen;
  652. TCHAR szSubKey[MAX_PATH+1], szSubKey1[MAX_PATH+1];
  653. TCHAR szCachePath[MAX_PATH];
  654. TCHAR szCachePath1[MAX_PATH];
  655. FILETIME ftWrite;
  656. HKEY hIECacheKey, hKey;
  657. DebugMsg((DM_VERBOSE, TEXT("SearchAndReplaceIEHistory: Fixing up the IE Registry keys")));
  658. if (RegOpenKeyEx(HKEY_CURRENT_USER, szIEHistKeyRoot, 0, KEY_ALL_ACCESS, &hKey) == ERROR_SUCCESS) {
  659. DebugMsg((DM_VERBOSE, TEXT("SearchAndReplaceIEHistory: Enumerating the keys under %s"), szIEHistKeyRoot));
  660. dwMsHistLen = lstrlen(IE_CACHEKEY_PREFIX);
  661. dwLen = ARRAYSIZE(szSubKey);
  662. while (RegEnumKeyEx(hKey, dwIndex, szSubKey, &dwLen, NULL, NULL, NULL, &ftWrite) == ERROR_SUCCESS) {
  663. DebugMsg((DM_VERBOSE, TEXT("SearchAndReplaceIEHistory: Testing Key %s"), szSubKey));
  664. lstrcpy(szSubKey1, szSubKey);
  665. szSubKey1[dwMsHistLen] = TEXT('\0');
  666. //
  667. // if the key name starts with MSHist
  668. //
  669. if (lstrcmpi(szSubKey1, IE_CACHEKEY_PREFIX) == 0) {
  670. if (RegOpenKeyEx(hKey, szSubKey, 0, KEY_ALL_ACCESS, &hIECacheKey) == ERROR_SUCCESS) {
  671. DWORD dwLen1;
  672. //
  673. // Get the current value
  674. //
  675. dwLen1 = sizeof(szCachePath);
  676. if (RegQueryValueEx(hIECacheKey, TEXT("CachePath"), 0, NULL, (LPBYTE)szCachePath, &dwLen1) == ERROR_SUCCESS) {
  677. //
  678. // Replace the szHistOld prefix with szHistNew value
  679. //
  680. lstrcpy(szCachePath1, szHistNew);
  681. lstrcpy(szSubKey1, szCachePath);
  682. szSubKey1[lstrlen(szHistOld)] = TEXT('\0');
  683. if (lstrcmpi(szSubKey1, szHistOld) == 0) {
  684. lstrcat(szCachePath1, szCachePath+lstrlen(szHistOld));
  685. RegSetValueEx(hIECacheKey, TEXT("CachePath"), 0, REG_SZ, (LPBYTE)szCachePath1, (lstrlen(szCachePath1)+1)*sizeof(TCHAR));
  686. DebugMsg((DM_VERBOSE, TEXT("SearchAndReplaceIEHistory: Finally, under %s Replacing %s with %s"), szSubKey, szCachePath, szCachePath1));
  687. }
  688. else {
  689. DebugMsg((DM_VERBOSE, TEXT("SearchAndReplaceIEHistory: Existing CachePath %s doesn't have %s, skipping.."), szCachePath, szHistOld));
  690. }
  691. }
  692. else {
  693. DebugMsg((DM_VERBOSE, TEXT("SearchAndReplaceIEHistory: Could not open CachePath value")));
  694. }
  695. RegCloseKey(hIECacheKey);
  696. }
  697. else {
  698. DebugMsg((DM_VERBOSE, TEXT("SearchAndReplaceIEHistory: Could not open %s subkey"), szSubKey));
  699. }
  700. }
  701. else {
  702. DebugMsg((DM_VERBOSE, TEXT("SearchAndReplaceIEHistory: %s subkey does not have %s prefix"), szSubKey, IE_CACHEKEY_PREFIX));
  703. }
  704. dwIndex++;
  705. dwLen = ARRAYSIZE(szSubKey);
  706. DebugMsg((DM_VERBOSE, TEXT("SearchAndReplaceIEHistory: Getting %d subkey next.."), dwIndex+1));
  707. }
  708. //
  709. // Close if the open succeeded
  710. //
  711. RegCloseKey(hKey);
  712. }
  713. else {
  714. DebugMsg((DM_VERBOSE, TEXT("SearchAndReplaceIEHistory: Failed to open the root of the key %s"), szIEHistKeyRoot));
  715. }
  716. return TRUE;
  717. }