]>
Commit | Line | Data |
---|---|---|
50944545 | 1 | /** @file |
2 | File System Access | |
3 | ||
4 | Copyright (c) 2004 - 2009, Intel Corporation. <BR> | |
5 | All rights reserved. This program and the accompanying materials | |
6 | are licensed and made available under the terms and conditions of the BSD License | |
7 | which accompanies this distribution. The full text of the license may be found at | |
8 | http://opensource.org/licenses/bsd-license.php | |
9 | ||
10 | THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, | |
11 | WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. | |
12 | ||
13 | **/ | |
14 | ||
15 | #include "NvVarsFileLib.h" | |
16 | ||
17 | #include <Library/BaseMemoryLib.h> | |
18 | #include <Library/DebugLib.h> | |
19 | #include <Library/MemoryAllocationLib.h> | |
20 | #include <Library/UefiRuntimeServicesTableLib.h> | |
21 | ||
22 | ||
23 | /** | |
24 | Writes the variable into the file so it can be restored from | |
25 | the file on future boots of the system. | |
26 | ||
27 | @param[in] File - The file to write to | |
28 | @param[in] Name - Variable name string | |
29 | @param[in] NameSize - Size of Name in bytes | |
30 | @param[in] Guid - GUID of variable | |
31 | @param[in] Attributes - Attributes of variable | |
32 | @param[in] Data - Buffer containing Data for variable | |
33 | @param[in] DataSize - Size of Data in bytes | |
34 | ||
35 | @return EFI_STATUS based on the success or failure of the operation | |
36 | ||
37 | **/ | |
38 | EFI_STATUS | |
39 | PackVariableIntoFile ( | |
40 | IN EFI_FILE_HANDLE File, | |
41 | IN CHAR16 *Name, | |
42 | IN UINT32 NameSize, | |
43 | IN EFI_GUID *Guid, | |
44 | IN UINT32 Attributes, | |
45 | IN VOID *Data, | |
46 | IN UINT32 DataSize | |
47 | ) | |
48 | { | |
49 | EFI_STATUS Status; | |
50 | UINTN WriteSize; | |
51 | ||
52 | WriteSize = sizeof (NameSize); | |
53 | Status = FileHandleWrite (File, &WriteSize, &NameSize); | |
54 | if (EFI_ERROR (Status)) { | |
55 | return Status; | |
56 | } | |
57 | ||
58 | WriteSize = NameSize; | |
59 | Status = FileHandleWrite (File, &WriteSize, (VOID*) Name); | |
60 | if (EFI_ERROR (Status)) { | |
61 | return Status; | |
62 | } | |
63 | ||
64 | WriteSize = sizeof (*Guid); | |
65 | Status = FileHandleWrite (File, &WriteSize, (VOID*) Guid); | |
66 | if (EFI_ERROR (Status)) { | |
67 | return Status; | |
68 | } | |
69 | ||
70 | WriteSize = sizeof (Attributes); | |
71 | Status = FileHandleWrite (File, &WriteSize, &Attributes); | |
72 | if (EFI_ERROR (Status)) { | |
73 | return Status; | |
74 | } | |
75 | ||
76 | WriteSize = sizeof (DataSize); | |
77 | Status = FileHandleWrite (File, &WriteSize, &DataSize); | |
78 | if (EFI_ERROR (Status)) { | |
79 | return Status; | |
80 | } | |
81 | ||
82 | WriteSize = DataSize; | |
83 | Status = FileHandleWrite (File, &WriteSize, Data); | |
84 | ||
85 | return Status; | |
86 | } | |
87 | ||
88 | ||
89 | /** | |
90 | Unpacks the next variable from the NvVars file data | |
91 | ||
92 | @param[in] Buffer - Buffer pointing to the next variable instance | |
93 | On subsequent calls, the pointer should be incremented | |
94 | by the returned SizeUsed value. | |
95 | @param[in] MaxSize - Max allowable size for the variable data | |
96 | On subsequent calls, this should be decremented | |
97 | by the returned SizeUsed value. | |
98 | @param[out] Name - Variable name string (address in Buffer) | |
99 | @param[out] NameSize - Size of Name in bytes | |
100 | @param[out] Guid - GUID of variable (address in Buffer) | |
101 | @param[out] Attributes - Attributes of variable | |
102 | @param[out] Data - Buffer containing Data for variable (address in Buffer) | |
103 | @param[out] DataSize - Size of Data in bytes | |
104 | @param[out] SizeUsed - Total size used for this variable instance in Buffer | |
105 | ||
106 | @return EFI_STATUS based on the success or failure of the operation | |
107 | ||
108 | **/ | |
109 | EFI_STATUS | |
110 | UnpackVariableFromBuffer ( | |
111 | IN VOID *Buffer, | |
112 | IN UINTN MaxSize, | |
113 | OUT CHAR16 **Name, | |
114 | OUT UINT32 *NameSize, | |
115 | OUT EFI_GUID **Guid, | |
116 | OUT UINT32 *Attributes, | |
117 | OUT UINT32 *DataSize, | |
118 | OUT VOID **Data, | |
119 | OUT UINTN *SizeUsed | |
120 | ) | |
121 | { | |
122 | UINT8 *BytePtr; | |
123 | UINTN Offset; | |
124 | ||
125 | BytePtr = (UINT8*)Buffer; | |
126 | Offset = 0; | |
127 | ||
128 | *NameSize = *(UINT32*) (BytePtr + Offset); | |
129 | Offset = Offset + sizeof (UINT32); | |
130 | ||
131 | if (Offset > MaxSize) { | |
132 | return EFI_INVALID_PARAMETER; | |
133 | } | |
134 | ||
135 | *Name = (CHAR16*) (BytePtr + Offset); | |
136 | Offset = Offset + *(UINT32*)BytePtr; | |
137 | if (Offset > MaxSize) { | |
138 | return EFI_INVALID_PARAMETER; | |
139 | } | |
140 | ||
141 | *Guid = (EFI_GUID*) (BytePtr + Offset); | |
142 | Offset = Offset + sizeof (EFI_GUID); | |
143 | if (Offset > MaxSize) { | |
144 | return EFI_INVALID_PARAMETER; | |
145 | } | |
146 | ||
147 | *Attributes = *(UINT32*) (BytePtr + Offset); | |
148 | Offset = Offset + sizeof (UINT32); | |
149 | if (Offset > MaxSize) { | |
150 | return EFI_INVALID_PARAMETER; | |
151 | } | |
152 | ||
153 | *DataSize = *(UINT32*) (BytePtr + Offset); | |
154 | Offset = Offset + sizeof (UINT32); | |
155 | if (Offset > MaxSize) { | |
156 | return EFI_INVALID_PARAMETER; | |
157 | } | |
158 | ||
159 | *Data = (VOID*) (BytePtr + Offset); | |
160 | Offset = Offset + *DataSize; | |
161 | if (Offset > MaxSize) { | |
162 | return EFI_INVALID_PARAMETER; | |
163 | } | |
164 | ||
165 | *SizeUsed = Offset; | |
166 | ||
167 | return EFI_SUCCESS; | |
168 | } | |
169 | ||
170 | ||
171 | /** | |
172 | Examines the NvVars file contents, and updates variables based on it. | |
173 | ||
174 | @param[in] Buffer - Buffer with NvVars data | |
175 | @param[in] MaxSize - Size of Buffer in bytes | |
176 | @param[in] DryRun - If TRUE, then no variable modifications should be made | |
177 | (If TRUE, the Buffer is still parsed for validity.) | |
178 | ||
179 | @return EFI_STATUS based on the success or failure of the operation | |
180 | ||
181 | **/ | |
182 | EFI_STATUS | |
183 | UnpackVariablesFromBuffer ( | |
184 | IN VOID *Buffer, | |
185 | IN UINTN MaxSize, | |
186 | IN BOOLEAN DryRun | |
187 | ) | |
188 | { | |
189 | EFI_STATUS Status; | |
190 | UINTN Count; | |
191 | UINTN TotalSizeUsed; | |
192 | UINTN SizeUsed; | |
193 | ||
194 | CHAR16 *Name; | |
195 | UINT32 NameSize; | |
196 | CHAR16 *AlignedName; | |
197 | UINT32 AlignedNameMaxSize; | |
198 | EFI_GUID *Guid; | |
199 | UINT32 Attributes; | |
200 | UINT32 DataSize; | |
201 | VOID *Data; | |
202 | ||
203 | AlignedName = NULL; | |
204 | AlignedNameMaxSize = 0; | |
205 | ||
206 | for ( | |
207 | Status = EFI_SUCCESS, Count = 0, TotalSizeUsed = 0; | |
208 | !EFI_ERROR (Status) && (TotalSizeUsed < MaxSize); | |
209 | ) { | |
210 | Status = UnpackVariableFromBuffer ( | |
211 | (VOID*) ((UINT8*) Buffer + TotalSizeUsed), | |
212 | (MaxSize - TotalSizeUsed), | |
213 | &Name, | |
214 | &NameSize, | |
215 | &Guid, | |
216 | &Attributes, | |
217 | &DataSize, | |
218 | &Data, | |
219 | &SizeUsed | |
220 | ); | |
221 | if (EFI_ERROR (Status)) { | |
222 | return Status; | |
223 | } | |
224 | ||
225 | // | |
226 | // We copy the name to a separately allocated buffer, | |
227 | // to be sure it is 16-bit aligned. | |
228 | // | |
229 | if (NameSize > AlignedNameMaxSize) { | |
230 | if (AlignedName != NULL) { | |
231 | FreePool (AlignedName); | |
232 | } | |
233 | AlignedName = AllocatePool (NameSize); | |
234 | } | |
235 | if (AlignedName == NULL) { | |
236 | return EFI_OUT_OF_RESOURCES; | |
237 | } | |
238 | CopyMem (AlignedName, Name, NameSize); | |
239 | ||
240 | DEBUG (( | |
241 | EFI_D_INFO, | |
242 | "Unpacked variable %g:%s\n", | |
243 | Guid, | |
244 | AlignedName | |
245 | )); | |
246 | ||
247 | TotalSizeUsed = TotalSizeUsed + SizeUsed; | |
248 | ||
249 | DEBUG (( | |
250 | EFI_D_INFO, | |
251 | "TotalSizeUsed(%d); MaxSize(%d)\n", | |
252 | TotalSizeUsed, | |
253 | MaxSize | |
254 | )); | |
255 | ||
256 | if (!DryRun) { | |
257 | // | |
258 | // Set the variable contents | |
259 | // | |
260 | gRT->SetVariable ( | |
261 | AlignedName, | |
262 | Guid, | |
263 | Attributes, | |
264 | DataSize, | |
265 | Data | |
266 | ); | |
267 | ||
268 | Count++; | |
269 | ||
270 | DEBUG (( | |
271 | EFI_D_INFO, | |
272 | "Restored variable %g:%s\n", | |
273 | Guid, | |
274 | AlignedName | |
275 | )); | |
276 | } | |
277 | ||
278 | } | |
279 | ||
280 | if (AlignedName != NULL) { | |
281 | FreePool (AlignedName); | |
282 | } | |
283 | ||
284 | // | |
285 | // Make sure the entire buffer was used, or else return an error | |
286 | // | |
287 | if (TotalSizeUsed != MaxSize) { | |
288 | DEBUG (( | |
289 | EFI_D_INFO, | |
290 | "TotalSizeUsed(%d) != MaxSize(%d)\n", | |
291 | TotalSizeUsed, | |
292 | MaxSize | |
293 | )); | |
294 | return EFI_INVALID_PARAMETER; | |
295 | } | |
296 | ||
297 | if (Count > 0) { | |
298 | DEBUG (( | |
299 | EFI_D_INFO, | |
300 | "Restored %d Variables\n", | |
301 | Count | |
302 | )); | |
303 | } | |
304 | ||
305 | return EFI_SUCCESS; | |
306 | } | |
307 | ||
308 | ||
309 | /** | |
310 | Examines the NvVars file contents, and updates variables based on it. | |
311 | ||
312 | @param[in] VarsBuffer - Buffer with NvVars data | |
313 | @param[in] VarsBufferSize - Size of VarsBuffer in bytes | |
314 | ||
315 | @return EFI_STATUS based on the success or failure of the operation | |
316 | ||
317 | **/ | |
318 | EFI_STATUS | |
319 | SetVariablesFromBuffer ( | |
320 | IN VOID *VarsBuffer, | |
321 | IN UINTN VarsBufferSize | |
322 | ) | |
323 | { | |
324 | EFI_STATUS Status; | |
325 | ||
326 | // | |
327 | // First test to make sure the entire buffer is in a good state | |
328 | // | |
329 | Status = UnpackVariablesFromBuffer (VarsBuffer, VarsBufferSize, TRUE); | |
330 | if (EFI_ERROR (Status)) { | |
331 | DEBUG ((EFI_D_INFO, "NvVars buffer format was invalid\n")); | |
332 | return Status; | |
333 | } | |
334 | ||
335 | // | |
336 | // Now, actually restore the variables. | |
337 | // | |
338 | Status = UnpackVariablesFromBuffer (VarsBuffer, VarsBufferSize, FALSE); | |
339 | if (EFI_ERROR (Status)) { | |
340 | return Status; | |
341 | } | |
342 | ||
343 | return Status; | |
344 | } | |
345 |