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