]> code.delx.au - refind/blobdiff - filesystems/fsw_efi_lib.c
Added filesystem drivers.
[refind] / filesystems / fsw_efi_lib.c
diff --git a/filesystems/fsw_efi_lib.c b/filesystems/fsw_efi_lib.c
new file mode 100644 (file)
index 0000000..956e9ee
--- /dev/null
@@ -0,0 +1,162 @@
+/* $Id: fsw_efi_lib.c 29125 2010-05-06 09:43:05Z vboxsync $ */
+/** @file
+ * fsw_efi_lib.c - EFI host environment library functions.
+ */
+
+/*
+ * Copyright (C) 2010 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ */
+
+/*-
+ * This code is based on:
+ *
+ * Copyright (c) 2006 Christoph Pfisterer
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the
+ *    distribution.
+ *
+ *  * Neither the name of Christoph Pfisterer nor the names of the
+ *    contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "fsw_efi.h"
+
+
+//
+// time conversion
+//
+// Adopted from public domain code in FreeBSD libc.
+//
+
+#define SECSPERMIN      60
+#define MINSPERHOUR     60
+#define HOURSPERDAY     24
+#define DAYSPERWEEK     7
+#define DAYSPERNYEAR    365
+#define DAYSPERLYEAR    366
+#define SECSPERHOUR     (SECSPERMIN * MINSPERHOUR)
+#define SECSPERDAY      ((long) SECSPERHOUR * HOURSPERDAY)
+#define MONSPERYEAR     12
+
+#define EPOCH_YEAR      1970
+#define EPOCH_WDAY      TM_THURSDAY
+
+#define isleap(y) (((y) % 4) == 0 && (((y) % 100) != 0 || ((y) % 400) == 0))
+#define LEAPS_THRU_END_OF(y)    ((y) / 4 - (y) / 100 + (y) / 400)
+
+static const int mon_lengths[2][MONSPERYEAR] = {
+    { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 },
+    { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }
+};
+static const int year_lengths[2] = {
+    DAYSPERNYEAR, DAYSPERLYEAR
+};
+
+VOID fsw_efi_decode_time(OUT EFI_TIME *EfiTime, IN UINT32 UnixTime)
+{
+    long        days, rem;
+    int         y, newy, yleap;
+    const int   *ip;
+
+    ZeroMem(EfiTime, sizeof(EFI_TIME));
+
+    days = UnixTime / SECSPERDAY;
+    rem = UnixTime % SECSPERDAY;
+
+    EfiTime->Hour = (UINT8) (rem / SECSPERHOUR);
+    rem = rem % SECSPERHOUR;
+    EfiTime->Minute = (UINT8) (rem / SECSPERMIN);
+    EfiTime->Second = (UINT8) (rem % SECSPERMIN);
+
+    y = EPOCH_YEAR;
+    while (days < 0 || days >= (long) year_lengths[yleap = isleap(y)]) {
+        newy = y + days / DAYSPERNYEAR;
+        if (days < 0)
+            --newy;
+        days -= (newy - y) * DAYSPERNYEAR +
+            LEAPS_THRU_END_OF(newy - 1) -
+            LEAPS_THRU_END_OF(y - 1);
+        y = newy;
+    }
+    EfiTime->Year = (UINT16)y;
+    ip = mon_lengths[yleap];
+    for (EfiTime->Month = 0; days >= (long) ip[EfiTime->Month]; ++(EfiTime->Month))
+        days = days - (long) ip[EfiTime->Month];
+    EfiTime->Month++;  // adjust range to EFI conventions
+    EfiTime->Day = (UINT8) (days + 1);
+}
+
+//
+// String functions, used for file and volume info
+//
+
+UINTN fsw_efi_strsize(struct fsw_string *s)
+{
+    if (s->type == FSW_STRING_TYPE_EMPTY)
+        return sizeof(CHAR16);
+    return (s->len + 1) * sizeof(CHAR16);
+}
+
+VOID fsw_efi_strcpy(CHAR16 *Dest, struct fsw_string *src)
+{
+    if (src->type == FSW_STRING_TYPE_EMPTY) {
+        Dest[0] = 0;
+    } else if (src->type == FSW_STRING_TYPE_UTF16) {
+        CopyMem(Dest, src->data, src->size);
+        Dest[src->len] = 0;
+    } else {
+        // TODO: coerce, recurse
+        Dest[0] = 0;
+    }
+}
+
+#ifdef VBOX
+int fsw_streq_ISO88591_UTF16(void *s1data, void *s2data, int len)
+{
+    int i;
+    fsw_u8 *p1 = (fsw_u8 *)s1data;
+    fsw_u16 *p2 = (fsw_u16 *)s2data;
+
+    for (i = 0; i<len; i++)
+    {
+        if (fsw_to_lower(p1[i]) != fsw_to_lower(p2[i]))
+        {
+            return 0;
+        }
+    }
+
+    return 1;
+}
+#endif
+
+// EOF