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