1 /** @file
2   The functions to delete a user profile.
3 
4 Copyright (c) 2009 - 2011, Intel Corporation. All rights reserved.<BR>
5 This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution.  The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
9 
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
12 
13 **/
14 
15 #include "UserProfileManager.h"
16 
17 /**
18   Get the username from the specified user.
19 
20   @param[in]   User              Handle of a user profile.
21 
22   @retval EFI_STRING_ID          The String Id of the user's username.
23 
24 **/
25 EFI_STRING_ID
GetUserName(IN EFI_USER_PROFILE_HANDLE User)26 GetUserName (
27   IN  EFI_USER_PROFILE_HANDLE                   User
28   )
29 {
30   EFI_STATUS            Status;
31   EFI_USER_INFO_HANDLE  UserInfo;
32   EFI_USER_INFO         *Info;
33   UINTN                 InfoSize;
34   UINTN                 MemSize;
35   UINTN                 NameLen;
36   CHAR16                UserName[USER_NAME_LENGTH];
37   EFI_STRING_ID         UserId;
38 
39   //
40   // Allocate user information memory.
41   //
42   MemSize = sizeof (EFI_USER_INFO) + 63;
43   Info    = AllocateZeroPool (MemSize);
44   ASSERT (Info != NULL);
45 
46   //
47   // Get user name information.
48   //
49   UserInfo = NULL;
50   while (TRUE) {
51     InfoSize = MemSize;
52     //
53     // Get next user information.
54     //
55     Status = mUserManager->GetNextInfo (
56                              mUserManager,
57                              User,
58                              &UserInfo
59                              );
60     if (EFI_ERROR (Status)) {
61       break;
62     }
63 
64     Status = mUserManager->GetInfo (
65                              mUserManager,
66                              User,
67                              UserInfo,
68                              Info,
69                              &InfoSize
70                              );
71     if (Status == EFI_BUFFER_TOO_SMALL) {
72       MemSize = InfoSize;
73       FreePool (Info);
74       Info = AllocateZeroPool (MemSize);
75       ASSERT (Info != NULL);
76 
77       Status = mUserManager->GetInfo (
78                                mUserManager,
79                                User,
80                                UserInfo,
81                                Info,
82                                &InfoSize
83                                );
84     }
85     //
86     // Check user information.
87     //
88     if (Status == EFI_SUCCESS) {
89       if (Info->InfoType == EFI_USER_INFO_NAME_RECORD) {
90         NameLen = Info->InfoSize - sizeof (EFI_USER_INFO);
91         if (NameLen > USER_NAME_LENGTH * sizeof (CHAR16)) {
92           NameLen = USER_NAME_LENGTH * sizeof (CHAR16);
93         }
94         ASSERT (NameLen >= sizeof (CHAR16));
95         CopyMem (UserName, (UINT8 *) (Info + 1), NameLen);
96         UserName[NameLen / sizeof (CHAR16) - 1] = 0;
97         UserId = HiiSetString (
98                    mCallbackInfo->HiiHandle,
99                    0,
100                    UserName,
101                    NULL
102                    );
103         if (UserId != 0) {
104           FreePool (Info);
105           return UserId;
106         }
107       }
108     }
109   }
110 
111   FreePool (Info);
112   return 0;
113 }
114 
115 
116 /**
117   Add a username item in form.
118 
119   @param[in]  User          Points to the user profile whose username is added.
120   @param[in]  Index         The index of the user in the user name list
121   @param[in]  OpCodeHandle  Points to container for dynamic created opcodes.
122 
123 **/
124 VOID
AddUserToForm(IN EFI_USER_PROFILE_HANDLE User,IN UINT16 Index,IN VOID * OpCodeHandle)125 AddUserToForm (
126   IN  EFI_USER_PROFILE_HANDLE                   User,
127   IN  UINT16                                    Index,
128   IN  VOID                                      *OpCodeHandle
129   )
130 {
131   EFI_STRING_ID NameId;
132 
133   //
134   // Get user name
135   //
136   NameId = GetUserName (User);
137   if (NameId == 0) {
138     return ;
139   }
140 
141   //
142   // Create user name option.
143   //
144   switch (Index & KEY_FIRST_FORM_MASK) {
145   case KEY_MODIFY_USER:
146     HiiCreateGotoOpCode (
147       OpCodeHandle,                   // Container for dynamic created opcodes
148       FORMID_USER_INFO,               // Target Form ID
149       NameId,                         // Prompt text
150       STRING_TOKEN (STR_NULL_STRING), // Help text
151       EFI_IFR_FLAG_CALLBACK,          // Question flag
152       Index                           // Question ID
153       );
154     break;
155 
156   case KEY_DEL_USER:
157     HiiCreateActionOpCode (
158       OpCodeHandle,                   // Container for dynamic created opcodes
159       Index,                          // Question ID
160       NameId,                         // Prompt text
161       STRING_TOKEN (STR_NULL_STRING), // Help text
162       EFI_IFR_FLAG_CALLBACK,          // Question flag
163       0                               // Action String ID
164       );
165     break;
166 
167   default:
168     break;
169   }
170 }
171 
172 
173 /**
174   Delete the user specified by UserIndex in user profile database.
175 
176   @param[in]  UserIndex       The index of user in the user name list
177                               to be deleted.
178 
179 **/
180 VOID
DeleteUser(IN UINT8 UserIndex)181 DeleteUser (
182   IN UINT8                                      UserIndex
183   )
184 {
185   EFI_STATUS              Status;
186   EFI_USER_PROFILE_HANDLE User;
187   EFI_INPUT_KEY           Key;
188   EFI_USER_INFO_HANDLE    UserInfo;
189   EFI_USER_INFO           *Info;
190   UINTN                   InfoSize;
191 
192   //
193   // Find specified user profile and delete it.
194   //
195   User    = NULL;
196   Status  = mUserManager->GetNext (mUserManager, &User);
197   if (EFI_ERROR (Status)) {
198     goto Done;
199   }
200 
201   while (UserIndex > 1) {
202     Status = mUserManager->GetNext (mUserManager, &User);
203     if (EFI_ERROR (Status)) {
204       goto Done;
205     }
206     UserIndex--;
207   }
208 
209   if (UserIndex == 1) {
210     //
211     // Get the identification policy.
212     //
213     Status = FindInfoByType (User, EFI_USER_INFO_IDENTITY_POLICY_RECORD, &UserInfo);
214     if (EFI_ERROR (Status)) {
215       goto Done;
216     }
217 
218     InfoSize = 0;
219     Info = NULL;
220     Status   = mUserManager->GetInfo (mUserManager, User, UserInfo, Info, &InfoSize);
221     if (Status == EFI_BUFFER_TOO_SMALL) {
222       Info = AllocateZeroPool (InfoSize);
223       if (Info == NULL) {
224         goto Done;
225       }
226       Status = mUserManager->GetInfo (mUserManager, User, UserInfo, Info, &InfoSize);
227     }
228 
229     //
230     // Delete the user on the credential providers by its identification policy.
231     //
232     ASSERT (Info != NULL);
233     DeleteCredentialFromProviders ((UINT8 *)(Info + 1), Info->InfoSize - sizeof (EFI_USER_INFO), User);
234     FreePool (Info);
235 
236     Status = mUserManager->Delete (mUserManager, User);
237     if (EFI_ERROR (Status)) {
238       goto Done;
239     }
240     CreatePopUp (
241       EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
242       &Key,
243       L"Delete User Succeed!",
244       L"",
245       L"Please Press Any Key to Continue ...",
246       NULL
247       );
248     return ;
249   }
250 
251 Done:
252   CreatePopUp (
253     EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
254     &Key,
255     L"Delete User Failed!",
256     L"",
257     L"Please Press Any Key to Continue ...",
258     NULL
259     );
260 }
261 
262 
263 /**
264   Display user select form, cab select a user to delete.
265 
266 **/
267 VOID
SelectUserToDelete(VOID)268 SelectUserToDelete (
269   VOID
270   )
271 {
272   EFI_STATUS              Status;
273   UINT8                   Index;
274   EFI_USER_PROFILE_HANDLE User;
275   EFI_USER_PROFILE_HANDLE CurrentUser;
276   VOID                    *StartOpCodeHandle;
277   VOID                    *EndOpCodeHandle;
278   EFI_IFR_GUID_LABEL      *StartLabel;
279   EFI_IFR_GUID_LABEL      *EndLabel;
280 
281   //
282   // Initialize the container for dynamic opcodes.
283   //
284   StartOpCodeHandle = HiiAllocateOpCodeHandle ();
285   ASSERT (StartOpCodeHandle != NULL);
286 
287   EndOpCodeHandle = HiiAllocateOpCodeHandle ();
288   ASSERT (EndOpCodeHandle != NULL);
289 
290   //
291   // Create Hii Extend Label OpCode.
292   //
293   StartLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (
294                                         StartOpCodeHandle,
295                                         &gEfiIfrTianoGuid,
296                                         NULL,
297                                         sizeof (EFI_IFR_GUID_LABEL)
298                                         );
299   StartLabel->ExtendOpCode  = EFI_IFR_EXTEND_OP_LABEL;
300   StartLabel->Number        = LABEL_USER_DEL_FUNC;
301 
302   EndLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (
303                                       EndOpCodeHandle,
304                                       &gEfiIfrTianoGuid,
305                                       NULL,
306                                       sizeof (EFI_IFR_GUID_LABEL)
307                                       );
308   EndLabel->ExtendOpCode  = EFI_IFR_EXTEND_OP_LABEL;
309   EndLabel->Number        = LABEL_END;
310 
311   //
312   // Add each user can be deleted.
313   //
314   User  = NULL;
315   Index = 1;
316   mUserManager->Current (mUserManager, &CurrentUser);
317   while (TRUE) {
318     Status = mUserManager->GetNext (mUserManager, &User);
319     if (EFI_ERROR (Status)) {
320       break;
321     }
322 
323     if (User != CurrentUser) {
324       AddUserToForm (
325         User,
326         (UINT16)(KEY_DEL_USER | KEY_SELECT_USER | Index),
327         StartOpCodeHandle
328         );
329     }
330     Index++;
331   }
332 
333   HiiUpdateForm (
334     mCallbackInfo->HiiHandle, // HII handle
335     &gUserProfileManagerGuid, // Formset GUID
336     FORMID_DEL_USER,          // Form ID
337     StartOpCodeHandle,        // Label for where to insert opcodes
338     EndOpCodeHandle           // Replace data
339     );
340 
341   HiiFreeOpCodeHandle (StartOpCodeHandle);
342   HiiFreeOpCodeHandle (EndOpCodeHandle);
343 }
344