From 2cc79ea9b33424d5fc32f15683adf7c956656b9b Mon Sep 17 00:00:00 2001 From: srs5694 Date: Fri, 30 Jan 2015 20:51:29 -0500 Subject: [PATCH] NTFS driver support, minor filesystem code tweaks, and changes to keyboard handling code. --- CREDITS.txt | 5 +- docs/refind/drivers.html | 52 ++++++++++++++++++--- docs/refind/installing.html | 91 +++++++++++++++++++++++++++++++------ docs/refind/themes.html | 2 + filesystems/Makefile | 12 ++++- filesystems/fsw_btrfs.c | 16 +++---- filesystems/fsw_core.h | 5 +- filesystems/fsw_efi.c | 13 ++++-- filesystems/fsw_ext2.c | 8 ++-- filesystems/fsw_ext4.c | 8 ++-- filesystems/fsw_hfs.c | 8 ++-- filesystems/fsw_iso9660.c | 8 ++-- filesystems/fsw_reiserfs.c | 16 +++---- refind/menu.c | 45 +++++++++++++----- 14 files changed, 215 insertions(+), 74 deletions(-) diff --git a/CREDITS.txt b/CREDITS.txt index 26ec59e..051d523 100644 --- a/CREDITS.txt +++ b/CREDITS.txt @@ -43,8 +43,9 @@ Program (C source code) files: * Stefan Agner (stefan@agner.ch) turned the original ext2fs/ext3fs driver into one that can read ext4fs. -* Samuel Liao ported the GRUB 2 Btrfs code into an EFI driver and - contributed it to this project. +* Samuel Liao ported the GRUB 2 Btrfs and NTFS code into EFI drivers and + contributed them to this project, along with several miscellaneous + improvements. * Emerson Barcelos (emerson_freitas@yahoo.com.br) wrote the code for enabling Intel VMX support (the enable_and_lock_vmx token in diff --git a/docs/refind/drivers.html b/docs/refind/drivers.html index 5c8ca65..3d76467 100644 --- a/docs/refind/drivers.html +++ b/docs/refind/drivers.html @@ -258,6 +258,13 @@ href="mailto:rodsmith@rodsbooks.com">rodsmith@rodsbooks.com

mainly because it compiled cleanly with no extra work, aside from providing a Makefile entry for it. +
  • NTFS—Samuel Liao contributed this driver, which uses the + rEFIt/rEFInd driver framework. My own testing of it is limited, but it + does work for me. Note that this driver is not required + to boot Windows with rEFInd, since Windows stores its boot loader on + the (FAT) ESP. You might use this driver if you want to store large + boot files, such as EFI-accessible RAM disk images, from Windows.
  • +

    All of these drivers rely on filesystem wrapper code written by rEFIt's author, Christoph Phisterer.

    @@ -283,7 +290,7 @@ fs0: map -r -

    Most of these cross-project drivers appear to be related, and most of them have fed into rEFInd's drivers. I used the Clover package, which in turn was based on the VirtualBox drivers, as a starting point. Everybody else has dropped rEFIt's original ReiserFS driver, but I added that back. Of these drivers, only the Clover EFI Tools NTFS driver is missing from rEFInd. Specific versions can have their own quirks, though. For instance, the Clover (and I suspect VirtualBox) drivers don't return volume labels, which causes rEFInd to display loaders on those volumes as being on a disk called Unknown. (I fixed that bug for rEFInd's version, and it wasn't present in the original rEFIt drivers.) Most of these drivers also suffer from speed problems on some computers. This is worst with the ext2fs drivers under VirtualBox; on my main computer, that combination takes 3 minutes to load a Linux kernel and initial RAM disk file! Most real computers don't suffer nearly so badly, but some can take an extra five seconds or so to boot a kernel. I've fixed the speed problems in rEFInd's drivers as of version 0.7.0.

    - -

    Driver availability could increase in the future. Source code to a wide variety of filesystems is available in GRUB Legacy, GRUB 2, Linux, various BSD kernels, and in other projects. Sooner or later somebody's likely to begin porting those drivers to EFI. If you do so, or if you know of additional EFI drivers, please tell me about it, so I can share the information here. Likewise if you know of a source for other EFI drivers—say, for a video card or disk controller card.

    +

    The rEFIt, Clover, and VirtualBox drivers are related, and all of them +have fed into rEFInd's drivers. Specific versions can have their own +quirks, though. For instance, the Clover (and I suspect VirtualBox) drivers +don't return volume labels, which causes rEFInd to display loaders on those +volumes as being on a disk called Unknown. (I fixed that bug for +rEFInd's version, and it wasn't present in the original rEFIt drivers.) +Most of these drivers also suffer from speed problems on some computers. +This is worst with the ext2fs drivers under VirtualBox; on my main +computer, that combination takes 3 minutes to load a Linux kernel and +initial RAM disk file! Most real computers don't suffer nearly so badly, +but some can take an extra five seconds or so to boot a kernel. I've fixed +the speed problems in rEFInd's drivers as of version 0.7.0.

    + +

    Driver availability could increase in the future. If you know of +additional EFI drivers, please tell +me about them, so I can share the information here. Likewise if you +know of a source for other EFI drivers—say, for a video card or disk +controller card.

    Once you've obtained an EFI driver, you can install it in rEFInd just as you would install rEFInd's own drivers, as described earlier.

    @@ -309,9 +331,25 @@ fs0: map -r

    Notes on Specific Drivers

    -

    I've tested several of the drivers described on this page on a handful of systems. The Pfisterer ext2fs driver (from any source) works on both ext2fs and ext3fs, but not on ext4fs—but Agner's derivative ext4fs driver handles ext4fs, so that's not a problem. The ReiserFS driver is obviously useful only on ReiserFS partitions. (Reiser4 is not supported, as far as I know.) The Btrfs driver is the newest of the lot, and so I've tested it the least, but it's worked for me on two test systems. Given that ext2fs, ext3fs, and ReiserFS are getting a bit on in age by Linux standards, you might do well to use them on a separate Linux /boot partition; however, if you're willing to use ext3fs, ext4fs, Btrfs, or ReiserFS on your root (/) filesystem, you can use the EFI drivers to read your kernel from it. Note that this assumes you use conventional partitions; to the best of my knowledge, there's no EFI driver for Linux's Logical Volume Manager (LVM) or Redundant Array of Independent Disks (RAID) configurations, so the EFI can't access filesystems stored in these ways.

    - -

    As noted earlier, rEFInd's drivers prior to version 0.7.0, as well as related drivers from rEFIt, Clover, and VirtualBox, suffer from speed problems. These problems are mostly minor, adding a second or two to boot times; but on some computers, the speed problems can be dramatic, boosting kernel-load times up to as much as three minutes (under VirtualBox). If you run into excessive boot times with such a driver, try switching to the latest rEFInd driver instead.

    +

    I've tested several of the drivers described on this page on a handful +of systems. The Pfisterer ext2fs driver (from any source) works on both +ext2fs and ext3fs, but not on ext4fs—but Agner's derivative ext4fs +driver handles ext4fs, so that's not a problem. The ReiserFS driver is +obviously useful only on ReiserFS partitions. (Reiser4 is not supported, as +far as I know.) The Btrfs driver is the newest of the Linux filesystem +drivers included with rEFInd, and so I've tested it the least, but it's +worked for me on several test systems. Given that ext2fs, ext3fs, and +ReiserFS are getting a bit on in age by Linux standards, you might do well +to use them on a separate Linux /boot partition; however, if +you're willing to use ext3fs, ext4fs, Btrfs, or ReiserFS on your root +(/) filesystem, you can use the EFI drivers to read your kernel +from it. Note that this assumes you use conventional partitions; to the +best of my knowledge, there's no EFI driver for Linux's Logical Volume +Manager (LVM) or Redundant Array of Independent Disks (RAID) +configurations, so the EFI can't access filesystems stored in these +ways.

    + +

    As noted earlier, rEFInd's drivers prior to version 0.7.0, as well as related drivers from rEFIt, Clover, and VirtualBox, suffer from speed problems. These problems are mostly minor, adding a second or two to boot times; but on some computers, the speed problems can be dramatic, boosting kernel-load times up to as much as three minutes (under VirtualBox). If you run into excessive boot times with such a driver, try switching to the latest rEFInd driver instead. You might also try Pete Batard's efifs drivers.

    Although ext2fs, ext3fs, ext4fs, and ReiserFS are all case-sensitive, these drivers treat them in a case-insensitive way. Symbolic links work; however, rEFInd 0.6.11 and later ignore symbolic links, since many distributions use them in a way that creates redundant or non-functional entries in the rEFInd menu. You should be able to use hard links if you want to use a single kernel file in multiple ways (say for two distributions).

    diff --git a/docs/refind/installing.html b/docs/refind/installing.html index 422133a..925c237 100644 --- a/docs/refind/installing.html +++ b/docs/refind/installing.html @@ -198,9 +198,19 @@ href="mailto:rodsmith@rodsbooks.com">rodsmith@rodsbooks.com

  • Fixing Windows Boot Problems
  • -
  • Uninstalling rEFInd
  • +
  • Uninstalling rEFInd - +
  • @@ -1073,27 +1083,79 @@ $ ioreg -l -p IODeviceTree | grep firmware-abi

    Uninstalling rEFInd

    -

    If you decide you don't want to keep rEFInd, you can uninstall it. Doing so is a matter of removing the rEFInd files from your ESP (or from your OS X boot partition, if you installed the program there). In Linux, a command like the following, typed as root, should do the trick:

    +

    If you decide you don't want to keep rEFInd, you can uninstall it. Doing so is a matter of removing the rEFInd files from your ESP (or from your OS X boot partition, if you installed the program there). The exact details of how to do this vary from one OS to another, though; and in some cases there are alternatives to completely uninstalling rEFInd that are easier to implement.

    + + +

    Uninstalling rEFInd from Linux

    +
    + +

    In Linux, a command like the following, typed as root, should remove rEFInd:

     # rm -r /boot/efi/EFI/refind
     
    -

    This example assumes that your ESP is mounted at /boot/efi and that rEFInd is installed in EFI/refind on that partition. If you've mounted your ESP elsewhere, or installed rEFInd elsewhere, you should adjust the command appropriately.

    +

    You must type this command as root (or use sudo in some environments, such as under Ubuntu). This example assumes that your ESP is mounted at /boot/efi and that rEFInd is installed in EFI/refind on that partition. If you've mounted your ESP elsewhere, or installed rEFInd elsewhere, you should adjust the command appropriately.

    -

    The same procedure works in OS X, with the caveat that the ESP isn't normally mounted in OS X. Thus, you must first mount the ESP, as described earlier, in the section on manually installing rEFInd in OS X. (You can forego this step if you installed to the OS X root partition.) You'll also need to use sudo to acquire root privileges. Thus, you'd probably use a command like the following in OS X:

    +

    If you installed via an RPM or Debian package in Linux, using your package manager will remove the package files, but not the files that the installer places on your ESP. Thus, you must uninstall those files manually, as just described. To complete the job, you'll also have to remove /boot/refind_linux.conf, and perhaps the /etc/refind.d directory.

    -
    -$ sudo rm -r /Volumes/esp/EFI/refind
    -
    + +

    Uninstalling rEFInd from OS X

    +
    -

    Many variants of both of these commands are possible on both OS X and Linux. For instance, you'd probably use sudo on Ubuntu. Note that dragging the rEFInd files to the Trash in OS X does not delete them; it just moves them to a different folder. Given the way that Macs reference boot loaders, this means that rEFInd may still launch. If you want to use the Finder to delete rEFInd, be sure to empty the trash after you drag the files there. That should do the job, provided there's no second installation hiding somewhere.

    +

    The easiest way to restore the standard OS X boot loader on a Mac is not to uninstall rEFInd; it's to bypass it. This can be accomplished with the Startup Disk item in the System Preferences panel:

    -

    If you installed via an RPM or Debian package in Linux, using your package manager will remove the package files, but not the files that the installer places on your ESP. Thus, you must uninstall those files manually, as just described. To complete the job, you'll also have to remove /boot/refind_linux.conf, and perhaps the /etc/refind.d directory.

    +
    The OS X Startup Disk tool enables you to reset a Mac
+    to use the standard OS X boot loader.

    + +

    Select your startup disk (Macintosh HD OS X, 10.10.1 in this example) and then click Restart. The computer should reboot into OS X, bypassing rEFInd.

    + +

    I recommend stopping here, because the procedure for completely removing rEFInd from a Mac depends on your installation method and tends to be challenging for many Mac users, who are unfamiliar with the necessary command-line tools. Basically, you must reverse the steps described earlier, in Installing rEFInd Manually Using Mac OS X:

    + +
      + +
    1. You must first determine where rEFInd is installed. If you used the + default installation location, this will be /EFI/refind on + your main partition if you installed rEFInd 0.8.3 or earlier, or in + EFI/refind or EFI/BOOT on the ESP if you installed + rEFInd 0.8.4 with the default options. If you used the + --ownhfs option, rEFInd will be in the + System/Library/CoreServices directory on the volume you + specified.
    2. + +
    3. If necessary, mount the ESP or rEFInd-specific HFS+ volume, as + described in Installing rEFInd Manually Using Mac OS + X.
    4. + +
    5. Verify that rEFInd is installed in the directory noted in step #1. If a + refind.conf file is present, rEFInd is almost certainly + installed in that directory. If not, it's not rEFInd there and you + should not proceed. Be extra cautious about deleting the + System/Library/CoreServices directory, since that's + the default location of the OS X boot loader!
    6. + +
    7. Once you've identified the rEFInd directory, delete it, or at least the + rEFInd boot file. This file may be called refind_x64.efi, + bootx64.efi, boot.efi, or conceivably something else. + You may need to use sudo rm at the command line to accomplish + this task, as in sudo rm -r + /Volumes/esp/EFI/refind. Note that dragging files to the Trash on + the Desktop may not be adequate unless you also empty the Trash.
    8. + +
    + + +

    Uninstalling rEFInd from Windows

    +

    From Windows, you must reverse the directions for installing in Windows—type mountvol S: /S to mount your ESP as S:, then navigate to the S:\EFI directory and delete the refind subdirectory.

    -

    In any of these cases, when the computer boots and cannot find the rEFInd files, it should move on to the next boot loader in its list. In my experience, some EFI firmware implementations remove boot loaders they can't find from their NVRAM lists, so nothing else will be required, provided you have another working boot loader in your firmware's list. If your firmware doesn't automatically clean up its NVRAM entries, rEFInd's entry will do little harm; however, you can delete it with the efibootmgr utility in Linux:

    + +

    Post-Uninstallation Activity (UEFI-Based PCs)

    +
    + +

    On a UEFI-based PC, when the computer boots and cannot find the rEFInd files, it should move on to the next boot loader in its list. In my experience, some EFI firmware implementations remove boot loaders they can't find from their NVRAM lists, so nothing else will be required, provided you have another working boot loader in your firmware's list. If your firmware doesn't automatically clean up its NVRAM entries, rEFInd's entry will do little harm; however, you can delete it with the efibootmgr utility in Linux:

     # efibootmgr --verbose
    @@ -1110,11 +1172,14 @@ Boot0007* CD/DVD Drive

    This example shows use of efibootmgr's --verbose (-v) option to display boot programs so as to identify which one is rEFInd, followed by --delete-bootnum (-B) to delete a boot program and --bootnum (-b) to identify which one to delete. Of course, in this example there's not much else left, so you'd presumably want to install another boot program at this point! If you already have another one installed, you may want to check the BootOrder line to determine which one will take precedence when you reboot. If you don't like what it shows, you can adjust it with the --bootorder (-o) option; consult efibootmgr's man page for details.

    -

    If you're not using Linux, you may be able to find a utility that serves a similar function. The OS X bless utility (or its GUI equivalent, the Startup Disk item in System Preferences) should do the trick; but Macs pick up standard OS X boot loaders when they boot and find that a configured non-standard boot loader is missing, so this shouldn't be necessary on Macs. Under Windows, the bcdedit command, described in the section on installing rEFInd under Windows, may work, although I've not attempted this.

    +

    If you're not using Linux, you may be able to find a utility that serves +a similar function. Under Windows, the bcdedit command, described +in the section on installing rEFInd under Windows, +may work, although I've not attempted this.


    -

    copyright © 2012–2014 by Roderick W. Smith

    +

    copyright © 2012–2015 by Roderick W. Smith

    This document is licensed under the terms of the GNU Free Documentation License (FDL), version 1.3.

    diff --git a/docs/refind/themes.html b/docs/refind/themes.html index f27db13..a7a2472 100644 --- a/docs/refind/themes.html +++ b/docs/refind/themes.html @@ -292,6 +292,8 @@ to be tedious.

  • jamaladdeen on deviantART has created an OS X theme that resembles the OS X environment.
  • +
  • Brian Lechthaler has created an alternative rEFInd banner. +

    If you've created or discovered another rEFInd theme, please tell me about it so that I can provide a link to it from this page.

    diff --git a/filesystems/Makefile b/filesystems/Makefile index 74d03da..ef83ceb 100644 --- a/filesystems/Makefile +++ b/filesystems/Makefile @@ -8,8 +8,8 @@ INSTALL_DIR = /boot/efi/EFI/refind/drivers -FILESYSTEMS = ext2 ext4 reiserfs iso9660 hfs btrfs -FILESYSTEMS_GNUEFI = ext2_gnuefi ext4_gnuefi reiserfs_gnuefi iso9660_gnuefi hfs_gnuefi btrfs_gnuefi +FILESYSTEMS = ext2 ext4 reiserfs iso9660 hfs btrfs ntfs +FILESYSTEMS_GNUEFI = ext2_gnuefi ext4_gnuefi reiserfs_gnuefi iso9660_gnuefi hfs_gnuefi btrfs_gnuefi ntfs_gnuefi TEXTFILES = $(FILESYSTEMS:=*.txt) # Build the drivers with TianoCore EDK2..... @@ -44,6 +44,10 @@ btrfs: rm -f fsw_efi.obj +make DRIVERNAME=btrfs -f Make.tiano +ntfs: + rm -f fsw_efi.obj + +make DRIVERNAME=ntfs -f Make.tiano + # Build the drivers with GNU-EFI.... gnuefi: $(FILESYSTEMS_GNUEFI) @@ -78,6 +82,10 @@ btrfs_gnuefi: rm -f fsw_efi.o +make DRIVERNAME=btrfs -f Make.gnuefi +ntfs_gnuefi: + rm -f fsw_efi.o + +make DRIVERNAME=ntfs -f Make.gnuefi + # utility rules clean: diff --git a/filesystems/fsw_btrfs.c b/filesystems/fsw_btrfs.c index c05547d..566be85 100644 --- a/filesystems/fsw_btrfs.c +++ b/filesystems/fsw_btrfs.c @@ -1165,19 +1165,19 @@ static fsw_status_t fsw_btrfs_dnode_stat(struct fsw_volume *volg, struct fsw_dno /* slave device got empty root */ if(dno->raw == NULL) { sb->used_bytes = 0; - sb->store_time_posix(sb, FSW_DNODE_STAT_CTIME, 0); - sb->store_time_posix(sb, FSW_DNODE_STAT_ATIME, 0); - sb->store_time_posix(sb, FSW_DNODE_STAT_MTIME, 0); + fsw_store_time_posix(sb, FSW_DNODE_STAT_CTIME, 0); + fsw_store_time_posix(sb, FSW_DNODE_STAT_ATIME, 0); + fsw_store_time_posix(sb, FSW_DNODE_STAT_MTIME, 0); return FSW_SUCCESS; } sb->used_bytes = fsw_u64_le_swap(dno->raw->nbytes); - sb->store_time_posix(sb, FSW_DNODE_STAT_ATIME, + fsw_store_time_posix(sb, FSW_DNODE_STAT_ATIME, fsw_u64_le_swap(dno->raw->atime.sec)); - sb->store_time_posix(sb, FSW_DNODE_STAT_CTIME, + fsw_store_time_posix(sb, FSW_DNODE_STAT_CTIME, fsw_u64_le_swap(dno->raw->ctime.sec)); - sb->store_time_posix(sb, FSW_DNODE_STAT_MTIME, + fsw_store_time_posix(sb, FSW_DNODE_STAT_MTIME, fsw_u64_le_swap(dno->raw->mtime.sec)); - sb->store_attr_posix(sb, fsw_u32_le_swap(dno->raw->mode)); + fsw_store_attr_posix(sb, fsw_u32_le_swap(dno->raw->mode)); return FSW_SUCCESS; } @@ -1325,7 +1325,7 @@ static fsw_status_t fsw_btrfs_get_extent(struct fsw_volume *volg, struct fsw_dno vol->extend = vol->extstart + fsw_u64_le_swap (vol->extent->size); if (vol->extent->type == GRUB_BTRFS_EXTENT_REGULAR - && (char *) &vol->extent + elemsize + && (char *) vol->extent + elemsize >= (char *) &vol->extent->filled + sizeof (vol->extent->filled)) vol->extend = vol->extstart + fsw_u64_le_swap (vol->extent->filled); diff --git a/filesystems/fsw_core.h b/filesystems/fsw_core.h index da86409..5d887fd 100644 --- a/filesystems/fsw_core.h +++ b/filesystems/fsw_core.h @@ -319,8 +319,6 @@ struct fsw_volume_stat { struct fsw_dnode_stat { fsw_u64 used_bytes; //!< Bytes actually used by the file on disk - void (*store_time_posix)(struct fsw_dnode_stat *sb, int which, fsw_u32 posix_time); //!< Callback for storing a Posix-style timestamp - void (*store_attr_posix)(struct fsw_dnode_stat *sb, fsw_u16 posix_mode); //!< Callback for storing a Posix-style file mode void *host_data; //!< Hook for a host-specific data structure }; @@ -422,6 +420,9 @@ fsw_status_t fsw_dnode_dir_read(struct fsw_shandle *shand, struct fsw_dnode **ch fsw_status_t fsw_dnode_readlink(struct fsw_dnode *dno, struct fsw_string *link_target); fsw_status_t fsw_dnode_readlink_data(struct DNODESTRUCTNAME *dno, struct fsw_string *link_target); fsw_status_t fsw_dnode_resolve(struct fsw_dnode *dno, struct fsw_dnode **target_dno_out); +void fsw_store_time_posix(struct fsw_dnode_stat *sb, int which, fsw_u32 posix_time); +void fsw_store_attr_posix(struct fsw_dnode_stat *sb, fsw_u16 posix_mode); +void fsw_store_attr_efi(struct fsw_dnode_stat *sb, fsw_u16 attr); /*@}*/ diff --git a/filesystems/fsw_efi.c b/filesystems/fsw_efi.c index f2cb4fe..762831e 100644 --- a/filesystems/fsw_efi.c +++ b/filesystems/fsw_efi.c @@ -1087,7 +1087,7 @@ EFI_STATUS fsw_efi_dnode_getinfo(IN FSW_FILE_DATA *File, * appropriate member of the EFI_FILE_INFO structure that we're filling. */ -static void fsw_efi_store_time_posix(struct fsw_dnode_stat *sb, int which, fsw_u32 posix_time) +void fsw_store_time_posix(struct fsw_dnode_stat *sb, int which, fsw_u32 posix_time) { EFI_FILE_INFO *FileInfo = (EFI_FILE_INFO *)sb->host_data; @@ -1105,7 +1105,7 @@ static void fsw_efi_store_time_posix(struct fsw_dnode_stat *sb, int which, fsw_u * adjustments to the EFI_FILE_INFO structure that we're filling. */ -static void fsw_efi_store_attr_posix(struct fsw_dnode_stat *sb, fsw_u16 posix_mode) +void fsw_store_attr_posix(struct fsw_dnode_stat *sb, fsw_u16 posix_mode) { EFI_FILE_INFO *FileInfo = (EFI_FILE_INFO *)sb->host_data; @@ -1113,6 +1113,13 @@ static void fsw_efi_store_attr_posix(struct fsw_dnode_stat *sb, fsw_u16 posix_mo FileInfo->Attribute |= EFI_FILE_READ_ONLY; } +void fsw_store_attr_efi(struct fsw_dnode_stat *sb, fsw_u16 attr) +{ + EFI_FILE_INFO *FileInfo = (EFI_FILE_INFO *)sb->host_data; + + FileInfo->Attribute |= attr; +} + /** * Common function to fill an EFI_FILE_INFO with information about a dnode. */ @@ -1158,8 +1165,6 @@ EFI_STATUS fsw_efi_dnode_fill_FileInfo(IN FSW_VOLUME_DATA *Volume, // get the missing info from the fs driver ZeroMem(&sb, sizeof(struct fsw_dnode_stat)); - sb.store_time_posix = fsw_efi_store_time_posix; - sb.store_attr_posix = fsw_efi_store_attr_posix; sb.host_data = FileInfo; Status = fsw_efi_map_status(fsw_dnode_stat(dno, &sb), Volume); if (EFI_ERROR(Status)) diff --git a/filesystems/fsw_ext2.c b/filesystems/fsw_ext2.c index 1b68b99..4a0acf3 100644 --- a/filesystems/fsw_ext2.c +++ b/filesystems/fsw_ext2.c @@ -257,10 +257,10 @@ static fsw_status_t fsw_ext2_dnode_stat(struct fsw_ext2_volume *vol, struct fsw_ struct fsw_dnode_stat *sb) { sb->used_bytes = dno->raw->i_blocks * 512; // very, very strange... - sb->store_time_posix(sb, FSW_DNODE_STAT_CTIME, dno->raw->i_ctime); - sb->store_time_posix(sb, FSW_DNODE_STAT_ATIME, dno->raw->i_atime); - sb->store_time_posix(sb, FSW_DNODE_STAT_MTIME, dno->raw->i_mtime); - sb->store_attr_posix(sb, dno->raw->i_mode); + fsw_store_time_posix(sb, FSW_DNODE_STAT_CTIME, dno->raw->i_ctime); + fsw_store_time_posix(sb, FSW_DNODE_STAT_ATIME, dno->raw->i_atime); + fsw_store_time_posix(sb, FSW_DNODE_STAT_MTIME, dno->raw->i_mtime); + fsw_store_attr_posix(sb, dno->raw->i_mode); return FSW_SUCCESS; } diff --git a/filesystems/fsw_ext4.c b/filesystems/fsw_ext4.c index 2d731c7..7cdca91 100644 --- a/filesystems/fsw_ext4.c +++ b/filesystems/fsw_ext4.c @@ -335,10 +335,10 @@ static fsw_status_t fsw_ext4_dnode_stat(struct fsw_ext4_volume *vol, struct fsw_ struct fsw_dnode_stat *sb) { sb->used_bytes = dno->raw->i_blocks_lo * EXT4_BLOCK_SIZE(vol->sb); // very, very strange... - sb->store_time_posix(sb, FSW_DNODE_STAT_CTIME, dno->raw->i_ctime); - sb->store_time_posix(sb, FSW_DNODE_STAT_ATIME, dno->raw->i_atime); - sb->store_time_posix(sb, FSW_DNODE_STAT_MTIME, dno->raw->i_mtime); - sb->store_attr_posix(sb, dno->raw->i_mode); + fsw_store_time_posix(sb, FSW_DNODE_STAT_CTIME, dno->raw->i_ctime); + fsw_store_time_posix(sb, FSW_DNODE_STAT_ATIME, dno->raw->i_atime); + fsw_store_time_posix(sb, FSW_DNODE_STAT_MTIME, dno->raw->i_mtime); + fsw_store_attr_posix(sb, dno->raw->i_mode); return FSW_SUCCESS; } diff --git a/filesystems/fsw_hfs.c b/filesystems/fsw_hfs.c index 76df9a3..d5c8ed5 100644 --- a/filesystems/fsw_hfs.c +++ b/filesystems/fsw_hfs.c @@ -530,10 +530,10 @@ static fsw_status_t fsw_hfs_dnode_stat(struct fsw_hfs_volume *vol, struct fsw_dnode_stat *sb) { sb->used_bytes = dno->used_bytes; - sb->store_time_posix(sb, FSW_DNODE_STAT_CTIME, mac_to_posix(dno->ctime)); - sb->store_time_posix(sb, FSW_DNODE_STAT_MTIME, mac_to_posix(dno->mtime)); - sb->store_time_posix(sb, FSW_DNODE_STAT_ATIME, 0); - sb->store_attr_posix(sb, 0700); + fsw_store_time_posix(sb, FSW_DNODE_STAT_CTIME, mac_to_posix(dno->ctime)); + fsw_store_time_posix(sb, FSW_DNODE_STAT_MTIME, mac_to_posix(dno->mtime)); + fsw_store_time_posix(sb, FSW_DNODE_STAT_ATIME, 0); + fsw_store_attr_posix(sb, 0700); return FSW_SUCCESS; } diff --git a/filesystems/fsw_iso9660.c b/filesystems/fsw_iso9660.c index 697c440..9962cb7 100644 --- a/filesystems/fsw_iso9660.c +++ b/filesystems/fsw_iso9660.c @@ -452,10 +452,10 @@ static fsw_status_t fsw_iso9660_dnode_stat(struct fsw_iso9660_volume *vol, struc { sb->used_bytes = (dno->g.size + (ISO9660_BLOCKSIZE-1)) & ~(ISO9660_BLOCKSIZE-1); /* - sb->store_time_posix(sb, FSW_DNODE_STAT_CTIME, dno->raw->i_ctime); - sb->store_time_posix(sb, FSW_DNODE_STAT_ATIME, dno->raw->i_atime); - sb->store_time_posix(sb, FSW_DNODE_STAT_MTIME, dno->raw->i_mtime); - sb->store_attr_posix(sb, dno->raw->i_mode); + fsw_store_time_posix(sb, FSW_DNODE_STAT_CTIME, dno->raw->i_ctime); + fsw_store_time_posix(sb, FSW_DNODE_STAT_ATIME, dno->raw->i_atime); + fsw_store_time_posix(sb, FSW_DNODE_STAT_MTIME, dno->raw->i_mtime); + fsw_store_attr_posix(sb, dno->raw->i_mode); */ return FSW_SUCCESS; diff --git a/filesystems/fsw_reiserfs.c b/filesystems/fsw_reiserfs.c index ee33aea..79978e5 100644 --- a/filesystems/fsw_reiserfs.c +++ b/filesystems/fsw_reiserfs.c @@ -304,16 +304,16 @@ static fsw_status_t fsw_reiserfs_dnode_stat(struct fsw_reiserfs_volume *vol, str sb->used_bytes = 0; else sb->used_bytes = dno->sd_v1->u.sd_blocks * vol->g.log_blocksize; - sb->store_time_posix(sb, FSW_DNODE_STAT_CTIME, dno->sd_v1->sd_ctime); - sb->store_time_posix(sb, FSW_DNODE_STAT_ATIME, dno->sd_v1->sd_atime); - sb->store_time_posix(sb, FSW_DNODE_STAT_MTIME, dno->sd_v1->sd_mtime); - sb->store_attr_posix(sb, dno->sd_v1->sd_mode); + fsw_store_time_posix(sb, FSW_DNODE_STAT_CTIME, dno->sd_v1->sd_ctime); + fsw_store_time_posix(sb, FSW_DNODE_STAT_ATIME, dno->sd_v1->sd_atime); + fsw_store_time_posix(sb, FSW_DNODE_STAT_MTIME, dno->sd_v1->sd_mtime); + fsw_store_attr_posix(sb, dno->sd_v1->sd_mode); } else if (dno->sd_v2) { sb->used_bytes = dno->sd_v2->sd_blocks * vol->g.log_blocksize; - sb->store_time_posix(sb, FSW_DNODE_STAT_CTIME, dno->sd_v2->sd_ctime); - sb->store_time_posix(sb, FSW_DNODE_STAT_ATIME, dno->sd_v2->sd_atime); - sb->store_time_posix(sb, FSW_DNODE_STAT_MTIME, dno->sd_v2->sd_mtime); - sb->store_attr_posix(sb, dno->sd_v2->sd_mode); + fsw_store_time_posix(sb, FSW_DNODE_STAT_CTIME, dno->sd_v2->sd_ctime); + fsw_store_time_posix(sb, FSW_DNODE_STAT_ATIME, dno->sd_v2->sd_atime); + fsw_store_time_posix(sb, FSW_DNODE_STAT_MTIME, dno->sd_v2->sd_mtime); + fsw_store_attr_posix(sb, dno->sd_v2->sd_mode); } return FSW_SUCCESS; diff --git a/refind/menu.c b/refind/menu.c index ab39137..e55bcf4 100644 --- a/refind/menu.c +++ b/refind/menu.c @@ -444,18 +444,39 @@ static UINTN RunGenericMenu(IN REFIT_MENU_SCREEN *Screen, IN MENU_STYLE_FUNC Sty // timeout expired MenuExit = MENU_EXIT_TIMEOUT; break; - } else if (HaveTimeout) { - refit_call1_wrapper(BS->Stall, 100000); // Pause for 100 ms - TimeoutCountdown--; - TimeSinceKeystroke++; - } else if (GlobalConfig.ScreensaverTime > 0) { - refit_call1_wrapper(BS->Stall, 100000); // Pause for 100 ms - TimeSinceKeystroke++; - if (TimeSinceKeystroke > (GlobalConfig.ScreensaverTime * 10)) { - SaveScreen(); - State.PaintAll = TRUE; - TimeSinceKeystroke = 0; - } // if + } else if (HaveTimeout || GlobalConfig.ScreensaverTime > 0) { + EFI_EVENT TimerEvent; + UINTN ElapsCount = 1; + + Status = refit_call5_wrapper(BS->CreateEvent, EVT_TIMER, 0, NULL, NULL, &TimerEvent); + if (EFI_ERROR(Status)) { + refit_call1_wrapper(BS->Stall, 100000); // Pause for 100 ms + } else { + EFI_EVENT WaitList[2]; + UINTN Index; + + refit_call3_wrapper(BS->SetTimer, TimerEvent, TimerRelative, 10000000); // 1s Timeout + WaitList[0] = ST->ConIn->WaitForKey; + WaitList[1] = TimerEvent; + Status = refit_call3_wrapper(BS->WaitForEvent, 2, WaitList, &Index); + refit_call1_wrapper(BS->CloseEvent, TimerEvent); + if (EFI_ERROR(Status)) + refit_call1_wrapper(BS->Stall, 100000); // Pause for 100 ms + else if(Index == 0) + continue; + else + ElapsCount = 10; // always counted as 1s to end of the timeout + } + TimeSinceKeystroke += ElapsCount; + if(HaveTimeout) { + TimeoutCountdown = TimeoutCountdown <= ElapsCount ? 0 : TimeoutCountdown - ElapsCount; + } else if (GlobalConfig.ScreensaverTime > 0 && + TimeSinceKeystroke > (GlobalConfig.ScreensaverTime * 10)) + { + SaveScreen(); + State.PaintAll = TRUE; + TimeSinceKeystroke = 0; + } // if } else { refit_call3_wrapper(BS->WaitForEvent, 1, &ST->ConIn->WaitForKey, &index); } -- 2.39.2