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.

240 lines
6.8 KiB

  1. //--------------------------------------------------------------
  2. //
  3. // File: scanstate
  4. //
  5. // Contents: Scans the machine and produces an INF file
  6. // describing the machine state.
  7. //
  8. //---------------------------------------------------------------
  9. #include "scanhead.cxx"
  10. #pragma hdrstop
  11. #include <common.hxx>
  12. #include <stdio.h>
  13. #include <io.h>
  14. #include <malloc.h>
  15. #include <setupapi.h>
  16. #include <scanstate.hxx>
  17. #include <bothchar.hxx>
  18. //---------------------------------------------------------------
  19. // Constants.
  20. const char MIGRATEINF[] = "\\migration.inf";
  21. //---------------------------------------------------------------
  22. // Types.
  23. //---------------------------------------------------------------
  24. // Globals.
  25. /***************************************************************************
  26. Function: main
  27. ***************************************************************************/
  28. int _cdecl main(int argc, char *argv[])
  29. {
  30. DWORD result;
  31. BOOL success;
  32. DWORD len;
  33. DWORD dwVersion;
  34. char *migrate;
  35. char *error;
  36. // logfile is not used outside this function so it doesn't need to be
  37. // global like loadstate's is.
  38. char logfile[MAX_PATH+1];
  39. logfile[0] = '\0';
  40. result = OpenFiles();
  41. if (result != ERROR_SUCCESS)
  42. {
  43. goto cleanup;
  44. }
  45. // Parse the parameters.
  46. result = ParseParams( argc, argv, TRUE, logfile );
  47. if (result != ERROR_SUCCESS) goto cleanup;
  48. // Determine the operating system. Major Minor
  49. // NT4 4 0
  50. // Win95 4 0
  51. // Win98 4 10
  52. // Millenium 4 90
  53. dwVersion = GetVersion() & 0xFFFF; // check minor, major numbers
  54. if (FALSE == TestMode)
  55. {
  56. LOG_ASSERT_EXPR((dwVersion==4 || dwVersion==0xA04), IDS_WRONG_OS, result,
  57. ERROR_BAD_ENVIRONMENT );
  58. }
  59. else if (dwVersion != 4 && dwVersion != 0xA04)
  60. Win32PrintfResource( LogFile, IDS_OS_WARNING );
  61. // Load any NT 4 APIs needed.
  62. result = NtImports();
  63. LOG_ASSERT( result );
  64. // Compute the name of migration.inf
  65. len = strlen(MigrationPath) + sizeof(MIGRATEINF) + 2;
  66. migrate = (char *) _alloca( len );
  67. strcpy( migrate, MigrationPath );
  68. strcat( migrate, MIGRATEINF );
  69. // Create the INF file. If the file already exists, but we're using the private
  70. // debugging flag "/q", overwrite it.
  71. OutputFile = CreateFileA( migrate,
  72. GENERIC_WRITE,
  73. 0,
  74. NULL,
  75. !TestMode ? CREATE_NEW : CREATE_ALWAYS,
  76. FILE_ATTRIBUTE_NORMAL,
  77. NULL );
  78. // If the open failed, print a message and exit.
  79. if (OutputFile == INVALID_HANDLE_VALUE)
  80. {
  81. result = GetLastError();
  82. if (result == ERROR_FILE_EXISTS)
  83. {
  84. Win32PrintfResource( Console, IDS_INF_EXISTS, migrate );
  85. }
  86. else
  87. {
  88. Win32PrintfResource( Console, IDS_OPEN_INF_ERROR, migrate );
  89. }
  90. error = NULL;
  91. FormatMessageA( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
  92. 0, result,
  93. MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
  94. (char *) &error, 0, NULL );
  95. if (error != NULL)
  96. {
  97. Win32Printf( Console, error );
  98. LocalFree( error );
  99. }
  100. goto cleanup;
  101. }
  102. //Write the Unicode signature - don't use Win32Printf because that will
  103. //pad the string with zeroes.
  104. if (!OutputAnsi)
  105. {
  106. USHORT sig;
  107. ULONG cbWritten;
  108. sig = 0xfeff;
  109. result = WriteFile(OutputFile, &sig, sizeof(USHORT), &cbWritten, NULL);
  110. if (!result || cbWritten != sizeof(USHORT))
  111. return GetLastError();
  112. }
  113. // Write the version header for the user to the INF file.
  114. result = Win32Printf( OutputFile, "[version]\r\nSignature=""$Windows NT$""\r\n\r\n" );
  115. LOG_ASSERT( result );
  116. DWORD dwLangID;
  117. result = ScanGetLang (&dwLangID);
  118. if (result != ERROR_SUCCESS) goto cleanup;
  119. // Write the OS version to the INF file.
  120. result = Win32Printf( OutputFile, "[%s]\r\n%s=0x%x\r\n%s=%04x\r\n%s=%08x\r\n",
  121. SOURCE_SECTION, VERSION, GetVersion(),
  122. LOCALE, dwLangID, USERLOCALE, GetUserDefaultLCID());
  123. LOG_ASSERT( result );
  124. if (DebugOutput)
  125. Win32Printf(LogFile, "Writing machine settings to output file\r\n");
  126. // Write the machine settings, errors are ignored
  127. // The destination machine should have reasonable defaults for these settings
  128. ScanGetKeyboardLayouts (OutputFile);
  129. ScanGetTimeZone (OutputFile);
  130. ScanGetFullName (OutputFile);
  131. ScanGetOrgName (OutputFile);
  132. result = Win32Printf (OutputFile, "\r\n");
  133. if (result != ERROR_SUCCESS) goto cleanup;
  134. // Initialize file migration structures
  135. if (DebugOutput)
  136. Win32Printf(LogFile, "Initializing file migration structures\r\n");
  137. result = InitializeFiles();
  138. if (result != ERROR_SUCCESS) goto cleanup;
  139. // Compute the temp directory.
  140. result = ComputeTemp();
  141. if (result != ERROR_SUCCESS) goto cleanup;
  142. // Copy the user registry.
  143. if (DebugOutput)
  144. Win32Printf(LogFile, "Initiating ScanUser\r\n");
  145. result = ScanUser();
  146. if (result != ERROR_SUCCESS) goto cleanup;
  147. // Process the extension sections.
  148. if (DebugOutput)
  149. Win32Printf(LogFile, "Processing the extension sections\r\n");
  150. result = ProcessExtensions();
  151. if (result != ERROR_SUCCESS) goto cleanup;
  152. // Process the executable extension sections.
  153. if (DebugOutput)
  154. Win32Printf(LogFile, "Processing the executable extension sections\r\n");
  155. result = ProcessExecExtensions();
  156. if (result != ERROR_SUCCESS) goto cleanup;
  157. // Copy system settings.
  158. if (DebugOutput)
  159. Win32Printf(LogFile, "Scanning system settings\r\n");
  160. result = ScanSystem();
  161. if (result != ERROR_SUCCESS) goto cleanup;
  162. // Copy files.
  163. if (DebugOutput)
  164. Win32Printf(LogFile, "Scanning files\r\n");
  165. result = ScanFiles();
  166. if (result != ERROR_SUCCESS) goto cleanup;
  167. if (DebugOutput)
  168. Win32Printf(LogFile, "ScanState complete. Cleaning up\r\n");
  169. // Clean up user stuff and ignore failures.
  170. CleanupUser();
  171. // Clean up file migration stuff and ignore failures.
  172. CleanupFiles();
  173. cleanup:
  174. // Clean up user stuff and ignore failures.
  175. CleanupUser();
  176. // Close any open files and ignore failures.
  177. CloseFiles();
  178. // Erase the temp directory and ignore failures.
  179. EraseTemp();
  180. // Print a message.
  181. if (Console != INVALID_HANDLE_VALUE)
  182. if (result == ERROR_SUCCESS)
  183. Win32PrintfResource( Console, IDS_COMPLETE_OK );
  184. else
  185. Win32PrintfResource( Console, IDS_COMPLETE_ERROR, logfile );
  186. if (Verbose)
  187. printf( "Returning to dos: 0x%x\r\n", result );
  188. // All done printing stuff, close the console handle
  189. if (Console != INVALID_HANDLE_VALUE)
  190. CloseHandle( Console );
  191. return result;
  192. }