]> git.proxmox.com Git - mirror_edk2.git/blame - NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrFileUtil.c
NetworkPkg: Fix Duplicate FreePool Error in WCM
[mirror_edk2.git] / NetworkPkg / WifiConnectionManagerDxe / WifiConnectionMgrFileUtil.c
CommitLineData
90b24889
WF
1/** @file\r
2 The file operation functions for WiFi Connection Manager.\r
3\r
4 Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>\r
5\r
6 This program and the accompanying materials\r
7 are licensed and made available under the terms and conditions of the BSD License\r
8 which accompanies this distribution. The full text of the license may be found at\r
9 http://opensource.org/licenses/bsd-license.php.\r
10\r
11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
13\r
14**/\r
15\r
16#include "WifiConnectionMgrFileUtil.h"\r
17\r
18CHAR16* mDerPemEncodedSuffix[] = {\r
19 L".cer",\r
20 L".der",\r
21 L".crt",\r
22 L".pem",\r
23 NULL\r
24};\r
25\r
26/**\r
27 This code checks if the FileSuffix is one of the possible DER/PEM-encoded certificate suffix.\r
28\r
29 @param[in] FileSuffix The suffix of the input certificate file\r
30\r
31 @retval TRUE It's a DER/PEM-encoded certificate.\r
32 @retval FALSE It's NOT a DER/PEM-encoded certificate.\r
33\r
34**/\r
35BOOLEAN\r
36IsDerPemEncodeCertificate (\r
37 IN CONST CHAR16 *FileSuffix\r
38)\r
39{\r
40 UINTN Index;\r
41 for (Index = 0; mDerPemEncodedSuffix[Index] != NULL; Index++) {\r
42 if (StrCmp (FileSuffix, mDerPemEncodedSuffix[Index]) == 0) {\r
43 return TRUE;\r
44 }\r
45 }\r
46 return FALSE;\r
47}\r
48\r
49/**\r
50 Read file content into BufferPtr, the size of the allocate buffer\r
51 is *FileSize plus AddtionAllocateSize.\r
52\r
53 @param[in] FileHandle The file to be read.\r
54 @param[in, out] BufferPtr Pointers to the pointer of allocated buffer.\r
55 @param[out] FileSize Size of input file\r
56 @param[in] AddtionAllocateSize Addtion size the buffer need to be allocated.\r
57 In case the buffer need to contain others besides the file content.\r
58\r
59 @retval EFI_SUCCESS The file was read into the buffer.\r
60 @retval EFI_INVALID_PARAMETER A parameter was invalid.\r
61 @retval EFI_OUT_OF_RESOURCES A memory allocation failed.\r
62 @retval others Unexpected error.\r
63\r
64**/\r
65EFI_STATUS\r
66ReadFileContent (\r
67 IN EFI_FILE_HANDLE FileHandle,\r
68 IN OUT VOID **BufferPtr,\r
69 OUT UINTN *FileSize,\r
70 IN UINTN AddtionAllocateSize\r
71 )\r
72{\r
73 UINTN BufferSize;\r
74 UINT64 SourceFileSize;\r
75 VOID *Buffer;\r
76 EFI_STATUS Status;\r
77\r
78 if ((FileHandle == NULL) || (FileSize == NULL)) {\r
79 return EFI_INVALID_PARAMETER;\r
80 }\r
81\r
82 Buffer = NULL;\r
83\r
84 //\r
85 // Get the file size\r
86 //\r
87 Status = FileHandle->SetPosition (FileHandle, (UINT64) -1);\r
88 if (EFI_ERROR (Status)) {\r
89 goto ON_EXIT;\r
90 }\r
91\r
92 Status = FileHandle->GetPosition (FileHandle, &SourceFileSize);\r
93 if (EFI_ERROR (Status)) {\r
94 goto ON_EXIT;\r
95 }\r
96\r
97 Status = FileHandle->SetPosition (FileHandle, 0);\r
98 if (EFI_ERROR (Status)) {\r
99 goto ON_EXIT;\r
100 }\r
101\r
102 BufferSize = (UINTN) SourceFileSize + AddtionAllocateSize;\r
103 Buffer = AllocateZeroPool(BufferSize);\r
104 if (Buffer == NULL) {\r
105 return EFI_OUT_OF_RESOURCES;\r
106 }\r
107\r
108 BufferSize = (UINTN) SourceFileSize;\r
109 *FileSize = BufferSize;\r
110\r
111 Status = FileHandle->Read (FileHandle, &BufferSize, Buffer);\r
112 if (EFI_ERROR (Status) || BufferSize != *FileSize) {\r
113 FreePool (Buffer);\r
114 Buffer = NULL;\r
115 Status = EFI_BAD_BUFFER_SIZE;\r
116 goto ON_EXIT;\r
117 }\r
118\r
119ON_EXIT:\r
120\r
121 *BufferPtr = Buffer;\r
122 return Status;\r
123}\r
124\r
125/**\r
126 This function converts an input device structure to a Unicode string.\r
127\r
128 @param[in] DevPath A pointer to the device path structure.\r
129\r
130 @return A new allocated Unicode string that represents the device path.\r
131\r
132**/\r
133CHAR16 *\r
134EFIAPI\r
135DevicePathToStr (\r
136 IN EFI_DEVICE_PATH_PROTOCOL *DevPath\r
137 )\r
138{\r
139 return ConvertDevicePathToText (\r
140 DevPath,\r
141 FALSE,\r
142 TRUE\r
143 );\r
144}\r
145\r
146/**\r
147 Extract filename from device path. The returned buffer is allocated using AllocateCopyPool.\r
148 The caller is responsible for freeing the allocated buffer using FreePool(). If return NULL\r
149 means not enough memory resource.\r
150\r
151 @param DevicePath Device path.\r
152\r
153 @retval NULL Not enough memory resourece for AllocateCopyPool.\r
154 @retval Other A new allocated string that represents the file name.\r
155\r
156**/\r
157CHAR16 *\r
158ExtractFileNameFromDevicePath (\r
159 IN EFI_DEVICE_PATH_PROTOCOL *DevicePath\r
160 )\r
161{\r
162 CHAR16 *String;\r
163 CHAR16 *MatchString;\r
164 CHAR16 *LastMatch;\r
165 CHAR16 *FileName;\r
166 UINTN Length;\r
167\r
168 ASSERT(DevicePath != NULL);\r
169\r
170 String = DevicePathToStr(DevicePath);\r
171 if (String == NULL) {\r
172 return NULL;\r
173 }\r
174 MatchString = String;\r
175 LastMatch = String;\r
176 FileName = NULL;\r
177\r
178 while(MatchString != NULL){\r
179 LastMatch = MatchString + 1;\r
180 MatchString = StrStr(LastMatch,L"\\");\r
181 }\r
182\r
183 Length = StrLen(LastMatch);\r
184 FileName = AllocateCopyPool ((Length + 1) * sizeof(CHAR16), LastMatch);\r
185 if (FileName != NULL) {\r
186 *(FileName + Length) = 0;\r
187 }\r
188\r
189 FreePool(String);\r
190\r
191 return FileName;\r
192}\r
193\r
194/**\r
195 Update the form base on the selected file.\r
196\r
197 @param[in] Private The pointer to the global private data structure.\r
198 @param[in] FilePath Point to the file path.\r
199 @param[in] FormId The form needs to display.\r
200\r
201 @retval TRUE Exit caller function.\r
202 @retval FALSE Not exit caller function.\r
203\r
204**/\r
205BOOLEAN\r
206UpdatePage(\r
207 IN WIFI_MGR_PRIVATE_DATA *Private,\r
208 IN EFI_DEVICE_PATH_PROTOCOL *FilePath,\r
209 IN EFI_FORM_ID FormId\r
210 )\r
211{\r
212 CHAR16 *FileName;\r
213 EFI_STATUS Status;\r
214\r
215 FileName = NULL;\r
216\r
217 if (FilePath != NULL) {\r
218 FileName = ExtractFileNameFromDevicePath(FilePath);\r
219 }\r
220 if (FileName == NULL) {\r
221 //\r
222 // FileName = NULL has two cases:\r
223 // 1. FilePath == NULL, not select file.\r
224 // 2. FilePath != NULL, but ExtractFileNameFromDevicePath return NULL not enough memory resource.\r
225 // In these two case, no need to update the form, and exit the caller function.\r
226 //\r
227 return TRUE;\r
228 }\r
229\r
230 //\r
231 // Close the previous file handle before open a new one.\r
232 //\r
233 if (Private->FileContext->FHandle != NULL) {\r
234 Private->FileContext->FHandle->Close (Private->FileContext->FHandle);\r
235 }\r
236 Private->FileContext->FHandle = NULL;\r
237\r
238 Status = EfiOpenFileByDevicePath (\r
239 &FilePath,\r
240 &Private->FileContext->FHandle,\r
241 EFI_FILE_MODE_READ,\r
242 0\r
243 );\r
244 if (EFI_ERROR (Status)) {\r
245 if (FormId == FORMID_ENROLL_CERT) {\r
246 HiiSetString (Private->RegisteredHandle,\r
247 STRING_TOKEN (STR_EAP_ENROLLED_CERT_NAME), L"", NULL);\r
248 } else if (FormId == FORMID_ENROLL_PRIVATE_KEY){\r
249 HiiSetString (Private->RegisteredHandle,\r
250 STRING_TOKEN (STR_EAP_ENROLLED_PRIVATE_KEY_NAME), L"", NULL);\r
251 }\r
252 } else {\r
253\r
254 if (Private->FileContext->FileName != NULL) {\r
255 FreePool (Private->FileContext->FileName);\r
a6c63ee6 256 Private->FileContext->FileName = NULL;\r
90b24889
WF
257 }\r
258 Private->FileContext->FileName = FileName;\r
259\r
260 if (FormId == FORMID_ENROLL_CERT) {\r
261 HiiSetString (Private->RegisteredHandle,\r
262 STRING_TOKEN (STR_EAP_ENROLLED_CERT_NAME), FileName, NULL);\r
263 } else if (FormId == FORMID_ENROLL_PRIVATE_KEY){\r
264 HiiSetString (Private->RegisteredHandle,\r
265 STRING_TOKEN (STR_EAP_ENROLLED_PRIVATE_KEY_NAME), FileName, NULL);\r
266 }\r
267 }\r
268\r
269 return TRUE;\r
270}\r
271\r
272/**\r
273 Update the CA form base on the input file path info.\r
274\r
275 @param[in] Private The pointer to the global private data structure.\r
276 @param[in] FilePath Point to the file path.\r
277\r
278 @retval TRUE Exit caller function.\r
279 @retval FALSE Not exit caller function.\r
280\r
281**/\r
282BOOLEAN\r
283UpdateCAFromFile (\r
284 IN WIFI_MGR_PRIVATE_DATA *Private,\r
285 IN EFI_DEVICE_PATH_PROTOCOL *FilePath\r
286 )\r
287{\r
288 return UpdatePage(Private, FilePath, FORMID_ENROLL_CERT);\r
289}\r
290\r
291/**\r
292 Update the Private Key form base on the input file path info.\r
293\r
294 @param[in] Private The pointer to the global private data structure.\r
295 @param[in] FilePath Point to the file path.\r
296\r
297 @retval TRUE Exit caller function.\r
298 @retval FALSE Not exit caller function.\r
299\r
300**/\r
301BOOLEAN\r
302UpdatePrivateKeyFromFile (\r
303 IN WIFI_MGR_PRIVATE_DATA *Private,\r
304 IN EFI_DEVICE_PATH_PROTOCOL *FilePath\r
305 )\r
306{\r
307 return UpdatePage(Private, FilePath, FORMID_ENROLL_PRIVATE_KEY);\r
308}\r
309\r