]> git.proxmox.com Git - mirror_edk2.git/blame - SecurityPkg/UserIdentification/UserProfileManagerDxe/ModifyAccessPolicy.c
Add new interface GetVariable2 and GetEfiGlobalVariable2 to return more info. Also...
[mirror_edk2.git] / SecurityPkg / UserIdentification / UserProfileManagerDxe / ModifyAccessPolicy.c
CommitLineData
0c5b25f0 1/** @file\r
2 The functions for access policy modification.\r
3 \r
4Copyright (c) 2009 - 2011, 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 "UserProfileManager.h"\r
16\r
17/**\r
18 Collect all the access policy data to mUserInfo.AccessPolicy, \r
19 and save it to user profile.\r
20\r
21**/\r
22VOID\r
23SaveAccessPolicy (\r
24 VOID\r
25 )\r
26{\r
27 EFI_STATUS Status;\r
28 UINTN OffSet;\r
29 UINTN Size;\r
30 EFI_USER_INFO_ACCESS_CONTROL Control;\r
31 EFI_USER_INFO_HANDLE UserInfo;\r
32 EFI_USER_INFO *Info;\r
33\r
34 if (mUserInfo.AccessPolicy != NULL) {\r
35 FreePool (mUserInfo.AccessPolicy);\r
36 }\r
37 mUserInfo.AccessPolicy = NULL;\r
38 mUserInfo.AccessPolicyLen = 0;\r
39 mUserInfo.AccessPolicyModified = TRUE;\r
40 OffSet = 0;\r
41 \r
42 //\r
43 // Save access right.\r
44 //\r
45 Size = sizeof (EFI_USER_INFO_ACCESS_CONTROL);\r
46 if (mUserInfo.AccessPolicyLen - OffSet < Size) {\r
47 ExpandMemory (OffSet, Size);\r
48 }\r
49\r
50 Control.Type = mAccessInfo.AccessRight;\r
51 Control.Size = (UINT32) Size;\r
52 CopyMem (mUserInfo.AccessPolicy + OffSet, &Control, sizeof (Control));\r
53 OffSet += sizeof (Control);\r
54 \r
55 //\r
56 // Save access setup.\r
57 //\r
58 Size = sizeof (EFI_USER_INFO_ACCESS_CONTROL) + sizeof (EFI_GUID);\r
59 if (mUserInfo.AccessPolicyLen - OffSet < Size) {\r
60 ExpandMemory (OffSet, Size);\r
61 }\r
62\r
63 Control.Type = EFI_USER_INFO_ACCESS_SETUP;\r
64 Control.Size = (UINT32) Size; \r
65 CopyMem (mUserInfo.AccessPolicy + OffSet, &Control, sizeof (Control));\r
66 OffSet += sizeof (Control);\r
67 \r
68 if (mAccessInfo.AccessSetup == ACCESS_SETUP_NORMAL) {\r
69 CopyGuid ((EFI_GUID *) (mUserInfo.AccessPolicy + OffSet), &gEfiUserInfoAccessSetupNormalGuid);\r
70 } else if (mAccessInfo.AccessSetup == ACCESS_SETUP_RESTRICTED) {\r
71 CopyGuid ((EFI_GUID *) (mUserInfo.AccessPolicy + OffSet), &gEfiUserInfoAccessSetupRestrictedGuid);\r
72 } else if (mAccessInfo.AccessSetup == ACCESS_SETUP_ADMIN) {\r
73 CopyGuid ((EFI_GUID *) (mUserInfo.AccessPolicy + OffSet), &gEfiUserInfoAccessSetupAdminGuid);\r
74 }\r
75 OffSet += sizeof (EFI_GUID);\r
76 \r
77 //\r
78 // Save access of boot order.\r
79 //\r
80 Size = sizeof (EFI_USER_INFO_ACCESS_CONTROL) + sizeof (UINT32);\r
81 if (mUserInfo.AccessPolicyLen - OffSet < Size) {\r
82 ExpandMemory (OffSet, Size);\r
83 }\r
84\r
85 Control.Type = EFI_USER_INFO_ACCESS_BOOT_ORDER;\r
86 Control.Size = (UINT32) Size; \r
87 CopyMem (mUserInfo.AccessPolicy + OffSet, &Control, sizeof (Control));\r
88 OffSet += sizeof (Control);\r
89\r
90 CopyMem ((UINT8 *) (mUserInfo.AccessPolicy + OffSet), &mAccessInfo.AccessBootOrder, sizeof (UINT32));\r
91 OffSet += sizeof (UINT32);\r
92 \r
93 //\r
94 // Save permit load.\r
95 //\r
96 if (mAccessInfo.LoadPermitLen > 0) {\r
97 Size = sizeof (EFI_USER_INFO_ACCESS_CONTROL) + mAccessInfo.LoadPermitLen;\r
98 if (mUserInfo.AccessPolicyLen - OffSet < Size) {\r
99 ExpandMemory (OffSet, Size);\r
100 }\r
101\r
102 Control.Type = EFI_USER_INFO_ACCESS_PERMIT_LOAD;\r
103 Control.Size = (UINT32) Size; \r
104 CopyMem (mUserInfo.AccessPolicy + OffSet, &Control, sizeof (Control));\r
105 OffSet += sizeof (Control);\r
106 \r
107 CopyMem (mUserInfo.AccessPolicy + OffSet, mAccessInfo.LoadPermit, mAccessInfo.LoadPermitLen);\r
108 OffSet += mAccessInfo.LoadPermitLen;\r
109 }\r
110 \r
111 //\r
112 // Save forbid load.\r
113 //\r
114 if (mAccessInfo.LoadForbidLen > 0) {\r
115 Size = sizeof (EFI_USER_INFO_ACCESS_CONTROL) + mAccessInfo.LoadForbidLen;\r
116 if (mUserInfo.AccessPolicyLen - OffSet < Size) {\r
117 ExpandMemory (OffSet, Size);\r
118 }\r
119\r
120 Control.Type = EFI_USER_INFO_ACCESS_FORBID_LOAD;\r
121 Control.Size = (UINT32) Size; \r
122 CopyMem (mUserInfo.AccessPolicy + OffSet, &Control, sizeof (Control));\r
123 OffSet += sizeof (Control);\r
124 \r
125 CopyMem (mUserInfo.AccessPolicy + OffSet, mAccessInfo.LoadForbid, mAccessInfo.LoadForbidLen);\r
126 OffSet += mAccessInfo.LoadForbidLen;\r
127 }\r
128 \r
129 //\r
130 // Save permit connect.\r
131 //\r
132 if (mAccessInfo.ConnectPermitLen > 0) {\r
133 Size = sizeof (EFI_USER_INFO_ACCESS_CONTROL) + mAccessInfo.ConnectPermitLen;\r
134 if (mUserInfo.AccessPolicyLen - OffSet < Size) {\r
135 ExpandMemory (OffSet, Size);\r
136 }\r
137\r
138 Control.Type = EFI_USER_INFO_ACCESS_PERMIT_CONNECT;\r
139 Control.Size = (UINT32) Size; \r
140 CopyMem (mUserInfo.AccessPolicy + OffSet, &Control, sizeof (Control));\r
141 OffSet += sizeof (Control);\r
142 \r
143 CopyMem (mUserInfo.AccessPolicy + OffSet, mAccessInfo.ConnectPermit, mAccessInfo.ConnectPermitLen);\r
144 OffSet += mAccessInfo.ConnectPermitLen;\r
145 }\r
146 \r
147 //\r
148 // Save forbid connect.\r
149 //\r
150 if (mAccessInfo.ConnectForbidLen > 0) {\r
151 Size = sizeof (EFI_USER_INFO_ACCESS_CONTROL) + mAccessInfo.ConnectForbidLen;\r
152 if (mUserInfo.AccessPolicyLen - OffSet < Size) {\r
153 ExpandMemory (OffSet, Size);\r
154 }\r
155\r
156 Control.Type = EFI_USER_INFO_ACCESS_FORBID_CONNECT;\r
157 Control.Size = (UINT32) Size; \r
158 CopyMem (mUserInfo.AccessPolicy + OffSet, &Control, sizeof (Control));\r
159 OffSet += sizeof (Control);\r
160 \r
161 CopyMem (mUserInfo.AccessPolicy + OffSet, mAccessInfo.ConnectForbid, mAccessInfo.ConnectForbidLen);\r
162 OffSet += mAccessInfo.ConnectForbidLen;\r
163 }\r
164\r
165 mUserInfo.AccessPolicyLen = OffSet;\r
166\r
167 //\r
168 // Save access policy.\r
169 //\r
44a957c6 170 if (mUserInfo.AccessPolicyModified && (mUserInfo.AccessPolicyLen > 0) && (mUserInfo.AccessPolicy != NULL)) {\r
0c5b25f0 171 Info = AllocateZeroPool (sizeof (EFI_USER_INFO) + mUserInfo.AccessPolicyLen);\r
172 if (Info == NULL) {\r
173 return ;\r
174 }\r
175\r
176 Status = FindInfoByType (mModifyUser, EFI_USER_INFO_ACCESS_POLICY_RECORD, &UserInfo);\r
177 if (!EFI_ERROR (Status)) {\r
178 Info->InfoType = EFI_USER_INFO_ACCESS_POLICY_RECORD;\r
179 Info->InfoAttribs = EFI_USER_INFO_STORAGE_PLATFORM_NV |\r
180 EFI_USER_INFO_PUBLIC |\r
181 EFI_USER_INFO_EXCLUSIVE;\r
182 Info->InfoSize = (UINT32) (sizeof (EFI_USER_INFO) + mUserInfo.AccessPolicyLen);\r
183 CopyMem ((UINT8 *) (Info + 1), mUserInfo.AccessPolicy, mUserInfo.AccessPolicyLen);\r
184 Status = mUserManager->SetInfo (\r
185 mUserManager,\r
186 mModifyUser,\r
187 &UserInfo,\r
188 Info,\r
189 Info->InfoSize\r
190 );\r
191 mUserInfo.AccessPolicyModified = FALSE;\r
192 }\r
193 FreePool (Info);\r
194 }\r
195\r
196 if (mAccessInfo.ConnectForbid != NULL) {\r
197 FreePool (mAccessInfo.ConnectForbid);\r
198 mAccessInfo.ConnectForbid = NULL;\r
199 }\r
200\r
201 if (mAccessInfo.ConnectPermit != NULL) {\r
202 FreePool (mAccessInfo.ConnectPermit);\r
203 mAccessInfo.ConnectPermit = NULL;\r
204 }\r
205\r
206 if (mAccessInfo.LoadForbid != NULL) {\r
207 FreePool (mAccessInfo.LoadForbid);\r
208 mAccessInfo.LoadForbid = NULL;\r
209 }\r
210\r
211 if (mAccessInfo.LoadPermit != NULL) {\r
212 FreePool (mAccessInfo.LoadPermit);\r
213 mAccessInfo.LoadPermit = NULL;\r
214 }\r
215}\r
216\r
217/**\r
218 Create an action OpCode with QuestionID and DevicePath on a given OpCodeHandle.\r
219\r
220 @param[in] QuestionID The question ID.\r
221 @param[in] DevicePath Points to device path.\r
222 @param[in] OpCodeHandle Points to container for dynamic created opcodes.\r
223\r
224**/\r
225VOID\r
226AddDevicePath (\r
227 IN UINTN QuestionID,\r
228 IN EFI_DEVICE_PATH_PROTOCOL *DevicePath,\r
229 IN VOID *OpCodeHandle\r
230 )\r
231{\r
232 EFI_STATUS Status;\r
233 EFI_DEVICE_PATH_PROTOCOL *Next;\r
234 EFI_STRING_ID NameID;\r
235 EFI_STRING DriverName;\r
236 EFI_DEVICE_PATH_TO_TEXT_PROTOCOL *DevicePathText;\r
237\r
238 //\r
239 // Locate device path to text protocol.\r
240 //\r
241 Status = gBS->LocateProtocol (\r
242 &gEfiDevicePathToTextProtocolGuid,\r
243 NULL,\r
244 (VOID **) &DevicePathText\r
245 );\r
246 if (EFI_ERROR (Status)) {\r
247 return ;\r
248 }\r
249 \r
250 //\r
251 // Get driver file name node.\r
252 //\r
253 Next = DevicePath;\r
254 while (!IsDevicePathEnd (Next)) {\r
255 DevicePath = Next;\r
256 Next = NextDevicePathNode (Next);\r
257 }\r
258\r
259 //\r
260 // Display the device path in form.\r
261 //\r
262 DriverName = DevicePathText->ConvertDevicePathToText (DevicePath, FALSE, FALSE);\r
263 NameID = HiiSetString (mCallbackInfo->HiiHandle, 0, DriverName, NULL);\r
264 FreePool (DriverName);\r
265 if (NameID == 0) {\r
266 return ;\r
267 }\r
268\r
269 HiiCreateActionOpCode (\r
270 OpCodeHandle, // Container for dynamic created opcodes\r
271 (UINT16) QuestionID, // Question ID\r
272 NameID, // Prompt text\r
273 STRING_TOKEN (STR_NULL_STRING), // Help text\r
274 EFI_IFR_FLAG_CALLBACK, // Question flag\r
275 0 // Action String ID\r
276 );\r
277}\r
278\r
279\r
280/**\r
281 Check whether the DevicePath is in the device path forbid list \r
282 (mAccessInfo.LoadForbid).\r
283\r
284 @param[in] DevicePath Points to device path.\r
285 \r
286 @retval TRUE The DevicePath is in the device path forbid list.\r
287 @retval FALSE The DevicePath is not in the device path forbid list.\r
288\r
289**/\r
290BOOLEAN\r
291IsLoadForbidden (\r
292 IN EFI_DEVICE_PATH_PROTOCOL *DevicePath\r
293 )\r
294{\r
295 UINTN OffSet;\r
296 UINTN DPSize;\r
297 UINTN Size;\r
298 EFI_DEVICE_PATH_PROTOCOL *Dp;\r
299\r
300 OffSet = 0;\r
301 Size = GetDevicePathSize (DevicePath);\r
302 //\r
303 // Check each device path.\r
304 //\r
305 while (OffSet < mAccessInfo.LoadForbidLen) {\r
306 Dp = (EFI_DEVICE_PATH_PROTOCOL *) (mAccessInfo.LoadForbid + OffSet);\r
307 DPSize = GetDevicePathSize (Dp);\r
308 //\r
309 // Compare device path.\r
310 //\r
311 if ((DPSize == Size) && (CompareMem (DevicePath, Dp, Size) == 0)) {\r
312 return TRUE;\r
313 }\r
314 OffSet += DPSize;\r
315 }\r
316 return FALSE;\r
317}\r
318\r
319\r
320/**\r
321 Display the permit load device path in the loadable device path list.\r
322\r
323**/\r
324VOID\r
325DisplayLoadPermit(\r
326 VOID\r
327 )\r
328{\r
329 EFI_STATUS Status;\r
330 CHAR16 *Order;\r
331 UINTN OrderSize;\r
332 UINTN ListCount;\r
333 UINTN Index;\r
334 UINT8 *Var;\r
335 UINT8 *VarPtr;\r
336 CHAR16 VarName[12];\r
337 VOID *StartOpCodeHandle;\r
338 VOID *EndOpCodeHandle;\r
339 EFI_IFR_GUID_LABEL *StartLabel;\r
340 EFI_IFR_GUID_LABEL *EndLabel;\r
341\r
342 //\r
343 // Get DriverOrder.\r
344 //\r
345 OrderSize = 0;\r
346 Status = gRT->GetVariable (\r
347 L"DriverOrder", \r
348 &gEfiGlobalVariableGuid, \r
349 NULL, \r
350 &OrderSize, \r
351 NULL\r
352 );\r
353 if (Status != EFI_BUFFER_TOO_SMALL) {\r
354 return ;\r
355 }\r
356\r
357 Order = AllocateZeroPool (OrderSize);\r
358 if (Order == NULL) {\r
359 return ;\r
360 }\r
361\r
362 Status = gRT->GetVariable (\r
363 L"DriverOrder", \r
364 &gEfiGlobalVariableGuid, \r
365 NULL, \r
366 &OrderSize, \r
367 Order\r
368 );\r
369 if (EFI_ERROR (Status)) {\r
370 return ;\r
371 }\r
372 \r
373 //\r
374 // Initialize the container for dynamic opcodes.\r
375 //\r
376 StartOpCodeHandle = HiiAllocateOpCodeHandle ();\r
377 ASSERT (StartOpCodeHandle != NULL);\r
378\r
379 EndOpCodeHandle = HiiAllocateOpCodeHandle ();\r
380 ASSERT (EndOpCodeHandle != NULL);\r
381\r
382 //\r
383 // Create Hii Extend Label OpCode.\r
384 //\r
385 StartLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (\r
386 StartOpCodeHandle,\r
387 &gEfiIfrTianoGuid,\r
388 NULL,\r
389 sizeof (EFI_IFR_GUID_LABEL)\r
390 );\r
391 StartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;\r
392 StartLabel->Number = LABEL_PERMIT_LOAD_FUNC;\r
393\r
394 EndLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (\r
395 EndOpCodeHandle,\r
396 &gEfiIfrTianoGuid,\r
397 NULL,\r
398 sizeof (EFI_IFR_GUID_LABEL)\r
399 );\r
400 EndLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;\r
401 EndLabel->Number = LABEL_END;\r
402\r
403 //\r
404 // Add each driver option.\r
405 //\r
406 Var = NULL;\r
407 ListCount = OrderSize / sizeof (UINT16);\r
408 for (Index = 0; Index < ListCount; Index++) {\r
409 //\r
410 // Get driver device path.\r
411 //\r
412 UnicodeSPrint (VarName, sizeof (VarName), L"Driver%04x", Order[Index]);\r
bf4a3dbd 413 GetEfiGlobalVariable2 (VarName, &Var, NULL);\r
0c5b25f0 414 if (Var == NULL) {\r
415 continue;\r
416 }\r
417 \r
418 //\r
419 // Check whether the driver is already forbidden.\r
420 //\r
421 \r
422 VarPtr = Var;\r
423 //\r
424 // Skip attribute.\r
425 //\r
426 VarPtr += sizeof (UINT32);\r
427\r
428 //\r
429 // Skip device path lenth.\r
430 //\r
431 VarPtr += sizeof (UINT16);\r
432\r
433 //\r
434 // Skip descript string.\r
435 //\r
436 VarPtr += StrSize ((UINT16 *) VarPtr);\r
437\r
438 if (IsLoadForbidden ((EFI_DEVICE_PATH_PROTOCOL *) VarPtr)) {\r
439 FreePool (Var);\r
440 Var = NULL;\r
441 continue;\r
442 }\r
443\r
444 AddDevicePath (\r
445 KEY_MODIFY_USER | KEY_MODIFY_AP_DP | KEY_LOAD_PERMIT_MODIFY | Order[Index],\r
446 (EFI_DEVICE_PATH_PROTOCOL *) VarPtr,\r
447 StartOpCodeHandle\r
448 );\r
449 FreePool (Var);\r
450 Var = NULL;\r
451 }\r
452\r
453 HiiUpdateForm (\r
454 mCallbackInfo->HiiHandle, // HII handle\r
455 &gUserProfileManagerGuid, // Formset GUID\r
456 FORMID_PERMIT_LOAD_DP, // Form ID\r
457 StartOpCodeHandle, // Label for where to insert opcodes\r
458 EndOpCodeHandle // Replace data\r
459 );\r
460\r
461 HiiFreeOpCodeHandle (StartOpCodeHandle);\r
462 HiiFreeOpCodeHandle (EndOpCodeHandle);\r
463\r
464 //\r
465 // Clear Environment.\r
466 //\r
467 if (Var != NULL) {\r
468 FreePool (Var);\r
469 }\r
470 FreePool (Order);\r
471}\r
472\r
473\r
474/**\r
475 Display the forbid load device path list (mAccessInfo.LoadForbid).\r
476\r
477**/\r
478VOID\r
479DisplayLoadForbid (\r
480 VOID\r
481 )\r
482{\r
483 UINTN Offset;\r
484 UINTN DPSize;\r
485 UINTN Index;\r
486 EFI_DEVICE_PATH_PROTOCOL *Dp;\r
487 VOID *StartOpCodeHandle;\r
488 VOID *EndOpCodeHandle;\r
489 EFI_IFR_GUID_LABEL *StartLabel;\r
490 EFI_IFR_GUID_LABEL *EndLabel;\r
491\r
492 //\r
493 // Initialize the container for dynamic opcodes.\r
494 //\r
495 StartOpCodeHandle = HiiAllocateOpCodeHandle ();\r
496 ASSERT (StartOpCodeHandle != NULL);\r
497\r
498 EndOpCodeHandle = HiiAllocateOpCodeHandle ();\r
499 ASSERT (EndOpCodeHandle != NULL);\r
500\r
501 //\r
502 // Create Hii Extend Label OpCode.\r
503 //\r
504 StartLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (\r
505 StartOpCodeHandle,\r
506 &gEfiIfrTianoGuid,\r
507 NULL,\r
508 sizeof (EFI_IFR_GUID_LABEL)\r
509 );\r
510 StartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;\r
511 StartLabel->Number = LABLE_FORBID_LOAD_FUNC;\r
512\r
513 EndLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (\r
514 EndOpCodeHandle,\r
515 &gEfiIfrTianoGuid,\r
516 NULL,\r
517 sizeof (EFI_IFR_GUID_LABEL)\r
518 );\r
519 EndLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;\r
520 EndLabel->Number = LABEL_END;\r
521\r
522 //\r
523 // Add each forbid load drivers.\r
524 //\r
525 Offset = 0;\r
526 Index = 0;\r
527 while (Offset < mAccessInfo.LoadForbidLen) {\r
528 Dp = (EFI_DEVICE_PATH_PROTOCOL *) (mAccessInfo.LoadForbid + Offset);\r
529 DPSize = GetDevicePathSize (Dp);\r
530 AddDevicePath (\r
531 KEY_MODIFY_USER | KEY_MODIFY_AP_DP | KEY_LOAD_FORBID_MODIFY | Index,\r
532 Dp,\r
533 StartOpCodeHandle\r
534 );\r
535 Index++;\r
536 Offset += DPSize;\r
537 }\r
538\r
539 HiiUpdateForm (\r
540 mCallbackInfo->HiiHandle, // HII handle\r
541 &gUserProfileManagerGuid, // Formset GUID\r
542 FORMID_FORBID_LOAD_DP, // Form ID\r
543 StartOpCodeHandle, // Label for where to insert opcodes\r
544 EndOpCodeHandle // Replace data\r
545 );\r
546\r
547 HiiFreeOpCodeHandle (StartOpCodeHandle);\r
548 HiiFreeOpCodeHandle (EndOpCodeHandle);\r
549}\r
550\r
551\r
552/**\r
553 Display the permit connect device path.\r
554\r
555**/\r
556VOID\r
557DisplayConnectPermit (\r
558 VOID\r
559 )\r
560{\r
561 //\r
562 // Note: \r
563 // As no architect protocol/interface to be called in ConnectController()\r
564 // to verify the device path, just add a place holder for permitted connect\r
565 // device path.\r
566 //\r
567}\r
568\r
569\r
570/**\r
571 Display the forbid connect device path list.\r
572\r
573**/\r
574VOID\r
575DisplayConnectForbid (\r
576 VOID\r
577 )\r
578{\r
579 //\r
580 // Note: \r
581 // As no architect protocol/interface to be called in ConnectController()\r
582 // to verify the device path, just add a place holder for forbidden connect\r
583 // device path.\r
584 //\r
585}\r
586\r
587\r
588/**\r
589 Delete the specified device path by DriverIndex from the forbid device path \r
590 list (mAccessInfo.LoadForbid).\r
591\r
592 @param[in] DriverIndex The index of driver in forbidden device path list.\r
593 \r
594**/\r
595VOID\r
596DeleteFromForbidLoad (\r
597 IN UINT16 DriverIndex\r
598 )\r
599{\r
600 UINTN OffSet;\r
601 UINTN DPSize;\r
602 UINTN OffLen;\r
603 EFI_DEVICE_PATH_PROTOCOL *Dp;\r
604\r
605 OffSet = 0;\r
606 //\r
607 // Find the specified device path.\r
608 //\r
609 while ((OffSet < mAccessInfo.LoadForbidLen) && (DriverIndex > 0)) {\r
610 Dp = (EFI_DEVICE_PATH_PROTOCOL *) (mAccessInfo.LoadForbid + OffSet);\r
611 DPSize = GetDevicePathSize (Dp);\r
612 OffSet += DPSize;\r
613 DriverIndex--;\r
614 }\r
615 \r
616 //\r
617 // Specified device path found.\r
618 //\r
619 if (DriverIndex == 0) {\r
620 Dp = (EFI_DEVICE_PATH_PROTOCOL *) (mAccessInfo.LoadForbid + OffSet);\r
621 DPSize = GetDevicePathSize (Dp);\r
622 OffLen = mAccessInfo.LoadForbidLen - OffSet - DPSize;\r
623 if (OffLen > 0) {\r
624 CopyMem (\r
625 mAccessInfo.LoadForbid + OffSet, \r
626 mAccessInfo.LoadForbid + OffSet + DPSize, \r
627 OffLen\r
628 );\r
629 }\r
630 mAccessInfo.LoadForbidLen -= DPSize;\r
631 }\r
632}\r
633\r
634\r
635/**\r
636 Add the specified device path by DriverIndex to the forbid device path \r
637 list (mAccessInfo.LoadForbid).\r
638\r
639 @param[in] DriverIndex The index of driver saved in driver options.\r
640 \r
641**/\r
642VOID\r
643AddToForbidLoad (\r
644 IN UINT16 DriverIndex\r
645 )\r
646{\r
647 UINTN DevicePathLen;\r
648 UINT8 *Var;\r
649 UINT8 *VarPtr;\r
650 UINTN NewLen;\r
651 UINT8 *NewFL;\r
652 CHAR16 VarName[13];\r
653\r
654 //\r
655 // Get loadable driver device path.\r
656 //\r
657 UnicodeSPrint (VarName, sizeof (VarName), L"Driver%04x", DriverIndex);\r
bf4a3dbd 658 GetEfiGlobalVariable2 (VarName, &Var, NULL);\r
0c5b25f0 659 if (Var == NULL) {\r
660 return;\r
661 }\r
662 \r
663 //\r
664 // Save forbid load driver.\r
665 //\r
666 \r
667 VarPtr = Var;\r
668 //\r
669 // Skip attribute.\r
670 //\r
671 VarPtr += sizeof (UINT32);\r
672\r
673 DevicePathLen = *(UINT16 *) VarPtr;\r
674 //\r
675 // Skip device path length.\r
676 //\r
677 VarPtr += sizeof (UINT16);\r
678\r
679 //\r
680 // Skip description string.\r
681 //\r
682 VarPtr += StrSize ((UINT16 *) VarPtr);\r
683\r
684 NewLen = mAccessInfo.LoadForbidLen + DevicePathLen;\r
685 NewFL = AllocateZeroPool (NewLen);\r
686 if (NewFL == NULL) {\r
687 FreePool (Var);\r
688 return ;\r
689 }\r
690\r
691 if (mAccessInfo.LoadForbidLen > 0) {\r
692 CopyMem (NewFL, mAccessInfo.LoadForbid, mAccessInfo.LoadForbidLen);\r
693 FreePool (mAccessInfo.LoadForbid);\r
694 }\r
695\r
696 CopyMem (NewFL + mAccessInfo.LoadForbidLen, VarPtr, DevicePathLen);\r
697 mAccessInfo.LoadForbidLen = NewLen;\r
698 mAccessInfo.LoadForbid = NewFL;\r
699 FreePool (Var);\r
700}\r
701\r
702\r