]> code.delx.au - refind/commitdiff
Fixed screen-clearing bug; display fs type & size rather than blank
authorsrs5694 <srs5694@users.sourceforge.net>
Tue, 18 Dec 2012 00:12:52 +0000 (19:12 -0500)
committersrs5694 <srs5694@users.sourceforge.net>
Tue, 18 Dec 2012 00:12:52 +0000 (19:12 -0500)
when fs has no label; tweaks to graphics mode-setting code

NEWS.txt
docs/refind/todo.html
libeg/screen.c
refind/global.h
refind/lib.c
refind/main.c
refind/screen.c

index 18712e86b638fd7ad3c2418e262e70e18e78eb83..5561a438315b26214f0b7a7783697d885fd6d448 100644 (file)
--- a/NEWS.txt
+++ b/NEWS.txt
@@ -1,4 +1,17 @@
-0.5.2 (12/??/2012):
+0.6.1 (12/??/2012):
+-------------------
+
+- Instead of displaying a blank filesystem label when a filesystem has
+  none, rEFInd now displays the size of the filesystem, as in "boot
+  EFI\foo\bar.efi from 200 MiB volume" rather than "boot EFI\foo\bar.efi
+  from". For some filesystems, the filesystem type is included, as in "boot
+  EFI\foo\bar.efi from 200 MiB ext3 volume".
+
+- Fixed a bug that caused the screen to clear after displaying an error
+  message but before displaying the "Hit any key to continue" message when
+  a boot loader launch failed.
+
+0.6.0 (12/16/2012):
 -------------------
 
 - Fixed a memory allocation bug that could cause a program crash when
index 459f766a35d76ec39a16c05f7d15931cd8dceae3..d890e43446ad2466312a5cf6baa48759a0f82be4 100644 (file)
@@ -165,6 +165,13 @@ href="mailto:rodsmith@rodsbooks.com">rodsmith@rodsbooks.com</a></p>
        from the partition data is harder than extracting the volume's
        label or counting up the filesystem numbers.</li>
 
+    <li>Currently, if a filesystem's label comes up empty, rEFInd
+       substitutes the size, so you get displays like <tt>boot
+       EFI\foo\bar.efi from 90 GiB volume</tt>. I'd like to add more
+       checks to substitute the GPT <i>partition</i> label if the
+       <i>filesystem</i> label comes up empty, or add a filesystem type
+       identifier to the size.</li>
+
     <li>The default_selection option in refind.conf could be improved by
        supporting a list of default options, so that if the first item
        isn't found, rEFInd will try to boot the second one in the list,
index 90988cf26cf71cb04d2d07a0a7a5259a7d73bfdb..bb55c08f0ef46537a982ea98fead3a00e5cf0ef3 100644 (file)
 #define LibLocateProtocol EfiLibLocateProtocol
 #endif
 
-// Scan for at least this many text-mode and graphics-mode display modes, even
-// if the first modes are invalid. The number of text modes scanned must be at
-// least 3 on some computers to properly list all the available modes when the
-// user specifies an invalid value, since mode 1 (numbered from 0) is often
-// invalid, but mode 2 (the third one) is usually valid. AFAIK, gaps never
-// occur in graphics modes, although I've heard of one case that makes me think
-// some exceptions may occur.
-#define MIN_SCAN_TEXT_MODES 3
-#define MIN_SCAN_GRAPHICS_MODES 1
-
 // Console defines and variables
 
 static EFI_GUID ConsoleControlProtocolGuid = EFI_CONSOLE_CONTROL_PROTOCOL_GUID;
