]> git.proxmox.com Git - mirror_edk2.git/blobdiff - SecurityPkg/UserIdentification/UserProfileManagerDxe/UserProfileManager.c
Add security package to repository.
[mirror_edk2.git] / SecurityPkg / UserIdentification / UserProfileManagerDxe / UserProfileManager.c
diff --git a/SecurityPkg/UserIdentification/UserProfileManagerDxe/UserProfileManager.c b/SecurityPkg/UserIdentification/UserProfileManagerDxe/UserProfileManager.c
new file mode 100644 (file)
index 0000000..74c979d
--- /dev/null
@@ -0,0 +1,806 @@
+/** @file\r
+  This driver is a configuration tool for adding, deleting or modifying user \r
+  profiles, including gathering the necessary information to ascertain their \r
+  identity in the future, updating user access policy and identification \r
+  policy, etc.\r
+\r
+Copyright (c) 2009 - 2011, Intel Corporation. All rights reserved.<BR>\r
+This program and the accompanying materials \r
+are licensed and made available under the terms and conditions of the BSD License \r
+which accompanies this distribution.  The full text of the license may be found at \r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include "UserProfileManager.h"\r
+\r
+EFI_GUID                  mUserProfileManagerGuid = USER_PROFILE_MANAGER_GUID;\r
+EFI_USER_MANAGER_PROTOCOL *mUserManager           = NULL;\r
+CREDENTIAL_PROVIDER_INFO  *mProviderInfo          = NULL;\r
+UINT8                     mProviderChoice;\r
+UINT8                     mConncetLogical;\r
+USER_INFO_ACCESS          mAccessInfo;\r
+USER_INFO                 mUserInfo;\r
+USER_PROFILE_MANAGER_CALLBACK_INFO  *mCallbackInfo;\r
+HII_VENDOR_DEVICE_PATH  mHiiVendorDevicePath = {\r
+  {\r
+    {\r
+      HARDWARE_DEVICE_PATH,\r
+      HW_VENDOR_DP,\r
+      {\r
+        (UINT8) (sizeof (VENDOR_DEVICE_PATH)),\r
+        (UINT8) ((sizeof (VENDOR_DEVICE_PATH)) >> 8)\r
+      }\r
+    },\r
+    {0xad2e3474, 0x93e6, 0x488b, {0x93, 0x19, 0x64, 0x88, 0xfc, 0x68, 0x1f, 0x16}}\r
+  },\r
+  {\r
+    END_DEVICE_PATH_TYPE,\r
+    END_ENTIRE_DEVICE_PATH_SUBTYPE,\r
+    {\r
+      (UINT8) (END_DEVICE_PATH_LENGTH),\r
+      (UINT8) ((END_DEVICE_PATH_LENGTH) >> 8)\r
+    }\r
+  }\r
+};\r
+\r
+\r
+/**\r
+  Get string by string id from HII Interface.\r
+\r
+\r
+  @param[in] Id      String ID to get the string from.\r
+\r
+  @retval  CHAR16 *  String from ID.\r
+  @retval  NULL      If error occurs.\r
+\r
+**/\r
+CHAR16 *\r
+GetStringById (\r
+  IN EFI_STRING_ID             Id\r
+  )\r
+{\r
+  //\r
+  // Get the current string for the current Language.\r
+  //\r
+  return HiiGetString (mCallbackInfo->HiiHandle, Id, NULL);\r
+}\r
+\r
+\r
+/**\r
+  This function gets all the credential providers in the system and saved them \r
+  to mProviderInfo.\r
+\r
+  @retval EFI_SUCESS     Init credential provider database successfully.\r
+  @retval Others         Fail to init credential provider database.\r
+  \r
+**/\r
+EFI_STATUS\r
+InitProviderInfo (\r
+  VOID\r
+  )\r
+{\r
+  EFI_STATUS  Status;\r
+  UINTN       HandleCount;\r
+  EFI_HANDLE  *HandleBuf;\r
+  UINTN       Index;  \r
+  \r
+  //\r
+  // Try to find all the user credential provider driver.\r
+  //\r
+  HandleCount = 0;\r
+  HandleBuf   = NULL;\r
+  Status = gBS->LocateHandleBuffer (\r
+                  ByProtocol,\r
+                  &gEfiUserCredentialProtocolGuid,\r
+                  NULL,\r
+                  &HandleCount,\r
+                  &HandleBuf\r
+                  );\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+  \r
+  //\r
+  // Get provider infomation.\r
+  //\r
+  if (mProviderInfo != NULL) {\r
+    FreePool (mProviderInfo);\r
+  }\r
+  mProviderInfo = AllocateZeroPool (\r
+                    sizeof (CREDENTIAL_PROVIDER_INFO) - \r
+                    sizeof (EFI_USER_CREDENTIAL_PROTOCOL *) +\r
+                    HandleCount * sizeof (EFI_USER_CREDENTIAL_PROTOCOL *)\r
+                    );\r
+  if (mProviderInfo == NULL) {\r
+    FreePool (HandleBuf);\r
+    return EFI_OUT_OF_RESOURCES;\r
+  }\r
+\r
+  mProviderInfo->Count = HandleCount;\r
+  for (Index = 0; Index < HandleCount; Index++) {\r
+    Status = gBS->HandleProtocol (\r
+                    HandleBuf[Index],\r
+                    &gEfiUserCredentialProtocolGuid,\r
+                    (VOID **) &mProviderInfo->Provider[Index]\r
+                    );\r
+    if (EFI_ERROR (Status)) {\r
+      FreePool (HandleBuf);\r
+      FreePool (mProviderInfo);\r
+      mProviderInfo = NULL;\r
+      return Status;\r
+    }\r
+  }\r
+\r
+  FreePool (HandleBuf);\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+\r
+/**\r
+  This function processes changes in user profile configuration.\r
+\r
+  @param  This                   Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.\r
+  @param  Action                 Specifies the type of action taken by the browser.\r
+  @param  QuestionId             A unique value which is sent to the original\r
+                                 exporting driver so that it can identify the type\r
+                                 of data to expect.\r
+  @param  Type                   The type of value for the question.\r
+  @param  Value                  A pointer to the data being sent to the original\r
+                                 exporting driver.\r
+  @param  ActionRequest          On return, points to the action requested by the\r
+                                 callback function.\r
+\r
+  @retval EFI_SUCCESS            The callback successfully handled the action.\r
+  @retval Others                 Fail to handle the action.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+UserProfileManagerCallback (\r
+  IN  CONST EFI_HII_CONFIG_ACCESS_PROTOCOL      *This,\r
+  IN  EFI_BROWSER_ACTION                        Action,\r
+  IN  EFI_QUESTION_ID                           QuestionId,\r
+  IN  UINT8                                     Type,\r
+  IN  EFI_IFR_TYPE_VALUE                        *Value,\r
+  OUT EFI_BROWSER_ACTION_REQUEST                *ActionRequest\r
+  )\r
+{\r
+  EFI_STATUS               Status;\r
+  EFI_INPUT_KEY            Key;\r
+  UINT32                   CurrentAccessRight;\r
+  CHAR16                   *QuestionStr;\r
+  CHAR16                   *PromptStr;\r
+  VOID                     *StartOpCodeHandle;\r
+  VOID                     *EndOpCodeHandle;\r
+  EFI_IFR_GUID_LABEL       *StartLabel;\r
+  EFI_IFR_GUID_LABEL       *EndLabel;\r
+  EFI_USER_PROFILE_HANDLE  CurrentUser;\r
+\r
+  Status = EFI_SUCCESS;\r
+\r
+  switch (Action) {\r
+  case EFI_BROWSER_ACTION_FORM_OPEN:\r
+    {\r
+      //\r
+      // Update user manage Form when user manage Form is opened.\r
+      // This will be done only in FORM_OPEN CallBack of question with QUESTIONID_USER_MANAGE from user manage Form.\r
+      //\r
+      if (QuestionId != QUESTIONID_USER_MANAGE) {\r
+        return EFI_SUCCESS;\r
+      }\r
+  \r
+      //\r
+      // Get current user\r
+      //\r
+      CurrentUser = NULL;\r
+      mUserManager->Current (mUserManager, &CurrentUser);\r
+      if (CurrentUser == NULL) {\r
+        DEBUG ((DEBUG_ERROR, "Error: current user does not exist!\n"));\r
+        return EFI_NOT_READY;\r
+      }\r
+      \r
+      //\r
+      // Get current user's right information.\r
+      //\r
+      Status = GetAccessRight (&CurrentAccessRight);\r
+      if (EFI_ERROR (Status)) {\r
+        CurrentAccessRight = EFI_USER_INFO_ACCESS_ENROLL_SELF;\r
+      }\r
+  \r
+      //\r
+      // Init credential provider information.\r
+      //\r
+      Status = InitProviderInfo ();\r
+      if (EFI_ERROR (Status)) {\r
+        return Status;\r
+      }\r
+      \r
+      //\r
+      // Initialize the container for dynamic opcodes.\r
+      //\r
+      StartOpCodeHandle = HiiAllocateOpCodeHandle ();\r
+      ASSERT (StartOpCodeHandle != NULL);\r
+  \r
+      EndOpCodeHandle = HiiAllocateOpCodeHandle ();\r
+      ASSERT (EndOpCodeHandle != NULL);\r
+  \r
+      //\r
+      // Create Hii Extend Label OpCode.\r
+      //\r
+      StartLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (\r
+                                            StartOpCodeHandle,\r
+                                            &gEfiIfrTianoGuid,\r
+                                            NULL,\r
+                                            sizeof (EFI_IFR_GUID_LABEL)\r
+                                            );\r
+      StartLabel->ExtendOpCode  = EFI_IFR_EXTEND_OP_LABEL;\r
+      StartLabel->Number        = LABEL_USER_MANAGE_FUNC;\r
+  \r
+      EndLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (\r
+                                          EndOpCodeHandle,\r
+                                          &gEfiIfrTianoGuid,\r
+                                          NULL,\r
+                                          sizeof (EFI_IFR_GUID_LABEL)\r
+                                          );\r
+      EndLabel->ExtendOpCode  = EFI_IFR_EXTEND_OP_LABEL;\r
+      EndLabel->Number        = LABEL_END;\r
+  \r
+      //\r
+      // Add user profile option.\r
+      //\r
+      if ((CurrentAccessRight == EFI_USER_INFO_ACCESS_MANAGE) ||\r
+          (CurrentAccessRight == EFI_USER_INFO_ACCESS_ENROLL_OTHERS)\r
+          ) {\r
+        HiiCreateActionOpCode (\r
+          StartOpCodeHandle,                  // Container for dynamic created opcodes\r
+          KEY_ADD_USER,                       // Question ID\r
+          STRING_TOKEN (STR_ADD_USER_TITLE),  // Prompt text\r
+          STRING_TOKEN (STR_ADD_USER_HELP),   // Help text\r
+          EFI_IFR_FLAG_CALLBACK,              // Question flag\r
+          0                                   // Action String ID\r
+          );\r
+      }\r
+      \r
+      //\r
+      // Add modify user profile option.\r
+      //\r
+      HiiCreateGotoOpCode (\r
+        StartOpCodeHandle,                    // Container for dynamic created opcodes\r
+        FORMID_MODIFY_USER,                   // Target Form ID\r
+        STRING_TOKEN (STR_MODIFY_USER_TITLE), // Prompt text\r
+        STRING_TOKEN (STR_MODIFY_USER_HELP),  // Help text\r
+        EFI_IFR_FLAG_CALLBACK,                // Question flag\r
+        KEY_MODIFY_USER                       // Question ID\r
+        );\r
+  \r
+      //\r
+      // Add delete user profile option\r
+      //\r
+      if (CurrentAccessRight == EFI_USER_INFO_ACCESS_MANAGE) {\r
+        HiiCreateGotoOpCode (\r
+          StartOpCodeHandle,                    // Container for dynamic created opcodes\r
+          FORMID_DEL_USER,                      // Target Form ID\r
+          STRING_TOKEN (STR_DELETE_USER_TITLE), // Prompt text\r
+          STRING_TOKEN (STR_DELETE_USER_HELP),  // Help text\r
+          EFI_IFR_FLAG_CALLBACK,                // Question flag\r
+          KEY_DEL_USER                          // Question ID\r
+          );\r
+      }\r
+  \r
+      HiiUpdateForm (\r
+        mCallbackInfo->HiiHandle,               // HII handle\r
+        &mUserProfileManagerGuid,               // Formset GUID\r
+        FORMID_USER_MANAGE,                     // Form ID\r
+        StartOpCodeHandle,                      // Label for where to insert opcodes\r
+        EndOpCodeHandle                         // Replace data\r
+        );\r
+  \r
+      HiiFreeOpCodeHandle (StartOpCodeHandle);\r
+      HiiFreeOpCodeHandle (EndOpCodeHandle);\r
+  \r
+      return EFI_SUCCESS;\r
+    }\r
+    break;\r
+\r
+  case EFI_BROWSER_ACTION_FORM_CLOSE:\r
+    Status = EFI_SUCCESS;\r
+    break;\r
+\r
+  case EFI_BROWSER_ACTION_CHANGING:\r
+  {  \r
+    //\r
+    // Handle the request from form.\r
+    //\r
+    if ((Value == NULL) || (ActionRequest == NULL)) {\r
+      return EFI_INVALID_PARAMETER;\r
+    }\r
+    \r
+    //\r
+    // Judge first 2 bits.\r
+    //\r
+    switch (QuestionId & KEY_FIRST_FORM_MASK) {\r
+    //\r
+    // Add user profile operation.\r
+    //\r
+    case KEY_ADD_USER:\r
+      CallAddUser ();\r
+      break;\r
+\r
+    //\r
+    // Delete user profile operation.\r
+    //\r
+    case KEY_DEL_USER:\r
+      //\r
+      // Judge next 2 bits.\r
+      //\r
+      switch (QuestionId & KEY_SECOND_FORM_MASK) {\r
+      //\r
+      // Enter delete user profile form.\r
+      //\r
+      case KEY_ENTER_NEXT_FORM:\r
+        SelectUserToDelete ();\r
+        break;\r
+\r
+      //\r
+      // Delete specified user profile.\r
+      //\r
+      case KEY_SELECT_USER:\r
+        DeleteUser ((UINT8) QuestionId);\r
+        //\r
+        // Update select user form after delete a user.\r
+        //\r
+        SelectUserToDelete ();\r
+        break;\r
+\r
+      default:\r
+        break;\r
+      }\r
+      break;\r
+\r
+    //\r
+    // Modify user profile operation.\r
+    //\r
+    case KEY_MODIFY_USER:\r
+      //\r
+      // Judge next 2 bits.\r
+      //\r
+      switch (QuestionId & KEY_SECOND_FORM_MASK) {\r
+      //\r
+      // Enter modify user profile form.\r
+      //\r
+      case KEY_ENTER_NEXT_FORM:\r
+        SelectUserToModify ();\r
+        break;\r
+\r
+      //\r
+      // Enter user profile information form.\r
+      //\r
+      case KEY_SELECT_USER:\r
+        //\r
+        // Judge next 3 bits.\r
+        //\r
+        switch (QuestionId & KEY_MODIFY_INFO_MASK) {\r
+        //\r
+        // Display user information form.\r
+        //\r
+        case KEY_ENTER_NEXT_FORM:\r
+          ModifyUserInfo ((UINT8) QuestionId);\r
+          break;\r
+\r
+        //\r
+        // Modify user name.\r
+        //\r
+        case KEY_MODIFY_NAME:\r
+          ModifyUserName ();\r
+          //\r
+          // Update username in parent form.\r
+          //\r
+          SelectUserToModify ();\r
+          break;\r
+\r
+        //\r
+        // Modify identity policy.\r
+        //\r
+        case KEY_MODIFY_IP:\r
+          //\r
+          // Judge next 3 bits\r
+          //\r
+          switch (QuestionId & KEY_MODIFY_IP_MASK) {\r
+          //\r
+          // Display identity policy modify form.\r
+          //\r
+          case KEY_ENTER_NEXT_FORM:\r
+            ModifyIdentityPolicy ();\r
+            break;\r
+\r
+          //\r
+          // Change credential provider option.\r
+          //\r
+          case KEY_MODIFY_PROV:         \r
+            mProviderChoice = Value->u8;\r
+            *ActionRequest  = EFI_BROWSER_ACTION_REQUEST_SUBMIT;\r
+            break;\r
+\r
+          //\r
+          // Change logical connector.\r
+          //\r
+          case KEY_MODIFY_CONN:\r
+            mConncetLogical = Value->u8;\r
+            *ActionRequest  = EFI_BROWSER_ACTION_REQUEST_SUBMIT;\r
+            break;\r
+\r
+          //\r
+          // Save option.\r
+          //\r
+          case KEY_ADD_IP_OP:\r
+            AddIdentityPolicyItem ();\r
+            break;\r
+\r
+          //\r
+          // Return to user profile information form.\r
+          //\r
+          case KEY_IP_RETURN_UIF:\r
+            SaveIdentityPolicy ();\r
+            *ActionRequest = EFI_BROWSER_ACTION_REQUEST_SUBMIT;\r
+            break;\r
+\r
+          default:\r
+            break;\r
+          }\r
+          break;\r
+\r
+        //\r
+        // Modify access policy.\r
+        //\r
+        case KEY_MODIFY_AP:\r
+          //\r
+          // Judge next 3 bits.\r
+          //\r
+          switch (QuestionId & KEY_MODIFY_AP_MASK) {\r
+          //\r
+          // Display access policy modify form.\r
+          //\r
+          case KEY_ENTER_NEXT_FORM:\r
+            ModidyAccessPolicy ();\r
+            break;\r
+\r
+          //\r
+          // Change access right choice.\r
+          //\r
+          case KEY_MODIFY_RIGHT:\r
+            mAccessInfo.AccessRight = Value->u8;\r
+            *ActionRequest  = EFI_BROWSER_ACTION_REQUEST_SUBMIT;\r
+            break;\r
+\r
+          //\r
+          // Change setup choice.\r
+          //\r
+          case KEY_MODIFY_SETUP:\r
+            mAccessInfo.AccessSetup= Value->u8;\r
+            *ActionRequest  = EFI_BROWSER_ACTION_REQUEST_SUBMIT;\r
+            break;\r
+\r
+          //\r
+          // Change boot order choice.\r
+          //\r
+          case KEY_MODIFY_BOOT:\r
+            mAccessInfo.AccessBootOrder = Value->u32;\r
+            *ActionRequest  = EFI_BROWSER_ACTION_REQUEST_SUBMIT;\r
+            break;\r
+\r
+          //\r
+          // Load device path form.\r
+          //\r
+          case KEY_MODIFY_LOAD:\r
+            //\r
+            // Judge next 2 bits.\r
+            //\r
+            switch (QuestionId & KEY_DISPLAY_DP_MASK) {\r
+            //\r
+            // Permit load device path.\r
+            //\r
+            case KEY_PERMIT_MODIFY:\r
+              DisplayLoadPermit ();\r
+              break;\r
+\r
+            //\r
+            // Forbid load device path.\r
+            //\r
+            case KEY_FORBID_MODIFY:\r
+              DisplayLoadForbid ();\r
+              break;\r
+\r
+            default:\r
+              break;\r
+            }\r
+            break;\r
+\r
+          //\r
+          // Connect device path form.\r
+          //\r
+          case KEY_MODIFY_CONNECT:\r
+            //\r
+            // Judge next 2 bits.\r
+            //\r
+            switch (QuestionId & KEY_DISPLAY_DP_MASK) {\r
+            //\r
+            // Permit connect device path.\r
+            //\r
+            case KEY_PERMIT_MODIFY:\r
+              DisplayConnectPermit ();\r
+              break;\r
+\r
+            //\r
+            // Forbid connect device path.\r
+            //\r
+            case KEY_FORBID_MODIFY:\r
+              DisplayConnectForbid ();\r
+              break;\r
+\r
+            default:\r
+              break;\r
+            }\r
+            break;\r
+\r
+          //\r
+          // Return to user profile information form.\r
+          //\r
+          case KEY_AP_RETURN_UIF:\r
+            SaveAccessPolicy ();\r
+            *ActionRequest = EFI_BROWSER_ACTION_REQUEST_SUBMIT;\r
+            break;\r
+\r
+          default:\r
+            break;\r
+          }\r
+          break;\r
+\r
+        default:\r
+          break;\r
+        }\r
+        break;\r
+\r
+      //\r
+      // Access policy device path modified.\r
+      //\r
+      case KEY_MODIFY_AP_DP:\r
+        //\r
+        // Judge next 2 bits.\r
+        //\r
+        switch (QuestionId & KEY_MODIFY_DP_MASK) {\r
+        //\r
+        // Load permit device path modified.\r
+        //\r
+        case KEY_LOAD_PERMIT_MODIFY:\r
+          QuestionStr = GetStringById (STRING_TOKEN (STR_MOVE_TO_FORBID_LIST));\r
+          PromptStr   = GetStringById (STRING_TOKEN (STR_PRESS_KEY_CONTINUE));\r
+          CreatePopUp (\r
+            EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
+            &Key,\r
+            QuestionStr,\r
+            L"",\r
+            PromptStr,\r
+            NULL\r
+            );\r
+          FreePool (QuestionStr);\r
+          FreePool (PromptStr);\r
+          if (Key.UnicodeChar != CHAR_CARRIAGE_RETURN) {\r
+            break;\r
+          }\r
+\r
+          AddToForbidLoad ((UINT16)(QuestionId & (KEY_MODIFY_DP_MASK - 1)));\r
+          DisplayLoadPermit ();\r
+          break;\r
+\r
+        //\r
+        // Load forbid device path modified.\r
+        //\r
+        case KEY_LOAD_FORBID_MODIFY:\r
+          QuestionStr = GetStringById (STRING_TOKEN (STR_MOVE_TO_PERMIT_LIST));\r
+          PromptStr   = GetStringById (STRING_TOKEN (STR_PRESS_KEY_CONTINUE));\r
+          CreatePopUp (\r
+            EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
+            &Key,\r
+            QuestionStr,\r
+            L"",\r
+            PromptStr,\r
+            NULL\r
+            );\r
+          FreePool (QuestionStr);\r
+          FreePool (PromptStr);\r
+          if (Key.UnicodeChar != CHAR_CARRIAGE_RETURN) {\r
+            break;\r
+          }\r
+\r
+          DeleteFromForbidLoad ((UINT16)(QuestionId & (KEY_MODIFY_DP_MASK - 1)));\r
+          DisplayLoadForbid ();\r
+          break;\r
+\r
+        //\r
+        // Connect permit device path modified.\r
+        //\r
+        case KEY_CONNECT_PERMIT_MODIFY:\r
+          break;\r
+\r
+        //\r
+        // Connect forbid device path modified.\r
+        //\r
+        case KEY_CONNECT_FORBID_MODIFY:\r
+          break;\r
+\r
+        default:\r
+          break;\r
+        }\r
+        break;\r
+\r
+      default:\r
+        break;\r
+      }\r
+      break;\r
+\r
+    default:\r
+      break;\r
+    }\r
+  }\r
+  break;\r
+\r
+  default:\r
+    //\r
+    // All other action return unsupported.\r
+    //\r
+    Status = EFI_UNSUPPORTED;\r
+    break;\r
+  }\r
+\r
+\r
+  return Status;\r
+}\r
+\r
+\r
+/**\r
+  This function allows a caller to extract the current configuration for one\r
+  or more named elements from the target driver.\r
+\r
+\r
+  @param This            Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.\r
+  @param Request         A null-terminated Unicode string in <ConfigRequest> format.\r
+  @param Progress        On return, points to a character in the Request string.\r
+                         Points to the string's null terminator if request was successful.\r
+                         Points to the most recent '&' before the first failing name/value\r
+                         pair (or the beginning of the string if the failure is in the\r
+                         first name/value pair) if the request was not successful.\r
+  @param Results         A null-terminated Unicode string in <ConfigAltResp> format which\r
+                         has all values filled in for the names in the Request string.\r
+                         String to be allocated by the called function.\r
+\r
+  @retval  EFI_SUCCESS            The Results is filled with the requested values.\r
+  @retval  EFI_OUT_OF_RESOURCES   Not enough memory to store the results.\r
+  @retval  EFI_INVALID_PARAMETER  Request is illegal syntax, or unknown name.\r
+  @retval  EFI_NOT_FOUND          Routing data doesn't match any storage in this driver.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+FakeExtractConfig (\r
+  IN  CONST EFI_HII_CONFIG_ACCESS_PROTOCOL   *This,\r
+  IN  CONST EFI_STRING                       Request,\r
+  OUT EFI_STRING                             *Progress,\r
+  OUT EFI_STRING                             *Results\r
+  )\r
+{\r
+  if (Progress == NULL || Results == NULL) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+  *Progress = Request;\r
+  return EFI_NOT_FOUND;\r
+}\r
+\r
+/**\r
+  This function processes the results of changes in configuration.\r
+\r
+\r
+  @param This            Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.\r
+  @param Configuration   A null-terminated Unicode string in <ConfigResp> format.\r
+  @param Progress        A pointer to a string filled in with the offset of the most\r
+                         recent '&' before the first failing name/value pair (or the\r
+                         beginning of the string if the failure is in the first\r
+                         name/value pair) or the terminating NULL if all was successful.\r
+\r
+  @retval  EFI_SUCCESS            The Results is processed successfully.\r
+  @retval  EFI_INVALID_PARAMETER  Configuration is NULL.\r
+  @retval  EFI_NOT_FOUND          Routing data doesn't match any storage in this driver.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+FakeRouteConfig (\r
+  IN  CONST EFI_HII_CONFIG_ACCESS_PROTOCOL   *This,\r
+  IN  CONST EFI_STRING                       Configuration,\r
+  OUT EFI_STRING                             *Progress\r
+  )\r
+{\r
+  if (Configuration == NULL || Progress == NULL) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  return EFI_NOT_FOUND;\r
+}\r
+\r
+\r
+/**\r
+  Main entry for this driver.\r
+\r
+  @param ImageHandle     Image handle this driver.\r
+  @param SystemTable     Pointer to SystemTable.\r
+\r
+  @retval EFI_SUCESS     This function always complete successfully.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+UserProfileManagerInit (\r
+  IN EFI_HANDLE                       ImageHandle,\r
+  IN EFI_SYSTEM_TABLE                 *SystemTable\r
+  )\r
+{\r
+  EFI_STATUS                          Status;\r
+  USER_PROFILE_MANAGER_CALLBACK_INFO  *CallbackInfo;\r
+\r
+  Status = gBS->LocateProtocol (\r
+                  &gEfiUserManagerProtocolGuid,\r
+                  NULL,\r
+                  (VOID **) &mUserManager\r
+                  );\r
+  if (EFI_ERROR (Status)) {\r
+    return EFI_SUCCESS;\r
+  }\r
+  \r
+  //\r
+  // Initialize driver private data.\r
+  //\r
+  ZeroMem (&mUserInfo, sizeof (mUserInfo));\r
+  ZeroMem (&mAccessInfo, sizeof (mAccessInfo));\r
+\r
+  CallbackInfo = AllocateZeroPool (sizeof (USER_PROFILE_MANAGER_CALLBACK_INFO));\r
+  ASSERT (CallbackInfo != NULL);  \r
+\r
+  CallbackInfo->Signature                   = USER_PROFILE_MANAGER_SIGNATURE;\r
+  CallbackInfo->ConfigAccess.ExtractConfig  = FakeExtractConfig;\r
+  CallbackInfo->ConfigAccess.RouteConfig    = FakeRouteConfig;\r
+  CallbackInfo->ConfigAccess.Callback       = UserProfileManagerCallback;\r
+  CallbackInfo->DriverHandle                = NULL;\r
+  \r
+  //\r
+  // Install Device Path Protocol and Config Access protocol to driver handle.\r
+  //\r
+  Status = gBS->InstallMultipleProtocolInterfaces (\r
+                  &CallbackInfo->DriverHandle,\r
+                  &gEfiDevicePathProtocolGuid,\r
+                  &mHiiVendorDevicePath,\r
+                  &gEfiHiiConfigAccessProtocolGuid,\r
+                  &CallbackInfo->ConfigAccess,\r
+                  NULL\r
+                  );\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
+  //\r
+  // Publish HII data.\r
+  //\r
+  CallbackInfo->HiiHandle = HiiAddPackages (\r
+                              &mUserProfileManagerGuid,\r
+                              CallbackInfo->DriverHandle,\r
+                              UserProfileManagerStrings,\r
+                              UserProfileManagerVfrBin,\r
+                              NULL\r
+                              );\r
+  ASSERT (CallbackInfo->HiiHandle != NULL);                              \r
+  mCallbackInfo = CallbackInfo;\r
+\r
+  return Status;\r
+}\r
+\r
+  \r