]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Library/VarCheckLib/VarCheckLib.c
SecurityPkg : Fix Rsa2048Sha256GuidedSectionExtractLib issue
[mirror_edk2.git] / MdeModulePkg / Library / VarCheckLib / VarCheckLib.c
CommitLineData
31b183bc
SZ
1/** @file\r
2 Implementation functions and structures for var check services.\r
3\r
4Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>\r
5This program and the accompanying materials\r
6are licensed and made available under the terms and conditions of the BSD License\r
7which accompanies this distribution. The full text of the license may be found at\r
8http://opensource.org/licenses/bsd-license.php\r
9\r
10THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
11WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
12\r
13**/\r
14\r
15#include <Library/VarCheckLib.h>\r
16#include <Library/BaseLib.h>\r
17#include <Library/BaseMemoryLib.h>\r
18#include <Library/DebugLib.h>\r
19#include <Library/MemoryAllocationLib.h>\r
20\r
21#include <Guid/GlobalVariable.h>\r
22#include <Guid/HardwareErrorVariable.h>\r
23\r
24BOOLEAN mVarCheckLibEndOfDxe = FALSE;\r
25\r
26#define VAR_CHECK_TABLE_SIZE 0x8\r
27\r
28UINTN mVarCheckLibEndOfDxeCallbackCount = 0;\r
29UINTN mVarCheckLibEndOfDxeCallbackMaxCount = 0;\r
30VAR_CHECK_END_OF_DXE_CALLBACK *mVarCheckLibEndOfDxeCallback = NULL;\r
31\r
32UINTN mVarCheckLibAddressPointerCount = 0;\r
33UINTN mVarCheckLibAddressPointerMaxCount = 0;\r
34VOID ***mVarCheckLibAddressPointer = NULL;\r
35\r
36UINTN mNumberOfVarCheckHandler = 0;\r
37UINTN mMaxNumberOfVarCheckHandler = 0;\r
38VAR_CHECK_SET_VARIABLE_CHECK_HANDLER *mVarCheckHandlerTable = NULL;\r
39\r
40typedef struct {\r
41 EFI_GUID Guid;\r
42 VAR_CHECK_VARIABLE_PROPERTY VariableProperty;\r
43 //CHAR16 *Name;\r
44} VAR_CHECK_VARIABLE_ENTRY;\r
45\r
46UINTN mNumberOfVarCheckVariable = 0;\r
47UINTN mMaxNumberOfVarCheckVariable = 0;\r
48VARIABLE_ENTRY_PROPERTY **mVarCheckVariableTable = NULL;\r
49\r
50//\r
51// Handle variables with wildcard name specially.\r
52//\r
53VARIABLE_ENTRY_PROPERTY mVarCheckVariableWithWildcardName[] = {\r
54 {\r
55 &gEfiGlobalVariableGuid,\r
56 L"Boot####",\r
57 {\r
58 0\r
59 },\r
60 },\r
61 {\r
62 &gEfiGlobalVariableGuid,\r
63 L"Driver####",\r
64 {\r
65 0\r
66 },\r
67 },\r
68 {\r
69 &gEfiGlobalVariableGuid,\r
70 L"SysPrep####",\r
71 {\r
72 0\r
73 },\r
74 },\r
75 {\r
76 &gEfiGlobalVariableGuid,\r
77 L"Key####",\r
78 {\r
79 0\r
80 },\r
81 },\r
82 {\r
83 &gEfiHardwareErrorVariableGuid,\r
84 L"HwErrRec####",\r
85 {\r
86 0\r
87 },\r
88 },\r
89};\r
90\r
91/**\r
92 Check if a Unicode character is a hexadecimal character.\r
93\r
94 This function checks if a Unicode character is a\r
95 hexadecimal character. The valid hexadecimal character is\r
96 L'0' to L'9', L'a' to L'f', or L'A' to L'F'.\r
97\r
98\r
99 @param[in] Char The character to check against.\r
100\r
101 @retval TRUE If the Char is a hexadecmial character.\r
102 @retval FALSE If the Char is not a hexadecmial character.\r
103\r
104**/\r
105BOOLEAN\r
106EFIAPI\r
107VarCheckInternalIsHexaDecimalDigitCharacter (\r
108 IN CHAR16 Char\r
109 )\r
110{\r
111 return (BOOLEAN) ((Char >= L'0' && Char <= L'9') || (Char >= L'A' && Char <= L'F') || (Char >= L'a' && Char <= L'f'));\r
112}\r
113\r
114/**\r
115 Variable property get with wildcard name.\r
116\r
117 @param[in] VariableName Pointer to variable name.\r
118 @param[in] VendorGuid Pointer to variable vendor GUID.\r
119 @param[in] WildcardMatch Try wildcard match or not.\r
120\r
121 @return Pointer to variable property.\r
122\r
123**/\r
124VAR_CHECK_VARIABLE_PROPERTY *\r
125VariablePropertyGetWithWildcardName (\r
126 IN CHAR16 *VariableName,\r
127 IN EFI_GUID *VendorGuid,\r
128 IN BOOLEAN WildcardMatch\r
129 )\r
130{\r
131 UINTN Index;\r
132 UINTN NameLength;\r
133\r
134 NameLength = StrLen (VariableName) - 4;\r
135 for (Index = 0; Index < sizeof (mVarCheckVariableWithWildcardName)/sizeof (mVarCheckVariableWithWildcardName[0]); Index++) {\r
136 if (CompareGuid (mVarCheckVariableWithWildcardName[Index].Guid, VendorGuid)){\r
137 if (WildcardMatch) {\r
138 if ((StrLen (VariableName) == StrLen (mVarCheckVariableWithWildcardName[Index].Name)) &&\r
139 (StrnCmp (VariableName, mVarCheckVariableWithWildcardName[Index].Name, NameLength) == 0) &&\r
140 VarCheckInternalIsHexaDecimalDigitCharacter (VariableName[NameLength]) &&\r
141 VarCheckInternalIsHexaDecimalDigitCharacter (VariableName[NameLength + 1]) &&\r
142 VarCheckInternalIsHexaDecimalDigitCharacter (VariableName[NameLength + 2]) &&\r
143 VarCheckInternalIsHexaDecimalDigitCharacter (VariableName[NameLength + 3])) {\r
1cce53d3
SZ
144 if (mVarCheckVariableWithWildcardName[Index].VariableProperty.Revision != VAR_CHECK_VARIABLE_PROPERTY_REVISION) {\r
145 return NULL;\r
146 } else {\r
147 return &mVarCheckVariableWithWildcardName[Index].VariableProperty;\r
148 }\r
31b183bc
SZ
149 }\r
150 }\r
151 if (StrCmp (mVarCheckVariableWithWildcardName[Index].Name, VariableName) == 0) {\r
1cce53d3
SZ
152 if (mVarCheckVariableWithWildcardName[Index].VariableProperty.Revision != VAR_CHECK_VARIABLE_PROPERTY_REVISION) {\r
153 return NULL;\r
154 } else {\r
155 return &mVarCheckVariableWithWildcardName[Index].VariableProperty;\r
156 }\r
31b183bc
SZ
157 }\r
158 }\r
159 }\r
160\r
161 return NULL;\r
162}\r
163\r
164/**\r
165 Variable property get function.\r
166\r
167 @param[in] Name Pointer to the variable name.\r
168 @param[in] Guid Pointer to the vendor GUID.\r
169 @param[in] WildcardMatch Try wildcard match or not.\r
170\r
171 @return Pointer to the property of variable specified by the Name and Guid.\r
172\r
173**/\r
174VAR_CHECK_VARIABLE_PROPERTY *\r
175VariablePropertyGetFunction (\r
176 IN CHAR16 *Name,\r
177 IN EFI_GUID *Guid,\r
178 IN BOOLEAN WildcardMatch\r
179 )\r
180{\r
181 UINTN Index;\r
182 VAR_CHECK_VARIABLE_ENTRY *Entry;\r
183 CHAR16 *VariableName;\r
184\r
185 for (Index = 0; Index < mNumberOfVarCheckVariable; Index++) {\r
186 Entry = (VAR_CHECK_VARIABLE_ENTRY *) mVarCheckVariableTable[Index];\r
187 VariableName = (CHAR16 *) ((UINTN) Entry + sizeof (*Entry));\r
188 if (CompareGuid (&Entry->Guid, Guid) && (StrCmp (VariableName, Name) == 0)) {\r
189 return &Entry->VariableProperty;\r
190 }\r
191 }\r
192\r
193 return VariablePropertyGetWithWildcardName (Name, Guid, WildcardMatch);\r
194}\r
195\r
196/**\r
197 Var check add table entry.\r
198\r
199 @param[in, out] Table Pointer to table buffer.\r
200 @param[in, out] MaxNumber Pointer to maximum number of entry in the table.\r
201 @param[in, out] CurrentNumber Pointer to current number of entry in the table.\r
202 @param[in] Entry Entry will be added to the table.\r
203\r
204 @retval EFI_SUCCESS Reallocate memory successfully.\r
205 @retval EFI_OUT_OF_RESOURCES No enough memory to allocate.\r
206\r
207**/\r
208EFI_STATUS\r
209VarCheckAddTableEntry (\r
210 IN OUT UINTN **Table,\r
211 IN OUT UINTN *MaxNumber,\r
212 IN OUT UINTN *CurrentNumber,\r
213 IN UINTN Entry\r
214 )\r
215{\r
216 UINTN *TempTable;\r
217\r
218 //\r
219 // Check whether the table is enough to store new entry.\r
220 //\r
221 if (*CurrentNumber == *MaxNumber) {\r
222 //\r
223 // Reallocate memory for the table.\r
224 //\r
225 TempTable = ReallocateRuntimePool (\r
226 *MaxNumber * sizeof (UINTN),\r
227 (*MaxNumber + VAR_CHECK_TABLE_SIZE) * sizeof (UINTN),\r
228 *Table\r
229 );\r
230\r
231 //\r
232 // No enough resource to allocate.\r
233 //\r
234 if (TempTable == NULL) {\r
235 return EFI_OUT_OF_RESOURCES;\r
236 }\r
237\r
238 *Table = TempTable;\r
239 //\r
240 // Increase max number.\r
241 //\r
242 *MaxNumber += VAR_CHECK_TABLE_SIZE;\r
243 }\r
244\r
245 //\r
246 // Add entry to the table.\r
247 //\r
248 (*Table)[*CurrentNumber] = Entry;\r
249 (*CurrentNumber)++;\r
250\r
251 return EFI_SUCCESS;\r
252}\r
253\r
254/**\r
255 Register END_OF_DXE callback.\r
256 The callback will be invoked by VarCheckLibInitializeAtEndOfDxe().\r
257\r
258 @param[in] Callback END_OF_DXE callback.\r
259\r
260 @retval EFI_SUCCESS The callback was registered successfully.\r
261 @retval EFI_INVALID_PARAMETER Callback is NULL.\r
262 @retval EFI_ACCESS_DENIED EFI_END_OF_DXE_EVENT_GROUP_GUID or EFI_EVENT_GROUP_READY_TO_BOOT has\r
263 already been signaled.\r
264 @retval EFI_OUT_OF_RESOURCES There is not enough resource for the callback register request.\r
265\r
266**/\r
267EFI_STATUS\r
268EFIAPI\r
269VarCheckLibRegisterEndOfDxeCallback (\r
270 IN VAR_CHECK_END_OF_DXE_CALLBACK Callback\r
271 )\r
272{\r
273 EFI_STATUS Status;\r
274\r
275 if (Callback == NULL) {\r
276 return EFI_INVALID_PARAMETER;\r
277 }\r
278\r
279 if (mVarCheckLibEndOfDxe) {\r
280 return EFI_ACCESS_DENIED;\r
281 }\r
282\r
283 Status = VarCheckAddTableEntry (\r
284 (UINTN **) &mVarCheckLibEndOfDxeCallback,\r
285 &mVarCheckLibEndOfDxeCallbackMaxCount,\r
286 &mVarCheckLibEndOfDxeCallbackCount,\r
287 (UINTN) Callback\r
288 );\r
289\r
290 DEBUG ((EFI_D_INFO, "VarCheckLibRegisterEndOfDxeCallback - 0x%x %r\n", Callback, Status));\r
291\r
292 return Status;\r
293}\r
294\r
295/**\r
296 Var check initialize at END_OF_DXE.\r
297\r
298 This function needs to be called at END_OF_DXE.\r
299 Address pointers may be returned,\r
300 and caller needs to ConvertPointer() for the pointers.\r
301\r
302 @param[in, out] AddressPointerCount Output pointer to address pointer count.\r
303\r
304 @return Address pointer buffer, NULL if input AddressPointerCount is NULL.\r
305\r
306**/\r
307VOID ***\r
308EFIAPI\r
309VarCheckLibInitializeAtEndOfDxe (\r
310 IN OUT UINTN *AddressPointerCount OPTIONAL\r
311 )\r
312{\r
313 VOID *TempTable;\r
314 UINTN TotalCount;\r
315 UINTN Index;\r
316\r
317 for (Index = 0; Index < mVarCheckLibEndOfDxeCallbackCount; Index++) {\r
318 //\r
319 // Invoke the callback registered by VarCheckLibRegisterEndOfDxeCallback().\r
320 //\r
321 mVarCheckLibEndOfDxeCallback[Index] ();\r
322 }\r
323 if (mVarCheckLibEndOfDxeCallback != NULL) {\r
324 //\r
325 // Free the callback buffer.\r
326 //\r
327 mVarCheckLibEndOfDxeCallbackCount = 0;\r
328 mVarCheckLibEndOfDxeCallbackMaxCount = 0;\r
329 FreePool ((VOID *) mVarCheckLibEndOfDxeCallback);\r
330 mVarCheckLibEndOfDxeCallback = NULL;\r
331 }\r
332\r
333 mVarCheckLibEndOfDxe = TRUE;\r
334\r
335 if (AddressPointerCount == NULL) {\r
336 if (mVarCheckLibAddressPointer != NULL) {\r
337 //\r
338 // Free the address pointer buffer.\r
339 //\r
340 mVarCheckLibAddressPointerCount = 0;\r
341 mVarCheckLibAddressPointerMaxCount = 0;\r
342 FreePool ((VOID *) mVarCheckLibAddressPointer);\r
343 mVarCheckLibAddressPointer = NULL;\r
344 }\r
345 return NULL;\r
346 }\r
347\r
348 //\r
349 // Get the total count needed.\r
350 // Also cover VarCheckHandler and the entries, and VarCheckVariable and the entries.\r
351 //\r
352 TotalCount = mVarCheckLibAddressPointerCount + (mNumberOfVarCheckHandler + 1) + (mNumberOfVarCheckVariable + 1);\r
353 TempTable = ReallocateRuntimePool (\r
354 mVarCheckLibAddressPointerMaxCount * sizeof (VOID **),\r
355 TotalCount * sizeof (VOID **),\r
356 (VOID *) mVarCheckLibAddressPointer\r
357 );\r
358\r
359 if (TempTable != NULL) {\r
360 mVarCheckLibAddressPointer = (VOID ***) TempTable;\r
361\r
362 //\r
363 // Cover VarCheckHandler and the entries.\r
364 //\r
365 mVarCheckLibAddressPointer[mVarCheckLibAddressPointerCount++] = (VOID **) &mVarCheckHandlerTable;\r
366 for (Index = 0; Index < mNumberOfVarCheckHandler; Index++) {\r
367 mVarCheckLibAddressPointer[mVarCheckLibAddressPointerCount++] = (VOID **) &mVarCheckHandlerTable[Index];\r
368 }\r
369\r
370 //\r
371 // Cover VarCheckVariable and the entries.\r
372 //\r
373 mVarCheckLibAddressPointer[mVarCheckLibAddressPointerCount++] = (VOID **) &mVarCheckVariableTable;\r
374 for (Index = 0; Index < mNumberOfVarCheckVariable; Index++) {\r
375 mVarCheckLibAddressPointer[mVarCheckLibAddressPointerCount++] = (VOID **) &mVarCheckVariableTable[Index];\r
376 }\r
377\r
378 ASSERT (mVarCheckLibAddressPointerCount == TotalCount);\r
379 mVarCheckLibAddressPointerMaxCount = mVarCheckLibAddressPointerCount;\r
380 }\r
381\r
382 *AddressPointerCount = mVarCheckLibAddressPointerCount;\r
383 return mVarCheckLibAddressPointer;\r
384}\r
385\r
386/**\r
387 Register address pointer.\r
388 The AddressPointer may be returned by VarCheckLibInitializeAtEndOfDxe().\r
389\r
390 @param[in] AddressPointer Address pointer.\r
391\r
392 @retval EFI_SUCCESS The address pointer was registered successfully.\r
393 @retval EFI_INVALID_PARAMETER AddressPointer is NULL.\r
394 @retval EFI_ACCESS_DENIED EFI_END_OF_DXE_EVENT_GROUP_GUID or EFI_EVENT_GROUP_READY_TO_BOOT has\r
395 already been signaled.\r
396 @retval EFI_OUT_OF_RESOURCES There is not enough resource for the address pointer register request.\r
397\r
398**/\r
399EFI_STATUS\r
400EFIAPI\r
401VarCheckLibRegisterAddressPointer (\r
402 IN VOID **AddressPointer\r
403 )\r
404{\r
405 EFI_STATUS Status;\r
406\r
407 if (AddressPointer == NULL) {\r
408 return EFI_INVALID_PARAMETER;\r
409 }\r
410\r
411 if (mVarCheckLibEndOfDxe) {\r
412 return EFI_ACCESS_DENIED;\r
413 }\r
414\r
415 Status = VarCheckAddTableEntry(\r
416 (UINTN **) &mVarCheckLibAddressPointer,\r
417 &mVarCheckLibAddressPointerMaxCount,\r
418 &mVarCheckLibAddressPointerCount,\r
419 (UINTN) AddressPointer\r
420 );\r
421\r
422 DEBUG ((EFI_D_INFO, "VarCheckLibRegisterAddressPointer - 0x%x %r\n", AddressPointer, Status));\r
423\r
424 return Status;\r
425}\r
426\r
427/**\r
428 Register SetVariable check handler.\r
429\r
430 @param[in] Handler Pointer to check handler.\r
431\r
432 @retval EFI_SUCCESS The SetVariable check handler was registered successfully.\r
433 @retval EFI_INVALID_PARAMETER Handler is NULL.\r
434 @retval EFI_ACCESS_DENIED EFI_END_OF_DXE_EVENT_GROUP_GUID or EFI_EVENT_GROUP_READY_TO_BOOT has\r
435 already been signaled.\r
436 @retval EFI_OUT_OF_RESOURCES There is not enough resource for the SetVariable check handler register request.\r
437 @retval EFI_UNSUPPORTED This interface is not implemented.\r
438 For example, it is unsupported in VarCheck protocol if both VarCheck and SmmVarCheck protocols are present.\r
439\r
440**/\r
441EFI_STATUS\r
442EFIAPI\r
443VarCheckLibRegisterSetVariableCheckHandler (\r
444 IN VAR_CHECK_SET_VARIABLE_CHECK_HANDLER Handler\r
445 )\r
446{\r
447 EFI_STATUS Status;\r
448\r
449 if (Handler == NULL) {\r
450 return EFI_INVALID_PARAMETER;\r
451 }\r
452\r
453 if (mVarCheckLibEndOfDxe) {\r
454 return EFI_ACCESS_DENIED;\r
455 }\r
456\r
457 Status = VarCheckAddTableEntry(\r
458 (UINTN **) &mVarCheckHandlerTable,\r
459 &mMaxNumberOfVarCheckHandler,\r
460 &mNumberOfVarCheckHandler,\r
461 (UINTN) Handler\r
462 );\r
463\r
464 DEBUG ((EFI_D_INFO, "VarCheckLibRegisterSetVariableCheckHandler - 0x%x %r\n", Handler, Status));\r
465\r
466 return Status;\r
467}\r
468\r
469/**\r
470 Variable property set.\r
471\r
472 @param[in] Name Pointer to the variable name.\r
473 @param[in] Guid Pointer to the vendor GUID.\r
474 @param[in] VariableProperty Pointer to the input variable property.\r
475\r
476 @retval EFI_SUCCESS The property of variable specified by the Name and Guid was set successfully.\r
477 @retval EFI_INVALID_PARAMETER Name, Guid or VariableProperty is NULL, or Name is an empty string,\r
478 or the fields of VariableProperty are not valid.\r
479 @retval EFI_ACCESS_DENIED EFI_END_OF_DXE_EVENT_GROUP_GUID or EFI_EVENT_GROUP_READY_TO_BOOT has\r
480 already been signaled.\r
481 @retval EFI_OUT_OF_RESOURCES There is not enough resource for the variable property set request.\r
482\r
483**/\r
484EFI_STATUS\r
485EFIAPI\r
486VarCheckLibVariablePropertySet (\r
487 IN CHAR16 *Name,\r
488 IN EFI_GUID *Guid,\r
489 IN VAR_CHECK_VARIABLE_PROPERTY *VariableProperty\r
490 )\r
491{\r
492 EFI_STATUS Status;\r
493 VAR_CHECK_VARIABLE_ENTRY *Entry;\r
494 CHAR16 *VariableName;\r
495 VAR_CHECK_VARIABLE_PROPERTY *Property;\r
496\r
497 if (Name == NULL || Name[0] == 0 || Guid == NULL) {\r
498 return EFI_INVALID_PARAMETER;\r
499 }\r
500\r
501 if (VariableProperty == NULL) {\r
502 return EFI_INVALID_PARAMETER;\r
503 }\r
504\r
505 if (VariableProperty->Revision != VAR_CHECK_VARIABLE_PROPERTY_REVISION) {\r
506 return EFI_INVALID_PARAMETER;\r
507 }\r
508\r
509 if (mVarCheckLibEndOfDxe) {\r
510 return EFI_ACCESS_DENIED;\r
511 }\r
512\r
513 Status = EFI_SUCCESS;\r
514\r
515 Property = VariablePropertyGetFunction (Name, Guid, FALSE);\r
516 if (Property != NULL) {\r
517 CopyMem (Property, VariableProperty, sizeof (*VariableProperty));\r
518 } else {\r
519 Entry = AllocateRuntimeZeroPool (sizeof (*Entry) + StrSize (Name));\r
520 if (Entry == NULL) {\r
521 return EFI_OUT_OF_RESOURCES;\r
522 }\r
523 VariableName = (CHAR16 *) ((UINTN) Entry + sizeof (*Entry));\r
524 StrCpyS (VariableName, StrSize (Name)/sizeof (CHAR16), Name);\r
525 CopyGuid (&Entry->Guid, Guid);\r
526 CopyMem (&Entry->VariableProperty, VariableProperty, sizeof (*VariableProperty));\r
527\r
528 Status = VarCheckAddTableEntry(\r
529 (UINTN **) &mVarCheckVariableTable,\r
530 &mMaxNumberOfVarCheckVariable,\r
531 &mNumberOfVarCheckVariable,\r
532 (UINTN) Entry\r
533 );\r
534\r
535 if (EFI_ERROR (Status)) {\r
536 FreePool (Entry);\r
537 }\r
538 }\r
539\r
540 return Status;\r
541}\r
542\r
543/**\r
544 Variable property get.\r
545\r
546 @param[in] Name Pointer to the variable name.\r
547 @param[in] Guid Pointer to the vendor GUID.\r
548 @param[out] VariableProperty Pointer to the output variable property.\r
549\r
550 @retval EFI_SUCCESS The property of variable specified by the Name and Guid was got successfully.\r
551 @retval EFI_INVALID_PARAMETER Name, Guid or VariableProperty is NULL, or Name is an empty string.\r
552 @retval EFI_NOT_FOUND The property of variable specified by the Name and Guid was not found.\r
553\r
554**/\r
555EFI_STATUS\r
556EFIAPI\r
557VarCheckLibVariablePropertyGet (\r
558 IN CHAR16 *Name,\r
559 IN EFI_GUID *Guid,\r
560 OUT VAR_CHECK_VARIABLE_PROPERTY *VariableProperty\r
561 )\r
562{\r
563 VAR_CHECK_VARIABLE_PROPERTY *Property;\r
564\r
565 if (Name == NULL || Name[0] == 0 || Guid == NULL) {\r
566 return EFI_INVALID_PARAMETER;\r
567 }\r
568\r
569 if (VariableProperty == NULL) {\r
570 return EFI_INVALID_PARAMETER;\r
571 }\r
572\r
573 Property = VariablePropertyGetFunction (Name, Guid, TRUE);\r
574 if (Property != NULL) {\r
575 CopyMem (VariableProperty, Property, sizeof (*VariableProperty));\r
576 return EFI_SUCCESS;\r
577 }\r
578\r
579 return EFI_NOT_FOUND;\r
580}\r
581\r
582/**\r
583 SetVariable check.\r
584\r
585 @param[in] VariableName Name of Variable to set.\r
586 @param[in] VendorGuid Variable vendor GUID.\r
587 @param[in] Attributes Attribute value of the variable.\r
588 @param[in] DataSize Size of Data to set.\r
589 @param[in] Data Data pointer.\r
590 @param[in] RequestSource Request source.\r
591\r
592 @retval EFI_SUCCESS The SetVariable check result was success.\r
593 @retval EFI_INVALID_PARAMETER An invalid combination of attribute bits, name, GUID,\r
594 DataSize and Data value was supplied.\r
595 @retval EFI_WRITE_PROTECTED The variable in question is read-only.\r
596 @retval Others The other return status from check handler.\r
597\r
598**/\r
599EFI_STATUS\r
600EFIAPI\r
601VarCheckLibSetVariableCheck (\r
602 IN CHAR16 *VariableName,\r
603 IN EFI_GUID *VendorGuid,\r
604 IN UINT32 Attributes,\r
605 IN UINTN DataSize,\r
606 IN VOID *Data,\r
607 IN VAR_CHECK_REQUEST_SOURCE RequestSource\r
608 )\r
609{\r
610 EFI_STATUS Status;\r
611 UINTN Index;\r
612 VAR_CHECK_VARIABLE_PROPERTY *Property;\r
613\r
614 if (!mVarCheckLibEndOfDxe) {\r
615 //\r
616 // Only do check after End Of Dxe.\r
617 //\r
618 return EFI_SUCCESS;\r
619 }\r
620\r
621 Property = VariablePropertyGetFunction (VariableName, VendorGuid, TRUE);\r
622 if (Property != NULL) {\r
623 if ((RequestSource != VarCheckFromTrusted) && ((Property->Property & VAR_CHECK_VARIABLE_PROPERTY_READ_ONLY) != 0)) {\r
624 DEBUG ((EFI_D_INFO, "Variable Check ReadOnly variable fail %r - %g:%s\n", EFI_WRITE_PROTECTED, VendorGuid, VariableName));\r
625 return EFI_WRITE_PROTECTED;\r
626 }\r
627 if (!((((Attributes & EFI_VARIABLE_APPEND_WRITE) == 0) && (DataSize == 0)) || (Attributes == 0))) {\r
628 //\r
629 // Not to delete variable.\r
630 //\r
631 if ((Property->Attributes != 0) && ((Attributes & (~EFI_VARIABLE_APPEND_WRITE)) != Property->Attributes)) {\r
632 DEBUG ((EFI_D_INFO, "Variable Check Attributes(0x%08x to 0x%08x) fail %r - %g:%s\n", Property->Attributes, Attributes, EFI_INVALID_PARAMETER, VendorGuid, VariableName));\r
633 return EFI_INVALID_PARAMETER;\r
634 }\r
635 if (DataSize != 0) {\r
636 if ((DataSize < Property->MinSize) || (DataSize > Property->MaxSize)) {\r
637 DEBUG ((EFI_D_INFO, "Variable Check DataSize fail(0x%x not in 0x%x - 0x%x) %r - %g:%s\n", DataSize, Property->MinSize, Property->MaxSize, EFI_INVALID_PARAMETER, VendorGuid, VariableName));\r
638 return EFI_INVALID_PARAMETER;\r
639 }\r
640 }\r
641 }\r
642 }\r
643\r
644 for (Index = 0; Index < mNumberOfVarCheckHandler; Index++) {\r
645 Status = mVarCheckHandlerTable[Index] (\r
646 VariableName,\r
647 VendorGuid,\r
648 Attributes,\r
649 DataSize,\r
650 Data\r
651 );\r
652 if (EFI_ERROR (Status)) {\r
653 DEBUG ((EFI_D_INFO, "Variable Check handler fail %r - %g:%s\n", Status, VendorGuid, VariableName));\r
654 return Status;\r
655 }\r
656 }\r
657 return EFI_SUCCESS;\r
658}\r