@@ -130,36 +120,39 @@ BOOLEAN egSetScreenSize(IN OUT UINTN *ScreenWidth, IN OUT UINTN *ScreenHeight) {
 
    if (GraphicsOutput != NULL) { // GOP mode (UEFI)
       if (*ScreenHeight == 0) { // User specified a mode number (stored in *ScreenWidth); use it directly
-         ModeNum = (UINT32) *ScreenWidth;
-         Status = refit_call4_wrapper(GraphicsOutput->QueryMode, GraphicsOutput, ModeNum, &Size, &Info);
-         if (Status == EFI_SUCCESS) {
-            Status = refit_call2_wrapper(GraphicsOutput->SetMode, GraphicsOutput, ModeNum);
-            if (Status == EFI_SUCCESS) {
-               ModeSet = TRUE;
-               *ScreenWidth = Info->HorizontalResolution;
-               *ScreenHeight = Info->VerticalResolution;
-            }
-         }
-      } else { // User specified width & height; must find mode
-         // Do a loop through the modes to see if the specified one is available;
-         // and if so, switch to it....
-         do {
+         if (*ScreenWidth == GraphicsOutput->Mode->Mode) { // user requested current mode; do nothing
+            ModeSet = TRUE;
+         } else {
+            ModeNum = (UINT32) *ScreenWidth;
             Status = refit_call4_wrapper(GraphicsOutput->QueryMode, GraphicsOutput, ModeNum, &Size, &Info);
-            if ((Status == EFI_SUCCESS) && (Size >= sizeof(*Info)) &&
-                (Info->HorizontalResolution == *ScreenWidth) && (Info->VerticalResolution == *ScreenHeight)) {
+            if (Status == EFI_SUCCESS) {
                Status = refit_call2_wrapper(GraphicsOutput->SetMode, GraphicsOutput, ModeNum);
-               ModeSet = (Status == EFI_SUCCESS);
-            } // if
-         } while (((++ModeNum < MIN_SCAN_GRAPHICS_MODES) || (Status == EFI_SUCCESS)) && !ModeSet);
-//          while ((Status == EFI_SUCCESS) && (!ModeSet)) {
-//             Status = refit_call4_wrapper(GraphicsOutput->QueryMode, GraphicsOutput, ModeNum, &Size, &Info);
-//             if ((Status == EFI_SUCCESS) && (Size >= sizeof(*Info)) &&
-//                 (Info->HorizontalResolution == *ScreenWidth) && (Info->VerticalResolution == *ScreenHeight)) {
-//                Status = refit_call2_wrapper(GraphicsOutput->SetMode, GraphicsOutput, ModeNum);
-//                ModeSet = (Status == EFI_SUCCESS);
-//             } // if
-//             ModeNum++;
-//          } // while()
+               if (Status == EFI_SUCCESS) {
+                  ModeSet = TRUE;
+                  *ScreenWidth = Info->HorizontalResolution;
+                  *ScreenHeight = Info->VerticalResolution;
+               } // if set mode OK
+            } // if queried mode OK
+         } // if/else
+
+      // User specified width & height; must find mode -- but only if change is required....
+      } else {
+         Status = refit_call4_wrapper(GraphicsOutput->QueryMode, GraphicsOutput, GraphicsOutput->Mode->Mode, &Size, &Info);
+         if ((Status == EFI_SUCCESS) && (Info->HorizontalResolution == *ScreenWidth) &&
+             (Info->VerticalResolution == *ScreenHeight)) {
+            ModeSet = TRUE; // user requested current mode; do nothing
+         } else {
+            // Do a loop through the modes to see if the specified one is available;
+            // and if so, switch to it....
+            do {
+               Status = refit_call4_wrapper(GraphicsOutput->QueryMode, GraphicsOutput, ModeNum, &Size, &Info);
+               if ((Status == EFI_SUCCESS) && (Size >= sizeof(*Info)) &&
+                   (Info->HorizontalResolution == *ScreenWidth) && (Info->VerticalResolution == *ScreenHeight)) {
+                  Status = refit_call2_wrapper(GraphicsOutput->SetMode, GraphicsOutput, ModeNum);
+                  ModeSet = (Status == EFI_SUCCESS);
+               } // if
+            } while ((++ModeNum < GraphicsOutput->Mode->MaxMode) && !ModeSet);
+         } // if/else
       } // if/else
 
       if (ModeSet) {
@@ -174,15 +167,7 @@ BOOLEAN egSetScreenSize(IN OUT UINTN *ScreenWidth, IN OUT UINTN *ScreenHeight) {
             if ((Status == EFI_SUCCESS) && (Info != NULL)) {
                Print(L"Mode %d: %d x %d\n", ModeNum, Info->HorizontalResolution, Info->VerticalResolution);
             } // else
-         } while ((++ModeNum < MIN_SCAN_GRAPHICS_MODES) || (Status == EFI_SUCCESS));
-//          Status = EFI_SUCCESS;
-//          while (Status == EFI_SUCCESS) {
-//             Status = refit_call4_wrapper(GraphicsOutput->QueryMode, GraphicsOutput, ModeNum, &Size, &Info);
-//             if ((Status == EFI_SUCCESS) && (Size >= sizeof(*Info))) {
-//                Print(L"Mode %d: %d x %d\n", ModeNum, Info->HorizontalResolution, Info->VerticalResolution);
-//             } // else
-//             ModeNum++;
-//          } // while()
+         } while (++ModeNum < GraphicsOutput->Mode->MaxMode);
          PauseForKey();
          SwitchToGraphics();
       } // if()
@@ -231,8 +216,8 @@ UINT32 egSetTextMode(UINT32 RequestedMode) {
          do {
             Status = refit_call4_wrapper(ST->ConOut->QueryMode, ST->ConOut, i, &Width, &Height);
             if (Status == EFI_SUCCESS)
-               Print(L"Mode: %d: %d x %d\n", i, Width, Height);
-         } while ((++i < MIN_SCAN_TEXT_MODES) || (Status == EFI_SUCCESS));
+               Print(L"Mode %d: %d x %d\n", i, Width, Height);
+         } while (++i < ST->ConOut->Mode->MaxMode);
 
          PauseForKey();
          SwitchToGraphics();
index a2db177498d905c9940b01abcba97e814ff4b4b2..1d4a1842d6c31b5e8e808925607de1f0df1d4ddd 100644 (file)
 #define DEVICE_TYPE_BIOS       0x05 /* returned by legacy (BIOS) boot loaders */
 #define DEVICE_TYPE_END        0x75 /* end of path */
 
-//TODO: may want to make this configurable via config file
-//static UINT16 SupportedLegacyDevices[] = {BBS_HARDDISK, BBS_CDROM, BBS_USB};
+// Filesystem type identifiers. Not all are yet used....
+#define FS_TYPE_UNKNOWN        0
+#define FS_TYPE_FAT            1
+#define FS_TYPE_EXT2           2
+#define FS_TYPE_EXT3           3
+#define FS_TYPE_EXT4           4
+#define FS_TYPE_HFSPLUS        5
+#define FS_TYPE_REISERFS       6
+#define FS_TYPE_ISO9660        7
 
 //
 // global definitions
@@ -152,6 +159,7 @@ typedef struct {
    EFI_DEVICE_PATH     *WholeDiskDevicePath;
    MBR_PARTITION_INFO  *MbrPartitionTable;
    BOOLEAN             IsReadable;
+   UINT32              FSType;
 } REFIT_VOLUME;
 
 typedef struct _refit_menu_entry {
index 4eb8378b630ed746884a6377ae0a4e9fcc46ec47..91a409b3eb407bd9ca3fe4196dc94024ade04d4f 100644 (file)
@@ -64,6 +64,15 @@ EFI_DEVICE_PATH EndDevicePath[] = {
 //#define EndDevicePath DevicePath
 #endif
 
+// "Magic" signatures for various filesystems
+#define FAT_MAGIC                        0xAA55
+#define EXT2_SUPER_MAGIC                 0xEF53
+#define HFSPLUS_MAGIC1                   0x2B48
+#define HFSPLUS_MAGIC2                   0x5848
+#define REISERFS_SUPER_MAGIC             0x52654973
+#define REISER2FS_SUPER_MAGIC_STRING     "ReIsEr2Fs"
+#define REISER2FS_JR_SUPER_MAGIC_STRING  "ReIsEr3Fs"
+
 // variables
 
 EFI_HANDLE       SelfImageHandle;
@@ -131,39 +140,6 @@ VOID CleanUpPathNameSlashes(IN OUT CHAR16 *PathName) {
    } // if allocation OK
 } // CleanUpPathNameSlashes()
 
-// VOID CleanUpPathNameSlashes(IN OUT CHAR16 *PathName) {
-//    CHAR16   *NewName;
-//    UINTN    i, FinalChar = 0;
-//    BOOLEAN  LastWasSlash = FALSE;
-// 
-//    NewName = AllocateZeroPool(sizeof(CHAR16) * (StrLen(PathName) + 4));
-//    if (NewName != NULL) {
-//       for (i = 0; i < StrLen(PathName); i++) {
-//          if ((PathName[i] == L'/') || (PathName[i] == L'\\')) {
-//             if ((!LastWasSlash) /* && (FinalChar != 0) */)
-//                NewName[FinalChar++] = L'\\';
-//             LastWasSlash = TRUE;
-//          } else {
-//             if (FinalChar == 0) {
-//                NewName[FinalChar++] = L'\\';
-//             }
-//             NewName[FinalChar++] = PathName[i];
-//             LastWasSlash = FALSE;
-//          } // if/else
-//       } // for
-//       NewName[FinalChar] = 0;
-//       if ((FinalChar > 1) && (NewName[FinalChar - 1] == L'\\'))
-//          NewName[--FinalChar] = 0;
-//       if (FinalChar == 0) {
-//          NewName[0] = L'\\';
-//          NewName[1] = 0;
-//       }
-//       // Copy the transformed name back....
-//       StrCpy(PathName, NewName);
-//       FreePool(NewName);
-//    } // if allocation OK
-// } // CleanUpPathNameSlashes()
-
 // Splits an EFI device path into device and filename components. For instance, if InString is
 // PciRoot(0x0)/Pci(0x1f,0x2)/Ata(Secondary,Master,0x0)/HD(2,GPT,8314ae90-ada3-48e9-9c3b-09a88f80d921,0x96028,0xfa000)/\bzImage-3.5.1.efi,
 // this function will truncate that input to
@@ -402,6 +378,83 @@ VOID ExtractLegacyLoaderPaths(EFI_DEVICE_PATH **PathList, UINTN MaxPaths, EFI_DE
 // volume functions
 //
 
+// Return a pointer to a string containing a filesystem type name. If the
+// filesystem type is unknown, a blank (but non-null) string is returned.
+// The returned variable is a constant that should NOT be freed.
+static CHAR16 *FSTypeName(IN UINT32 TypeCode) {
+   CHAR16 *retval = NULL;
+
+   switch (TypeCode) {
+      case FS_TYPE_FAT:
+         retval = L" FAT";
+         break;
+      case FS_TYPE_HFSPLUS:
+         retval = L" HFS+";
+         break;
+      case FS_TYPE_EXT2:
+         retval = L" ext2";
+         break;
+      case FS_TYPE_EXT3:
+         retval = L" ext3";
+         break;
+      case FS_TYPE_EXT4:
+         retval = L" ext4";
+         break;
+      case FS_TYPE_REISERFS:
+         retval = L" ReiserFS";
+         break;
+      case FS_TYPE_ISO9660:
+         retval = L" ISO-9660";
+         break;
+      default:
+         retval = L"";
+         break;
+   } // switch
+   return retval;
+} // CHAR16 *FSTypeName()
+
+// Identify the filesystem type, if possible. Expects a Buffer containing
+// the first few (normally 4096) bytes of the filesystem, and outputs a
+// code representing the identified filesystem type.
+static UINT32 IdentifyFilesystemType(IN UINT8 *Buffer, IN UINTN BufferSize) {
+   UINT32       FoundType = FS_TYPE_UNKNOWN;
+   UINT32       *Ext2Incompat, *Ext2Compat;
+   UINT16       *Magic16;
+
+   if (Buffer != NULL) {
+
+      if (BufferSize >= (1024 + 100)) {
+         Magic16 = (UINT16*) (Buffer + 1024 + 56);
+         if (*Magic16 == EXT2_SUPER_MAGIC) { // ext2/3/4
+            Ext2Compat = (UINT32*) (Buffer + 1024 + 92);
+            Ext2Incompat = (UINT32*) (Buffer + 1024 + 96);
+            if ((*Ext2Incompat & 0x0040) || (*Ext2Incompat & 0x0200)) { // check for extents or flex_bg
+               return FS_TYPE_EXT4;
+            } else if (*Ext2Compat & 0x0004) { // check for journal
+               return FS_TYPE_EXT3;
+            } else { // none of these features; presume it's ext2...
+               return FS_TYPE_EXT2;
+            }
+         }
+      } // search for ext2/3/4 magic
+
+      if (BufferSize >= 512) {
+         Magic16 = (UINT16*) (Buffer + 510);
+         if (*Magic16 == FAT_MAGIC)
+            return FS_TYPE_FAT;
+      } // search for FAT magic
+
+      if (BufferSize >= (1024 + 2)) {
+         Magic16 = (UINT16*) (Buffer + 1024);
+         if ((*Magic16 == HFSPLUS_MAGIC1) || (*Magic16 == HFSPLUS_MAGIC2)) {
+            return FS_TYPE_HFSPLUS;
+         }
+      } // search for HFS+ magic
+   } // if (Buffer != NULL)
+
+   return FoundType;
+}
+
 static VOID ScanVolumeBootcode(IN OUT REFIT_VOLUME *Volume, OUT BOOLEAN *Bootable)
 {
     EFI_STATUS              Status;
@@ -426,6 +479,7 @@ static VOID ScanVolumeBootcode(IN OUT REFIT_VOLUME *Volume, OUT BOOLEAN *Bootabl
                                  Volume->BlockIOOffset, SECTOR_SIZE, SectorBuffer);
     if (!EFI_ERROR(Status)) {
 
+        Volume->FSType = IdentifyFilesystemType(SectorBuffer, SECTOR_SIZE);
         if (*((UINT16 *)(SectorBuffer + 510)) == 0xaa55 && SectorBuffer[0] != 0) {
             *Bootable = TRUE;
             Volume->HasBootCode = TRUE;
@@ -574,6 +628,90 @@ static VOID ScanVolumeDefaultIcon(IN OUT REFIT_VOLUME *Volume)
     } // switch()
 }
 
+// Return a string representing the input size in IEEE-1541 units.
+// The calling function is responsible for freeing the allocated memory.
+static CHAR16 *SizeInIEEEUnits(UINT64 SizeInBytes) {
+   float SizeInIeee;
+   UINTN Index = 0;
+   CHAR16 *Units, *Prefixes = L" KMGTPEZ";
+   CHAR16 *TheValue;
+
+   TheValue = AllocateZeroPool(sizeof(CHAR16) * 80);
+   if (TheValue != NULL) {
+      SizeInIeee = (float) SizeInBytes;
+      while ((SizeInIeee > 1024.0) && (Index < (StrLen(Prefixes) - 1))) {
+         Index++;
+         SizeInIeee /= 1024.0;
+      } // while
+      if (Prefixes[Index] == ' ') {
+         Units = StrDuplicate(L"-byte");
+      } else {
+         Units = StrDuplicate(L"  iB");
+         Units[1] = Prefixes[Index];
+      } // if/else
+      SPrint(TheValue, 79, L"%d%s", (UINTN) SizeInIeee, Units);
+   } // if
+   return TheValue;
+} // CHAR16 *SizeInSIUnits()
+
+// Return a name for the volume. Ideally this should be the label for the
+// filesystem it contains, but this function falls back to describing the
+// filesystem by size (200 MiB, etc.) and/or type (ext2, HFS+, etc.), if
+// this information can be extracted.
+// The calling function is responsible for freeing the memory allocated
+// for the name string.
+static CHAR16 *GetVolumeName(IN REFIT_VOLUME *Volume) {
+   EFI_FILE_SYSTEM_INFO    *FileSystemInfoPtr;
+   CHAR16                  *FoundName = NULL;
+   CHAR16                  *SISize, *TypeName;
+
+   FileSystemInfoPtr = LibFileSystemInfo(Volume->RootDir);
+   if (FileSystemInfoPtr != NULL) {
+       if ((FileSystemInfoPtr->VolumeLabel != NULL) && (StrLen(FileSystemInfoPtr->VolumeLabel) > 0)) {
+          FoundName = StrDuplicate(FileSystemInfoPtr->VolumeLabel);
+       }
+
+       // Special case: rEFInd HFS+ driver always returns label of "HFS+ volume", so wipe
+       // this so that we can build a new name that includes the size....
+       if ((FoundName != NULL) && (StrCmp(FoundName, L"HFS+ volume") == 0) && (Volume->FSType == FS_TYPE_HFSPLUS)) {
+          MyFreePool(FoundName);
+          FoundName = NULL;
+       } // if rEFInd HFS+ driver suspected
+
+       if (FoundName == NULL) { // filesystem has no name....
+          FoundName = AllocateZeroPool(sizeof(CHAR16) * 256);
+          if (FoundName != NULL) {
+             SISize = SizeInIEEEUnits(FileSystemInfoPtr->VolumeSize);
+             SPrint(FoundName, 255, L"%s%s volume", SISize, FSTypeName(Volume->FSType));
+             MyFreePool(SISize);
+          } // if allocated memory OK
+       } // if (FoundName == NULL)
+
+       FreePool(FileSystemInfoPtr);
+
+   } else {
+      FoundName = AllocateZeroPool(sizeof(CHAR16) * 256);
+      if (FoundName != NULL) {
+         TypeName = FSTypeName(Volume->FSType); // NOTE: Don't free TypeName; fn returns constant
+         if (StrLen(TypeName) > 0)
+            SPrint(FoundName, 255, L"%s volume", FSTypeName(Volume->FSType));
+         else
+            SPrint(FoundName, 255, L"unknown volume");
+      } // if allocated memory OK
+   } // if
+
+   // TODO: Above could be improved/extended, in case filesystem name is not found,
+   // such as:
+   //  - use partition label
+   //  - use or add disk/partition number (e.g., "(hd0,2)")
+
+   // Desperate fallback name....
+   if (FoundName == NULL) {
+      FoundName = StrDuplicate(L"unknown volume");
+   }
+   return FoundName;
+} // static CHAR16 *GetVolumeName()
+
 VOID ScanVolume(IN OUT REFIT_VOLUME *Volume)
 {
     EFI_STATUS              Status;
@@ -581,7 +719,6 @@ VOID ScanVolume(IN OUT REFIT_VOLUME *Volume)
     EFI_DEVICE_PATH         *DiskDevicePath, *RemainingDevicePath;
     EFI_HANDLE              WholeDiskHandle;
     UINTN                   PartialLength;
-    EFI_FILE_SYSTEM_INFO    *FileSystemInfoPtr;
     BOOLEAN                 Bootable;
 
     // get device path
@@ -694,20 +831,7 @@ VOID ScanVolume(IN OUT REFIT_VOLUME *Volume)
         Volume->IsReadable = TRUE;
     }
 
-    // get volume name
-    FileSystemInfoPtr = LibFileSystemInfo(Volume->RootDir);
-    if (FileSystemInfoPtr != NULL) {
-        Volume->VolName = StrDuplicate(FileSystemInfoPtr->VolumeLabel);
-        FreePool(FileSystemInfoPtr);
-    }
-
-    if (Volume->VolName == NULL) {
-       Volume->VolName = StrDuplicate(L"Unknown");
-    }
-    // TODO: if no official volume name is found or it is empty, use something else, e.g.:
-    //   - name from bytes 3 to 10 of the boot sector
-    //   - partition number
-    //   - name derived from file system type or partition type
+    Volume->VolName = GetVolumeName(Volume);
 
     // get custom volume icon if present
     if (FileExists(Volume->RootDir, VOLUME_BADGE_NAME))
index ab6efe6452fd7c7a37a8c73259b7871e21bf4939..ea8c337e793e49bf1e2dc028da8bb5c700b78e84 100644 (file)
@@ -118,7 +118,7 @@ static VOID AboutrEFInd(VOID)
 
     if (AboutMenu.EntryCount == 0) {
         AboutMenu.TitleImage = BuiltinIcon(BUILTIN_ICON_FUNC_ABOUT);
-        AddMenuInfoLine(&AboutMenu, L"rEFInd Version 0.6.0");
+        AddMenuInfoLine(&AboutMenu, L"rEFInd Version 0.6.0.1");
         AddMenuInfoLine(&AboutMenu, L"");
         AddMenuInfoLine(&AboutMenu, L"Copyright (c) 2006-2010 Christoph Pfisterer");
         AddMenuInfoLine(&AboutMenu, L"Copyright (c) 2012 Roderick W. Smith");
index 4656e0190be0ce09ec784ac035ef23b3b016f697..7f485a42d303ea48255048f599bc0b0fc12e7b00 100644 (file)
@@ -193,9 +193,6 @@ VOID BeginExternalScreen(IN BOOLEAN UseGraphicsMode, IN CHAR16 *Title)
        DrawScreenHeader(Title);
     } // if/else
 
-    // show the header
-//    DrawScreenHeader(Title);
-
     if (!UseGraphicsMode)
         SwitchToText(TRUE);
 
@@ -205,9 +202,6 @@ VOID BeginExternalScreen(IN BOOLEAN UseGraphicsMode, IN CHAR16 *Title)
 
 VOID FinishExternalScreen(VOID)
 {
-    // Reset the screen resolution, in case external program changed it....
-    SetupScreen();
-
     // make sure we clean up later
     GraphicsScreenDirty = TRUE;
 
@@ -216,6 +210,9 @@ VOID FinishExternalScreen(VOID)
         PauseForKey();
     }
 
+    // Reset the screen resolution, in case external program changed it....
+    SetupScreen();
+
     // reset error flag
     haveError = FALSE;
 }