Leaked source code of windows server 2003
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.

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