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.

260 lines
6.9 KiB

  1. #include "enduser.h"
  2. UINT
  3. PresentOsMenu(
  4. IN FPCHAR ImageNames[MAX_PARTITION_IMAGES],
  5. IN FPCHAR ImageDesc[MAX_PARTITION_IMAGES],
  6. IN UINT ImageCount
  7. );
  8. BOOL
  9. ValidateOsSelection(
  10. IN FPCHAR Name
  11. );
  12. VOID
  13. GetUserOsChoice(
  14. IN HDISK DiskHandle
  15. )
  16. {
  17. UINT Selection;
  18. FPCHAR ImageNames[MAX_PARTITION_IMAGES];
  19. FPCHAR ImageDesc[MAX_PARTITION_IMAGES];
  20. UINT Count;
  21. UINT u;
  22. int BaseMsg,DescBase;
  23. FPPARTITION_IMAGE Image;
  24. //
  25. // See if we already got the user's selection. If so, don't get it again.
  26. // If not, get it.
  27. //
  28. if(MasterDiskInfo.State >= MDS_GOT_OS_CHOICE) {
  29. _Log("Already have OS choice (%u), returning\n",MasterDiskInfo.SelectionOrdinal);
  30. return;
  31. }
  32. //
  33. // Validate image count.
  34. //
  35. if(!MasterDiskInfo.ImageCount) {
  36. FatalError(textNoOsImages);
  37. }
  38. //
  39. // Locate the first message for the OS name overrides in the
  40. // message file. We assume the messages are contiguous in the table.
  41. //
  42. Count = GetTextCount();
  43. BaseMsg = -1;
  44. for(u=0; u<Count; u++) {
  45. if(TextMessages[u].Id == TEXT_OS_NAME_BASE) {
  46. BaseMsg = u;
  47. }
  48. if(TextMessages[u].Id == TEXT_OS_DESC_BASE) {
  49. DescBase = u;
  50. }
  51. }
  52. //
  53. // Build the array of names.
  54. //
  55. _Log("Reading partition image headers to build os choice menu...\n\n");
  56. Image = IoBuffer;
  57. for(u=0; u<MasterDiskInfo.ImageCount; u++) {
  58. //
  59. // Read the image's header from the disk.
  60. //
  61. if(!ReadDisk(DiskHandle,MasterDiskInfo.ImageStartSector[u],1,IoBuffer)) {
  62. FatalError(textReadFailedAtSector,1,MasterDiskInfo.ImageStartSector[u]);
  63. }
  64. _Log("Image %u --\n",u);
  65. _Log(" Signature: 0x%lx\n",Image->Signature);
  66. _Log(" Size: %u\n",Image->Size);
  67. _Log(" NonClusterSectors: 0x%lx\n",Image->NonClusterSectors);
  68. _Log(" ClusterCount: 0x%lx\n",Image->ClusterCount);
  69. _Log(" TotalSectorCount: 0x%lx\n",Image->TotalSectorCount);
  70. _Log(" LastUsedCluster: 0x%lx\n",Image->LastUsedCluster);
  71. _Log(" UsedClusterCount: 0x%lx\n",Image->UsedClusterCount);
  72. _Log(" BitmapRelocStart: 0x%lx\n",Image->BitmapRelocationStart);
  73. _Log(" BootRelocStart: 0x%lx\n",Image->BootRelocationStart);
  74. _Log(" SectorsPerCluster: %u\n",Image->SectorsPerCluster);
  75. _Log(" SystemId: %u\n",Image->SystemId);
  76. _Log(" Flags: 0x%x\n",Image->Flags);
  77. _Log("\n");
  78. ImageNames[u] = strdup(*TextMessages[BaseMsg+u].String);
  79. if(!ImageNames[u]) {
  80. FatalError(textOOM);
  81. }
  82. ImageDesc[u] = strdup(*TextMessages[DescBase+u].String);
  83. if(!ImageDesc[u]) {
  84. FatalError(textOOM);
  85. }
  86. }
  87. do {
  88. Selection = PresentOsMenu(ImageNames,ImageDesc,MasterDiskInfo.ImageCount);
  89. } while(!ValidateOsSelection(ImageNames[Selection]));
  90. for(u=0; u<MasterDiskInfo.ImageCount; u++) {
  91. free(ImageNames[u]);
  92. free(ImageDesc[u]);
  93. }
  94. MasterDiskInfo.SelectionOrdinal = Selection;
  95. if(!CmdLineArgs.Test) {
  96. _Log("Updating master disk state for os selection (%u)...\n",Selection);
  97. UpdateMasterDiskState(DiskHandle,MDS_GOT_OS_CHOICE);
  98. _Log("Master disk state for os selection has been updated\n");
  99. }
  100. }
  101. UINT
  102. PresentOsMenu(
  103. IN FPCHAR ImageNames[MAX_PARTITION_IMAGES],
  104. IN FPCHAR ImageDesc[MAX_PARTITION_IMAGES],
  105. IN UINT ImageCount
  106. )
  107. {
  108. UINT u;
  109. BYTE x,top;
  110. UINT LongestName,Length;
  111. char str[80];
  112. USHORT key;
  113. UINT Selection;
  114. int Previous;
  115. FPVOID SaveArea;
  116. unsigned SaveBytesPerRow,SaveTop,SaveHeight,DescriptionTop;
  117. DispClearClientArea(NULL);
  118. DispPositionCursor(TEXT_LEFT_MARGIN,TEXT_TOP_LINE);
  119. DispWriteString(textSelectOsPrompt);
  120. DispWriteString("\n\n");
  121. DispGetCursorPosition(&x,&top);
  122. top++; // top is now first line of menu
  123. #define OS_LEFT 10
  124. DispSetLeftMargin(OS_LEFT);
  125. SaveArea = DispSaveDescriptionArea(&SaveTop,&SaveHeight,&SaveBytesPerRow,&DescriptionTop);
  126. DrainKeyboard();
  127. LongestName = 0;
  128. for(u=0; u<ImageCount; u++) {
  129. Length = strlen(ImageNames[u]);
  130. if(Length > LongestName) {
  131. LongestName = Length;
  132. }
  133. DispWriteString("\n ");
  134. DispWriteString(ImageNames[u]);
  135. }
  136. Selection = 0;
  137. goto highlight;
  138. while((key = GetKey()) != ASCI_CR) {
  139. Previous = -1;
  140. if(key == DN_KEY_UP) {
  141. if(Selection) {
  142. Previous = Selection;
  143. Selection--;
  144. }
  145. } else {
  146. if(key == DN_KEY_DOWN) {
  147. if(Selection < (ImageCount-1)) {
  148. Previous = Selection;
  149. Selection++;
  150. }
  151. }
  152. }
  153. if(Previous != -1) {
  154. //
  155. // Unhighlight the previous one and erase its description
  156. //
  157. memset(str,' ',LongestName+2);
  158. str[LongestName+2] = 0;
  159. memcpy(str+1,ImageNames[Previous],strlen(ImageNames[Previous]));
  160. DispPositionCursor(OS_LEFT,(BYTE)(top+Previous));
  161. DispWriteString(str);
  162. //
  163. // Restore description area
  164. //
  165. if(SaveArea) {
  166. VgaBitBlt(0,SaveTop,640,SaveHeight,SaveBytesPerRow,TRUE,NULL,SaveArea);
  167. } else {
  168. VgaClearRegion(0,SaveTop,640,SaveHeight,VGAPIX_BLUE);
  169. }
  170. //
  171. // Highlight the newly selected one
  172. //
  173. highlight:
  174. memset(str,' ',LongestName+2);
  175. str[LongestName+2] = 0;
  176. memcpy(str+1,ImageNames[Selection],strlen(ImageNames[Selection]));
  177. DispPositionCursor(OS_LEFT,(BYTE)(top+Selection));
  178. DispSetCurrentPixelValue(HIGHLIGHT_TEXT_PIXEL_VALUE);
  179. DispWriteString(str);
  180. //
  181. // Write description
  182. //
  183. DispPositionCursor(1,(BYTE)DescriptionTop);
  184. DispSetLeftMargin(1);
  185. DispSetCurrentPixelValue(VGAPIX_LIGHT_CYAN);
  186. DispWriteString(ImageDesc[Selection]);
  187. //
  188. // Restore defaults for future text display
  189. //
  190. DispSetLeftMargin(OS_LEFT);
  191. DispSetCurrentPixelValue(DEFAULT_TEXT_PIXEL_VALUE);
  192. }
  193. }
  194. if(SaveArea) {
  195. free(SaveArea);
  196. }
  197. DispSetLeftMargin(TEXT_LEFT_MARGIN);
  198. return(Selection);
  199. }
  200. BOOL
  201. ValidateOsSelection(
  202. IN FPCHAR Name
  203. )
  204. {
  205. DispClearClientArea(NULL);
  206. DispPositionCursor(TEXT_LEFT_MARGIN,TEXT_TOP_LINE);
  207. DispWriteString(textConfirmOs1);
  208. DispWriteString("\n\n\n");
  209. DispWriteString(Name);
  210. DispWriteString("\n\n\n");
  211. DispWriteString(textConfirmOs2);
  212. DrainKeyboard();
  213. return(GetKey() == DN_KEY_F8);
  214. }