Commit | Line | Data |
---|---|---|
99c9b949 PA |
1 | /** @file\r |
2 | Helper functions for mangling file names in UDF/ECMA-167 file systems.\r | |
3 | \r | |
4 | Copyright (C) 2014-2017 Paulo Alcantara <pcacjr@zytor.com>\r | |
5 | \r | |
9d510e61 | 6 | SPDX-License-Identifier: BSD-2-Clause-Patent\r |
99c9b949 PA |
7 | **/\r |
8 | \r | |
9 | #include "Udf.h"\r | |
10 | \r | |
077f8c43 HW |
11 | /**\r |
12 | Trim the leading and trailing spaces for a give Unicode string.\r | |
13 | \r | |
14 | @param[in] String The Unicode string to trim.\r | |
15 | \r | |
16 | @return A pointer to the trimmed string.\r | |
17 | \r | |
18 | **/\r | |
99c9b949 PA |
19 | CHAR16 *\r |
20 | TrimString (\r | |
1436aea4 | 21 | IN CHAR16 *String\r |
99c9b949 PA |
22 | )\r |
23 | {\r | |
1436aea4 | 24 | CHAR16 *TempString;\r |
99c9b949 PA |
25 | \r |
26 | for ( ; *String != L'\0' && *String == L' '; String++) {\r | |
99c9b949 PA |
27 | }\r |
28 | \r | |
29 | TempString = String + StrLen (String) - 1;\r | |
30 | while ((TempString >= String) && (*TempString == L' ')) {\r | |
31 | TempString--;\r | |
32 | }\r | |
33 | \r | |
34 | *(TempString + 1) = L'\0';\r | |
35 | \r | |
36 | return String;\r | |
37 | }\r | |
38 | \r | |
077f8c43 HW |
39 | /**\r |
40 | Replace the content of a Unicode string with the content of another Unicode\r | |
41 | string.\r | |
42 | \r | |
43 | @param[in] Destination A pointer to a Unicode string.\r | |
44 | @param[in] Source A pointer to a Unicode string.\r | |
45 | \r | |
46 | **/\r | |
99c9b949 PA |
47 | VOID\r |
48 | ReplaceLeft (\r | |
1436aea4 MK |
49 | IN CHAR16 *Destination,\r |
50 | IN CONST CHAR16 *Source\r | |
99c9b949 PA |
51 | )\r |
52 | {\r | |
1436aea4 | 53 | CONST CHAR16 *EndString;\r |
99c9b949 PA |
54 | \r |
55 | EndString = Source + StrLen (Source);\r | |
56 | while (Source <= EndString) {\r | |
57 | *Destination++ = *Source++;\r | |
58 | }\r | |
59 | }\r | |
60 | \r | |
077f8c43 HW |
61 | /**\r |
62 | Remove one or more consecutive backslashes starting from the second character\r | |
63 | of a given Unicode string.\r | |
64 | \r | |
65 | @param[in] String A pointer to a Unicode string.\r | |
66 | \r | |
67 | @return A pointer to the modified string.\r | |
68 | \r | |
69 | **/\r | |
99c9b949 PA |
70 | CHAR16 *\r |
71 | ExcludeTrailingBackslashes (\r | |
1436aea4 | 72 | IN CHAR16 *String\r |
99c9b949 PA |
73 | )\r |
74 | {\r | |
1436aea4 | 75 | CHAR16 *TempString;\r |
99c9b949 PA |
76 | \r |
77 | switch (*(String + 1)) {\r | |
1436aea4 MK |
78 | case L'\\':\r |
79 | break;\r | |
80 | case L'\0':\r | |
81 | default:\r | |
82 | String++;\r | |
83 | goto Exit;\r | |
99c9b949 PA |
84 | }\r |
85 | \r | |
86 | TempString = String;\r | |
87 | while (*TempString != L'\0' && *TempString == L'\\') {\r | |
88 | TempString++;\r | |
89 | }\r | |
90 | \r | |
91 | if (TempString - 1 > String) {\r | |
92 | ReplaceLeft (String + 1, TempString);\r | |
93 | }\r | |
94 | \r | |
95 | String++;\r | |
96 | \r | |
97 | Exit:\r | |
98 | return String;\r | |
99 | }\r | |
100 | \r | |
101 | /**\r | |
102 | Mangle a filename by cutting off trailing whitespaces, "\\", "." and "..".\r | |
103 | \r | |
104 | @param[in] FileName Filename.\r | |
105 | \r | |
077f8c43 | 106 | @retval The mangled Filename.\r |
99c9b949 PA |
107 | \r |
108 | **/\r | |
109 | CHAR16 *\r | |
110 | MangleFileName (\r | |
1436aea4 | 111 | IN CHAR16 *FileName\r |
99c9b949 PA |
112 | )\r |
113 | {\r | |
1436aea4 MK |
114 | CHAR16 *FileNameSavedPointer;\r |
115 | CHAR16 *TempFileName;\r | |
116 | UINTN BackslashesNo;\r | |
99c9b949 | 117 | \r |
1436aea4 | 118 | if ((FileName == NULL) || (*FileName == L'\0')) {\r |
99c9b949 PA |
119 | FileName = NULL;\r |
120 | goto Exit;\r | |
121 | }\r | |
122 | \r | |
123 | FileName = TrimString (FileName);\r | |
124 | if (*FileName == L'\0') {\r | |
125 | goto Exit;\r | |
126 | }\r | |
127 | \r | |
128 | if ((StrLen (FileName) > 1) && (FileName[StrLen (FileName) - 1] == L'\\')) {\r | |
129 | FileName[StrLen (FileName) - 1] = L'\0';\r | |
130 | }\r | |
131 | \r | |
132 | FileNameSavedPointer = FileName;\r | |
133 | \r | |
134 | if (FileName[0] == L'.') {\r | |
135 | if (FileName[1] == L'.') {\r | |
136 | if (FileName[2] == L'\0') {\r | |
137 | goto Exit;\r | |
138 | } else {\r | |
139 | FileName += 2;\r | |
140 | }\r | |
141 | } else if (FileName[1] == L'\0') {\r | |
142 | goto Exit;\r | |
143 | }\r | |
144 | }\r | |
145 | \r | |
146 | while (*FileName != L'\0') {\r | |
147 | if (*FileName == L'\\') {\r | |
148 | FileName = ExcludeTrailingBackslashes (FileName);\r | |
149 | } else if (*FileName == L'.') {\r | |
150 | switch (*(FileName + 1)) {\r | |
1436aea4 MK |
151 | case L'\0':\r |
152 | *FileName = L'\0';\r | |
153 | break;\r | |
154 | case L'\\':\r | |
155 | TempFileName = FileName + 1;\r | |
156 | TempFileName = ExcludeTrailingBackslashes (TempFileName);\r | |
157 | ReplaceLeft (FileName, TempFileName);\r | |
158 | break;\r | |
159 | case '.':\r | |
160 | if ((*(FileName - 1) != L'\\') && ((*(FileName + 2) != L'\\') ||\r | |
161 | (*(FileName + 2) != L'\0')))\r | |
162 | {\r | |
163 | FileName++;\r | |
164 | continue;\r | |
99c9b949 PA |
165 | }\r |
166 | \r | |
1436aea4 MK |
167 | BackslashesNo = 0;\r |
168 | TempFileName = FileName - 1;\r | |
169 | while (TempFileName >= FileNameSavedPointer) {\r | |
170 | if (*TempFileName == L'\\') {\r | |
171 | if (++BackslashesNo == 2) {\r | |
172 | break;\r | |
173 | }\r | |
174 | }\r | |
99c9b949 | 175 | \r |
1436aea4 MK |
176 | TempFileName--;\r |
177 | }\r | |
99c9b949 | 178 | \r |
1436aea4 MK |
179 | TempFileName++;\r |
180 | \r | |
181 | if ((*TempFileName == L'.') && (*(TempFileName + 1) == L'.')) {\r | |
182 | FileName += 2;\r | |
99c9b949 | 183 | } else {\r |
1436aea4 MK |
184 | if (*(FileName + 2) != L'\0') {\r |
185 | ReplaceLeft (TempFileName, FileName + 3);\r | |
186 | if (*(TempFileName - 1) == L'\\') {\r | |
187 | FileName = TempFileName;\r | |
188 | ExcludeTrailingBackslashes (TempFileName - 1);\r | |
189 | TempFileName = FileName;\r | |
190 | }\r | |
191 | } else {\r | |
192 | *TempFileName = L'\0';\r | |
193 | }\r | |
99c9b949 | 194 | \r |
1436aea4 MK |
195 | FileName = TempFileName;\r |
196 | }\r | |
99c9b949 | 197 | \r |
1436aea4 MK |
198 | break;\r |
199 | default:\r | |
200 | FileName++;\r | |
99c9b949 PA |
201 | }\r |
202 | } else {\r | |
203 | FileName++;\r | |
204 | }\r | |
205 | }\r | |
206 | \r | |
207 | FileName = FileNameSavedPointer;\r | |
1436aea4 MK |
208 | if ((StrLen (FileName) > 1) && (FileName[StrLen (FileName) - 1] == L'\\')) {\r |
209 | FileName[StrLen (FileName) - 1] = L'\0';\r | |
99c9b949 PA |
210 | }\r |
211 | \r | |
212 | Exit:\r | |
213 | return FileName;\r | |
214 | }\r |