+++ /dev/null
-/* $Id: path.c,v 1.4 2002/10/29 04:45:33 rex Exp $
- */
-/*
- * COPYRIGHT: See COPYING in the top level directory
- * PROJECT: ReactOS POSIX+ Subsystem
- * FILE: subsys/psx/lib/psxdll/misc/path.c
- * PURPOSE: POSIX subsystem path utilities
- * PROGRAMMER: KJK::Hyperion <noog@libero.it>
- * UPDATE HISTORY:
- * 31/01/2002: Created
- */
-
-#include <ddk/ntddk.h>
-#include <errno.h>
-#include <string.h>
-#include <psx/stdlib.h>
-#include <psx/pdata.h>
-#include <psx/path.h>
-
-BOOLEAN
-__PdxPosixPathGetNextComponent_U
-(
- IN UNICODE_STRING PathName,
- IN OUT PUNICODE_STRING PathComponent,
- OUT PBOOLEAN TrailingDelimiter OPTIONAL
-)
-{
- int i, j;
- USHORT l = PathName.Length / sizeof(WCHAR);
-
- if(PathComponent->Buffer == 0)
- i = 0;
- else
- i = ((ULONG)PathComponent->Buffer - (ULONG)PathName.Buffer + PathComponent->Length) / sizeof(WCHAR);
-
- /* skip leading empty components */
- while(1)
- if(i >= l)
- {
- PathComponent->Length = PathComponent->MaximumLength = 0;
- return (FALSE);
- }
- else if(IS_CHAR_DELIMITER_U(PathName.Buffer[i]))
- i ++;
- else
- break;
-
- if(i > l)
- {
- PathComponent->Length = PathComponent->MaximumLength = 0;
- return (FALSE);
- }
-
- PathComponent->Buffer = &PathName.Buffer[i];
-
- j = i + 1;
-
- /* advance until the end of the string, or the next delimiter */
- while(1)
- {
- if(j >= l)
- {
-
- if(TrailingDelimiter != 0)
- *TrailingDelimiter = FALSE;
-
- break;
- }
- else if (IS_CHAR_DELIMITER_U(PathName.Buffer[j]))
- {
-
- if(TrailingDelimiter != 0)
- *TrailingDelimiter = TRUE;
-
- break;
- }
- else
- j ++;
- }
-
- PathComponent->Length = PathComponent->MaximumLength = (j - i) * sizeof(WCHAR);
-
- return (TRUE);
-
-}
-
-BOOLEAN
-__PdxPosixPathResolve_U
-(
- IN UNICODE_STRING PathName,
- OUT PUNICODE_STRING ResolvedPathName,
- IN WCHAR PathDelimiter OPTIONAL
-)
-{
- UNICODE_STRING wstrThisComponent = {0, 0, NULL};
- PWCHAR pwcCurPos;
- PWCHAR pwcStartPos;
- BOOLEAN bIsDirectory;
-
- if(PathDelimiter == 0)
- PathDelimiter = L'/';
-
- /* start from the beginning of the return buffer */
- pwcCurPos = ResolvedPathName->Buffer;
-
- /* path begins with a delimiter (absolute path) */
- if(IS_CHAR_DELIMITER_U(PathName.Buffer[0]))
- {
- /* put a delimiter in front of the return buffer */
- *pwcCurPos = PathDelimiter;
- /* move to next character */
- pwcCurPos ++;
- }
-
- pwcStartPos = pwcCurPos;
-
- /* repeat until the end of the path string */
- while(__PdxPosixPathGetNextComponent_U(PathName, &wstrThisComponent, &bIsDirectory))
- {
- /* ".": skip */
- if(IS_COMPONENT_DOT_U(wstrThisComponent))
- continue;
- /* "..": go back to the last component */
- else if(IS_COMPONENT_DOTDOT_U(wstrThisComponent))
- {
- if(pwcCurPos == pwcStartPos)
- continue;
-
- /* skip the last (undefined) character */
- pwcCurPos --;
- /* down to the previous path delimiter */
- do{ pwcCurPos --; }while(!IS_CHAR_DELIMITER_U(*pwcCurPos));
- /* include the delimiter */
- pwcCurPos ++;
- }
- else
- {
- /* copy this component into the return string */
- memcpy
- (
- pwcCurPos,
- wstrThisComponent.Buffer,
- wstrThisComponent.Length
- );
-
- /* move the current position to the end of the string */
- pwcCurPos = (PWCHAR)((PBYTE)pwcCurPos + wstrThisComponent.Length);
-
- /* component had a trailing delimiter */
- if(bIsDirectory)
- {
- /* append a delimiter */
- *pwcCurPos = PathDelimiter;
- /* on to next character */
- pwcCurPos ++;
- }
- }
- }
-
- /* set the return string's length as the byte offset between the initial buffer
- position and the current position */
- ResolvedPathName->Length = ((ULONG)pwcCurPos - (ULONG)ResolvedPathName->Buffer);
-
- return (TRUE);
-
-}
-
-BOOLEAN
-__PdxPosixPathGetNextComponent_A
-(
- IN ANSI_STRING PathName,
- IN OUT PANSI_STRING PathComponent,
- OUT PBOOLEAN TrailingDelimiter OPTIONAL
-)
-{
- int i, j;
-
- if(PathComponent->Buffer == 0)
- i = 0;
- else
- i = ((ULONG)PathComponent->Buffer - (ULONG)PathName.Buffer + PathComponent->Length);
-
- /* skip leading empty components */
- while(1)
- if(i >= PathName.Length)
- {
- PathComponent->Length = PathComponent->MaximumLength = 0;
- return (FALSE);
- }
- else if(IS_CHAR_DELIMITER_A(PathName.Buffer[i]))
- i ++;
- else
- break;
-
- if(i > PathName.Length)
- {
- PathComponent->Length = PathComponent->MaximumLength = 0;
- return (FALSE);
- }
-
- PathComponent->Buffer = &PathName.Buffer[i];
-
- j = i + 1;
-
- /* advance until the end of the string, or the next delimiter */
- while(1)
- {
- if(j >= PathName.Length)
- {
-
- if(TrailingDelimiter != 0)
- *TrailingDelimiter = FALSE;
-
- break;
- }
- else if (IS_CHAR_DELIMITER_A(PathName.Buffer[j]))
- {
-
- if(TrailingDelimiter != 0)
- *TrailingDelimiter = TRUE;
-
- break;
- }
- else
- j ++;
- }
-
- PathComponent->Length = PathComponent->MaximumLength = j - i;
-
- return (TRUE);
-
-}
-
-BOOLEAN
-__PdxPosixPathResolve_A
-(
- IN ANSI_STRING PathName,
- OUT PANSI_STRING ResolvedPathName,
- IN CHAR PathDelimiter OPTIONAL
-)
-{
- ANSI_STRING strThisComponent = {0, 0, NULL};
- PCHAR pcCurPos;
- PCHAR pcStartPos;
- BOOLEAN bIsDirectory;
-
- if(PathDelimiter == 0)
- PathDelimiter = '/';
-
- /* start from the beginning of the return buffer */
- pcCurPos = ResolvedPathName->Buffer;
-
- /* path begins with a delimiter (absolute path) */
- if(IS_CHAR_DELIMITER_A(PathName.Buffer[0]))
- {
- /* put a delimiter in front of the return buffer */
- *pcCurPos = PathDelimiter;
- /* move to next character */
- pcCurPos ++;
- }
-
- pcStartPos = pcCurPos;
-
- /* repeat until the end of the path string */
- while(__PdxPosixPathGetNextComponent_A(PathName, &strThisComponent, &bIsDirectory))
- {
- /* ".": skip */
- if(IS_COMPONENT_DOT_A(strThisComponent))
- continue;
- /* "..": go back to the last component */
- else if(IS_COMPONENT_DOTDOT_A(strThisComponent))
- {
- if(pcCurPos == pcStartPos)
- continue;
-
- /* skip the last (undefined) character */
- pcCurPos --;
- /* down to the previous path delimiter */
- do{ pcCurPos --; }while(!IS_CHAR_DELIMITER_A(*pcCurPos));
- /* include the delimiter */
- pcCurPos ++;
- }
- else
- {
- /* copy this component into the return string */
- strncpy
- (
- pcCurPos,
- strThisComponent.Buffer,
- strThisComponent.Length
- );
-
- /* move the current position to the end of the string */
- pcCurPos = (PCHAR)((PBYTE)pcCurPos + strThisComponent.Length);
-
- /* component had a trailing delimiter */
- if(bIsDirectory)
- {
- /* append a delimiter */
- *pcCurPos = PathDelimiter;
- /* on to next character */
- pcCurPos ++;
- }
- }
- }
-
- /* set the return string's length as the byte offset between the initial buffer
- position and the current position */
- ResolvedPathName->Length = ((ULONG)pcCurPos - (ULONG)ResolvedPathName->Buffer);
-
- return (TRUE);
-
-}
-
-BOOLEAN
-__PdxPosixPathNameToNtPathName
-(
- IN PWCHAR PosixPath,
- OUT PUNICODE_STRING NativePath,
- IN PUNICODE_STRING CurDir OPTIONAL,
- IN PUNICODE_STRING RootDir OPTIONAL
-)
-{
- UNICODE_STRING wstrPosixPath;
- UNICODE_STRING wstrTempString;
-
- /* parameter validation */
- if
- (
- PosixPath == 0 ||
- NativePath == 0 ||
- NativePath->Buffer == 0 ||
- NativePath->MaximumLength == 0 ||
- (RootDir != 0 && RootDir->Buffer == 0)
- )
- {
- errno = EINVAL;
- return (FALSE);
- }
-
- RtlInitUnicodeString(&wstrPosixPath, PosixPath);
-
- /* path is null */
- if(0 == wstrPosixPath.Length)
- {
- errno = EINVAL;
- return (FALSE);
- }
-
- /* first, copy the root path into the return buffer */
- /* if no root dir passed by the caller... */
- if(RootDir == 0)
- /* return buffer too small */
- if(NativePath->MaximumLength < sizeof(WCHAR))
- {
- errno = ENOBUFS;
- return (FALSE);
- }
- /* set the first character to a backslash, and set length accordingly */
- else
- {
- NativePath->Buffer[0] = L'\\';
- NativePath->Length = sizeof(WCHAR);
- }
- /* ... else copy the root dir into the return buffer */
- else
- /* return buffer too small */
- if(NativePath->MaximumLength < RootDir->Length)
- {
- errno = ENOBUFS;
- return (FALSE);
- }
- /* copy the root directory into the return buffer, and set length */
- else
- {
- memcpy(NativePath->Buffer, RootDir->Buffer, RootDir->Length);
- NativePath->Length = RootDir->Length;
- }
-
- /* path is "/" - our work is done */
- if(sizeof(WCHAR) == wstrPosixPath.Length && IS_CHAR_DELIMITER_U(wstrPosixPath.Buffer[0]))
- return (TRUE);
-
- /* temp string pointing to the tail of the return buffer */
- wstrTempString.Length = 0;
- wstrTempString.MaximumLength = NativePath->MaximumLength - NativePath->Length;
- wstrTempString.Buffer = (PWCHAR)(((PBYTE)(NativePath->Buffer)) + NativePath->Length);
-
- /* path begins with '/': absolute path. Append the resolved path to the return buffer */
- if(IS_CHAR_DELIMITER_U(wstrPosixPath.Buffer[0]))
- {
- /* copy the resolved path in the return buffer */
- __PdxPosixPathResolve_U(wstrPosixPath, &wstrTempString, L'\\');
-
- return (TRUE);
- }
- else
- {
- UNICODE_STRING wstrAbsolutePath;
-
- if(CurDir == 0)
- CurDir = __PdxGetCurDir();
-
- /* initialize the buffer for the absolute path */
- wstrAbsolutePath.Length = 0;
- wstrAbsolutePath.MaximumLength = 0xFFFF;
- wstrAbsolutePath.Buffer = __malloc(0xFFFF);
-
- /* if the current directory is not null... */
- if(!(CurDir->Buffer == 0 || CurDir->Length == 0))
- {
- /* copy it into the absolute path buffer */
- memcpy(wstrAbsolutePath.Buffer, CurDir->Buffer, CurDir->Length);
- wstrAbsolutePath.Length += CurDir->Length;
- }
-
- /* not enough space to append an extra slash */
- if((wstrAbsolutePath.MaximumLength - wstrAbsolutePath.Length) < (USHORT)sizeof(WCHAR))
- {
- __free(wstrAbsolutePath.Buffer);
- NativePath->Length = 0;
- errno = ENOBUFS;
- return (FALSE);
- }
-
- /* append an extra slash */
- wstrAbsolutePath.Buffer[wstrAbsolutePath.Length / sizeof(WCHAR)] = L'/';
- wstrAbsolutePath.Length += sizeof(WCHAR);
-
- /* not enough space to copy the relative path */
- if((wstrAbsolutePath.MaximumLength - wstrAbsolutePath.Length) < wstrPosixPath.Length)
- {
- __free(wstrAbsolutePath.Buffer);
- NativePath->Length = 0;
- errno = ENOBUFS;
- return (FALSE);
- }
-
- /* append the relative path to the absolute path */
- memcpy(
- (PWCHAR)(((PBYTE)wstrAbsolutePath.Buffer) + wstrAbsolutePath.Length),
- wstrPosixPath.Buffer,
- wstrPosixPath.Length
- );
- wstrAbsolutePath.Length += wstrPosixPath.Length;
-
- /* resolve the path */
- __PdxPosixPathResolve_U(wstrAbsolutePath, &wstrTempString, L'\\');
-
- __free(wstrAbsolutePath.Buffer);
-
- return (TRUE);
- }
-
- return (FALSE);
-
-}
-
-/* EOF */
-