Cc: Paulo Alcantara <pcacjr@zytor.com> Cc: Ruiyu Ni <ruiyu.ni@intel.com> Cc: Star Zeng <star.zeng@intel.com> Cc: Eric Dong <eric.dong@intel.com> Cc: Dandan Bi <dandan.bi@intel.com> Contributed-under: TianoCore Contribution Agreement 1.1 Signed-off-by: Hao Wu <hao.a.wu@intel.com> Reviewed-by: Paulo Alcantara <pcacjr@zytor.com> Reviewed-by: Star Zeng <star.zeng@intel.com>
		
			
				
	
	
		
			221 lines
		
	
	
		
			5.0 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			221 lines
		
	
	
		
			5.0 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /** @file
 | |
|   Helper functions for mangling file names in UDF/ECMA-167 file systems.
 | |
| 
 | |
|   Copyright (C) 2014-2017 Paulo Alcantara <pcacjr@zytor.com>
 | |
| 
 | |
|   This program and the accompanying materials are licensed and made available
 | |
|   under the terms and conditions of the BSD License which accompanies this
 | |
|   distribution.  The full text of the license may be found at
 | |
|   http://opensource.org/licenses/bsd-license.php
 | |
| 
 | |
|   THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, WITHOUT
 | |
|   WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 | |
| **/
 | |
| 
 | |
| #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;
 | |
| }
 |