]> code.delx.au - refind/blob - filesystems/fsw_efi_lib.c
Added filesystem drivers.
[refind] / filesystems / fsw_efi_lib.c
1 /* $Id: fsw_efi_lib.c 29125 2010-05-06 09:43:05Z vboxsync $ */
2 /** @file
3 * fsw_efi_lib.c - EFI host environment library functions.
4 */
5
6 /*
7 * Copyright (C) 2010 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 */
17
18 /*-
19 * This code is based on:
20 *
21 * Copyright (c) 2006 Christoph Pfisterer
22 *
23 * Redistribution and use in source and binary forms, with or without
24 * modification, are permitted provided that the following conditions are
25 * met:
26 *
27 * * Redistributions of source code must retain the above copyright
28 * notice, this list of conditions and the following disclaimer.
29 *
30 * * Redistributions in binary form must reproduce the above copyright
31 * notice, this list of conditions and the following disclaimer in the
32 * documentation and/or other materials provided with the
33 * distribution.
34 *
35 * * Neither the name of Christoph Pfisterer nor the names of the
36 * contributors may be used to endorse or promote products derived
37 * from this software without specific prior written permission.
38 *
39 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
40 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
41 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
42 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
43 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
44 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
45 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
46 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
47 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
48 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
49 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
50 */
51
52 #include "fsw_efi.h"
53
54
55 //
56 // time conversion
57 //
58 // Adopted from public domain code in FreeBSD libc.
59 //
60
61 #define SECSPERMIN 60
62 #define MINSPERHOUR 60
63 #define HOURSPERDAY 24
64 #define DAYSPERWEEK 7
65 #define DAYSPERNYEAR 365
66 #define DAYSPERLYEAR 366
67 #define SECSPERHOUR (SECSPERMIN * MINSPERHOUR)
68 #define SECSPERDAY ((long) SECSPERHOUR * HOURSPERDAY)
69 #define MONSPERYEAR 12
70
71 #define EPOCH_YEAR 1970
72 #define EPOCH_WDAY TM_THURSDAY
73
74 #define isleap(y) (((y) % 4) == 0 && (((y) % 100) != 0 || ((y) % 400) == 0))
75 #define LEAPS_THRU_END_OF(y) ((y) / 4 - (y) / 100 + (y) / 400)
76
77 static const int mon_lengths[2][MONSPERYEAR] = {
78 { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 },
79 { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }
80 };
81 static const int year_lengths[2] = {
82 DAYSPERNYEAR, DAYSPERLYEAR
83 };
84
85 VOID fsw_efi_decode_time(OUT EFI_TIME *EfiTime, IN UINT32 UnixTime)
86 {
87 long days, rem;
88 int y, newy, yleap;
89 const int *ip;
90
91 ZeroMem(EfiTime, sizeof(EFI_TIME));
92
93 days = UnixTime / SECSPERDAY;
94 rem = UnixTime % SECSPERDAY;
95
96 EfiTime->Hour = (UINT8) (rem / SECSPERHOUR);
97 rem = rem % SECSPERHOUR;
98 EfiTime->Minute = (UINT8) (rem / SECSPERMIN);
99 EfiTime->Second = (UINT8) (rem % SECSPERMIN);
100
101 y = EPOCH_YEAR;
102 while (days < 0 || days >= (long) year_lengths[yleap = isleap(y)]) {
103 newy = y + days / DAYSPERNYEAR;
104 if (days < 0)
105 --newy;
106 days -= (newy - y) * DAYSPERNYEAR +
107 LEAPS_THRU_END_OF(newy - 1) -
108 LEAPS_THRU_END_OF(y - 1);
109 y = newy;
110 }
111 EfiTime->Year = (UINT16)y;
112 ip = mon_lengths[yleap];
113 for (EfiTime->Month = 0; days >= (long) ip[EfiTime->Month]; ++(EfiTime->Month))
114 days = days - (long) ip[EfiTime->Month];
115 EfiTime->Month++; // adjust range to EFI conventions
116 EfiTime->Day = (UINT8) (days + 1);
117 }
118
119 //
120 // String functions, used for file and volume info
121 //
122
123 UINTN fsw_efi_strsize(struct fsw_string *s)
124 {
125 if (s->type == FSW_STRING_TYPE_EMPTY)
126 return sizeof(CHAR16);
127 return (s->len + 1) * sizeof(CHAR16);
128 }
129
130 VOID fsw_efi_strcpy(CHAR16 *Dest, struct fsw_string *src)
131 {
132 if (src->type == FSW_STRING_TYPE_EMPTY) {
133 Dest[0] = 0;
134 } else if (src->type == FSW_STRING_TYPE_UTF16) {
135 CopyMem(Dest, src->data, src->size);
136 Dest[src->len] = 0;
137 } else {
138 // TODO: coerce, recurse
139 Dest[0] = 0;
140 }
141 }
142
143 #ifdef VBOX
144 int fsw_streq_ISO88591_UTF16(void *s1data, void *s2data, int len)
145 {
146 int i;
147 fsw_u8 *p1 = (fsw_u8 *)s1data;
148 fsw_u16 *p2 = (fsw_u16 *)s2data;
149
150 for (i = 0; i<len; i++)
151 {
152 if (fsw_to_lower(p1[i]) != fsw_to_lower(p2[i]))
153 {
154 return 0;
155 }
156 }
157
158 return 1;
159 }
160 #endif
161
162 // EOF