UserProfileModify.c revision a0c56a8219ec268d8ac4e051035f1636545cc478
1/** @file
2  The functions to modify a user profile.
3
4Copyright (c) 2009 - 2011, Intel Corporation. All rights reserved.<BR>
5This program and the accompanying materials
6are licensed and made available under the terms and conditions of the BSD License
7which accompanies this distribution.  The full text of the license may be found at
8http://opensource.org/licenses/bsd-license.php
9
10THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
12
13**/
14
15#include "UserProfileManager.h"
16
17EFI_USER_PROFILE_HANDLE           mModifyUser = NULL;
18
19/**
20  Display user select form, cab select a user to modify.
21
22**/
23VOID
24SelectUserToModify  (
25  VOID
26  )
27{
28  EFI_STATUS              Status;
29  UINT8                   Index;
30  EFI_USER_PROFILE_HANDLE User;
31  EFI_USER_PROFILE_HANDLE CurrentUser;
32  UINT32                  CurrentAccessRight;
33  VOID                    *StartOpCodeHandle;
34  VOID                    *EndOpCodeHandle;
35  EFI_IFR_GUID_LABEL      *StartLabel;
36  EFI_IFR_GUID_LABEL      *EndLabel;
37
38  //
39  // Initialize the container for dynamic opcodes.
40  //
41  StartOpCodeHandle = HiiAllocateOpCodeHandle ();
42  ASSERT (StartOpCodeHandle != NULL);
43
44  EndOpCodeHandle = HiiAllocateOpCodeHandle ();
45  ASSERT (EndOpCodeHandle != NULL);
46
47  //
48  // Create Hii Extend Label OpCode.
49  //
50  StartLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (
51                                        StartOpCodeHandle,
52                                        &gEfiIfrTianoGuid,
53                                        NULL,
54                                        sizeof (EFI_IFR_GUID_LABEL)
55                                        );
56  StartLabel->ExtendOpCode  = EFI_IFR_EXTEND_OP_LABEL;
57  StartLabel->Number        = LABEL_USER_MOD_FUNC;
58
59  EndLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (
60                                      EndOpCodeHandle,
61                                      &gEfiIfrTianoGuid,
62                                      NULL,
63                                      sizeof (EFI_IFR_GUID_LABEL)
64                                      );
65  EndLabel->ExtendOpCode  = EFI_IFR_EXTEND_OP_LABEL;
66  EndLabel->Number        = LABEL_END;
67
68  //
69  // Add each user can be modified.
70  //
71  User  = NULL;
72  Index = 1;
73  mUserManager->Current (mUserManager, &CurrentUser);
74  while (TRUE) {
75    Status = mUserManager->GetNext (mUserManager, &User);
76    if (EFI_ERROR (Status)) {
77      break;
78    }
79
80    Status = GetAccessRight (&CurrentAccessRight);
81    if (EFI_ERROR (Status)) {
82      CurrentAccessRight = EFI_USER_INFO_ACCESS_ENROLL_SELF;
83    }
84
85    if ((CurrentAccessRight == EFI_USER_INFO_ACCESS_MANAGE) || (User == CurrentUser)) {
86      AddUserToForm (User, (UINT16)(KEY_MODIFY_USER | KEY_SELECT_USER | Index), StartOpCodeHandle);
87    }
88    Index++;
89  }
90
91  HiiUpdateForm (
92    mCallbackInfo->HiiHandle, // HII handle
93    &gUserProfileManagerGuid, // Formset GUID
94    FORMID_MODIFY_USER,       // Form ID
95    StartOpCodeHandle,        // Label for where to insert opcodes
96    EndOpCodeHandle           // Replace data
97    );
98
99  HiiFreeOpCodeHandle (StartOpCodeHandle);
100  HiiFreeOpCodeHandle (EndOpCodeHandle);
101}
102
103
104/**
105  Get all the user info from mModifyUser in the user manager, and save on the
106  global variable.
107
108**/
109VOID
110GetAllUserInfo (
111  VOID
112  )
113{
114  EFI_STATUS            Status;
115  EFI_USER_INFO_HANDLE  UserInfo;
116  EFI_USER_INFO         *Info;
117  UINTN                 InfoSize;
118  UINTN                 MemSize;
119  UINTN                 DataLen;
120
121  //
122  // Init variable to default value.
123  //
124  mProviderChoice                   = 0;
125  mConncetLogical                   = 0;
126
127  mUserInfo.CreateDateExist         = FALSE;
128  mUserInfo.UsageDateExist          = FALSE;
129  mUserInfo.UsageCount              = 0;
130
131  mUserInfo.AccessPolicyLen         = 0;
132  mUserInfo.AccessPolicyModified    = FALSE;
133  if (mUserInfo.AccessPolicy != NULL) {
134    FreePool (mUserInfo.AccessPolicy);
135    mUserInfo.AccessPolicy = NULL;
136  }
137  mUserInfo.IdentityPolicyLen       = 0;
138  mUserInfo.IdentityPolicyModified  = FALSE;
139  if (mUserInfo.IdentityPolicy != NULL) {
140    FreePool (mUserInfo.IdentityPolicy);
141    mUserInfo.IdentityPolicy = NULL;
142  }
143
144  //
145  // Allocate user information memory.
146  //
147  MemSize = sizeof (EFI_USER_INFO) + 63;
148  Info    = AllocateZeroPool (MemSize);
149  if (Info == NULL) {
150    return ;
151  }
152
153  //
154  // Get each user information.
155  //
156  UserInfo = NULL;
157  while (TRUE) {
158    Status = mUserManager->GetNextInfo (mUserManager, mModifyUser, &UserInfo);
159    if (EFI_ERROR (Status)) {
160      break;
161    }
162    //
163    // Get information.
164    //
165    InfoSize  = MemSize;
166    Status    = mUserManager->GetInfo (
167                                mUserManager,
168                                mModifyUser,
169                                UserInfo,
170                                Info,
171                                &InfoSize
172                                );
173    if (Status == EFI_BUFFER_TOO_SMALL) {
174      MemSize = InfoSize;
175      FreePool (Info);
176      Info = AllocateZeroPool (MemSize);
177      if (Info == NULL) {
178        return ;
179      }
180
181      Status = mUserManager->GetInfo (
182                               mUserManager,
183                               mModifyUser,
184                               UserInfo,
185                               Info,
186                               &InfoSize
187                               );
188    }
189
190    if (Status == EFI_SUCCESS) {
191      //
192      // Deal with each information according to informaiton type.
193      //
194      DataLen = Info->InfoSize - sizeof (EFI_USER_INFO);
195      switch (Info->InfoType) {
196      case EFI_USER_INFO_NAME_RECORD:
197        CopyMem (&mUserInfo.UserName, (UINT8 *) (Info + 1), DataLen);
198        break;
199
200      case EFI_USER_INFO_CREATE_DATE_RECORD:
201        CopyMem (&mUserInfo.CreateDate, (UINT8 *) (Info + 1), DataLen);
202        mUserInfo.CreateDateExist = TRUE;
203        break;
204
205      case EFI_USER_INFO_USAGE_DATE_RECORD:
206        CopyMem (&mUserInfo.UsageDate, (UINT8 *) (Info + 1), DataLen);
207        mUserInfo.UsageDateExist = TRUE;
208        break;
209
210      case EFI_USER_INFO_USAGE_COUNT_RECORD:
211        CopyMem (&mUserInfo.UsageCount, (UINT8 *) (Info + 1), DataLen);
212        break;
213
214      case EFI_USER_INFO_ACCESS_POLICY_RECORD:
215        mUserInfo.AccessPolicy = AllocateZeroPool (DataLen);
216        if (mUserInfo.AccessPolicy == NULL) {
217          break;
218        }
219
220        CopyMem (mUserInfo.AccessPolicy, (UINT8 *) (Info + 1), DataLen);
221        mUserInfo.AccessPolicyLen = DataLen;
222        break;
223
224      case EFI_USER_INFO_IDENTITY_POLICY_RECORD:
225        mUserInfo.IdentityPolicy = AllocateZeroPool (DataLen);
226        if (mUserInfo.IdentityPolicy == NULL) {
227          break;
228        }
229
230        CopyMem (mUserInfo.IdentityPolicy, (UINT8 *) (Info + 1), DataLen);
231        mUserInfo.IdentityPolicyLen = DataLen;
232        break;
233
234      default:
235        break;
236      }
237    }
238  }
239  FreePool (Info);
240}
241
242
243/**
244  Convert the Date to a string, and update the Hii database DateID string with it.
245
246  @param[in] Date       Points to the date to be converted.
247  @param[in] DateId     String ID in the HII database to be replaced.
248
249**/
250VOID
251ResolveDate (
252  IN EFI_TIME                                   *Date,
253  IN EFI_STRING_ID                              DateId
254  )
255{
256  CHAR16  *Str;
257  UINTN   DateBufLen;
258
259  //
260  // Convert date to string.
261  //
262  DateBufLen = 64;
263  Str        = AllocateZeroPool (DateBufLen);
264  if (Str == NULL) {
265    return ;
266  }
267
268  UnicodeSPrint (
269    Str,
270    DateBufLen,
271    L"%4d-%2d-%2d ",
272    Date->Year,
273    Date->Month,
274    Date->Day
275    );
276
277  //
278  // Convert time to string.
279  //
280  DateBufLen -= StrLen (Str);
281  UnicodeSPrint (
282    Str + StrLen (Str),
283    DateBufLen,
284    L"%2d:%2d:%2d",
285    Date->Hour,
286    Date->Minute,
287    Date->Second
288    );
289
290  HiiSetString (mCallbackInfo->HiiHandle, DateId, Str, NULL);
291  FreePool (Str);
292}
293
294
295/**
296  Convert the CountVal to a string, and update the Hii database CountId string
297  with it.
298
299  @param[in]  CountVal   The hex value to convert.
300  @param[in]  CountId    String ID in the HII database to be replaced.
301
302**/
303VOID
304ResolveCount (
305  IN UINT32                                     CountVal,
306  IN EFI_STRING_ID                              CountId
307  )
308{
309  CHAR16  Count[10];
310
311  UnicodeSPrint (Count, 20, L"%d", CountVal);
312  HiiSetString (mCallbackInfo->HiiHandle, CountId, Count, NULL);
313}
314
315
316/**
317  Concatenates one Null-terminated Unicode string to another Null-terminated
318  Unicode string.
319
320  @param[in, out]  Source1      On entry, point to a Null-terminated Unicode string.
321                                On exit, point to a new concatenated Unicode string
322  @param[in]       Source2      Pointer to a Null-terminated Unicode string.
323
324**/
325VOID
326AddStr (
327  IN OUT  CHAR16                  **Source1,
328  IN      CONST CHAR16            *Source2
329  )
330{
331  CHAR16                        *TmpStr;
332  UINTN                         StrLength;
333
334  ASSERT (Source1 != NULL);
335  ASSERT (Source2 != NULL);
336
337  if (*Source1 == NULL) {
338    StrLength = StrSize (Source2);
339  } else {
340    StrLength  = StrSize (*Source1);
341    StrLength += StrSize (Source2) -1;
342  }
343
344  TmpStr     = AllocateZeroPool (StrLength);
345  ASSERT (TmpStr != NULL);
346
347  if (*Source1 == NULL) {
348    StrCpy (TmpStr, Source2);;
349  } else {
350    StrCpy (TmpStr, *Source1);
351    FreePool (*Source1);
352    StrCat (TmpStr, Source2);
353  }
354
355  *Source1 = TmpStr;
356}
357
358
359/**
360  Convert the identity policy to a unicode string and update the Hii database
361  IpStringId string with it.
362
363  @param[in]  Ip         Points to identity policy.
364  @param[in]  IpLen      The identity policy length.
365  @param[in]  IpStringId String ID in the HII database to be replaced.
366
367**/
368VOID
369ResolveIdentityPolicy (
370  IN  UINT8                                     *Ip,
371  IN  UINTN                                     IpLen,
372  IN  EFI_STRING_ID                             IpStringId
373  )
374{
375  CHAR16                        *TmpStr;
376  UINTN                         ChkLen;
377  EFI_USER_INFO_IDENTITY_POLICY *Identity;
378  UINT16                        Index;
379  CHAR16                        *ProvStr;
380  EFI_STRING_ID                 ProvId;
381  EFI_HII_HANDLE                HiiHandle;
382  EFI_USER_CREDENTIAL_PROTOCOL  *UserCredential;
383
384  TmpStr = NULL;
385
386  //
387  // Resolve each policy.
388  //
389  ChkLen  = 0;
390  while (ChkLen < IpLen) {
391    Identity = (EFI_USER_INFO_IDENTITY_POLICY *) (Ip + ChkLen);
392    switch (Identity->Type) {
393    case EFI_USER_INFO_IDENTITY_FALSE:
394      AddStr (&TmpStr, L"False");
395      break;
396
397    case EFI_USER_INFO_IDENTITY_TRUE:
398      AddStr (&TmpStr, L"None");
399      break;
400
401    case EFI_USER_INFO_IDENTITY_NOT:
402      AddStr (&TmpStr, L"! ");
403      break;
404
405    case EFI_USER_INFO_IDENTITY_AND:
406      AddStr (&TmpStr, L" && ");
407      break;
408
409    case EFI_USER_INFO_IDENTITY_OR:
410      AddStr (&TmpStr, L" || ");
411      break;
412
413    case EFI_USER_INFO_IDENTITY_CREDENTIAL_TYPE:
414      for (Index = 0; Index < mProviderInfo->Count; Index++) {
415        UserCredential = mProviderInfo->Provider[Index];
416        if (CompareGuid ((EFI_GUID *) (Identity + 1), &UserCredential->Type)) {
417          UserCredential->Title (
418                            UserCredential,
419                            &HiiHandle,
420                            &ProvId
421                            );
422          ProvStr = HiiGetString (HiiHandle, ProvId, NULL);
423          if (ProvStr != NULL) {
424            AddStr (&TmpStr, ProvStr);
425            FreePool (ProvStr);
426          }
427          break;
428        }
429      }
430      break;
431
432    case EFI_USER_INFO_IDENTITY_CREDENTIAL_PROVIDER:
433      for (Index = 0; Index < mProviderInfo->Count; Index++) {
434        UserCredential = mProviderInfo->Provider[Index];
435        if (CompareGuid ((EFI_GUID *) (Identity + 1), &UserCredential->Identifier)) {
436          UserCredential->Title (
437                            UserCredential,
438                            &HiiHandle,
439                            &ProvId
440                            );
441          ProvStr = HiiGetString (HiiHandle, ProvId, NULL);
442          if (ProvStr != NULL) {
443            AddStr (&TmpStr, ProvStr);
444            FreePool (ProvStr);
445          }
446          break;
447        }
448      }
449      break;
450    }
451
452    ChkLen += Identity->Length;
453  }
454
455  if (TmpStr != NULL) {
456    HiiSetString (mCallbackInfo->HiiHandle, IpStringId, TmpStr, NULL);
457    FreePool (TmpStr);
458  }
459}
460
461
462/**
463  Display modify user information form.
464
465  This form displays, username, create Date, usage date, usage count, identity policy,
466  and access policy.
467
468  @param[in] UserIndex       The index of the user in display list to modify.
469
470**/
471VOID
472ModifyUserInfo (
473  IN UINT8                                      UserIndex
474  )
475{
476  EFI_STATUS               Status;
477  EFI_USER_PROFILE_HANDLE  CurrentUser;
478  UINT32                   CurrentAccessRight;
479  VOID                     *StartOpCodeHandle;
480  VOID                     *EndOpCodeHandle;
481  EFI_IFR_GUID_LABEL       *StartLabel;
482  EFI_IFR_GUID_LABEL       *EndLabel;
483
484  //
485  // Initialize the container for dynamic opcodes.
486  //
487  StartOpCodeHandle = HiiAllocateOpCodeHandle ();
488  ASSERT (StartOpCodeHandle != NULL);
489
490  EndOpCodeHandle = HiiAllocateOpCodeHandle ();
491  ASSERT (EndOpCodeHandle != NULL);
492
493  //
494  // Create Hii Extend Label OpCode.
495  //
496  StartLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (
497                                        StartOpCodeHandle,
498                                        &gEfiIfrTianoGuid,
499                                        NULL,
500                                        sizeof (EFI_IFR_GUID_LABEL)
501                                        );
502  StartLabel->ExtendOpCode  = EFI_IFR_EXTEND_OP_LABEL;
503  StartLabel->Number        = LABEL_USER_INFO_FUNC;
504
505  EndLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (
506                                      EndOpCodeHandle,
507                                      &gEfiIfrTianoGuid,
508                                      NULL,
509                                      sizeof (EFI_IFR_GUID_LABEL)
510                                      );
511  EndLabel->ExtendOpCode  = EFI_IFR_EXTEND_OP_LABEL;
512  EndLabel->Number        = LABEL_END;
513
514  //
515  // Find the user profile to be modified.
516  //
517  mModifyUser = NULL;
518  Status      = mUserManager->GetNext (mUserManager, &mModifyUser);
519  if (EFI_ERROR (Status)) {
520    return ;
521  }
522
523  while (UserIndex > 1) {
524    Status = mUserManager->GetNext (mUserManager, &mModifyUser);
525    if (EFI_ERROR (Status)) {
526      return ;
527    }
528    UserIndex--;
529  }
530
531  //
532  // Get user profile information.
533  //
534  GetAllUserInfo ();
535
536  //
537  // Update user name.
538  HiiSetString (
539    mCallbackInfo->HiiHandle,
540    STRING_TOKEN (STR_USER_NAME_VAL),
541    mUserInfo.UserName,
542    NULL
543    );
544
545  //
546  // Update create date.
547  //
548  if (mUserInfo.CreateDateExist) {
549    ResolveDate (&mUserInfo.CreateDate, STRING_TOKEN (STR_CREATE_DATE_VAL));
550  } else {
551    HiiSetString (
552      mCallbackInfo->HiiHandle,
553      STRING_TOKEN (STR_CREATE_DATE_VAL),
554      L"",
555      NULL
556      );
557  }
558
559  //
560  // Add usage date.
561  //
562  if (mUserInfo.UsageDateExist) {
563    ResolveDate (&mUserInfo.UsageDate, STRING_TOKEN (STR_USAGE_DATE_VAL));
564  } else {
565    HiiSetString (
566      mCallbackInfo->HiiHandle,
567      STRING_TOKEN (STR_USAGE_DATE_VAL),
568      L"",
569      NULL
570      );
571  }
572
573  //
574  // Add usage count.
575  //
576  ResolveCount ((UINT32) mUserInfo.UsageCount, STRING_TOKEN (STR_USAGE_COUNT_VAL));
577
578  //
579  // Add identity policy.
580  //
581  mUserManager->Current (mUserManager, &CurrentUser);
582  if (mModifyUser == CurrentUser) {
583    ResolveIdentityPolicy (
584      mUserInfo.IdentityPolicy,
585      mUserInfo.IdentityPolicyLen,
586      STRING_TOKEN (STR_IDENTIFY_POLICY_VAL)
587      );
588    HiiCreateGotoOpCode (
589      StartOpCodeHandle,                                  // Container for opcodes
590      FORMID_MODIFY_IP,                                   // Target Form ID
591      STRING_TOKEN (STR_IDENTIFY_POLICY),                 // Prompt text
592      STRING_TOKEN (STR_IDENTIFY_POLICY_VAL),             // Help text
593      EFI_IFR_FLAG_CALLBACK,                              // Question flag
594      KEY_MODIFY_USER | KEY_SELECT_USER | KEY_MODIFY_IP   // Question ID
595      );
596  }
597
598  //
599  // Add access policy.
600  //
601  Status = GetAccessRight (&CurrentAccessRight);
602  if (EFI_ERROR (Status)) {
603    CurrentAccessRight = EFI_USER_INFO_ACCESS_ENROLL_SELF;
604  }
605
606  if (CurrentAccessRight == EFI_USER_INFO_ACCESS_MANAGE) {
607    HiiCreateGotoOpCode (
608      StartOpCodeHandle,                                  // Container for opcodes
609      FORMID_MODIFY_AP,                                   // Target Form ID
610      STRING_TOKEN (STR_ACCESS_POLICY),                   // Prompt text
611      STRING_TOKEN (STR_NULL_STRING),                     // Help text
612      EFI_IFR_FLAG_CALLBACK,                              // Question flag
613      KEY_MODIFY_USER | KEY_SELECT_USER | KEY_MODIFY_AP   // Question ID
614      );
615  }
616
617  HiiUpdateForm (
618    mCallbackInfo->HiiHandle,                             // HII handle
619    &gUserProfileManagerGuid,                             // Formset GUID
620    FORMID_USER_INFO,                                     // Form ID
621    StartOpCodeHandle,                                    // Label
622    EndOpCodeHandle                                       // Replace data
623    );
624
625  HiiFreeOpCodeHandle (StartOpCodeHandle);
626  HiiFreeOpCodeHandle (EndOpCodeHandle);
627}
628
629
630/**
631  Get all the access policy info from current user info, and save in the global
632  variable.
633
634**/
635VOID
636ResolveAccessPolicy (
637  VOID
638  )
639{
640  UINTN                         OffSet;
641  EFI_USER_INFO_ACCESS_CONTROL  Control;
642  UINTN                         ValLen;
643  UINT8                         *AccessData;
644
645  //
646  // Set default value
647  //
648  mAccessInfo.AccessRight       = EFI_USER_INFO_ACCESS_ENROLL_SELF;
649  mAccessInfo.AccessSetup       = ACCESS_SETUP_RESTRICTED;
650  mAccessInfo.AccessBootOrder   = EFI_USER_INFO_ACCESS_BOOT_ORDER_INSERT;
651
652  mAccessInfo.LoadPermitLen     = 0;
653  mAccessInfo.LoadForbidLen     = 0;
654  mAccessInfo.ConnectPermitLen  = 0;
655  mAccessInfo.ConnectForbidLen  = 0;
656
657  //
658  // Get each user access policy.
659  //
660  OffSet = 0;
661  while (OffSet < mUserInfo.AccessPolicyLen) {
662    CopyMem (&Control, mUserInfo.AccessPolicy + OffSet, sizeof (Control));
663    ValLen = Control.Size - sizeof (Control);
664    switch (Control.Type) {
665    case EFI_USER_INFO_ACCESS_ENROLL_SELF:
666      mAccessInfo.AccessRight = EFI_USER_INFO_ACCESS_ENROLL_SELF;
667      break;
668
669    case EFI_USER_INFO_ACCESS_ENROLL_OTHERS:
670      mAccessInfo.AccessRight = EFI_USER_INFO_ACCESS_ENROLL_OTHERS;
671      break;
672
673    case EFI_USER_INFO_ACCESS_MANAGE:
674      mAccessInfo.AccessRight = EFI_USER_INFO_ACCESS_MANAGE;
675      break;
676
677    case EFI_USER_INFO_ACCESS_SETUP:
678      AccessData = mUserInfo.AccessPolicy + OffSet + sizeof (Control);
679      if (CompareGuid ((EFI_GUID *) AccessData, &gEfiUserInfoAccessSetupNormalGuid)) {
680        mAccessInfo.AccessSetup = ACCESS_SETUP_NORMAL;
681      } else if (CompareGuid ((EFI_GUID *) AccessData, &gEfiUserInfoAccessSetupRestrictedGuid)) {
682        mAccessInfo.AccessSetup = ACCESS_SETUP_RESTRICTED;
683      } else if (CompareGuid ((EFI_GUID *) AccessData, &gEfiUserInfoAccessSetupAdminGuid)) {
684        mAccessInfo.AccessSetup = ACCESS_SETUP_ADMIN;
685      }
686      break;
687
688    case EFI_USER_INFO_ACCESS_BOOT_ORDER:
689      AccessData = mUserInfo.AccessPolicy + OffSet + sizeof (Control);
690      CopyMem (&mAccessInfo.AccessBootOrder, AccessData, sizeof (UINT32));
691      break;
692
693    case EFI_USER_INFO_ACCESS_FORBID_LOAD:
694      if (mAccessInfo.LoadForbid != NULL) {
695        FreePool (mAccessInfo.LoadForbid);
696      }
697
698      mAccessInfo.LoadForbid = AllocateZeroPool (ValLen);
699      if (mAccessInfo.LoadForbid != NULL) {
700        AccessData = mUserInfo.AccessPolicy + OffSet + sizeof (Control);
701        CopyMem (mAccessInfo.LoadForbid, AccessData, ValLen);
702        mAccessInfo.LoadForbidLen = ValLen;
703      }
704      break;
705
706    case EFI_USER_INFO_ACCESS_PERMIT_LOAD:
707      if (mAccessInfo.LoadPermit != NULL) {
708        FreePool (mAccessInfo.LoadPermit);
709      }
710
711      mAccessInfo.LoadPermit = AllocateZeroPool (ValLen);
712      if (mAccessInfo.LoadPermit != NULL) {
713        AccessData = mUserInfo.AccessPolicy + OffSet + sizeof (Control);
714        CopyMem (mAccessInfo.LoadPermit, AccessData, ValLen);
715        mAccessInfo.LoadPermitLen = ValLen;
716      }
717      break;
718
719    case EFI_USER_INFO_ACCESS_FORBID_CONNECT:
720      if (mAccessInfo.ConnectForbid != NULL) {
721        FreePool (mAccessInfo.ConnectForbid);
722      }
723
724      mAccessInfo.ConnectForbid = AllocateZeroPool (ValLen);
725      if (mAccessInfo.ConnectForbid != NULL) {
726        AccessData = mUserInfo.AccessPolicy + OffSet + sizeof (Control);
727        CopyMem (mAccessInfo.ConnectForbid, AccessData, ValLen);
728        mAccessInfo.ConnectForbidLen = ValLen;
729      }
730      break;
731
732    case EFI_USER_INFO_ACCESS_PERMIT_CONNECT:
733      if (mAccessInfo.ConnectPermit != NULL) {
734        FreePool (mAccessInfo.ConnectPermit);
735      }
736
737      mAccessInfo.ConnectPermit = AllocateZeroPool (ValLen);
738      if (mAccessInfo.ConnectPermit != NULL) {
739        AccessData = mUserInfo.AccessPolicy + OffSet + sizeof (Control);
740        CopyMem (mAccessInfo.ConnectPermit, AccessData, ValLen);
741        mAccessInfo.ConnectPermitLen = ValLen;
742      }
743      break;
744    }
745
746    OffSet += Control.Size;
747  }
748}
749
750
751/**
752  Find the specified info in profile mModifyUser by the InfoType.
753
754  @param[in]  InfoType     The user information type to find.
755  @param[out] UserInfo     Points to user information handle found.
756
757  @retval EFI_SUCCESS      Find the user information successfully.
758  @retval Others           Fail to find the user information.
759
760**/
761EFI_STATUS
762FindInfoByType (
763  IN  UINT8                                     InfoType,
764  OUT EFI_USER_INFO_HANDLE                      *UserInfo
765  )
766{
767  EFI_STATUS    Status;
768  EFI_USER_INFO *Info;
769  UINTN         InfoSize;
770  UINTN         MemSize;
771
772  if (UserInfo == NULL) {
773    return EFI_INVALID_PARAMETER;
774  }
775
776  *UserInfo = NULL;
777  //
778  // Allocate user information memory.
779  //
780  MemSize = sizeof (EFI_USER_INFO) + 63;
781  Info    = AllocateZeroPool (MemSize);
782  if (Info == NULL) {
783    return EFI_OUT_OF_RESOURCES;
784  }
785
786  //
787  // Get each user information.
788  //
789  while (TRUE) {
790    Status = mUserManager->GetNextInfo (mUserManager, mModifyUser, UserInfo);
791    if (EFI_ERROR (Status)) {
792      break;
793    }
794    //
795    // Get information.
796    //
797    InfoSize  = MemSize;
798    Status    = mUserManager->GetInfo (
799                                mUserManager,
800                                mModifyUser,
801                                *UserInfo,
802                                Info,
803                                &InfoSize
804                                );
805    if (Status == EFI_BUFFER_TOO_SMALL) {
806      MemSize = InfoSize;
807      FreePool (Info);
808      Info = AllocateZeroPool (MemSize);
809      if (Info == NULL) {
810        return EFI_OUT_OF_RESOURCES;
811      }
812      Status = mUserManager->GetInfo (
813                               mUserManager,
814                               mModifyUser,
815                               *UserInfo,
816                               Info,
817                               &InfoSize
818                               );
819    }
820    if (Status == EFI_SUCCESS) {
821      if (Info->InfoType == InfoType) {
822        break;
823      }
824    }
825  }
826
827  FreePool (Info);
828  return Status;
829}
830
831
832/**
833  Display modify user access policy form.
834
835  In this form, access right, access setup and access boot order are dynamically
836  added. Load devicepath and connect devicepath are displayed too.
837
838**/
839VOID
840ModidyAccessPolicy (
841  VOID
842  )
843{
844  VOID                *StartOpCodeHandle;
845  VOID                *EndOpCodeHandle;
846  VOID                *OptionsOpCodeHandle;
847  EFI_IFR_GUID_LABEL  *StartLabel;
848  EFI_IFR_GUID_LABEL  *EndLabel;
849  VOID                *DefaultOpCodeHandle;
850
851  //
852  // Initialize the container for dynamic opcodes.
853  //
854  StartOpCodeHandle = HiiAllocateOpCodeHandle ();
855  ASSERT (StartOpCodeHandle != NULL);
856
857  EndOpCodeHandle = HiiAllocateOpCodeHandle ();
858  ASSERT (EndOpCodeHandle != NULL);
859
860  //
861  // Create Hii Extend Label OpCode.
862  //
863  StartLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (
864                                        StartOpCodeHandle,
865                                        &gEfiIfrTianoGuid,
866                                        NULL,
867                                        sizeof (EFI_IFR_GUID_LABEL)
868                                        );
869  StartLabel->ExtendOpCode  = EFI_IFR_EXTEND_OP_LABEL;
870  StartLabel->Number        = LABEL_AP_MOD_FUNC;
871
872  EndLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (
873                                      EndOpCodeHandle,
874                                      &gEfiIfrTianoGuid,
875                                      NULL,
876                                      sizeof (EFI_IFR_GUID_LABEL)
877                                      );
878  EndLabel->ExtendOpCode  = EFI_IFR_EXTEND_OP_LABEL;
879  EndLabel->Number        = LABEL_END;
880
881
882  //
883  // Resolve access policy information.
884  //
885  ResolveAccessPolicy ();
886
887  //
888  // Add access right one-of-code.
889  //
890  OptionsOpCodeHandle = HiiAllocateOpCodeHandle ();
891  ASSERT (OptionsOpCodeHandle != NULL);
892  DefaultOpCodeHandle = HiiAllocateOpCodeHandle ();
893  ASSERT (DefaultOpCodeHandle != NULL);
894
895  HiiCreateOneOfOptionOpCode (
896    OptionsOpCodeHandle,
897    STRING_TOKEN (STR_NORMAL),
898    0,
899    EFI_IFR_NUMERIC_SIZE_1,
900    EFI_USER_INFO_ACCESS_ENROLL_SELF
901    );
902
903  HiiCreateOneOfOptionOpCode (
904    OptionsOpCodeHandle,
905    STRING_TOKEN (STR_ENROLL),
906    0,
907    EFI_IFR_NUMERIC_SIZE_1,
908    EFI_USER_INFO_ACCESS_ENROLL_OTHERS
909    );
910
911  HiiCreateOneOfOptionOpCode (
912    OptionsOpCodeHandle,
913    STRING_TOKEN (STR_MANAGE),
914    0,
915    EFI_IFR_NUMERIC_SIZE_1,
916    EFI_USER_INFO_ACCESS_MANAGE
917    );
918
919  HiiCreateDefaultOpCode (
920    DefaultOpCodeHandle,
921    EFI_HII_DEFAULT_CLASS_STANDARD,
922    EFI_IFR_NUMERIC_SIZE_1,
923    mAccessInfo.AccessRight
924    );
925
926  HiiCreateOneOfOpCode (
927    StartOpCodeHandle,                    // Container for dynamic created opcodes
928    KEY_MODIFY_USER | KEY_SELECT_USER | KEY_MODIFY_AP | KEY_MODIFY_RIGHT, // Question ID
929    0,                                    // VarStore ID
930    0,                                    // Offset in Buffer Storage
931    STRING_TOKEN (STR_ACCESS_RIGHT),      // Question prompt text
932    STRING_TOKEN (STR_ACCESS_RIGHT_HELP), // Question help text
933    EFI_IFR_FLAG_CALLBACK,                // Question flag
934    EFI_IFR_NUMERIC_SIZE_1,               // Data type of Question Value
935    OptionsOpCodeHandle,                  // Option Opcode list
936    DefaultOpCodeHandle                   // Default Opcode
937    );
938  HiiFreeOpCodeHandle (DefaultOpCodeHandle);
939  HiiFreeOpCodeHandle (OptionsOpCodeHandle);
940
941
942  //
943  // Add setup type one-of-code.
944  //
945  OptionsOpCodeHandle = HiiAllocateOpCodeHandle ();
946  ASSERT (OptionsOpCodeHandle != NULL);
947  DefaultOpCodeHandle = HiiAllocateOpCodeHandle ();
948  ASSERT (DefaultOpCodeHandle != NULL);
949
950  HiiCreateOneOfOptionOpCode (
951    OptionsOpCodeHandle,
952    STRING_TOKEN (STR_RESTRICTED),
953    0,
954    EFI_IFR_NUMERIC_SIZE_1,
955    ACCESS_SETUP_RESTRICTED
956    );
957
958  HiiCreateOneOfOptionOpCode (
959    OptionsOpCodeHandle,
960    STRING_TOKEN (STR_NORMAL),
961    0,
962    EFI_IFR_NUMERIC_SIZE_1,
963    ACCESS_SETUP_NORMAL
964    );
965
966  HiiCreateOneOfOptionOpCode (
967    OptionsOpCodeHandle,
968    STRING_TOKEN (STR_ADMIN),
969    0,
970    EFI_IFR_NUMERIC_SIZE_1,
971    ACCESS_SETUP_ADMIN
972    );
973
974  HiiCreateDefaultOpCode (
975    DefaultOpCodeHandle,
976    EFI_HII_DEFAULT_CLASS_STANDARD,
977    EFI_IFR_NUMERIC_SIZE_1,
978    mAccessInfo.AccessSetup
979    );
980
981  HiiCreateOneOfOpCode (
982    StartOpCodeHandle,                    // Container for dynamic created opcodes
983    KEY_MODIFY_USER | KEY_SELECT_USER | KEY_MODIFY_AP | KEY_MODIFY_SETUP, // Question ID
984    0,                                    // VarStore ID
985    0,                                    // Offset in Buffer Storage
986    STRING_TOKEN (STR_ACCESS_SETUP),      // Question prompt text
987    STRING_TOKEN (STR_ACCESS_SETUP_HELP), // Question help text
988    EFI_IFR_FLAG_CALLBACK,                // Question flag
989    EFI_IFR_NUMERIC_SIZE_1,               // Data type of Question Value
990    OptionsOpCodeHandle,                  // Option Opcode list
991    DefaultOpCodeHandle                   // Default Opcode
992    );
993  HiiFreeOpCodeHandle (DefaultOpCodeHandle);
994  HiiFreeOpCodeHandle (OptionsOpCodeHandle);
995
996  //
997  // Add boot order one-of-code.
998  //
999  OptionsOpCodeHandle = HiiAllocateOpCodeHandle ();
1000  ASSERT (OptionsOpCodeHandle != NULL);
1001  DefaultOpCodeHandle = HiiAllocateOpCodeHandle ();
1002  ASSERT (DefaultOpCodeHandle != NULL);
1003
1004  HiiCreateOneOfOptionOpCode (
1005    OptionsOpCodeHandle,
1006    STRING_TOKEN (STR_INSERT),
1007    0,
1008    EFI_IFR_NUMERIC_SIZE_4,
1009    EFI_USER_INFO_ACCESS_BOOT_ORDER_INSERT
1010    );
1011
1012  HiiCreateOneOfOptionOpCode (
1013    OptionsOpCodeHandle,
1014    STRING_TOKEN (STR_APPEND),
1015    0,
1016    EFI_IFR_NUMERIC_SIZE_4,
1017    EFI_USER_INFO_ACCESS_BOOT_ORDER_APPEND
1018    );
1019
1020  HiiCreateOneOfOptionOpCode (
1021    OptionsOpCodeHandle,
1022    STRING_TOKEN (STR_REPLACE),
1023    0,
1024    EFI_IFR_NUMERIC_SIZE_4,
1025    EFI_USER_INFO_ACCESS_BOOT_ORDER_REPLACE
1026    );
1027
1028  HiiCreateOneOfOptionOpCode (
1029    OptionsOpCodeHandle,
1030    STRING_TOKEN (STR_NODEFAULT),
1031    0,
1032    EFI_IFR_NUMERIC_SIZE_4,
1033    EFI_USER_INFO_ACCESS_BOOT_ORDER_NODEFAULT
1034    );
1035
1036  HiiCreateDefaultOpCode (
1037    DefaultOpCodeHandle,
1038    EFI_HII_DEFAULT_CLASS_STANDARD,
1039    EFI_IFR_NUMERIC_SIZE_4,
1040    mAccessInfo.AccessBootOrder
1041    );
1042
1043  HiiCreateOneOfOpCode (
1044    StartOpCodeHandle,                  // Container for dynamic created opcodes
1045    KEY_MODIFY_USER | KEY_SELECT_USER | KEY_MODIFY_AP | KEY_MODIFY_BOOT, // Question ID
1046    0,                                  // VarStore ID
1047    0,                                  // Offset in Buffer Storage
1048    STRING_TOKEN (STR_BOOR_ORDER),      // Question prompt text
1049    STRING_TOKEN (STR_BOOT_ORDER_HELP), // Question help text
1050    EFI_IFR_FLAG_CALLBACK,              // Question flag
1051    EFI_IFR_NUMERIC_SIZE_1,             // Data type of Question Value
1052    OptionsOpCodeHandle,                // Option Opcode list
1053    DefaultOpCodeHandle                 // Default Opcode
1054    );
1055  HiiFreeOpCodeHandle (DefaultOpCodeHandle);
1056  HiiFreeOpCodeHandle (OptionsOpCodeHandle);
1057
1058  //
1059  // Update Form.
1060  //
1061  HiiUpdateForm (
1062    mCallbackInfo->HiiHandle,           // HII handle
1063    &gUserProfileManagerGuid,           // Formset GUID
1064    FORMID_MODIFY_AP,                   // Form ID
1065    StartOpCodeHandle,                  // Label for where to insert opcodes
1066    EndOpCodeHandle                     // Replace data
1067    );
1068
1069  HiiFreeOpCodeHandle (StartOpCodeHandle);
1070  HiiFreeOpCodeHandle (EndOpCodeHandle);
1071}
1072
1073
1074/**
1075  Expand access policy memory size.
1076
1077  @param[in] ValidLen       The valid access policy length.
1078  @param[in] ExpandLen      The length that is needed to expand.
1079
1080**/
1081VOID
1082ExpandMemory (
1083  IN      UINTN                                 ValidLen,
1084  IN      UINTN                                 ExpandLen
1085  )
1086{
1087  UINT8 *Mem;
1088  UINTN Len;
1089
1090  //
1091  // Expand memory.
1092  //
1093  Len = mUserInfo.AccessPolicyLen + (ExpandLen / 64 + 1) * 64;
1094  Mem = AllocateZeroPool (Len);
1095  ASSERT (Mem != NULL);
1096
1097  if (mUserInfo.AccessPolicy != NULL) {
1098    CopyMem (Mem, mUserInfo.AccessPolicy, ValidLen);
1099    FreePool (mUserInfo.AccessPolicy);
1100  }
1101
1102  mUserInfo.AccessPolicy    = Mem;
1103  mUserInfo.AccessPolicyLen = Len;
1104}
1105
1106
1107/**
1108  Collect all the access policy data to mUserInfo.AccessPolicy,
1109  and save it to user profile.
1110
1111**/
1112VOID
1113SaveAccessPolicy (
1114  VOID
1115  )
1116{
1117  EFI_STATUS                    Status;
1118  UINTN                         OffSet;
1119  UINTN                         Size;
1120  EFI_USER_INFO_ACCESS_CONTROL  Control;
1121  EFI_USER_INFO_HANDLE          UserInfo;
1122  EFI_USER_INFO                 *Info;
1123
1124  if (mUserInfo.AccessPolicy != NULL) {
1125    FreePool (mUserInfo.AccessPolicy);
1126  }
1127  mUserInfo.AccessPolicy          = NULL;
1128  mUserInfo.AccessPolicyLen       = 0;
1129  mUserInfo.AccessPolicyModified  = TRUE;
1130  OffSet                          = 0;
1131
1132  //
1133  // Save access right.
1134  //
1135  Size = sizeof (EFI_USER_INFO_ACCESS_CONTROL);
1136  if (mUserInfo.AccessPolicyLen - OffSet < Size) {
1137    ExpandMemory (OffSet, Size);
1138  }
1139
1140  Control.Type = mAccessInfo.AccessRight;
1141  Control.Size = (UINT32) Size;
1142  CopyMem (mUserInfo.AccessPolicy + OffSet, &Control, sizeof (Control));
1143  OffSet += sizeof (Control);
1144
1145  //
1146  // Save access setup.
1147  //
1148  Size = sizeof (EFI_USER_INFO_ACCESS_CONTROL) + sizeof (EFI_GUID);
1149  if (mUserInfo.AccessPolicyLen - OffSet < Size) {
1150    ExpandMemory (OffSet, Size);
1151  }
1152
1153  Control.Type = EFI_USER_INFO_ACCESS_SETUP;
1154  Control.Size = (UINT32) Size;
1155  CopyMem (mUserInfo.AccessPolicy + OffSet, &Control, sizeof (Control));
1156  OffSet += sizeof (Control);
1157
1158  if (mAccessInfo.AccessSetup == ACCESS_SETUP_NORMAL) {
1159    CopyGuid ((EFI_GUID *) (mUserInfo.AccessPolicy + OffSet), &gEfiUserInfoAccessSetupNormalGuid);
1160  } else if (mAccessInfo.AccessSetup == ACCESS_SETUP_RESTRICTED) {
1161    CopyGuid ((EFI_GUID *) (mUserInfo.AccessPolicy + OffSet), &gEfiUserInfoAccessSetupRestrictedGuid);
1162  } else if (mAccessInfo.AccessSetup == ACCESS_SETUP_ADMIN) {
1163    CopyGuid ((EFI_GUID *) (mUserInfo.AccessPolicy + OffSet), &gEfiUserInfoAccessSetupAdminGuid);
1164  }
1165  OffSet += sizeof (EFI_GUID);
1166
1167  //
1168  // Save access of boot order.
1169  //
1170  Size = sizeof (EFI_USER_INFO_ACCESS_CONTROL) + sizeof (UINT32);
1171  if (mUserInfo.AccessPolicyLen - OffSet < Size) {
1172    ExpandMemory (OffSet, Size);
1173  }
1174
1175  Control.Type = EFI_USER_INFO_ACCESS_BOOT_ORDER;
1176  Control.Size = (UINT32) Size;
1177  CopyMem (mUserInfo.AccessPolicy + OffSet, &Control, sizeof (Control));
1178  OffSet += sizeof (Control);
1179
1180  CopyMem ((UINT8 *) (mUserInfo.AccessPolicy + OffSet), &mAccessInfo.AccessBootOrder, sizeof (UINT32));
1181  OffSet += sizeof (UINT32);
1182
1183  //
1184  // Save permit load.
1185  //
1186  if (mAccessInfo.LoadPermitLen > 0) {
1187    Size = sizeof (EFI_USER_INFO_ACCESS_CONTROL) + mAccessInfo.LoadPermitLen;
1188    if (mUserInfo.AccessPolicyLen - OffSet < Size) {
1189      ExpandMemory (OffSet, Size);
1190    }
1191
1192    Control.Type = EFI_USER_INFO_ACCESS_PERMIT_LOAD;
1193    Control.Size = (UINT32) Size;
1194    CopyMem (mUserInfo.AccessPolicy + OffSet, &Control, sizeof (Control));
1195    OffSet += sizeof (Control);
1196
1197    CopyMem (mUserInfo.AccessPolicy + OffSet, mAccessInfo.LoadPermit, mAccessInfo.LoadPermitLen);
1198    OffSet += mAccessInfo.LoadPermitLen;
1199  }
1200
1201  //
1202  // Save forbid load.
1203  //
1204  if (mAccessInfo.LoadForbidLen > 0) {
1205    Size = sizeof (EFI_USER_INFO_ACCESS_CONTROL) + mAccessInfo.LoadForbidLen;
1206    if (mUserInfo.AccessPolicyLen - OffSet < Size) {
1207      ExpandMemory (OffSet, Size);
1208    }
1209
1210    Control.Type = EFI_USER_INFO_ACCESS_FORBID_LOAD;
1211    Control.Size = (UINT32) Size;
1212    CopyMem (mUserInfo.AccessPolicy + OffSet, &Control, sizeof (Control));
1213    OffSet += sizeof (Control);
1214
1215    CopyMem (mUserInfo.AccessPolicy + OffSet, mAccessInfo.LoadForbid, mAccessInfo.LoadForbidLen);
1216    OffSet += mAccessInfo.LoadForbidLen;
1217  }
1218
1219  //
1220  // Save permit connect.
1221  //
1222  if (mAccessInfo.ConnectPermitLen > 0) {
1223    Size = sizeof (EFI_USER_INFO_ACCESS_CONTROL) + mAccessInfo.ConnectPermitLen;
1224    if (mUserInfo.AccessPolicyLen - OffSet < Size) {
1225      ExpandMemory (OffSet, Size);
1226    }
1227
1228    Control.Type = EFI_USER_INFO_ACCESS_PERMIT_CONNECT;
1229    Control.Size = (UINT32) Size;
1230    CopyMem (mUserInfo.AccessPolicy + OffSet, &Control, sizeof (Control));
1231    OffSet += sizeof (Control);
1232
1233    CopyMem (mUserInfo.AccessPolicy + OffSet, mAccessInfo.ConnectPermit, mAccessInfo.ConnectPermitLen);
1234    OffSet += mAccessInfo.ConnectPermitLen;
1235  }
1236
1237  //
1238  // Save forbid connect.
1239  //
1240  if (mAccessInfo.ConnectForbidLen > 0) {
1241    Size = sizeof (EFI_USER_INFO_ACCESS_CONTROL) + mAccessInfo.ConnectForbidLen;
1242    if (mUserInfo.AccessPolicyLen - OffSet < Size) {
1243      ExpandMemory (OffSet, Size);
1244    }
1245
1246    Control.Type = EFI_USER_INFO_ACCESS_FORBID_CONNECT;
1247    Control.Size = (UINT32) Size;
1248    CopyMem (mUserInfo.AccessPolicy + OffSet, &Control, sizeof (Control));
1249    OffSet += sizeof (Control);
1250
1251    CopyMem (mUserInfo.AccessPolicy + OffSet, mAccessInfo.ConnectForbid, mAccessInfo.ConnectForbidLen);
1252    OffSet += mAccessInfo.ConnectForbidLen;
1253  }
1254
1255  mUserInfo.AccessPolicyLen = OffSet;
1256
1257  //
1258  // Save access policy.
1259  //
1260  if (mUserInfo.AccessPolicyModified && (mUserInfo.AccessPolicyLen > 0)) {
1261    Info = AllocateZeroPool (sizeof (EFI_USER_INFO) + mUserInfo.AccessPolicyLen);
1262    if (Info == NULL) {
1263      return ;
1264    }
1265
1266    Status = FindInfoByType (EFI_USER_INFO_ACCESS_POLICY_RECORD, &UserInfo);
1267    if (!EFI_ERROR (Status)) {
1268      Info->InfoType    = EFI_USER_INFO_ACCESS_POLICY_RECORD;
1269      Info->InfoAttribs = EFI_USER_INFO_STORAGE_PLATFORM_NV |
1270                          EFI_USER_INFO_PUBLIC |
1271                          EFI_USER_INFO_EXCLUSIVE;
1272      Info->InfoSize    = (UINT32) (sizeof (EFI_USER_INFO) + mUserInfo.AccessPolicyLen);
1273      CopyMem ((UINT8 *) (Info + 1), mUserInfo.AccessPolicy, mUserInfo.AccessPolicyLen);
1274      Status = mUserManager->SetInfo (
1275                               mUserManager,
1276                               mModifyUser,
1277                               &UserInfo,
1278                               Info,
1279                               Info->InfoSize
1280                               );
1281      mUserInfo.AccessPolicyModified = FALSE;
1282    }
1283    FreePool (Info);
1284  }
1285
1286  if (mAccessInfo.ConnectForbid != NULL) {
1287    FreePool (mAccessInfo.ConnectForbid);
1288    mAccessInfo.ConnectForbid = NULL;
1289  }
1290
1291  if (mAccessInfo.ConnectPermit != NULL) {
1292    FreePool (mAccessInfo.ConnectPermit);
1293    mAccessInfo.ConnectPermit = NULL;
1294  }
1295
1296  if (mAccessInfo.LoadForbid != NULL) {
1297    FreePool (mAccessInfo.LoadForbid);
1298    mAccessInfo.LoadForbid = NULL;
1299  }
1300
1301  if (mAccessInfo.LoadPermit != NULL) {
1302    FreePool (mAccessInfo.LoadPermit);
1303    mAccessInfo.LoadPermit = NULL;
1304  }
1305}
1306
1307
1308/**
1309  Get the username from user input, and update username string in the Hii
1310  database with it.
1311
1312**/
1313VOID
1314ModifyUserName (
1315  VOID
1316  )
1317{
1318  EFI_STATUS              Status;
1319  CHAR16                  UserName[USER_NAME_LENGTH];
1320  UINTN                   Len;
1321  EFI_INPUT_KEY           Key;
1322  EFI_USER_INFO_HANDLE    UserInfo;
1323  EFI_USER_INFO           *Info;
1324  EFI_USER_PROFILE_HANDLE TempUser;
1325
1326  //
1327  // Get the new user name.
1328  //
1329  Len = sizeof (UserName);
1330  Status = GetUserNameInput (&Len, UserName);
1331  if (EFI_ERROR (Status)) {
1332    if (Status != EFI_ABORTED) {
1333      CreatePopUp (
1334        EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
1335        &Key,
1336        L"Failed To Get User Name.",
1337        L"",
1338        L"Please Press Any Key to Continue ...",
1339        NULL
1340        );
1341    }
1342    return ;
1343  }
1344
1345  //
1346  // Check whether the username had been used or not.
1347  //
1348  Info = AllocateZeroPool (sizeof (EFI_USER_INFO) + Len);
1349  if (Info == NULL) {
1350    return ;
1351  }
1352
1353  Info->InfoType    = EFI_USER_INFO_NAME_RECORD;
1354  Info->InfoAttribs = EFI_USER_INFO_STORAGE_PLATFORM_NV |
1355                      EFI_USER_INFO_PUBLIC |
1356                      EFI_USER_INFO_EXCLUSIVE;
1357  Info->InfoSize    = (UINT32) (sizeof (EFI_USER_INFO) + Len);
1358  CopyMem ((UINT8 *) (Info + 1), UserName, Len);
1359
1360  TempUser  = NULL;
1361  Status    = mUserManager->Find (
1362                              mUserManager,
1363                              &TempUser,
1364                              NULL,
1365                              Info,
1366                              Info->InfoSize
1367                              );
1368  if (!EFI_ERROR (Status)) {
1369    CreatePopUp (
1370      EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
1371      &Key,
1372      L"The User Name Had Been Used.",
1373      L"",
1374      L"Please Use Other User Name",
1375      NULL
1376      );
1377    FreePool (Info);
1378    return ;
1379  }
1380
1381  //
1382  // Update username display in the form.
1383  //
1384  CopyMem (mUserInfo.UserName, UserName, Len);
1385  HiiSetString (
1386    mCallbackInfo->HiiHandle,
1387    STRING_TOKEN (STR_USER_NAME_VAL),
1388    mUserInfo.UserName,
1389    NULL
1390    );
1391
1392  //
1393  // Save the user name.
1394  //
1395  Status = FindInfoByType (EFI_USER_INFO_NAME_RECORD, &UserInfo);
1396  if (!EFI_ERROR (Status)) {
1397    mUserManager->SetInfo (
1398                    mUserManager,
1399                    mModifyUser,
1400                    &UserInfo,
1401                    Info,
1402                    Info->InfoSize
1403                    );
1404  }
1405  FreePool (Info);
1406}
1407
1408
1409/**
1410  Display the form of the modifying user identity policy.
1411
1412**/
1413VOID
1414ModifyIdentityPolicy (
1415  VOID
1416  )
1417{
1418  UINTN               Index;
1419  CHAR16              *ProvStr;
1420  EFI_STRING_ID       ProvID;
1421  EFI_HII_HANDLE      HiiHandle;
1422  VOID                *OptionsOpCodeHandle;
1423  VOID                *StartOpCodeHandle;
1424  VOID                *EndOpCodeHandle;
1425  EFI_IFR_GUID_LABEL  *StartLabel;
1426  EFI_IFR_GUID_LABEL  *EndLabel;
1427
1428  //
1429  // Initialize the container for dynamic opcodes.
1430  //
1431  StartOpCodeHandle = HiiAllocateOpCodeHandle ();
1432  ASSERT (StartOpCodeHandle != NULL);
1433
1434  EndOpCodeHandle = HiiAllocateOpCodeHandle ();
1435  ASSERT (EndOpCodeHandle != NULL);
1436
1437  //
1438  // Create Hii Extend Label OpCode.
1439  //
1440  StartLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (
1441                                        StartOpCodeHandle,
1442                                        &gEfiIfrTianoGuid,
1443                                        NULL,
1444                                        sizeof (EFI_IFR_GUID_LABEL)
1445                                        );
1446  StartLabel->ExtendOpCode  = EFI_IFR_EXTEND_OP_LABEL;
1447  StartLabel->Number        = LABEL_IP_MOD_FUNC;
1448
1449  EndLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (
1450                                      EndOpCodeHandle,
1451                                      &gEfiIfrTianoGuid,
1452                                      NULL,
1453                                      sizeof (EFI_IFR_GUID_LABEL)
1454                                      );
1455  EndLabel->ExtendOpCode  = EFI_IFR_EXTEND_OP_LABEL;
1456  EndLabel->Number        = LABEL_END;
1457
1458  //
1459  // Add credential providers
1460  //.
1461  if (mProviderInfo->Count > 0) {
1462    OptionsOpCodeHandle = HiiAllocateOpCodeHandle ();
1463    ASSERT (OptionsOpCodeHandle != NULL);
1464
1465    //
1466    // Add credential provider Option OpCode.
1467    //
1468    for (Index = 0; Index < mProviderInfo->Count; Index++) {
1469      mProviderInfo->Provider[Index]->Title (
1470                                        mProviderInfo->Provider[Index],
1471                                        &HiiHandle,
1472                                        &ProvID
1473                                        );
1474      ProvStr = HiiGetString (HiiHandle, ProvID, NULL);
1475      ProvID  = HiiSetString (mCallbackInfo->HiiHandle, 0, ProvStr, NULL);
1476      FreePool (ProvStr);
1477      if (ProvID == 0) {
1478        return ;
1479      }
1480
1481      HiiCreateOneOfOptionOpCode (
1482        OptionsOpCodeHandle,
1483        ProvID,
1484        0,
1485        EFI_IFR_NUMERIC_SIZE_1,
1486        (UINT8) Index
1487        );
1488    }
1489
1490    HiiCreateOneOfOpCode (
1491      StartOpCodeHandle,                // Container for dynamic created opcodes
1492      KEY_MODIFY_USER | KEY_SELECT_USER | KEY_MODIFY_IP | KEY_MODIFY_PROV,  // Question ID
1493      0,                                // VarStore ID
1494      0,                                // Offset in Buffer Storage
1495      STRING_TOKEN (STR_PROVIDER),      // Question prompt text
1496      STRING_TOKEN (STR_PROVIDER_HELP), // Question help text
1497      EFI_IFR_FLAG_CALLBACK,            // Question flag
1498      EFI_IFR_NUMERIC_SIZE_1,           // Data type of Question Value
1499      OptionsOpCodeHandle,              // Option Opcode list
1500      NULL                              // Default Opcode is NULl
1501      );
1502
1503    HiiFreeOpCodeHandle (OptionsOpCodeHandle);
1504  }
1505
1506  //
1507  // Add logical connector Option OpCode.
1508  //
1509  OptionsOpCodeHandle = HiiAllocateOpCodeHandle ();
1510  ASSERT (OptionsOpCodeHandle != NULL);
1511
1512  HiiCreateOneOfOptionOpCode (
1513    OptionsOpCodeHandle,
1514    STRING_TOKEN (STR_AND_CON),
1515    0,
1516    EFI_IFR_NUMERIC_SIZE_1,
1517    0
1518    );
1519
1520  HiiCreateOneOfOptionOpCode (
1521    OptionsOpCodeHandle,
1522    STRING_TOKEN (STR_OR_CON),
1523    0,
1524    EFI_IFR_NUMERIC_SIZE_1,
1525    1
1526    );
1527
1528  HiiCreateOneOfOpCode (
1529    StartOpCodeHandle,                  // Container for dynamic created opcodes
1530    KEY_MODIFY_USER | KEY_SELECT_USER | KEY_MODIFY_IP | KEY_MODIFY_CONN,  // Question ID
1531    0,                                  // VarStore ID
1532    0,                                  // Offset in Buffer Storage
1533    STRING_TOKEN (STR_CONNECTOR),       // Question prompt text
1534    STRING_TOKEN (STR_CONNECTOR_HELP),  // Question help text
1535    EFI_IFR_FLAG_CALLBACK,              // Question flag
1536    EFI_IFR_NUMERIC_SIZE_1,             // Data type of Question Value
1537    OptionsOpCodeHandle,                // Option Opcode list
1538    NULL                                // Default Opcode is NULl
1539    );
1540
1541  HiiFreeOpCodeHandle (OptionsOpCodeHandle);
1542
1543  //
1544  // Update identity policy in the form.
1545  //
1546  ResolveIdentityPolicy (
1547    mUserInfo.IdentityPolicy,
1548    mUserInfo.IdentityPolicyLen,
1549    STRING_TOKEN (STR_IDENTIFY_POLICY_VALUE)
1550    );
1551
1552  if (mUserInfo.NewIdentityPolicy != NULL) {
1553    FreePool (mUserInfo.NewIdentityPolicy);
1554    mUserInfo.NewIdentityPolicy         = NULL;
1555    mUserInfo.NewIdentityPolicyLen      = 0;
1556    mUserInfo.NewIdentityPolicyModified = FALSE;
1557  }
1558  mProviderChoice = 0;
1559  mConncetLogical = 0;
1560
1561  HiiUpdateForm (
1562    mCallbackInfo->HiiHandle, // HII handle
1563    &gUserProfileManagerGuid, // Formset GUID
1564    FORMID_MODIFY_IP,         // Form ID
1565    StartOpCodeHandle,        // Label for where to insert opcodes
1566    EndOpCodeHandle           // Replace data
1567    );
1568
1569  HiiFreeOpCodeHandle (StartOpCodeHandle);
1570  HiiFreeOpCodeHandle (EndOpCodeHandle);
1571}
1572
1573
1574/**
1575  Save the identity policy and update UI with it.
1576
1577  This funciton will verify the new identity policy, in current implementation,
1578  the identity policy can be:  T, P & P & P & ..., P | P | P | ...
1579  Here, "T" means "True", "P" means "Credential Provider", "&" means "and", "|" means "or".
1580  Other identity policies are not supported.
1581
1582**/
1583VOID
1584SaveIdentityPolicy (
1585  VOID
1586  )
1587{
1588  EFI_STATUS                    Status;
1589  EFI_USER_INFO_IDENTITY_POLICY *Identity;
1590  EFI_USER_INFO_HANDLE          UserInfo;
1591  EFI_USER_INFO                 *Info;
1592  EFI_INPUT_KEY                 Key;
1593  UINTN                         Offset;
1594  UINT32                        OpCode;
1595  UINTN                         InfoSize;
1596
1597  if (!mUserInfo.NewIdentityPolicyModified || (mUserInfo.NewIdentityPolicyLen == 0)) {
1598    return;
1599  }
1600
1601  //
1602  // Check policy expression.
1603  //
1604  OpCode  = EFI_USER_INFO_IDENTITY_FALSE;
1605  Offset  = 0;
1606  while (Offset < mUserInfo.NewIdentityPolicyLen) {
1607    //
1608    // Check access policy according to type
1609    //
1610    Identity = (EFI_USER_INFO_IDENTITY_POLICY *) (mUserInfo.NewIdentityPolicy + Offset);
1611    switch (Identity->Type) {
1612
1613    case EFI_USER_INFO_IDENTITY_TRUE:
1614      break;
1615
1616    case EFI_USER_INFO_IDENTITY_OR:
1617      if (OpCode == EFI_USER_INFO_IDENTITY_AND) {
1618        CreatePopUp (
1619          EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
1620          &Key,
1621          L"Invalid Identity Policy, Mixed Connector Unsupport!",
1622          L"",
1623          L"Press Any Key to Continue ...",
1624          NULL
1625          );
1626        return ;
1627      }
1628
1629      OpCode = EFI_USER_INFO_IDENTITY_OR;
1630      break;
1631
1632    case EFI_USER_INFO_IDENTITY_AND:
1633      if (OpCode == EFI_USER_INFO_IDENTITY_OR) {
1634        CreatePopUp (
1635          EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
1636          &Key,
1637          L"Invalid Identity Policy, Mixed Connector Unsupport!",
1638          L"",
1639          L"Press Any Key to Continue ...",
1640          NULL
1641          );
1642        return ;
1643      }
1644
1645      OpCode = EFI_USER_INFO_IDENTITY_AND;
1646      break;
1647
1648    case EFI_USER_INFO_IDENTITY_CREDENTIAL_PROVIDER:
1649      break;
1650
1651    default:
1652      CreatePopUp (
1653        EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
1654        &Key,
1655        L"Unsupport parameter",
1656        L"",
1657        L"Press Any Key to Continue ...",
1658        NULL
1659        );
1660      return ;
1661    }
1662    Offset += Identity->Length;
1663  }
1664
1665  //
1666  // Save identity policy.
1667  //
1668  Info = AllocateZeroPool (
1669           sizeof (EFI_USER_INFO) +
1670           mUserInfo.NewIdentityPolicyLen
1671           );
1672  if (Info == NULL) {
1673    return ;
1674  }
1675
1676  Status = FindInfoByType (EFI_USER_INFO_IDENTITY_POLICY_RECORD, &UserInfo);
1677  if (EFI_ERROR (Status)) {
1678    FreePool (Info);
1679    return ;
1680  }
1681
1682  Info->InfoType    = EFI_USER_INFO_IDENTITY_POLICY_RECORD;
1683  Info->InfoAttribs = EFI_USER_INFO_STORAGE_PLATFORM_NV |
1684                      EFI_USER_INFO_PRIVATE |
1685                      EFI_USER_INFO_EXCLUSIVE;
1686  Info->InfoSize    = (UINT32) (sizeof (EFI_USER_INFO) + mUserInfo.NewIdentityPolicyLen);
1687  CopyMem ((UINT8 *) (Info + 1), mUserInfo.NewIdentityPolicy, mUserInfo.NewIdentityPolicyLen);
1688  Status = mUserManager->SetInfo (
1689                           mUserManager,
1690                           mModifyUser,
1691                           &UserInfo,
1692                           Info,
1693                           Info->InfoSize
1694                           );
1695  FreePool (Info);
1696  if (EFI_ERROR (Status)) {
1697    //
1698    // Get the user information again, it may be changed during saving it.
1699    //
1700    InfoSize = 0;
1701    Status = mUserManager->GetInfo (
1702                             mUserManager,
1703                             mModifyUser,
1704                             UserInfo,
1705                             Info,
1706                             &InfoSize
1707                             );
1708    if (Status == EFI_BUFFER_TOO_SMALL) {
1709      Info = AllocateZeroPool (InfoSize);
1710      ASSERT (Info != NULL);
1711      Status = mUserManager->GetInfo (
1712                               mUserManager,
1713                               mModifyUser,
1714                               UserInfo,
1715                               Info,
1716                               &InfoSize
1717                               );
1718    }
1719    ASSERT_EFI_ERROR (Status);
1720
1721    //
1722    // Save current identification policy to mUserInfo.IdentityPolicy.
1723    //
1724    ASSERT (Info != NULL);
1725    if (mUserInfo.IdentityPolicy != NULL) {
1726      FreePool (mUserInfo.IdentityPolicy);
1727    }
1728
1729    mUserInfo.IdentityPolicyLen = Info->InfoSize - sizeof (EFI_USER_INFO);
1730    mUserInfo.IdentityPolicy    = AllocateCopyPool (mUserInfo.IdentityPolicyLen, Info + 1);
1731    ASSERT (mUserInfo.IdentityPolicy != NULL);
1732
1733    //
1734    // Free the memory
1735    //
1736    FreePool (Info);
1737    FreePool (mUserInfo.NewIdentityPolicy);
1738  } else {
1739    //
1740    // Update the mUserInfo.IdentityPolicy by mUserInfo.NewIdentityPolicy
1741    //
1742    if (mUserInfo.IdentityPolicy != NULL) {
1743      FreePool (mUserInfo.IdentityPolicy);
1744    }
1745    mUserInfo.IdentityPolicy    = mUserInfo.NewIdentityPolicy;
1746    mUserInfo.IdentityPolicyLen = mUserInfo.NewIdentityPolicyLen;
1747  }
1748
1749  mUserInfo.NewIdentityPolicy         = NULL;
1750  mUserInfo.NewIdentityPolicyLen      = 0;
1751  mUserInfo.NewIdentityPolicyModified = FALSE;
1752
1753  //
1754  // Update identity policy choice.
1755  //
1756  ResolveIdentityPolicy (
1757    mUserInfo.IdentityPolicy,
1758    mUserInfo.IdentityPolicyLen,
1759    STRING_TOKEN (STR_IDENTIFY_POLICY_VAL)
1760    );
1761}
1762
1763
1764/**
1765  Verify the new identity policy in the current implementation. The same credential
1766  provider can't appear twice in one identity policy.
1767
1768  @param[in] NewGuid       Points to the credential provider guid.
1769
1770  @retval TRUE     The NewGuid was found in the identity policy.
1771  @retval FALSE    The NewGuid was not found.
1772
1773**/
1774BOOLEAN
1775CheckIdentityPolicy (
1776  IN EFI_GUID                                      *NewGuid
1777  )
1778{
1779  UINTN                         Offset;
1780  EFI_USER_INFO_IDENTITY_POLICY *Identity;
1781  EFI_INPUT_KEY                 Key;
1782
1783  Offset = 0;
1784  while (Offset < mUserInfo.NewIdentityPolicyLen) {
1785    //
1786    // Check access policy according to type.
1787    //
1788    Identity = (EFI_USER_INFO_IDENTITY_POLICY *) (mUserInfo.NewIdentityPolicy + Offset);
1789    switch (Identity->Type) {
1790
1791    case EFI_USER_INFO_IDENTITY_TRUE:
1792    case EFI_USER_INFO_IDENTITY_OR:
1793    case EFI_USER_INFO_IDENTITY_AND:
1794      break;
1795
1796    case EFI_USER_INFO_IDENTITY_CREDENTIAL_PROVIDER:
1797      if (CompareGuid (NewGuid, (EFI_GUID *) (Identity + 1))) {
1798        CreatePopUp (
1799          EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
1800          &Key,
1801          L"This Credential Provider Are Already Used!",
1802          L"",
1803          L"Press Any Key to Continue ...",
1804          NULL
1805          );
1806        return FALSE;
1807      }
1808      break;
1809
1810    default:
1811      CreatePopUp (
1812        EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
1813        &Key,
1814        L"Unsupport parameter",
1815        L"",
1816        L"Press Any Key to Continue ...",
1817        NULL
1818        );
1819      return FALSE;
1820    }
1821
1822    Offset += Identity->Length;
1823  }
1824  return TRUE;
1825}
1826
1827
1828/**
1829  Update the mUserInfo.NewIdentityPolicy, and UI when 'add option' is pressed.
1830
1831**/
1832VOID
1833AddIdentityPolicyItem (
1834  VOID
1835  )
1836{
1837  UINT8                         *NewInfo;
1838  EFI_USER_INFO_IDENTITY_POLICY *Policy;
1839
1840  if (mProviderInfo->Count == 0) {
1841    return ;
1842  }
1843
1844  if (!mUserInfo.NewIdentityPolicyModified && (mUserInfo.NewIdentityPolicyLen > 0)) {
1845    FreePool (mUserInfo.NewIdentityPolicy);
1846    mUserInfo.NewIdentityPolicy     = NULL;
1847    mUserInfo.NewIdentityPolicyLen  = 0;
1848  }
1849  //
1850  // Expand the identity policy memory for the newly added policy info.
1851  //
1852  if (mUserInfo.NewIdentityPolicyLen > 0) {
1853    //
1854    // The new policy is not empty, expand space for connetor and provider.
1855    //
1856    if (!CheckIdentityPolicy (&mProviderInfo->Provider[mProviderChoice]->Identifier)) {
1857      return ;
1858    }
1859    NewInfo = AllocateZeroPool (
1860                mUserInfo.NewIdentityPolicyLen +
1861                sizeof (EFI_USER_INFO_IDENTITY_POLICY) * 2 +
1862                sizeof (EFI_GUID)
1863                );
1864  } else {
1865    //
1866    // The new policy is empty, only expand space for provider.
1867    //
1868    NewInfo = AllocateZeroPool (
1869                mUserInfo.NewIdentityPolicyLen +
1870                sizeof (EFI_USER_INFO_IDENTITY_POLICY) +
1871                sizeof (EFI_GUID)
1872                );
1873  }
1874
1875  if (NewInfo == NULL) {
1876    return ;
1877  }
1878
1879  if (mUserInfo.NewIdentityPolicyLen > 0) {
1880    CopyMem (NewInfo, mUserInfo.NewIdentityPolicy, mUserInfo.NewIdentityPolicyLen);
1881    FreePool (mUserInfo.NewIdentityPolicy);
1882  }
1883  mUserInfo.NewIdentityPolicy = NewInfo;
1884
1885  //
1886  // Save logical connector.
1887  //
1888  if (mUserInfo.NewIdentityPolicyLen > 0) {
1889    Policy = (EFI_USER_INFO_IDENTITY_POLICY *) (mUserInfo.NewIdentityPolicy +
1890                                                mUserInfo.NewIdentityPolicyLen);
1891    if (mConncetLogical == 0) {
1892      Policy->Type = EFI_USER_INFO_IDENTITY_AND;
1893    } else {
1894      Policy->Type = EFI_USER_INFO_IDENTITY_OR;
1895    }
1896
1897    Policy->Length = sizeof (EFI_USER_INFO_IDENTITY_POLICY);
1898    mUserInfo.NewIdentityPolicyLen += Policy->Length;
1899  }
1900
1901  //
1902  // Save credential provider.
1903  //
1904  Policy = (EFI_USER_INFO_IDENTITY_POLICY *) (mUserInfo.NewIdentityPolicy +
1905                                              mUserInfo.NewIdentityPolicyLen);
1906  Policy->Length = sizeof (EFI_USER_INFO_IDENTITY_POLICY) + sizeof (EFI_GUID);
1907  Policy->Type   = EFI_USER_INFO_IDENTITY_CREDENTIAL_PROVIDER;
1908  CopyGuid ((EFI_GUID *) (Policy + 1), &mProviderInfo->Provider[mProviderChoice]->Identifier);
1909  mUserInfo.NewIdentityPolicyLen += Policy->Length;
1910
1911  //
1912  // Update identity policy choice.
1913  //
1914  mUserInfo.NewIdentityPolicyModified = TRUE;
1915  ResolveIdentityPolicy (
1916    mUserInfo.NewIdentityPolicy,
1917    mUserInfo.NewIdentityPolicyLen,
1918    STRING_TOKEN (STR_IDENTIFY_POLICY_VALUE)
1919    );
1920}
1921
1922
1923/**
1924  Create an action OpCode with QuestionID and DevicePath on a given OpCodeHandle.
1925
1926  @param[in]  QuestionID            The question ID.
1927  @param[in]  DevicePath            Points to device path.
1928  @param[in]  OpCodeHandle          Points to container for dynamic created opcodes.
1929
1930**/
1931VOID
1932AddDevicePath (
1933  IN  UINTN                                     QuestionID,
1934  IN  EFI_DEVICE_PATH_PROTOCOL                  *DevicePath,
1935  IN     VOID                                   *OpCodeHandle
1936  )
1937{
1938  EFI_STATUS                        Status;
1939  EFI_DEVICE_PATH_PROTOCOL          *Next;
1940  EFI_STRING_ID                     NameID;
1941  EFI_STRING                        DriverName;
1942  EFI_DEVICE_PATH_TO_TEXT_PROTOCOL  *DevicePathText;
1943
1944  //
1945  // Locate device path to text protocol.
1946  //
1947  Status = gBS->LocateProtocol (
1948                  &gEfiDevicePathToTextProtocolGuid,
1949                  NULL,
1950                  (VOID **) &DevicePathText
1951                  );
1952  if (EFI_ERROR (Status)) {
1953    return ;
1954  }
1955
1956  //
1957  // Get driver file name node.
1958  //
1959  Next = DevicePath;
1960  while (!IsDevicePathEnd (Next)) {
1961    DevicePath  = Next;
1962    Next        = NextDevicePathNode (Next);
1963  }
1964
1965  //
1966  // Display the device path in form.
1967  //
1968  DriverName = DevicePathText->ConvertDevicePathToText (DevicePath, FALSE, FALSE);
1969  NameID = HiiSetString (mCallbackInfo->HiiHandle, 0, DriverName, NULL);
1970  FreePool (DriverName);
1971  if (NameID == 0) {
1972    return ;
1973  }
1974
1975  HiiCreateActionOpCode (
1976    OpCodeHandle,                   // Container for dynamic created opcodes
1977    (UINT16) QuestionID,            // Question ID
1978    NameID,                         // Prompt text
1979    STRING_TOKEN (STR_NULL_STRING), // Help text
1980    EFI_IFR_FLAG_CALLBACK,          // Question flag
1981    0                               // Action String ID
1982    );
1983}
1984
1985
1986/**
1987  Check whether the DevicePath is in the device path forbid list
1988  (mAccessInfo.LoadForbid).
1989
1990  @param[in]  DevicePath           Points to device path.
1991
1992  @retval TRUE     The DevicePath is in the device path forbid list.
1993  @retval FALSE    The DevicePath is not in the device path forbid list.
1994
1995**/
1996BOOLEAN
1997IsLoadForbidden (
1998  IN  EFI_DEVICE_PATH_PROTOCOL                  *DevicePath
1999  )
2000{
2001  UINTN                     OffSet;
2002  UINTN                     DPSize;
2003  UINTN                     Size;
2004  EFI_DEVICE_PATH_PROTOCOL  *Dp;
2005
2006  OffSet = 0;
2007  Size   = GetDevicePathSize (DevicePath);
2008  //
2009  // Check each device path.
2010  //
2011  while (OffSet < mAccessInfo.LoadForbidLen) {
2012    Dp      = (EFI_DEVICE_PATH_PROTOCOL *) (mAccessInfo.LoadForbid + OffSet);
2013    DPSize  = GetDevicePathSize (Dp);
2014    //
2015    // Compare device path.
2016    //
2017    if ((DPSize == Size) && (CompareMem (DevicePath, Dp, Size) == 0)) {
2018      return TRUE;
2019    }
2020    OffSet += DPSize;
2021  }
2022  return FALSE;
2023}
2024
2025
2026/**
2027  Display the permit load device path in the loadable device path list.
2028
2029**/
2030VOID
2031DisplayLoadPermit(
2032  VOID
2033  )
2034{
2035  EFI_STATUS          Status;
2036  CHAR16              *Order;
2037  UINTN               OrderSize;
2038  UINTN               ListCount;
2039  UINTN               Index;
2040  UINT8               *Var;
2041  UINT8               *VarPtr;
2042  CHAR16              VarName[12];
2043  VOID                *StartOpCodeHandle;
2044  VOID                *EndOpCodeHandle;
2045  EFI_IFR_GUID_LABEL  *StartLabel;
2046  EFI_IFR_GUID_LABEL  *EndLabel;
2047
2048  //
2049  // Get DriverOrder.
2050  //
2051  OrderSize = 0;
2052  Status    = gRT->GetVariable (
2053                     L"DriverOrder",
2054                     &gEfiGlobalVariableGuid,
2055                     NULL,
2056                     &OrderSize,
2057                     NULL
2058                     );
2059  if (Status != EFI_BUFFER_TOO_SMALL) {
2060    return ;
2061  }
2062
2063  Order = AllocateZeroPool (OrderSize);
2064  if (Order == NULL) {
2065    return ;
2066  }
2067
2068  Status = gRT->GetVariable (
2069                  L"DriverOrder",
2070                  &gEfiGlobalVariableGuid,
2071                  NULL,
2072                  &OrderSize,
2073                  Order
2074                  );
2075  if (EFI_ERROR (Status)) {
2076    return ;
2077  }
2078
2079  //
2080  // Initialize the container for dynamic opcodes.
2081  //
2082  StartOpCodeHandle = HiiAllocateOpCodeHandle ();
2083  ASSERT (StartOpCodeHandle != NULL);
2084
2085  EndOpCodeHandle = HiiAllocateOpCodeHandle ();
2086  ASSERT (EndOpCodeHandle != NULL);
2087
2088  //
2089  // Create Hii Extend Label OpCode.
2090  //
2091  StartLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (
2092                                        StartOpCodeHandle,
2093                                        &gEfiIfrTianoGuid,
2094                                        NULL,
2095                                        sizeof (EFI_IFR_GUID_LABEL)
2096                                        );
2097  StartLabel->ExtendOpCode  = EFI_IFR_EXTEND_OP_LABEL;
2098  StartLabel->Number        = LABEL_PERMIT_LOAD_FUNC;
2099
2100  EndLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (
2101                                      EndOpCodeHandle,
2102                                      &gEfiIfrTianoGuid,
2103                                      NULL,
2104                                      sizeof (EFI_IFR_GUID_LABEL)
2105                                      );
2106  EndLabel->ExtendOpCode  = EFI_IFR_EXTEND_OP_LABEL;
2107  EndLabel->Number        = LABEL_END;
2108
2109  //
2110  // Add each driver option.
2111  //
2112  Var       = NULL;
2113  ListCount = OrderSize / sizeof (UINT16);
2114  for (Index = 0; Index < ListCount; Index++) {
2115    //
2116    // Get driver device path.
2117    //
2118    UnicodeSPrint (VarName, sizeof (VarName), L"Driver%04x", Order[Index]);
2119    Var = GetEfiGlobalVariable (VarName);
2120    if (Var == NULL) {
2121      continue;
2122    }
2123
2124    //
2125    // Check whether the driver is already forbidden.
2126    //
2127
2128    VarPtr = Var;
2129    //
2130    // Skip attribute.
2131    //
2132    VarPtr += sizeof (UINT32);
2133
2134    //
2135    // Skip device path lenth.
2136    //
2137    VarPtr += sizeof (UINT16);
2138
2139    //
2140    // Skip descript string.
2141    //
2142    VarPtr += StrSize ((UINT16 *) VarPtr);
2143
2144    if (IsLoadForbidden ((EFI_DEVICE_PATH_PROTOCOL *) VarPtr)) {
2145      FreePool (Var);
2146      Var = NULL;
2147      continue;
2148    }
2149
2150    AddDevicePath (
2151      KEY_MODIFY_USER | KEY_MODIFY_AP_DP | KEY_LOAD_PERMIT_MODIFY | Order[Index],
2152      (EFI_DEVICE_PATH_PROTOCOL *) VarPtr,
2153      StartOpCodeHandle
2154      );
2155    FreePool (Var);
2156    Var = NULL;
2157  }
2158
2159  HiiUpdateForm (
2160    mCallbackInfo->HiiHandle, // HII handle
2161    &gUserProfileManagerGuid, // Formset GUID
2162    FORMID_PERMIT_LOAD_DP,    // Form ID
2163    StartOpCodeHandle,        // Label for where to insert opcodes
2164    EndOpCodeHandle           // Replace data
2165    );
2166
2167  HiiFreeOpCodeHandle (StartOpCodeHandle);
2168  HiiFreeOpCodeHandle (EndOpCodeHandle);
2169
2170  //
2171  // Clear Environment.
2172  //
2173  if (Var != NULL) {
2174    FreePool (Var);
2175  }
2176  FreePool (Order);
2177}
2178
2179
2180/**
2181  Display the forbid load device path list (mAccessInfo.LoadForbid).
2182
2183**/
2184VOID
2185DisplayLoadForbid (
2186  VOID
2187  )
2188{
2189  UINTN                     Offset;
2190  UINTN                     DPSize;
2191  UINTN                     Index;
2192  EFI_DEVICE_PATH_PROTOCOL  *Dp;
2193  VOID                      *StartOpCodeHandle;
2194  VOID                      *EndOpCodeHandle;
2195  EFI_IFR_GUID_LABEL        *StartLabel;
2196  EFI_IFR_GUID_LABEL        *EndLabel;
2197
2198  //
2199  // Initialize the container for dynamic opcodes.
2200  //
2201  StartOpCodeHandle = HiiAllocateOpCodeHandle ();
2202  ASSERT (StartOpCodeHandle != NULL);
2203
2204  EndOpCodeHandle = HiiAllocateOpCodeHandle ();
2205  ASSERT (EndOpCodeHandle != NULL);
2206
2207  //
2208  // Create Hii Extend Label OpCode.
2209  //
2210  StartLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (
2211                                        StartOpCodeHandle,
2212                                        &gEfiIfrTianoGuid,
2213                                        NULL,
2214                                        sizeof (EFI_IFR_GUID_LABEL)
2215                                        );
2216  StartLabel->ExtendOpCode  = EFI_IFR_EXTEND_OP_LABEL;
2217  StartLabel->Number        = LABLE_FORBID_LOAD_FUNC;
2218
2219  EndLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (
2220                                      EndOpCodeHandle,
2221                                      &gEfiIfrTianoGuid,
2222                                      NULL,
2223                                      sizeof (EFI_IFR_GUID_LABEL)
2224                                      );
2225  EndLabel->ExtendOpCode  = EFI_IFR_EXTEND_OP_LABEL;
2226  EndLabel->Number        = LABEL_END;
2227
2228  //
2229  // Add each forbid load drivers.
2230  //
2231  Offset  = 0;
2232  Index   = 0;
2233  while (Offset < mAccessInfo.LoadForbidLen) {
2234    Dp      = (EFI_DEVICE_PATH_PROTOCOL *) (mAccessInfo.LoadForbid + Offset);
2235    DPSize  = GetDevicePathSize (Dp);
2236    AddDevicePath (
2237      KEY_MODIFY_USER | KEY_MODIFY_AP_DP | KEY_LOAD_FORBID_MODIFY | Index,
2238      Dp,
2239      StartOpCodeHandle
2240      );
2241    Index++;
2242    Offset += DPSize;
2243  }
2244
2245  HiiUpdateForm (
2246    mCallbackInfo->HiiHandle, // HII handle
2247    &gUserProfileManagerGuid, // Formset GUID
2248    FORMID_FORBID_LOAD_DP,    // Form ID
2249    StartOpCodeHandle,        // Label for where to insert opcodes
2250    EndOpCodeHandle           // Replace data
2251    );
2252
2253  HiiFreeOpCodeHandle (StartOpCodeHandle);
2254  HiiFreeOpCodeHandle (EndOpCodeHandle);
2255}
2256
2257
2258/**
2259  Display the permit connect device path.
2260
2261**/
2262VOID
2263DisplayConnectPermit (
2264  VOID
2265  )
2266{
2267  //
2268  // Note:
2269  // As no architect protocol/interface to be called in ConnectController()
2270  // to verify the device path, just add a place holder for permitted connect
2271  // device path.
2272  //
2273}
2274
2275
2276/**
2277  Display the forbid connect device path list.
2278
2279**/
2280VOID
2281DisplayConnectForbid (
2282  VOID
2283  )
2284{
2285  //
2286  // Note:
2287  // As no architect protocol/interface to be called in ConnectController()
2288  // to verify the device path, just add a place holder for forbidden connect
2289  // device path.
2290  //
2291}
2292
2293
2294/**
2295  Delete the specified device path by DriverIndex from the forbid device path
2296  list (mAccessInfo.LoadForbid).
2297
2298  @param[in]  DriverIndex   The index of driver in forbidden device path list.
2299
2300**/
2301VOID
2302DeleteFromForbidLoad (
2303  IN  UINT16                                    DriverIndex
2304  )
2305{
2306  UINTN                     OffSet;
2307  UINTN                     DPSize;
2308  UINTN                     OffLen;
2309  EFI_DEVICE_PATH_PROTOCOL  *Dp;
2310
2311  OffSet = 0;
2312  //
2313  // Find the specified device path.
2314  //
2315  while ((OffSet < mAccessInfo.LoadForbidLen) && (DriverIndex > 0)) {
2316    Dp      = (EFI_DEVICE_PATH_PROTOCOL *) (mAccessInfo.LoadForbid + OffSet);
2317    DPSize  = GetDevicePathSize (Dp);
2318    OffSet += DPSize;
2319    DriverIndex--;
2320  }
2321
2322  //
2323  // Specified device path found.
2324  //
2325  if (DriverIndex == 0) {
2326    Dp      = (EFI_DEVICE_PATH_PROTOCOL *) (mAccessInfo.LoadForbid + OffSet);
2327    DPSize  = GetDevicePathSize (Dp);
2328    OffLen  = mAccessInfo.LoadForbidLen - OffSet - DPSize;
2329    if (OffLen > 0) {
2330      CopyMem (
2331        mAccessInfo.LoadForbid + OffSet,
2332        mAccessInfo.LoadForbid + OffSet + DPSize,
2333        OffLen
2334        );
2335    }
2336    mAccessInfo.LoadForbidLen -= DPSize;
2337  }
2338}
2339
2340
2341/**
2342  Add the specified device path by DriverIndex to the forbid device path
2343  list (mAccessInfo.LoadForbid).
2344
2345  @param[in]  DriverIndex   The index of driver saved in driver options.
2346
2347**/
2348VOID
2349AddToForbidLoad (
2350  IN  UINT16                                    DriverIndex
2351  )
2352{
2353  UINTN       DevicePathLen;
2354  UINT8       *Var;
2355  UINT8       *VarPtr;
2356  UINTN       NewLen;
2357  UINT8       *NewFL;
2358  CHAR16      VarName[13];
2359
2360  //
2361  // Get loadable driver device path.
2362  //
2363  UnicodeSPrint  (VarName, sizeof (VarName), L"Driver%04x", DriverIndex);
2364  Var = GetEfiGlobalVariable (VarName);
2365  if (Var == NULL) {
2366    return;
2367  }
2368
2369  //
2370  // Save forbid load driver.
2371  //
2372
2373  VarPtr = Var;
2374  //
2375  // Skip attribute.
2376  //
2377  VarPtr += sizeof (UINT32);
2378
2379  DevicePathLen = *(UINT16 *) VarPtr;
2380  //
2381  // Skip device path length.
2382  //
2383  VarPtr += sizeof (UINT16);
2384
2385  //
2386  // Skip description string.
2387  //
2388  VarPtr += StrSize ((UINT16 *) VarPtr);
2389
2390  NewLen  = mAccessInfo.LoadForbidLen + DevicePathLen;
2391  NewFL   = AllocateZeroPool (NewLen);
2392  if (NewFL == NULL) {
2393    FreePool (Var);
2394    return ;
2395  }
2396
2397  if (mAccessInfo.LoadForbidLen > 0) {
2398    CopyMem (NewFL, mAccessInfo.LoadForbid, mAccessInfo.LoadForbidLen);
2399    FreePool (mAccessInfo.LoadForbid);
2400  }
2401
2402  CopyMem (NewFL + mAccessInfo.LoadForbidLen, VarPtr, DevicePathLen);
2403  mAccessInfo.LoadForbidLen = NewLen;
2404  mAccessInfo.LoadForbid    = NewFL;
2405  FreePool (Var);
2406}
2407
2408
2409/**
2410  Get current user's access right.
2411
2412  @param[out]  AccessRight  Points to the buffer used for user's access right.
2413
2414  @retval EFI_SUCCESS       Get current user access right successfully.
2415  @retval others            Fail to get current user access right.
2416
2417**/
2418EFI_STATUS
2419GetAccessRight (
2420  OUT  UINT32                                    *AccessRight
2421  )
2422{
2423  EFI_STATUS                    Status;
2424  EFI_USER_INFO_HANDLE          UserInfo;
2425  EFI_USER_INFO                 *Info;
2426  UINTN                         InfoSize;
2427  UINTN                         MemSize;
2428  EFI_USER_INFO_ACCESS_CONTROL  Access;
2429  EFI_USER_PROFILE_HANDLE       CurrentUser;
2430  UINTN                         TotalLen;
2431  UINTN                         CheckLen;
2432
2433  //
2434  // Allocate user information memory.
2435  //
2436  MemSize = sizeof (EFI_USER_INFO) + 63;
2437  Info    = AllocateZeroPool (MemSize);
2438  if (Info == NULL) {
2439    return EFI_OUT_OF_RESOURCES;
2440  }
2441
2442  //
2443  // Get user access information.
2444  //
2445  UserInfo = NULL;
2446  mUserManager->Current (mUserManager, &CurrentUser);
2447  while (TRUE) {
2448    InfoSize = MemSize;
2449    //
2450    // Get next user information.
2451    //
2452    Status = mUserManager->GetNextInfo (mUserManager, CurrentUser, &UserInfo);
2453    if (EFI_ERROR (Status)) {
2454      break;
2455    }
2456
2457    Status = mUserManager->GetInfo (
2458                             mUserManager,
2459                             CurrentUser,
2460                             UserInfo,
2461                             Info,
2462                             &InfoSize
2463                             );
2464    if (Status == EFI_BUFFER_TOO_SMALL) {
2465      MemSize = InfoSize;
2466      FreePool (Info);
2467      Info = AllocateZeroPool (MemSize);
2468      if (Info == NULL) {
2469        return EFI_OUT_OF_RESOURCES;
2470      }
2471      Status = mUserManager->GetInfo (
2472                               mUserManager,
2473                               CurrentUser,
2474                               UserInfo,
2475                               Info,
2476                               &InfoSize
2477                               );
2478    }
2479    if (EFI_ERROR (Status)) {
2480      break;
2481    }
2482
2483    //
2484    // Check user information.
2485    //
2486    if (Info->InfoType == EFI_USER_INFO_ACCESS_POLICY_RECORD) {
2487      TotalLen  = Info->InfoSize - sizeof (EFI_USER_INFO);
2488      CheckLen  = 0;
2489      //
2490      // Get specified access information.
2491      //
2492      while (CheckLen < TotalLen) {
2493        CopyMem (&Access, (UINT8 *) (Info + 1) + CheckLen, sizeof (Access));
2494        if ((Access.Type == EFI_USER_INFO_ACCESS_ENROLL_SELF) ||
2495            (Access.Type == EFI_USER_INFO_ACCESS_ENROLL_OTHERS) ||
2496            (Access.Type == EFI_USER_INFO_ACCESS_MANAGE)
2497            ) {
2498          *AccessRight = Access.Type;
2499          FreePool (Info);
2500          return EFI_SUCCESS;
2501        }
2502        CheckLen += Access.Size;
2503      }
2504    }
2505  }
2506  FreePool (Info);
2507  return EFI_NOT_FOUND;
2508}
2509
2510
2511
2512