]> git.proxmox.com Git - mirror_edk2.git/blame - ShellPkg/Application/Shell/ShellManParser.c
udk2010.up2.shell initial release.
[mirror_edk2.git] / ShellPkg / Application / Shell / ShellManParser.c
CommitLineData
a405b86d 1/** @file\r
2 Provides interface to shell MAN file parser.\r
3\r
4 Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.<BR>\r
5 This program and the accompanying materials\r
6 are licensed and made available under the terms and conditions of the BSD License\r
7 which accompanies this distribution. The full text of the license may be found at\r
8 http://opensource.org/licenses/bsd-license.php\r
9\r
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
12\r
13**/\r
14\r
15#include "Shell.h"\r
16\r
17/**\r
18 Verifies that the filename has .MAN on the end.\r
19\r
20 allocates a new buffer and copies the name (appending .MAN if necessary)\r
21\r
22 ASSERT if ManFileName is NULL\r
23\r
24 @param[in] ManFileName original filename\r
25\r
26 @return the new filename with .man as the extension.\r
27**/\r
28CHAR16 *\r
29EFIAPI\r
30GetManFileName(\r
31 IN CONST CHAR16 *ManFileName\r
32 )\r
33{\r
34 CHAR16 *Buffer;\r
35 ASSERT(ManFileName != NULL);\r
36 //\r
37 // Fix the file name\r
38 //\r
39 if (StrnCmp(ManFileName+StrLen(ManFileName)-4, L".man", 4)==0) {\r
40 Buffer = AllocateZeroPool(StrSize(ManFileName));\r
41 StrCpy(Buffer, ManFileName);\r
42 } else {\r
43 Buffer = AllocateZeroPool(StrSize(ManFileName) + 4*sizeof(CHAR16));\r
44 StrCpy(Buffer, ManFileName);\r
45 StrCat(Buffer, L".man");\r
46 }\r
47 return (Buffer);\r
48}\r
49\r
50/**\r
51 Search the path environment variable for possible locations and test for\r
52 which one contains a man file with the name specified. If a valid file is found\r
53 stop searching and return the (opened) SHELL_FILE_HANDLE for that file.\r
54\r
55 @param[in] FileName Name of the file to find and open.\r
56 @param[out] Handle Pointer to the handle of the found file. The\r
57 value of this is undefined for return values\r
58 except EFI_SUCCESS.\r
59\r
60 @retval EFI_SUCCESS The file was found. Handle is a valid SHELL_FILE_HANDLE\r
61 @retval EFI_INVALID_PARAMETER A parameter had an invalid value.\r
62 @retval EFI_NOT_FOUND The file was not found.\r
63**/\r
64EFI_STATUS\r
65EFIAPI\r
66SearchPathForFile(\r
67 IN CONST CHAR16 *FileName,\r
68 OUT SHELL_FILE_HANDLE *Handle\r
69 )\r
70{\r
71 CHAR16 *FullFileName;\r
72 EFI_STATUS Status;\r
73\r
74 if ( FileName == NULL\r
75 || Handle == NULL\r
76 || StrLen(FileName) == 0\r
77 ){\r
78 return (EFI_INVALID_PARAMETER);\r
79 }\r
80\r
81 FullFileName = ShellFindFilePath(FileName);\r
82 if (FullFileName == NULL) {\r
83 return (EFI_NOT_FOUND);\r
84 }\r
85\r
86 //\r
87 // now open that file\r
88 //\r
89 Status = EfiShellOpenFileByName(FullFileName, Handle, EFI_FILE_MODE_READ);\r
90 FreePool(FullFileName);\r
91\r
92 return (Status);\r
93}\r
94\r
95/**\r
96 parses through Buffer (which is MAN file formatted) and returns the\r
97 detailed help for any sub section specified in the comma seperated list of\r
98 sections provided. If the end of the file or a .TH section is found then\r
99 return.\r
100\r
101 Upon a sucessful return the caller is responsible to free the memory in *HelpText\r
102\r
103 @param[in] Buffer Buffer to read from\r
104 @param[in] Sections name of command's sub sections to find\r
105 @param[in] HelpText pointer to pointer to string where text goes.\r
106 @param[in] HelpSize pointer to size of allocated HelpText (may be updated)\r
107\r
108 @retval EFI_OUT_OF_RESOURCES a memory allocation failed.\r
109 @retval EFI_SUCCESS the section was found and its description sotred in\r
110 an alloceted buffer.\r
111**/\r
112EFI_STATUS\r
113EFIAPI\r
114ManBufferFindSections(\r
115 IN CONST CHAR16 *Buffer,\r
116 IN CONST CHAR16 *Sections,\r
117 IN CHAR16 **HelpText,\r
118 IN UINTN *HelpSize\r
119 )\r
120{\r
121 EFI_STATUS Status;\r
122 CONST CHAR16 *CurrentLocation;\r
123 BOOLEAN CurrentlyReading;\r
124 CHAR16 *SectionName;\r
125 UINTN SectionLen;\r
126 BOOLEAN Found;\r
127 CHAR16 *TempString;\r
128 CHAR16 *TempString2;\r
129\r
130 if ( Buffer == NULL\r
131 || HelpText == NULL\r
132 || HelpSize == NULL\r
133 ){\r
134 return (EFI_INVALID_PARAMETER);\r
135 }\r
136\r
137 Status = EFI_SUCCESS;\r
138 CurrentlyReading = FALSE;\r
139 Found = FALSE;\r
140\r
141 for (CurrentLocation = Buffer,TempString = NULL\r
142 ; CurrentLocation != NULL && *CurrentLocation != CHAR_NULL\r
143 ; CurrentLocation=StrStr(CurrentLocation, L"\r\n"),TempString = NULL\r
144 ){\r
145 while(CurrentLocation[0] == L'\r' || CurrentLocation[0] == L'\n') {\r
146 CurrentLocation++;\r
147 }\r
148 if (CurrentLocation[0] == L'#') {\r
149 //\r
150 // Skip comment lines\r
151 //\r
152 continue;\r
153 }\r
154 if (StrnCmp(CurrentLocation, L".TH", 3) == 0) {\r
155 //\r
156 // we hit the end of this commands section so stop.\r
157 //\r
158 break;\r
159 }\r
160 if (StrnCmp(CurrentLocation, L".SH ", 4) == 0) {\r
161 if (Sections == NULL) {\r
162 CurrentlyReading = TRUE;\r
163 continue;\r
164 } else if (CurrentlyReading) {\r
165 CurrentlyReading = FALSE;\r
166 }\r
167 CurrentLocation += 4;\r
168 //\r
169 // is this a section we want to read in?\r
170 //\r
171 if (StrLen(CurrentLocation)!=0) {\r
172 TempString2 = StrStr(CurrentLocation, L" ");\r
173 TempString2 = MIN(TempString2, StrStr(CurrentLocation, L"\r"));\r
174 TempString2 = MIN(TempString2, StrStr(CurrentLocation, L"\n"));\r
175 ASSERT(TempString == NULL);\r
176 TempString = StrnCatGrow(&TempString, NULL, CurrentLocation, TempString2==NULL?0:TempString2 - CurrentLocation);\r
177 SectionName = TempString;\r
178 SectionLen = StrLen(SectionName);\r
179 SectionName = StrStr(Sections, SectionName);\r
180 if (SectionName == NULL) {\r
181 continue;\r
182 }\r
183 if (*(SectionName + SectionLen) == CHAR_NULL || *(SectionName + SectionLen) == L',') {\r
184 CurrentlyReading = TRUE;\r
185 }\r
186 }\r
187 } else if (CurrentlyReading) {\r
188 Found = TRUE;\r
189 if (StrLen(CurrentLocation)!=0) {\r
190 TempString2 = StrStr(CurrentLocation, L"\r");\r
191 TempString2 = MIN(TempString2, StrStr(CurrentLocation, L"\n"));\r
192 ASSERT(TempString == NULL);\r
193 TempString = StrnCatGrow(&TempString, NULL, CurrentLocation, TempString2==NULL?0:TempString2 - CurrentLocation);\r
194 //\r
195 // copy and save the current line.\r
196 //\r
197 ASSERT((*HelpText == NULL && *HelpSize == 0) || (*HelpText != NULL));\r
198 StrnCatGrow (HelpText, HelpSize, TempString, 0);\r
199 StrnCatGrow (HelpText, HelpSize, L"\r\n", 0);\r
200 }\r
201 }\r
202 SHELL_FREE_NON_NULL(TempString);\r
203 }\r
204 if (!Found && !EFI_ERROR(Status)) {\r
205 return (EFI_NOT_FOUND);\r
206 }\r
207 return (Status);\r
208}\r
209\r
210/**\r
211 parses through the MAN file specified by SHELL_FILE_HANDLE and returns the\r
212 detailed help for any sub section specified in the comma seperated list of\r
213 sections provided. If the end of the file or a .TH section is found then\r
214 return.\r
215\r
216 Upon a sucessful return the caller is responsible to free the memory in *HelpText\r
217\r
218 @param[in] Handle FileHandle to read from\r
219 @param[in] Sections name of command's sub sections to find\r
220 @param[out] HelpText pointer to pointer to string where text goes.\r
221 @param[out] HelpSize pointer to size of allocated HelpText (may be updated)\r
222 @param[in] Ascii TRUE if the file is ASCII, FALSE otherwise.\r
223\r
224 @retval EFI_OUT_OF_RESOURCES a memory allocation failed.\r
225 @retval EFI_SUCCESS the section was found and its description sotred in\r
226 an alloceted buffer.\r
227**/\r
228EFI_STATUS\r
229EFIAPI\r
230ManFileFindSections(\r
231 IN SHELL_FILE_HANDLE Handle,\r
232 IN CONST CHAR16 *Sections,\r
233 OUT CHAR16 **HelpText,\r
234 OUT UINTN *HelpSize,\r
235 IN BOOLEAN Ascii\r
236 )\r
237{\r
238 EFI_STATUS Status;\r
239 CHAR16 *ReadLine;\r
240 UINTN Size;\r
241 BOOLEAN CurrentlyReading;\r
242 CHAR16 *SectionName;\r
243 UINTN SectionLen;\r
244 BOOLEAN Found;\r
245\r
246 if ( Handle == NULL\r
247 || HelpText == NULL\r
248 || HelpSize == NULL\r
249 ){\r
250 return (EFI_INVALID_PARAMETER);\r
251 }\r
252\r
253 Status = EFI_SUCCESS;\r
254 CurrentlyReading = FALSE;\r
255 Size = 1024;\r
256 Found = FALSE;\r
257\r
258 ReadLine = AllocateZeroPool(Size);\r
259 if (ReadLine == NULL) {\r
260 return (EFI_OUT_OF_RESOURCES);\r
261 }\r
262\r
263 for (;!ShellFileHandleEof(Handle);Size = 1024) {\r
264 Status = ShellFileHandleReadLine(Handle, ReadLine, &Size, TRUE, &Ascii);\r
265 if (ReadLine[0] == L'#') {\r
266 //\r
267 // Skip comment lines\r
268 //\r
269 continue;\r
270 }\r
271 //\r
272 // ignore too small of buffer...\r
273 //\r
274 if (Status == EFI_BUFFER_TOO_SMALL) {\r
275 Status = EFI_SUCCESS;\r
276 }\r
277 if (EFI_ERROR(Status)) {\r
278 break;\r
279 } else if (StrnCmp(ReadLine, L".TH", 3) == 0) {\r
280 //\r
281 // we hit the end of this commands section so stop.\r
282 //\r
283 break;\r
284 } else if (StrnCmp(ReadLine, L".SH", 3) == 0) {\r
285 if (Sections == NULL) {\r
286 CurrentlyReading = TRUE;\r
287 continue;\r
288 }\r
289 //\r
290 // we found a section\r
291 //\r
292 if (CurrentlyReading) {\r
293 CurrentlyReading = FALSE;\r
294 }\r
295 //\r
296 // is this a section we want to read in?\r
297 //\r
298 for ( SectionName = ReadLine + 3\r
299 ; *SectionName == L' '\r
300 ; SectionName++);\r
301 SectionLen = StrLen(SectionName);\r
302 SectionName = StrStr(Sections, SectionName);\r
303 if (SectionName == NULL) {\r
304 continue;\r
305 }\r
306 if (*(SectionName + SectionLen) == CHAR_NULL || *(SectionName + SectionLen) == L',') {\r
307 CurrentlyReading = TRUE;\r
308 }\r
309 } else if (CurrentlyReading) {\r
310 Found = TRUE;\r
311 //\r
312 // copy and save the current line.\r
313 //\r
314 ASSERT((*HelpText == NULL && *HelpSize == 0) || (*HelpText != NULL));\r
315 StrnCatGrow (HelpText, HelpSize, ReadLine, 0);\r
316 StrnCatGrow (HelpText, HelpSize, L"\r\n", 0);\r
317 }\r
318 }\r
319 FreePool(ReadLine);\r
320 if (!Found && !EFI_ERROR(Status)) {\r
321 return (EFI_NOT_FOUND);\r
322 }\r
323 return (Status);\r
324}\r
325\r
326/**\r
327 parses through the MAN file formatted Buffer and returns the\r
328 "Brief Description" for the .TH section as specified by Command. If the\r
329 command section is not found return EFI_NOT_FOUND.\r
330\r
331 Upon a sucessful return the caller is responsible to free the memory in *BriefDesc\r
332\r
333 @param[in] Handle Buffer to read from\r
334 @param[in] Command name of command's section to find\r
335 @param[in] BriefDesc pointer to pointer to string where description goes.\r
336 @param[in] BriefSize pointer to size of allocated BriefDesc\r
337\r
338 @retval EFI_OUT_OF_RESOURCES a memory allocation failed.\r
339 @retval EFI_SUCCESS the section was found and its description sotred in\r
340 an alloceted buffer.\r
341**/\r
342EFI_STATUS\r
343EFIAPI\r
344ManBufferFindTitleSection(\r
345 IN CHAR16 **Buffer,\r
346 IN CONST CHAR16 *Command,\r
347 IN CHAR16 **BriefDesc,\r
348 IN UINTN *BriefSize\r
349 )\r
350{\r
351 EFI_STATUS Status;\r
352 CHAR16 *TitleString;\r
353 CHAR16 *TitleEnd;\r
354 CHAR16 *CurrentLocation;\r
355\r
356 if ( Buffer == NULL\r
357 || Command == NULL\r
358 || (BriefDesc != NULL && BriefSize == NULL)\r
359 ){\r
360 return (EFI_INVALID_PARAMETER);\r
361 }\r
362\r
363 Status = EFI_SUCCESS;\r
364\r
365 TitleString = AllocatePool((7*sizeof(CHAR16)) + StrSize(Command));\r
366 if (TitleString == NULL) {\r
367 return (EFI_OUT_OF_RESOURCES);\r
368 }\r
369 StrCpy(TitleString, L".TH ");\r
370 StrCat(TitleString, Command);\r
371 StrCat(TitleString, L" 0 ");\r
372\r
373 CurrentLocation = StrStr(*Buffer, TitleString);\r
374 if (CurrentLocation == NULL){\r
375 Status = EFI_NOT_FOUND;\r
376 } else {\r
377 //\r
378 // we found it so copy out the rest of the line into BriefDesc\r
379 // After skipping any spaces or zeroes\r
380 //\r
381 for (CurrentLocation += StrLen(TitleString)\r
382 ; *CurrentLocation == L' ' || *CurrentLocation == L'0' || *CurrentLocation == L'1' || *CurrentLocation == L'\"'\r
383 ; CurrentLocation++);\r
384\r
385 TitleEnd = StrStr(CurrentLocation, L"\"");\r
386 ASSERT(TitleEnd != NULL);\r
387 if (BriefDesc != NULL) {\r
388 *BriefSize = StrSize(TitleEnd);\r
389 *BriefDesc = AllocateZeroPool(*BriefSize);\r
390 if (*BriefDesc == NULL) {\r
391 Status = EFI_OUT_OF_RESOURCES;\r
392 } else {\r
393 StrnCpy(*BriefDesc, CurrentLocation, TitleEnd-CurrentLocation);\r
394 }\r
395 }\r
396\r
397 for (CurrentLocation = TitleEnd\r
398 ; *CurrentLocation != L'\n'\r
399 ; CurrentLocation++);\r
400 for (\r
401 ; *CurrentLocation == L' ' || *CurrentLocation == L'\n' || *CurrentLocation == L'\r'\r
402 ; CurrentLocation++);\r
403 *Buffer = CurrentLocation;\r
404 }\r
405\r
406 FreePool(TitleString);\r
407 return (Status);\r
408}\r
409\r
410/**\r
411 parses through the MAN file specified by SHELL_FILE_HANDLE and returns the\r
412 "Brief Description" for the .TH section as specified by Command. if the\r
413 command section is not found return EFI_NOT_FOUND.\r
414\r
415 Upon a sucessful return the caller is responsible to free the memory in *BriefDesc\r
416\r
417 @param[in] Handle FileHandle to read from\r
418 @param[in] Command name of command's section to find\r
419 @param[out] BriefDesc pointer to pointer to string where description goes.\r
420 @param[out] BriefSize pointer to size of allocated BriefDesc\r
421 @param[in,out] Ascii TRUE if the file is ASCII, FALSE otherwise, will be\r
422 set if the file handle is at the 0 position.\r
423\r
424 @retval EFI_OUT_OF_RESOURCES a memory allocation failed.\r
425 @retval EFI_SUCCESS the section was found and its description sotred in\r
426 an alloceted buffer.\r
427**/\r
428EFI_STATUS\r
429EFIAPI\r
430ManFileFindTitleSection(\r
431 IN SHELL_FILE_HANDLE Handle,\r
432 IN CONST CHAR16 *Command,\r
433 OUT CHAR16 **BriefDesc OPTIONAL,\r
434 OUT UINTN *BriefSize OPTIONAL,\r
435 IN OUT BOOLEAN *Ascii\r
436 )\r
437{\r
438 EFI_STATUS Status;\r
439 CHAR16 *TitleString;\r
440 CHAR16 *ReadLine;\r
441 UINTN Size;\r
442 CHAR16 *TitleEnd;\r
443 UINTN TitleLen;\r
444 BOOLEAN Found;\r
445\r
446 if ( Handle == NULL\r
447 || Command == NULL\r
448 || (BriefDesc != NULL && BriefSize == NULL)\r
449 ){\r
450 return (EFI_INVALID_PARAMETER);\r
451 }\r
452\r
453 Status = EFI_SUCCESS;\r
454 Size = 1024;\r
455 Found = FALSE;\r
456\r
457 ReadLine = AllocateZeroPool(Size);\r
458 if (ReadLine == NULL) {\r
459 return (EFI_OUT_OF_RESOURCES);\r
460 }\r
461\r
462 TitleString = AllocatePool((4*sizeof(CHAR16)) + StrSize(Command));\r
463 if (TitleString == NULL) {\r
464 FreePool(ReadLine);\r
465 return (EFI_OUT_OF_RESOURCES);\r
466 }\r
467 StrCpy(TitleString, L".TH ");\r
468 StrCat(TitleString, Command);\r
469 TitleLen = StrLen(TitleString);\r
470 for (;!ShellFileHandleEof(Handle);Size = 1024) {\r
471 Status = ShellFileHandleReadLine(Handle, ReadLine, &Size, TRUE, Ascii);\r
472 if (ReadLine[0] == L'#') {\r
473 //\r
474 // Skip comment lines\r
475 //\r
476 continue;\r
477 }\r
478 //\r
479 // ignore too small of buffer...\r
480 //\r
481 if (Status == EFI_BUFFER_TOO_SMALL) {\r
482 Status = EFI_SUCCESS;\r
483 }\r
484 if (EFI_ERROR(Status)) {\r
485 break;\r
486 }\r
487 if (StrnCmp(ReadLine, TitleString, TitleLen) == 0) {\r
488 Found = TRUE;\r
489 //\r
490 // we found it so copy out the rest of the line into BriefDesc\r
491 // After skipping any spaces or zeroes\r
492 //\r
493 for ( TitleEnd = ReadLine+TitleLen\r
494 ; *TitleEnd == L' ' || *TitleEnd == L'0' || *TitleEnd == L'1'\r
495 ; TitleEnd++);\r
496 if (BriefDesc != NULL) {\r
497 *BriefSize = StrSize(TitleEnd);\r
498 *BriefDesc = AllocateZeroPool(*BriefSize);\r
499 if (*BriefDesc == NULL) {\r
500 Status = EFI_OUT_OF_RESOURCES;\r
501 break;\r
502 }\r
503 StrCpy(*BriefDesc, TitleEnd);\r
504 }\r
505 break;\r
506 }\r
507 }\r
508 FreePool(ReadLine);\r
509 FreePool(TitleString);\r
510 if (!Found && !EFI_ERROR(Status)) {\r
511 return (EFI_NOT_FOUND);\r
512 }\r
513 return (Status);\r
514}\r
515\r
516/**\r
517 This function returns the help information for the specified command. The help text\r
518 will be parsed from a UEFI Shell manual page. (see UEFI Shell 2.0 Appendix B)\r
519\r
520 If Sections is specified, then each section name listed will be compared in a casesensitive\r
521 manner, to the section names described in Appendix B. If the section exists,\r
522 it will be appended to the returned help text. If the section does not exist, no\r
523 information will be returned. If Sections is NULL, then all help text information\r
524 available will be returned.\r
525\r
526 if BriefDesc is NULL, then the breif description will not be savedd seperatly,\r
527 but placed first in the main HelpText.\r
528\r
529 @param[in] ManFileName Points to the NULL-terminated UEFI Shell MAN file name.\r
530 @param[in] Command Points to the NULL-terminated UEFI Shell command name.\r
531 @param[in] Sections Points to the NULL-terminated comma-delimited\r
532 section names to return. If NULL, then all\r
533 sections will be returned.\r
534 @param[out] BriefDesc On return, points to a callee-allocated buffer\r
535 containing brief description text.\r
536 @param[out] HelpText On return, points to a callee-allocated buffer\r
537 containing all specified help text.\r
538\r
539 @retval EFI_SUCCESS The help text was returned.\r
540 @retval EFI_OUT_OF_RESOURCES The necessary buffer could not be allocated to hold the\r
541 returned help text.\r
542 @retval EFI_INVALID_PARAMETER HelpText is NULL\r
543 @retval EFI_NOT_FOUND There is no help text available for Command.\r
544**/\r
545EFI_STATUS\r
546EFIAPI\r
547ProcessManFile(\r
548 IN CONST CHAR16 *ManFileName,\r
549 IN CONST CHAR16 *Command,\r
550 IN CONST CHAR16 *Sections OPTIONAL,\r
551 OUT CHAR16 **BriefDesc OPTIONAL,\r
552 OUT CHAR16 **HelpText\r
553 )\r
554{\r
555 CHAR16 *TempString;\r
556 SHELL_FILE_HANDLE FileHandle;\r
557 EFI_STATUS Status;\r
558 UINTN HelpSize;\r
559 UINTN BriefSize;\r
560 BOOLEAN Ascii;\r
561 CHAR16 *TempString2;\r
562 EFI_DEVICE_PATH_PROTOCOL *FileDevPath;\r
563 EFI_DEVICE_PATH_PROTOCOL *DevPath;\r
564\r
565 if ( ManFileName == NULL\r
566 || Command == NULL\r
567 || HelpText == NULL\r
568 ){\r
569 return (EFI_INVALID_PARAMETER);\r
570 }\r
571\r
572 HelpSize = 0;\r
573 BriefSize = 0;\r
574 TempString = NULL;\r
575 //\r
576 // See if it's in HII first\r
577 //\r
578 TempString = ShellCommandGetCommandHelp(Command);\r
579 if (TempString != NULL) {\r
580 TempString2 = TempString;\r
581 Status = ManBufferFindTitleSection(&TempString2, Command, BriefDesc, &BriefSize);\r
582 if (!EFI_ERROR(Status) && HelpText != NULL){\r
583 Status = ManBufferFindSections(TempString2, Sections, HelpText, &HelpSize);\r
584 }\r
585 } else {\r
586 FileHandle = NULL;\r
587 TempString = GetManFileName(ManFileName);\r
588\r
589 Status = SearchPathForFile(TempString, &FileHandle);\r
590 if (EFI_ERROR(Status)) {\r
591 FileDevPath = FileDevicePath(NULL, TempString);\r
592 DevPath = AppendDevicePath (ShellInfoObject.ImageDevPath, FileDevPath);\r
593 Status = InternalOpenFileDevicePath(DevPath, &FileHandle, EFI_FILE_MODE_READ, 0);\r
594 FreePool(FileDevPath);\r
595 FreePool(DevPath);\r
596 }\r
597\r
598 if (!EFI_ERROR(Status)) {\r
599 HelpSize = 0;\r
600 BriefSize = 0;\r
601 Status = ManFileFindTitleSection(FileHandle, Command, BriefDesc, &BriefSize, &Ascii);\r
602 if (!EFI_ERROR(Status) && HelpText != NULL){\r
603 Status = ManFileFindSections(FileHandle, Sections, HelpText, &HelpSize, Ascii);\r
604 }\r
605 ShellInfoObject.NewEfiShellProtocol->CloseFile(FileHandle);\r
606 } else {\r
607 *HelpText = NULL;\r
608 }\r
609 }\r
610 if (TempString != NULL) {\r
611 FreePool(TempString);\r
612 }\r
613\r
614 return (Status);\r
615}\r