]> git.proxmox.com Git - mirror_edk2.git/blob - ShellPkg/Library/UefiShellLevel2CommandsLib/Vol.c
connect - add comments and add input verification
[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 Status = gEfiShellProtocol->OpenFileByName(
48 Path,
49 &ShellFileHandle,
50 Name != NULL?EFI_FILE_MODE_READ|EFI_FILE_MODE_WRITE:EFI_FILE_MODE_READ);
51
52 if (EFI_ERROR(Status) || ShellFileHandle == NULL) {
53 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_OPEN_FAIL), gShellLevel2HiiHandle, Path);
54 ShellStatus = SHELL_ACCESS_DENIED;
55 return (ShellStatus);
56 }
57
58 //
59 // Get the Volume Info from ShellFileHandle
60 //
61 SysInfo = NULL;
62 SysInfoSize = 0;
63 EfiFpHandle = ConvertShellHandleToEfiFileProtocol(ShellFileHandle);
64 Status = EfiFpHandle->GetInfo(
65 EfiFpHandle,
66 &gEfiFileSystemInfoGuid,
67 &SysInfoSize,
68 SysInfo);
69
70 if (Status == EFI_BUFFER_TOO_SMALL) {
71 SysInfo = AllocateZeroPool(SysInfoSize);
72 Status = EfiFpHandle->GetInfo(
73 EfiFpHandle,
74 &gEfiFileSystemInfoGuid,
75 &SysInfoSize,
76 SysInfo);
77 }
78
79 if (Delete) {
80 StrCpy ((CHAR16 *) SysInfo->VolumeLabel, L"");
81 SysInfo->Size = SIZE_OF_EFI_FILE_SYSTEM_INFO + StrSize(SysInfo->VolumeLabel);
82 Status = EfiFpHandle->SetInfo(
83 EfiFpHandle,
84 &gEfiFileSystemInfoGuid,
85 (UINTN)SysInfo->Size,
86 SysInfo);
87 } else if (Name != NULL) {
88 Size1 = StrSize(Name);
89 Size2 = StrSize(SysInfo->VolumeLabel);
90 if (Size1 > Size2) {
91 SysInfo = ReallocatePool((UINTN)SysInfo->Size, (UINTN)SysInfo->Size + Size1 - Size2, SysInfo);
92 }
93 StrCpy ((CHAR16 *) SysInfo->VolumeLabel, Name);
94 SysInfo->Size = SIZE_OF_EFI_FILE_SYSTEM_INFO + Size1;
95 Status = EfiFpHandle->SetInfo(
96 EfiFpHandle,
97 &gEfiFileSystemInfoGuid,
98 (UINTN)SysInfo->Size,
99 SysInfo);
100 }
101
102 FreePool(SysInfo);
103
104 if (Delete || Name != NULL) {
105 if (EFI_ERROR(Status)) {
106 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_AD), gShellLevel2HiiHandle, Path);
107 ShellStatus = SHELL_ACCESS_DENIED;
108 }
109 }
110
111 SysInfo = AllocateZeroPool(SysInfoSize);
112 Status = EfiFpHandle->GetInfo(
113 EfiFpHandle,
114 &gEfiFileSystemInfoGuid,
115 &SysInfoSize,
116 SysInfo);
117
118 gEfiShellProtocol->CloseFile(ShellFileHandle);
119
120 //
121 // print VolumeInfo table
122 //
123 ShellPrintHiiEx (
124 0,
125 gST->ConOut->Mode->CursorRow,
126 NULL,
127 STRING_TOKEN (STR_VOL_VOLINFO),
128 gShellLevel2HiiHandle,
129 SysInfo->VolumeLabel,
130 SysInfo->ReadOnly?L"r":L"rw",
131 SysInfo->VolumeSize,
132 SysInfo->FreeSpace,
133 SysInfo->BlockSize
134 );
135 SHELL_FREE_NON_NULL(SysInfo);
136
137 return (ShellStatus);
138 }
139
140 STATIC CONST SHELL_PARAM_ITEM ParamList[] = {
141 {L"-d", TypeFlag},
142 {L"-n", TypeValue},
143 {NULL, TypeMax}
144 };
145
146 /**
147 Function for 'Vol' command.
148
149 @param[in] ImageHandle Handle to the Image (NULL if Internal).
150 @param[in] SystemTable Pointer to the System Table (NULL if Internal).
151 **/
152 SHELL_STATUS
153 EFIAPI
154 ShellCommandRunVol (
155 IN EFI_HANDLE ImageHandle,
156 IN EFI_SYSTEM_TABLE *SystemTable
157 )
158 {
159 EFI_STATUS Status;
160 LIST_ENTRY *Package;
161 CHAR16 *ProblemParam;
162 SHELL_STATUS ShellStatus;
163 CONST CHAR16 *PathName;
164 CONST CHAR16 *CurDir;
165 BOOLEAN DeleteMode;
166 CHAR16 *FullPath;
167 UINTN Length;
168
169 Length = 0;
170 ProblemParam = NULL;
171 ShellStatus = SHELL_SUCCESS;
172 PathName = NULL;
173 CurDir = NULL;
174 FullPath = NULL;
175
176 //
177 // initialize the shell lib (we must be in non-auto-init...)
178 //
179 Status = ShellInitialize();
180 ASSERT_EFI_ERROR(Status);
181
182 //
183 // Fix local copies of the protocol pointers
184 //
185 Status = CommandInit();
186 ASSERT_EFI_ERROR(Status);
187
188 //
189 // parse the command line
190 //
191 Status = ShellCommandLineParse (ParamList, &Package, &ProblemParam, TRUE);
192 if (EFI_ERROR(Status)) {
193 if (Status == EFI_VOLUME_CORRUPTED && ProblemParam != NULL) {
194 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellLevel2HiiHandle, ProblemParam);
195 FreePool(ProblemParam);
196 ShellStatus = SHELL_INVALID_PARAMETER;
197 } else {
198 ASSERT(FALSE);
199 }
200 } else {
201 //
202 // check for "-?"
203 //
204 if (ShellCommandLineGetFlag(Package, L"-?")) {
205 ASSERT(FALSE);
206 }
207
208 if (ShellCommandLineGetCount(Package) > 2) {
209 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellLevel2HiiHandle);
210 ShellStatus = SHELL_INVALID_PARAMETER;
211 } else {
212 PathName = ShellCommandLineGetRawValue(Package, 1);
213 if (PathName == NULL) {
214 CurDir = gEfiShellProtocol->GetCurDir(NULL);
215 if (CurDir == NULL) {
216 ShellStatus = SHELL_NOT_FOUND;
217 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_CWD), gShellLevel2HiiHandle);
218 } else {
219 PathName = CurDir;
220 }
221 }
222 if (PathName != NULL) {
223 StrnCatGrow(&FullPath, &Length, PathName, StrStr(PathName, L"\\")==NULL?0:StrStr(PathName, L"\\")-PathName+1);
224 if (StrStr(FullPath, L":\\") == NULL) {
225 StrnCatGrow(&FullPath, &Length, L":\\", 0);
226 }
227 DeleteMode = ShellCommandLineGetFlag(Package, L"-d");
228 if (DeleteMode && ShellCommandLineGetFlag(Package, L"-n")) {
229 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_CON), gShellLevel2HiiHandle);
230 ShellStatus = SHELL_INVALID_PARAMETER;
231 } else if (ShellCommandLineGetFlag(Package, L"-n") && ShellCommandLineGetValue(Package, L"-n") == NULL) {
232 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_VALUE), gShellLevel2HiiHandle, L"-n");
233 ShellStatus = SHELL_INVALID_PARAMETER;
234 } else if (ShellCommandLineGetValue(Package, L"-n") != NULL && StrLen(ShellCommandLineGetValue(Package, L"-n")) > 11) {
235 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM_VAL), gShellLevel2HiiHandle, L"-n");
236 ShellStatus = SHELL_INVALID_PARAMETER;
237 } else if (ShellStatus == SHELL_SUCCESS) {
238 ShellStatus = HandleVol(
239 FullPath,
240 DeleteMode,
241 ShellCommandLineGetValue(Package, L"-n")
242 );
243 }
244 }
245 }
246 }
247
248 SHELL_FREE_NON_NULL(FullPath);
249
250 //
251 // free the command line package
252 //
253 ShellCommandLineFreeVarList (Package);
254
255 return (ShellStatus);
256 }