/** @file | |
Helper functions for mangling file names in UDF/ECMA-167 file systems. | |
Copyright (C) 2014-2017 Paulo Alcantara <pcacjr@zytor.com> | |
SPDX-License-Identifier: BSD-2-Clause-Patent | |
**/ | |
#include "Udf.h" | |
/** | |
Trim the leading and trailing spaces for a give Unicode string. | |
@param[in] String The Unicode string to trim. | |
@return A pointer to the trimmed string. | |
**/ | |
CHAR16 * | |
TrimString ( | |
IN CHAR16 *String | |
) | |
{ | |
CHAR16 *TempString; | |
for ( ; *String != L'\0' && *String == L' '; String++) { | |
; | |
} | |
TempString = String + StrLen (String) - 1; | |
while ((TempString >= String) && (*TempString == L' ')) { | |
TempString--; | |
} | |
*(TempString + 1) = L'\0'; | |
return String; | |
} | |
/** | |
Replace the content of a Unicode string with the content of another Unicode | |
string. | |
@param[in] Destination A pointer to a Unicode string. | |
@param[in] Source A pointer to a Unicode string. | |
**/ | |
VOID | |
ReplaceLeft ( | |
IN CHAR16 *Destination, | |
IN CONST CHAR16 *Source | |
) | |
{ | |
CONST CHAR16 *EndString; | |
EndString = Source + StrLen (Source); | |
while (Source <= EndString) { | |
*Destination++ = *Source++; | |
} | |
} | |
/** | |
Remove one or more consecutive backslashes starting from the second character | |
of a given Unicode string. | |
@param[in] String A pointer to a Unicode string. | |
@return A pointer to the modified string. | |
**/ | |
CHAR16 * | |
ExcludeTrailingBackslashes ( | |
IN CHAR16 *String | |
) | |
{ | |
CHAR16 *TempString; | |
switch (*(String + 1)) { | |
case L'\\': | |
break; | |
case L'\0': | |
default: | |
String++; | |
goto Exit; | |
} | |
TempString = String; | |
while (*TempString != L'\0' && *TempString == L'\\') { | |
TempString++; | |
} | |
if (TempString - 1 > String) { | |
ReplaceLeft (String + 1, TempString); | |
} | |
String++; | |
Exit: | |
return String; | |
} | |
/** | |
Mangle a filename by cutting off trailing whitespaces, "\\", "." and "..". | |
@param[in] FileName Filename. | |
@retval The mangled Filename. | |
**/ | |
CHAR16 * | |
MangleFileName ( | |
IN CHAR16 *FileName | |
) | |
{ | |
CHAR16 *FileNameSavedPointer; | |
CHAR16 *TempFileName; | |
UINTN BackslashesNo; | |
if (FileName == NULL || *FileName == L'\0') { | |
FileName = NULL; | |
goto Exit; | |
} | |
FileName = TrimString (FileName); | |
if (*FileName == L'\0') { | |
goto Exit; | |
} | |
if ((StrLen (FileName) > 1) && (FileName[StrLen (FileName) - 1] == L'\\')) { | |
FileName[StrLen (FileName) - 1] = L'\0'; | |
} | |
FileNameSavedPointer = FileName; | |
if (FileName[0] == L'.') { | |
if (FileName[1] == L'.') { | |
if (FileName[2] == L'\0') { | |
goto Exit; | |
} else { | |
FileName += 2; | |
} | |
} else if (FileName[1] == L'\0') { | |
goto Exit; | |
} | |
} | |
while (*FileName != L'\0') { | |
if (*FileName == L'\\') { | |
FileName = ExcludeTrailingBackslashes (FileName); | |
} else if (*FileName == L'.') { | |
switch (*(FileName + 1)) { | |
case L'\0': | |
*FileName = L'\0'; | |
break; | |
case L'\\': | |
TempFileName = FileName + 1; | |
TempFileName = ExcludeTrailingBackslashes (TempFileName); | |
ReplaceLeft (FileName, TempFileName); | |
break; | |
case '.': | |
if ((*(FileName - 1) != L'\\') && ((*(FileName + 2) != L'\\') || | |
(*(FileName + 2) != L'\0'))) { | |
FileName++; | |
continue; | |
} | |
BackslashesNo = 0; | |
TempFileName = FileName - 1; | |
while (TempFileName >= FileNameSavedPointer) { | |
if (*TempFileName == L'\\') { | |
if (++BackslashesNo == 2) { | |
break; | |
} | |
} | |
TempFileName--; | |
} | |
TempFileName++; | |
if ((*TempFileName == L'.') && (*(TempFileName + 1) == L'.')) { | |
FileName += 2; | |
} else { | |
if (*(FileName + 2) != L'\0') { | |
ReplaceLeft (TempFileName, FileName + 3); | |
if (*(TempFileName - 1) == L'\\') { | |
FileName = TempFileName; | |
ExcludeTrailingBackslashes (TempFileName - 1); | |
TempFileName = FileName; | |
} | |
} else { | |
*TempFileName = L'\0'; | |
} | |
FileName = TempFileName; | |
} | |
break; | |
default: | |
FileName++; | |
} | |
} else { | |
FileName++; | |
} | |
} | |
FileName = FileNameSavedPointer; | |
if ((StrLen (FileName) > 1) && (FileName [StrLen (FileName) - 1] == L'\\')) { | |
FileName [StrLen (FileName) - 1] = L'\0'; | |
} | |
Exit: | |
return FileName; | |
} |