1 | /** @file
|
---|
2 | Defines file-path manipulation functions.
|
---|
3 |
|
---|
4 | Copyright (c) 2011 - 2017, Intel Corporation. All rights reserved.<BR>
|
---|
5 | Copyright (c) 2018, Dell Technologies. All rights reserved.<BR>
|
---|
6 | SPDX-License-Identifier: BSD-2-Clause-Patent
|
---|
7 | **/
|
---|
8 | #include <Library/BaseMemoryLib.h>
|
---|
9 | #include <Library/BaseLib.h>
|
---|
10 |
|
---|
11 | /**
|
---|
12 | Removes the last directory or file entry in a path. For a path which is
|
---|
13 | like L"fs0:startup.nsh", it's converted to L"fs0:".
|
---|
14 |
|
---|
15 | @param[in,out] Path A pointer to the path to modify.
|
---|
16 |
|
---|
17 | @retval FALSE Nothing was found to remove.
|
---|
18 | @retval TRUE A directory or file was removed.
|
---|
19 | **/
|
---|
20 | BOOLEAN
|
---|
21 | EFIAPI
|
---|
22 | PathRemoveLastItem(
|
---|
23 | IN OUT CHAR16 *Path
|
---|
24 | )
|
---|
25 | {
|
---|
26 | CHAR16 *Walker;
|
---|
27 | CHAR16 *LastSlash;
|
---|
28 | //
|
---|
29 | // get directory name from path... ('chop' off extra)
|
---|
30 | //
|
---|
31 | for ( Walker = Path, LastSlash = NULL
|
---|
32 | ; Walker != NULL && *Walker != CHAR_NULL
|
---|
33 | ; Walker++
|
---|
34 | ){
|
---|
35 | if (*Walker == L'\\' && *(Walker + 1) != CHAR_NULL) {
|
---|
36 | LastSlash = Walker+1;
|
---|
37 | } else if (*Walker == L':' && *(Walker + 1) != L'\\' && *(Walker + 1) != CHAR_NULL) {
|
---|
38 | LastSlash = Walker+1;
|
---|
39 | }
|
---|
40 | }
|
---|
41 | if (LastSlash != NULL) {
|
---|
42 | *LastSlash = CHAR_NULL;
|
---|
43 | return (TRUE);
|
---|
44 | }
|
---|
45 | return (FALSE);
|
---|
46 | }
|
---|
47 |
|
---|
48 | /**
|
---|
49 | Function to clean up paths.
|
---|
50 |
|
---|
51 | - Single periods in the path are removed.
|
---|
52 | - Double periods in the path are removed along with a single parent directory.
|
---|
53 | - Forward slashes L'/' are converted to backward slashes L'\'.
|
---|
54 |
|
---|
55 | This will be done inline and the existing buffer may be larger than required
|
---|
56 | upon completion.
|
---|
57 |
|
---|
58 | @param[in] Path The pointer to the string containing the path.
|
---|
59 |
|
---|
60 | @return Returns Path, otherwise returns NULL to indicate that an error has occured.
|
---|
61 | **/
|
---|
62 | CHAR16*
|
---|
63 | EFIAPI
|
---|
64 | PathCleanUpDirectories(
|
---|
65 | IN CHAR16 *Path
|
---|
66 | )
|
---|
67 | {
|
---|
68 | CHAR16 *TempString;
|
---|
69 |
|
---|
70 | if (Path == NULL) {
|
---|
71 | return NULL;
|
---|
72 | }
|
---|
73 |
|
---|
74 | //
|
---|
75 | // Replace the '/' with '\'
|
---|
76 | //
|
---|
77 | for (TempString = Path; *TempString != CHAR_NULL; TempString++) {
|
---|
78 | if (*TempString == L'/') {
|
---|
79 | *TempString = L'\\';
|
---|
80 | }
|
---|
81 | }
|
---|
82 |
|
---|
83 | //
|
---|
84 | // Replace the "\\" with "\"
|
---|
85 | //
|
---|
86 | while ((TempString = StrStr (Path, L"\\\\")) != NULL) {
|
---|
87 | CopyMem (TempString, TempString + 1, StrSize (TempString + 1));
|
---|
88 | }
|
---|
89 |
|
---|
90 | //
|
---|
91 | // Remove all the "\.". E.g.: fs0:\abc\.\def\.
|
---|
92 | //
|
---|
93 | while ((TempString = StrStr (Path, L"\\.\\")) != NULL) {
|
---|
94 | CopyMem (TempString, TempString + 2, StrSize (TempString + 2));
|
---|
95 | }
|
---|
96 | if ((StrLen (Path) >= 2) && (StrCmp (Path + StrLen (Path) - 2, L"\\.") == 0)) {
|
---|
97 | Path[StrLen (Path) - 1] = CHAR_NULL;
|
---|
98 | }
|
---|
99 |
|
---|
100 | //
|
---|
101 | // Remove all the "\..". E.g.: fs0:\abc\..\def\..
|
---|
102 | //
|
---|
103 | while (((TempString = StrStr(Path, L"\\..")) != NULL) &&
|
---|
104 | ((*(TempString + 3) == L'\\') || (*(TempString + 3) == CHAR_NULL))
|
---|
105 | ) {
|
---|
106 | *(TempString + 1) = CHAR_NULL;
|
---|
107 | PathRemoveLastItem(Path);
|
---|
108 | if (*(TempString + 3) != CHAR_NULL) {
|
---|
109 | CopyMem (Path + StrLen (Path), TempString + 4, StrSize (TempString + 4));
|
---|
110 | }
|
---|
111 | }
|
---|
112 |
|
---|
113 | return Path;
|
---|
114 | }
|
---|
115 |
|
---|