+// 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_WHOLEDISK:
+ retval = L" whole disk";
+ break;
+ 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_BTRFS:
+ retval = L" Btrfs";
+ break;
+ case FS_TYPE_ISO9660:
+ retval = L" ISO-9660";
+ break;
+ case FS_TYPE_NTFS:
+ retval = L" NTFS";
+ break;
+ default:
+ retval = L"";
+ break;
+ } // switch
+ return retval;
+} // CHAR16 *FSTypeName()
+
+// Identify the filesystem type and record the filesystem's UUID/serial number,
+// if possible. Expects a Buffer containing the first few (normally at least
+// 4096) bytes of the filesystem. Sets the filesystem type code in Volume->FSType
+// and the UUID/serial number in Volume->VolUuid. Note that the UUID value is
+// recognized differently for each filesystem, and is currently supported only
+// for NTFS, ext2/3/4fs, and ReiserFS (and for NTFS it's really a 64-bit serial
+// number not a UUID or GUID). If the UUID can't be determined, it's set to 0.
+// Also, the UUID is just read directly into memory; it is *NOT* valid when
+// displayed by GuidAsString() or used in other GUID/UUID-manipulating
+// functions. (As I write, it's being used merely to detect partitions that are
+// part of a RAID 1 array.)
+static VOID SetFilesystemData(IN UINT8 *Buffer, IN UINTN BufferSize, IN OUT REFIT_VOLUME *Volume) {
+ UINT32 *Ext2Incompat, *Ext2Compat;
+ UINT16 *Magic16;
+ char *MagicString;
+ EFI_FILE *RootDir;
+
+ if ((Buffer != NULL) && (Volume != NULL)) {
+ SetMem(&(Volume->VolUuid), sizeof(EFI_GUID), 0);
+ Volume->FSType = FS_TYPE_UNKNOWN;
+
+ if (BufferSize >= 512) {
+
+ // Search for NTFS, FAT, and MBR/EBR.
+ // These all have 0xAA55 at the end of the first sector, but FAT and
+ // MBR/EBR are not easily distinguished. Thus, we first check to see
+ // if the "volume" is in fact a disk device; then look for NTFS
+ // "magic"; and then check to see if the volume can be mounted, thus
+ // relying on the EFI's built-in FAT driver to identify FAT.
+ Magic16 = (UINT16*) (Buffer + 510);
+ if (*Magic16 == FAT_MAGIC) {
+ MagicString = (char*) (Buffer + 3);
+ // Confusingly, "LogicalPartition" refers to the presence of a
+ // partition table, not an MBR logical partition.
+ if (Volume->BlockIO->Media->LogicalPartition) {
+ Volume->FSType = FS_TYPE_WHOLEDISK;
+ } else if (CompareMem(MagicString, NTFS_SIGNATURE, 8) == 0) {
+ Volume->FSType = FS_TYPE_NTFS;
+ CopyMem(&(Volume->VolUuid), Buffer + 0x48, sizeof(UINT64));
+ } else {
+ RootDir = LibOpenRoot(Volume->DeviceHandle);
+ if (RootDir != NULL)
+ Volume->FSType = FS_TYPE_FAT;
+ } // if/elseif/else
+ return;
+ } // if
+ } // search for FAT and NTFS magic
+
+ 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
+ Volume->FSType = FS_TYPE_EXT4;
+ } else if (*Ext2Compat & 0x0004) { // check for journal
+ Volume->FSType = FS_TYPE_EXT3;
+ } else { // none of these features; presume it's ext2...
+ Volume->FSType = FS_TYPE_EXT2;
+ }
+ CopyMem(&(Volume->VolUuid), Buffer + 1024 + 104, sizeof(EFI_GUID));
+ return;
+ }
+ } // search for ext2/3/4 magic
+
+ if (BufferSize >= (65536 + 100)) {
+ MagicString = (char*) (Buffer + 65536 + 52);
+ if ((CompareMem(MagicString, REISERFS_SUPER_MAGIC_STRING, 8) == 0) ||
+ (CompareMem(MagicString, REISER2FS_SUPER_MAGIC_STRING, 9) == 0) ||
+ (CompareMem(MagicString, REISER2FS_JR_SUPER_MAGIC_STRING, 9) == 0)) {
+ Volume->FSType = FS_TYPE_REISERFS;
+ CopyMem(&(Volume->VolUuid), Buffer + 65536 + 84, sizeof(EFI_GUID));
+ return;
+ } // if
+ } // search for ReiserFS magic
+
+ if (BufferSize >= (65536 + 64 + 8)) {
+ MagicString = (char*) (Buffer + 65536 + 64);
+ if (CompareMem(MagicString, BTRFS_SIGNATURE, 8) == 0) {
+ Volume->FSType = FS_TYPE_BTRFS;
+ return;
+ } // if
+ } // search for Btrfs magic
+
+ if (BufferSize >= (1024 + 2)) {
+ Magic16 = (UINT16*) (Buffer + 1024);
+ if ((*Magic16 == HFSPLUS_MAGIC1) || (*Magic16 == HFSPLUS_MAGIC2)) {
+ Volume->FSType = FS_TYPE_HFSPLUS;
+ return;
+ }
+ } // search for HFS+ magic
+
+ } // if (Buffer != NULL)
+
+} // UINT32 SetFilesystemData()
+
+static VOID ScanVolumeBootcode(REFIT_VOLUME *Volume, BOOLEAN *Bootable)