ArmPkg/ArmMmuLib ARM: fix thinko in second level page table handling
[mirror_edk2.git] / SecurityPkg / UserIdentification / UserProfileManagerDxe / ModifyAccessPolicy.c
1 /** @file\r
2   The functions for access policy modification.\r
3 \r
4 Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR>\r
5 This program and the accompanying materials\r
6 are licensed and made available under the terms and conditions of the BSD License\r
7 which accompanies this distribution.  The full text of the license may be found at\r
8 http://opensource.org/licenses/bsd-license.php\r
9 \r
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
11 WITHOUT 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
22 VOID\r
23 SaveAccessPolicy (\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
170   if (mUserInfo.AccessPolicyModified && (mUserInfo.AccessPolicyLen > 0) && (mUserInfo.AccessPolicy != NULL)) {\r
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
225 VOID\r
226 AddDevicePath (\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_DEVICE_PATH_PROTOCOL          *Next;\r
233   EFI_STRING_ID                     NameID;\r
234   EFI_STRING                        DriverName;\r
235 \r
236   //\r
237   // Get driver file name node.\r
238   //\r
239   Next = DevicePath;\r
240   while (!IsDevicePathEnd (Next)) {\r
241     DevicePath  = Next;\r
242     Next        = NextDevicePathNode (Next);\r
243   }\r
244 \r
245   //\r
246   // Display the device path in form.\r
247   //\r
248   DriverName = ConvertDevicePathToText (DevicePath, FALSE, FALSE);\r
249   NameID = HiiSetString (mCallbackInfo->HiiHandle, 0, DriverName, NULL);\r
250   FreePool (DriverName);\r
251   if (NameID == 0) {\r
252     return ;\r
253   }\r
254 \r
255   HiiCreateActionOpCode (\r
256     OpCodeHandle,                   // Container for dynamic created opcodes\r
257     (UINT16) QuestionID,            // Question ID\r
258     NameID,                         // Prompt text\r
259     STRING_TOKEN (STR_NULL_STRING), // Help text\r
260     EFI_IFR_FLAG_CALLBACK,          // Question flag\r
261     0                               // Action String ID\r
262     );\r
263 }\r
264 \r
265 \r
266 /**\r
267   Check whether the DevicePath is in the device path forbid list\r
268   (mAccessInfo.LoadForbid).\r
269 \r
270   @param[in]  DevicePath           Points to device path.\r
271 \r
272   @retval TRUE     The DevicePath is in the device path forbid list.\r
273   @retval FALSE    The DevicePath is not in the device path forbid list.\r
274 \r
275 **/\r
276 BOOLEAN\r
277 IsLoadForbidden (\r
278   IN  EFI_DEVICE_PATH_PROTOCOL                  *DevicePath\r
279   )\r
280 {\r
281   UINTN                     OffSet;\r
282   UINTN                     DPSize;\r
283   UINTN                     Size;\r
284   EFI_DEVICE_PATH_PROTOCOL  *Dp;\r
285 \r
286   OffSet = 0;\r
287   Size   = GetDevicePathSize (DevicePath);\r
288   //\r
289   // Check each device path.\r
290   //\r
291   while (OffSet < mAccessInfo.LoadForbidLen) {\r
292     Dp      = (EFI_DEVICE_PATH_PROTOCOL *) (mAccessInfo.LoadForbid + OffSet);\r
293     DPSize  = GetDevicePathSize (Dp);\r
294     //\r
295     // Compare device path.\r
296     //\r
297     if ((DPSize == Size) && (CompareMem (DevicePath, Dp, Size) == 0)) {\r
298       return TRUE;\r
299     }\r
300     OffSet += DPSize;\r
301   }\r
302   return FALSE;\r
303 }\r
304 \r
305 \r
306 /**\r
307   Display the permit load device path in the loadable device path list.\r
308 \r
309 **/\r
310 VOID\r
311 DisplayLoadPermit(\r
312   VOID\r
313   )\r
314 {\r
315   EFI_STATUS          Status;\r
316   CHAR16              *Order;\r
317   UINTN               OrderSize;\r
318   UINTN               ListCount;\r
319   UINTN               Index;\r
320   UINT8               *Var;\r
321   UINT8               *VarPtr;\r
322   CHAR16              VarName[12];\r
323   VOID                *StartOpCodeHandle;\r
324   VOID                *EndOpCodeHandle;\r
325   EFI_IFR_GUID_LABEL  *StartLabel;\r
326   EFI_IFR_GUID_LABEL  *EndLabel;\r
327 \r
328   //\r
329   // Get DriverOrder.\r
330   //\r
331   OrderSize = 0;\r
332   Status    = gRT->GetVariable (\r
333                      L"DriverOrder",\r
334                      &gEfiGlobalVariableGuid,\r
335                      NULL,\r
336                      &OrderSize,\r
337                      NULL\r
338                      );\r
339   if (Status != EFI_BUFFER_TOO_SMALL) {\r
340     return ;\r
341   }\r
342 \r
343   Order = AllocateZeroPool (OrderSize);\r
344   if (Order == NULL) {\r
345     return ;\r
346   }\r
347 \r
348   Status = gRT->GetVariable (\r
349                   L"DriverOrder",\r
350                   &gEfiGlobalVariableGuid,\r
351                   NULL,\r
352                   &OrderSize,\r
353                   Order\r
354                   );\r
355   if (EFI_ERROR (Status)) {\r
356     return ;\r
357   }\r
358 \r
359   //\r
360   // Initialize the container for dynamic opcodes.\r
361   //\r
362   StartOpCodeHandle = HiiAllocateOpCodeHandle ();\r
363   ASSERT (StartOpCodeHandle != NULL);\r
364 \r
365   EndOpCodeHandle = HiiAllocateOpCodeHandle ();\r
366   ASSERT (EndOpCodeHandle != NULL);\r
367 \r
368   //\r
369   // Create Hii Extend Label OpCode.\r
370   //\r
371   StartLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (\r
372                                         StartOpCodeHandle,\r
373                                         &gEfiIfrTianoGuid,\r
374                                         NULL,\r
375                                         sizeof (EFI_IFR_GUID_LABEL)\r
376                                         );\r
377   StartLabel->ExtendOpCode  = EFI_IFR_EXTEND_OP_LABEL;\r
378   StartLabel->Number        = LABEL_PERMIT_LOAD_FUNC;\r
379 \r
380   EndLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (\r
381                                       EndOpCodeHandle,\r
382                                       &gEfiIfrTianoGuid,\r
383                                       NULL,\r
384                                       sizeof (EFI_IFR_GUID_LABEL)\r
385                                       );\r
386   EndLabel->ExtendOpCode  = EFI_IFR_EXTEND_OP_LABEL;\r
387   EndLabel->Number        = LABEL_END;\r
388 \r
389   //\r
390   // Add each driver option.\r
391   //\r
392   Var       = NULL;\r
393   ListCount = OrderSize / sizeof (UINT16);\r
394   for (Index = 0; Index < ListCount; Index++) {\r
395     //\r
396     // Get driver device path.\r
397     //\r
398     UnicodeSPrint (VarName, sizeof (VarName), L"Driver%04x", Order[Index]);\r
399     GetEfiGlobalVariable2 (VarName, (VOID**)&Var, NULL);\r
400     if (Var == NULL) {\r
401       continue;\r
402     }\r
403 \r
404     //\r
405     // Check whether the driver is already forbidden.\r
406     //\r
407 \r
408     VarPtr = Var;\r
409     //\r
410     // Skip attribute.\r
411     //\r
412     VarPtr += sizeof (UINT32);\r
413 \r
414     //\r
415     // Skip device path lenth.\r
416     //\r
417     VarPtr += sizeof (UINT16);\r
418 \r
419     //\r
420     // Skip descript string.\r
421     //\r
422     VarPtr += StrSize ((UINT16 *) VarPtr);\r
423 \r
424     if (IsLoadForbidden ((EFI_DEVICE_PATH_PROTOCOL *) VarPtr)) {\r
425       FreePool (Var);\r
426       Var = NULL;\r
427       continue;\r
428     }\r
429 \r
430     AddDevicePath (\r
431       KEY_MODIFY_USER | KEY_MODIFY_AP_DP | KEY_LOAD_PERMIT_MODIFY | Order[Index],\r
432       (EFI_DEVICE_PATH_PROTOCOL *) VarPtr,\r
433       StartOpCodeHandle\r
434       );\r
435     FreePool (Var);\r
436     Var = NULL;\r
437   }\r
438 \r
439   HiiUpdateForm (\r
440     mCallbackInfo->HiiHandle, // HII handle\r
441     &gUserProfileManagerGuid, // Formset GUID\r
442     FORMID_PERMIT_LOAD_DP,    // Form ID\r
443     StartOpCodeHandle,        // Label for where to insert opcodes\r
444     EndOpCodeHandle           // Replace data\r
445     );\r
446 \r
447   HiiFreeOpCodeHandle (StartOpCodeHandle);\r
448   HiiFreeOpCodeHandle (EndOpCodeHandle);\r
449 \r
450   //\r
451   // Clear Environment.\r
452   //\r
453   if (Var != NULL) {\r
454     FreePool (Var);\r
455   }\r
456   FreePool (Order);\r
457 }\r
458 \r
459 \r
460 /**\r
461   Display the forbid load device path list (mAccessInfo.LoadForbid).\r
462 \r
463 **/\r
464 VOID\r
465 DisplayLoadForbid (\r
466   VOID\r
467   )\r
468 {\r
469   UINTN                     Offset;\r
470   UINTN                     DPSize;\r
471   UINTN                     Index;\r
472   EFI_DEVICE_PATH_PROTOCOL  *Dp;\r
473   VOID                      *StartOpCodeHandle;\r
474   VOID                      *EndOpCodeHandle;\r
475   EFI_IFR_GUID_LABEL        *StartLabel;\r
476   EFI_IFR_GUID_LABEL        *EndLabel;\r
477 \r
478   //\r
479   // Initialize the container for dynamic opcodes.\r
480   //\r
481   StartOpCodeHandle = HiiAllocateOpCodeHandle ();\r
482   ASSERT (StartOpCodeHandle != NULL);\r
483 \r
484   EndOpCodeHandle = HiiAllocateOpCodeHandle ();\r
485   ASSERT (EndOpCodeHandle != NULL);\r
486 \r
487   //\r
488   // Create Hii Extend Label OpCode.\r
489   //\r
490   StartLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (\r
491                                         StartOpCodeHandle,\r
492                                         &gEfiIfrTianoGuid,\r
493                                         NULL,\r
494                                         sizeof (EFI_IFR_GUID_LABEL)\r
495                                         );\r
496   StartLabel->ExtendOpCode  = EFI_IFR_EXTEND_OP_LABEL;\r
497   StartLabel->Number        = LABLE_FORBID_LOAD_FUNC;\r
498 \r
499   EndLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (\r
500                                       EndOpCodeHandle,\r
501                                       &gEfiIfrTianoGuid,\r
502                                       NULL,\r
503                                       sizeof (EFI_IFR_GUID_LABEL)\r
504                                       );\r
505   EndLabel->ExtendOpCode  = EFI_IFR_EXTEND_OP_LABEL;\r
506   EndLabel->Number        = LABEL_END;\r
507 \r
508   //\r
509   // Add each forbid load drivers.\r
510   //\r
511   Offset  = 0;\r
512   Index   = 0;\r
513   while (Offset < mAccessInfo.LoadForbidLen) {\r
514     Dp      = (EFI_DEVICE_PATH_PROTOCOL *) (mAccessInfo.LoadForbid + Offset);\r
515     DPSize  = GetDevicePathSize (Dp);\r
516     AddDevicePath (\r
517       KEY_MODIFY_USER | KEY_MODIFY_AP_DP | KEY_LOAD_FORBID_MODIFY | Index,\r
518       Dp,\r
519       StartOpCodeHandle\r
520       );\r
521     Index++;\r
522     Offset += DPSize;\r
523   }\r
524 \r
525   HiiUpdateForm (\r
526     mCallbackInfo->HiiHandle, // HII handle\r
527     &gUserProfileManagerGuid, // Formset GUID\r
528     FORMID_FORBID_LOAD_DP,    // Form ID\r
529     StartOpCodeHandle,        // Label for where to insert opcodes\r
530     EndOpCodeHandle           // Replace data\r
531     );\r
532 \r
533   HiiFreeOpCodeHandle (StartOpCodeHandle);\r
534   HiiFreeOpCodeHandle (EndOpCodeHandle);\r
535 }\r
536 \r
537 \r
538 /**\r
539   Display the permit connect device path.\r
540 \r
541 **/\r
542 VOID\r
543 DisplayConnectPermit (\r
544   VOID\r
545   )\r
546 {\r
547   //\r
548   // Note:\r
549   // As no architect protocol/interface to be called in ConnectController()\r
550   // to verify the device path, just add a place holder for permitted connect\r
551   // device path.\r
552   //\r
553 }\r
554 \r
555 \r
556 /**\r
557   Display the forbid connect device path list.\r
558 \r
559 **/\r
560 VOID\r
561 DisplayConnectForbid (\r
562   VOID\r
563   )\r
564 {\r
565   //\r
566   // Note:\r
567   // As no architect protocol/interface to be called in ConnectController()\r
568   // to verify the device path, just add a place holder for forbidden connect\r
569   // device path.\r
570   //\r
571 }\r
572 \r
573 \r
574 /**\r
575   Delete the specified device path by DriverIndex from the forbid device path\r
576   list (mAccessInfo.LoadForbid).\r
577 \r
578   @param[in]  DriverIndex   The index of driver in forbidden device path list.\r
579 \r
580 **/\r
581 VOID\r
582 DeleteFromForbidLoad (\r
583   IN  UINT16                                    DriverIndex\r
584   )\r
585 {\r
586   UINTN                     OffSet;\r
587   UINTN                     DPSize;\r
588   UINTN                     OffLen;\r
589   EFI_DEVICE_PATH_PROTOCOL  *Dp;\r
590 \r
591   OffSet = 0;\r
592   //\r
593   // Find the specified device path.\r
594   //\r
595   while ((OffSet < mAccessInfo.LoadForbidLen) && (DriverIndex > 0)) {\r
596     Dp      = (EFI_DEVICE_PATH_PROTOCOL *) (mAccessInfo.LoadForbid + OffSet);\r
597     DPSize  = GetDevicePathSize (Dp);\r
598     OffSet += DPSize;\r
599     DriverIndex--;\r
600   }\r
601 \r
602   //\r
603   // Specified device path found.\r
604   //\r
605   if (DriverIndex == 0) {\r
606     Dp      = (EFI_DEVICE_PATH_PROTOCOL *) (mAccessInfo.LoadForbid + OffSet);\r
607     DPSize  = GetDevicePathSize (Dp);\r
608     OffLen  = mAccessInfo.LoadForbidLen - OffSet - DPSize;\r
609     if (OffLen > 0) {\r
610       CopyMem (\r
611         mAccessInfo.LoadForbid + OffSet,\r
612         mAccessInfo.LoadForbid + OffSet + DPSize,\r
613         OffLen\r
614         );\r
615     }\r
616     mAccessInfo.LoadForbidLen -= DPSize;\r
617   }\r
618 }\r
619 \r
620 \r
621 /**\r
622   Add the specified device path by DriverIndex to the forbid device path\r
623   list (mAccessInfo.LoadForbid).\r
624 \r
625   @param[in]  DriverIndex   The index of driver saved in driver options.\r
626 \r
627 **/\r
628 VOID\r
629 AddToForbidLoad (\r
630   IN  UINT16                                    DriverIndex\r
631   )\r
632 {\r
633   UINTN       DevicePathLen;\r
634   UINT8       *Var;\r
635   UINT8       *VarPtr;\r
636   UINTN       NewLen;\r
637   UINT8       *NewFL;\r
638   CHAR16      VarName[13];\r
639 \r
640   //\r
641   // Get loadable driver device path.\r
642   //\r
643   UnicodeSPrint  (VarName, sizeof (VarName), L"Driver%04x", DriverIndex);\r
644   GetEfiGlobalVariable2 (VarName, (VOID**)&Var, NULL);\r
645   if (Var == NULL) {\r
646     return;\r
647   }\r
648 \r
649   //\r
650   // Save forbid load driver.\r
651   //\r
652 \r
653   VarPtr = Var;\r
654   //\r
655   // Skip attribute.\r
656   //\r
657   VarPtr += sizeof (UINT32);\r
658 \r
659   DevicePathLen = *(UINT16 *) VarPtr;\r
660   //\r
661   // Skip device path length.\r
662   //\r
663   VarPtr += sizeof (UINT16);\r
664 \r
665   //\r
666   // Skip description string.\r
667   //\r
668   VarPtr += StrSize ((UINT16 *) VarPtr);\r
669 \r
670   NewLen  = mAccessInfo.LoadForbidLen + DevicePathLen;\r
671   NewFL   = AllocateZeroPool (NewLen);\r
672   if (NewFL == NULL) {\r
673     FreePool (Var);\r
674     return ;\r
675   }\r
676 \r
677   if (mAccessInfo.LoadForbidLen > 0) {\r
678     CopyMem (NewFL, mAccessInfo.LoadForbid, mAccessInfo.LoadForbidLen);\r
679     FreePool (mAccessInfo.LoadForbid);\r
680   }\r
681 \r
682   CopyMem (NewFL + mAccessInfo.LoadForbidLen, VarPtr, DevicePathLen);\r
683   mAccessInfo.LoadForbidLen = NewLen;\r
684   mAccessInfo.LoadForbid    = NewFL;\r
685   FreePool (Var);\r
686 }\r
687 \r
688 \r