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