mirror of
https://github.com/reactos/reactos.git
synced 2024-07-31 00:28:56 +00:00
[KERNEL32]
- Fix IN/OUT declaration of parameters for GetFullPathNameA/W - Fix a bad usage of GetFullPathNameW in the GetTempPathW API, where the source and destination buffer for GetFullPathNameW was the same (Yet another Wineism :(( ). On Windows, using the same buffer fills it with a garbled string. Avoid this behaviour on ReactOS too, because internally GetFullPathNameW calls RtlGetFullPathName_U, the latter zeroing-out the destination buffer before usage. [RTL:PATH] See comments of revision r59183 (and in particular, fix some ntdll:RtlDos* path functions). svn path=/trunk/; revision=59193
This commit is contained in:
parent
2370b46e6f
commit
450943cf42
|
@ -986,8 +986,8 @@ DWORD
|
||||||
WINAPI
|
WINAPI
|
||||||
GetFullPathNameA(IN LPCSTR lpFileName,
|
GetFullPathNameA(IN LPCSTR lpFileName,
|
||||||
IN DWORD nBufferLength,
|
IN DWORD nBufferLength,
|
||||||
IN LPSTR lpBuffer,
|
OUT LPSTR lpBuffer,
|
||||||
IN LPSTR *lpFilePart)
|
OUT LPSTR *lpFilePart)
|
||||||
{
|
{
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
PWCHAR Buffer;
|
PWCHAR Buffer;
|
||||||
|
@ -1099,11 +1099,11 @@ DWORD
|
||||||
WINAPI
|
WINAPI
|
||||||
GetFullPathNameW(IN LPCWSTR lpFileName,
|
GetFullPathNameW(IN LPCWSTR lpFileName,
|
||||||
IN DWORD nBufferLength,
|
IN DWORD nBufferLength,
|
||||||
IN LPWSTR lpBuffer,
|
OUT LPWSTR lpBuffer,
|
||||||
OUT LPWSTR *lpFilePart)
|
OUT LPWSTR *lpFilePart)
|
||||||
{
|
{
|
||||||
/* Call Rtl to do the work */
|
/* Call Rtl to do the work */
|
||||||
return RtlGetFullPathName_U((LPWSTR)lpFileName,
|
return RtlGetFullPathName_U(lpFileName,
|
||||||
nBufferLength * sizeof(WCHAR),
|
nBufferLength * sizeof(WCHAR),
|
||||||
lpBuffer,
|
lpBuffer,
|
||||||
lpFilePart) / sizeof(WCHAR);
|
lpFilePart) / sizeof(WCHAR);
|
||||||
|
@ -2079,6 +2079,7 @@ GetTempPathW(IN DWORD count,
|
||||||
static const WCHAR temp[] = { 'T', 'E', 'M', 'P', 0 };
|
static const WCHAR temp[] = { 'T', 'E', 'M', 'P', 0 };
|
||||||
static const WCHAR userprofile[] = { 'U','S','E','R','P','R','O','F','I','L','E',0 };
|
static const WCHAR userprofile[] = { 'U','S','E','R','P','R','O','F','I','L','E',0 };
|
||||||
WCHAR tmp_path[MAX_PATH];
|
WCHAR tmp_path[MAX_PATH];
|
||||||
|
WCHAR full_tmp_path[MAX_PATH];
|
||||||
UINT ret;
|
UINT ret;
|
||||||
|
|
||||||
DPRINT("%u,%p\n", count, path);
|
DPRINT("%u,%p\n", count, path);
|
||||||
|
@ -2087,42 +2088,44 @@ GetTempPathW(IN DWORD count,
|
||||||
!(ret = GetEnvironmentVariableW( temp, tmp_path, MAX_PATH )) &&
|
!(ret = GetEnvironmentVariableW( temp, tmp_path, MAX_PATH )) &&
|
||||||
!(ret = GetEnvironmentVariableW( userprofile, tmp_path, MAX_PATH )) &&
|
!(ret = GetEnvironmentVariableW( userprofile, tmp_path, MAX_PATH )) &&
|
||||||
!(ret = GetWindowsDirectoryW( tmp_path, MAX_PATH )))
|
!(ret = GetWindowsDirectoryW( tmp_path, MAX_PATH )))
|
||||||
|
{
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (ret > MAX_PATH)
|
if (ret > MAX_PATH)
|
||||||
{
|
{
|
||||||
SetLastError(ERROR_FILENAME_EXCED_RANGE);
|
SetLastError(ERROR_FILENAME_EXCED_RANGE);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = GetFullPathNameW(tmp_path, MAX_PATH, tmp_path, NULL);
|
ret = GetFullPathNameW(tmp_path, MAX_PATH, full_tmp_path, NULL);
|
||||||
if (!ret) return 0;
|
if (!ret) return 0;
|
||||||
|
|
||||||
if (ret > MAX_PATH - 2)
|
if (ret > MAX_PATH - 2)
|
||||||
{
|
{
|
||||||
SetLastError(ERROR_FILENAME_EXCED_RANGE);
|
SetLastError(ERROR_FILENAME_EXCED_RANGE);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tmp_path[ret-1] != '\\')
|
if (full_tmp_path[ret-1] != '\\')
|
||||||
{
|
{
|
||||||
tmp_path[ret++] = '\\';
|
full_tmp_path[ret++] = '\\';
|
||||||
tmp_path[ret] = '\0';
|
full_tmp_path[ret] = '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
ret++; /* add space for terminating 0 */
|
ret++; /* add space for terminating 0 */
|
||||||
|
|
||||||
if (count)
|
if (count)
|
||||||
{
|
{
|
||||||
lstrcpynW(path, tmp_path, count);
|
lstrcpynW(path, full_tmp_path, count);
|
||||||
if (count >= ret)
|
if (count >= ret)
|
||||||
ret--; /* return length without 0 */
|
ret--; /* return length without 0 */
|
||||||
else if (count < 4)
|
else if (count < 4)
|
||||||
path[0] = 0; /* avoid returning ambiguous "X:" */
|
path[0] = 0; /* avoid returning ambiguous "X:" */
|
||||||
}
|
}
|
||||||
|
|
||||||
DPRINT("GetTempPathW returning %u, %S\n", ret, path);
|
DPRINT("GetTempPathW returning %u, %S\n", ret, path);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -160,7 +160,7 @@ RtlIsDosDeviceName_Ustr(IN PCUNICODE_STRING PathString)
|
||||||
{
|
{
|
||||||
/* Check if the character is a path or drive separator */
|
/* Check if the character is a path or drive separator */
|
||||||
c = *End;
|
c = *End;
|
||||||
if ((c == '\\') || (c == '/') || ((c == ':') && (End == PathCopy.Buffer + 1)))
|
if (IS_PATH_SEPARATOR(c) || ((c == ':') && (End == PathCopy.Buffer + 1)))
|
||||||
{
|
{
|
||||||
/* Get the next lower case character */
|
/* Get the next lower case character */
|
||||||
End++;
|
End++;
|
||||||
|
@ -422,30 +422,33 @@ RtlpWin32NTNameToNtPathName_U(IN PUNICODE_STRING DosPath,
|
||||||
if (PartName)
|
if (PartName)
|
||||||
{
|
{
|
||||||
/* Loop from the back until we find a path separator */
|
/* Loop from the back until we find a path separator */
|
||||||
p = &NewBuffer[(DosLength - 1) / sizeof (WCHAR)];
|
p = &NewBuffer[DosLength / sizeof(WCHAR)];
|
||||||
while (p > NewBuffer) if (*p-- == '\\') break;
|
while (--p > NewBuffer)
|
||||||
|
|
||||||
/* Was one found? */
|
|
||||||
if (p > NewBuffer)
|
|
||||||
{
|
{
|
||||||
/* Move past it -- anything left? */
|
/* We found a path separator, move past it */
|
||||||
p++;
|
if (*p == OBJ_NAME_PATH_SEPARATOR)
|
||||||
if (!*p)
|
|
||||||
{
|
{
|
||||||
/* The path ends with a path separator, no part name */
|
++p;
|
||||||
*PartName = NULL;
|
break;
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* What follows the path separator is the part name */
|
|
||||||
*PartName = p;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Check whether a separator was found and if something remains */
|
||||||
|
if ((p > NewBuffer) && *p)
|
||||||
|
{
|
||||||
|
/* What follows the path separator is the partial name */
|
||||||
|
*PartName = p;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* The path ends with a path separator, no partial name */
|
||||||
|
*PartName = NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Build the final NT path string */
|
/* Build the final NT path string */
|
||||||
NtPath->Length = (USHORT)DosLength;
|
|
||||||
NtPath->Buffer = NewBuffer;
|
NtPath->Buffer = NewBuffer;
|
||||||
|
NtPath->Length = (USHORT)DosLength;
|
||||||
NtPath->MaximumLength = (USHORT)DosLength + sizeof(UNICODE_NULL);
|
NtPath->MaximumLength = (USHORT)DosLength + sizeof(UNICODE_NULL);
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
@ -574,7 +577,6 @@ RtlpDosPathNameToRelativeNtPathName_Ustr(IN BOOLEAN HaveRelative,
|
||||||
/* Nothing else is expected */
|
/* Nothing else is expected */
|
||||||
default:
|
default:
|
||||||
ASSERT(FALSE);
|
ASSERT(FALSE);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Now copy the prefix and the buffer */
|
/* Now copy the prefix and the buffer */
|
||||||
|
@ -592,7 +594,7 @@ RtlpDosPathNameToRelativeNtPathName_Ustr(IN BOOLEAN HaveRelative,
|
||||||
NtName->Length = (USHORT)Length;
|
NtName->Length = (USHORT)Length;
|
||||||
NtName->MaximumLength = (USHORT)MaxLength;
|
NtName->MaximumLength = (USHORT)MaxLength;
|
||||||
NewBuffer[LengthChars] = UNICODE_NULL;
|
NewBuffer[LengthChars] = UNICODE_NULL;
|
||||||
DPRINT("new buffer: %S\n", NewBuffer);
|
DPRINT("New buffer: %S\n", NewBuffer);
|
||||||
DPRINT("NT Name: %wZ\n", NtName);
|
DPRINT("NT Name: %wZ\n", NtName);
|
||||||
|
|
||||||
/* Check if a partial name was requested */
|
/* Check if a partial name was requested */
|
||||||
|
@ -651,7 +653,7 @@ RtlpDosPathNameToRelativeNtPathName_Ustr(IN BOOLEAN HaveRelative,
|
||||||
RelativeName->RelativeName.Buffer = (PWSTR)((ULONG_PTR)NewBuffer + PrefixLength + FullPath.Length - PrefixCut * sizeof(WCHAR));
|
RelativeName->RelativeName.Buffer = (PWSTR)((ULONG_PTR)NewBuffer + PrefixLength + FullPath.Length - PrefixCut * sizeof(WCHAR));
|
||||||
RelativeName->RelativeName.Length = (USHORT)(PathLength - FullPath.Length);
|
RelativeName->RelativeName.Length = (USHORT)(PathLength - FullPath.Length);
|
||||||
/* If relative name starts with \, skip it */
|
/* If relative name starts with \, skip it */
|
||||||
if (RelativeName->RelativeName.Buffer[0] == L'\\')
|
if (RelativeName->RelativeName.Buffer[0] == OBJ_NAME_PATH_SEPARATOR)
|
||||||
{
|
{
|
||||||
RelativeName->RelativeName.Buffer++;
|
RelativeName->RelativeName.Buffer++;
|
||||||
RelativeName->RelativeName.Length -= sizeof(WCHAR);
|
RelativeName->RelativeName.Length -= sizeof(WCHAR);
|
||||||
|
@ -1121,7 +1123,7 @@ RtlSetCurrentDirectory_U(IN PUNICODE_STRING Path)
|
||||||
FullPath.Length = (USHORT)FullPathLength;
|
FullPath.Length = (USHORT)FullPathLength;
|
||||||
|
|
||||||
/* If full path isn't \ terminated, do it */
|
/* If full path isn't \ terminated, do it */
|
||||||
if (FullPath.Buffer[CharLength - 1] != L'\\')
|
if (FullPath.Buffer[CharLength - 1] != OBJ_NAME_PATH_SEPARATOR)
|
||||||
{
|
{
|
||||||
if ((CharLength + 1) * sizeof(WCHAR) > SavedLength)
|
if ((CharLength + 1) * sizeof(WCHAR) > SavedLength)
|
||||||
{
|
{
|
||||||
|
@ -1129,7 +1131,7 @@ RtlSetCurrentDirectory_U(IN PUNICODE_STRING Path)
|
||||||
goto Leave;
|
goto Leave;
|
||||||
}
|
}
|
||||||
|
|
||||||
FullPath.Buffer[CharLength] = L'\\';
|
FullPath.Buffer[CharLength] = OBJ_NAME_PATH_SEPARATOR;
|
||||||
FullPath.Buffer[CharLength + 1] = UNICODE_NULL;
|
FullPath.Buffer[CharLength + 1] = UNICODE_NULL;
|
||||||
FullPath.Length += sizeof(WCHAR);
|
FullPath.Length += sizeof(WCHAR);
|
||||||
}
|
}
|
||||||
|
@ -1500,6 +1502,9 @@ ULONG NTAPI RtlGetFullPathName_U(
|
||||||
|
|
||||||
if (!name || !*name) return 0;
|
if (!name || !*name) return 0;
|
||||||
|
|
||||||
|
/* Zero out the destination buffer (implies that "name" should be different from "buffer" to get this function well-behaving) */
|
||||||
|
RtlZeroMemory(buffer, size);
|
||||||
|
|
||||||
if (file_part) *file_part = NULL;
|
if (file_part) *file_part = NULL;
|
||||||
|
|
||||||
/* check for DOS device name */
|
/* check for DOS device name */
|
||||||
|
@ -1733,9 +1738,9 @@ RtlDosSearchPath_U(IN PCWSTR Path,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Add a terminating slash if needed */
|
/* Add a terminating slash if needed */
|
||||||
if ((BufferStart != NewBuffer) && (BufferStart[-1] != '\\'))
|
if ((BufferStart != NewBuffer) && (BufferStart[-1] != OBJ_NAME_PATH_SEPARATOR))
|
||||||
{
|
{
|
||||||
*BufferStart++ = '\\';
|
*BufferStart++ = OBJ_NAME_PATH_SEPARATOR;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Bail out if we reached the end */
|
/* Bail out if we reached the end */
|
||||||
|
@ -2051,6 +2056,7 @@ RtlDosSearchPath_Ustr(IN ULONG Flags,
|
||||||
/* Initialize optional arguments */
|
/* Initialize optional arguments */
|
||||||
if (FullNameOut) *FullNameOut = NULL;
|
if (FullNameOut) *FullNameOut = NULL;
|
||||||
if (FilePartSize) *FilePartSize = 0;
|
if (FilePartSize) *FilePartSize = 0;
|
||||||
|
if (LengthNeeded) *LengthNeeded = 0;
|
||||||
if (DynamicString)
|
if (DynamicString)
|
||||||
{
|
{
|
||||||
DynamicString->Length = DynamicString->MaximumLength = 0;
|
DynamicString->Length = DynamicString->MaximumLength = 0;
|
||||||
|
@ -2322,7 +2328,7 @@ RtlDosSearchPath_Ustr(IN ULONG Flags,
|
||||||
&StaticCandidateString,
|
&StaticCandidateString,
|
||||||
Status);
|
Status);
|
||||||
}
|
}
|
||||||
DPRINT("STatus: %lx BUFFER: %S\n", Status, CallerBuffer->Buffer);
|
DPRINT("Status: %lx BUFFER: %S\n", Status, CallerBuffer->Buffer);
|
||||||
goto Quickie;
|
goto Quickie;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
Loading…
Reference in a new issue