summaryrefslogtreecommitdiffstats
path: root/MdePkg/Library/BaseLib/FilePaths.c
blob: 43808075e8b1d30fe673aecba0392a311f482323 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
/** @file
  Defines file-path manipulation functions.

  Copyright (c) 2011 - 2017, Intel Corporation. All rights reserved.<BR>
  Copyright (c) 2018, Dell Technologies. All rights reserved.<BR>
  SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#include  <Library/BaseMemoryLib.h>
#include  <Library/BaseLib.h>

/**
  Removes the last directory or file entry in a path. For a path which is
  like L"fs0:startup.nsh", it's converted to L"fs0:".

  @param[in,out] Path     A pointer to the path to modify.

  @retval FALSE     Nothing was found to remove.
  @retval TRUE      A directory or file was removed.
**/
BOOLEAN
EFIAPI
PathRemoveLastItem (
  IN OUT CHAR16  *Path
  )
{
  CHAR16  *Walker;
  CHAR16  *LastSlash;

  //
  // get directory name from path... ('chop' off extra)
  //
  for ( Walker = Path, LastSlash = NULL
        ; Walker != NULL && *Walker != CHAR_NULL
        ; Walker++
        )
  {
    if ((*Walker == L'\\') && (*(Walker + 1) != CHAR_NULL)) {
      LastSlash = Walker+1;
    } else if ((*Walker == L':') && (*(Walker + 1) != L'\\') && (*(Walker + 1) != CHAR_NULL)) {
      LastSlash = Walker+1;
    }
  }

  if (LastSlash != NULL) {
    *LastSlash = CHAR_NULL;
    return (TRUE);
  }

  return (FALSE);
}

/**
  Function to clean up paths.

  - Single periods in the path are removed.
  - Double periods in the path are removed along with a single parent directory.
  - Forward slashes L'/' are converted to backward slashes L'\'.

  This will be done inline and the existing buffer may be larger than required
  upon completion.

  @param[in] Path       The pointer to the string containing the path.

  @return       Returns Path, otherwise returns NULL to indicate that an error has occurred.
**/
CHAR16 *
EFIAPI
PathCleanUpDirectories (
  IN CHAR16  *Path
  )
{
  CHAR16  *TempString;

  if (Path == NULL) {
    return NULL;
  }

  //
  // Replace the '/' with '\'
  //
  for (TempString = Path; *TempString != CHAR_NULL; TempString++) {
    if (*TempString == L'/') {
      *TempString = L'\\';
    }
  }

  //
  // Replace the "\\" with "\"
  //
  while ((TempString = StrStr (Path, L"\\\\")) != NULL) {
    CopyMem (TempString, TempString + 1, StrSize (TempString + 1));
  }

  //
  // Remove all the "\.". E.g.: fs0:\abc\.\def\.
  //
  while ((TempString = StrStr (Path, L"\\.\\")) != NULL) {
    CopyMem (TempString, TempString + 2, StrSize (TempString + 2));
  }

  if ((StrLen (Path) >= 2) && (StrCmp (Path + StrLen (Path) - 2, L"\\.") == 0)) {
    Path[StrLen (Path) - 1] = CHAR_NULL;
  }

  //
  // Remove all the "\..". E.g.: fs0:\abc\..\def\..
  //
  while (((TempString = StrStr (Path, L"\\..")) != NULL) &&
         ((*(TempString + 3) == L'\\') || (*(TempString + 3) == CHAR_NULL))
         )
  {
    *(TempString + 1) = CHAR_NULL;
    PathRemoveLastItem (Path);
    if (*(TempString + 3) != CHAR_NULL) {
      CopyMem (Path + StrLen (Path), TempString + 4, StrSize (TempString + 4));
    }
  }

  return Path;
}