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