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.

605 lines
15 KiB

  1. /*++
  2. Copyright (c) 1996 Microsoft Corporation
  3. Module Name:
  4. migapp.c
  5. Abstract:
  6. Majority of functions for application migration on the Win95 side..
  7. Everything in this source file called from MigApp_Main.
  8. Author:
  9. Mike Condra (mikeco) 28-Oct-1996
  10. Revision History:
  11. jimschm 23-Sep-1998 Updated for new fileops code
  12. calinn 22-May-1998 Added code for broken CPLs processing.
  13. calinn 03-Feb-1998 ** Major cleanup ** More than 1500 line were deleted.
  14. jimschm 20-Jan-1998 Replaced migration DLL code
  15. marcw 03-Dec-1997 Suprressed the display of hidden directories.
  16. jimschm 02-Dec-1997 Turned off rename of system32 when it is a directory
  17. marcw 15-Jul-1997 Switched to common acc. drives/exclusion handling code.
  18. mikeco 08-Jul-1997 Format per NT common std
  19. mikeco 06-Jun-1997 Pass exclude.inf exclusions thru to migrate.infs.
  20. mikeco 17-Apr-1997 BadSoftwareDeferred_* functions.
  21. marcw 14-Apr-1997 Retrofitted new Progress Bar code into project.
  22. --*/
  23. #include "pch.h"
  24. #include "migdbp.h"
  25. #include "migappp.h"
  26. #include <regstr.h>
  27. #define DBG_MIGAPP "MigApp"
  28. HASHTABLE g_PerUserRegKeys;
  29. //
  30. // MigApp initialization and cleanup (not static)
  31. //
  32. BOOL
  33. WINAPI
  34. MigApp_Entry (
  35. IN HINSTANCE hInstance,
  36. IN DWORD dwReason,
  37. LPVOID lpReserved
  38. )
  39. {
  40. switch (dwReason) {
  41. case DLL_PROCESS_ATTACH:
  42. g_RegKeyPresentIndex = MigDb_GetAttributeIdx ("REGKEYPRESENT");
  43. g_PerUserRegKeys = HtAllocWithData (sizeof (BOOL));
  44. break;
  45. case DLL_PROCESS_DETACH:
  46. HtFree (g_PerUserRegKeys);
  47. break;
  48. }
  49. return TRUE;
  50. }
  51. BOOL
  52. pSearchCompatibleModule (
  53. IN PCTSTR CommandLine,
  54. OUT PTSTR *FullFileName, // OPTIONAL
  55. IN PCTSTR Category95
  56. )
  57. {
  58. TCHAR key [MEMDB_MAX];
  59. TCHAR module [MAX_TCHAR_PATH] = TEXT("");
  60. TCHAR moduleLong [MAX_TCHAR_PATH] = TEXT("");
  61. PATH_ENUM pathEnum;
  62. BOOL result = FALSE;
  63. if (FullFileName) {
  64. *FullFileName = NULL;
  65. }
  66. ExtractArgZeroEx (CommandLine, module, NULL, FALSE);
  67. if (OurGetLongPathName (module, moduleLong, MAX_TCHAR_PATH)) {
  68. MemDbBuildKey (key, Category95, moduleLong, NULL, NULL);
  69. result = MemDbGetValue (key, NULL);
  70. if (FullFileName) {
  71. *FullFileName = DuplicatePathString (moduleLong, 0);
  72. }
  73. } else {
  74. if (EnumFirstPath (&pathEnum, NULL, g_WinDir, g_SystemDir)) {
  75. do {
  76. MemDbBuildKey (key, pathEnum.PtrCurrPath, module, NULL, NULL);
  77. if (OurGetLongPathName (key, moduleLong, MAX_TCHAR_PATH)) {
  78. MemDbBuildKey (key, Category95, moduleLong, NULL, NULL);
  79. result = MemDbGetValue (key, NULL);
  80. if (FullFileName) {
  81. *FullFileName = DuplicatePathString (moduleLong, 0);
  82. }
  83. break;
  84. }
  85. }
  86. while (EnumNextPath (&pathEnum));
  87. }
  88. EnumPathAbort (&pathEnum);
  89. MemDbBuildKey (key, Category95, module, NULL, NULL);
  90. result = MemDbGetValue (key, NULL);
  91. if (FullFileName) {
  92. *FullFileName = DuplicatePathString (module, 0);
  93. }
  94. }
  95. return result;
  96. }
  97. BOOL
  98. pReportBadShell (
  99. VOID
  100. )
  101. {
  102. PCTSTR object = NULL;
  103. PCTSTR message = NULL;
  104. BOOL result = TRUE;
  105. __try {
  106. object = BuildMessageGroup (MSG_INSTALL_NOTES_ROOT, MSG_REPORT_SHELL_SUBGROUP, NULL);
  107. message = GetStringResource (MSG_REPORT_SHELL_INCOMPATIBLE);
  108. if (object && message) {
  109. MsgMgr_ObjectMsg_Add (TEXT("*BadShell"), object, message);
  110. } else {
  111. result = FALSE;
  112. }
  113. }
  114. __finally {
  115. if (object != NULL) {
  116. FreeText (object);
  117. }
  118. if (message != NULL) {
  119. FreeStringResource (message);
  120. }
  121. }
  122. return result;
  123. }
  124. VOID
  125. pProcessAsRunKey (
  126. IN HKEY RunKey
  127. )
  128. {
  129. PCTSTR entryStr;
  130. REGVALUE_ENUM runKeyEnum;
  131. PTSTR fullFileName;
  132. DWORD Status;
  133. if (EnumFirstRegValue (&runKeyEnum, RunKey)) {
  134. do {
  135. entryStr = GetRegValueString (RunKey, runKeyEnum.ValueName);
  136. if (entryStr != NULL) {
  137. if (pSearchCompatibleModule (entryStr, &fullFileName, MEMDB_CATEGORY_COMPATIBLE_RUNKEY)) {
  138. MemDbSetValueEx (
  139. MEMDB_CATEGORY_COMPATIBLE_RUNKEY_NT,
  140. runKeyEnum.ValueName,
  141. NULL,
  142. NULL,
  143. 0,
  144. NULL
  145. );
  146. } else {
  147. if (fullFileName) {
  148. Status = GetFileStatusOnNt (fullFileName);
  149. if (!TreatAsGood (fullFileName)) {
  150. if (!(Status & FILESTATUS_REPLACED)) {
  151. if (!IsFileMarkedAsOsFile (fullFileName)) {
  152. if (!IsFileMarkedForAnnounce (fullFileName)) {
  153. // unknown
  154. AnnounceFileInReport (fullFileName, 0, ACT_INC_SAFETY);
  155. } else {
  156. // known bad
  157. MemDbSetValueEx (
  158. MEMDB_CATEGORY_INCOMPATIBLE_RUNKEY_NT,
  159. runKeyEnum.ValueName,
  160. NULL,
  161. NULL,
  162. 0,
  163. NULL
  164. );
  165. }
  166. }
  167. }
  168. } else {
  169. MemDbSetValueEx (
  170. MEMDB_CATEGORY_COMPATIBLE_RUNKEY_NT,
  171. runKeyEnum.ValueName,
  172. NULL,
  173. NULL,
  174. 0,
  175. NULL
  176. );
  177. }
  178. }
  179. }
  180. FreePathString (fullFileName);
  181. MemFree (g_hHeap, 0, entryStr);
  182. }
  183. } while (EnumNextRegValue (&runKeyEnum));
  184. }
  185. }
  186. BOOL
  187. pProcessRunKey (
  188. VOID
  189. )
  190. {
  191. HKEY runKey;
  192. runKey = OpenRegKeyStr (S_RUNKEY);
  193. if (runKey != NULL) {
  194. pProcessAsRunKey (runKey);
  195. CloseRegKey (runKey);
  196. }
  197. return TRUE;
  198. }
  199. DWORD
  200. ProcessRunKey (
  201. IN DWORD Request
  202. )
  203. {
  204. switch (Request) {
  205. case REQUEST_QUERYTICKS:
  206. return TICKS_PROCESS_RUN_KEY;
  207. case REQUEST_RUN:
  208. if (!pProcessRunKey ()) {
  209. return GetLastError ();
  210. }
  211. else {
  212. return ERROR_SUCCESS;
  213. }
  214. default:
  215. LOG ((LOG_ERROR, "Bad parameter while processing run key."));
  216. }
  217. return 0;
  218. }
  219. VOID
  220. pProcessRunKey_User (
  221. IN PUSERENUM EnumPtr
  222. )
  223. {
  224. HKEY runKey;
  225. runKey = OpenRegKey (EnumPtr->UserRegKey, REGSTR_PATH_RUN);
  226. if (runKey != NULL) {
  227. pProcessAsRunKey (runKey);
  228. CloseRegKey (runKey);
  229. }
  230. }
  231. DWORD
  232. ProcessRunKey_User (
  233. IN DWORD Request,
  234. IN PUSERENUM EnumPtr
  235. )
  236. {
  237. switch (Request) {
  238. case REQUEST_QUERYTICKS:
  239. return TICKS_PROCESS_RUN_KEY;
  240. case REQUEST_BEGINUSERPROCESSING:
  241. //
  242. // No initialization needed.
  243. //
  244. break;
  245. case REQUEST_RUN:
  246. pProcessRunKey_User (EnumPtr);
  247. break;
  248. case REQUEST_ENDUSERPROCESSING:
  249. //
  250. // No cleanup needed.
  251. //
  252. break;
  253. }
  254. return ERROR_SUCCESS;
  255. }
  256. PTSTR
  257. GetFullLongName (
  258. PCTSTR FileName
  259. )
  260. {
  261. PTSTR result = NULL;
  262. TCHAR longName [MAX_TCHAR_PATH];
  263. PTSTR dontCare;
  264. if (DoesFileExist (FileName)) {
  265. if (!OurGetLongPathName (FileName, longName, MAX_TCHAR_PATH)) {
  266. _tcsncpy (longName, FileName, MAX_TCHAR_PATH);
  267. }
  268. result = DuplicatePathString (longName, 0);
  269. }
  270. else {
  271. if (SearchPath (NULL, FileName, NULL, MAX_TCHAR_PATH, longName, &dontCare)) {
  272. result = DuplicatePathString (longName, 0);
  273. }
  274. }
  275. return result;
  276. }
  277. BOOL
  278. pReportIncompatibleSCR (
  279. IN PCTSTR FileName,
  280. IN PMIGDB_CONTEXT Context,
  281. IN WORD ActType
  282. )
  283. {
  284. PTSTR friendlyName = NULL;
  285. PTSTR extPtr = NULL;
  286. PTSTR displayName = NULL;
  287. PCTSTR reportEntry = NULL;
  288. PTSTR component = NULL;
  289. PCTSTR temp1, temp2;
  290. BOOL reportEntryIsResource = TRUE;
  291. if ((Context != NULL) &&
  292. (Context->SectLocalizedName != NULL)
  293. ) {
  294. friendlyName = DuplicatePathString (Context->SectLocalizedName, 0);
  295. }
  296. else {
  297. friendlyName = DuplicatePathString (GetFileNameFromPath (FileName), 0);
  298. extPtr = (PTSTR) GetFileExtensionFromPath (friendlyName);
  299. if (extPtr != NULL) {
  300. extPtr = _tcsdec (friendlyName, extPtr);
  301. if (extPtr != NULL) {
  302. *extPtr = 0;
  303. }
  304. }
  305. displayName = (PTSTR)ParseMessageID (MSG_NICE_PATH_SCREEN_SAVER, &friendlyName);
  306. FreePathString (friendlyName);
  307. friendlyName = NULL;
  308. }
  309. switch (ActType) {
  310. case ACT_REINSTALL:
  311. temp1 = GetStringResource (MSG_REINSTALL_ROOT);
  312. if (!temp1) {
  313. break;
  314. }
  315. temp2 = GetStringResource (
  316. Context && Context->Message ?
  317. MSG_REINSTALL_DETAIL_SUBGROUP :
  318. MSG_REINSTALL_LIST_SUBGROUP
  319. );
  320. if (!temp2) {
  321. break;
  322. }
  323. reportEntry = JoinPaths (temp1, temp2);
  324. reportEntryIsResource = FALSE;
  325. FreeStringResource (temp1);
  326. FreeStringResource (temp2);
  327. break;
  328. case ACT_REINSTALL_BLOCK:
  329. temp1 = GetStringResource (MSG_BLOCKING_ITEMS_ROOT);
  330. if (!temp1) {
  331. break;
  332. }
  333. temp2 = GetStringResource (MSG_REINSTALL_BLOCK_ROOT);
  334. if (!temp2) {
  335. break;
  336. }
  337. reportEntry = JoinPaths (temp1, temp2);
  338. reportEntryIsResource = FALSE;
  339. FreeStringResource (temp1);
  340. FreeStringResource (temp2);
  341. break;
  342. case ACT_MINORPROBLEMS:
  343. reportEntry = GetStringResource (MSG_MINOR_PROBLEM_ROOT);
  344. break;
  345. case ACT_INCOMPATIBLE:
  346. case ACT_INC_NOBADAPPS:
  347. temp1 = GetStringResource (MSG_INCOMPATIBLE_ROOT);
  348. if (!temp1) {
  349. break;
  350. }
  351. temp2 = GetStringResource (
  352. Context && Context->Message ?
  353. MSG_INCOMPATIBLE_DETAIL_SUBGROUP :
  354. MSG_TOTALLY_INCOMPATIBLE_SUBGROUP
  355. );
  356. if (!temp2) {
  357. break;
  358. }
  359. reportEntry = JoinPaths (temp1, temp2);
  360. reportEntryIsResource = FALSE;
  361. FreeStringResource (temp1);
  362. FreeStringResource (temp2);
  363. break;
  364. default:
  365. LOG((LOG_ERROR, "Bad parameter found while processing incompatible screen savers."));
  366. return FALSE;
  367. }
  368. if (!reportEntry) {
  369. LOG((LOG_ERROR, "Cannot read resources while processing incompatible screen savers."));
  370. } else {
  371. component = JoinPaths (reportEntry, displayName?displayName:friendlyName);
  372. MsgMgr_ObjectMsg_Add (FileName, component, Context ? Context->Message : NULL);
  373. FreePathString (component);
  374. if (reportEntryIsResource) {
  375. FreeStringResource (reportEntry);
  376. } else {
  377. FreePathString (reportEntry);
  378. }
  379. reportEntry = NULL;
  380. }
  381. if (displayName) {
  382. FreeStringResourcePtrA (&displayName);
  383. }
  384. if (friendlyName) {
  385. FreePathString (friendlyName);
  386. }
  387. return TRUE;
  388. }
  389. BOOL
  390. pProcessShellSettings (
  391. VOID
  392. )
  393. {
  394. HINF infHandle = INVALID_HANDLE_VALUE;
  395. PCTSTR infName = NULL;
  396. PCTSTR field = NULL;
  397. INFSTRUCT context = INITINFSTRUCT_POOLHANDLE;
  398. PCTSTR saverName = NULL;
  399. TCHAR key [MEMDB_MAX];
  400. PMIGDB_CONTEXT migDbContext;
  401. DWORD actType;
  402. infName = JoinPaths (g_WinDir, TEXT("SYSTEM.INI"));
  403. __try {
  404. infHandle = InfOpenInfFile (infName);
  405. if (infHandle == INVALID_HANDLE_VALUE) {
  406. __leave;
  407. }
  408. if (InfFindFirstLine (infHandle, TEXT("boot"), TEXT("SCRNSAVE.EXE"), &context)) {
  409. field = InfGetStringField (&context, 1);
  410. if (field != NULL) {
  411. // see if this is a compatible module so far
  412. saverName = GetFullLongName (field);
  413. if (saverName) {
  414. MemDbBuildKey (key, MEMDB_CATEGORY_DEFERREDANNOUNCE, saverName, NULL, NULL);
  415. if (MemDbGetValueAndFlags (key, (PDWORD)(&migDbContext), &actType)) {
  416. pReportIncompatibleSCR (saverName, migDbContext, (WORD) actType);
  417. }
  418. FreePathString (saverName);
  419. }
  420. }
  421. }
  422. if (InfFindFirstLine (infHandle, TEXT("boot"), TEXT("SHELL"), &context)) {
  423. field = InfGetStringField (&context, 1);
  424. if (field != NULL) {
  425. if (pSearchCompatibleModule (field, NULL, MEMDB_CATEGORY_COMPATIBLE_SHELL)) {
  426. MemDbSetValueEx (
  427. MEMDB_CATEGORY_COMPATIBLE_SHELL_NT,
  428. field,
  429. NULL,
  430. NULL,
  431. 0,
  432. NULL);
  433. }
  434. else {
  435. pReportBadShell ();
  436. }
  437. }
  438. }
  439. }
  440. __finally {
  441. if (infHandle != INVALID_HANDLE_VALUE) {
  442. InfCloseInfFile (infHandle);
  443. }
  444. if (infName != NULL) {
  445. FreePathString (infName);
  446. }
  447. InfCleanUpInfStruct(&context);
  448. }
  449. return TRUE;
  450. }
  451. DWORD
  452. ProcessShellSettings (
  453. IN DWORD Request
  454. )
  455. {
  456. switch (Request) {
  457. case REQUEST_QUERYTICKS:
  458. return TICKS_PROCESS_SHELL_SETTINGS;
  459. case REQUEST_RUN:
  460. if (!pProcessShellSettings ()) {
  461. return GetLastError ();
  462. }
  463. else {
  464. return ERROR_SUCCESS;
  465. }
  466. default:
  467. LOG ((LOG_ERROR, "Bad parameter found while processing shell settings."));
  468. }
  469. return 0;
  470. }
  471. BOOL
  472. pProcessCompatibleSection (
  473. VOID
  474. )
  475. {
  476. INFCONTEXT context;
  477. CHAR object [MEMDB_MAX];
  478. MYASSERT (g_MigDbInf);
  479. if (SetupFindFirstLine (g_MigDbInf, S_COMPATIBLE, NULL, &context)) {
  480. do {
  481. if (SetupGetStringField (&context, 1, object, MEMDB_MAX, NULL)) {
  482. HandleReportObject (object);
  483. }
  484. }
  485. while (SetupFindNextLine (&context, &context));
  486. }
  487. return TRUE;
  488. }
  489. DWORD
  490. ProcessCompatibleSection (
  491. IN DWORD Request
  492. )
  493. {
  494. switch (Request) {
  495. case REQUEST_QUERYTICKS:
  496. return TICKS_PROCESS_COMPATIBLE_SECTION;
  497. case REQUEST_RUN:
  498. if (!pProcessCompatibleSection ()) {
  499. return GetLastError ();
  500. }
  501. else {
  502. return ERROR_SUCCESS;
  503. }
  504. default:
  505. LOG ((LOG_ERROR, "Bad parameter found while processing compatible files."));
  506. }
  507. return 0;
  508. }