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.

413 lines
11 KiB

  1. #include "enduser.h"
  2. /*
  3. In message files:
  4. [10000]-[10019] are reserved for language names
  5. [11000]-[11019] are reserved for OS selection names,
  6. which override the names specified in the images'
  7. partition image header structures.
  8. */
  9. //
  10. // Global data
  11. //
  12. FPVOID IoBuffer,_IoBuffer;
  13. MASTER_DISK MasterDiskInfo;
  14. CMD_LINE_ARGS CmdLineArgs;
  15. VOID
  16. GetUserLanguageChoice(
  17. IN HDISK DiskHandle
  18. );
  19. VOID
  20. SwitchMessageFiles(
  21. IN UINT LanguageOrdinal
  22. );
  23. VOID
  24. SwitchBitmapAndFont(
  25. IN UINT LanguageOrdinal
  26. );
  27. VOID
  28. main(
  29. IN int argc,
  30. IN char *argv[]
  31. )
  32. {
  33. HDISK DiskHandle;
  34. UINT MasterDiskId;
  35. ParseArgs(argc,argv,FALSE,"DLMTXY",&CmdLineArgs);
  36. _LogSetFlags(LOGFLAG_CLOSE_REOPEN);
  37. //
  38. // Load the initial message file. If this fails something is *really* hosed.
  39. // Bail out. Note that the bail-out message is in English but there's nothing
  40. // we can do about it since we haven't been able to load the message file!
  41. //
  42. if(!PatchMessagesFromFile("enduser.msg",TextMessages,GetTextCount())) {
  43. fprintf(stderr,"Setup could not load its message file.\n");
  44. fprintf(stderr,"Contact your computer's manufacturer.\n");
  45. return;
  46. }
  47. //
  48. // Load the initial font. If this failes something is *really* hosed.
  49. // We won't even be able to go into graphics mode, but we will be able
  50. // to at least tell the user something's wrong using the text from
  51. // the message file.
  52. //
  53. if(!FontLoadAndInit("enduser.fon")) {
  54. fprintf(stderr,"%s\n\n%s\n\n",textFatalError1,textFatalError2);
  55. fprintf(stderr,textCantLoadFont,"enduser.fon");
  56. fprintf(stderr,"\n");
  57. return;
  58. }
  59. //
  60. // Allocate a maximally-sized track buffer now.
  61. //
  62. if(!AllocTrackBuffer(63,&IoBuffer,&_IoBuffer)) {
  63. _Log("Can't allocate 63-sector I/O buffer\n");
  64. FatalError(textOOM);
  65. }
  66. //
  67. // Initialize the display package. This clears the screen and
  68. // tosses up the background and banner bitmaps.
  69. //
  70. DispInitialize();
  71. //
  72. // Locate and open the master HD. Read the master disk info structure
  73. // off the disk.
  74. //
  75. MasterDiskId = LocateMasterDisk(CmdLineArgs.MasterDiskInt13Unit);
  76. DiskHandle = OpenDisk(MasterDiskId);
  77. if(!DiskHandle) {
  78. FatalError(textCantOpenMasterDisk);
  79. }
  80. if(!ReadDisk(DiskHandle,1,1,IoBuffer)) {
  81. FatalError(textReadFailedAtSector,1,1L);
  82. }
  83. memcpy(&MasterDiskInfo,IoBuffer,sizeof(MASTER_DISK));
  84. _Log("\nInitial master disk info (read from disk sector 1):\n");
  85. _Log(" Signature = 0x%lx\n",MasterDiskInfo.Signature);
  86. _Log(" Size = %u\n",MasterDiskInfo.Size);
  87. _Log(" State = %u\n",MasterDiskInfo.State);
  88. _Log(" StartupPartitionStartSector = 0x%lx\n",MasterDiskInfo.StartupPartitionStartSector);
  89. _Log(" ImageCount = %u\n",MasterDiskInfo.ImageCount);
  90. _Log(" SelectedLanguage = %u\n",MasterDiskInfo.SelectedLanguage);
  91. _Log(" SelectionOrdinal = %u\n",MasterDiskInfo.SelectionOrdinal);
  92. _Log(" ClusterBitmapStart = 0x%lx\n",MasterDiskInfo.ClusterBitmapStart);
  93. _Log(" NonClusterSectorsDone = 0x%lx\n",MasterDiskInfo.NonClusterSectorsDone);
  94. _Log(" ForwardXferSectorCount = 0x%lx\n",MasterDiskInfo.ForwardXferSectorCount);
  95. _Log(" ReverseXferSectorCount = 0x%lx\n",MasterDiskInfo.ReverseXferSectorCount);
  96. _Log(" OriginalSectorsPerTrack = 0x%u\n",MasterDiskInfo.OriginalSectorsPerTrack);
  97. _Log(" OriginalHeads = 0x%u\n",MasterDiskInfo.OriginalHeads);
  98. _Log("\n");
  99. //
  100. // Get user's choice of language and change message files and font
  101. // and banner bitmap.
  102. //
  103. GetUserLanguageChoice(DiskHandle);
  104. SwitchMessageFiles(MasterDiskInfo.SelectedLanguage);
  105. SwitchBitmapAndFont(MasterDiskInfo.SelectedLanguage);
  106. //
  107. // Get user's choice of OSes.
  108. //
  109. GetUserOsChoice(DiskHandle);
  110. //
  111. // Restore the selected OS.
  112. //
  113. RestoreUsersDisk(DiskHandle);
  114. //
  115. // Done, reboot.
  116. //
  117. DispClearClientArea(NULL);
  118. DispPositionCursor(TEXT_LEFT_MARGIN,TEXT_TOP_LINE+2);
  119. DispWriteString(textRebootPrompt1);
  120. DispWriteString("\n\n");
  121. DispWriteString(textRebootPrompt2);
  122. _Log("Done.\n");
  123. while(GetKey() != ASCI_CR) ;
  124. if(CmdLineArgs.Test) {
  125. _asm {
  126. mov ax,3 // standard vga mode
  127. int 10h
  128. }
  129. } else {
  130. RebootSystem();
  131. }
  132. }
  133. VOID
  134. GetUserLanguageChoice(
  135. IN HDISK DiskHandle
  136. )
  137. {
  138. UINT Selection = 0;
  139. int Previous;
  140. UINT OriginalLangCount;
  141. UINT Count,i;
  142. UINT BaseMsg;
  143. BYTE x,y;
  144. USHORT c;
  145. char string[250];
  146. //
  147. // See if we already got the user's selection. If so, don't get it again.
  148. // If not, get it.
  149. //
  150. if(!CmdLineArgs.Test && (MasterDiskInfo.State >= MDS_GOT_LANGUAGE)) {
  151. _Log("Already have language (%u), returning\n",MasterDiskInfo.SelectedLanguage);
  152. return;
  153. }
  154. OriginalLangCount = CmdLineArgs.LanguageCount;
  155. if(CmdLineArgs.LanguageCount > 1) {
  156. _Log("Don't already have language, allow user to select 1 of %u languages\n",CmdLineArgs.LanguageCount);
  157. //
  158. // Verify that we actually have names for these languages.
  159. // Otherwise we could end up following null pointers.
  160. //
  161. CmdLineArgs.LanguageCount = 0;
  162. Count = GetTextCount();
  163. for(i=0; i<Count; i++) {
  164. if(TextMessages[i].Id == TEXT_LANGUAGE_NAME_BASE) {
  165. BaseMsg = i;
  166. while((TextMessages[i].Id <= TEXT_LANGUAGE_NAME_END)
  167. && TextMessages[i].String
  168. && *TextMessages[i].String) {
  169. CmdLineArgs.LanguageCount++;
  170. i++;
  171. }
  172. break;
  173. }
  174. }
  175. if(CmdLineArgs.LanguageCount > OriginalLangCount) {
  176. CmdLineArgs.LanguageCount = OriginalLangCount;
  177. }
  178. }
  179. if(CmdLineArgs.LanguageCount > 1) {
  180. _Log("Language count validated, user will select 1 of %u languages\n",CmdLineArgs.LanguageCount);
  181. reselect:
  182. DrainKeyboard();
  183. DispPositionCursor(TEXT_LEFT_MARGIN,TEXT_TOP_LINE);
  184. DispWriteString(textSelectLanguage);
  185. DispWriteString("\n\n");
  186. DispGetCursorPosition(&x,&y);
  187. y++; // y is coord of top language line
  188. #define LANG_LEFT 15
  189. DispSetLeftMargin(LANG_LEFT);
  190. x = 0;
  191. for(i=0; i<CmdLineArgs.LanguageCount; i++) {
  192. DispWriteString("\n ");
  193. DispWriteString(*TextMessages[BaseMsg+i].String);
  194. if((Count = strlen(*TextMessages[BaseMsg+i].String)) > x) {
  195. x = (BYTE)Count;
  196. }
  197. }
  198. goto highlight;
  199. while((c = GetKey()) != ASCI_CR) {
  200. Previous = -1;
  201. if(c == DN_KEY_UP) {
  202. if(Selection) {
  203. Previous = Selection;
  204. Selection--;
  205. }
  206. } else {
  207. if(c == DN_KEY_DOWN) {
  208. if(Selection < (CmdLineArgs.LanguageCount-1)) {
  209. Previous = Selection;
  210. Selection++;
  211. }
  212. }
  213. }
  214. if(Previous != -1) {
  215. memset(string,' ',x+2);
  216. string[x+2] = 0;
  217. memcpy(
  218. string+1,
  219. *TextMessages[BaseMsg+Previous].String,
  220. strlen(*TextMessages[BaseMsg+Previous].String)
  221. );
  222. DispPositionCursor(LANG_LEFT,(BYTE)(y+Previous));
  223. DispWriteString(string);
  224. highlight:
  225. memset(string,' ',x+2);
  226. string[x+2] = 0;
  227. memcpy(
  228. string+1,
  229. *TextMessages[BaseMsg+Selection].String,
  230. strlen(*TextMessages[BaseMsg+Selection].String)
  231. );
  232. DispPositionCursor(LANG_LEFT,(BYTE)(y+Selection));
  233. DispSetCurrentPixelValue(HIGHLIGHT_TEXT_PIXEL_VALUE);
  234. DispWriteString(string);
  235. DispSetCurrentPixelValue(DEFAULT_TEXT_PIXEL_VALUE);
  236. }
  237. }
  238. DispSetLeftMargin(TEXT_LEFT_MARGIN);
  239. //
  240. // Now confirm.
  241. //
  242. DispClearClientArea(NULL);
  243. DispPositionCursor(TEXT_LEFT_MARGIN,TEXT_TOP_LINE);
  244. sprintf(string,textConfirmLanguage1,*TextMessages[BaseMsg+Selection].String);
  245. DispWriteString(string);
  246. DispWriteString("\n\n");
  247. DispWriteString(textConfirmLanguage2);
  248. DrainKeyboard();
  249. if(GetKey() != ASCI_CR) {
  250. DispClearClientArea(NULL);
  251. goto reselect;
  252. }
  253. } else {
  254. _Log("Language selection option not invoked\n");
  255. Selection = 0;
  256. }
  257. MasterDiskInfo.SelectedLanguage = Selection;
  258. if(!CmdLineArgs.Test) {
  259. _Log("Updating master disk state for language selection (%u)...\n",Selection);
  260. UpdateMasterDiskState(DiskHandle,MDS_GOT_LANGUAGE);
  261. _Log("Master disk state for language selection has been updated\n");
  262. }
  263. }
  264. VOID
  265. SwitchMessageFiles(
  266. IN UINT LanguageOrdinal
  267. )
  268. /*++
  269. Routine Description:
  270. This routine loads a new text message file based on the language
  271. selected by the user.
  272. The filename will be <language_ordinal>.msg.
  273. Arguments:
  274. LanguageOrdinal - supplies the ordinal of the language selected
  275. by the user, 0-n.
  276. Return Value:
  277. None.
  278. --*/
  279. {
  280. char Filename[20];
  281. sprintf(Filename,"%u.msg",LanguageOrdinal);
  282. //
  283. // If this fails, oh, well.
  284. //
  285. PatchMessagesFromFile(Filename,TextMessages,GetTextCount());
  286. }
  287. VOID
  288. SwitchBitmapAndFont(
  289. IN UINT LanguageOrdinal
  290. )
  291. /*++
  292. Routine Description:
  293. This routine loads a new font and banner bitmap based on the language
  294. selected by the user.
  295. The filenames will be <language_ordinal>.fon and .bmp.
  296. Arguments:
  297. LanguageOrdinal - supplies the ordinal of the language selected
  298. by the user, 0-n.
  299. Return Value:
  300. None.
  301. --*/
  302. {
  303. char Filename[20];
  304. //
  305. // If this fails assume the file doesn't exist and
  306. // don't worry about it.
  307. //
  308. sprintf(Filename,"%u.fon",LanguageOrdinal);
  309. FontLoadAndInit(Filename);
  310. //
  311. // Reinitialize the display to recalc font stuff
  312. //
  313. DispReinitialize();
  314. //
  315. // Pass a new banner bitmap filename and reinitialize
  316. // the display area.
  317. //
  318. sprintf(Filename,"%u.bmp",LanguageOrdinal);
  319. DispClearClientArea(Filename);
  320. }