]> git.proxmox.com Git - mirror_edk2.git/blame - SecurityPkg/UserIdentification/PwdCredentialProviderDxe/PwdCredentialProvider.c
Add security package to repository.
[mirror_edk2.git] / SecurityPkg / UserIdentification / PwdCredentialProviderDxe / PwdCredentialProvider.c
CommitLineData
0c18794e 1/** @file\r
2 Password Credential Provider driver implementation.\r
3 \r
4Copyright (c) 2009 - 2011, 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 "PwdCredentialProvider.h"\r
16\r
17CREDENTIAL_TABLE *mPwdTable = NULL;\r
18PWD_PROVIDER_CALLBACK_INFO *mCallbackInfo = NULL;\r
19PASSWORD_CREDENTIAL_INFO *mPwdInfoHandle = NULL;\r
20\r
21//\r
22// Used for save password credential and form browser.\r
23// Also used as provider identifier.\r
24//\r
25EFI_GUID mPwdCredentialGuid = PWD_CREDENTIAL_PROVIDER_GUID;\r
26\r
27HII_VENDOR_DEVICE_PATH mHiiVendorDevicePath = {\r
28 {\r
29 {\r
30 HARDWARE_DEVICE_PATH,\r
31 HW_VENDOR_DP,\r
32 {\r
33 (UINT8) (sizeof (VENDOR_DEVICE_PATH)),\r
34 (UINT8) ((sizeof (VENDOR_DEVICE_PATH)) >> 8)\r
35 }\r
36 },\r
37 { 0xeba7fc2b, 0xa465, 0x4d96, { 0x85, 0xa9, 0xd2, 0xf6, 0x64, 0xdf, 0x9b, 0x45 } } \r
38 },\r
39 {\r
40 END_DEVICE_PATH_TYPE,\r
41 END_ENTIRE_DEVICE_PATH_SUBTYPE,\r
42 {\r
43 (UINT8) (END_DEVICE_PATH_LENGTH),\r
44 (UINT8) ((END_DEVICE_PATH_LENGTH) >> 8)\r
45 }\r
46 }\r
47};\r
48\r
49EFI_USER_CREDENTIAL_PROTOCOL gPwdCredentialProviderDriver = {\r
50 PWD_CREDENTIAL_PROVIDER_GUID,\r
51 EFI_USER_CREDENTIAL_CLASS_PASSWORD,\r
52 CredentialEnroll,\r
53 CredentialForm,\r
54 CredentialTile,\r
55 CredentialTitle,\r
56 CredentialUser,\r
57 CredentialSelect,\r
58 CredentialDeselect,\r
59 CredentialDefault,\r
60 CredentialGetInfo,\r
61 CredentialGetNextInfo\r
62};\r
63\r
64\r
65/**\r
66 Get string by string id from HII Interface.\r
67\r
68\r
69 @param[in] Id String ID to get the string from.\r
70\r
71 @retval CHAR16 * String from ID.\r
72 @retval NULL If error occurs.\r
73\r
74**/\r
75CHAR16 *\r
76GetStringById (\r
77 IN EFI_STRING_ID Id\r
78 )\r
79{\r
80 //\r
81 // Get the current string for the current Language.\r
82 //\r
83 return HiiGetString (mCallbackInfo->HiiHandle, Id, NULL);\r
84}\r
85\r
86\r
87/**\r
88 Expand password table size.\r
89\r
90**/\r
91VOID\r
92ExpandTableSize (\r
93 VOID\r
94 )\r
95{\r
96 CREDENTIAL_TABLE *NewTable;\r
97 UINTN Count;\r
98\r
99 Count = mPwdTable->MaxCount + PASSWORD_TABLE_INC;\r
100 //\r
101 // Create new credential table.\r
102 //\r
103 NewTable = (CREDENTIAL_TABLE *) AllocateZeroPool (\r
104 sizeof (CREDENTIAL_TABLE) + \r
105 (Count - 1) * sizeof (PASSWORD_INFO)\r
106 );\r
107 ASSERT (NewTable != NULL); \r
108\r
109 NewTable->MaxCount = Count;\r
110 NewTable->Count = mPwdTable->Count;\r
111 NewTable->ValidIndex = mPwdTable->ValidIndex;\r
112 //\r
113 // Copy old entries\r
114 //\r
115 CopyMem (\r
116 &NewTable->UserInfo, \r
117 &mPwdTable->UserInfo, \r
118 mPwdTable->Count * sizeof (PASSWORD_INFO)\r
119 );\r
120 FreePool (mPwdTable);\r
121 mPwdTable = NewTable;\r
122}\r
123\r
124\r
125/**\r
126 Add or delete info in table, and sync with NV variable.\r
127\r
128 @param[in] Index The index of the password in table. The index begin from 1.\r
129 If index is found in table, delete the info, else add the \r
130 into to table. \r
131 @param[in] Info The new password info to add into table.\r
132\r
133 @retval EFI_INVALID_PARAMETER Info is NULL when save the info.\r
134 @retval EFI_SUCCESS Modify the table successfully.\r
135 @retval Others Failed to modify the table.\r
136\r
137**/\r
138EFI_STATUS\r
139ModifyTable (\r
140 IN UINTN Index,\r
141 IN PASSWORD_INFO * Info OPTIONAL\r
142 )\r
143{\r
144 EFI_STATUS Status;\r
145 \r
146 if (Index < mPwdTable->Count) {\r
147 //\r
148 // Delete the specified entry.\r
149 //\r
150 mPwdTable->Count--;\r
151 if (Index != mPwdTable->Count) {\r
152 CopyMem (\r
153 &mPwdTable->UserInfo[Index],\r
154 &mPwdTable->UserInfo[mPwdTable->Count],\r
155 sizeof (PASSWORD_INFO)\r
156 );\r
157 }\r
158 } else {\r
159 //\r
160 // Add a new entry.\r
161 //\r
162 if (Info == NULL) {\r
163 return EFI_INVALID_PARAMETER;\r
164 }\r
165\r
166 if (mPwdTable->Count >= mPwdTable->MaxCount) {\r
167 ExpandTableSize ();\r
168 }\r
169\r
170 CopyMem (\r
171 &mPwdTable->UserInfo[mPwdTable->Count], \r
172 Info, \r
173 sizeof (PASSWORD_INFO)\r
174 );\r
175 mPwdTable->Count++;\r
176 }\r
177\r
178 //\r
179 // Save the credential table.\r
180 //\r
181 Status = gRT->SetVariable (\r
182 L"PwdCredential",\r
183 &mPwdCredentialGuid,\r
184 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,\r
185 mPwdTable->Count * sizeof (PASSWORD_INFO),\r
186 &mPwdTable->UserInfo\r
187 );\r
188 return Status;\r
189}\r
190\r
191\r
192/**\r
193 Create a password table.\r
194\r
195 @retval EFI_SUCCESS Create a password table successfully.\r
196 @retval Others Failed to create a password.\r
197\r
198**/\r
199EFI_STATUS\r
200InitCredentialTable (\r
201 VOID\r
202 )\r
203{\r
204 EFI_STATUS Status;\r
205 UINT8 *Var;\r
206 UINTN VarSize;\r
207\r
208 //\r
209 // Get Password credential data from NV variable.\r
210 //\r
211 VarSize = 0;\r
212 Var = NULL;\r
213 Status = gRT->GetVariable (\r
214 L"PwdCredential", \r
215 &mPwdCredentialGuid, \r
216 NULL, \r
217 &VarSize,\r
218 Var\r
219 );\r
220 if (Status == EFI_BUFFER_TOO_SMALL) {\r
221 Var = AllocateZeroPool (VarSize);\r
222 if (Var == NULL) {\r
223 return EFI_OUT_OF_RESOURCES;\r
224 }\r
225 Status = gRT->GetVariable (\r
226 L"PwdCredential", \r
227 &mPwdCredentialGuid, \r
228 NULL, \r
229 &VarSize,\r
230 Var\r
231 );\r
232 }\r
233 if (EFI_ERROR (Status) && (Status != EFI_NOT_FOUND)) {\r
234 return Status;\r
235 }\r
236 \r
237 //\r
238 // Create the password credential table.\r
239 //\r
240 mPwdTable = AllocateZeroPool (\r
241 sizeof (CREDENTIAL_TABLE) - sizeof (PASSWORD_INFO) +\r
242 PASSWORD_TABLE_INC * sizeof (PASSWORD_INFO) + \r
243 VarSize\r
244 );\r
245 if (mPwdTable == NULL) {\r
246 FreePool (Var);\r
247 return EFI_OUT_OF_RESOURCES;\r
248 }\r
249\r
250 mPwdTable->Count = VarSize / sizeof (PASSWORD_INFO);\r
251 mPwdTable->MaxCount = mPwdTable->Count + PASSWORD_TABLE_INC;\r
252 mPwdTable->ValidIndex = 0;\r
253 if (Var != NULL) {\r
254 CopyMem (mPwdTable->UserInfo, Var, VarSize);\r
255 FreePool (Var);\r
256 }\r
257 return EFI_SUCCESS;\r
258}\r
259\r
260\r
261/**\r
262 Hash the password to get credential.\r
263\r
264 @param[in] Password Points to the input password.\r
265 @param[in] PasswordSize The size of password, in bytes.\r
266 @param[out] Credential Points to the hashed result.\r
267\r
268 @retval TRUE Hash the password successfully.\r
269 @retval FALSE Failed to hash the password.\r
270 \r
271**/\r
272BOOLEAN\r
273GenerateCredential (\r
274 IN CHAR16 *Password,\r
275 IN UINTN PasswordSize,\r
276 OUT UINT8 *Credential\r
277 )\r
278{\r
279 BOOLEAN Status;\r
280 UINTN HashSize;\r
281 VOID *Hash;\r
282 \r
283 HashSize = Sha1GetContextSize ();\r
284 Hash = AllocatePool (HashSize);\r
285 ASSERT (Hash != NULL);\r
286 \r
287 Status = Sha1Init (Hash);\r
288 if (!Status) {\r
289 goto Done;\r
290 }\r
291 \r
292 Status = Sha1Update (Hash, Password, PasswordSize);\r
293 if (!Status) {\r
294 goto Done;\r
295 }\r
296 \r
297 Status = Sha1Final (Hash, Credential);\r
298 \r
299Done:\r
300 FreePool (Hash);\r
301 return Status;\r
302}\r
303\r
304\r
305/**\r
306 Get password from user input.\r
307\r
308 @param[in] FirstPwd If True, prompt to input the first password.\r
309 If False, prompt to input password again.\r
310 @param[out] Credential Points to the input password.\r
311\r
312**/\r
313VOID\r
314GetPassword (\r
315 IN BOOLEAN FirstPwd,\r
316 OUT CHAR8 *Credential\r
317 )\r
318{\r
319 EFI_INPUT_KEY Key;\r
320 CHAR16 PasswordMask[CREDENTIAL_LEN + 1];\r
321 CHAR16 Password[CREDENTIAL_LEN];\r
322 UINTN PasswordLen;\r
323 CHAR16 *QuestionStr;\r
324 CHAR16 *LineStr;\r
325 \r
326 PasswordLen = 0;\r
327 while (TRUE) {\r
328 PasswordMask[PasswordLen] = L'_';\r
329 PasswordMask[PasswordLen + 1] = L'\0';\r
330 LineStr = GetStringById (STRING_TOKEN (STR_DRAW_A_LINE));\r
331 if (FirstPwd) {\r
332 QuestionStr = GetStringById (STRING_TOKEN (STR_INPUT_PASSWORD));\r
333 } else {\r
334 QuestionStr = GetStringById (STRING_TOKEN (STR_INPUT_PASSWORD_AGAIN));\r
335 }\r
336 CreatePopUp (\r
337 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
338 &Key,\r
339 QuestionStr,\r
340 LineStr,\r
341 PasswordMask,\r
342 NULL\r
343 );\r
344 FreePool (QuestionStr);\r
345 FreePool (LineStr);\r
346 \r
347 //\r
348 // Check key stroke\r
349 //\r
350 if (Key.ScanCode == SCAN_NULL) {\r
351 if (Key.UnicodeChar == CHAR_CARRIAGE_RETURN) {\r
352 break;\r
353 } else if (Key.UnicodeChar == CHAR_BACKSPACE) {\r
354 if (PasswordLen > 0) {\r
355 PasswordLen--;\r
356 }\r
357 } else if ((Key.UnicodeChar == CHAR_NULL) || \r
358 (Key.UnicodeChar == CHAR_TAB) || \r
359 (Key.UnicodeChar == CHAR_LINEFEED)) {\r
360 continue;\r
361 } else {\r
362 Password[PasswordLen] = Key.UnicodeChar;\r
363 PasswordMask[PasswordLen] = L'*';\r
364 PasswordLen++;\r
365 if (PasswordLen == CREDENTIAL_LEN) {\r
366 break;\r
367 }\r
368 }\r
369 }\r
370 }\r
371 \r
372 PasswordLen = PasswordLen * sizeof (CHAR16);\r
373 GenerateCredential (Password, PasswordLen, (UINT8 *)Credential);\r
374}\r
375\r
376/**\r
377 Check whether the password can be found on this provider.\r
378\r
379 @param[in] Password The password to be found.\r
380\r
381 @retval EFI_SUCCESS Found password sucessfully.\r
382 @retval EFI_NOT_FOUND Fail to find the password.\r
383\r
384**/\r
385EFI_STATUS\r
386CheckPassword (\r
387 IN CHAR8 *Password\r
388 )\r
389{\r
390 UINTN Index;\r
391 CHAR8 *Pwd;\r
392 \r
393 //\r
394 // Check password credential.\r
395 //\r
396 mPwdTable->ValidIndex = 0;\r
397 for (Index = 0; Index < mPwdTable->Count; Index++) {\r
398 Pwd = mPwdTable->UserInfo[Index].Password;\r
399 if (CompareMem (Pwd, Password, CREDENTIAL_LEN) == 0) {\r
400 mPwdTable->ValidIndex = Index + 1;\r
401 return EFI_SUCCESS;\r
402 }\r
403 }\r
404\r
405 return EFI_NOT_FOUND;\r
406}\r
407\r
408\r
409/**\r
410 Find a user infomation record by the information record type.\r
411\r
412 This function searches all user information records of User from beginning \r
413 until either the information is found, or there are no more user infomation\r
414 records. A match occurs when a Info.InfoType field matches the user information\r
415 record type.\r
416\r
417 @param[in] User Points to the user profile record to search. \r
418 @param[in] InfoType The infomation type to be searched.\r
419 @param[out] Info Points to the user info found, the caller is responsible\r
420 to free.\r
421 \r
422 @retval EFI_SUCCESS Find the user information successfully.\r
423 @retval Others Fail to find the user information.\r
424\r
425**/\r
426EFI_STATUS\r
427FindUserInfoByType (\r
428 IN EFI_USER_PROFILE_HANDLE User,\r
429 IN UINT8 InfoType,\r
430 OUT EFI_USER_INFO **Info\r
431 )\r
432{\r
433 EFI_STATUS Status;\r
434 EFI_USER_INFO *UserInfo;\r
435 UINTN UserInfoSize;\r
436 EFI_USER_INFO_HANDLE UserInfoHandle;\r
437 EFI_USER_MANAGER_PROTOCOL *UserManager;\r
438 \r
439 //\r
440 // Find user information by information type.\r
441 //\r
442 if (Info == NULL) {\r
443 return EFI_INVALID_PARAMETER;\r
444 }\r
445\r
446 Status = gBS->LocateProtocol (\r
447 &gEfiUserManagerProtocolGuid,\r
448 NULL,\r
449 (VOID **) &UserManager\r
450 );\r
451 if (EFI_ERROR (Status)) {\r
452 return EFI_NOT_FOUND;\r
453 }\r
454\r
455 //\r
456 // Get each user information.\r
457 //\r
458\r
459 UserInfoHandle = NULL;\r
460 UserInfo = NULL;\r
461 UserInfoSize = 0;\r
462 while (TRUE) {\r
463 Status = UserManager->GetNextInfo (UserManager, User, &UserInfoHandle);\r
464 if (EFI_ERROR (Status)) {\r
465 break;\r
466 }\r
467 //\r
468 // Get information.\r
469 //\r
470 Status = UserManager->GetInfo (\r
471 UserManager,\r
472 User,\r
473 UserInfoHandle,\r
474 UserInfo,\r
475 &UserInfoSize\r
476 );\r
477 if (Status == EFI_BUFFER_TOO_SMALL) {\r
478 if (UserInfo != NULL) {\r
479 FreePool (UserInfo);\r
480 }\r
481 UserInfo = AllocateZeroPool (UserInfoSize);\r
482 if (UserInfo == NULL) {\r
483 return EFI_OUT_OF_RESOURCES;\r
484 }\r
485 Status = UserManager->GetInfo (\r
486 UserManager,\r
487 User,\r
488 UserInfoHandle,\r
489 UserInfo,\r
490 &UserInfoSize\r
491 );\r
492 }\r
493 if (EFI_ERROR (Status)) {\r
494 break;\r
495 }\r
496\r
497 ASSERT (UserInfo != NULL);\r
498 if (UserInfo->InfoType == InfoType) {\r
499 *Info = UserInfo;\r
500 return EFI_SUCCESS;\r
501 } \r
502 }\r
503\r
504 if (UserInfo != NULL) {\r
505 FreePool (UserInfo);\r
506 }\r
507 return Status;\r
508}\r
509\r
510\r
511/**\r
512 This function processes the results of changes in configuration.\r
513\r
514 @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.\r
515 @param Action Specifies the type of action taken by the browser.\r
516 @param QuestionId A unique value which is sent to the original\r
517 exporting driver so that it can identify the type\r
518 of data to expect.\r
519 @param Type The type of value for the question.\r
520 @param Value A pointer to the data being sent to the original\r
521 exporting driver.\r
522 @param ActionRequest On return, points to the action requested by the\r
523 callback function.\r
524\r
525 @retval EFI_SUCCESS The callback successfully handled the action.\r
526 @retval EFI_OUT_OF_RESOURCES Not enough storage is available to hold the\r
527 variable and its data.\r
528 @retval EFI_DEVICE_ERROR The variable could not be saved.\r
529 @retval EFI_UNSUPPORTED The specified Action is not supported by the\r
530 callback.\r
531\r
532**/\r
533EFI_STATUS\r
534EFIAPI\r
535CredentialDriverCallback (\r
536 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,\r
537 IN EFI_BROWSER_ACTION Action,\r
538 IN EFI_QUESTION_ID QuestionId,\r
539 IN UINT8 Type,\r
540 IN EFI_IFR_TYPE_VALUE *Value,\r
541 OUT EFI_BROWSER_ACTION_REQUEST *ActionRequest\r
542 )\r
543{\r
544 EFI_STATUS Status;\r
545 EFI_INPUT_KEY Key;\r
546 CHAR8 Password[CREDENTIAL_LEN];\r
547 CHAR16 *PromptStr;\r
548\r
549 if (Action == EFI_BROWSER_ACTION_CHANGING) {\r
550 if (QuestionId == KEY_GET_PASSWORD) {\r
551 //\r
552 // Get and check password.\r
553 //\r
554 GetPassword (TRUE, Password);\r
555 Status = CheckPassword (Password);\r
556 if (EFI_ERROR (Status)) {\r
557 PromptStr = GetStringById (STRING_TOKEN (STR_PASSWORD_INCORRECT));\r
558 CreatePopUp (\r
559 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
560 &Key,\r
561 L"",\r
562 PromptStr,\r
563 L"",\r
564 NULL\r
565 );\r
566 FreePool (PromptStr);\r
567 return Status;\r
568 }\r
569 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_EXIT;\r
570 } \r
571 return EFI_SUCCESS;\r
572 }\r
573\r
574 //\r
575 // All other action return unsupported.\r
576 //\r
577 return EFI_UNSUPPORTED;\r
578}\r
579\r
580\r
581/**\r
582 This function allows a caller to extract the current configuration for one\r
583 or more named elements from the target driver.\r
584\r
585\r
586 @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.\r
587 @param Request A null-terminated Unicode string in <ConfigRequest> format.\r
588 @param Progress On return, points to a character in the Request string.\r
589 Points to the string's null terminator if request was successful.\r
590 Points to the most recent '&' before the first failing name/value\r
591 pair (or the beginning of the string if the failure is in the\r
592 first name/value pair) if the request was not successful.\r
593 @param Results A null-terminated Unicode string in <ConfigAltResp> format which\r
594 has all values filled in for the names in the Request string.\r
595 String to be allocated by the called function.\r
596\r
597 @retval EFI_SUCCESS The Results is filled with the requested values.\r
598 @retval EFI_OUT_OF_RESOURCES Not enough memory to store the results.\r
599 @retval EFI_INVALID_PARAMETER Request is illegal syntax, or unknown name.\r
600 @retval EFI_NOT_FOUND Routing data doesn't match any storage in this driver.\r
601\r
602**/\r
603EFI_STATUS\r
604EFIAPI\r
605FakeExtractConfig (\r
606 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,\r
607 IN CONST EFI_STRING Request,\r
608 OUT EFI_STRING *Progress,\r
609 OUT EFI_STRING *Results\r
610 )\r
611{\r
612 if (Progress == NULL || Results == NULL) {\r
613 return EFI_INVALID_PARAMETER;\r
614 }\r
615 *Progress = Request;\r
616 return EFI_NOT_FOUND;\r
617}\r
618\r
619/**\r
620 This function processes the results of changes in configuration.\r
621\r
622\r
623 @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.\r
624 @param Configuration A null-terminated Unicode string in <ConfigResp> format.\r
625 @param Progress A pointer to a string filled in with the offset of the most\r
626 recent '&' before the first failing name/value pair (or the\r
627 beginning of the string if the failure is in the first\r
628 name/value pair) or the terminating NULL if all was successful.\r
629\r
630 @retval EFI_SUCCESS The Results is processed successfully.\r
631 @retval EFI_INVALID_PARAMETER Configuration is NULL.\r
632 @retval EFI_NOT_FOUND Routing data doesn't match any storage in this driver.\r
633\r
634**/\r
635EFI_STATUS\r
636EFIAPI\r
637FakeRouteConfig (\r
638 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,\r
639 IN CONST EFI_STRING Configuration,\r
640 OUT EFI_STRING *Progress\r
641 )\r
642{\r
643 if (Configuration == NULL || Progress == NULL) {\r
644 return EFI_INVALID_PARAMETER;\r
645 }\r
646\r
647 return EFI_NOT_FOUND;\r
648}\r
649\r
650/**\r
651 This function initialize the data mainly used in form browser.\r
652\r
653 @retval EFI_SUCCESS Initialize form data successfully.\r
654 @retval Others Fail to Initialize form data.\r
655\r
656**/\r
657EFI_STATUS\r
658InitFormBrowser (\r
659 VOID\r
660 )\r
661{\r
662 EFI_STATUS Status;\r
663 PWD_PROVIDER_CALLBACK_INFO *CallbackInfo;\r
664\r
665 //\r
666 // Initialize driver private data.\r
667 //\r
668 CallbackInfo = AllocateZeroPool (sizeof (PWD_PROVIDER_CALLBACK_INFO));\r
669 if (CallbackInfo == NULL) {\r
670 return EFI_OUT_OF_RESOURCES;\r
671 }\r
672\r
673 CallbackInfo->Signature = PWD_PROVIDER_SIGNATURE;\r
674 CallbackInfo->ConfigAccess.ExtractConfig = FakeExtractConfig;\r
675 CallbackInfo->ConfigAccess.RouteConfig = FakeRouteConfig;\r
676 CallbackInfo->ConfigAccess.Callback = CredentialDriverCallback;\r
677 CallbackInfo->DriverHandle = NULL;\r
678\r
679 //\r
680 // Install Device Path Protocol and Config Access protocol to driver handle.\r
681 //\r
682 Status = gBS->InstallMultipleProtocolInterfaces (\r
683 &CallbackInfo->DriverHandle,\r
684 &gEfiDevicePathProtocolGuid,\r
685 &mHiiVendorDevicePath,\r
686 &gEfiHiiConfigAccessProtocolGuid,\r
687 &CallbackInfo->ConfigAccess,\r
688 NULL\r
689 );\r
690 ASSERT_EFI_ERROR (Status);\r
691\r
692 //\r
693 // Publish HII data.\r
694 //\r
695 CallbackInfo->HiiHandle = HiiAddPackages (\r
696 &mPwdCredentialGuid,\r
697 CallbackInfo->DriverHandle,\r
698 PwdCredentialProviderStrings,\r
699 PwdCredentialProviderVfrBin,\r
700 NULL\r
701 );\r
702 if (CallbackInfo->HiiHandle == NULL) {\r
703 return EFI_OUT_OF_RESOURCES;\r
704 }\r
705 mCallbackInfo = CallbackInfo;\r
706\r
707 return Status;\r
708}\r
709\r
710\r
711/**\r
712 Enroll a user on a credential provider.\r
713\r
714 This function enrolls and deletes a user profile using this credential provider. \r
715 If a user profile is successfully enrolled, it calls the User Manager Protocol \r
716 function Notify() to notify the user manager driver that credential information \r
717 has changed. If an enrolled user does exist, delete the user on the credential \r
718 provider.\r
719 \r
720 @param[in] This Points to this instance of EFI_USER_CREDENTIAL_PROTOCOL.\r
721 @param[in] User The user profile to enroll.\r
722 \r
723 @retval EFI_SUCCESS User profile was successfully enrolled.\r
724 @retval EFI_ACCESS_DENIED Current user profile does not permit enrollment on the\r
725 user profile handle. Either the user profile cannot enroll\r
726 on any user profile or cannot enroll on a user profile \r
727 other than the current user profile.\r
728 @retval EFI_UNSUPPORTED This credential provider does not support enrollment in\r
729 the pre-OS.\r
730 @retval EFI_DEVICE_ERROR The new credential could not be created because of a device\r
731 error.\r
732 @retval EFI_INVALID_PARAMETER User does not refer to a valid user profile handle.\r
733 \r
734**/\r
735EFI_STATUS\r
736EFIAPI\r
737CredentialEnroll (\r
738 IN CONST EFI_USER_CREDENTIAL_PROTOCOL *This,\r
739 IN EFI_USER_PROFILE_HANDLE User\r
740 )\r
741{\r
742 EFI_STATUS Status;\r
743 UINTN Index;\r
744 PASSWORD_INFO PwdInfo;\r
745 EFI_USER_INFO *UserInfo;\r
746 CHAR8 Password[CREDENTIAL_LEN];\r
747 EFI_INPUT_KEY Key;\r
748 EFI_USER_MANAGER_PROTOCOL *UserManager;\r
749 UINT8 *UserId;\r
750 UINT8 *NewUserId;\r
751 CHAR16 *QuestionStr;\r
752 CHAR16 *PromptStr;\r
753\r
754 if ((This == NULL) || (User == NULL)) {\r
755 return EFI_INVALID_PARAMETER;\r
756 }\r
757\r
758 Status = gBS->LocateProtocol (\r
759 &gEfiUserManagerProtocolGuid,\r
760 NULL,\r
761 (VOID **) &UserManager\r
762 );\r
763 if (EFI_ERROR (Status)) {\r
764 return EFI_UNSUPPORTED;\r
765 }\r
766\r
767 //\r
768 // Get User Identifier.\r
769 //\r
770 UserInfo = NULL;\r
771 Status = FindUserInfoByType (\r
772 User,\r
773 EFI_USER_INFO_IDENTIFIER_RECORD,\r
774 &UserInfo\r
775 );\r
776 if (EFI_ERROR (Status)) {\r
777 return EFI_INVALID_PARAMETER;\r
778 }\r
779\r
780 //\r
781 // If User exists in mPwdTable, delete User.\r
782 // \r
783 for (Index = 0; Index < mPwdTable->Count; Index++) {\r
784 UserId = (UINT8 *) &mPwdTable->UserInfo[Index].UserId;\r
785 NewUserId = (UINT8 *) (UserInfo + 1);\r
786 if (CompareMem (UserId, NewUserId, sizeof (EFI_USER_INFO_IDENTIFIER)) == 0) {\r
787 //\r
788 // Delete the existing password.\r
789 //\r
790 FreePool (UserInfo);\r
791 return ModifyTable (Index, NULL);\r
792 }\r
793 }\r
794\r
795 //\r
796 // The User doesn't exist in mPwdTable; Enroll the new User.\r
797 // \r
798 while (TRUE) {\r
799 //\r
800 // Input password.\r
801 //\r
802 GetPassword (TRUE, PwdInfo.Password);\r
803\r
804 //\r
805 // Input password again.\r
806 //\r
807 GetPassword (FALSE, Password);\r
808\r
809 //\r
810 // Compare the two password consistency.\r
811 //\r
812 if (CompareMem (PwdInfo.Password, Password, CREDENTIAL_LEN) == 0) {\r
813 break;\r
814 } \r
815\r
816 QuestionStr = GetStringById (STRING_TOKEN (STR_PASSWORD_MISMATCH));\r
817 PromptStr = GetStringById (STRING_TOKEN (STR_INPUT_PASSWORD_AGAIN)); \r
818 CreatePopUp (\r
819 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
820 &Key,\r
821 QuestionStr,\r
822 L"",\r
823 PromptStr,\r
824 NULL\r
825 );\r
826 FreePool (QuestionStr);\r
827 FreePool (PromptStr);\r
828 }\r
829\r
830 CopyMem (\r
831 PwdInfo.UserId, \r
832 (UINT8 *) (UserInfo + 1), \r
833 sizeof (EFI_USER_INFO_IDENTIFIER)\r
834 ); \r
835 FreePool (UserInfo);\r
836 \r
837 //\r
838 // Save the new added entry.\r
839 //\r
840 Status = ModifyTable (mPwdTable->Count, &PwdInfo);\r
841 if (EFI_ERROR (Status)) {\r
842 return Status;\r
843 }\r
844\r
845 //\r
846 // Notify the user manager driver that credential information has changed.\r
847 //\r
848 UserManager->Notify (UserManager, mCallbackInfo->DriverHandle); \r
849\r
850 return EFI_SUCCESS;\r
851}\r
852\r
853\r
854/**\r
855 Returns the user interface information used during user identification.\r
856\r
857 This function returns information about the form used when interacting with the\r
858 user during user identification. The form is the first enabled form in the form-set\r
859 class EFI_HII_USER_CREDENTIAL_FORMSET_GUID installed on the HII handle HiiHandle. If \r
860 the user credential provider does not require a form to identify the user, then this\r
861 function should return EFI_NOT_FOUND.\r
862\r
863 @param[in] This Points to this instance of the EFI_USER_CREDENTIAL_PROTOCOL.\r
864 @param[out] Hii On return, holds the HII database handle.\r
865 @param[out] FormSetId On return, holds the identifier of the form set which contains\r
866 the form used during user identification.\r
867 @param[out] FormId On return, holds the identifier of the form used during user \r
868 identification.\r
869 \r
870 @retval EFI_SUCCESS Form returned successfully.\r
871 @retval EFI_NOT_FOUND Form not returned.\r
872 @retval EFI_INVALID_PARAMETER Hii is NULL or FormSetId is NULL or FormId is NULL.\r
873 \r
874**/\r
875EFI_STATUS\r
876EFIAPI\r
877CredentialForm (\r
878 IN CONST EFI_USER_CREDENTIAL_PROTOCOL *This,\r
879 OUT EFI_HII_HANDLE *Hii,\r
880 OUT EFI_GUID *FormSetId,\r
881 OUT EFI_FORM_ID *FormId\r
882 )\r
883{\r
884 if ((This == NULL) || (Hii == NULL) || \r
885 (FormSetId == NULL) || (FormId == NULL)) {\r
886 return EFI_INVALID_PARAMETER;\r
887 }\r
888\r
889 *Hii = mCallbackInfo->HiiHandle;\r
890 *FormId = FORMID_GET_PASSWORD_FORM;\r
891 CopyGuid (FormSetId, &mPwdCredentialGuid);\r
892 \r
893 return EFI_SUCCESS;\r
894}\r
895\r
896\r
897/**\r
898 Returns bitmap used to describe the credential provider type.\r
899\r
900 This optional function returns a bitmap that is less than or equal to the number\r
901 of pixels specified by Width and Height. If no such bitmap exists, then EFI_NOT_FOUND\r
902 is returned. \r
903\r
904 @param[in] This Points to this instance of the EFI_USER_CREDENTIAL_PROTOCOL.\r
905 @param[in, out] Width On entry, points to the desired bitmap width. If NULL then no \r
906 bitmap information will be returned. On exit, points to the \r
907 width of the bitmap returned.\r
908 @param[in, out] Height On entry, points to the desired bitmap height. If NULL then no\r
909 bitmap information will be returned. On exit, points to the \r
910 height of the bitmap returned\r
911 @param[out] Hii On return, holds the HII database handle. \r
912 @param[out] Image On return, holds the HII image identifier. \r
913 \r
914 @retval EFI_SUCCESS Image identifier returned successfully.\r
915 @retval EFI_NOT_FOUND Image identifier not returned.\r
916 @retval EFI_INVALID_PARAMETER Hii is NULL or Image is NULL.\r
917 \r
918**/\r
919EFI_STATUS\r
920EFIAPI\r
921CredentialTile (\r
922 IN CONST EFI_USER_CREDENTIAL_PROTOCOL *This,\r
923 IN OUT UINTN *Width,\r
924 IN OUT UINTN *Height,\r
925 OUT EFI_HII_HANDLE *Hii,\r
926 OUT EFI_IMAGE_ID *Image\r
927 )\r
928{ \r
929 if ((This == NULL) || (Hii == NULL) || (Image == NULL)) {\r
930 return EFI_INVALID_PARAMETER;\r
931 }\r
932 return EFI_NOT_FOUND;\r
933}\r
934\r
935\r
936/**\r
937 Returns string used to describe the credential provider type.\r
938\r
939 This function returns a string which describes the credential provider. If no\r
940 such string exists, then EFI_NOT_FOUND is returned. \r
941\r
942 @param[in] This Points to this instance of the EFI_USER_CREDENTIAL_PROTOCOL.\r
943 @param[out] Hii On return, holds the HII database handle.\r
944 @param[out] String On return, holds the HII string identifier.\r
945 \r
946 @retval EFI_SUCCESS String identifier returned successfully.\r
947 @retval EFI_NOT_FOUND String identifier not returned.\r
948 @retval EFI_INVALID_PARAMETER Hii is NULL or String is NULL.\r
949 \r
950**/\r
951EFI_STATUS\r
952EFIAPI\r
953CredentialTitle (\r
954 IN CONST EFI_USER_CREDENTIAL_PROTOCOL *This,\r
955 OUT EFI_HII_HANDLE *Hii,\r
956 OUT EFI_STRING_ID *String\r
957 )\r
958{\r
959 if ((This == NULL) || (Hii == NULL) || (String == NULL)) {\r
960 return EFI_INVALID_PARAMETER;\r
961 }\r
962 \r
963 //\r
964 // Set Hii handle and String ID.\r
965 //\r
966 *Hii = mCallbackInfo->HiiHandle;\r
967 *String = STRING_TOKEN (STR_CREDENTIAL_TITLE);\r
968\r
969 return EFI_SUCCESS;\r
970}\r
971\r
972\r
973/**\r
974 Return the user identifier associated with the currently authenticated user.\r
975\r
976 This function returns the user identifier of the user authenticated by this credential\r
977 provider. This function is called after the credential-related information has been \r
978 submitted on a form, OR after a call to Default() has returned that this credential is\r
979 ready to log on.\r
980\r
981 @param[in] This Points to this instance of the EFI_USER_CREDENTIAL_PROTOCOL.\r
982 @param[in] User The user profile handle of the user profile currently being \r
983 considered by the user identity manager. If NULL, then no user\r
984 profile is currently under consideration.\r
985 @param[out] Identifier On return, points to the user identifier. \r
986 \r
987 @retval EFI_SUCCESS User identifier returned successfully.\r
988 @retval EFI_NOT_READY No user identifier can be returned.\r
989 @retval EFI_ACCESS_DENIED The user has been locked out of this user credential.\r
990 @retval EFI_INVALID_PARAMETER This is NULL, or Identifier is NULL.\r
991 @retval EFI_NOT_FOUND User is not NULL, and the specified user handle can't be\r
992 found in user profile database\r
993 \r
994**/\r
995EFI_STATUS\r
996EFIAPI\r
997CredentialUser (\r
998 IN CONST EFI_USER_CREDENTIAL_PROTOCOL *This,\r
999 IN EFI_USER_PROFILE_HANDLE User,\r
1000 OUT EFI_USER_INFO_IDENTIFIER *Identifier\r
1001 )\r
1002{\r
1003 EFI_STATUS Status;\r
1004 UINTN Index;\r
1005 EFI_USER_INFO *UserInfo;\r
1006 UINT8 *UserId;\r
1007 UINT8 *NewUserId;\r
1008 CHAR8 *Pwd;\r
1009 CHAR8 *NewPwd;\r
1010\r
1011 if ((This == NULL) || (Identifier == NULL)) {\r
1012 return EFI_INVALID_PARAMETER;\r
1013 }\r
1014\r
1015 if (mPwdTable->ValidIndex == 0) {\r
1016 //\r
1017 // No password input, or the input password doesn't match\r
1018 // anyone in PwdTable.\r
1019 //\r
1020 return EFI_NOT_READY;\r
1021 }\r
1022 \r
1023 if (User == NULL) {\r
1024 //\r
1025 // Return the user ID whose password matches the input password.\r
1026 // \r
1027 CopyMem (\r
1028 Identifier, \r
1029 &mPwdTable->UserInfo[mPwdTable->ValidIndex - 1].UserId, \r
1030 sizeof (EFI_USER_INFO_IDENTIFIER)\r
1031 ); \r
1032 return EFI_SUCCESS;\r
1033 }\r
1034 \r
1035 //\r
1036 // Get the User's ID.\r
1037 //\r
1038 Status = FindUserInfoByType (\r
1039 User,\r
1040 EFI_USER_INFO_IDENTIFIER_RECORD,\r
1041 &UserInfo\r
1042 );\r
1043 if (EFI_ERROR (Status)) {\r
1044 return EFI_NOT_FOUND;\r
1045 }\r
1046 \r
1047 //\r
1048 // Check whether the input password matches one in PwdTable.\r
1049 //\r
1050 for (Index = 0; Index < mPwdTable->Count; Index++) {\r
1051 UserId = (UINT8 *) &mPwdTable->UserInfo[Index].UserId;\r
1052 NewUserId = (UINT8 *) (UserInfo + 1);\r
1053 if (CompareMem (UserId, NewUserId, sizeof (EFI_USER_INFO_IDENTIFIER)) == 0) {\r
1054 Pwd = mPwdTable->UserInfo[Index].Password;\r
1055 NewPwd = mPwdTable->UserInfo[mPwdTable->ValidIndex - 1].Password;\r
1056 if (CompareMem (Pwd, NewPwd, CREDENTIAL_LEN) == 0) {\r
1057 CopyMem (Identifier, UserId, sizeof (EFI_USER_INFO_IDENTIFIER));\r
1058 FreePool (UserInfo);\r
1059 return EFI_SUCCESS;\r
1060 } \r
1061 }\r
1062 }\r
1063\r
1064 //\r
1065 // The User's password doesn't match the input password.\r
1066 // Return the user ID whose password matches the input password.\r
1067 //\r
1068 CopyMem (\r
1069 Identifier,\r
1070 &mPwdTable->UserInfo[mPwdTable->ValidIndex - 1].UserId,\r
1071 sizeof (EFI_USER_INFO_IDENTIFIER)\r
1072 );\r
1073 FreePool (UserInfo); \r
1074 return EFI_SUCCESS;\r
1075}\r
1076\r
1077\r
1078/**\r
1079 Indicate that user interface interaction has begun for the specified credential.\r
1080\r
1081 This function is called when a credential provider is selected by the user. If \r
1082 AutoLogon returns FALSE, then the user interface will be constructed by the User\r
1083 Identity Manager. \r
1084\r
1085 @param[in] This Points to this instance of the EFI_USER_CREDENTIAL_PROTOCOL.\r
1086 @param[out] AutoLogon On return, points to the credential provider's capabilities \r
1087 after the credential provider has been selected by the user. \r
1088 \r
1089 @retval EFI_SUCCESS Credential provider successfully selected.\r
1090 @retval EFI_INVALID_PARAMETER AutoLogon is NULL.\r
1091 \r
1092**/\r
1093EFI_STATUS\r
1094EFIAPI\r
1095CredentialSelect (\r
1096 IN CONST EFI_USER_CREDENTIAL_PROTOCOL *This,\r
1097 OUT EFI_CREDENTIAL_LOGON_FLAGS *AutoLogon\r
1098 )\r
1099{\r
1100 if ((This == NULL) || (AutoLogon == NULL)) {\r
1101 return EFI_INVALID_PARAMETER;\r
1102 }\r
1103 *AutoLogon = 0;\r
1104\r
1105 return EFI_SUCCESS;\r
1106}\r
1107\r
1108\r
1109/**\r
1110 Indicate that user interface interaction has ended for the specified credential.\r
1111\r
1112 This function is called when a credential provider is deselected by the user.\r
1113\r
1114 @param[in] This Points to this instance of the EFI_USER_CREDENTIAL_PROTOCOL.\r
1115 \r
1116 @retval EFI_SUCCESS Credential provider successfully deselected.\r
1117 \r
1118**/\r
1119EFI_STATUS\r
1120EFIAPI\r
1121CredentialDeselect (\r
1122 IN CONST EFI_USER_CREDENTIAL_PROTOCOL *This\r
1123 )\r
1124{\r
1125 if (This == NULL) {\r
1126 return EFI_INVALID_PARAMETER;\r
1127 }\r
1128 return EFI_SUCCESS;\r
1129}\r
1130\r
1131\r
1132/**\r
1133 Return the default logon behavior for this user credential.\r
1134\r
1135 This function reports the default login behavior regarding this credential provider. \r
1136\r
1137 @param[in] This Points to this instance of the EFI_USER_CREDENTIAL_PROTOCOL.\r
1138 @param[out] AutoLogon On return, holds whether the credential provider should be used\r
1139 by default to automatically log on the user. \r
1140 \r
1141 @retval EFI_SUCCESS Default information successfully returned.\r
1142 @retval EFI_INVALID_PARAMETER AutoLogon is NULL.\r
1143 \r
1144**/\r
1145EFI_STATUS\r
1146EFIAPI\r
1147CredentialDefault (\r
1148 IN CONST EFI_USER_CREDENTIAL_PROTOCOL *This,\r
1149 OUT EFI_CREDENTIAL_LOGON_FLAGS *AutoLogon\r
1150 )\r
1151{\r
1152 if ((This == NULL) || (AutoLogon == NULL)) {\r
1153 return EFI_INVALID_PARAMETER;\r
1154 }\r
1155 *AutoLogon = 0;\r
1156 \r
1157 return EFI_SUCCESS;\r
1158}\r
1159\r
1160\r
1161/**\r
1162 Return information attached to the credential provider.\r
1163\r
1164 This function returns user information. \r
1165\r
1166 @param[in] This Points to this instance of the EFI_USER_CREDENTIAL_PROTOCOL.\r
1167 @param[in] UserInfo Handle of the user information data record. \r
1168 @param[out] Info On entry, points to a buffer of at least *InfoSize bytes. On\r
1169 exit, holds the user information. If the buffer is too small\r
1170 to hold the information, then EFI_BUFFER_TOO_SMALL is returned\r
1171 and InfoSize is updated to contain the number of bytes actually\r
1172 required.\r
1173 @param[in, out] InfoSize On entry, points to the size of Info. On return, points to the \r
1174 size of the user information. \r
1175 \r
1176 @retval EFI_SUCCESS Information returned successfully.\r
1177 @retval EFI_BUFFER_TOO_SMALL The size specified by InfoSize is too small to hold all of the\r
1178 user information. The size required is returned in *InfoSize.\r
1179 @retval EFI_INVALID_PARAMETER Info is NULL or InfoSize is NULL.\r
1180 @retval EFI_NOT_FOUND The specified UserInfo does not refer to a valid user info handle. \r
1181 \r
1182**/\r
1183EFI_STATUS\r
1184EFIAPI\r
1185CredentialGetInfo (\r
1186 IN CONST EFI_USER_CREDENTIAL_PROTOCOL *This,\r
1187 IN EFI_USER_INFO_HANDLE UserInfo,\r
1188 OUT EFI_USER_INFO *Info,\r
1189 IN OUT UINTN *InfoSize\r
1190 )\r
1191{\r
1192 EFI_USER_INFO *CredentialInfo;\r
1193 UINTN Index;\r
1194 \r
1195 if ((This == NULL) || (InfoSize == NULL) || (Info == NULL)) {\r
1196 return EFI_INVALID_PARAMETER;\r
1197 }\r
1198\r
1199 if ((UserInfo == NULL) || (mPwdInfoHandle == NULL)) {\r
1200 return EFI_NOT_FOUND;\r
1201 }\r
1202 \r
1203 //\r
1204 // Find information handle in credential info table.\r
1205 //\r
1206 for (Index = 0; Index < mPwdInfoHandle->Count; Index++) {\r
1207 CredentialInfo = mPwdInfoHandle->Info[Index];\r
1208 if (UserInfo == (EFI_USER_INFO_HANDLE)CredentialInfo) {\r
1209 //\r
1210 // The handle is found, copy the user info.\r
1211 //\r
1212 if (CredentialInfo->InfoSize > *InfoSize) {\r
1213 *InfoSize = CredentialInfo->InfoSize;\r
1214 return EFI_BUFFER_TOO_SMALL;\r
1215 }\r
1216 CopyMem (Info, CredentialInfo, CredentialInfo->InfoSize); \r
1217 return EFI_SUCCESS; \r
1218 }\r
1219 }\r
1220 \r
1221 return EFI_NOT_FOUND;\r
1222}\r
1223\r
1224\r
1225/**\r
1226 Enumerate all of the user informations on the credential provider.\r
1227\r
1228 This function returns the next user information record. To retrieve the first user\r
1229 information record handle, point UserInfo at a NULL. Each subsequent call will retrieve\r
1230 another user information record handle until there are no more, at which point UserInfo\r
1231 will point to NULL. \r
1232\r
1233 @param[in] This Points to this instance of the EFI_USER_CREDENTIAL_PROTOCOL.\r
1234 @param[in, out] UserInfo On entry, points to the previous user information handle or NULL\r
1235 to start enumeration. On exit, points to the next user information\r
1236 handle or NULL if there is no more user information.\r
1237 \r
1238 @retval EFI_SUCCESS User information returned.\r
1239 @retval EFI_NOT_FOUND No more user information found.\r
1240 @retval EFI_INVALID_PARAMETER UserInfo is NULL.\r
1241 \r
1242**/\r
1243EFI_STATUS\r
1244EFIAPI\r
1245CredentialGetNextInfo (\r
1246 IN CONST EFI_USER_CREDENTIAL_PROTOCOL *This,\r
1247 IN OUT EFI_USER_INFO_HANDLE *UserInfo\r
1248 )\r
1249{\r
1250 EFI_USER_INFO *Info;\r
1251 CHAR16 *ProvNameStr;\r
1252 UINTN InfoLen;\r
1253 UINTN Index;\r
1254 UINTN ProvStrLen;\r
1255 \r
1256 if ((This == NULL) || (UserInfo == NULL)) {\r
1257 return EFI_INVALID_PARAMETER;\r
1258 }\r
1259\r
1260 if (mPwdInfoHandle == NULL) {\r
1261 //\r
1262 // Initilized user info table. There are 4 user info records in the table.\r
1263 //\r
1264 InfoLen = sizeof (PASSWORD_CREDENTIAL_INFO) + (4 - 1) * sizeof (EFI_USER_INFO *);\r
1265 mPwdInfoHandle = AllocateZeroPool (InfoLen);\r
1266 if (mPwdInfoHandle == NULL) {\r
1267 *UserInfo = NULL;\r
1268 return EFI_NOT_FOUND;\r
1269 }\r
1270\r
1271 //\r
1272 // The first information, Credential Provider info.\r
1273 //\r
1274 InfoLen = sizeof (EFI_USER_INFO) + sizeof (EFI_GUID);\r
1275 Info = AllocateZeroPool (InfoLen);\r
1276 ASSERT (Info != NULL);\r
1277 \r
1278 Info->InfoType = EFI_USER_INFO_CREDENTIAL_PROVIDER_RECORD;\r
1279 Info->InfoSize = (UINT32) InfoLen;\r
1280 Info->InfoAttribs = EFI_USER_INFO_PROTECTED;\r
1281 CopyGuid (&Info->Credential, &mPwdCredentialGuid);\r
1282 CopyGuid ((EFI_GUID *)(Info + 1), &mPwdCredentialGuid);\r
1283 \r
1284 mPwdInfoHandle->Info[0] = Info;\r
1285 mPwdInfoHandle->Count++;\r
1286\r
1287 //\r
1288 // The second information, Credential Provider name info.\r
1289 //\r
1290 ProvNameStr = GetStringById (STRING_TOKEN (STR_PROVIDER_NAME));\r
1291 ProvStrLen = StrSize (ProvNameStr);\r
1292 InfoLen = sizeof (EFI_USER_INFO) + ProvStrLen;\r
1293 Info = AllocateZeroPool (InfoLen);\r
1294 ASSERT (Info != NULL);\r
1295 \r
1296 Info->InfoType = EFI_USER_INFO_CREDENTIAL_PROVIDER_NAME_RECORD;\r
1297 Info->InfoSize = (UINT32) InfoLen;\r
1298 Info->InfoAttribs = EFI_USER_INFO_PROTECTED;\r
1299 CopyGuid (&Info->Credential, &mPwdCredentialGuid);\r
1300 CopyMem ((UINT8*)(Info + 1), ProvNameStr, ProvStrLen);\r
1301 FreePool (ProvNameStr);\r
1302\r
1303 mPwdInfoHandle->Info[1] = Info;\r
1304 mPwdInfoHandle->Count++;\r
1305\r
1306 //\r
1307 // The third information, Credential Provider type info.\r
1308 //\r
1309 InfoLen = sizeof (EFI_USER_INFO) + sizeof (EFI_GUID);\r
1310 Info = AllocateZeroPool (InfoLen);\r
1311 ASSERT (Info != NULL);\r
1312 \r
1313 Info->InfoType = EFI_USER_INFO_CREDENTIAL_TYPE_RECORD;\r
1314 Info->InfoSize = (UINT32) InfoLen;\r
1315 Info->InfoAttribs = EFI_USER_INFO_PROTECTED;\r
1316 CopyGuid (&Info->Credential, &mPwdCredentialGuid);\r
1317 CopyGuid ((EFI_GUID *)(Info + 1), &gEfiUserCredentialClassPasswordGuid);\r
1318 \r
1319 mPwdInfoHandle->Info[2] = Info;\r
1320 mPwdInfoHandle->Count++;\r
1321 \r
1322 //\r
1323 // The fourth information, Credential Provider type name info.\r
1324 //\r
1325 ProvNameStr = GetStringById (STRING_TOKEN (STR_PROVIDER_TYPE_NAME));\r
1326 ProvStrLen = StrSize (ProvNameStr);\r
1327 InfoLen = sizeof (EFI_USER_INFO) + ProvStrLen;\r
1328 Info = AllocateZeroPool (InfoLen);\r
1329 ASSERT (Info != NULL);\r
1330 \r
1331 Info->InfoType = EFI_USER_INFO_CREDENTIAL_PROVIDER_NAME_RECORD;\r
1332 Info->InfoSize = (UINT32) InfoLen;\r
1333 Info->InfoAttribs = EFI_USER_INFO_PROTECTED;\r
1334 CopyGuid (&Info->Credential, &mPwdCredentialGuid);\r
1335 CopyMem ((UINT8*)(Info + 1), ProvNameStr, ProvStrLen);\r
1336 FreePool (ProvNameStr);\r
1337 \r
1338 mPwdInfoHandle->Info[3] = Info;\r
1339 mPwdInfoHandle->Count++;\r
1340 }\r
1341 \r
1342 if (*UserInfo == NULL) {\r
1343 //\r
1344 // Return the first info handle.\r
1345 //\r
1346 *UserInfo = (EFI_USER_INFO_HANDLE) mPwdInfoHandle->Info[0];\r
1347 return EFI_SUCCESS;\r
1348 }\r
1349 \r
1350 //\r
1351 // Find information handle in credential info table.\r
1352 //\r
1353 for (Index = 0; Index < mPwdInfoHandle->Count; Index++) {\r
1354 Info = mPwdInfoHandle->Info[Index];\r
1355 if (*UserInfo == (EFI_USER_INFO_HANDLE)Info) {\r
1356 //\r
1357 // The handle is found, get the next one.\r
1358 //\r
1359 if (Index == mPwdInfoHandle->Count - 1) {\r
1360 //\r
1361 // Already last one.\r
1362 //\r
1363 *UserInfo = NULL;\r
1364 return EFI_NOT_FOUND;\r
1365 }\r
1366 \r
1367 Index++;\r
1368 *UserInfo = (EFI_USER_INFO_HANDLE)mPwdInfoHandle->Info[Index];\r
1369 return EFI_SUCCESS; \r
1370 }\r
1371 }\r
1372\r
1373 *UserInfo = NULL;\r
1374 return EFI_NOT_FOUND;\r
1375}\r
1376\r
1377\r
1378/**\r
1379 Main entry for this driver.\r
1380\r
1381 @param ImageHandle Image handle this driver.\r
1382 @param SystemTable Pointer to SystemTable.\r
1383\r
1384 @retval EFI_SUCESS This function always complete successfully.\r
1385\r
1386**/\r
1387EFI_STATUS\r
1388EFIAPI\r
1389PasswordProviderInit (\r
1390 IN EFI_HANDLE ImageHandle,\r
1391 IN EFI_SYSTEM_TABLE *SystemTable\r
1392 )\r
1393{\r
1394 EFI_STATUS Status;\r
1395\r
1396 //\r
1397 // Init credential table.\r
1398 //\r
1399 Status = InitCredentialTable ();\r
1400 if (EFI_ERROR (Status)) {\r
1401 return Status;\r
1402 }\r
1403 \r
1404 //\r
1405 // Init Form Browser.\r
1406 //\r
1407 Status = InitFormBrowser ();\r
1408 if (EFI_ERROR (Status)) {\r
1409 return Status;\r
1410 }\r
1411 \r
1412 //\r
1413 // Install protocol interfaces for the password credential provider.\r
1414 //\r
1415 Status = gBS->InstallProtocolInterface (\r
1416 &mCallbackInfo->DriverHandle,\r
1417 &gEfiUserCredentialProtocolGuid,\r
1418 EFI_NATIVE_INTERFACE,\r
1419 &gPwdCredentialProviderDriver\r
1420 );\r
1421 return Status;\r
1422}\r