mirror of
https://github.com/reactos/reactos.git
synced 2024-12-31 19:42:51 +00:00
[RTL]: Implement RtlGetFullPathName_Ustr, not yet used.
[RTL]: Simplify RtlDosSearchPath_U by not using a temporary "char" value, and just reading straight from the string buffer. svn path=/trunk/; revision=52713
This commit is contained in:
parent
7ba859bd6b
commit
094e863db8
1 changed files with 141 additions and 17 deletions
|
@ -29,7 +29,6 @@ static const UNICODE_STRING _condev = RTL_CONSTANT_STRING(L"\\\\.\\CON");
|
|||
static const UNICODE_STRING _unc = RTL_CONSTANT_STRING(L"\\??\\UNC\\");
|
||||
|
||||
const UNICODE_STRING DeviceRootString = RTL_CONSTANT_STRING(L"\\\\.\\");
|
||||
|
||||
const UNICODE_STRING RtlpDosLPTDevice = RTL_CONSTANT_STRING(L"LPT");
|
||||
const UNICODE_STRING RtlpDosCOMDevice = RTL_CONSTANT_STRING(L"COM");
|
||||
const UNICODE_STRING RtlpDosPRNDevice = RTL_CONSTANT_STRING(L"PRN");
|
||||
|
@ -327,6 +326,135 @@ RtlDetermineDosPathNameType_Ustr(IN PCUNICODE_STRING PathString)
|
|||
}
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
RtlpCheckDeviceName(IN PUNICODE_STRING FileName,
|
||||
IN ULONG Length,
|
||||
OUT PBOOLEAN NameInvalid)
|
||||
{
|
||||
PWCHAR Buffer;
|
||||
NTSTATUS Status;
|
||||
|
||||
/* Allocate a large enough buffer */
|
||||
Buffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, FileName->Length);
|
||||
if (Buffer)
|
||||
{
|
||||
/* Assume failure */
|
||||
*NameInvalid = TRUE;
|
||||
|
||||
/* Copy the filename */
|
||||
RtlCopyMemory(Buffer, FileName->Buffer, FileName->Length);
|
||||
|
||||
/* And add a dot at the end */
|
||||
Buffer[Length / sizeof(WCHAR)] = L'.';
|
||||
Buffer[(Length / sizeof(WCHAR)) + 1] = UNICODE_NULL;
|
||||
|
||||
/* Check if the file exists or not */
|
||||
*NameInvalid = RtlDoesFileExists_U(Buffer) ? FALSE: TRUE;
|
||||
|
||||
/* Get rid of the buffer now */
|
||||
Status = RtlFreeHeap(RtlGetProcessHeap(), 0, Buffer);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Assume the name is ok, but fail the call */
|
||||
*NameInvalid = FALSE;
|
||||
Status = STATUS_NO_MEMORY;
|
||||
}
|
||||
|
||||
/* Return the status */
|
||||
return Status;
|
||||
}
|
||||
|
||||
ULONG
|
||||
NTAPI
|
||||
RtlGetFullPathName_Ustr(IN PUNICODE_STRING FileName,
|
||||
IN ULONG Size,
|
||||
IN PWSTR Buffer,
|
||||
OUT PCWSTR *ShortName,
|
||||
OUT PBOOLEAN InvalidName,
|
||||
OUT RTL_PATH_TYPE *PathType)
|
||||
{
|
||||
PWCHAR FileNameBuffer;
|
||||
ULONG FileNameLength, FileNameChars, DosLength, DosLengthOffset, FullLength;
|
||||
WCHAR c;
|
||||
NTSTATUS Status;
|
||||
|
||||
/* For now, assume the name is valid */
|
||||
if (InvalidName) *InvalidName = FALSE;
|
||||
|
||||
/* Handle initial path type and failure case */
|
||||
*PathType = RtlPathTypeUnknown;
|
||||
if (!(Size) || (FileName->Buffer[0] == UNICODE_NULL)) return 0;
|
||||
|
||||
/* Break filename into component parts */
|
||||
FileNameBuffer = FileName->Buffer;
|
||||
FileNameLength = FileName->Length;
|
||||
FileNameChars = FileNameLength / sizeof(WCHAR);
|
||||
|
||||
/* Kill trailing spaces */
|
||||
c = FileNameBuffer[FileNameChars - 1];
|
||||
while ((FileNameLength) && (c != L' '))
|
||||
{
|
||||
/* Keep going, ignoring the spaces */
|
||||
FileNameLength -= sizeof(WCHAR);
|
||||
if (FileNameLength) c = FileNameBuffer[FileNameLength / sizeof(WCHAR) - 1];
|
||||
}
|
||||
|
||||
/* Check if anything is left */
|
||||
if (!FileNameLength ) return 0;
|
||||
|
||||
/* Check if this is a DOS name */
|
||||
DosLength = RtlIsDosDeviceName_Ustr(FileName);
|
||||
if (DosLength)
|
||||
{
|
||||
/* Zero out the short name */
|
||||
if (ShortName) *ShortName = NULL;
|
||||
|
||||
/* See comment for RtlIsDosDeviceName_Ustr if this is confusing... */
|
||||
DosLengthOffset = DosLength >> 16;
|
||||
DosLength = DosLength & 0xFFFF;
|
||||
|
||||
/* Do we have a DOS length, and does the caller want validity? */
|
||||
if ((InvalidName) && (DosLengthOffset))
|
||||
{
|
||||
/* Do the check */
|
||||
Status = RtlpCheckDeviceName(FileName, DosLengthOffset, InvalidName);
|
||||
|
||||
/* If the check failed, or the name is invalid, fail here */
|
||||
if (!NT_SUCCESS(Status)) return 0;
|
||||
if (*InvalidName) return 0;
|
||||
}
|
||||
|
||||
/* Add the size of the device root and check if it fits in the size */
|
||||
FullLength = DosLength + DeviceRootString.Length;
|
||||
if (FullLength < Size)
|
||||
{
|
||||
/* Add the device string */
|
||||
RtlMoveMemory(Buffer, DeviceRootString.Buffer, DeviceRootString.Length);
|
||||
|
||||
/* Now add the DOS device name */
|
||||
RtlMoveMemory((PCHAR)Buffer + DeviceRootString.Length,
|
||||
(PCHAR)FileNameBuffer + DosLengthOffset,
|
||||
DosLength);
|
||||
|
||||
/* Null terminate */
|
||||
*(PWCHAR)((ULONG_PTR)Buffer + FullLength) = UNICODE_NULL;
|
||||
return FullLength;
|
||||
}
|
||||
|
||||
/* Otherwise, there's no space, so return the buffer size needed */
|
||||
if ((FullLength + sizeof(UNICODE_NULL)) > UNICODE_STRING_MAX_BYTES) return 0;
|
||||
return FullLength + sizeof(UNICODE_NULL);
|
||||
}
|
||||
|
||||
/* This should work well enough for our current needs */
|
||||
*PathType = RtlDetermineDosPathNameType_U(FileNameBuffer);
|
||||
|
||||
/* This is disgusting... but avoids re-writing everything */
|
||||
return RtlGetFullPathName_U(FileNameBuffer, Size, Buffer, (PWSTR*)ShortName);
|
||||
}
|
||||
|
||||
/* PUBLIC FUNCTIONS ***********************************************************/
|
||||
|
||||
/*
|
||||
|
@ -1111,11 +1239,10 @@ RtlDosSearchPath_U(IN PCWSTR Path,
|
|||
OUT PWSTR *PartName)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
WCHAR c;
|
||||
ULONG ExtensionLength, Length, FileNameLength, PathLength;
|
||||
UNICODE_STRING TempString;
|
||||
PWCHAR NewBuffer, BufferStart;
|
||||
PCWSTR TempPtr;
|
||||
PCWSTR p;
|
||||
|
||||
/* Check if this is an absolute path */
|
||||
if (RtlDetermineDosPathNameType_U(FileName) != RtlPathTypeRelative)
|
||||
|
@ -1132,20 +1259,19 @@ RtlDosSearchPath_U(IN PCWSTR Path,
|
|||
}
|
||||
|
||||
/* Scan the filename */
|
||||
TempPtr = FileName;
|
||||
c = *TempPtr;
|
||||
while (c)
|
||||
p = FileName;
|
||||
while (*p)
|
||||
{
|
||||
/* Looking for an extension */
|
||||
if (c == '.')
|
||||
if (*p == '.')
|
||||
{
|
||||
/* No extension string needed -- it's part of the filename */
|
||||
Extension = NULL;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
/* Next character */
|
||||
c = *++TempPtr;
|
||||
p++;
|
||||
}
|
||||
|
||||
/* Do we have an extension? */
|
||||
|
@ -1191,21 +1317,19 @@ RtlDosSearchPath_U(IN PCWSTR Path,
|
|||
while (TRUE)
|
||||
{
|
||||
/* Check if we have a valid character */
|
||||
c = *Path;
|
||||
BufferStart = NewBuffer;
|
||||
if (c)
|
||||
if (*Path)
|
||||
{
|
||||
/* Loop as long as there's no semicolon */
|
||||
while (c != ';')
|
||||
while (*Path != ';')
|
||||
{
|
||||
/* Copy the next character */
|
||||
*BufferStart++ = c;
|
||||
c = *++Path;
|
||||
if (!c) break;
|
||||
*BufferStart++ = *Path++;
|
||||
if (!*Path) break;
|
||||
}
|
||||
|
||||
/* We found a semi-colon, to stop path processing on this loop */
|
||||
if (c == ';') ++Path;
|
||||
if (*Path == ';') ++Path;
|
||||
}
|
||||
|
||||
/* Add a terminating slash if needed */
|
||||
|
@ -1215,7 +1339,7 @@ RtlDosSearchPath_U(IN PCWSTR Path,
|
|||
}
|
||||
|
||||
/* Bail out if we reached the end */
|
||||
if (!c) Path = NULL;
|
||||
if (!*Path) Path = NULL;
|
||||
|
||||
/* Copy the file name and check if an extension is needed */
|
||||
RtlCopyMemory(BufferStart, FileName, FileNameLength);
|
||||
|
|
Loading…
Reference in a new issue