]> git.proxmox.com Git - mirror_edk2.git/blob - ShellPkg/Library/UefiShellLevel2CommandsLib/Vol.c
e9cd0d098244aff95dd0b63096a1ca2f26884068
[mirror_edk2.git] / ShellPkg / Library / UefiShellLevel2CommandsLib / Vol.c
1 /** @file
2 Main file for vol shell level 2 function.
3
4 Copyright (c) 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 "UefiShellLevel2CommandsLib.h"
16 #include <Guid/FileSystemInfo.h>
17 #include <Guid/FileSystemVolumeLabelInfo.h>
18
19 /**
20 Print the info or change the volume info.
21
22 @param[in] Path String with starting path.
23 @param[in] Delete TRUE to delete the volume label. FALSE otherwise.
24 @param[in] Name New name to set to the volume label.
25
26 @retval SHELL_SUCCESS The operation was sucessful.
27 **/
28 SHELL_STATUS
29 EFIAPI
30 HandleVol(
31 IN CONST CHAR16 *Path,
32 IN CONST BOOLEAN Delete,
33 IN CONST CHAR16 *Name
34 )
35 {
36 EFI_STATUS Status;
37 SHELL_STATUS ShellStatus;
38 EFI_FILE_SYSTEM_INFO *SysInfo;
39 UINTN SysInfoSize;
40 SHELL_FILE_HANDLE ShellFileHandle;
41 EFI_FILE_PROTOCOL *EfiFpHandle;
42 UINTN Size1;
43 UINTN Size2;
44
45 ShellStatus = SHELL_SUCCESS;
46
47 if (
48 StrStr(Name, L"%") != NULL ||
49 StrStr(Name, L"^") != NULL ||
50 StrStr(Name, L"*") != NULL ||
51 StrStr(Name, L"+") != NULL ||
52 StrStr(Name, L"=") != NULL ||
53 StrStr(Name, L"[") != NULL ||
54 StrStr(Name, L"]") != NULL ||
55 StrStr(Name, L"|") != NULL ||
56 StrStr(Name, L":") != NULL ||
57 StrStr(Name, L";") != NULL ||
58 StrStr(Name, L"\"") != NULL ||
59 StrStr(Name, L"<") != NULL ||
60 StrStr(Name, L">") != NULL ||
61 StrStr(Name, L"?") != NULL ||
62 StrStr(Name, L"/") != NULL ||
63 StrStr(Name, L" ") != NULL
64 ){
65 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellLevel2HiiHandle, Name);
66 return (SHELL_INVALID_PARAMETER);
67 }
68
69 Status = gEfiShellProtocol->OpenFileByName(
70 Path,
71 &ShellFileHandle,
72 Name != NULL?EFI_FILE_MODE_READ|EFI_FILE_MODE_WRITE:EFI_FILE_MODE_READ);
73
74 if (EFI_ERROR(Status) || ShellFileHandle == NULL) {
75 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_OPEN_FAIL), gShellLevel2HiiHandle, Path);
76 return (SHELL_ACCESS_DENIED);
77 }
78
79 //
80 // Get the Volume Info from ShellFileHandle
81 //
82 SysInfo = NULL;
83 SysInfoSize = 0;
84 EfiFpHandle = ConvertShellHandleToEfiFileProtocol(ShellFileHandle);
85 Status = EfiFpHandle->GetInfo(
86 EfiFpHandle,
87 &gEfiFileSystemInfoGuid,
88 &SysInfoSize,
89 SysInfo);
90
91 if (Status == EFI_BUFFER_TOO_SMALL) {
92 SysInfo = AllocateZeroPool(SysInfoSize);
93 Status = EfiFpHandle->GetInfo(
94 EfiFpHandle,
95 &gEfiFileSystemInfoGuid,
96 &SysInfoSize,
97 SysInfo);
98 }
99
100 if (Delete) {
101 StrCpy ((CHAR16 *) SysInfo->VolumeLabel, L"");
102 SysInfo->Size = SIZE_OF_EFI_FILE_SYSTEM_INFO + StrSize(SysInfo->VolumeLabel);
103 Status = EfiFpHandle->SetInfo(
104 EfiFpHandle,
105 &gEfiFileSystemInfoGuid,
106 (UINTN)SysInfo->Size,
107 SysInfo);
108 } else if (Name != NULL) {
109 Size1 = StrSize(Name);
110 Size2 = StrSize(SysInfo->VolumeLabel);
111 if (Size1 > Size2) {
112 SysInfo = ReallocatePool((UINTN)SysInfo->Size, (UINTN)SysInfo->Size + Size1 - Size2, SysInfo);
113 }
114 StrCpy ((CHAR16 *) SysInfo->VolumeLabel, Name);
115 SysInfo->Size = SIZE_OF_EFI_FILE_SYSTEM_INFO + Size1;
116 Status = EfiFpHandle->SetInfo(
117 EfiFpHandle,
118 &gEfiFileSystemInfoGuid,
119 (UINTN)SysInfo->Size,
120 SysInfo);
121 }
122
123 FreePool(SysInfo);
124
125 if (Delete || Name != NULL) {
126 if (EFI_ERROR(Status)) {
127 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_AD), gShellLevel2HiiHandle, Path);
128 ShellStatus = SHELL_ACCESS_DENIED;
129 }
130 }
131
132 SysInfoSize = 0;
133 SysInfo = NULL;
134
135 Status = EfiFpHandle->GetInfo(
136 EfiFpHandle,
137 &gEfiFileSystemInfoGuid,
138 &SysInfoSize,
139 SysInfo);
140
141 if (Status == EFI_BUFFER_TOO_SMALL) {
142 SysInfo = AllocateZeroPool(SysInfoSize);
143 Status = EfiFpHandle->GetInfo(
144 EfiFpHandle,
145 &gEfiFileSystemInfoGuid,
146 &SysInfoSize,
147 SysInfo);
148 }
149
150 gEfiShellProtocol->CloseFile(ShellFileHandle);
151
152 //
153 // print VolumeInfo table
154 //
155 ShellPrintHiiEx (
156 0,
157 gST->ConOut->Mode->CursorRow,
158 NULL,
159 STRING_TOKEN (STR_VOL_VOLINFO),
160 gShellLevel2HiiHandle,
161 SysInfo->VolumeLabel,
162 SysInfo->ReadOnly?L"r":L"rw",
163 SysInfo->VolumeSize,
164 SysInfo->FreeSpace,
165 SysInfo->BlockSize
166 );
167 SHELL_FREE_NON_NULL(SysInfo);
168
169 return (ShellStatus);
170 }
171
172 STATIC CONST SHELL_PARAM_ITEM ParamList[] = {
173 {L"-d", TypeFlag},
174 {L"-n", TypeValue},
175 {NULL, TypeMax}
176 };
177
178 /**
179 Function for 'Vol' command.
180
181 @param[in] ImageHandle Handle to the Image (NULL if Internal).
182 @param[in] SystemTable Pointer to the System Table (NULL if Internal).
183 **/
184 SHELL_STATUS
185 EFIAPI
186 ShellCommandRunVol (
187 IN EFI_HANDLE ImageHandle,
188 IN EFI_SYSTEM_TABLE *SystemTable
189 )
190 {
191 EFI_STATUS Status;
192 LIST_ENTRY *Package;
193 CHAR16 *ProblemParam;
194 SHELL_STATUS ShellStatus;
195 CONST CHAR16 *PathName;
196 CONST CHAR16 *CurDir;
197 BOOLEAN DeleteMode;
198 CHAR16 *FullPath;
199 CHAR16 *TempSpot;
200 UINTN Length;
201
202 Length = 0;
203 ProblemParam = NULL;
204 ShellStatus = SHELL_SUCCESS;
205 PathName = NULL;
206 CurDir = NULL;
207 FullPath = NULL;
208
209 //
210 // initialize the shell lib (we must be in non-auto-init...)
211 //
212 Status = ShellInitialize();
213 ASSERT_EFI_ERROR(Status);
214
215 //
216 // Fix local copies of the protocol pointers
217 //
218 Status = CommandInit();
219 ASSERT_EFI_ERROR(Status);
220
221 //
222 // parse the command line
223 //
224 Status = ShellCommandLineParse (ParamList, &Package, &ProblemParam, TRUE);
225 if (EFI_ERROR(Status)) {
226 if (Status == EFI_VOLUME_CORRUPTED && ProblemParam != NULL) {
227 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellLevel2HiiHandle, ProblemParam);
228 FreePool(ProblemParam);
229 ShellStatus = SHELL_INVALID_PARAMETER;
230 } else {
231 ASSERT(FALSE);
232 }
233 } else {
234 //
235 // check for "-?"
236 //
237 if (ShellCommandLineGetFlag(Package, L"-?")) {
238 ASSERT(FALSE);
239 }
240
241 if (ShellCommandLineGetCount(Package) > 2) {
242 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellLevel2HiiHandle);
243 ShellStatus = SHELL_INVALID_PARAMETER;
244 } else {
245 PathName = ShellCommandLineGetRawValue(Package, 1);
246 if (PathName == NULL) {
247 CurDir = gEfiShellProtocol->GetCurDir(NULL);
248 if (CurDir == NULL) {
249 ShellStatus = SHELL_NOT_FOUND;
250 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_CWD), gShellLevel2HiiHandle);
251 } else {
252 PathName = CurDir;
253 }
254 }
255 if (PathName != NULL) {
256 TempSpot = StrStr(PathName, L":");
257 if (TempSpot != NULL) {
258 *TempSpot = CHAR_NULL;
259 }
260 TempSpot = StrStr(PathName, L"\\");
261 if (TempSpot != NULL) {
262 *TempSpot = CHAR_NULL;
263 }
264 StrnCatGrow(&FullPath, &Length, PathName, 0);
265 StrnCatGrow(&FullPath, &Length, L":\\", 0);
266 DeleteMode = ShellCommandLineGetFlag(Package, L"-d");
267 if (DeleteMode && ShellCommandLineGetFlag(Package, L"-n")) {
268 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_CON), gShellLevel2HiiHandle);
269 ShellStatus = SHELL_INVALID_PARAMETER;
270 } else if (ShellCommandLineGetFlag(Package, L"-n") && ShellCommandLineGetValue(Package, L"-n") == NULL) {
271 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_VALUE), gShellLevel2HiiHandle, L"-n");
272 ShellStatus = SHELL_INVALID_PARAMETER;
273 } else if (ShellCommandLineGetValue(Package, L"-n") != NULL && StrLen(ShellCommandLineGetValue(Package, L"-n")) > 11) {
274 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM_VAL), gShellLevel2HiiHandle, L"-n");
275 ShellStatus = SHELL_INVALID_PARAMETER;
276 } else if (ShellStatus == SHELL_SUCCESS) {
277 ShellStatus = HandleVol(
278 FullPath,
279 DeleteMode,
280 ShellCommandLineGetValue(Package, L"-n")
281 );
282 }
283 }
284 }
285 }
286
287 SHELL_FREE_NON_NULL(FullPath);
288
289 //
290 // free the command line package
291 //
292 ShellCommandLineFreeVarList (Package);
293
294 return (ShellStatus);
295 }