summaryrefslogtreecommitdiff
path: root/StdLib/LibC/Uefi/Devices/Utility/Path.c
diff options
context:
space:
mode:
Diffstat (limited to 'StdLib/LibC/Uefi/Devices/Utility/Path.c')
-rw-r--r--StdLib/LibC/Uefi/Devices/Utility/Path.c431
1 files changed, 0 insertions, 431 deletions
diff --git a/StdLib/LibC/Uefi/Devices/Utility/Path.c b/StdLib/LibC/Uefi/Devices/Utility/Path.c
deleted file mode 100644
index 96392e018d..0000000000
--- a/StdLib/LibC/Uefi/Devices/Utility/Path.c
+++ /dev/null
@@ -1,431 +0,0 @@
-/** @file
- Device Abstraction: Path manipulation utilities.
-
- Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>
- This program and the accompanying materials are licensed and made available under
- the terms and conditions of the BSD License that 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 <Library/BaseLib.h>
-
-#include <LibConfig.h>
-
-#include <errno.h>
-#include <stdlib.h>
-#include <wchar.h>
-#include <wctype.h>
-#include <kfile.h>
-#include <Device/Device.h>
-#include <MainData.h>
-
-/** Identify the type of path pointed to by Path.
-
- Paths are classified based upon their initial character sequences.
- ^\\ Absolute Path
- ^\. Relative Path
- ^[^:\\]: Mapping Path
- .* Relative Path
-
- Mapping paths are broken into two parts at the ':'. The part to the left of the ':'
- is the Map Name, pointed to by Path, and the part to the right of the ':' is pointed
- to by NewPath.
-
- If Path was not a Mapping Path, then NewPath is set to Path.
-
- @param[in] Path Pointer to the path to be classified.
- @param[out] NewPath Pointer to the path portion of a mapping path.
- @param[out] Length Length of the Map Name portion of the path.
-
- @retval PathAbsolute Path is an absolute path. NewPath points to the first '\'.
- @retval PathRelative Path is a relative path. NewPath = Path.
- @retval PathMapping Path is a mapping path. NewPath points to the character following ':'.
- @retval PathError Path is NULL.
-**/
-PATH_CLASS
-EFIAPI
-ClassifyPath(
- IN wchar_t * Path,
- OUT wchar_t ** NewPath,
- OUT int * const Length
- )
-{
- size_t MapLen;
-
- if(Path == NULL) {
- return PathError; // Bad parameter
- }
- if(NewPath != NULL) {
- *NewPath = Path; // Setup default condition
- }
- if((*Path == L'\\') || (*Path == L'\0')) {
- return PathAbsolute;
- }
- if(*Path == L'.') {
- return PathRelative;
- }
- /* The easy stuff has been done, now see if this is a mapping path.
- See if there is a ':' in Path that isn't the first character and is before
- any '\\' characters.
- */
- MapLen = wcscspn(Path, L"\\:");
- if(Length != NULL) {
- *Length = (int)MapLen;
- }
- /* MapLen == 0 means that the first character is a ':'
- == PathLen means that there are no '\\' or ':'
- Otherwise, Path[MapLen] == ':' for a mapping path
- or '\\' for a relative path.
- */
- if(MapLen == 0) {
- return PathError;
- }
- if(Path[MapLen] == L':') {
- if(NewPath != NULL) {
- *NewPath = &Path[MapLen + 1]; // Point to character after then ':'. Might be '\0'.
- }
- return PathMapping;
- }
- return PathRelative;
-}
-
-/* Normalize a narrow-character path and produce a wide-character path
- that has forward slashes replaced with backslashes.
- Backslashes are directory separators in UEFI File Paths.
-
- It is the caller's responsibility to eventually free() the returned buffer.
-
- @param[in] path A pointer to the narrow-character path to be normalized.
-
- @return A pointer to a buffer containing the normalized, wide-character, path.
-*/
-wchar_t *
-NormalizePath( const char *path)
-{
- wchar_t *temp;
- wchar_t *OldPath;
- wchar_t *NewPath;
- size_t Length;
-
- OldPath = AsciiStrToUnicodeStr(path, gMD->UString);
- Length = wcslen(OldPath) + 1;
-
- NewPath = calloc(Length, sizeof(wchar_t));
- if(NewPath != NULL) {
- temp = NewPath;
- for( ; *OldPath; ++OldPath) {
- if(*OldPath == L'/') {
- *temp = L'\\';
- }
- else {
- *temp = *OldPath;
- }
- ++temp;
- }
- }
- else {
- errno = ENOMEM;
- EFIerrno = RETURN_OUT_OF_RESOURCES;
- }
- return NewPath;
-}
-
-/** Process a wide character string representing a Mapping Path and extract the instance number.
-
- The instance number is the sequence of decimal digits immediately to the left
- of the ":" in the Map Name portion of a Mapping Path.
-
- This function is called with a pointer to beginning of the Map Name.
- Thus Path[Length] must be a ':' and Path[Length - 1] must be a decimal digit.
- If either of these are not true, an instance value of 0 is returned.
-
- If Path is NULL, an instance value of 0 is returned.
-
- @param[in] Path Points to the beginning of a Mapping Path
- @param[in] Length Number of valid characters to the left of the ':'
-
- @return Returns either 0 or the value of the contiguous digits to the left of the ':'.
-**/
-int
-EFIAPI
-PathInstance(
- const wchar_t *Path,
- int Length
- )
-{
- wchar_t *temp;
- int instance = 0;
-
- if((Path != NULL) && (Path[Length] == L':') && (Length > 0)) {
- for(temp = __UNCONST(&Path[Length - 1]); Length > 0; --Length) {
- if(!iswdigit(*temp)) {
- break;
- }
- --temp;
- }
- instance = (int)wcstol(temp+1, NULL, 10);
- }
- return instance;
-}
-
-/** Transform a relative path into an absolute path.
-
- If Path is NULL, return NULL.
- Otherwise, pre-pend the CWD to Path then process the resulting path to:
- - Replace "/./" with "/"
- - Replace "/<dirname>/../" with "/"
- - Do not allow one to back up past the root, "/"
-
- Also sets the Current Working Device to the Root Device.
-
- Path must be a previously allocated buffer. PathAdjust will
- allocate a new buffer to hold the results of the transformation
- and free Path. A pointer to the newly allocated buffer is returned.
-
- @param[in] Path A pointer to the path to be transformed. This buffer
- will always be freed.
-
- @return A pointer to a buffer containing the transformed path.
-**/
-wchar_t *
-EFIAPI
-PathAdjust(
- wchar_t *Path
- )
-{
- wchar_t *NewPath;
-
- NewPath = calloc(PATH_MAX, sizeof(wchar_t));
- if(NewPath != NULL) {
- wmemcpy(NewPath, Path, PATH_MAX);
- }
- else {
- errno = ENOMEM;
- }
- free(Path);
- return NewPath;
-}
-
-/** Replace the leading portion of Path with any aliases.
-
- Aliases are read from /etc/fstab. If there is an associated device, the
- Current Working Device is set to that device.
-
- Path must be a previously allocated buffer. PathAlias will
- allocate a new buffer to hold the results of the transformation
- then free Path. A pointer to the newly allocated buffer is returned.
-
- @param[in] Path A pointer to the original, unaliased, path. This
- buffer is always freed.
- @param[out] Node Filled in with a pointer to the Device Node describing
- the device abstraction associated with this path.
-
- @return A pointer to a buffer containing the aliased path.
-**/
-wchar_t *
-EFIAPI
-PathAlias(
- wchar_t *Path,
- DeviceNode **Node
- )
-{
- wchar_t *NewPath;
-
- NewPath = calloc(PATH_MAX, sizeof(wchar_t));
- if(NewPath != NULL) {
- wmemcpy(NewPath, Path, PATH_MAX);
- }
- else {
- errno = ENOMEM;
- }
- free(Path);
- *Node = NULL;
- return NewPath;
-}
-
-/** Parse a path producing the target device, device instance, and file path.
-
- It is the caller's responsibility to free() FullPath and MapPath when they
- are no longer needed.
-
- @param[in] path
- @param[out] FullPath
- @param[out] DevNode
- @param[out] Which
- @param[out] MapPath OPTIONAL. If not NULL, it points to the place to save a pointer
- to the extracted map name. If the path didn't have a map name,
- then *MapPath is set to NULL.
-
- @retval RETURN_SUCCESS The path was parsed successfully.
- @retval RETURN_NOT_FOUND The path does not map to a valid device.
- @retval RETURN_OUT_OF_RESOURCES Insufficient memory to calloc a MapName buffer.
- The errno variable is set to ENOMEM.
- @retval RETURN_INVALID_PARAMETER The path parameter is not valid.
- The errno variable is set to EINVAL.
-**/
-RETURN_STATUS
-EFIAPI
-ParsePath(
- IN const char *path,
- OUT wchar_t **FullPath,
- OUT DeviceNode **DevNode,
- OUT int *Which,
- OUT wchar_t **MapPath
- )
-{
- int MapLen;
- PATH_CLASS PathClass;
- wchar_t *NewPath;
- wchar_t *WPath = NULL;
- wchar_t *MPath = NULL;
- DeviceNode *Node = NULL;
- RETURN_STATUS Status = RETURN_NOT_FOUND;
- int Instance = 0;
- BOOLEAN ReMapped;
-
- ReMapped = FALSE;
-
- // Convert name from MBCS to WCS and change '/' to '\\'
- WPath = NormalizePath( path);
- PathClass = ClassifyPath(WPath, &NewPath, &MapLen);
-
-reclassify:
- switch(PathClass) {
- case PathMapping:
- if(!ReMapped) {
- if((NewPath == NULL) || (*NewPath == L'\0')) { /* Nothing after the ':' */
- PathClass = PathAbsolute;
- }
- else {
- Instance = PathInstance(WPath, MapLen);
- PathClass = ClassifyPath(NewPath, NULL, NULL);
- }
- ReMapped = TRUE;
- if(WPath[MapLen] == L':') {
- // Get the Map Name, including the trailing ':'. */
- MPath = calloc(MapLen+2, sizeof(wchar_t));
- if(MPath != NULL) {
- wmemcpy(MPath, WPath, MapLen+1);
- }
- else {
- errno = ENOMEM;
- Status = RETURN_OUT_OF_RESOURCES;
- break; // Exit the switch(PathClass) statement.
- }
- }
- if(WPath != NewPath) {
- /* Shift the RHS of the path down to the start of the buffer. */
- wmemmove(WPath, NewPath, wcslen(NewPath)+1);
- NewPath = WPath;
- }
- goto reclassify;
- }
- /* Fall through to PathError if Remapped.
- This means that the path looked like "foo:bar:something".
- */
-
- case PathError:
- errno = EINVAL;
- Status = RETURN_INVALID_PARAMETER;
- break;
-
- case PathRelative:
- /* Transform a relative path into an Absolute path.
- Prepends CWD and handles ./ and ../ entries.
- It is the caller's responsibility to free the space
- allocated to WPath.
- */
- WPath = PathAdjust(NewPath); // WPath was malloc()ed by PathAdjust
-
- case PathAbsolute:
- /* Perform any path aliasing. For example: /dev/foo -> { node.foo, "" }
- The current volume and directory are updated in the path as needed.
- It is the caller's responsibility to free the space
- allocated to WPath.
- */
- Status = RETURN_SUCCESS;
- WPath = PathAlias(WPath, &Node); // PathAlias frees its argument and malloc()s a new one.
- break;
- }
- if(!RETURN_ERROR(Status)) {
- *FullPath = WPath;
- *Which = Instance;
- if(MapPath != NULL) {
- *MapPath = MPath;
- }
- else if(MPath != NULL) {
- free(MPath); /* Caller doesn't want it so let MPath go free */
- }
-
- /* At this point, WPath is an absolute path,
- MPath is either NULL or points to the Map Name,
- and Instance is the instance number.
- */
- if(MPath == NULL) {
- /* This is NOT a mapped path. */
- if(Node == NULL) {
- Node = daDefaultDevice;
- }
- if(Node != NULL) {
- Status = RETURN_SUCCESS;
- }
- else {
- Status = RETURN_NOT_FOUND;
- }
- }
- else {
- /* This is a mapped path. */
- Status = __DevSearch( MPath, NULL, &Node);
- if(Status == RETURN_NOT_FOUND) {
- Node = daDefaultDevice;
-
- if(Node != NULL) {
- Status = RETURN_SUCCESS;
- }
- }
- }
- if(DevNode != NULL) {
- *DevNode = Node;
- }
- }
- return Status;
-}
-
-/**
- Parses a normalized wide character path and returns a pointer to the entry
- following the last \. If a \ is not found in the path the return value will
- be the same as the input value. All error conditions return NULL.
-
- The behavior when passing in a path that has not been normalized is undefined.
-
- @param Path - A pointer to a wide character string containing a path to a
- directory or a file.
-
- @return Pointer to the file name or terminal directory. NULL if an error is
- detected.
-**/
-wchar_t *
-EFIAPI
-GetFileNameFromPath (
- const wchar_t *Path
- )
-{
- wchar_t *Tail;
-
- if (Path == NULL) {
- return NULL;
- }
-
- Tail = wcsrchr(Path, L'\\');
- if(Tail == NULL) {
- Tail = (wchar_t *) Path;
- } else {
- // Move to the next character after the '\\' to get the file name.
- Tail++;
- }
-
- return Tail;
-}