]> git.proxmox.com Git - mirror_edk2.git/blame - SecurityPkg/UserIdentification/UserProfileManagerDxe/ModifyAccessPolicy.c
Update all the code to consume the ConvertDevicePathToText, ConvertDevicePathNodeToTe...
[mirror_edk2.git] / SecurityPkg / UserIdentification / UserProfileManagerDxe / ModifyAccessPolicy.c
CommitLineData
0c5b25f0 1/** @file\r
2 The functions for access policy modification.\r
3 \r
863986b3 4Copyright (c) 2009 - 2013, Intel Corporation. All rights reserved.<BR>\r
0c5b25f0 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
0c5b25f0 232 EFI_DEVICE_PATH_PROTOCOL *Next;\r
233 EFI_STRING_ID NameID;\r
234 EFI_STRING DriverName;\r
0c5b25f0 235\r
0c5b25f0 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
863986b3 248 DriverName = ConvertDevicePathToText (DevicePath, FALSE, FALSE);\r
0c5b25f0 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
276BOOLEAN\r
277IsLoadForbidden (\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
310VOID\r
311DisplayLoadPermit(\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
f01b91ae 399 GetEfiGlobalVariable2 (VarName, (VOID**)&Var, NULL);\r
0c5b25f0 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
464VOID\r
465DisplayLoadForbid (\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
542VOID\r
543DisplayConnectPermit (\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
560VOID\r
561DisplayConnectForbid (\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
581VOID\r
582DeleteFromForbidLoad (\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
628VOID\r
629AddToForbidLoad (\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
f01b91ae 644 GetEfiGlobalVariable2 (VarName, (VOID**)&Var, NULL);\r
0c5b25f0 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