]>
code.delx.au - refind/blob - filesystems/fsw_efi_lib.c
1 /* $Id: fsw_efi_lib.c 29125 2010-05-06 09:43:05Z vboxsync $ */
3 * fsw_efi_lib.c - EFI host environment library functions.
7 * Copyright (C) 2010 Oracle Corporation
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.
19 * This code is based on:
21 * Copyright (c) 2006 Christoph Pfisterer
23 * Redistribution and use in source and binary forms, with or without
24 * modification, are permitted provided that the following conditions are
27 * * Redistributions of source code must retain the above copyright
28 * notice, this list of conditions and the following disclaimer.
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
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.
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.
58 // Adopted from public domain code in FreeBSD libc.
62 #define MINSPERHOUR 60
63 #define HOURSPERDAY 24
65 #define DAYSPERNYEAR 365
66 #define DAYSPERLYEAR 366
67 #define SECSPERHOUR (SECSPERMIN * MINSPERHOUR)
68 #define SECSPERDAY ((long) SECSPERHOUR * HOURSPERDAY)
69 #define MONSPERYEAR 12
71 #define EPOCH_YEAR 1970
72 #define EPOCH_WDAY TM_THURSDAY
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)
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 }
81 static const int year_lengths
[2] = {
82 DAYSPERNYEAR
, DAYSPERLYEAR
85 VOID
fsw_efi_decode_time(OUT EFI_TIME
*EfiTime
, IN UINT32 UnixTime
)
91 ZeroMem(EfiTime
, sizeof(EFI_TIME
));
93 days
= UnixTime
/ SECSPERDAY
;
94 rem
= UnixTime
% SECSPERDAY
;
96 EfiTime
->Hour
= (UINT8
) (rem
/ SECSPERHOUR
);
97 rem
= rem
% SECSPERHOUR
;
98 EfiTime
->Minute
= (UINT8
) (rem
/ SECSPERMIN
);
99 EfiTime
->Second
= (UINT8
) (rem
% SECSPERMIN
);
102 while (days
< 0 || days
>= (long) year_lengths
[yleap
= isleap(y
)]) {
103 newy
= y
+ days
/ DAYSPERNYEAR
;
106 days
-= (newy
- y
) * DAYSPERNYEAR
+
107 LEAPS_THRU_END_OF(newy
- 1) -
108 LEAPS_THRU_END_OF(y
- 1);
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);
120 // String functions, used for file and volume info
123 UINTN
fsw_efi_strsize(struct fsw_string
*s
)
125 if (s
->type
== FSW_STRING_TYPE_EMPTY
)
126 return sizeof(CHAR16
);
127 return (s
->len
+ 1) * sizeof(CHAR16
);
130 VOID
fsw_efi_strcpy(CHAR16
*Dest
, struct fsw_string
*src
)
132 if (src
->type
== FSW_STRING_TYPE_EMPTY
) {
134 } else if (src
->type
== FSW_STRING_TYPE_UTF16
) {
135 CopyMem(Dest
, src
->data
, src
->size
);
138 // TODO: coerce, recurse
144 int fsw_streq_ISO88591_UTF16(void *s1data
, void *s2data
, int len
)
147 fsw_u8
*p1
= (fsw_u8
*)s1data
;
148 fsw_u16
*p2
= (fsw_u16
*)s2data
;
150 for (i
= 0; i
<len
; i
++)
152 if (fsw_to_lower(p1
[i
]) != fsw_to_lower(p2
[i
]))