]> git.proxmox.com Git - mirror_edk2.git/blame_incremental - SecurityPkg/UserIdentification/UserIdentifyManagerDxe/UserIdentifyManager.c
Force UID modules build error to warn user that currently it is just a sample.
[mirror_edk2.git] / SecurityPkg / UserIdentification / UserIdentifyManagerDxe / UserIdentifyManager.c
... / ...
CommitLineData
1/** @file\r
2 This driver manages user information and produces user manager protocol.\r
3 \r
4Copyright (c) 2009 - 2014, Intel Corporation. All rights reserved.<BR>\r
5This program and the accompanying materials \r
6are licensed and made available under the terms and conditions of the BSD License \r
7which accompanies this distribution. The full text of the license may be found at \r
8http://opensource.org/licenses/bsd-license.php\r
9\r
10THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
11WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
12\r
13**/\r
14\r
15#include "UserIdentifyManager.h"\r
16\r
17//\r
18// Default user name.\r
19//\r
20CHAR16 mUserName[] = L"Administrator";\r
21\r
22//\r
23// Points to the user profile database.\r
24//\r
25USER_PROFILE_DB *mUserProfileDb = NULL;\r
26\r
27//\r
28// Points to the credential providers found in system.\r
29//\r
30CREDENTIAL_PROVIDER_INFO *mProviderDb = NULL;\r
31\r
32//\r
33// Current user shared in multi function.\r
34//\r
35EFI_USER_PROFILE_HANDLE mCurrentUser = NULL;\r
36\r
37//\r
38// Flag indicates a user is identified.\r
39//\r
40BOOLEAN mIdentified = FALSE;\r
41USER_MANAGER_CALLBACK_INFO *mCallbackInfo = NULL;\r
42HII_VENDOR_DEVICE_PATH mHiiVendorDevicePath = {\r
43 {\r
44 {\r
45 HARDWARE_DEVICE_PATH,\r
46 HW_VENDOR_DP,\r
47 {\r
48 (UINT8) (sizeof (VENDOR_DEVICE_PATH)),\r
49 (UINT8) ((sizeof (VENDOR_DEVICE_PATH)) >> 8)\r
50 }\r
51 },\r
52 USER_IDENTIFY_MANAGER_GUID\r
53 },\r
54 {\r
55 END_DEVICE_PATH_TYPE,\r
56 END_ENTIRE_DEVICE_PATH_SUBTYPE,\r
57 {\r
58 (UINT8) (END_DEVICE_PATH_LENGTH),\r
59 (UINT8) ((END_DEVICE_PATH_LENGTH) >> 8)\r
60 }\r
61 }\r
62};\r
63\r
64\r
65EFI_USER_MANAGER_PROTOCOL gUserIdentifyManager = {\r
66 UserProfileCreate,\r
67 UserProfileDelete,\r
68 UserProfileGetNext,\r
69 UserProfileCurrent,\r
70 UserProfileIdentify,\r
71 UserProfileFind,\r
72 UserProfileNotify,\r
73 UserProfileGetInfo,\r
74 UserProfileSetInfo,\r
75 UserProfileDeleteInfo,\r
76 UserProfileGetNextInfo,\r
77};\r
78\r
79\r
80/**\r
81 Find the specified user in the user database.\r
82\r
83 This function searches the specified user from the beginning of the user database. \r
84 And if NextUser is TRUE, return the next User in the user database. \r
85 \r
86 @param[in, out] User On entry, points to the user profile entry to search. \r
87 On return, points to the user profile entry or NULL if not found.\r
88 @param[in] NextUser If FALSE, find the user in user profile database specifyed by User\r
89 If TRUE, find the next user in user profile database specifyed \r
90 by User. \r
91 @param[out] ProfileIndex A pointer to the index of user profile database that matches the \r
92 user specifyed by User.\r
93\r
94 @retval EFI_NOT_FOUND User was NULL, or User was not found, or the next user was not found.\r
95 @retval EFI_SUCCESS User or the next user are found in user profile database\r
96 \r
97**/\r
98EFI_STATUS\r
99FindUserProfile (\r
100 IN OUT USER_PROFILE_ENTRY **User,\r
101 IN BOOLEAN NextUser,\r
102 OUT UINTN *ProfileIndex OPTIONAL\r
103 )\r
104{\r
105 UINTN Index;\r
106\r
107 //\r
108 // Check parameters\r
109 //\r
110 if ((mUserProfileDb == NULL) || (User == NULL)) {\r
111 return EFI_NOT_FOUND;\r
112 }\r
113 \r
114 //\r
115 // Check whether the user profile is in the user profile database.\r
116 //\r
117 for (Index = 0; Index < mUserProfileDb->UserProfileNum; Index++) {\r
118 if (mUserProfileDb->UserProfile[Index] == *User) {\r
119 if (ProfileIndex != NULL) {\r
120 *ProfileIndex = Index;\r
121 }\r
122 break;\r
123 }\r
124 }\r
125\r
126 if (NextUser) {\r
127 //\r
128 // Find the next user profile.\r
129 //\r
130 Index++;\r
131 if (Index < mUserProfileDb->UserProfileNum) {\r
132 *User = mUserProfileDb->UserProfile[Index];\r
133 } else if (Index == mUserProfileDb->UserProfileNum) {\r
134 *User = NULL;\r
135 return EFI_NOT_FOUND;\r
136 } else {\r
137 if ((mUserProfileDb->UserProfileNum > 0) && (*User == NULL)) {\r
138 *User = mUserProfileDb->UserProfile[0];\r
139 } else {\r
140 *User = NULL;\r
141 return EFI_NOT_FOUND;\r
142 }\r
143 }\r
144 } else if (Index == mUserProfileDb->UserProfileNum) {\r
145 return EFI_NOT_FOUND;\r
146 }\r
147\r
148 return EFI_SUCCESS;\r
149}\r
150\r
151/**\r
152 Find the specified user information record in the specified User profile.\r
153\r
154 This function searches the specified user information record from the beginning of the user \r
155 profile. And if NextInfo is TRUE, return the next info in the user profile. \r
156 \r
157 @param[in] User Points to the user profile entry. \r
158 @param[in, out] Info On entry, points to the user information record or NULL to start\r
159 searching with the first user information record.\r
160 On return, points to the user information record or NULL if not found. \r
161 @param[in] NextInfo If FALSE, find the user information record in profile specifyed by User.\r
162 If TRUE, find the next user information record in profile specifyed \r
163 by User. \r
164 @param[out] Offset A pointer to the offset of the information record in the user profile.\r
165\r
166 @retval EFI_INVALID_PARAMETER Info is NULL\r
167 @retval EFI_NOT_FOUND Info was not found, or the next Info was not found.\r
168 @retval EFI_SUCCESS Info or the next info are found in user profile.\r
169 \r
170**/\r
171EFI_STATUS\r
172FindUserInfo (\r
173 IN USER_PROFILE_ENTRY * User,\r
174 IN OUT EFI_USER_INFO **Info,\r
175 IN BOOLEAN NextInfo,\r
176 OUT UINTN *Offset OPTIONAL\r
177 )\r
178{\r
179 EFI_STATUS Status;\r
180 EFI_USER_INFO *UserInfo;\r
181 UINTN InfoLen;\r
182\r
183 if (Info == NULL) {\r
184 return EFI_INVALID_PARAMETER;\r
185 }\r
186 \r
187 //\r
188 // Check user profile entry\r
189 //\r
190 Status = FindUserProfile (&User, FALSE, NULL);\r
191 if (EFI_ERROR (Status)) {\r
192 return Status;\r
193 }\r
194\r
195 //\r
196 // Find user information in the specified user record.\r
197 //\r
198 InfoLen = 0;\r
199 while (InfoLen < User->UserProfileSize) {\r
200 UserInfo = (EFI_USER_INFO *) (User->ProfileInfo + InfoLen);\r
201 if (UserInfo == *Info) {\r
202 if (Offset != NULL) {\r
203 *Offset = InfoLen;\r
204 }\r
205 break;\r
206 }\r
207 InfoLen += ALIGN_VARIABLE (UserInfo->InfoSize);\r
208 }\r
209 \r
210 //\r
211 // Check whether to find the next user information.\r
212 //\r
213 if (NextInfo) {\r
214 if (InfoLen < User->UserProfileSize) {\r
215 UserInfo = (EFI_USER_INFO *) (User->ProfileInfo + InfoLen);\r
216 InfoLen += ALIGN_VARIABLE (UserInfo->InfoSize);\r
217 if (InfoLen < User->UserProfileSize) {\r
218 *Info = (EFI_USER_INFO *) (User->ProfileInfo + InfoLen);\r
219 if (Offset != NULL) {\r
220 *Offset = InfoLen;\r
221 }\r
222 } else if (InfoLen == User->UserProfileSize) {\r
223 *Info = NULL;\r
224 return EFI_NOT_FOUND;\r
225 }\r
226 } else {\r
227 if (*Info == NULL) {\r
228 *Info = (EFI_USER_INFO *) User->ProfileInfo;\r
229 if (Offset != NULL) {\r
230 *Offset = 0;\r
231 }\r
232 } else {\r
233 *Info = NULL;\r
234 return EFI_NOT_FOUND;\r
235 }\r
236 }\r
237 } else if (InfoLen == User->UserProfileSize) {\r
238 return EFI_NOT_FOUND;\r
239 }\r
240\r
241 return EFI_SUCCESS;\r
242}\r
243\r
244/**\r
245 Find a user infomation record by the information record type.\r
246\r
247 This function searches all user information records of User. The search starts with the \r
248 user information record following Info and continues until either the information is found \r
249 or there are no more user infomation record.\r
250 A match occurs when a Info.InfoType field matches the user information record type.\r
251\r
252 @param[in] User Points to the user profile record to search. \r
253 @param[in, out] Info On entry, points to the user information record or NULL to start\r
254 searching with the first user information record.\r
255 On return, points to the user information record or NULL if not found.\r
256 @param[in] InfoType The infomation type to be searched.\r
257\r
258 @retval EFI_SUCCESS User information was found. Info points to the user information record.\r
259 @retval EFI_NOT_FOUND User information was not found. \r
260 @retval EFI_INVALID_PARAMETER User is NULL or Info is NULL.\r
261 \r
262**/\r
263EFI_STATUS\r
264FindUserInfoByType (\r
265 IN USER_PROFILE_ENTRY *User,\r
266 IN OUT EFI_USER_INFO **Info,\r
267 IN UINT8 InfoType\r
268 )\r
269{\r
270 EFI_STATUS Status;\r
271 EFI_USER_INFO *UserInfo;\r
272 UINTN InfoLen;\r
273\r
274 if (Info == NULL) {\r
275 return EFI_INVALID_PARAMETER;\r
276 }\r
277 \r
278 //\r
279 // Check whether the user has the specified user information.\r
280 //\r
281 InfoLen = 0;\r
282 if (*Info == NULL) {\r
283 Status = FindUserProfile (&User, FALSE, NULL);\r
284 } else {\r
285 Status = FindUserInfo (User, Info, TRUE, &InfoLen);\r
286 }\r
287\r
288 if (EFI_ERROR (Status)) {\r
289 return EFI_NOT_FOUND;\r
290 }\r
291 \r
292 while (InfoLen < User->UserProfileSize) {\r
293 UserInfo = (EFI_USER_INFO *) (User->ProfileInfo + InfoLen);\r
294 if (UserInfo->InfoType == InfoType) {\r
295 if (UserInfo != *Info) {\r
296 *Info = UserInfo;\r
297 return EFI_SUCCESS;\r
298 }\r
299 }\r
300\r
301 InfoLen += ALIGN_VARIABLE (UserInfo->InfoSize);\r
302 }\r
303\r
304 *Info = NULL;\r
305 return EFI_NOT_FOUND;\r
306}\r
307\r
308/**\r
309 Find a user using a user information record.\r
310\r
311 This function searches all user profiles for the specified user information record. The \r
312 search starts with the user information record handle following UserInfo and continues \r
313 until either the information is found or there are no more user profiles.\r
314 A match occurs when the Info.InfoType field matches the user information record type and the \r
315 user information record data matches the portion of Info passed the EFI_USER_INFO header.\r
316\r
317 @param[in, out] User On entry, points to the previously returned user profile record, \r
318 or NULL to start searching with the first user profile. \r
319 On return, points to the user profile entry, or NULL if not found.\r
320 @param[in, out] UserInfo On entry, points to the previously returned user information record, \r
321 or NULL to start searching with the first. \r
322 On return, points to the user information record, or NULL if not found.\r
323 @param[in] Info Points to the buffer containing the user information to be compared \r
324 to the user information record.\r
325 @param[in] InfoSize The size of Info, in bytes. Same as Info->InfoSize.\r
326\r
327 @retval EFI_SUCCESS User information was found. User points to the user profile record, \r
328 and UserInfo points to the user information record.\r
329 @retval EFI_NOT_FOUND User information was not found. \r
330 @retval EFI_INVALID_PARAMETER User is NULL; Info is NULL; or, InfoSize is too small.\r
331 \r
332**/\r
333EFI_STATUS\r
334FindUserProfileByInfo (\r
335 IN OUT USER_PROFILE_ENTRY **User,\r
336 IN OUT EFI_USER_INFO **UserInfo, OPTIONAL\r
337 IN EFI_USER_INFO *Info,\r
338 IN UINTN InfoSize\r
339 )\r
340{\r
341 EFI_STATUS Status;\r
342 EFI_USER_INFO *InfoEntry;\r
343\r
344\r
345 if ((User == NULL) || (Info == NULL)) {\r
346 return EFI_INVALID_PARAMETER;\r
347 }\r
348\r
349 if (InfoSize < sizeof (EFI_USER_INFO)) {\r
350 return EFI_INVALID_PARAMETER;\r
351 }\r
352\r
353 if (UserInfo != NULL) {\r
354 InfoEntry = *UserInfo;\r
355 } else {\r
356 InfoEntry = NULL;\r
357 }\r
358 //\r
359 // Find user profile according to information.\r
360 //\r
361 if (*User == NULL) {\r
362 *User = mUserProfileDb->UserProfile[0];\r
363 }\r
364 \r
365 //\r
366 // Check user profile handle.\r
367 //\r
368 Status = FindUserProfile (User, FALSE, NULL);\r
369\r
370 while (!EFI_ERROR (Status)) {\r
371 //\r
372 // Find the user information in a user profile.\r
373 //\r
374 while (TRUE) {\r
375 Status = FindUserInfoByType (*User, &InfoEntry, Info->InfoType);\r
376 if (EFI_ERROR (Status)) {\r
377 break;\r
378 }\r
379 \r
380 if (InfoSize == Info->InfoSize) {\r
381 if (CompareMem ((UINT8 *) (InfoEntry + 1), (UINT8 *) (Info + 1), InfoSize - sizeof (EFI_USER_INFO)) == 0) {\r
382 //\r
383 // Found the infomation record.\r
384 //\r
385 if (UserInfo != NULL) {\r
386 *UserInfo = InfoEntry;\r
387 }\r
388 return EFI_SUCCESS;\r
389 }\r
390 } \r
391 }\r
392 \r
393 //\r
394 // Get next user profile.\r
395 //\r
396 InfoEntry = NULL;\r
397 Status = FindUserProfile (User, TRUE, NULL);\r
398 }\r
399\r
400 return EFI_NOT_FOUND;\r
401}\r
402\r
403\r
404/**\r
405 Check whether the access policy is valid.\r
406\r
407 @param[in] PolicyInfo Point to the access policy.\r
408 @param[in] InfoLen The policy length.\r
409\r
410 @retval TRUE The policy is a valid access policy.\r
411 @retval FALSE The access policy is not a valid access policy.\r
412 \r
413**/\r
414BOOLEAN\r
415CheckAccessPolicy (\r
416 IN UINT8 *PolicyInfo,\r
417 IN UINTN InfoLen\r
418 )\r
419{\r
420 UINTN TotalLen;\r
421 UINTN ValueLen;\r
422 UINTN OffSet;\r
423 EFI_USER_INFO_ACCESS_CONTROL Access;\r
424 EFI_DEVICE_PATH_PROTOCOL *Path;\r
425 UINTN PathSize;\r
426\r
427 TotalLen = 0;\r
428 while (TotalLen < InfoLen) {\r
429 //\r
430 // Check access policy according to type.\r
431 //\r
432 CopyMem (&Access, PolicyInfo + TotalLen, sizeof (Access)); \r
433 ValueLen = Access.Size - sizeof (EFI_USER_INFO_ACCESS_CONTROL);\r
434 switch (Access.Type) {\r
435 case EFI_USER_INFO_ACCESS_FORBID_LOAD:\r
436 case EFI_USER_INFO_ACCESS_PERMIT_LOAD:\r
437 case EFI_USER_INFO_ACCESS_FORBID_CONNECT:\r
438 case EFI_USER_INFO_ACCESS_PERMIT_CONNECT:\r
439 OffSet = 0;\r
440 while (OffSet < ValueLen) {\r
441 Path = (EFI_DEVICE_PATH_PROTOCOL *) (PolicyInfo + TotalLen + sizeof (Access) + OffSet);\r
442 PathSize = GetDevicePathSize (Path);\r
443 OffSet += PathSize;\r
444 }\r
445 if (OffSet != ValueLen) {\r
446 return FALSE;\r
447 }\r
448 break;\r
449\r
450 case EFI_USER_INFO_ACCESS_SETUP:\r
451 if (ValueLen % sizeof (EFI_GUID) != 0) {\r
452 return FALSE;\r
453 }\r
454 break;\r
455\r
456 case EFI_USER_INFO_ACCESS_BOOT_ORDER:\r
457 if (ValueLen % sizeof (EFI_USER_INFO_ACCESS_BOOT_ORDER_HDR) != 0) {\r
458 return FALSE;\r
459 }\r
460 break;\r
461\r
462 case EFI_USER_INFO_ACCESS_ENROLL_SELF:\r
463 case EFI_USER_INFO_ACCESS_ENROLL_OTHERS:\r
464 case EFI_USER_INFO_ACCESS_MANAGE:\r
465 if (ValueLen != 0) {\r
466 return FALSE;\r
467 }\r
468 break;\r
469\r
470 default:\r
471 return FALSE;\r
472 break;\r
473 }\r
474\r
475 TotalLen += Access.Size;\r
476 }\r
477\r
478 if (TotalLen != InfoLen) {\r
479 return FALSE;\r
480 }\r
481\r
482 return TRUE;\r
483}\r
484\r
485\r
486/**\r
487 Check whether the identity policy is valid.\r
488\r
489 @param[in] PolicyInfo Point to the identity policy.\r
490 @param[in] InfoLen The policy length.\r
491\r
492 @retval TRUE The policy is a valid identity policy.\r
493 @retval FALSE The access policy is not a valid identity policy.\r
494 \r
495**/\r
496BOOLEAN\r
497CheckIdentityPolicy (\r
498 IN UINT8 *PolicyInfo,\r
499 IN UINTN InfoLen\r
500 )\r
501{\r
502 UINTN TotalLen;\r
503 UINTN ValueLen;\r
504 EFI_USER_INFO_IDENTITY_POLICY *Identity;\r
505\r
506 TotalLen = 0;\r
507\r
508 //\r
509 // Check each part of policy expression.\r
510 //\r
511 while (TotalLen < InfoLen) {\r
512 //\r
513 // Check access polisy according to type.\r
514 //\r
515 Identity = (EFI_USER_INFO_IDENTITY_POLICY *) (PolicyInfo + TotalLen);\r
516 ValueLen = Identity->Length - sizeof (EFI_USER_INFO_IDENTITY_POLICY);\r
517 switch (Identity->Type) {\r
518 //\r
519 // Check False option.\r
520 //\r
521 case EFI_USER_INFO_IDENTITY_FALSE:\r
522 if (ValueLen != 0) {\r
523 return FALSE;\r
524 }\r
525 break;\r
526\r
527 //\r
528 // Check True option.\r
529 //\r
530 case EFI_USER_INFO_IDENTITY_TRUE:\r
531 if (ValueLen != 0) {\r
532 return FALSE;\r
533 }\r
534 break;\r
535\r
536 //\r
537 // Check negative operation.\r
538 //\r
539 case EFI_USER_INFO_IDENTITY_NOT:\r
540 if (ValueLen != 0) {\r
541 return FALSE;\r
542 }\r
543 break;\r
544\r
545 //\r
546 // Check and operation.\r
547 //\r
548 case EFI_USER_INFO_IDENTITY_AND:\r
549 if (ValueLen != 0) {\r
550 return FALSE;\r
551 }\r
552 break;\r
553\r
554 //\r
555 // Check or operation.\r
556 //\r
557 case EFI_USER_INFO_IDENTITY_OR:\r
558 if (ValueLen != 0) {\r
559 return FALSE;\r
560 }\r
561 break;\r
562\r
563 //\r
564 // Check credential provider by type.\r
565 //\r
566 case EFI_USER_INFO_IDENTITY_CREDENTIAL_TYPE:\r
567 if (ValueLen != sizeof (EFI_GUID)) {\r
568 return FALSE;\r
569 }\r
570 break;\r
571\r
572 //\r
573 // Check credential provider by ID.\r
574 //\r
575 case EFI_USER_INFO_IDENTITY_CREDENTIAL_PROVIDER:\r
576 if (ValueLen != sizeof (EFI_GUID)) {\r
577 return FALSE;\r
578 }\r
579 break;\r
580\r
581 default:\r
582 return FALSE;\r
583 break;\r
584 }\r
585\r
586 TotalLen += Identity->Length;\r
587 }\r
588\r
589 if (TotalLen != InfoLen) {\r
590 return FALSE;\r
591 }\r
592\r
593 return TRUE;\r
594}\r
595\r
596\r
597/**\r
598 Check whether the user information is a valid user information record.\r
599\r
600 @param[in] Info points to the user information.\r
601\r
602 @retval TRUE The info is a valid user information record.\r
603 @retval FALSE The info is not a valid user information record.\r
604 \r
605**/\r
606BOOLEAN\r
607CheckUserInfo (\r
608 IN CONST EFI_USER_INFO *Info\r
609 )\r
610{\r
611 UINTN InfoLen;\r
612\r
613 if (Info == NULL) {\r
614 return FALSE;\r
615 }\r
616 //\r
617 // Check user information according to information type.\r
618 //\r
619 InfoLen = Info->InfoSize - sizeof (EFI_USER_INFO);\r
620 switch (Info->InfoType) {\r
621 case EFI_USER_INFO_EMPTY_RECORD:\r
622 if (InfoLen != 0) {\r
623 return FALSE;\r
624 }\r
625 break;\r
626\r
627 case EFI_USER_INFO_NAME_RECORD:\r
628 case EFI_USER_INFO_CREDENTIAL_TYPE_NAME_RECORD:\r
629 case EFI_USER_INFO_CREDENTIAL_PROVIDER_NAME_RECORD:\r
630 break;\r
631\r
632 case EFI_USER_INFO_CREATE_DATE_RECORD:\r
633 case EFI_USER_INFO_USAGE_DATE_RECORD:\r
634 if (InfoLen != sizeof (EFI_TIME)) {\r
635 return FALSE;\r
636 }\r
637 break;\r
638\r
639 case EFI_USER_INFO_USAGE_COUNT_RECORD:\r
640 if (InfoLen != sizeof (UINT64)) {\r
641 return FALSE;\r
642 }\r
643 break;\r
644\r
645 case EFI_USER_INFO_IDENTIFIER_RECORD:\r
646 if (InfoLen != 16) {\r
647 return FALSE;\r
648 }\r
649 break;\r
650\r
651 case EFI_USER_INFO_CREDENTIAL_TYPE_RECORD:\r
652 case EFI_USER_INFO_CREDENTIAL_PROVIDER_RECORD:\r
653 case EFI_USER_INFO_GUID_RECORD:\r
654 if (InfoLen != sizeof (EFI_GUID)) {\r
655 return FALSE;\r
656 }\r
657 break;\r
658\r
659 case EFI_USER_INFO_PKCS11_RECORD:\r
660 case EFI_USER_INFO_CBEFF_RECORD:\r
661 break;\r
662\r
663 case EFI_USER_INFO_FAR_RECORD:\r
664 case EFI_USER_INFO_RETRY_RECORD:\r
665 if (InfoLen != 1) {\r
666 return FALSE;\r
667 }\r
668 break;\r
669\r
670 case EFI_USER_INFO_ACCESS_POLICY_RECORD:\r
671 if(!CheckAccessPolicy ((UINT8 *) (Info + 1), InfoLen)) {\r
672 return FALSE;\r
673 }\r
674 break;\r
675\r
676 case EFI_USER_INFO_IDENTITY_POLICY_RECORD:\r
677 if (!CheckIdentityPolicy ((UINT8 *) (Info + 1), InfoLen)) {\r
678 return FALSE;\r
679 }\r
680 break;\r
681\r
682 default:\r
683 return FALSE;\r
684 break;\r
685 }\r
686\r
687 return TRUE;\r
688}\r
689\r
690\r
691/**\r
692 Check the user profile data format to be added.\r
693\r
694 @param[in] UserProfileInfo Points to the user profile data.\r
695 @param[in] UserProfileSize The length of user profile data.\r
696\r
697 @retval TRUE It is a valid user profile.\r
698 @retval FALSE It is not a valid user profile.\r
699 \r
700**/\r
701BOOLEAN\r
702CheckProfileInfo (\r
703 IN UINT8 *UserProfileInfo,\r
704 IN UINTN UserProfileSize\r
705 )\r
706{\r
707 UINTN ChkLen;\r
708 EFI_USER_INFO *Info;\r
709\r
710 if (UserProfileInfo == NULL) {\r
711 return FALSE;\r
712 }\r
713 \r
714 //\r
715 // Check user profile information length.\r
716 //\r
717 ChkLen = 0;\r
718 while (ChkLen < UserProfileSize) {\r
719 Info = (EFI_USER_INFO *) (UserProfileInfo + ChkLen);\r
720 //\r
721 // Check user information format.\r
722 //\r
723 if (!CheckUserInfo (Info)) {\r
724 return FALSE;\r
725 }\r
726\r
727 ChkLen += ALIGN_VARIABLE (Info->InfoSize);\r
728 }\r
729\r
730 if (ChkLen != UserProfileSize) {\r
731 return FALSE;\r
732 }\r
733\r
734 return TRUE;\r
735}\r
736\r
737\r
738/**\r
739 Find the specified RightType in current user profile.\r
740\r
741 @param[in] RightType Could be EFI_USER_INFO_ACCESS_MANAGE,\r
742 EFI_USER_INFO_ACCESS_ENROLL_OTHERS or\r
743 EFI_USER_INFO_ACCESS_ENROLL_SELF.\r
744 \r
745 @retval TRUE Find the specified RightType in current user profile.\r
746 @retval FALSE Can't find the right in the profile.\r
747 \r
748**/\r
749BOOLEAN\r
750CheckCurrentUserAccessRight (\r
751 IN UINT32 RightType\r
752 )\r
753{\r
754 EFI_STATUS Status;\r
755 EFI_USER_INFO *Info;\r
756 UINTN TotalLen;\r
757 UINTN CheckLen;\r
758 EFI_USER_INFO_ACCESS_CONTROL Access;\r
759\r
760 //\r
761 // Get user access right information.\r
762 //\r
763 Info = NULL;\r
764 Status = FindUserInfoByType (\r
765 (USER_PROFILE_ENTRY *) mCurrentUser,\r
766 &Info,\r
767 EFI_USER_INFO_ACCESS_POLICY_RECORD\r
768 );\r
769 if (EFI_ERROR (Status)) {\r
770 return FALSE;\r
771 }\r
772\r
773 ASSERT (Info != NULL);\r
774 TotalLen = Info->InfoSize - sizeof (EFI_USER_INFO);\r
775 CheckLen = 0;\r
776 while (CheckLen < TotalLen) {\r
777 //\r
778 // Check right according to access type.\r
779 //\r
780 CopyMem (&Access, (UINT8 *) (Info + 1) + CheckLen, sizeof (Access));\r
781 if (Access.Type == RightType) {\r
782 return TRUE;;\r
783 }\r
784\r
785 CheckLen += Access.Size;\r
786 }\r
787\r
788 return FALSE;\r
789}\r
790\r
791\r
792/**\r
793 Create a unique user identifier.\r
794\r
795 @param[out] Identifier This points to the identifier.\r
796\r
797**/\r
798VOID\r
799GenerateIdentifier (\r
800 OUT UINT8 *Identifier\r
801 )\r
802{\r
803 EFI_TIME Time;\r
804 UINT64 MonotonicCount;\r
805 UINT32 *MonotonicPointer;\r
806 UINTN Index;\r
807\r
808 //\r
809 // Create a unique user identifier.\r
810 //\r
811 gRT->GetTime (&Time, NULL);\r
812 CopyMem (Identifier, &Time, sizeof (EFI_TIME));\r
813 //\r
814 // Remove zeros.\r
815 //\r
816 for (Index = 0; Index < sizeof (EFI_TIME); Index++) {\r
817 if (Identifier[Index] == 0) {\r
818 Identifier[Index] = 0x5a;\r
819 }\r
820 }\r
821\r
822 MonotonicPointer = (UINT32 *) Identifier;\r
823 gBS->GetNextMonotonicCount (&MonotonicCount);\r
824 MonotonicPointer[0] += (UINT32) MonotonicCount;\r
825 MonotonicPointer[1] += (UINT32) MonotonicCount;\r
826 MonotonicPointer[2] += (UINT32) MonotonicCount;\r
827 MonotonicPointer[3] += (UINT32) MonotonicCount;\r
828}\r
829\r
830\r
831/**\r
832 Generate unique user ID.\r
833\r
834 @param[out] UserId Points to the user identifer.\r
835\r
836**/\r
837VOID\r
838GenerateUserId (\r
839 OUT UINT8 *UserId\r
840 )\r
841{\r
842 EFI_STATUS Status;\r
843 USER_PROFILE_ENTRY *UserProfile;\r
844 EFI_USER_INFO *UserInfo;\r
845 UINTN Index;\r
846\r
847 //\r
848 // Generate unique user ID\r
849 //\r
850 while (TRUE) {\r
851 GenerateIdentifier (UserId);\r
852 //\r
853 // Check whether it's unique in user profile database.\r
854 //\r
855 if (mUserProfileDb == NULL) {\r
856 return ;\r
857 }\r
858\r
859 for (Index = 0; Index < mUserProfileDb->UserProfileNum; Index++) {\r
860 UserProfile = (USER_PROFILE_ENTRY *) (mUserProfileDb->UserProfile[Index]);\r
861 UserInfo = NULL;\r
862 Status = FindUserInfoByType (UserProfile, &UserInfo, EFI_USER_INFO_IDENTIFIER_RECORD);\r
863 if (EFI_ERROR (Status)) {\r
864 continue;\r
865 }\r
866\r
867 if (CompareMem ((UINT8 *) (UserInfo + 1), UserId, sizeof (EFI_USER_INFO_IDENTIFIER)) == 0) {\r
868 break;\r
869 }\r
870 }\r
871\r
872 if (Index == mUserProfileDb->UserProfileNum) {\r
873 return ;\r
874 }\r
875 }\r
876}\r
877\r
878\r
879/**\r
880 Expand user profile database.\r
881\r
882 @retval TRUE Success to expand user profile database.\r
883 @retval FALSE Fail to expand user profile database.\r
884 \r
885**/\r
886BOOLEAN\r
887ExpandUsermUserProfileDb (\r
888 VOID\r
889 )\r
890{\r
891 UINTN MaxNum;\r
892 USER_PROFILE_DB *NewDataBase;\r
893\r
894 //\r
895 // Create new user profile database.\r
896 //\r
897 if (mUserProfileDb == NULL) {\r
898 MaxNum = USER_NUMBER_INC;\r
899 } else {\r
900 MaxNum = mUserProfileDb->MaxProfileNum + USER_NUMBER_INC;\r
901 }\r
902\r
903 NewDataBase = AllocateZeroPool (\r
904 sizeof (USER_PROFILE_DB) - sizeof (EFI_USER_PROFILE_HANDLE) +\r
905 MaxNum * sizeof (EFI_USER_PROFILE_HANDLE)\r
906 );\r
907 if (NewDataBase == NULL) {\r
908 return FALSE;\r
909 }\r
910\r
911 NewDataBase->MaxProfileNum = MaxNum;\r
912\r
913 //\r
914 // Copy old user profile database value\r
915 //\r
916 if (mUserProfileDb == NULL) {\r
917 NewDataBase->UserProfileNum = 0;\r
918 } else {\r
919 NewDataBase->UserProfileNum = mUserProfileDb->UserProfileNum;\r
920 CopyMem (\r
921 NewDataBase->UserProfile,\r
922 mUserProfileDb->UserProfile,\r
923 NewDataBase->UserProfileNum * sizeof (EFI_USER_PROFILE_HANDLE)\r
924 );\r
925 FreePool (mUserProfileDb);\r
926 }\r
927\r
928 mUserProfileDb = NewDataBase;\r
929 return TRUE;\r
930}\r
931\r
932\r
933/**\r
934 Expand user profile\r
935\r
936 @param[in] User Points to user profile.\r
937 @param[in] ExpandSize The size of user profile. \r
938\r
939 @retval TRUE Success to expand user profile size.\r
940 @retval FALSE Fail to expand user profile size.\r
941 \r
942**/\r
943BOOLEAN\r
944ExpandUserProfile (\r
945 IN USER_PROFILE_ENTRY *User,\r
946 IN UINTN ExpandSize\r
947 )\r
948{\r
949 UINT8 *Info;\r
950 UINTN InfoSizeInc;\r
951\r
952 //\r
953 // Allocate new memory.\r
954 //\r
955 InfoSizeInc = 128;\r
956 User->MaxProfileSize += ((ExpandSize + InfoSizeInc - 1) / InfoSizeInc) * InfoSizeInc;\r
957 Info = AllocateZeroPool (User->MaxProfileSize);\r
958 if (Info == NULL) {\r
959 return FALSE;\r
960 }\r
961 \r
962 //\r
963 // Copy exist information.\r
964 //\r
965 if (User->UserProfileSize > 0) {\r
966 CopyMem (Info, User->ProfileInfo, User->UserProfileSize);\r
967 FreePool (User->ProfileInfo);\r
968 }\r
969\r
970 User->ProfileInfo = Info;\r
971 return TRUE;\r
972}\r
973\r
974\r
975/**\r
976 Save the user profile to non-volatile memory, or delete it from non-volatile memory.\r
977\r
978 @param[in] User Point to the user profile\r
979 @param[in] Delete If TRUE, delete the found user profile.\r
980 If FALSE, save the user profile.\r
981 @retval EFI_SUCCESS Save or delete user profile successfully.\r
982 @retval Others Fail to change the profile.\r
983 \r
984**/\r
985EFI_STATUS\r
986SaveNvUserProfile (\r
987 IN USER_PROFILE_ENTRY *User,\r
988 IN BOOLEAN Delete\r
989 )\r
990{\r
991 EFI_STATUS Status;\r
992\r
993 //\r
994 // Check user profile entry.\r
995 //\r
996 Status = FindUserProfile (&User, FALSE, NULL);\r
997 if (EFI_ERROR (Status)) {\r
998 return Status;\r
999 }\r
1000 \r
1001 //\r
1002 // Save the user profile to non-volatile memory.\r
1003 //\r
1004 Status = gRT->SetVariable (\r
1005 User->UserVarName,\r
1006 &gUserIdentifyManagerGuid,\r
1007 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,\r
1008 Delete ? 0 : User->UserProfileSize,\r
1009 User->ProfileInfo\r
1010 );\r
1011 return Status;\r
1012}\r
1013\r
1014/**\r
1015 Add one new user info into the user's profile.\r
1016\r
1017 @param[in] User point to the user profile\r
1018 @param[in] Info Points to the user information payload.\r
1019 @param[in] InfoSize The size of the user information payload, in bytes.\r
1020 @param[out] UserInfo Point to the new info in user profile\r
1021 @param[in] Save If TRUE, save the profile to NV flash.\r
1022 If FALSE, don't need to save the profile to NV flash.\r
1023\r
1024 @retval EFI_SUCCESS Add user info to user profile successfully.\r
1025 @retval Others Fail to add user info to user profile.\r
1026\r
1027**/\r
1028EFI_STATUS\r
1029AddUserInfo (\r
1030 IN USER_PROFILE_ENTRY *User,\r
1031 IN UINT8 *Info,\r
1032 IN UINTN InfoSize,\r
1033 OUT EFI_USER_INFO **UserInfo, OPTIONAL\r
1034 IN BOOLEAN Save\r
1035 )\r
1036{\r
1037 EFI_STATUS Status;\r
1038\r
1039 if ((Info == NULL) || (User == NULL)) {\r
1040 return EFI_INVALID_PARAMETER;\r
1041 }\r
1042 \r
1043 //\r
1044 // Check user profile handle.\r
1045 //\r
1046 Status = FindUserProfile (&User, FALSE, NULL);\r
1047 if (EFI_ERROR (Status)) {\r
1048 return Status;\r
1049 }\r
1050 \r
1051 //\r
1052 // Check user information memory size.\r
1053 //\r
1054 if (User->MaxProfileSize - User->UserProfileSize < ALIGN_VARIABLE (InfoSize)) {\r
1055 if (!ExpandUserProfile (User, ALIGN_VARIABLE (InfoSize))) {\r
1056 return EFI_OUT_OF_RESOURCES;\r
1057 }\r
1058 }\r
1059 \r
1060 //\r
1061 // Add new user information.\r
1062 //\r
1063 CopyMem (User->ProfileInfo + User->UserProfileSize, Info, InfoSize);\r
1064 if (UserInfo != NULL) {\r
1065 *UserInfo = (EFI_USER_INFO *) (User->ProfileInfo + User->UserProfileSize);\r
1066 }\r
1067 User->UserProfileSize += ALIGN_VARIABLE (InfoSize);\r
1068\r
1069 //\r
1070 // Save user profile information.\r
1071 //\r
1072 if (Save) {\r
1073 Status = SaveNvUserProfile (User, FALSE);\r
1074 }\r
1075\r
1076 return Status;\r
1077}\r
1078\r
1079\r
1080/**\r
1081 Get the user info from the specified user info handle.\r
1082\r
1083 @param[in] User Point to the user profile.\r
1084 @param[in] UserInfo Point to the user information record to get.\r
1085 @param[out] Info On entry, points to a buffer of at least *InfoSize bytes. \r
1086 On exit, holds the user information.\r
1087 @param[in, out] InfoSize On entry, points to the size of Info. \r
1088 On return, points to the size of the user information.\r
1089 @param[in] ChkRight If TRUE, check the user info attribute.\r
1090 If FALSE, don't check the user info attribute.\r
1091\r
1092\r
1093 @retval EFI_ACCESS_DENIED The information cannot be accessed by the current user.\r
1094 @retval EFI_INVALID_PARAMETER InfoSize is NULL or UserInfo is NULL.\r
1095 @retval EFI_BUFFER_TOO_SMALL The number of bytes specified by *InfoSize is too small to hold the \r
1096 returned data. The actual size required is returned in *InfoSize.\r
1097 @retval EFI_SUCCESS Information returned successfully.\r
1098\r
1099**/\r
1100EFI_STATUS\r
1101GetUserInfo (\r
1102 IN USER_PROFILE_ENTRY *User,\r
1103 IN EFI_USER_INFO *UserInfo,\r
1104 OUT EFI_USER_INFO *Info,\r
1105 IN OUT UINTN *InfoSize,\r
1106 IN BOOLEAN ChkRight\r
1107 )\r
1108{\r
1109 EFI_STATUS Status;\r
1110\r
1111 if ((InfoSize == NULL) || (UserInfo == NULL)) {\r
1112 return EFI_INVALID_PARAMETER;\r
1113 }\r
1114\r
1115 if ((*InfoSize != 0) && (Info == NULL)) {\r
1116 return EFI_INVALID_PARAMETER;\r
1117 }\r
1118 \r
1119 //\r
1120 // Find the user information to get.\r
1121 //\r
1122 Status = FindUserInfo (User, &UserInfo, FALSE, NULL);\r
1123 if (EFI_ERROR (Status)) {\r
1124 return Status;\r
1125 }\r
1126 \r
1127 //\r
1128 // Check information attributes.\r
1129 //\r
1130 if (ChkRight) {\r
1131 switch (UserInfo->InfoAttribs & EFI_USER_INFO_ACCESS) {\r
1132 case EFI_USER_INFO_PRIVATE:\r
1133 case EFI_USER_INFO_PROTECTED:\r
1134 if (User != mCurrentUser) {\r
1135 return EFI_ACCESS_DENIED;\r
1136 }\r
1137 break;\r
1138\r
1139 case EFI_USER_INFO_PUBLIC:\r
1140 break;\r
1141\r
1142 default:\r
1143 return EFI_INVALID_PARAMETER;\r
1144 break;\r
1145 }\r
1146 }\r
1147 \r
1148 //\r
1149 // Get user information.\r
1150 //\r
1151 if (UserInfo->InfoSize > *InfoSize) {\r
1152 *InfoSize = UserInfo->InfoSize;\r
1153 return EFI_BUFFER_TOO_SMALL;\r
1154 }\r
1155\r
1156 *InfoSize = UserInfo->InfoSize;\r
1157 if (Info != NULL) {\r
1158 CopyMem (Info, UserInfo, *InfoSize);\r
1159 }\r
1160\r
1161 return EFI_SUCCESS;\r
1162}\r
1163\r
1164\r
1165/**\r
1166 Delete the specified user information from user profile.\r
1167\r
1168 @param[in] User Point to the user profile.\r
1169 @param[in] Info Point to the user information record to delete.\r
1170 @param[in] Save If TRUE, save the profile to NV flash.\r
1171 If FALSE, don't need to save the profile to NV flash.\r
1172\r
1173 @retval EFI_SUCCESS Delete user info from user profile successfully.\r
1174 @retval Others Fail to delete user info from user profile.\r
1175\r
1176**/\r
1177EFI_STATUS\r
1178DelUserInfo (\r
1179 IN USER_PROFILE_ENTRY *User,\r
1180 IN EFI_USER_INFO *Info,\r
1181 IN BOOLEAN Save\r
1182 )\r
1183{\r
1184 EFI_STATUS Status;\r
1185 UINTN Offset;\r
1186 UINTN NextOffset;\r
1187\r
1188 //\r
1189 // Check user information handle.\r
1190 //\r
1191 Status = FindUserInfo (User, &Info, FALSE, &Offset);\r
1192 if (EFI_ERROR (Status)) {\r
1193 return Status;\r
1194 }\r
1195\r
1196 if (Info->InfoType == EFI_USER_INFO_IDENTIFIER_RECORD) {\r
1197 return EFI_ACCESS_DENIED;\r
1198 }\r
1199 \r
1200 //\r
1201 // Delete the specified user information.\r
1202 //\r
1203 NextOffset = Offset + ALIGN_VARIABLE (Info->InfoSize);\r
1204 User->UserProfileSize -= ALIGN_VARIABLE (Info->InfoSize);\r
1205 if (Offset < User->UserProfileSize) {\r
1206 CopyMem (User->ProfileInfo + Offset, User->ProfileInfo + NextOffset, User->UserProfileSize - Offset);\r
1207 }\r
1208\r
1209 if (Save) {\r
1210 Status = SaveNvUserProfile (User, FALSE);\r
1211 }\r
1212\r
1213 return Status;\r
1214}\r
1215\r
1216\r
1217/**\r
1218 Add or update user information.\r
1219\r
1220 @param[in] User Point to the user profile.\r
1221 @param[in, out] UserInfo On entry, points to the user information to modify,\r
1222 or NULL to add a new UserInfo. \r
1223 On return, points to the modified user information.\r
1224 @param[in] Info Points to the new user information.\r
1225 @param[in] InfoSize The size of Info,in bytes.\r
1226\r
1227 @retval EFI_INVALID_PARAMETER UserInfo is NULL or Info is NULL.\r
1228 @retval EFI_ACCESS_DENIED The record is exclusive.\r
1229 @retval EFI_SUCCESS User information was successfully changed/added.\r
1230\r
1231**/\r
1232EFI_STATUS\r
1233ModifyUserInfo (\r
1234 IN USER_PROFILE_ENTRY *User,\r
1235 IN OUT EFI_USER_INFO **UserInfo,\r
1236 IN CONST EFI_USER_INFO *Info,\r
1237 IN UINTN InfoSize\r
1238 )\r
1239{\r
1240 EFI_STATUS Status;\r
1241 UINTN PayloadLen;\r
1242 EFI_USER_INFO *OldInfo;\r
1243\r
1244 if ((UserInfo == NULL) || (Info == NULL)) {\r
1245 return EFI_INVALID_PARAMETER;\r
1246 }\r
1247\r
1248 if (InfoSize < sizeof (EFI_USER_INFO) || InfoSize != Info->InfoSize) {\r
1249 return EFI_INVALID_PARAMETER;\r
1250 }\r
1251 \r
1252 //\r
1253 // Check user information.\r
1254 //\r
1255 if (Info->InfoType == EFI_USER_INFO_IDENTIFIER_RECORD) {\r
1256 return EFI_ACCESS_DENIED;\r
1257 }\r
1258 \r
1259 if (!CheckUserInfo (Info)) {\r
1260 return EFI_INVALID_PARAMETER;\r
1261 }\r
1262\r
1263\r
1264 if (*UserInfo == NULL) {\r
1265 //\r
1266 // Add new user information.\r
1267 //\r
1268 OldInfo = NULL;\r
1269 do {\r
1270 Status = FindUserInfoByType (User, &OldInfo, Info->InfoType);\r
1271 if (EFI_ERROR (Status)) {\r
1272 break;\r
1273 }\r
1274 ASSERT (OldInfo != NULL);\r
1275\r
1276 if (((OldInfo->InfoAttribs & EFI_USER_INFO_EXCLUSIVE) != 0) || \r
1277 ((Info->InfoAttribs & EFI_USER_INFO_EXCLUSIVE) != 0)) {\r
1278 //\r
1279 // Same type can not co-exist for exclusive information.\r
1280 //\r
1281 return EFI_ACCESS_DENIED;\r
1282 }\r
1283\r
1284 //\r
1285 // Check whether it exists in DB.\r
1286 //\r
1287 if (Info->InfoSize != OldInfo->InfoSize) {\r
1288 continue;\r
1289 }\r
1290\r
1291 if (!CompareGuid (&OldInfo->Credential, &Info->Credential)) {\r
1292 continue;\r
1293 }\r
1294 \r
1295 PayloadLen = Info->InfoSize - sizeof (EFI_USER_INFO);\r
1296 if (PayloadLen == 0) {\r
1297 continue;\r
1298 }\r
1299\r
1300 if (CompareMem ((UINT8 *)(OldInfo + 1), (UINT8 *)(Info + 1), PayloadLen) != 0) {\r
1301 continue;\r
1302 }\r
1303\r
1304 //\r
1305 // Yes. The new info is as same as the one in profile.\r
1306 //\r
1307 return EFI_SUCCESS;\r
1308 } while (!EFI_ERROR (Status));\r
1309\r
1310 Status = AddUserInfo (User, (UINT8 *) Info, InfoSize, UserInfo, TRUE);\r
1311 return Status;\r
1312 }\r
1313 \r
1314 //\r
1315 // Modify existing user information.\r
1316 //\r
1317 OldInfo = *UserInfo;\r
1318 if (OldInfo->InfoType != Info->InfoType) {\r
1319 return EFI_INVALID_PARAMETER;\r
1320 }\r
1321 \r
1322 if (((Info->InfoAttribs & EFI_USER_INFO_EXCLUSIVE) != 0) && \r
1323 (OldInfo->InfoAttribs & EFI_USER_INFO_EXCLUSIVE) == 0) {\r
1324 //\r
1325 // Try to add exclusive attrib in new info. \r
1326 // Check whether there is another information with the same type in profile.\r
1327 //\r
1328 OldInfo = NULL;\r
1329 do {\r
1330 Status = FindUserInfoByType (User, &OldInfo, Info->InfoType);\r
1331 if (EFI_ERROR (Status)) {\r
1332 break;\r
1333 }\r
1334 if (OldInfo != *UserInfo) {\r
1335 //\r
1336 // There is another information with the same type in profile.\r
1337 // Therefore, can't modify existing user information to add exclusive attribute.\r
1338 //\r
1339 return EFI_ACCESS_DENIED;\r
1340 }\r
1341 } while (TRUE); \r
1342 }\r
1343\r
1344 Status = DelUserInfo (User, *UserInfo, FALSE);\r
1345 if (EFI_ERROR (Status)) {\r
1346 return Status;\r
1347 }\r
1348\r
1349 return AddUserInfo (User, (UINT8 *) Info, InfoSize, UserInfo, TRUE);\r
1350}\r
1351\r
1352\r
1353/**\r
1354 Delete the user profile from non-volatile memory and database.\r
1355\r
1356 @param[in] User Points to the user profile.\r
1357\r
1358 @retval EFI_SUCCESS Delete user from the user profile successfully.\r
1359 @retval Others Fail to delete user from user profile\r
1360 \r
1361**/\r
1362EFI_STATUS\r
1363DelUserProfile (\r
1364 IN USER_PROFILE_ENTRY *User\r
1365 )\r
1366{\r
1367 EFI_STATUS Status;\r
1368 UINTN Index;\r
1369\r
1370 //\r
1371 // Check whether it is in the user profile database.\r
1372 //\r
1373 Status = FindUserProfile (&User, FALSE, &Index);\r
1374 if (EFI_ERROR (Status)) {\r
1375 return EFI_INVALID_PARAMETER;\r
1376 }\r
1377 \r
1378 //\r
1379 // Check whether it is the current user.\r
1380 //\r
1381 if (User == mCurrentUser) {\r
1382 return EFI_ACCESS_DENIED;\r
1383 }\r
1384 \r
1385 //\r
1386 // Delete user profile from the non-volatile memory.\r
1387 //\r
1388 Status = SaveNvUserProfile (mUserProfileDb->UserProfile[mUserProfileDb->UserProfileNum - 1], TRUE);\r
1389 if (EFI_ERROR (Status)) {\r
1390 return Status;\r
1391 }\r
1392 mUserProfileDb->UserProfileNum--;\r
1393\r
1394 //\r
1395 // Modify user profile database.\r
1396 //\r
1397 if (Index != mUserProfileDb->UserProfileNum) {\r
1398 mUserProfileDb->UserProfile[Index] = mUserProfileDb->UserProfile[mUserProfileDb->UserProfileNum];\r
1399 CopyMem (\r
1400 ((USER_PROFILE_ENTRY *) mUserProfileDb->UserProfile[Index])->UserVarName,\r
1401 User->UserVarName,\r
1402 sizeof (User->UserVarName)\r
1403 );\r
1404 Status = SaveNvUserProfile (mUserProfileDb->UserProfile[Index], FALSE);\r
1405 if (EFI_ERROR (Status)) {\r
1406 return Status;\r
1407 }\r
1408 }\r
1409 //\r
1410 // Delete user profile information.\r
1411 //\r
1412 if (User->ProfileInfo != NULL) {\r
1413 FreePool (User->ProfileInfo);\r
1414 }\r
1415\r
1416 FreePool (User);\r
1417 return EFI_SUCCESS;\r
1418}\r
1419\r
1420\r
1421/**\r
1422 Add user profile to user profile database.\r
1423\r
1424 @param[out] UserProfile Point to the newly added user profile.\r
1425 @param[in] ProfileSize The size of the user profile.\r
1426 @param[in] ProfileInfo Point to the user profie data.\r
1427 @param[in] Save If TRUE, save the new added profile to NV flash.\r
1428 If FALSE, don't save the profile to NV flash.\r
1429\r
1430 @retval EFI_SUCCESS Add user profile to user profile database successfully.\r
1431 @retval Others Fail to add user profile to user profile database.\r
1432\r
1433**/\r
1434EFI_STATUS\r
1435AddUserProfile (\r
1436 OUT USER_PROFILE_ENTRY **UserProfile, OPTIONAL\r
1437 IN UINTN ProfileSize,\r
1438 IN UINT8 *ProfileInfo,\r
1439 IN BOOLEAN Save\r
1440 )\r
1441{\r
1442 EFI_STATUS Status;\r
1443 USER_PROFILE_ENTRY *User;\r
1444\r
1445 //\r
1446 // Check the data format to be added.\r
1447 //\r
1448 if (!CheckProfileInfo (ProfileInfo, ProfileSize)) {\r
1449 return EFI_SECURITY_VIOLATION;\r
1450 }\r
1451 \r
1452 //\r
1453 // Create user profile entry.\r
1454 //\r
1455 User = AllocateZeroPool (sizeof (USER_PROFILE_ENTRY));\r
1456 if (User == NULL) {\r
1457 return EFI_OUT_OF_RESOURCES;\r
1458 }\r
1459 //\r
1460 // Add the entry to the user profile database.\r
1461 //\r
1462 if (mUserProfileDb->UserProfileNum == mUserProfileDb->MaxProfileNum) {\r
1463 if (!ExpandUsermUserProfileDb ()) {\r
1464 FreePool (User);\r
1465 return EFI_OUT_OF_RESOURCES;\r
1466 }\r
1467 }\r
1468\r
1469 UnicodeSPrint (\r
1470 User->UserVarName, \r
1471 sizeof (User->UserVarName),\r
1472 L"User%04x", \r
1473 mUserProfileDb->UserProfileNum\r
1474 );\r
1475 User->UserProfileSize = 0;\r
1476 User->MaxProfileSize = 0;\r
1477 User->ProfileInfo = NULL;\r
1478 mUserProfileDb->UserProfile[mUserProfileDb->UserProfileNum] = (EFI_USER_PROFILE_HANDLE) User;\r
1479 mUserProfileDb->UserProfileNum++;\r
1480\r
1481 //\r
1482 // Add user profile information.\r
1483 //\r
1484 Status = AddUserInfo (User, ProfileInfo, ProfileSize, NULL, Save);\r
1485 if (EFI_ERROR (Status)) {\r
1486 DelUserProfile (User);\r
1487 return Status;\r
1488 }\r
1489 //\r
1490 // Set new user profile handle.\r
1491 //\r
1492 if (UserProfile != NULL) {\r
1493 *UserProfile = User;\r
1494 }\r
1495\r
1496 return EFI_SUCCESS;\r
1497}\r
1498\r
1499\r
1500/**\r
1501 This function creates a new user profile with only a new user identifier\r
1502 attached and returns its handle. The user profile is non-volatile, but the\r
1503 handle User can change across reboots.\r
1504\r
1505 @param[out] User Handle of a new user profile.\r
1506\r
1507 @retval EFI_SUCCESS User profile was successfully created.\r
1508 @retval Others Fail to create user profile\r
1509\r
1510**/\r
1511EFI_STATUS\r
1512CreateUserProfile (\r
1513 OUT USER_PROFILE_ENTRY **User\r
1514 )\r
1515{\r
1516 EFI_STATUS Status;\r
1517 EFI_USER_INFO *UserInfo;\r
1518\r
1519 if (User == NULL) {\r
1520 return EFI_INVALID_PARAMETER;\r
1521 }\r
1522 //\r
1523 // Generate user id information.\r
1524 //\r
1525 UserInfo = AllocateZeroPool (sizeof (EFI_USER_INFO) + sizeof (EFI_USER_INFO_IDENTIFIER));\r
1526 if (UserInfo == NULL) {\r
1527 return EFI_OUT_OF_RESOURCES;\r
1528 }\r
1529\r
1530 UserInfo->InfoType = EFI_USER_INFO_IDENTIFIER_RECORD;\r
1531 UserInfo->InfoSize = sizeof (EFI_USER_INFO) + sizeof (EFI_USER_INFO_IDENTIFIER);\r
1532 UserInfo->InfoAttribs = EFI_USER_INFO_STORAGE_PLATFORM_NV | EFI_USER_INFO_PUBLIC | EFI_USER_INFO_EXCLUSIVE;\r
1533 GenerateUserId ((UINT8 *) (UserInfo + 1));\r
1534 \r
1535 //\r
1536 // Add user profile to the user profile database.\r
1537 //\r
1538 Status = AddUserProfile (User, UserInfo->InfoSize, (UINT8 *) UserInfo, TRUE);\r
1539 FreePool (UserInfo);\r
1540 return Status;\r
1541}\r
1542\r
1543\r
1544/**\r
1545 Add a default user profile to user profile database.\r
1546\r
1547 @retval EFI_SUCCESS A default user profile is added successfully.\r
1548 @retval Others Fail to add a default user profile\r
1549 \r
1550**/\r
1551EFI_STATUS\r
1552AddDefaultUserProfile (\r
1553 VOID\r
1554 )\r
1555{\r
1556 EFI_STATUS Status;\r
1557 USER_PROFILE_ENTRY *User;\r
1558 EFI_USER_INFO *Info;\r
1559 EFI_USER_INFO *NewInfo;\r
1560 EFI_USER_INFO_CREATE_DATE CreateDate;\r
1561 EFI_USER_INFO_USAGE_COUNT UsageCount;\r
1562 EFI_USER_INFO_ACCESS_CONTROL *Access;\r
1563 EFI_USER_INFO_IDENTITY_POLICY *Policy;\r
1564 \r
1565 //\r
1566 // Create a user profile.\r
1567 //\r
1568 Status = CreateUserProfile (&User);\r
1569 if (EFI_ERROR (Status)) {\r
1570 return Status;\r
1571 }\r
1572 \r
1573 //\r
1574 // Allocate a buffer to add all default user information.\r
1575 //\r
1576 Info = AllocateZeroPool (sizeof (EFI_USER_INFO) + INFO_PAYLOAD_SIZE);\r
1577 if (Info == NULL) {\r
1578 return EFI_OUT_OF_RESOURCES;\r
1579 }\r
1580\r
1581 //\r
1582 // Add user name.\r
1583 //\r
1584 Info->InfoType = EFI_USER_INFO_NAME_RECORD;\r
1585 Info->InfoAttribs = EFI_USER_INFO_STORAGE_PLATFORM_NV | EFI_USER_INFO_PUBLIC | EFI_USER_INFO_EXCLUSIVE;\r
1586 Info->InfoSize = sizeof (EFI_USER_INFO) + sizeof (mUserName);\r
1587 CopyMem ((UINT8 *) (Info + 1), mUserName, sizeof (mUserName));\r
1588 NewInfo = NULL;\r
1589 Status = ModifyUserInfo (User, &NewInfo, Info, Info->InfoSize);\r
1590 if (EFI_ERROR (Status)) {\r
1591 goto Done;\r
1592 }\r
1593 \r
1594 //\r
1595 // Add user profile create date record.\r
1596 //\r
1597 Info->InfoType = EFI_USER_INFO_CREATE_DATE_RECORD;\r
1598 Info->InfoAttribs = EFI_USER_INFO_STORAGE_PLATFORM_NV | EFI_USER_INFO_PUBLIC | EFI_USER_INFO_EXCLUSIVE;\r
1599 Info->InfoSize = sizeof (EFI_USER_INFO) + sizeof (EFI_USER_INFO_CREATE_DATE);\r
1600 Status = gRT->GetTime (&CreateDate, NULL);\r
1601 if (EFI_ERROR (Status)) {\r
1602 goto Done;\r
1603 }\r
1604\r
1605 CopyMem ((UINT8 *) (Info + 1), &CreateDate, sizeof (EFI_USER_INFO_CREATE_DATE));\r
1606 NewInfo = NULL;\r
1607 Status = ModifyUserInfo (User, &NewInfo, Info, Info->InfoSize);\r
1608 if (EFI_ERROR (Status)) {\r
1609 goto Done;\r
1610 }\r
1611 \r
1612 //\r
1613 // Add user profile usage count record.\r
1614 //\r
1615 Info->InfoType = EFI_USER_INFO_USAGE_COUNT_RECORD;\r
1616 Info->InfoAttribs = EFI_USER_INFO_STORAGE_PLATFORM_NV | EFI_USER_INFO_PUBLIC | EFI_USER_INFO_EXCLUSIVE;\r
1617 Info->InfoSize = sizeof (EFI_USER_INFO) + sizeof (EFI_USER_INFO_USAGE_COUNT);\r
1618 UsageCount = 0;\r
1619 CopyMem ((UINT8 *) (Info + 1), &UsageCount, sizeof (EFI_USER_INFO_USAGE_COUNT));\r
1620 NewInfo = NULL;\r
1621 Status = ModifyUserInfo (User, &NewInfo, Info, Info->InfoSize);\r
1622 if (EFI_ERROR (Status)) {\r
1623 goto Done;\r
1624 }\r
1625 \r
1626 //\r
1627 // Add user access right.\r
1628 //\r
1629 Info->InfoType = EFI_USER_INFO_ACCESS_POLICY_RECORD;\r
1630 Info->InfoAttribs = EFI_USER_INFO_STORAGE_PLATFORM_NV | EFI_USER_INFO_PUBLIC | EFI_USER_INFO_EXCLUSIVE;\r
1631 Access = (EFI_USER_INFO_ACCESS_CONTROL *) (Info + 1);\r
1632 Access->Type = EFI_USER_INFO_ACCESS_MANAGE;\r
1633 Access->Size = sizeof (EFI_USER_INFO_ACCESS_CONTROL);\r
1634 Info->InfoSize = sizeof (EFI_USER_INFO) + Access->Size;\r
1635 NewInfo = NULL;\r
1636 Status = ModifyUserInfo (User, &NewInfo, Info, Info->InfoSize);\r
1637 if (EFI_ERROR (Status)) {\r
1638 goto Done;\r
1639 }\r
1640 \r
1641 //\r
1642 // Add user identity policy.\r
1643 //\r
1644 Info->InfoType = EFI_USER_INFO_IDENTITY_POLICY_RECORD;\r
1645 Info->InfoAttribs = EFI_USER_INFO_STORAGE_PLATFORM_NV | EFI_USER_INFO_PRIVATE | EFI_USER_INFO_EXCLUSIVE;\r
1646 Policy = (EFI_USER_INFO_IDENTITY_POLICY *) (Info + 1);\r
1647 Policy->Type = EFI_USER_INFO_IDENTITY_TRUE;\r
1648 Policy->Length = sizeof (EFI_USER_INFO_IDENTITY_POLICY); \r
1649 Info->InfoSize = sizeof (EFI_USER_INFO) + Policy->Length;\r
1650 NewInfo = NULL;\r
1651 Status = ModifyUserInfo (User, &NewInfo, Info, Info->InfoSize);\r
1652\r
1653Done:\r
1654 FreePool (Info);\r
1655 return Status;\r
1656}\r
1657\r
1658\r
1659/**\r
1660 Publish current user information into EFI System Configuration Table.\r
1661\r
1662 By UEFI spec, the User Identity Manager will publish the current user profile \r
1663 into the EFI System Configuration Table. Currently, only the user identifier and user\r
1664 name are published.\r
1665\r
1666 @retval EFI_SUCCESS Current user information is published successfully.\r
1667 @retval Others Fail to publish current user information\r
1668\r
1669**/\r
1670EFI_STATUS\r
1671PublishUserTable (\r
1672 VOID\r
1673 )\r
1674{\r
1675 EFI_STATUS Status;\r
1676 EFI_CONFIGURATION_TABLE *EfiConfigurationTable;\r
1677 EFI_USER_INFO_TABLE *UserInfoTable;\r
1678 EFI_USER_INFO *IdInfo;\r
1679 EFI_USER_INFO *NameInfo;\r
1680\r
1681 Status = EfiGetSystemConfigurationTable (\r
1682 &gEfiUserManagerProtocolGuid,\r
1683 (VOID **) &EfiConfigurationTable\r
1684 );\r
1685 if (!EFI_ERROR (Status)) {\r
1686 //\r
1687 // The table existed! \r
1688 //\r
1689 return EFI_SUCCESS;\r
1690 }\r
1691\r
1692 //\r
1693 // Get user ID information.\r
1694 //\r
1695 IdInfo = NULL;\r
1696 Status = FindUserInfoByType (mCurrentUser, &IdInfo, EFI_USER_INFO_IDENTIFIER_RECORD);\r
1697 if (EFI_ERROR (Status)) {\r
1698 return Status;\r
1699\r
1700 }\r
1701 //\r
1702 // Get user name information.\r
1703 //\r
1704 NameInfo = NULL;\r
1705 Status = FindUserInfoByType (mCurrentUser, &NameInfo, EFI_USER_INFO_NAME_RECORD);\r
1706 if (EFI_ERROR (Status)) {\r
1707 return Status;\r
1708 }\r
1709 \r
1710 //\r
1711 // Allocate a buffer for user information table.\r
1712 //\r
1713 UserInfoTable = (EFI_USER_INFO_TABLE *) AllocateRuntimePool (\r
1714 sizeof (EFI_USER_INFO_TABLE) + \r
1715 IdInfo->InfoSize + \r
1716 NameInfo->InfoSize\r
1717 );\r
1718 if (UserInfoTable == NULL) {\r
1719 Status = EFI_OUT_OF_RESOURCES;\r
1720 return Status;\r
1721 }\r
1722\r
1723 UserInfoTable->Size = sizeof (EFI_USER_INFO_TABLE); \r
1724 \r
1725 //\r
1726 // Append the user information to the user info table\r
1727 //\r
1728 CopyMem ((UINT8 *) UserInfoTable + UserInfoTable->Size, (UINT8 *) IdInfo, IdInfo->InfoSize);\r
1729 UserInfoTable->Size += IdInfo->InfoSize;\r
1730\r
1731 CopyMem ((UINT8 *) UserInfoTable + UserInfoTable->Size, (UINT8 *) NameInfo, NameInfo->InfoSize);\r
1732 UserInfoTable->Size += NameInfo->InfoSize;\r
1733\r
1734 Status = gBS->InstallConfigurationTable (&gEfiUserManagerProtocolGuid, (VOID *) UserInfoTable);\r
1735 return Status;\r
1736}\r
1737\r
1738\r
1739/**\r
1740 Get the user's identity type.\r
1741\r
1742 The identify manager only supports the identity policy in which the credential \r
1743 provider handles are connected by the operator 'AND' or 'OR'.\r
1744\r
1745\r
1746 @param[in] User Handle of a user profile.\r
1747 @param[out] PolicyType Point to the identity type.\r
1748\r
1749 @retval EFI_SUCCESS Get user's identity type successfully.\r
1750 @retval Others Fail to get user's identity type.\r
1751\r
1752**/\r
1753EFI_STATUS\r
1754GetIdentifyType (\r
1755 IN EFI_USER_PROFILE_HANDLE User,\r
1756 OUT UINT8 *PolicyType\r
1757 )\r
1758{\r
1759 EFI_STATUS Status;\r
1760 EFI_USER_INFO *IdentifyInfo;\r
1761 UINTN TotalLen;\r
1762 EFI_USER_INFO_IDENTITY_POLICY *Identity;\r
1763\r
1764 //\r
1765 // Get user identify policy information.\r
1766 //\r
1767 IdentifyInfo = NULL;\r
1768 Status = FindUserInfoByType (User, &IdentifyInfo, EFI_USER_INFO_IDENTITY_POLICY_RECORD);\r
1769 if (EFI_ERROR (Status)) {\r
1770 return Status;\r
1771 }\r
1772 ASSERT (IdentifyInfo != NULL);\r
1773 \r
1774 //\r
1775 // Search the user identify policy according to type.\r
1776 //\r
1777 TotalLen = 0;\r
1778 *PolicyType = EFI_USER_INFO_IDENTITY_FALSE;\r
1779 while (TotalLen < IdentifyInfo->InfoSize - sizeof (EFI_USER_INFO)) {\r
1780 Identity = (EFI_USER_INFO_IDENTITY_POLICY *) ((UINT8 *) (IdentifyInfo + 1) + TotalLen);\r
1781 if (Identity->Type == EFI_USER_INFO_IDENTITY_AND) {\r
1782 *PolicyType = EFI_USER_INFO_IDENTITY_AND;\r
1783 break;\r
1784 }\r
1785\r
1786 if (Identity->Type == EFI_USER_INFO_IDENTITY_OR) {\r
1787 *PolicyType = EFI_USER_INFO_IDENTITY_OR;\r
1788 break;\r
1789 }\r
1790 TotalLen += Identity->Length;\r
1791 }\r
1792 return EFI_SUCCESS;\r
1793}\r
1794\r
1795\r
1796/**\r
1797 Identify the User by the specfied provider.\r
1798\r
1799 @param[in] User Handle of a user profile.\r
1800 @param[in] Provider Points to the identifier of credential provider.\r
1801\r
1802 @retval EFI_INVALID_PARAMETER Provider is NULL.\r
1803 @retval EFI_NOT_FOUND Fail to identify the specified user.\r
1804 @retval EFI_SUCCESS User is identified successfully.\r
1805\r
1806**/\r
1807EFI_STATUS\r
1808IdentifyByProviderId (\r
1809 IN EFI_USER_PROFILE_HANDLE User,\r
1810 IN EFI_GUID *Provider\r
1811 )\r
1812{\r
1813 EFI_STATUS Status;\r
1814 EFI_USER_INFO_IDENTIFIER UserId;\r
1815 UINTN Index;\r
1816 EFI_CREDENTIAL_LOGON_FLAGS AutoLogon;\r
1817 EFI_HII_HANDLE HiiHandle;\r
1818 EFI_GUID FormSetId;\r
1819 EFI_FORM_ID FormId;\r
1820 EFI_USER_CREDENTIAL2_PROTOCOL *UserCredential;\r
1821\r
1822 if (Provider == NULL) {\r
1823 return EFI_INVALID_PARAMETER;\r
1824 }\r
1825 \r
1826 //\r
1827 // Check the user ID identified by the specified credential provider.\r
1828 //\r
1829 for (Index = 0; Index < mProviderDb->Count; Index++) {\r
1830 //\r
1831 // Check credential provider class.\r
1832 //\r
1833 UserCredential = mProviderDb->Provider[Index];\r
1834 if (CompareGuid (&UserCredential->Identifier, Provider)) {\r
1835 Status = UserCredential->Select (UserCredential, &AutoLogon);\r
1836 if (EFI_ERROR (Status)) {\r
1837 return Status;\r
1838 }\r
1839\r
1840 if ((AutoLogon & EFI_CREDENTIAL_LOGON_FLAG_AUTO) == 0) {\r
1841 //\r
1842 // Get credential provider form.\r
1843 //\r
1844 Status = UserCredential->Form (\r
1845 UserCredential, \r
1846 &HiiHandle, \r
1847 &FormSetId, \r
1848 &FormId\r
1849 );\r
1850 if (!EFI_ERROR (Status)) { \r
1851 //\r
1852 // Send form to get user input.\r
1853 //\r
1854 Status = mCallbackInfo->FormBrowser2->SendForm (\r
1855 mCallbackInfo->FormBrowser2,\r
1856 &HiiHandle,\r
1857 1,\r
1858 &FormSetId,\r
1859 FormId,\r
1860 NULL,\r
1861 NULL\r
1862 );\r
1863 if (EFI_ERROR (Status)) {\r
1864 return Status;\r
1865 } \r
1866 } \r
1867 }\r
1868\r
1869 Status = UserCredential->User (UserCredential, User, &UserId);\r
1870 if (EFI_ERROR (Status)) {\r
1871 return Status;\r
1872 }\r
1873\r
1874 Status = UserCredential->Deselect (UserCredential);\r
1875 if (EFI_ERROR (Status)) {\r
1876 return Status;\r
1877 }\r
1878 \r
1879 return EFI_SUCCESS;\r
1880 }\r
1881 }\r
1882\r
1883 return EFI_NOT_FOUND;\r
1884}\r
1885\r
1886\r
1887/**\r
1888 Update user information when user is logon on successfully.\r
1889\r
1890 @param[in] User Points to user profile.\r
1891\r
1892 @retval EFI_SUCCESS Update user information successfully.\r
1893 @retval Others Fail to update user information.\r
1894\r
1895**/\r
1896EFI_STATUS\r
1897UpdateUserInfo (\r
1898 IN USER_PROFILE_ENTRY *User\r
1899 )\r
1900{\r
1901 EFI_STATUS Status;\r
1902 EFI_USER_INFO *Info;\r
1903 EFI_USER_INFO *NewInfo;\r
1904 EFI_USER_INFO_CREATE_DATE Date;\r
1905 EFI_USER_INFO_USAGE_COUNT UsageCount;\r
1906 UINTN InfoLen;\r
1907\r
1908 //\r
1909 // Allocate a buffer to update user's date record and usage record.\r
1910 //\r
1911 InfoLen = MAX (sizeof (EFI_USER_INFO_CREATE_DATE), sizeof (EFI_USER_INFO_USAGE_COUNT));\r
1912 Info = AllocateZeroPool (sizeof (EFI_USER_INFO) + InfoLen);\r
1913 if (Info == NULL) {\r
1914 return EFI_OUT_OF_RESOURCES;\r
1915 }\r
1916 \r
1917 //\r
1918 // Check create date record.\r
1919 //\r
1920 NewInfo = NULL;\r
1921 Status = FindUserInfoByType (User, &NewInfo, EFI_USER_INFO_CREATE_DATE_RECORD);\r
1922 if (Status == EFI_NOT_FOUND) {\r
1923 Info->InfoType = EFI_USER_INFO_CREATE_DATE_RECORD;\r
1924 Info->InfoAttribs = EFI_USER_INFO_STORAGE_PLATFORM_NV | EFI_USER_INFO_PUBLIC | EFI_USER_INFO_EXCLUSIVE;\r
1925 Info->InfoSize = sizeof (EFI_USER_INFO) + sizeof (EFI_USER_INFO_CREATE_DATE);\r
1926 Status = gRT->GetTime (&Date, NULL);\r
1927 if (EFI_ERROR (Status)) {\r
1928 FreePool (Info);\r
1929 return Status;\r
1930 }\r
1931\r
1932 CopyMem ((UINT8 *) (Info + 1), &Date, sizeof (EFI_USER_INFO_CREATE_DATE));\r
1933 NewInfo = NULL;\r
1934 Status = ModifyUserInfo (User, &NewInfo, Info, Info->InfoSize);\r
1935 if (EFI_ERROR (Status)) {\r
1936 FreePool (Info);\r
1937 return Status;\r
1938 }\r
1939 }\r
1940 \r
1941 //\r
1942 // Update usage date record.\r
1943 //\r
1944 NewInfo = NULL;\r
1945 Status = FindUserInfoByType (User, &NewInfo, EFI_USER_INFO_USAGE_DATE_RECORD);\r
1946 if ((Status == EFI_SUCCESS) || (Status == EFI_NOT_FOUND)) {\r
1947 Info->InfoType = EFI_USER_INFO_USAGE_DATE_RECORD;\r
1948 Info->InfoAttribs = EFI_USER_INFO_STORAGE_PLATFORM_NV | EFI_USER_INFO_PUBLIC | EFI_USER_INFO_EXCLUSIVE;\r
1949 Info->InfoSize = sizeof (EFI_USER_INFO) + sizeof (EFI_USER_INFO_USAGE_DATE);\r
1950 Status = gRT->GetTime (&Date, NULL);\r
1951 if (EFI_ERROR (Status)) {\r
1952 FreePool (Info);\r
1953 return Status;\r
1954 }\r
1955\r
1956 CopyMem ((UINT8 *) (Info + 1), &Date, sizeof (EFI_USER_INFO_USAGE_DATE));\r
1957 Status = ModifyUserInfo (User, &NewInfo, Info, Info->InfoSize);\r
1958 if (EFI_ERROR (Status)) {\r
1959 FreePool (Info);\r
1960 return Status;\r
1961 }\r
1962 }\r
1963 \r
1964 //\r
1965 // Update usage count record.\r
1966 //\r
1967 UsageCount = 0;\r
1968 NewInfo = NULL;\r
1969 Status = FindUserInfoByType (User, &NewInfo, EFI_USER_INFO_USAGE_COUNT_RECORD);\r
1970 //\r
1971 // Get usage count.\r
1972 //\r
1973 if (Status == EFI_SUCCESS) {\r
1974 CopyMem (&UsageCount, (UINT8 *) (NewInfo + 1), sizeof (EFI_USER_INFO_USAGE_COUNT));\r
1975 }\r
1976\r
1977 UsageCount++;\r
1978 if ((Status == EFI_SUCCESS) || (Status == EFI_NOT_FOUND)) {\r
1979 Info->InfoType = EFI_USER_INFO_USAGE_COUNT_RECORD;\r
1980 Info->InfoAttribs = EFI_USER_INFO_STORAGE_PLATFORM_NV | EFI_USER_INFO_PUBLIC | EFI_USER_INFO_EXCLUSIVE;\r
1981 Info->InfoSize = sizeof (EFI_USER_INFO) + sizeof (EFI_USER_INFO_USAGE_COUNT);\r
1982 CopyMem ((UINT8 *) (Info + 1), &UsageCount, sizeof (EFI_USER_INFO_USAGE_COUNT));\r
1983 Status = ModifyUserInfo (User, &NewInfo, Info, Info->InfoSize);\r
1984 if (EFI_ERROR (Status)) {\r
1985 FreePool (Info);\r
1986 return Status;\r
1987 }\r
1988 }\r
1989\r
1990 FreePool (Info);\r
1991 return EFI_SUCCESS;\r
1992}\r
1993\r
1994\r
1995/**\r
1996 Add a credenetial provider item in form.\r
1997\r
1998 @param[in] ProviderGuid Points to the identifir of credential provider.\r
1999 @param[in] OpCodeHandle Points to container for dynamic created opcodes.\r
2000\r
2001**/\r
2002VOID\r
2003AddProviderSelection (\r
2004 IN EFI_GUID *ProviderGuid,\r
2005 IN VOID *OpCodeHandle\r
2006 )\r
2007{\r
2008 EFI_HII_HANDLE HiiHandle;\r
2009 EFI_STRING_ID ProvID;\r
2010 CHAR16 *ProvStr;\r
2011 UINTN Index;\r
2012 EFI_USER_CREDENTIAL2_PROTOCOL *UserCredential;\r
2013\r
2014 for (Index = 0; Index < mProviderDb->Count; Index++) {\r
2015 UserCredential = mProviderDb->Provider[Index];\r
2016 if (CompareGuid (&UserCredential->Identifier, ProviderGuid)) {\r
2017 //\r
2018 // Add credential provider selection.\r
2019 //\r
2020 UserCredential->Title (UserCredential, &HiiHandle, &ProvID);\r
2021 ProvStr = HiiGetString (HiiHandle, ProvID, NULL);\r
2022 if (ProvStr == NULL) {\r
2023 continue ;\r
2024 }\r
2025 ProvID = HiiSetString (mCallbackInfo->HiiHandle, 0, ProvStr, NULL);\r
2026 FreePool (ProvStr);\r
2027 HiiCreateActionOpCode (\r
2028 OpCodeHandle, // Container for dynamic created opcodes\r
2029 (EFI_QUESTION_ID)(LABEL_PROVIDER_NAME + Index), // Question ID\r
2030 ProvID, // Prompt text\r
2031 STRING_TOKEN (STR_NULL_STRING), // Help text\r
2032 EFI_IFR_FLAG_CALLBACK, // Question flag\r
2033 0 // Action String ID\r
2034 );\r
2035 break;\r
2036 }\r
2037 }\r
2038}\r
2039\r
2040\r
2041/**\r
2042 Add a username item in form.\r
2043\r
2044 @param[in] Index The index of the user in the user name list.\r
2045 @param[in] User Points to the user profile whose username is added. \r
2046 @param[in] OpCodeHandle Points to container for dynamic created opcodes.\r
2047\r
2048 @retval EFI_SUCCESS Add a username successfully.\r
2049 @retval Others Fail to add a username.\r
2050\r
2051**/\r
2052EFI_STATUS\r
2053AddUserSelection (\r
2054 IN UINT16 Index,\r
2055 IN USER_PROFILE_ENTRY *User,\r
2056 IN VOID *OpCodeHandle\r
2057 )\r
2058{\r
2059 EFI_STRING_ID UserName;\r
2060 EFI_STATUS Status;\r
2061 EFI_USER_INFO *UserInfo;\r
2062\r
2063 UserInfo = NULL;\r
2064 Status = FindUserInfoByType (User, &UserInfo, EFI_USER_INFO_NAME_RECORD);\r
2065 if (EFI_ERROR (Status)) {\r
2066 return Status;\r
2067 }\r
2068 \r
2069 //\r
2070 // Add user name selection.\r
2071 //\r
2072 UserName = HiiSetString (mCallbackInfo->HiiHandle, 0, (EFI_STRING) (UserInfo + 1), NULL);\r
2073 if (UserName == 0) {\r
2074 return EFI_OUT_OF_RESOURCES;\r
2075 }\r
2076\r
2077 HiiCreateGotoOpCode (\r
2078 OpCodeHandle, // Container for dynamic created opcodes\r
2079 FORMID_PROVIDER_FORM, // Target Form ID\r
2080 UserName, // Prompt text\r
2081 STRING_TOKEN (STR_NULL_STRING), // Help text\r
2082 EFI_IFR_FLAG_CALLBACK, // Question flag\r
2083 (UINT16) Index // Question ID\r
2084 );\r
2085\r
2086 return EFI_SUCCESS;\r
2087}\r
2088\r
2089\r
2090/**\r
2091 Identify the user whose identity policy does not contain the operator 'OR'.\r
2092 \r
2093 @param[in] User Points to the user profile.\r
2094\r
2095 @retval EFI_SUCCESS The specified user is identified successfully.\r
2096 @retval Others Fail to identify the user.\r
2097 \r
2098**/\r
2099EFI_STATUS\r
2100IdentifyAndTypeUser (\r
2101 IN USER_PROFILE_ENTRY *User\r
2102 )\r
2103{\r
2104 EFI_STATUS Status;\r
2105 EFI_USER_INFO *IdentifyInfo;\r
2106 BOOLEAN Success;\r
2107 UINTN TotalLen;\r
2108 UINTN ValueLen;\r
2109 EFI_USER_INFO_IDENTITY_POLICY *Identity;\r
2110\r
2111 //\r
2112 // Get user identify policy information.\r
2113 //\r
2114 IdentifyInfo = NULL;\r
2115 Status = FindUserInfoByType (User, &IdentifyInfo, EFI_USER_INFO_IDENTITY_POLICY_RECORD);\r
2116 if (EFI_ERROR (Status)) {\r
2117 return Status;\r
2118 }\r
2119 ASSERT (IdentifyInfo != NULL);\r
2120 \r
2121 //\r
2122 // Check each part of identification policy expression.\r
2123 //\r
2124 Success = FALSE;\r
2125 TotalLen = 0;\r
2126 while (TotalLen < IdentifyInfo->InfoSize - sizeof (EFI_USER_INFO)) {\r
2127 Identity = (EFI_USER_INFO_IDENTITY_POLICY *) ((UINT8 *) (IdentifyInfo + 1) + TotalLen);\r
2128 ValueLen = Identity->Length - sizeof (EFI_USER_INFO_IDENTITY_POLICY);\r
2129 switch (Identity->Type) {\r
2130\r
2131 case EFI_USER_INFO_IDENTITY_FALSE:\r
2132 //\r
2133 // Check False option.\r
2134 //\r
2135 Success = FALSE;\r
2136 break;\r
2137\r
2138 case EFI_USER_INFO_IDENTITY_TRUE:\r
2139 //\r
2140 // Check True option.\r
2141 //\r
2142 Success = TRUE;\r
2143 break;\r
2144\r
2145 case EFI_USER_INFO_IDENTITY_NOT:\r
2146 //\r
2147 // Check negative operation.\r
2148 //\r
2149 break;\r
2150\r
2151 case EFI_USER_INFO_IDENTITY_AND:\r
2152 //\r
2153 // Check and operation.\r
2154 //\r
2155 if (!Success) {\r
2156 return EFI_NOT_READY;\r
2157 }\r
2158\r
2159 Success = FALSE;\r
2160 break;\r
2161\r
2162 case EFI_USER_INFO_IDENTITY_OR:\r
2163 //\r
2164 // Check or operation.\r
2165 //\r
2166 if (Success) {\r
2167 return EFI_SUCCESS;\r
2168 }\r
2169 break;\r
2170\r
2171 case EFI_USER_INFO_IDENTITY_CREDENTIAL_TYPE:\r
2172 //\r
2173 // Check credential provider by type.\r
2174 //\r
2175 break;\r
2176\r
2177 case EFI_USER_INFO_IDENTITY_CREDENTIAL_PROVIDER:\r
2178 //\r
2179 // Check credential provider by ID.\r
2180 //\r
2181 if (ValueLen != sizeof (EFI_GUID)) {\r
2182 return EFI_INVALID_PARAMETER;\r
2183 }\r
2184\r
2185 Status = IdentifyByProviderId (User, (EFI_GUID *) (Identity + 1));\r
2186 if (EFI_ERROR (Status)) {\r
2187 return Status;\r
2188 }\r
2189\r
2190 Success = TRUE;\r
2191 break;\r
2192\r
2193 default:\r
2194 return EFI_INVALID_PARAMETER;\r
2195 break;\r
2196 }\r
2197\r
2198 TotalLen += Identity->Length;\r
2199 }\r
2200\r
2201 if (TotalLen != IdentifyInfo->InfoSize - sizeof (EFI_USER_INFO)) {\r
2202 return EFI_INVALID_PARAMETER;\r
2203 }\r
2204\r
2205 if (!Success) {\r
2206 return EFI_NOT_READY;\r
2207 }\r
2208\r
2209 return EFI_SUCCESS;\r
2210}\r
2211\r
2212\r
2213/**\r
2214 Identify the user whose identity policy does not contain the operator 'AND'.\r
2215 \r
2216 @param[in] User Points to the user profile.\r
2217\r
2218 @retval EFI_SUCCESS The specified user is identified successfully.\r
2219 @retval Others Fail to identify the user.\r
2220 \r
2221**/\r
2222EFI_STATUS\r
2223IdentifyOrTypeUser (\r
2224 IN USER_PROFILE_ENTRY *User\r
2225 )\r
2226{\r
2227 EFI_STATUS Status;\r
2228 EFI_USER_INFO *IdentifyInfo;\r
2229 UINTN TotalLen;\r
2230 UINTN ValueLen;\r
2231 EFI_USER_INFO_IDENTITY_POLICY *Identity;\r
2232 VOID *StartOpCodeHandle;\r
2233 VOID *EndOpCodeHandle;\r
2234 EFI_IFR_GUID_LABEL *StartLabel;\r
2235 EFI_IFR_GUID_LABEL *EndLabel;\r
2236\r
2237 //\r
2238 // Get user identify policy information.\r
2239 //\r
2240 IdentifyInfo = NULL;\r
2241 Status = FindUserInfoByType (User, &IdentifyInfo, EFI_USER_INFO_IDENTITY_POLICY_RECORD);\r
2242 if (EFI_ERROR (Status)) {\r
2243 return Status;\r
2244 }\r
2245 ASSERT (IdentifyInfo != NULL);\r
2246 \r
2247 //\r
2248 // Initialize the container for dynamic opcodes.\r
2249 //\r
2250 StartOpCodeHandle = HiiAllocateOpCodeHandle ();\r
2251 ASSERT (StartOpCodeHandle != NULL);\r
2252\r
2253 EndOpCodeHandle = HiiAllocateOpCodeHandle ();\r
2254 ASSERT (EndOpCodeHandle != NULL);\r
2255\r
2256 //\r
2257 // Create Hii Extend Label OpCode.\r
2258 //\r
2259 StartLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (\r
2260 StartOpCodeHandle,\r
2261 &gEfiIfrTianoGuid,\r
2262 NULL,\r
2263 sizeof (EFI_IFR_GUID_LABEL)\r
2264 );\r
2265 StartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;\r
2266 StartLabel->Number = LABEL_PROVIDER_NAME;\r
2267\r
2268 EndLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (\r
2269 EndOpCodeHandle,\r
2270 &gEfiIfrTianoGuid,\r
2271 NULL,\r
2272 sizeof (EFI_IFR_GUID_LABEL)\r
2273 );\r
2274 EndLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;\r
2275 EndLabel->Number = LABEL_END;\r
2276\r
2277 //\r
2278 // Add the providers that exists in the user's policy.\r
2279 //\r
2280 TotalLen = 0;\r
2281 while (TotalLen < IdentifyInfo->InfoSize - sizeof (EFI_USER_INFO)) {\r
2282 Identity = (EFI_USER_INFO_IDENTITY_POLICY *) ((UINT8 *) (IdentifyInfo + 1) + TotalLen);\r
2283 ValueLen = Identity->Length - sizeof (EFI_USER_INFO_IDENTITY_POLICY);\r
2284 if (Identity->Type == EFI_USER_INFO_IDENTITY_CREDENTIAL_PROVIDER) {\r
2285 AddProviderSelection ((EFI_GUID *) (Identity + 1), StartOpCodeHandle);\r
2286 }\r
2287\r
2288 TotalLen += Identity->Length;\r
2289 }\r
2290\r
2291 HiiUpdateForm (\r
2292 mCallbackInfo->HiiHandle, // HII handle\r
2293 &gUserIdentifyManagerGuid,// Formset GUID\r
2294 FORMID_PROVIDER_FORM, // Form ID\r
2295 StartOpCodeHandle, // Label for where to insert opcodes\r
2296 EndOpCodeHandle // Replace data\r
2297 );\r
2298\r
2299 HiiFreeOpCodeHandle (StartOpCodeHandle);\r
2300 HiiFreeOpCodeHandle (EndOpCodeHandle);\r
2301\r
2302 return EFI_SUCCESS;\r
2303}\r
2304\r
2305\r
2306/**\r
2307 This function processes the results of changes in configuration.\r
2308\r
2309 @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.\r
2310 @param Action Specifies the type of action taken by the browser.\r
2311 @param QuestionId A unique value which is sent to the original\r
2312 exporting driver so that it can identify the type\r
2313 of data to expect.\r
2314 @param Type The type of value for the question.\r
2315 @param Value A pointer to the data being sent to the original\r
2316 exporting driver.\r
2317 @param ActionRequest On return, points to the action requested by the\r
2318 callback function.\r
2319\r
2320 @retval EFI_SUCCESS The callback successfully handled the action.\r
2321 @retval Others Fail to handle the action.\r
2322\r
2323**/\r
2324EFI_STATUS\r
2325EFIAPI\r
2326UserIdentifyManagerCallback (\r
2327 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,\r
2328 IN EFI_BROWSER_ACTION Action,\r
2329 IN EFI_QUESTION_ID QuestionId,\r
2330 IN UINT8 Type,\r
2331 IN EFI_IFR_TYPE_VALUE *Value,\r
2332 OUT EFI_BROWSER_ACTION_REQUEST *ActionRequest\r
2333 )\r
2334{\r
2335 EFI_STATUS Status;\r
2336 USER_PROFILE_ENTRY *User;\r
2337 UINT8 PolicyType;\r
2338 UINT16 Index;\r
2339 VOID *StartOpCodeHandle;\r
2340 VOID *EndOpCodeHandle;\r
2341 EFI_IFR_GUID_LABEL *StartLabel;\r
2342 EFI_IFR_GUID_LABEL *EndLabel;\r
2343\r
2344 Status = EFI_SUCCESS;\r
2345\r
2346 switch (Action) {\r
2347 case EFI_BROWSER_ACTION_FORM_OPEN:\r
2348 {\r
2349 //\r
2350 // Update user Form when user Form is opened.\r
2351 // This will be done only in FORM_OPEN CallBack of question with FORM_OPEN_QUESTION_ID from user Form.\r
2352 //\r
2353 if (QuestionId != FORM_OPEN_QUESTION_ID) {\r
2354 return EFI_SUCCESS;\r
2355 }\r
2356 \r
2357 //\r
2358 // Initialize the container for dynamic opcodes.\r
2359 //\r
2360 StartOpCodeHandle = HiiAllocateOpCodeHandle ();\r
2361 ASSERT (StartOpCodeHandle != NULL);\r
2362 \r
2363 EndOpCodeHandle = HiiAllocateOpCodeHandle ();\r
2364 ASSERT (EndOpCodeHandle != NULL);\r
2365 \r
2366 //\r
2367 // Create Hii Extend Label OpCode.\r
2368 //\r
2369 StartLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (\r
2370 StartOpCodeHandle,\r
2371 &gEfiIfrTianoGuid,\r
2372 NULL,\r
2373 sizeof (EFI_IFR_GUID_LABEL)\r
2374 );\r
2375 StartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;\r
2376 StartLabel->Number = LABEL_USER_NAME;\r
2377 \r
2378 EndLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (\r
2379 EndOpCodeHandle,\r
2380 &gEfiIfrTianoGuid,\r
2381 NULL,\r
2382 sizeof (EFI_IFR_GUID_LABEL)\r
2383 );\r
2384 EndLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;\r
2385 EndLabel->Number = LABEL_END;\r
2386 \r
2387 //\r
2388 // Add all the user profile in the user profile database.\r
2389 //\r
2390 for (Index = 0; Index < mUserProfileDb->UserProfileNum; Index++) {\r
2391 User = (USER_PROFILE_ENTRY *) mUserProfileDb->UserProfile[Index];\r
2392 AddUserSelection ((UINT16)(LABEL_USER_NAME + Index), User, StartOpCodeHandle);\r
2393 }\r
2394 \r
2395 HiiUpdateForm (\r
2396 mCallbackInfo->HiiHandle, // HII handle\r
2397 &gUserIdentifyManagerGuid,// Formset GUID\r
2398 FORMID_USER_FORM, // Form ID\r
2399 StartOpCodeHandle, // Label for where to insert opcodes\r
2400 EndOpCodeHandle // Replace data\r
2401 );\r
2402 \r
2403 HiiFreeOpCodeHandle (StartOpCodeHandle);\r
2404 HiiFreeOpCodeHandle (EndOpCodeHandle);\r
2405 \r
2406 return EFI_SUCCESS;\r
2407 }\r
2408 break;\r
2409\r
2410 case EFI_BROWSER_ACTION_FORM_CLOSE:\r
2411 Status = EFI_SUCCESS;\r
2412 break;\r
2413\r
2414 case EFI_BROWSER_ACTION_CHANGED:\r
2415 if (QuestionId >= LABEL_PROVIDER_NAME) {\r
2416 //\r
2417 // QuestionId comes from the second Form (Select a Credential Provider if identity \r
2418 // policy is OR type). Identify the user by the selected provider.\r
2419 //\r
2420 Status = IdentifyByProviderId (mCurrentUser, &mProviderDb->Provider[QuestionId & 0xFFF]->Identifier);\r
2421 if (Status == EFI_SUCCESS) {\r
2422 mIdentified = TRUE;\r
2423 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_EXIT;\r
2424 }\r
2425 return EFI_SUCCESS;\r
2426 }\r
2427 break;\r
2428 \r
2429 case EFI_BROWSER_ACTION_CHANGING:\r
2430 //\r
2431 // QuestionId comes from the first Form (Select a user to identify).\r
2432 //\r
2433 if (QuestionId >= LABEL_PROVIDER_NAME) {\r
2434 return EFI_SUCCESS;\r
2435 }\r
2436\r
2437 User = (USER_PROFILE_ENTRY *) mUserProfileDb->UserProfile[QuestionId & 0xFFF];\r
2438 Status = GetIdentifyType (User, &PolicyType);\r
2439 if (EFI_ERROR (Status)) {\r
2440 return Status;\r
2441 }\r
2442\r
2443 if (PolicyType == EFI_USER_INFO_IDENTITY_OR) {\r
2444 //\r
2445 // Identify the user by "OR" logical.\r
2446 //\r
2447 Status = IdentifyOrTypeUser (User);\r
2448 if (EFI_ERROR (Status)) {\r
2449 return Status;\r
2450 }\r
2451\r
2452 mCurrentUser = (EFI_USER_PROFILE_HANDLE) User;\r
2453 } else {\r
2454 //\r
2455 // Identify the user by "AND" logical.\r
2456 //\r
2457 Status = IdentifyAndTypeUser (User);\r
2458 if (EFI_ERROR (Status)) {\r
2459 return Status;\r
2460 }\r
2461\r
2462 mCurrentUser = (EFI_USER_PROFILE_HANDLE) User;\r
2463 mIdentified = TRUE;\r
2464 if (Type == EFI_IFR_TYPE_REF) {\r
2465 Value->ref.FormId = FORMID_INVALID_FORM;\r
2466 }\r
2467 }\r
2468 break;\r
2469\r
2470 default:\r
2471 //\r
2472 // All other action return unsupported.\r
2473 //\r
2474 Status = EFI_UNSUPPORTED;\r
2475 break;\r
2476 }\r
2477\r
2478\r
2479 return Status;\r
2480}\r
2481\r
2482\r
2483/**\r
2484 This function construct user profile database from user data saved in the Flash.\r
2485 If no user is found in Flash, add one default user "administrator" in the user \r
2486 profile database.\r
2487\r
2488 @retval EFI_SUCCESS Init user profile database successfully.\r
2489 @retval Others Fail to init user profile database.\r
2490 \r
2491**/\r
2492EFI_STATUS\r
2493InitUserProfileDb (\r
2494 VOID\r
2495 )\r
2496{\r
2497 EFI_STATUS Status;\r
2498 UINT8 *VarData;\r
2499 UINTN VarSize;\r
2500 UINTN CurVarSize;\r
2501 CHAR16 VarName[10];\r
2502 UINTN Index;\r
2503 UINT32 VarAttr;\r
2504\r
2505 if (mUserProfileDb != NULL) {\r
2506 //\r
2507 // The user profiles had been already initialized.\r
2508 //\r
2509 return EFI_SUCCESS;\r
2510 }\r
2511\r
2512 //\r
2513 // Init user profile database structure.\r
2514 //\r
2515 if (!ExpandUsermUserProfileDb ()) {\r
2516 return EFI_OUT_OF_RESOURCES;\r
2517 }\r
2518\r
2519 CurVarSize = DEFAULT_PROFILE_SIZE;\r
2520 VarData = AllocateZeroPool (CurVarSize);\r
2521 if (VarData == NULL) {\r
2522 return EFI_OUT_OF_RESOURCES;\r
2523 }\r
2524 \r
2525 //\r
2526 // Get all user proifle entries.\r
2527 //\r
2528 Index = 0;\r
2529 while (TRUE) {\r
2530 //\r
2531 // Get variable name.\r
2532 //\r
2533 UnicodeSPrint (\r
2534 VarName, \r
2535 sizeof (VarName),\r
2536 L"User%04x", \r
2537 Index\r
2538 );\r
2539 Index++;\r
2540\r
2541 //\r
2542 // Get variable value.\r
2543 //\r
2544 VarSize = CurVarSize;\r
2545 Status = gRT->GetVariable (VarName, &gUserIdentifyManagerGuid, &VarAttr, &VarSize, VarData);\r
2546 if (Status == EFI_BUFFER_TOO_SMALL) {\r
2547 FreePool (VarData);\r
2548 VarData = AllocatePool (VarSize);\r
2549 if (VarData == NULL) {\r
2550 Status = EFI_OUT_OF_RESOURCES;\r
2551 break;\r
2552 }\r
2553\r
2554 CurVarSize = VarSize;\r
2555 Status = gRT->GetVariable (VarName, &gUserIdentifyManagerGuid, &VarAttr, &VarSize, VarData);\r
2556 }\r
2557\r
2558 if (EFI_ERROR (Status)) {\r
2559 if (Status == EFI_NOT_FOUND) {\r
2560 Status = EFI_SUCCESS;\r
2561 }\r
2562 break;\r
2563 }\r
2564 \r
2565 //\r
2566 // Check variable attributes.\r
2567 //\r
2568 if (VarAttr != (EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS)) {\r
2569 Status = gRT->SetVariable (VarName, &gUserIdentifyManagerGuid, VarAttr, 0, NULL);\r
2570 continue;\r
2571 }\r
2572 \r
2573 //\r
2574 // Add user profile to the user profile database.\r
2575 //\r
2576 Status = AddUserProfile (NULL, VarSize, VarData, FALSE);\r
2577 if (EFI_ERROR (Status)) {\r
2578 if (Status == EFI_SECURITY_VIOLATION) {\r
2579 //\r
2580 // Delete invalid user profile\r
2581 //\r
2582 gRT->SetVariable (VarName, &gUserIdentifyManagerGuid, VarAttr, 0, NULL);\r
2583 } else if (Status == EFI_OUT_OF_RESOURCES) {\r
2584 break;\r
2585 }\r
2586 } else {\r
2587 //\r
2588 // Delete and save the profile again if some invalid profiles are deleted.\r
2589 //\r
2590 if (mUserProfileDb->UserProfileNum < Index) {\r
2591 gRT->SetVariable (VarName, &gUserIdentifyManagerGuid, VarAttr, 0, NULL);\r
2592 SaveNvUserProfile (mUserProfileDb->UserProfile[mUserProfileDb->UserProfileNum - 1], FALSE);\r
2593 }\r
2594 }\r
2595 }\r
2596\r
2597 if (VarData != NULL) {\r
2598 FreePool (VarData);\r
2599 }\r
2600\r
2601 if (EFI_ERROR (Status)) {\r
2602 return Status;\r
2603 }\r
2604 \r
2605 //\r
2606 // Check whether the user profile database is empty.\r
2607 //\r
2608 if (mUserProfileDb->UserProfileNum == 0) {\r
2609 Status = AddDefaultUserProfile ();\r
2610 }\r
2611\r
2612 return Status;\r
2613}\r
2614\r
2615\r
2616/**\r
2617 This function collects all the credential providers and saves to mProviderDb.\r
2618\r
2619 @retval EFI_SUCCESS Collect credential providers successfully.\r
2620 @retval Others Fail to collect credential providers.\r
2621\r
2622**/\r
2623EFI_STATUS\r
2624InitProviderInfo (\r
2625 VOID\r
2626 )\r
2627{\r
2628 EFI_STATUS Status;\r
2629 UINTN HandleCount;\r
2630 EFI_HANDLE *HandleBuf;\r
2631 UINTN Index; \r
2632\r
2633 if (mProviderDb != NULL) {\r
2634 //\r
2635 // The credential providers had been collected before.\r
2636 //\r
2637 return EFI_SUCCESS;\r
2638 }\r
2639\r
2640 //\r
2641 // Try to find all the user credential provider driver.\r
2642 //\r
2643 HandleCount = 0;\r
2644 HandleBuf = NULL;\r
2645 Status = gBS->LocateHandleBuffer (\r
2646 ByProtocol,\r
2647 &gEfiUserCredential2ProtocolGuid,\r
2648 NULL,\r
2649 &HandleCount,\r
2650 &HandleBuf\r
2651 );\r
2652 if (EFI_ERROR (Status)) {\r
2653 return Status;\r
2654 }\r
2655\r
2656 //\r
2657 // Get provider infomation.\r
2658 //\r
2659 mProviderDb = AllocateZeroPool (\r
2660 sizeof (CREDENTIAL_PROVIDER_INFO) - \r
2661 sizeof (EFI_USER_CREDENTIAL2_PROTOCOL *) + \r
2662 HandleCount * sizeof (EFI_USER_CREDENTIAL2_PROTOCOL *)\r
2663 );\r
2664 if (mProviderDb == NULL) {\r
2665 FreePool (HandleBuf);\r
2666 return EFI_OUT_OF_RESOURCES;\r
2667 }\r
2668\r
2669 mProviderDb->Count = HandleCount;\r
2670 for (Index = 0; Index < HandleCount; Index++) {\r
2671 Status = gBS->HandleProtocol (\r
2672 HandleBuf[Index],\r
2673 &gEfiUserCredential2ProtocolGuid,\r
2674 (VOID **) &mProviderDb->Provider[Index]\r
2675 );\r
2676 if (EFI_ERROR (Status)) {\r
2677 FreePool (HandleBuf);\r
2678 FreePool (mProviderDb);\r
2679 mProviderDb = NULL;\r
2680 return Status;\r
2681 }\r
2682 }\r
2683\r
2684 FreePool (HandleBuf);\r
2685 return EFI_SUCCESS;\r
2686}\r
2687\r
2688\r
2689/**\r
2690 This function allows a caller to extract the current configuration for one\r
2691 or more named elements from the target driver.\r
2692\r
2693\r
2694 @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.\r
2695 @param Request A null-terminated Unicode string in <ConfigRequest> format.\r
2696 @param Progress On return, points to a character in the Request string.\r
2697 Points to the string's null terminator if request was successful.\r
2698 Points to the most recent '&' before the first failing name/value\r
2699 pair (or the beginning of the string if the failure is in the\r
2700 first name/value pair) if the request was not successful.\r
2701 @param Results A null-terminated Unicode string in <ConfigAltResp> format which\r
2702 has all values filled in for the names in the Request string.\r
2703 String to be allocated by the called function.\r
2704\r
2705 @retval EFI_SUCCESS The Results is filled with the requested values.\r
2706 @retval EFI_OUT_OF_RESOURCES Not enough memory to store the results.\r
2707 @retval EFI_INVALID_PARAMETER Request is illegal syntax, or unknown name.\r
2708 @retval EFI_NOT_FOUND Routing data doesn't match any storage in this driver.\r
2709\r
2710**/\r
2711EFI_STATUS\r
2712EFIAPI\r
2713FakeExtractConfig (\r
2714 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,\r
2715 IN CONST EFI_STRING Request,\r
2716 OUT EFI_STRING *Progress,\r
2717 OUT EFI_STRING *Results\r
2718 )\r
2719{\r
2720 if (Progress == NULL || Results == NULL) {\r
2721 return EFI_INVALID_PARAMETER;\r
2722 }\r
2723 *Progress = Request;\r
2724 return EFI_NOT_FOUND;\r
2725}\r
2726\r
2727/**\r
2728 This function processes the results of changes in configuration.\r
2729\r
2730\r
2731 @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.\r
2732 @param Configuration A null-terminated Unicode string in <ConfigResp> format.\r
2733 @param Progress A pointer to a string filled in with the offset of the most\r
2734 recent '&' before the first failing name/value pair (or the\r
2735 beginning of the string if the failure is in the first\r
2736 name/value pair) or the terminating NULL if all was successful.\r
2737\r
2738 @retval EFI_SUCCESS The Results is processed successfully.\r
2739 @retval EFI_INVALID_PARAMETER Configuration is NULL.\r
2740 @retval EFI_NOT_FOUND Routing data doesn't match any storage in this driver.\r
2741\r
2742**/\r
2743EFI_STATUS\r
2744EFIAPI\r
2745FakeRouteConfig (\r
2746 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,\r
2747 IN CONST EFI_STRING Configuration,\r
2748 OUT EFI_STRING *Progress\r
2749 )\r
2750{\r
2751 if (Configuration == NULL || Progress == NULL) {\r
2752 return EFI_INVALID_PARAMETER;\r
2753 }\r
2754\r
2755 return EFI_NOT_FOUND;\r
2756}\r
2757\r
2758\r
2759/**\r
2760 This function initialize the data mainly used in form browser.\r
2761\r
2762 @retval EFI_SUCCESS Initialize form data successfully.\r
2763 @retval Others Fail to Initialize form data.\r
2764\r
2765**/\r
2766EFI_STATUS\r
2767InitFormBrowser (\r
2768 VOID\r
2769 )\r
2770{\r
2771 EFI_STATUS Status;\r
2772 USER_MANAGER_CALLBACK_INFO *CallbackInfo;\r
2773 EFI_HII_DATABASE_PROTOCOL *HiiDatabase;\r
2774 EFI_HII_STRING_PROTOCOL *HiiString;\r
2775 EFI_FORM_BROWSER2_PROTOCOL *FormBrowser2;\r
2776\r
2777 //\r
2778 // Initialize driver private data.\r
2779 //\r
2780 CallbackInfo = AllocateZeroPool (sizeof (USER_MANAGER_CALLBACK_INFO));\r
2781 if (CallbackInfo == NULL) {\r
2782 return EFI_OUT_OF_RESOURCES;\r
2783 }\r
2784\r
2785 CallbackInfo->Signature = USER_MANAGER_SIGNATURE;\r
2786 CallbackInfo->ConfigAccess.ExtractConfig = FakeExtractConfig;\r
2787 CallbackInfo->ConfigAccess.RouteConfig = FakeRouteConfig;\r
2788 CallbackInfo->ConfigAccess.Callback = UserIdentifyManagerCallback;\r
2789\r
2790 //\r
2791 // Locate Hii Database protocol.\r
2792 //\r
2793 Status = gBS->LocateProtocol (&gEfiHiiDatabaseProtocolGuid, NULL, (VOID **) &HiiDatabase);\r
2794 if (EFI_ERROR (Status)) {\r
2795 return Status;\r
2796 }\r
2797 CallbackInfo->HiiDatabase = HiiDatabase;\r
2798\r
2799 //\r
2800 // Locate HiiString protocol.\r
2801 //\r
2802 Status = gBS->LocateProtocol (&gEfiHiiStringProtocolGuid, NULL, (VOID **) &HiiString);\r
2803 if (EFI_ERROR (Status)) {\r
2804 return Status;\r
2805 }\r
2806 CallbackInfo->HiiString = HiiString;\r
2807\r
2808 //\r
2809 // Locate Formbrowser2 protocol.\r
2810 //\r
2811 Status = gBS->LocateProtocol (&gEfiFormBrowser2ProtocolGuid, NULL, (VOID **) &FormBrowser2);\r
2812 if (EFI_ERROR (Status)) {\r
2813 return Status;\r
2814 }\r
2815\r
2816 CallbackInfo->FormBrowser2 = FormBrowser2;\r
2817 CallbackInfo->DriverHandle = NULL;\r
2818 \r
2819 //\r
2820 // Install Device Path Protocol and Config Access protocol to driver handle.\r
2821 //\r
2822 Status = gBS->InstallMultipleProtocolInterfaces (\r
2823 &CallbackInfo->DriverHandle,\r
2824 &gEfiDevicePathProtocolGuid,\r
2825 &mHiiVendorDevicePath,\r
2826 &gEfiHiiConfigAccessProtocolGuid,\r
2827 &CallbackInfo->ConfigAccess,\r
2828 NULL\r
2829 );\r
2830 ASSERT_EFI_ERROR (Status);\r
2831\r
2832 //\r
2833 // Publish HII data.\r
2834 //\r
2835 CallbackInfo->HiiHandle = HiiAddPackages (\r
2836 &gUserIdentifyManagerGuid,\r
2837 CallbackInfo->DriverHandle,\r
2838 UserIdentifyManagerStrings,\r
2839 UserIdentifyManagerVfrBin,\r
2840 NULL\r
2841 );\r
2842 if (CallbackInfo->HiiHandle == NULL) {\r
2843 return EFI_OUT_OF_RESOURCES;\r
2844 }\r
2845\r
2846 mCallbackInfo = CallbackInfo;\r
2847\r
2848 return EFI_SUCCESS;\r
2849}\r
2850\r
2851\r
2852/**\r
2853 Identify the user whose identification policy supports auto logon.\r
2854\r
2855 @param[in] ProviderIndex The provider index in the provider list.\r
2856 @param[out] User Points to user user profile if a user is identified successfully.\r
2857\r
2858 @retval EFI_SUCCESS Identify a user with the specified provider successfully.\r
2859 @retval Others Fail to identify a user.\r
2860\r
2861**/\r
2862EFI_STATUS\r
2863IdentifyAutoLogonUser (\r
2864 IN UINTN ProviderIndex,\r
2865 OUT USER_PROFILE_ENTRY **User\r
2866 )\r
2867{\r
2868 EFI_STATUS Status;\r
2869 EFI_USER_INFO *Info;\r
2870 UINT8 PolicyType;\r
2871\r
2872 Info = AllocateZeroPool (sizeof (EFI_USER_INFO) + sizeof (EFI_USER_INFO_IDENTIFIER));\r
2873 if (Info == NULL) {\r
2874 return EFI_OUT_OF_RESOURCES;\r
2875 }\r
2876\r
2877 Info->InfoType = EFI_USER_INFO_IDENTIFIER_RECORD;\r
2878 Info->InfoSize = sizeof (EFI_USER_INFO) + sizeof (EFI_USER_INFO_IDENTIFIER);\r
2879\r
2880 //\r
2881 // Identify the specified credential provider's auto logon user.\r
2882 //\r
2883 Status = mProviderDb->Provider[ProviderIndex]->User (\r
2884 mProviderDb->Provider[ProviderIndex],\r
2885 NULL,\r
2886 (EFI_USER_INFO_IDENTIFIER *) (Info + 1)\r
2887 );\r
2888 if (EFI_ERROR (Status)) {\r
2889 FreePool (Info);\r
2890 return Status;\r
2891 }\r
2892 \r
2893 //\r
2894 // Find user with the specified user ID.\r
2895 //\r
2896 *User = NULL;\r
2897 Status = FindUserProfileByInfo (User, NULL, Info, Info->InfoSize);\r
2898 FreePool (Info);\r
2899 if (EFI_ERROR (Status)) {\r
2900 return Status;\r
2901 }\r
2902\r
2903 Status = GetIdentifyType ((EFI_USER_PROFILE_HANDLE) * User, &PolicyType);\r
2904 if (PolicyType == EFI_USER_INFO_IDENTITY_AND) {\r
2905 //\r
2906 // The identified user need also identified by other credential provider.\r
2907 // This can handle through select user.\r
2908 //\r
2909 return EFI_NOT_READY;\r
2910 }\r
2911 \r
2912 return Status;\r
2913}\r
2914\r
2915\r
2916/**\r
2917 Check whether the given console is ready.\r
2918\r
2919 @param[in] ProtocolGuid Points to the protocol guid of sonsole .\r
2920 \r
2921 @retval TRUE The given console is ready.\r
2922 @retval FALSE The given console is not ready.\r
2923 \r
2924**/\r
2925BOOLEAN\r
2926CheckConsole (\r
2927 EFI_GUID *ProtocolGuid \r
2928 )\r
2929{\r
2930 EFI_STATUS Status;\r
2931 UINTN HandleCount;\r
2932 EFI_HANDLE *HandleBuf;\r
2933 UINTN Index; \r
2934 EFI_DEVICE_PATH_PROTOCOL *DevicePath;\r
2935 \r
2936 //\r
2937 // Try to find all the handle driver.\r
2938 //\r
2939 HandleCount = 0;\r
2940 HandleBuf = NULL;\r
2941 Status = gBS->LocateHandleBuffer (\r
2942 ByProtocol,\r
2943 ProtocolGuid,\r
2944 NULL,\r
2945 &HandleCount,\r
2946 &HandleBuf\r
2947 );\r
2948 if (EFI_ERROR (Status)) {\r
2949 return FALSE;\r
2950 }\r
2951\r
2952 for (Index = 0; Index < HandleCount; Index++) {\r
2953 DevicePath = DevicePathFromHandle (HandleBuf[Index]);\r
2954 if (DevicePath != NULL) {\r
2955 FreePool (HandleBuf);\r
2956 return TRUE;\r
2957 }\r
2958 }\r
2959 FreePool (HandleBuf); \r
2960 return FALSE;\r
2961}\r
2962\r
2963\r
2964/**\r
2965 Check whether the console is ready.\r
2966\r
2967 @retval TRUE The console is ready.\r
2968 @retval FALSE The console is not ready.\r
2969 \r
2970**/\r
2971BOOLEAN\r
2972IsConsoleReady (\r
2973 VOID\r
2974 )\r
2975{\r
2976 if (!CheckConsole (&gEfiSimpleTextOutProtocolGuid)) {\r
2977 return FALSE;\r
2978 }\r
2979\r
2980 if (!CheckConsole (&gEfiSimpleTextInProtocolGuid)) {\r
2981 if (!CheckConsole (&gEfiSimpleTextInputExProtocolGuid)) {\r
2982 return FALSE;\r
2983 }\r
2984 }\r
2985 \r
2986 return TRUE;\r
2987}\r
2988\r
2989\r
2990/**\r
2991 Identify a user to logon.\r
2992\r
2993 @param[out] User Points to user user profile if a user is identified successfully.\r
2994\r
2995 @retval EFI_SUCCESS Identify a user successfully.\r
2996\r
2997**/\r
2998EFI_STATUS\r
2999IdentifyUser (\r
3000 OUT USER_PROFILE_ENTRY **User\r
3001 )\r
3002{\r
3003 EFI_STATUS Status;\r
3004 UINTN Index;\r
3005 EFI_CREDENTIAL_LOGON_FLAGS AutoLogon;\r
3006 EFI_USER_INFO *IdentifyInfo;\r
3007 EFI_USER_INFO_IDENTITY_POLICY *Identity;\r
3008 EFI_USER_CREDENTIAL2_PROTOCOL *UserCredential;\r
3009 USER_PROFILE_ENTRY *UserEntry;\r
3010\r
3011 //\r
3012 // Initialize credential providers.\r
3013 //\r
3014 InitProviderInfo ();\r
3015\r
3016 //\r
3017 // Initialize user profile database.\r
3018 //\r
3019 InitUserProfileDb ();\r
3020\r
3021 //\r
3022 // If only one user in system, and its identify policy is TRUE, then auto logon.\r
3023 //\r
3024 if (mUserProfileDb->UserProfileNum == 1) {\r
3025 UserEntry = (USER_PROFILE_ENTRY *) mUserProfileDb->UserProfile[0];\r
3026 IdentifyInfo = NULL;\r
3027 Status = FindUserInfoByType (UserEntry, &IdentifyInfo, EFI_USER_INFO_IDENTITY_POLICY_RECORD);\r
3028 if (EFI_ERROR (Status)) {\r
3029 return Status;\r
3030 }\r
3031 ASSERT (IdentifyInfo != NULL);\r
3032\r
3033 Identity = (EFI_USER_INFO_IDENTITY_POLICY *) ((UINT8 *) (IdentifyInfo + 1));\r
3034 if (Identity->Type == EFI_USER_INFO_IDENTITY_TRUE) {\r
3035 mCurrentUser = (EFI_USER_PROFILE_HANDLE) UserEntry;\r
3036 UpdateUserInfo (UserEntry);\r
3037 *User = UserEntry;\r
3038 return EFI_SUCCESS;\r
3039 }\r
3040 }\r
3041 \r
3042 //\r
3043 // Find and login the default & AutoLogon user.\r
3044 //\r
3045 for (Index = 0; Index < mProviderDb->Count; Index++) {\r
3046 UserCredential = mProviderDb->Provider[Index];\r
3047 Status = UserCredential->Default (UserCredential, &AutoLogon);\r
3048 if (EFI_ERROR (Status)) {\r
3049 continue;\r
3050 }\r
3051\r
3052 if ((AutoLogon & (EFI_CREDENTIAL_LOGON_FLAG_DEFAULT | EFI_CREDENTIAL_LOGON_FLAG_AUTO)) != 0) {\r
3053 Status = IdentifyAutoLogonUser (Index, &UserEntry);\r
3054 if (Status == EFI_SUCCESS) {\r
3055 mCurrentUser = (EFI_USER_PROFILE_HANDLE) UserEntry;\r
3056 UpdateUserInfo (UserEntry);\r
3057 *User = UserEntry;\r
3058 return EFI_SUCCESS;\r
3059 }\r
3060 }\r
3061 }\r
3062 \r
3063 if (!IsConsoleReady ()) {\r
3064 //\r
3065 // The console is still not ready for user selection.\r
3066 //\r
3067 return EFI_ACCESS_DENIED;\r
3068 }\r
3069\r
3070 //\r
3071 // Select a user and identify it.\r
3072 //\r
3073 mCallbackInfo->FormBrowser2->SendForm (\r
3074 mCallbackInfo->FormBrowser2,\r
3075 &mCallbackInfo->HiiHandle,\r
3076 1,\r
3077 &gUserIdentifyManagerGuid,\r
3078 0,\r
3079 NULL,\r
3080 NULL\r
3081 );\r
3082 \r
3083 if (mIdentified) {\r
3084 *User = (USER_PROFILE_ENTRY *) mCurrentUser;\r
3085 UpdateUserInfo (*User);\r
3086 return EFI_SUCCESS;\r
3087 }\r
3088 \r
3089 return EFI_ACCESS_DENIED;\r
3090}\r
3091\r
3092\r
3093/**\r
3094 An empty function to pass error checking of CreateEventEx ().\r
3095 \r
3096 @param Event Event whose notification function is being invoked.\r
3097 @param Context Pointer to the notification function's context,\r
3098 which is implementation-dependent.\r
3099\r
3100**/\r
3101VOID\r
3102EFIAPI\r
3103InternalEmptyFuntion (\r
3104 IN EFI_EVENT Event,\r
3105 IN VOID *Context\r
3106 )\r
3107{\r
3108}\r
3109\r
3110\r
3111/**\r
3112 Create, Signal, and Close the User Profile Changed event.\r
3113\r
3114**/\r
3115VOID\r
3116SignalEventUserProfileChanged (\r
3117 VOID\r
3118 )\r
3119{\r
3120 EFI_STATUS Status;\r
3121 EFI_EVENT Event;\r
3122\r
3123 Status = gBS->CreateEventEx (\r
3124 EVT_NOTIFY_SIGNAL,\r
3125 TPL_CALLBACK,\r
3126 InternalEmptyFuntion,\r
3127 NULL,\r
3128 &gEfiEventUserProfileChangedGuid,\r
3129 &Event\r
3130 );\r
3131 ASSERT_EFI_ERROR (Status);\r
3132 gBS->SignalEvent (Event);\r
3133 gBS->CloseEvent (Event);\r
3134}\r
3135\r
3136\r
3137/**\r
3138 Create a new user profile.\r
3139\r
3140 This function creates a new user profile with only a new user identifier attached and returns \r
3141 its handle. The user profile is non-volatile, but the handle User can change across reboots.\r
3142\r
3143 @param[in] This Points to this instance of the EFI_USER_MANAGER_PROTOCOL.\r
3144 @param[out] User On return, points to the new user profile handle. \r
3145 The user profile handle is unique only during this boot.\r
3146 \r
3147 @retval EFI_SUCCESS User profile was successfully created.\r
3148 @retval EFI_ACCESS_DENIED Current user does not have sufficient permissions to create a \r
3149 user profile.\r
3150 @retval EFI_UNSUPPORTED Creation of new user profiles is not supported.\r
3151 @retval EFI_INVALID_PARAMETER The User parameter is NULL.\r
3152 \r
3153**/\r
3154EFI_STATUS\r
3155EFIAPI\r
3156UserProfileCreate (\r
3157 IN CONST EFI_USER_MANAGER_PROTOCOL *This,\r
3158 OUT EFI_USER_PROFILE_HANDLE *User\r
3159 )\r
3160{\r
3161 EFI_STATUS Status;\r
3162\r
3163 if ((This == NULL) || (User == NULL)) {\r
3164 return EFI_INVALID_PARAMETER;\r
3165 }\r
3166\r
3167 //\r
3168 // Check the right of the current user.\r
3169 //\r
3170 if (!CheckCurrentUserAccessRight (EFI_USER_INFO_ACCESS_MANAGE)) {\r
3171 if (!CheckCurrentUserAccessRight (EFI_USER_INFO_ACCESS_ENROLL_OTHERS)) {\r
3172 return EFI_ACCESS_DENIED;\r
3173 }\r
3174 }\r
3175 \r
3176 //\r
3177 // Create new user profile\r
3178 //\r
3179 Status = CreateUserProfile ((USER_PROFILE_ENTRY **) User);\r
3180 if (EFI_ERROR (Status)) {\r
3181 return EFI_ACCESS_DENIED;\r
3182 }\r
3183 return EFI_SUCCESS;\r
3184}\r
3185\r
3186\r
3187/**\r
3188 Delete an existing user profile.\r
3189\r
3190 @param[in] This Points to this instance of the EFI_USER_MANAGER_PROTOCOL.\r
3191 @param[in] User User profile handle. \r
3192\r
3193 @retval EFI_SUCCESS User profile was successfully deleted.\r
3194 @retval EFI_ACCESS_DENIED Current user does not have sufficient permissions to delete a user\r
3195 profile or there is only one user profile.\r
3196 @retval EFI_UNSUPPORTED Deletion of new user profiles is not supported.\r
3197 @retval EFI_INVALID_PARAMETER User does not refer to a valid user profile.\r
3198 \r
3199**/\r
3200EFI_STATUS\r
3201EFIAPI\r
3202UserProfileDelete (\r
3203 IN CONST EFI_USER_MANAGER_PROTOCOL *This,\r
3204 IN EFI_USER_PROFILE_HANDLE User\r
3205 )\r
3206{\r
3207 EFI_STATUS Status;\r
3208\r
3209 if (This == NULL) {\r
3210 return EFI_INVALID_PARAMETER;\r
3211 }\r
3212 \r
3213 //\r
3214 // Check the right of the current user.\r
3215 //\r
3216 if (!CheckCurrentUserAccessRight (EFI_USER_INFO_ACCESS_MANAGE)) {\r
3217 return EFI_ACCESS_DENIED;\r
3218 }\r
3219 \r
3220 //\r
3221 // Delete user profile.\r
3222 //\r
3223 Status = DelUserProfile (User);\r
3224 if (EFI_ERROR (Status)) {\r
3225 if (Status != EFI_INVALID_PARAMETER) {\r
3226 return EFI_ACCESS_DENIED;\r
3227 }\r
3228 return EFI_INVALID_PARAMETER;\r
3229 }\r
3230\r
3231 return EFI_SUCCESS;\r
3232}\r
3233\r
3234\r
3235/**\r
3236 Enumerate all of the enrolled users on the platform.\r
3237\r
3238 This function returns the next enrolled user profile. To retrieve the first user profile handle, \r
3239 point User at a NULL. Each subsequent call will retrieve another user profile handle until there \r
3240 are no more, at which point User will point to NULL. \r
3241\r
3242 @param[in] This Points to this instance of the EFI_USER_MANAGER_PROTOCOL.\r
3243 @param[in, out] User On entry, points to the previous user profile handle or NULL to \r
3244 start enumeration. On exit, points to the next user profile handle\r
3245 or NULL if there are no more user profiles.\r
3246\r
3247 @retval EFI_SUCCESS Next enrolled user profile successfully returned. \r
3248 @retval EFI_ACCESS_DENIED Next enrolled user profile was not successfully returned.\r
3249 @retval EFI_INVALID_PARAMETER The User parameter is NULL.\r
3250**/\r
3251EFI_STATUS\r
3252EFIAPI\r
3253UserProfileGetNext (\r
3254 IN CONST EFI_USER_MANAGER_PROTOCOL *This,\r
3255 IN OUT EFI_USER_PROFILE_HANDLE *User\r
3256 )\r
3257{\r
3258 EFI_STATUS Status;\r
3259\r
3260 if ((This == NULL) || (User == NULL)) {\r
3261 return EFI_INVALID_PARAMETER;\r
3262 }\r
3263 \r
3264 Status = FindUserProfile ((USER_PROFILE_ENTRY **) User, TRUE, NULL);\r
3265 if (EFI_ERROR (Status)) {\r
3266 return EFI_ACCESS_DENIED;\r
3267 }\r
3268 return EFI_SUCCESS;\r
3269}\r
3270\r
3271\r
3272/**\r
3273 Return the current user profile handle.\r
3274\r
3275 @param[in] This Points to this instance of the EFI_USER_MANAGER_PROTOCOL.\r
3276 @param[out] CurrentUser On return, points to the current user profile handle.\r
3277\r
3278 @retval EFI_SUCCESS Current user profile handle returned successfully. \r
3279 @retval EFI_INVALID_PARAMETER The CurrentUser parameter is NULL.\r
3280 \r
3281**/\r
3282EFI_STATUS\r
3283EFIAPI\r
3284UserProfileCurrent (\r
3285 IN CONST EFI_USER_MANAGER_PROTOCOL *This,\r
3286 OUT EFI_USER_PROFILE_HANDLE *CurrentUser\r
3287 )\r
3288{ \r
3289 //\r
3290 // Get current user profile.\r
3291 //\r
3292 if ((This == NULL) || (CurrentUser == NULL)) {\r
3293 return EFI_INVALID_PARAMETER;\r
3294 }\r
3295\r
3296 *CurrentUser = mCurrentUser;\r
3297 return EFI_SUCCESS;\r
3298}\r
3299\r
3300\r
3301/**\r
3302 Identify a user.\r
3303\r
3304 Identify the user and, if authenticated, returns the user handle and changes the current\r
3305 user profile. All user information marked as private in a previously selected profile\r
3306 is no longer available for inspection. \r
3307 Whenever the current user profile is changed then the an event with the GUID \r
3308 EFI_EVENT_GROUP_USER_PROFILE_CHANGED is signaled.\r
3309\r
3310 @param[in] This Points to this instance of the EFI_USER_MANAGER_PROTOCOL.\r
3311 @param[out] User On return, points to the user profile handle for the current\r
3312 user profile.\r
3313\r
3314 @retval EFI_SUCCESS User was successfully identified.\r
3315 @retval EFI_ACCESS_DENIED User was not successfully identified.\r
3316 @retval EFI_INVALID_PARAMETER The User parameter is NULL.\r
3317 \r
3318**/\r
3319EFI_STATUS\r
3320EFIAPI\r
3321UserProfileIdentify (\r
3322 IN CONST EFI_USER_MANAGER_PROTOCOL *This,\r
3323 OUT EFI_USER_PROFILE_HANDLE *User\r
3324 )\r
3325{\r
3326 EFI_STATUS Status;\r
3327\r
3328 if ((This == NULL) || (User == NULL)) {\r
3329 return EFI_INVALID_PARAMETER;\r
3330 }\r
3331\r
3332 if (mCurrentUser != NULL) {\r
3333 *User = mCurrentUser;\r
3334 return EFI_SUCCESS;\r
3335 }\r
3336 \r
3337 //\r
3338 // Identify user\r
3339 //\r
3340 Status = IdentifyUser ((USER_PROFILE_ENTRY **) User);\r
3341 if (EFI_ERROR (Status)) {\r
3342 return EFI_ACCESS_DENIED;\r
3343 }\r
3344 \r
3345 //\r
3346 // Publish the user info into the EFI system configuration table.\r
3347 //\r
3348 PublishUserTable ();\r
3349\r
3350 //\r
3351 // Signal User Profile Changed event.\r
3352 //\r
3353 SignalEventUserProfileChanged ();\r
3354 return EFI_SUCCESS;\r
3355}\r
3356\r
3357/**\r
3358 Find a user using a user information record.\r
3359\r
3360 This function searches all user profiles for the specified user information record.\r
3361 The search starts with the user information record handle following UserInfo and \r
3362 continues until either the information is found or there are no more user profiles.\r
3363 A match occurs when the Info.InfoType field matches the user information record\r
3364 type and the user information record data matches the portion of Info.\r
3365\r
3366 @param[in] This Points to this instance of the EFI_USER_MANAGER_PROTOCOL.\r
3367 @param[in, out] User On entry, points to the previously returned user profile \r
3368 handle, or NULL to start searching with the first user profile.\r
3369 On return, points to the user profile handle, or NULL if not\r
3370 found.\r
3371 @param[in, out] UserInfo On entry, points to the previously returned user information\r
3372 handle, or NULL to start searching with the first. On return, \r
3373 points to the user information handle of the user information\r
3374 record, or NULL if not found. Can be NULL, in which case only \r
3375 one user information record per user can be returned. \r
3376 @param[in] Info Points to the buffer containing the user information to be \r
3377 compared to the user information record. If the user information \r
3378 record data is empty, then only the user information record type \r
3379 is compared. If InfoSize is 0, then the user information record \r
3380 must be empty.\r
3381\r
3382 @param[in] InfoSize The size of Info, in bytes. \r
3383\r
3384 @retval EFI_SUCCESS User information was found. User points to the user profile\r
3385 handle, and UserInfo points to the user information handle.\r
3386 @retval EFI_NOT_FOUND User information was not found. User points to NULL, and \r
3387 UserInfo points to NULL.\r
3388 @retval EFI_INVALID_PARAMETER User is NULL. Or Info is NULL. \r
3389 \r
3390**/\r
3391EFI_STATUS\r
3392EFIAPI\r
3393UserProfileFind (\r
3394 IN CONST EFI_USER_MANAGER_PROTOCOL *This,\r
3395 IN OUT EFI_USER_PROFILE_HANDLE *User,\r
3396 IN OUT EFI_USER_INFO_HANDLE *UserInfo OPTIONAL,\r
3397 IN CONST EFI_USER_INFO *Info,\r
3398 IN UINTN InfoSize\r
3399 )\r
3400{\r
3401 EFI_STATUS Status;\r
3402 UINTN Size;\r
3403\r
3404 if ((This == NULL) || (User == NULL) || (Info == NULL)) {\r
3405 return EFI_INVALID_PARAMETER;\r
3406 }\r
3407\r
3408 if (InfoSize == 0) {\r
3409 //\r
3410 // If InfoSize is 0, then the user information record must be empty.\r
3411 //\r
3412 if (Info->InfoSize != sizeof (EFI_USER_INFO)) {\r
3413 return EFI_INVALID_PARAMETER;\r
3414 }\r
3415 } else {\r
3416 if (InfoSize != Info->InfoSize) {\r
3417 return EFI_INVALID_PARAMETER;\r
3418 }\r
3419 }\r
3420 Size = Info->InfoSize; \r
3421 \r
3422 //\r
3423 // Find user profile accdoring to user information.\r
3424 //\r
3425 Status = FindUserProfileByInfo (\r
3426 (USER_PROFILE_ENTRY **) User,\r
3427 (EFI_USER_INFO **) UserInfo,\r
3428 (EFI_USER_INFO *) Info,\r
3429 Size\r
3430 );\r
3431 if (EFI_ERROR (Status)) {\r
3432 *User = NULL;\r
3433 if (UserInfo != NULL) {\r
3434 *UserInfo = NULL;\r
3435 }\r
3436 return EFI_NOT_FOUND;\r
3437 }\r
3438 \r
3439 return EFI_SUCCESS;\r
3440}\r
3441\r
3442\r
3443/**\r
3444 Return information attached to the user.\r
3445\r
3446 This function returns user information. The format of the information is described in User \r
3447 Information. The function may return EFI_ACCESS_DENIED if the information is marked private \r
3448 and the handle specified by User is not the current user profile. The function may return \r
3449 EFI_ACCESS_DENIED if the information is marked protected and the information is associated \r
3450 with a credential provider for which the user has not been authenticated.\r
3451\r
3452 @param[in] This Points to this instance of the EFI_USER_MANAGER_PROTOCOL.\r
3453 @param[in] User Handle of the user whose profile will be retrieved. \r
3454 @param[in] UserInfo Handle of the user information data record. \r
3455 @param[out] Info On entry, points to a buffer of at least *InfoSize bytes. On exit, \r
3456 holds the user information. If the buffer is too small to hold the \r
3457 information, then EFI_BUFFER_TOO_SMALL is returned and InfoSize is \r
3458 updated to contain the number of bytes actually required. \r
3459 @param[in, out] InfoSize On entry, points to the size of Info. On return, points to the size \r
3460 of the user information. \r
3461\r
3462 @retval EFI_SUCCESS Information returned successfully.\r
3463 @retval EFI_ACCESS_DENIED The information about the specified user cannot be accessed by the \r
3464 current user.\r
3465 @retval EFI_BUFFER_TOO_SMALL The number of bytes specified by *InfoSize is too small to hold the \r
3466 returned data. The actual size required is returned in *InfoSize.\r
3467 @retval EFI_NOT_FOUND User does not refer to a valid user profile or UserInfo does not refer \r
3468 to a valid user info handle.\r
3469 @retval EFI_INVALID_PARAMETER Info is NULL or InfoSize is NULL.\r
3470 \r
3471**/\r
3472EFI_STATUS\r
3473EFIAPI\r
3474UserProfileGetInfo (\r
3475 IN CONST EFI_USER_MANAGER_PROTOCOL *This,\r
3476 IN EFI_USER_PROFILE_HANDLE User,\r
3477 IN EFI_USER_INFO_HANDLE UserInfo,\r
3478 OUT EFI_USER_INFO *Info,\r
3479 IN OUT UINTN *InfoSize\r
3480 )\r
3481{\r
3482 EFI_STATUS Status;\r
3483\r
3484 if ((This == NULL) || (InfoSize == NULL)) {\r
3485 return EFI_INVALID_PARAMETER;\r
3486 }\r
3487\r
3488 if ((*InfoSize != 0) && (Info == NULL)) {\r
3489 return EFI_INVALID_PARAMETER;\r
3490 }\r
3491 \r
3492 if ((User == NULL) || (UserInfo == NULL)) {\r
3493 return EFI_NOT_FOUND;\r
3494 }\r
3495 \r
3496 Status = GetUserInfo (User, UserInfo, Info, InfoSize, TRUE);\r
3497 if (EFI_ERROR (Status)) {\r
3498 if (Status == EFI_BUFFER_TOO_SMALL) {\r
3499 return EFI_BUFFER_TOO_SMALL;\r
3500 }\r
3501 return EFI_ACCESS_DENIED;\r
3502 }\r
3503 return EFI_SUCCESS;\r
3504}\r
3505\r
3506\r
3507/**\r
3508 Add or update user information.\r
3509\r
3510 This function changes user information. If NULL is pointed to by UserInfo, then a new user \r
3511 information record is created and its handle is returned in UserInfo. Otherwise, the existing \r
3512 one is replaced.\r
3513 If EFI_USER_INFO_IDENITTY_POLICY_RECORD is changed, it is the caller's responsibility to keep \r
3514 it to be synced with the information on credential providers.\r
3515 If EFI_USER_INFO_EXCLUSIVE is specified in Info and a user information record of the same \r
3516 type already exists in the user profile, then EFI_ACCESS_DENIED will be returned and UserInfo\r
3517 will point to the handle of the existing record.\r
3518\r
3519 @param[in] This Points to this instance of the EFI_USER_MANAGER_PROTOCOL.\r
3520 @param[in] User Handle of the user whose profile will be retrieved. \r
3521 @param[in, out] UserInfo Handle of the user information data record. \r
3522 @param[in] Info On entry, points to a buffer of at least *InfoSize bytes. On exit, \r
3523 holds the user information. If the buffer is too small to hold the \r
3524 information, then EFI_BUFFER_TOO_SMALL is returned and InfoSize is \r
3525 updated to contain the number of bytes actually required. \r
3526 @param[in] InfoSize On entry, points to the size of Info. On return, points to the size \r
3527 of the user information. \r
3528\r
3529 @retval EFI_SUCCESS Information returned successfully.\r
3530 @retval EFI_ACCESS_DENIED The record is exclusive.\r
3531 @retval EFI_SECURITY_VIOLATION The current user does not have permission to change the specified \r
3532 user profile or user information record.\r
3533 @retval EFI_NOT_FOUND User does not refer to a valid user profile or UserInfo does not \r
3534 refer to a valid user info handle.\r
3535 @retval EFI_INVALID_PARAMETER UserInfo is NULL or Info is NULL. \r
3536**/\r
3537EFI_STATUS\r
3538EFIAPI\r
3539UserProfileSetInfo (\r
3540 IN CONST EFI_USER_MANAGER_PROTOCOL *This,\r
3541 IN EFI_USER_PROFILE_HANDLE User,\r
3542 IN OUT EFI_USER_INFO_HANDLE *UserInfo,\r
3543 IN CONST EFI_USER_INFO *Info,\r
3544 IN UINTN InfoSize\r
3545 )\r
3546{\r
3547 EFI_STATUS Status;\r
3548\r
3549 if ((This == NULL) || (User == NULL) || (UserInfo == NULL) || (Info == NULL)) {\r
3550 return EFI_INVALID_PARAMETER;\r
3551 }\r
3552 \r
3553 //\r
3554 // Check the right of the current user.\r
3555 //\r
3556 if (User != mCurrentUser) {\r
3557 if (!CheckCurrentUserAccessRight (EFI_USER_INFO_ACCESS_MANAGE)) {\r
3558 if (*UserInfo != NULL) {\r
3559 //\r
3560 // Can't update info in other profiles without MANAGE right.\r
3561 //\r
3562 return EFI_SECURITY_VIOLATION;\r
3563 }\r
3564 \r
3565 if (!CheckCurrentUserAccessRight (EFI_USER_INFO_ACCESS_ENROLL_OTHERS)) {\r
3566 //\r
3567 // Can't add info into other profiles.\r
3568 //\r
3569 return EFI_SECURITY_VIOLATION;\r
3570 }\r
3571 }\r
3572 }\r
3573\r
3574 if (User == mCurrentUser) {\r
3575 if (CheckCurrentUserAccessRight (EFI_USER_INFO_ACCESS_ENROLL_SELF)) {\r
3576 //\r
3577 // Only identify policy can be added/updated.\r
3578 //\r
3579 if (Info->InfoType != EFI_USER_INFO_IDENTITY_POLICY_RECORD) {\r
3580 return EFI_SECURITY_VIOLATION;\r
3581 }\r
3582 }\r
3583 }\r
3584 \r
3585 //\r
3586 // Modify user information.\r
3587 //\r
3588 Status = ModifyUserInfo (User, (EFI_USER_INFO **) UserInfo, Info, InfoSize);\r
3589 if (EFI_ERROR (Status)) {\r
3590 if (Status == EFI_ACCESS_DENIED) {\r
3591 return EFI_ACCESS_DENIED; \r
3592 }\r
3593 return EFI_SECURITY_VIOLATION;\r
3594 }\r
3595 return EFI_SUCCESS;\r
3596}\r
3597\r
3598\r
3599/**\r
3600 Called by credential provider to notify of information change.\r
3601\r
3602 This function allows the credential provider to notify the User Identity Manager when user status \r
3603 has changed.\r
3604 If the User Identity Manager doesn't support asynchronous changes in credentials, then this function \r
3605 should return EFI_UNSUPPORTED. \r
3606 If current user does not exist, and the credential provider can identify a user, then make the user \r
3607 to be current user and signal the EFI_EVENT_GROUP_USER_PROFILE_CHANGED event.\r
3608 If current user already exists, and the credential provider can identify another user, then switch \r
3609 current user to the newly identified user, and signal the EFI_EVENT_GROUP_USER_PROFILE_CHANGED event.\r
3610 If current user was identified by this credential provider and now the credential provider cannot identify \r
3611 current user, then logout current user and signal the EFI_EVENT_GROUP_USER_PROFILE_CHANGED event.\r
3612\r
3613 @param[in] This Points to this instance of the EFI_USER_MANAGER_PROTOCOL.\r
3614 @param[in] Changed Handle on which is installed an instance of the EFI_USER_CREDENTIAL2_PROTOCOL \r
3615 where the user has changed.\r
3616\r
3617 @retval EFI_SUCCESS The User Identity Manager has handled the notification.\r
3618 @retval EFI_NOT_READY The function was called while the specified credential provider was not selected.\r
3619 @retval EFI_UNSUPPORTED The User Identity Manager doesn't support asynchronous notifications.\r
3620 \r
3621**/\r
3622EFI_STATUS\r
3623EFIAPI\r
3624UserProfileNotify (\r
3625 IN CONST EFI_USER_MANAGER_PROTOCOL *This,\r
3626 IN EFI_HANDLE Changed\r
3627 )\r
3628{ \r
3629 return EFI_UNSUPPORTED;\r
3630}\r
3631\r
3632\r
3633/**\r
3634 Delete user information.\r
3635\r
3636 Delete the user information attached to the user profile specified by the UserInfo.\r
3637\r
3638 @param[in] This Points to this instance of the EFI_USER_MANAGER_PROTOCOL.\r
3639 @param[in] User Handle of the user whose information will be deleted.\r
3640 @param[in] UserInfo Handle of the user information to remove.\r
3641\r
3642 @retval EFI_SUCCESS User information deleted successfully.\r
3643 @retval EFI_NOT_FOUND User information record UserInfo does not exist in the user profile.\r
3644 @retval EFI_ACCESS_DENIED The current user does not have permission to delete this user information. \r
3645 \r
3646**/\r
3647EFI_STATUS\r
3648EFIAPI\r
3649UserProfileDeleteInfo (\r
3650 IN CONST EFI_USER_MANAGER_PROTOCOL *This,\r
3651 IN EFI_USER_PROFILE_HANDLE User,\r
3652 IN EFI_USER_INFO_HANDLE UserInfo\r
3653 )\r
3654{\r
3655 EFI_STATUS Status;\r
3656\r
3657 if (This == NULL) {\r
3658 return EFI_INVALID_PARAMETER;\r
3659 }\r
3660 \r
3661 //\r
3662 // Check the right of the current user.\r
3663 //\r
3664 if (User != mCurrentUser) {\r
3665 if (!CheckCurrentUserAccessRight (EFI_USER_INFO_ACCESS_MANAGE)) {\r
3666 return EFI_ACCESS_DENIED;\r
3667 }\r
3668 }\r
3669 \r
3670 //\r
3671 // Delete user information.\r
3672 //\r
3673 Status = DelUserInfo (User, UserInfo, TRUE);\r
3674 if (EFI_ERROR (Status)) {\r
3675 if (Status == EFI_NOT_FOUND) {\r
3676 return EFI_NOT_FOUND;\r
3677 }\r
3678 return EFI_ACCESS_DENIED;\r
3679 } \r
3680 return EFI_SUCCESS;\r
3681}\r
3682\r
3683\r
3684/**\r
3685 Enumerate user information of all the enrolled users on the platform.\r
3686\r
3687 This function returns the next user information record. To retrieve the first user \r
3688 information record handle, point UserInfo at a NULL. Each subsequent call will retrieve \r
3689 another user information record handle until there are no more, at which point UserInfo \r
3690 will point to NULL. \r
3691\r
3692 @param[in] This Points to this instance of the EFI_USER_MANAGER_PROTOCOL.\r
3693 @param[in] User Handle of the user whose information will be deleted.\r
3694 @param[in, out] UserInfo Handle of the user information to remove.\r
3695\r
3696 @retval EFI_SUCCESS User information returned.\r
3697 @retval EFI_NOT_FOUND No more user information found.\r
3698 @retval EFI_INVALID_PARAMETER UserInfo is NULL.\r
3699 \r
3700**/\r
3701EFI_STATUS\r
3702EFIAPI\r
3703UserProfileGetNextInfo (\r
3704 IN CONST EFI_USER_MANAGER_PROTOCOL *This,\r
3705 IN EFI_USER_PROFILE_HANDLE User,\r
3706 IN OUT EFI_USER_INFO_HANDLE *UserInfo\r
3707 )\r
3708{\r
3709 if ((This == NULL) || (UserInfo == NULL)) {\r
3710 return EFI_INVALID_PARAMETER;\r
3711 }\r
3712 //\r
3713 // Get next user information entry.\r
3714 //\r
3715 return FindUserInfo (User, (EFI_USER_INFO **) UserInfo, TRUE, NULL);\r
3716}\r
3717\r
3718\r
3719/**\r
3720 Main entry for this driver.\r
3721\r
3722 @param[in] ImageHandle Image handle this driver.\r
3723 @param[in] SystemTable Pointer to SystemTable.\r
3724\r
3725 @retval EFI_SUCESS This function always complete successfully.\r
3726\r
3727**/\r
3728EFI_STATUS\r
3729EFIAPI\r
3730UserIdentifyManagerInit (\r
3731 IN EFI_HANDLE ImageHandle,\r
3732 IN EFI_SYSTEM_TABLE *SystemTable\r
3733 )\r
3734{\r
3735\r
3736 EFI_STATUS Status;\r
3737\r
3738 //\r
3739 // It is NOT robust enough to be included in production.\r
3740 //\r
3741 #error "This implementation is just a sample, please comment this line if you really want to use this driver."\r
3742\r
3743 //\r
3744 // Initiate form browser.\r
3745 //\r
3746 InitFormBrowser ();\r
3747\r
3748 //\r
3749 // Install protocol interfaces for the User Identity Manager.\r
3750 //\r
3751 Status = gBS->InstallProtocolInterface (\r
3752 &mCallbackInfo->DriverHandle,\r
3753 &gEfiUserManagerProtocolGuid,\r
3754 EFI_NATIVE_INTERFACE,\r
3755 &gUserIdentifyManager\r
3756 );\r
3757 ASSERT_EFI_ERROR (Status); \r
3758\r
3759 LoadDeferredImageInit (ImageHandle);\r
3760 return EFI_SUCCESS;\r
3761}\r
3762\r
3763\r