]> git.proxmox.com Git - mirror_edk2.git/blob - MdeModulePkg/Universal/Variable/RuntimeDxe/VariableExLib.c
MdeModulePkg/Variable: Consolidate common parsing functions
[mirror_edk2.git] / MdeModulePkg / Universal / Variable / RuntimeDxe / VariableExLib.c
1 /** @file
2 Provides variable driver extended services.
3
4 Copyright (c) 2015 - 2019, Intel Corporation. All rights reserved.<BR>
5 SPDX-License-Identifier: BSD-2-Clause-Patent
6
7 **/
8
9 #include "Variable.h"
10 #include "VariableParsing.h"
11
12 /**
13 Finds variable in storage blocks of volatile and non-volatile storage areas.
14
15 This code finds variable in storage blocks of volatile and non-volatile storage areas.
16 If VariableName is an empty string, then we just return the first
17 qualified variable without comparing VariableName and VendorGuid.
18
19 @param[in] VariableName Name of the variable to be found.
20 @param[in] VendorGuid Variable vendor GUID to be found.
21 @param[out] AuthVariableInfo Pointer to AUTH_VARIABLE_INFO structure for
22 output of the variable found.
23
24 @retval EFI_INVALID_PARAMETER If VariableName is not an empty string,
25 while VendorGuid is NULL.
26 @retval EFI_SUCCESS Variable successfully found.
27 @retval EFI_NOT_FOUND Variable not found
28
29 **/
30 EFI_STATUS
31 EFIAPI
32 VariableExLibFindVariable (
33 IN CHAR16 *VariableName,
34 IN EFI_GUID *VendorGuid,
35 OUT AUTH_VARIABLE_INFO *AuthVariableInfo
36 )
37 {
38 EFI_STATUS Status;
39 VARIABLE_POINTER_TRACK Variable;
40 AUTHENTICATED_VARIABLE_HEADER *AuthVariable;
41
42 Status = FindVariable (
43 VariableName,
44 VendorGuid,
45 &Variable,
46 &mVariableModuleGlobal->VariableGlobal,
47 FALSE
48 );
49 if (EFI_ERROR (Status)) {
50 AuthVariableInfo->Data = NULL;
51 AuthVariableInfo->DataSize = 0;
52 AuthVariableInfo->Attributes = 0;
53 AuthVariableInfo->PubKeyIndex = 0;
54 AuthVariableInfo->MonotonicCount = 0;
55 AuthVariableInfo->TimeStamp = NULL;
56 return Status;
57 }
58
59 AuthVariableInfo->DataSize = DataSizeOfVariable (Variable.CurrPtr);
60 AuthVariableInfo->Data = GetVariableDataPtr (Variable.CurrPtr);
61 AuthVariableInfo->Attributes = Variable.CurrPtr->Attributes;
62 if (mVariableModuleGlobal->VariableGlobal.AuthFormat) {
63 AuthVariable = (AUTHENTICATED_VARIABLE_HEADER *) Variable.CurrPtr;
64 AuthVariableInfo->PubKeyIndex = AuthVariable->PubKeyIndex;
65 AuthVariableInfo->MonotonicCount = ReadUnaligned64 (&(AuthVariable->MonotonicCount));
66 AuthVariableInfo->TimeStamp = &AuthVariable->TimeStamp;
67 }
68
69 return EFI_SUCCESS;
70 }
71
72 /**
73 Finds next variable in storage blocks of volatile and non-volatile storage areas.
74
75 This code finds next variable in storage blocks of volatile and non-volatile storage areas.
76 If VariableName is an empty string, then we just return the first
77 qualified variable without comparing VariableName and VendorGuid.
78
79 @param[in] VariableName Name of the variable to be found.
80 @param[in] VendorGuid Variable vendor GUID to be found.
81 @param[out] AuthVariableInfo Pointer to AUTH_VARIABLE_INFO structure for
82 output of the next variable.
83
84 @retval EFI_INVALID_PARAMETER If VariableName is not an empty string,
85 while VendorGuid is NULL.
86 @retval EFI_SUCCESS Variable successfully found.
87 @retval EFI_NOT_FOUND Variable not found
88
89 **/
90 EFI_STATUS
91 EFIAPI
92 VariableExLibFindNextVariable (
93 IN CHAR16 *VariableName,
94 IN EFI_GUID *VendorGuid,
95 OUT AUTH_VARIABLE_INFO *AuthVariableInfo
96 )
97 {
98 EFI_STATUS Status;
99 VARIABLE_HEADER *VariablePtr;
100 AUTHENTICATED_VARIABLE_HEADER *AuthVariablePtr;
101
102 Status = VariableServiceGetNextVariableInternal (
103 VariableName,
104 VendorGuid,
105 &VariablePtr
106 );
107 if (EFI_ERROR (Status)) {
108 AuthVariableInfo->VariableName = NULL;
109 AuthVariableInfo->VendorGuid = NULL;
110 AuthVariableInfo->Data = NULL;
111 AuthVariableInfo->DataSize = 0;
112 AuthVariableInfo->Attributes = 0;
113 AuthVariableInfo->PubKeyIndex = 0;
114 AuthVariableInfo->MonotonicCount = 0;
115 AuthVariableInfo->TimeStamp = NULL;
116 return Status;
117 }
118
119 AuthVariableInfo->VariableName = GetVariableNamePtr (VariablePtr);
120 AuthVariableInfo->VendorGuid = GetVendorGuidPtr (VariablePtr);
121 AuthVariableInfo->DataSize = DataSizeOfVariable (VariablePtr);
122 AuthVariableInfo->Data = GetVariableDataPtr (VariablePtr);
123 AuthVariableInfo->Attributes = VariablePtr->Attributes;
124 if (mVariableModuleGlobal->VariableGlobal.AuthFormat) {
125 AuthVariablePtr = (AUTHENTICATED_VARIABLE_HEADER *) VariablePtr;
126 AuthVariableInfo->PubKeyIndex = AuthVariablePtr->PubKeyIndex;
127 AuthVariableInfo->MonotonicCount = ReadUnaligned64 (&(AuthVariablePtr->MonotonicCount));
128 AuthVariableInfo->TimeStamp = &AuthVariablePtr->TimeStamp;
129 }
130
131 return EFI_SUCCESS;
132 }
133
134 /**
135 Update the variable region with Variable information.
136
137 @param[in] AuthVariableInfo Pointer AUTH_VARIABLE_INFO structure for
138 input of the variable.
139
140 @retval EFI_SUCCESS The update operation is success.
141 @retval EFI_INVALID_PARAMETER Invalid parameter.
142 @retval EFI_WRITE_PROTECTED Variable is write-protected.
143 @retval EFI_OUT_OF_RESOURCES There is not enough resource.
144
145 **/
146 EFI_STATUS
147 EFIAPI
148 VariableExLibUpdateVariable (
149 IN AUTH_VARIABLE_INFO *AuthVariableInfo
150 )
151 {
152 VARIABLE_POINTER_TRACK Variable;
153
154 FindVariable (AuthVariableInfo->VariableName, AuthVariableInfo->VendorGuid, &Variable, &mVariableModuleGlobal->VariableGlobal, FALSE);
155 return UpdateVariable (
156 AuthVariableInfo->VariableName,
157 AuthVariableInfo->VendorGuid,
158 AuthVariableInfo->Data,
159 AuthVariableInfo->DataSize,
160 AuthVariableInfo->Attributes,
161 AuthVariableInfo->PubKeyIndex,
162 AuthVariableInfo->MonotonicCount,
163 &Variable,
164 AuthVariableInfo->TimeStamp
165 );
166 }
167
168 /**
169 Get scratch buffer.
170
171 @param[in, out] ScratchBufferSize Scratch buffer size. If input size is greater than
172 the maximum supported buffer size, this value contains
173 the maximum supported buffer size as output.
174 @param[out] ScratchBuffer Pointer to scratch buffer address.
175
176 @retval EFI_SUCCESS Get scratch buffer successfully.
177 @retval EFI_UNSUPPORTED If input size is greater than the maximum supported buffer size.
178
179 **/
180 EFI_STATUS
181 EFIAPI
182 VariableExLibGetScratchBuffer (
183 IN OUT UINTN *ScratchBufferSize,
184 OUT VOID **ScratchBuffer
185 )
186 {
187 UINTN MaxBufferSize;
188
189 MaxBufferSize = mVariableModuleGlobal->ScratchBufferSize;
190 if (*ScratchBufferSize > MaxBufferSize) {
191 *ScratchBufferSize = MaxBufferSize;
192 return EFI_UNSUPPORTED;
193 }
194
195 *ScratchBuffer = GetEndPointer ((VARIABLE_STORE_HEADER *) ((UINTN) mVariableModuleGlobal->VariableGlobal.VolatileVariableBase));
196 return EFI_SUCCESS;
197 }
198
199 /**
200 This function is to check if the remaining variable space is enough to set
201 all Variables from argument list successfully. The purpose of the check
202 is to keep the consistency of the Variables to be in variable storage.
203
204 Note: Variables are assumed to be in same storage.
205 The set sequence of Variables will be same with the sequence of VariableEntry from argument list,
206 so follow the argument sequence to check the Variables.
207
208 @param[in] Attributes Variable attributes for Variable entries.
209 @param ... The variable argument list with type VARIABLE_ENTRY_CONSISTENCY *.
210 A NULL terminates the list. The VariableSize of
211 VARIABLE_ENTRY_CONSISTENCY is the variable data size as input.
212 It will be changed to variable total size as output.
213
214 @retval TRUE Have enough variable space to set the Variables successfully.
215 @retval FALSE No enough variable space to set the Variables successfully.
216
217 **/
218 BOOLEAN
219 EFIAPI
220 VariableExLibCheckRemainingSpaceForConsistency (
221 IN UINT32 Attributes,
222 ...
223 )
224 {
225 VA_LIST Marker;
226 BOOLEAN Return;
227
228 VA_START (Marker, Attributes);
229
230 Return = CheckRemainingSpaceForConsistencyInternal (Attributes, Marker);
231
232 VA_END (Marker);
233
234 return Return;
235 }
236
237 /**
238 Return TRUE if at OS runtime.
239
240 @retval TRUE If at OS runtime.
241 @retval FALSE If at boot time.
242
243 **/
244 BOOLEAN
245 EFIAPI
246 VariableExLibAtRuntime (
247 VOID
248 )
249 {
250 return AtRuntime ();
251 }