]>
code.delx.au - refind/blob - filesystems/fsw_efi_lib.c
3 * EFI host environment library functions.
7 * Copyright (c) 2006 Christoph Pfisterer
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions are
13 * * Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
16 * * Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the
21 * * Neither the name of Christoph Pfisterer nor the names of the
22 * contributors may be used to endorse or promote products derived
23 * from this software without specific prior written permission.
25 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
26 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
27 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
28 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
29 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
30 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
31 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
32 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
33 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
35 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
44 // Adopted from public domain code in FreeBSD libc.
48 #define MINSPERHOUR 60
49 #define HOURSPERDAY 24
51 #define DAYSPERNYEAR 365
52 #define DAYSPERLYEAR 366
53 #define SECSPERHOUR (SECSPERMIN * MINSPERHOUR)
54 #define SECSPERDAY ((long) SECSPERHOUR * HOURSPERDAY)
55 #define MONSPERYEAR 12
57 #define EPOCH_YEAR 1970
58 #define EPOCH_WDAY TM_THURSDAY
60 #define isleap(y) (((y) % 4) == 0 && (((y) % 100) != 0 || ((y) % 400) == 0))
61 #define LEAPS_THRU_END_OF(y) ((y) / 4 - (y) / 100 + (y) / 400)
63 static const int mon_lengths
[2][MONSPERYEAR
] = {
64 { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 },
65 { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }
67 static const int year_lengths
[2] = {
68 DAYSPERNYEAR
, DAYSPERLYEAR
71 VOID
fsw_efi_decode_time(OUT EFI_TIME
*EfiTime
, IN UINT32 UnixTime
)
77 ZeroMem(EfiTime
, sizeof(EFI_TIME
));
79 days
= UnixTime
/ SECSPERDAY
;
80 rem
= UnixTime
% SECSPERDAY
;
82 EfiTime
->Hour
= (UINT8
) (rem
/ SECSPERHOUR
);
83 rem
= rem
% SECSPERHOUR
;
84 EfiTime
->Minute
= (UINT8
) (rem
/ SECSPERMIN
);
85 EfiTime
->Second
= (UINT8
) (rem
% SECSPERMIN
);
88 while (days
< 0 || days
>= (long) year_lengths
[yleap
= isleap(y
)]) {
89 newy
= y
+ days
/ DAYSPERNYEAR
;
92 days
-= (newy
- y
) * DAYSPERNYEAR
+
93 LEAPS_THRU_END_OF(newy
- 1) -
94 LEAPS_THRU_END_OF(y
- 1);
97 EfiTime
->Year
= (UINT16
)y
;
98 ip
= mon_lengths
[yleap
];
99 for (EfiTime
->Month
= 0; days
>= (long) ip
[EfiTime
->Month
]; ++(EfiTime
->Month
))
100 days
= days
- (long) ip
[EfiTime
->Month
];
101 EfiTime
->Month
++; // adjust range to EFI conventions
102 EfiTime
->Day
= (UINT8
) (days
+ 1);
106 // String functions, used for file and volume info
109 UINTN
fsw_efi_strsize(struct fsw_string
*s
)
111 if (s
->type
== FSW_STRING_TYPE_EMPTY
)
112 return sizeof(CHAR16
);
113 return (s
->len
+ 1) * sizeof(CHAR16
);
116 VOID
fsw_efi_strcpy(CHAR16
*Dest
, struct fsw_string
*src
)
118 if (src
->type
== FSW_STRING_TYPE_EMPTY
| src
->size
== 0) {
120 } else if (src
->type
== FSW_STRING_TYPE_UTF16
) {
121 CopyMem(Dest
, src
->data
, src
->size
);
124 // TODO: coerce, recurse