]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Library/VarCheckPcdLib/VarCheckPcdLibNullClass.c
MdeModulePkg: Fix the build fail issue on VS2008\VS2010\GCC
[mirror_edk2.git] / MdeModulePkg / Library / VarCheckPcdLib / VarCheckPcdLibNullClass.c
CommitLineData
a2918326
SZ
1/** @file\r
2 Var Check PCD handler.\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/DebugLib.h>\r
18#include <Library/BaseMemoryLib.h>\r
19#include <Library/MemoryAllocationLib.h>\r
20#include <Library/DxeServicesLib.h>\r
21\r
22#include "VarCheckPcdStructure.h"\r
23\r
24//#define DUMP_VAR_CHECK_PCD\r
25\r
26GLOBAL_REMOVE_IF_UNREFERENCED CONST CHAR8 mVarCheckPcdHex[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};\r
27\r
28/**\r
29 Dump some hexadecimal data.\r
30\r
31 @param[in] Indent How many spaces to indent the output.\r
32 @param[in] Offset The offset of the dump.\r
33 @param[in] DataSize The size in bytes of UserData.\r
34 @param[in] UserData The data to dump.\r
35\r
36**/\r
37VOID\r
38VarCheckPcdInternalDumpHex (\r
39 IN UINTN Indent,\r
40 IN UINTN Offset,\r
41 IN UINTN DataSize,\r
42 IN VOID *UserData\r
43 )\r
44{\r
45 UINT8 *Data;\r
46\r
47 CHAR8 Val[50];\r
48\r
49 CHAR8 Str[20];\r
50\r
51 UINT8 TempByte;\r
52 UINTN Size;\r
53 UINTN Index;\r
54\r
55 Data = UserData;\r
56 while (DataSize != 0) {\r
57 Size = 16;\r
58 if (Size > DataSize) {\r
59 Size = DataSize;\r
60 }\r
61\r
62 for (Index = 0; Index < Size; Index += 1) {\r
63 TempByte = Data[Index];\r
64 Val[Index * 3 + 0] = mVarCheckPcdHex[TempByte >> 4];\r
65 Val[Index * 3 + 1] = mVarCheckPcdHex[TempByte & 0xF];\r
66 Val[Index * 3 + 2] = (CHAR8) ((Index == 7) ? '-' : ' ');\r
67 Str[Index] = (CHAR8) ((TempByte < ' ' || TempByte > 'z') ? '.' : TempByte);\r
68 }\r
69\r
70 Val[Index * 3] = 0;\r
71 Str[Index] = 0;\r
72 DEBUG ((EFI_D_INFO, "%*a%08X: %-48a *%a*\r\n", Indent, "", Offset, Val, Str));\r
73\r
74 Data += Size;\r
75 Offset += Size;\r
76 DataSize -= Size;\r
77 }\r
78}\r
79\r
80/**\r
81 Var Check Pcd ValidData.\r
82\r
83 @param[in] PcdValidData Pointer to Pcd ValidData\r
84 @param[in] Data Data pointer.\r
85 @param[in] DataSize Size of Data to set.\r
86\r
87 @retval TRUE Check pass\r
88 @retval FALSE Check fail.\r
89\r
90**/\r
91BOOLEAN\r
92VarCheckPcdValidData (\r
93 IN VAR_CHECK_PCD_VALID_DATA_HEADER *PcdValidData,\r
94 IN VOID *Data,\r
95 IN UINTN DataSize\r
96 )\r
97{\r
98 UINT64 OneData;\r
99 UINT64 Minimum;\r
100 UINT64 Maximum;\r
101 UINT64 OneValue;\r
102 UINT8 *Ptr;\r
103\r
104 OneData = 0;\r
105 CopyMem (&OneData, (UINT8 *) Data + PcdValidData->VarOffset, PcdValidData->StorageWidth);\r
106\r
107 switch (PcdValidData->Type) {\r
108 case VarCheckPcdValidList:\r
109 Ptr = (UINT8 *) ((VAR_CHECK_PCD_VALID_LIST *) PcdValidData + 1);\r
110 while ((UINTN) Ptr < (UINTN) PcdValidData + PcdValidData->Length) {\r
111 OneValue = 0;\r
112 CopyMem (&OneValue, Ptr, PcdValidData->StorageWidth);\r
113 if (OneData == OneValue) {\r
114 //\r
115 // Match\r
116 //\r
117 break;\r
118 }\r
119 Ptr += PcdValidData->StorageWidth;\r
120 }\r
121 if ((UINTN) Ptr >= ((UINTN) PcdValidData + PcdValidData->Length)) {\r
122 //\r
123 // No match\r
124 //\r
125 DEBUG ((EFI_D_INFO, "VarCheckPcdValidData fail: ValidList mismatch (0x%lx)\n", OneData));\r
126 DEBUG_CODE (VarCheckPcdInternalDumpHex (2, 0, PcdValidData->Length, (UINT8 *) PcdValidData););\r
127 return FALSE;\r
128 }\r
129 break;\r
130\r
131 case VarCheckPcdValidRange:\r
132 Minimum = 0;\r
133 Maximum = 0;\r
134 Ptr = (UINT8 *) ((VAR_CHECK_PCD_VALID_RANGE *) PcdValidData + 1);\r
135 while ((UINTN) Ptr < (UINTN) PcdValidData + PcdValidData->Length) {\r
136 CopyMem (&Minimum, Ptr, PcdValidData->StorageWidth);\r
137 Ptr += PcdValidData->StorageWidth;\r
138 CopyMem (&Maximum, Ptr, PcdValidData->StorageWidth);\r
139 Ptr += PcdValidData->StorageWidth;\r
140\r
141 if ((OneData >= Minimum) && (OneData <= Maximum)) {\r
142 return TRUE;\r
143 }\r
144 }\r
145 DEBUG ((EFI_D_INFO, "VarCheckPcdValidData fail: ValidRange mismatch (0x%lx)\n", OneData));\r
146 DEBUG_CODE (VarCheckPcdInternalDumpHex (2, 0, PcdValidData->Length, (UINT8 *) PcdValidData););\r
147 return FALSE;\r
148 break;\r
149\r
150 default:\r
151 ASSERT (FALSE);\r
152 break;\r
153 }\r
154\r
155 return TRUE;\r
156}\r
157\r
158VAR_CHECK_PCD_VARIABLE_HEADER *mVarCheckPcdBin = NULL;\r
159UINTN mVarCheckPcdBinSize = 0;\r
160\r
161/**\r
162 SetVariable check handler PCD.\r
163\r
164 @param[in] VariableName Name of Variable to set.\r
165 @param[in] VendorGuid Variable vendor GUID.\r
166 @param[in] Attributes Attribute value of the variable.\r
167 @param[in] DataSize Size of Data to set.\r
168 @param[in] Data Data pointer.\r
169\r
170 @retval EFI_SUCCESS The SetVariable check result was success.\r
171 @retval EFI_SECURITY_VIOLATION Check fail.\r
172\r
173**/\r
174EFI_STATUS\r
175EFIAPI\r
176SetVariableCheckHandlerPcd (\r
177 IN CHAR16 *VariableName,\r
178 IN EFI_GUID *VendorGuid,\r
179 IN UINT32 Attributes,\r
180 IN UINTN DataSize,\r
181 IN VOID *Data\r
182 )\r
183{\r
184 VAR_CHECK_PCD_VARIABLE_HEADER *PcdVariable;\r
185 VAR_CHECK_PCD_VALID_DATA_HEADER *PcdValidData;\r
186\r
187 if (mVarCheckPcdBin == NULL) {\r
188 return EFI_SUCCESS;\r
189 }\r
190\r
191 if ((((Attributes & EFI_VARIABLE_APPEND_WRITE) == 0) && (DataSize == 0)) || (Attributes == 0)) {\r
192 //\r
193 // Do not check delete variable.\r
194 //\r
195 return EFI_SUCCESS;\r
196 }\r
197\r
198 //\r
199 // For Pcd Variable header align.\r
200 //\r
201 PcdVariable = (VAR_CHECK_PCD_VARIABLE_HEADER *) HEADER_ALIGN (mVarCheckPcdBin);\r
202 while ((UINTN) PcdVariable < ((UINTN) mVarCheckPcdBin + mVarCheckPcdBinSize)) {\r
203 if ((StrCmp ((CHAR16 *) (PcdVariable + 1), VariableName) == 0) &&\r
204 (CompareGuid (&PcdVariable->Guid, VendorGuid))) {\r
205 //\r
206 // Found the Pcd Variable that could be used to do check.\r
207 //\r
208 DEBUG ((EFI_D_INFO, "VarCheckPcdVariable - %s:%g with Attributes = 0x%08x Size = 0x%x\n", VariableName, VendorGuid, Attributes, DataSize));\r
209 if ((PcdVariable->Attributes != 0) && PcdVariable->Attributes != Attributes) {\r
210 DEBUG ((EFI_D_INFO, "VarCheckPcdVariable fail for Attributes - 0x%08x\n", PcdVariable->Attributes));\r
211 return EFI_SECURITY_VIOLATION;\r
212 }\r
213\r
214 if (DataSize == 0) {\r
215 DEBUG ((EFI_D_INFO, "VarCheckPcdVariable - CHECK PASS with DataSize == 0 !\n"));\r
216 return EFI_SUCCESS;\r
217 }\r
218\r
219 //\r
220 // Do the check.\r
221 // For Pcd ValidData header align.\r
222 //\r
223 PcdValidData = (VAR_CHECK_PCD_VALID_DATA_HEADER *) HEADER_ALIGN (((UINTN) PcdVariable + PcdVariable->HeaderLength));\r
224 while ((UINTN) PcdValidData < ((UINTN) PcdVariable + PcdVariable->Length)) {\r
225 if (((UINTN) PcdValidData->VarOffset + PcdValidData->StorageWidth) <= DataSize) {\r
226 if (!VarCheckPcdValidData (PcdValidData, Data, DataSize)) {\r
227 return EFI_SECURITY_VIOLATION;\r
228 }\r
229 }\r
230 //\r
231 // For Pcd ValidData header align.\r
232 //\r
233 PcdValidData = (VAR_CHECK_PCD_VALID_DATA_HEADER *) HEADER_ALIGN (((UINTN) PcdValidData + PcdValidData->Length));\r
234 }\r
235\r
236 DEBUG ((EFI_D_INFO, "VarCheckPcdVariable - ALL CHECK PASS!\n"));\r
237 return EFI_SUCCESS;\r
238 }\r
239 //\r
240 // For Pcd Variable header align.\r
241 //\r
242 PcdVariable = (VAR_CHECK_PCD_VARIABLE_HEADER *) HEADER_ALIGN (((UINTN) PcdVariable + PcdVariable->Length));\r
243 }\r
244\r
245 // Not found, so pass.\r
246 return EFI_SUCCESS;\r
247}\r
248\r
249#ifdef DUMP_VAR_CHECK_PCD\r
250/**\r
251 Dump Pcd ValidData.\r
252\r
253 @param[in] PcdValidData Pointer to Pcd ValidData.\r
254\r
255**/\r
256VOID\r
257DumpPcdValidData (\r
258 IN VAR_CHECK_PCD_VALID_DATA_HEADER *PcdValidData\r
259 )\r
260{\r
261 UINT64 Minimum;\r
262 UINT64 Maximum;\r
263 UINT64 OneValue;\r
264 UINT8 *Ptr;\r
265\r
266 DEBUG ((EFI_D_INFO, " VAR_CHECK_PCD_VALID_DATA_HEADER\n"));\r
267 DEBUG ((EFI_D_INFO, " Type - 0x%02x\n", PcdValidData->Type));\r
268 DEBUG ((EFI_D_INFO, " Length - 0x%02x\n", PcdValidData->Length));\r
269 DEBUG ((EFI_D_INFO, " VarOffset - 0x%04x\n", PcdValidData->VarOffset));\r
270 DEBUG ((EFI_D_INFO, " StorageWidth - 0x%02x\n", PcdValidData->StorageWidth));\r
271\r
272 switch (PcdValidData->Type) {\r
273 case VarCheckPcdValidList:\r
274 Ptr = (UINT8 *) ((VAR_CHECK_PCD_VALID_LIST *) PcdValidData + 1);\r
275 while ((UINTN) Ptr < ((UINTN) PcdValidData + PcdValidData->Length)) {\r
276 OneValue = 0;\r
277 CopyMem (&OneValue, Ptr, PcdValidData->StorageWidth);\r
278 switch (PcdValidData->StorageWidth) {\r
279 case sizeof (UINT8):\r
280 DEBUG ((EFI_D_INFO, " ValidList - 0x%02x\n", OneValue));\r
281 break;\r
282 case sizeof (UINT16):\r
283 DEBUG ((EFI_D_INFO, " ValidList - 0x%04x\n", OneValue));\r
284 break;\r
285 case sizeof (UINT32):\r
286 DEBUG ((EFI_D_INFO, " ValidList - 0x%08x\n", OneValue));\r
287 break;\r
288 case sizeof (UINT64):\r
289 DEBUG ((EFI_D_INFO, " ValidList - 0x%016lx\n", OneValue));\r
290 break;\r
291 default:\r
292 ASSERT (FALSE);\r
293 break;\r
294 }\r
295 Ptr += PcdValidData->StorageWidth;\r
296 }\r
297 break;\r
298\r
299 case VarCheckPcdValidRange:\r
300 Minimum = 0;\r
301 Maximum = 0;\r
302 Ptr = (UINT8 *) ((VAR_CHECK_PCD_VALID_RANGE *) PcdValidData + 1);\r
303 while ((UINTN) Ptr < (UINTN) PcdValidData + PcdValidData->Length) {\r
304 CopyMem (&Minimum, Ptr, PcdValidData->StorageWidth);\r
305 Ptr += PcdValidData->StorageWidth;\r
306 CopyMem (&Maximum, Ptr, PcdValidData->StorageWidth);\r
307 Ptr += PcdValidData->StorageWidth;\r
308\r
309 switch (PcdValidData->StorageWidth) {\r
310 case sizeof (UINT8):\r
311 DEBUG ((EFI_D_INFO, " Minimum - 0x%02x\n", Minimum));\r
312 DEBUG ((EFI_D_INFO, " Maximum - 0x%02x\n", Maximum));\r
313 break;\r
314 case sizeof (UINT16):\r
315 DEBUG ((EFI_D_INFO, " Minimum - 0x%04x\n", Minimum));\r
316 DEBUG ((EFI_D_INFO, " Maximum - 0x%04x\n", Maximum));\r
317 break;\r
318 case sizeof (UINT32):\r
319 DEBUG ((EFI_D_INFO, " Minimum - 0x%08x\n", Minimum));\r
320 DEBUG ((EFI_D_INFO, " Maximum - 0x%08x\n", Maximum));\r
321 break;\r
322 case sizeof (UINT64):\r
323 DEBUG ((EFI_D_INFO, " Minimum - 0x%016lx\n", Minimum));\r
324 DEBUG ((EFI_D_INFO, " Maximum - 0x%016lx\n", Maximum));\r
325 break;\r
326 default:\r
327 ASSERT (FALSE);\r
328 break;\r
329 }\r
330 }\r
331 break;\r
332\r
333 default:\r
334 ASSERT (FALSE);\r
335 break;\r
336 }\r
337}\r
338\r
339/**\r
340 Dump Pcd Variable.\r
341\r
342 @param[in] PcdVariable Pointer to Pcd Variable.\r
343\r
344**/\r
345VOID\r
346DumpPcdVariable (\r
347 IN VAR_CHECK_PCD_VARIABLE_HEADER *PcdVariable\r
348 )\r
349{\r
350 VAR_CHECK_PCD_VALID_DATA_HEADER *PcdValidData;\r
351\r
352 DEBUG ((EFI_D_INFO, "VAR_CHECK_PCD_VARIABLE_HEADER\n"));\r
353 DEBUG ((EFI_D_INFO, " Revision - 0x%04x\n", PcdVariable->Revision));\r
354 DEBUG ((EFI_D_INFO, " HeaderLength - 0x%04x\n", PcdVariable->HeaderLength));\r
355 DEBUG ((EFI_D_INFO, " Length - 0x%08x\n", PcdVariable->Length));\r
356 DEBUG ((EFI_D_INFO, " Type - 0x%02x\n", PcdVariable->Type));\r
357 DEBUG ((EFI_D_INFO, " Attributes - 0x%08x\n", PcdVariable->Attributes));\r
358 DEBUG ((EFI_D_INFO, " Guid - %g\n", &PcdVariable->Guid));\r
359 DEBUG ((EFI_D_INFO, " Name - %s\n", PcdVariable + 1));\r
360\r
361 //\r
362 // For Pcd ValidData header align.\r
363 //\r
364 PcdValidData = (VAR_CHECK_PCD_VALID_DATA_HEADER *) HEADER_ALIGN (((UINTN) PcdVariable + PcdVariable->HeaderLength));\r
365 while ((UINTN) PcdValidData < ((UINTN) PcdVariable + PcdVariable->Length)) {\r
366 //\r
367 // Dump Pcd ValidData related to the Pcd Variable.\r
368 //\r
369 DumpPcdValidData (PcdValidData);\r
370 //\r
371 // For Pcd ValidData header align.\r
372 //\r
373 PcdValidData = (VAR_CHECK_PCD_VALID_DATA_HEADER *) HEADER_ALIGN (((UINTN) PcdValidData + PcdValidData->Length));\r
374 }\r
375}\r
376\r
377/**\r
378 Dump Var Check PCD.\r
379\r
380 @param[in] VarCheckPcdBin Pointer to VarCheckPcdBin.\r
381 @param[in] VarCheckPcdBinSize VarCheckPcdBin size.\r
382\r
383**/\r
384VOID\r
385DumpVarCheckPcd (\r
386 IN VOID *VarCheckPcdBin,\r
387 IN UINTN VarCheckPcdBinSize\r
388 )\r
389{\r
390 VAR_CHECK_PCD_VARIABLE_HEADER *PcdVariable;\r
391\r
392 DEBUG ((EFI_D_INFO, "DumpVarCheckPcd\n"));\r
393\r
394 //\r
395 // For Pcd Variable header align.\r
396 //\r
397 PcdVariable = (VAR_CHECK_PCD_VARIABLE_HEADER *) HEADER_ALIGN (VarCheckPcdBin);\r
398 while ((UINTN) PcdVariable < ((UINTN) VarCheckPcdBin + VarCheckPcdBinSize)) {\r
399 DumpPcdVariable (PcdVariable);\r
400 //\r
401 // For Pcd Variable header align.\r
402 //\r
403 PcdVariable = (VAR_CHECK_PCD_VARIABLE_HEADER *) HEADER_ALIGN (((UINTN) PcdVariable + PcdVariable->Length));\r
404 }\r
405}\r
406#endif\r
407\r
408/**\r
409 Locate VarCheckPcdBin.\r
410\r
411**/\r
412VOID\r
413EFIAPI\r
414LocateVarCheckPcdBin (\r
415 VOID\r
416 )\r
417{\r
418 EFI_STATUS Status;\r
419 VAR_CHECK_PCD_VARIABLE_HEADER *VarCheckPcdBin;\r
420 UINTN VarCheckPcdBinSize;\r
421\r
422 //\r
423 // Search the VarCheckPcdBin from the first RAW section of current FFS.\r
424 //\r
425 Status = GetSectionFromFfs (\r
426 EFI_SECTION_RAW,\r
427 0,\r
428 (VOID **) &VarCheckPcdBin,\r
429 &VarCheckPcdBinSize\r
430 );\r
431 if (!EFI_ERROR (Status)) {\r
432 //\r
433 // AllocateRuntimeZeroPool () from MemoryAllocateLib is used for runtime access\r
434 // in SetVariable check handler.\r
435 //\r
436 mVarCheckPcdBin = AllocateRuntimeCopyPool (VarCheckPcdBinSize, VarCheckPcdBin);\r
437 ASSERT (mVarCheckPcdBin != NULL);\r
438 mVarCheckPcdBinSize = VarCheckPcdBinSize;\r
439 FreePool (VarCheckPcdBin);\r
440\r
441 DEBUG ((EFI_D_INFO, "VarCheckPcdBin - at 0x%x size = 0x%x\n", mVarCheckPcdBin, mVarCheckPcdBinSize));\r
442\r
443#ifdef DUMP_VAR_CHECK_PCD\r
444 DEBUG_CODE (\r
445 DumpVarCheckPcd (mVarCheckPcdBin, mVarCheckPcdBinSize);\r
446 );\r
447#endif\r
448 } else {\r
449 DEBUG ((EFI_D_INFO, "[VarCheckPcd] No VarCheckPcdBin found at the first RAW section\n"));\r
450 }\r
451}\r
452\r
453/**\r
454 Constructor function of VarCheckPcdLib to register var check PCD handler.\r
455\r
456 @param[in] ImageHandle The firmware allocated handle for the EFI image.\r
457 @param[in] SystemTable A pointer to the EFI System Table.\r
458\r
459 @retval EFI_SUCCESS The constructor executed correctly.\r
460\r
461**/\r
462EFI_STATUS\r
463EFIAPI\r
464VarCheckPcdLibNullClassConstructor (\r
465 IN EFI_HANDLE ImageHandle,\r
466 IN EFI_SYSTEM_TABLE *SystemTable\r
467 )\r
468{\r
469 LocateVarCheckPcdBin ();\r
470 VarCheckLibRegisterAddressPointer ((VOID **) &mVarCheckPcdBin);\r
471 VarCheckLibRegisterSetVariableCheckHandler (SetVariableCheckHandlerPcd);\r
472\r
473 return EFI_SUCCESS;\r
474}\r