[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:
Hermès Bélusca-Maïto 2013-06-08 14:48:33 +00:00
parent 2370b46e6f
commit 450943cf42
2 changed files with 66 additions and 57 deletions

View file

@ -986,8 +986,8 @@ DWORD
WINAPI
GetFullPathNameA(IN LPCSTR lpFileName,
IN DWORD nBufferLength,
IN LPSTR lpBuffer,
IN LPSTR *lpFilePart)
OUT LPSTR lpBuffer,
OUT LPSTR *lpFilePart)
{
NTSTATUS Status;
PWCHAR Buffer;
@ -1099,11 +1099,11 @@ DWORD
WINAPI
GetFullPathNameW(IN LPCWSTR lpFileName,
IN DWORD nBufferLength,
IN LPWSTR lpBuffer,
OUT LPWSTR lpBuffer,
OUT LPWSTR *lpFilePart)
{
/* Call Rtl to do the work */
return RtlGetFullPathName_U((LPWSTR)lpFileName,
return RtlGetFullPathName_U(lpFileName,
nBufferLength * sizeof(WCHAR),
lpBuffer,
lpFilePart) / sizeof(WCHAR);
@ -2079,6 +2079,7 @@ GetTempPathW(IN DWORD count,
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 };
WCHAR tmp_path[MAX_PATH];
WCHAR full_tmp_path[MAX_PATH];
UINT ret;
DPRINT("%u,%p\n", count, path);
@ -2087,42 +2088,44 @@ GetTempPathW(IN DWORD count,
!(ret = GetEnvironmentVariableW( temp, tmp_path, MAX_PATH )) &&
!(ret = GetEnvironmentVariableW( userprofile, tmp_path, MAX_PATH )) &&
!(ret = GetWindowsDirectoryW( tmp_path, MAX_PATH )))
{
return 0;
}
if (ret > MAX_PATH)
{
SetLastError(ERROR_FILENAME_EXCED_RANGE);
return 0;
}
if (ret > MAX_PATH)
{
SetLastError(ERROR_FILENAME_EXCED_RANGE);
return 0;
}
ret = GetFullPathNameW(tmp_path, MAX_PATH, tmp_path, NULL);
if (!ret) return 0;
ret = GetFullPathNameW(tmp_path, MAX_PATH, full_tmp_path, NULL);
if (!ret) return 0;
if (ret > MAX_PATH - 2)
{
SetLastError(ERROR_FILENAME_EXCED_RANGE);
return 0;
}
if (ret > MAX_PATH - 2)
{
SetLastError(ERROR_FILENAME_EXCED_RANGE);
return 0;
}
if (tmp_path[ret-1] != '\\')
{
tmp_path[ret++] = '\\';
tmp_path[ret] = '\0';
}
if (full_tmp_path[ret-1] != '\\')
{
full_tmp_path[ret++] = '\\';
full_tmp_path[ret] = '\0';
}
ret++; /* add space for terminating 0 */
ret++; /* add space for terminating 0 */
if (count)
{
lstrcpynW(path, tmp_path, count);
if (count >= ret)
ret--; /* return length without 0 */
else if (count < 4)
path[0] = 0; /* avoid returning ambiguous "X:" */
}
if (count)
{
lstrcpynW(path, full_tmp_path, count);
if (count >= ret)
ret--; /* return length without 0 */
else if (count < 4)
path[0] = 0; /* avoid returning ambiguous "X:" */
}
DPRINT("GetTempPathW returning %u, %S\n", ret, path);
return ret;
DPRINT("GetTempPathW returning %u, %S\n", ret, path);
return ret;
}
/*

View file

@ -160,7 +160,7 @@ RtlIsDosDeviceName_Ustr(IN PCUNICODE_STRING PathString)
{
/* Check if the character is a path or drive separator */
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 */
End++;
@ -422,30 +422,33 @@ RtlpWin32NTNameToNtPathName_U(IN PUNICODE_STRING DosPath,
if (PartName)
{
/* Loop from the back until we find a path separator */
p = &NewBuffer[(DosLength - 1) / sizeof (WCHAR)];
while (p > NewBuffer) if (*p-- == '\\') break;
/* Was one found? */
if (p > NewBuffer)
p = &NewBuffer[DosLength / sizeof(WCHAR)];
while (--p > NewBuffer)
{
/* Move past it -- anything left? */
p++;
if (!*p)
/* We found a path separator, move past it */
if (*p == OBJ_NAME_PATH_SEPARATOR)
{
/* The path ends with a path separator, no part name */
*PartName = NULL;
}
else
{
/* What follows the path separator is the part name */
*PartName = p;
++p;
break;
}
}
/* 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 */
NtPath->Length = (USHORT)DosLength;
NtPath->Buffer = NewBuffer;
NtPath->Length = (USHORT)DosLength;
NtPath->MaximumLength = (USHORT)DosLength + sizeof(UNICODE_NULL);
return STATUS_SUCCESS;
}
@ -574,7 +577,6 @@ RtlpDosPathNameToRelativeNtPathName_Ustr(IN BOOLEAN HaveRelative,
/* Nothing else is expected */
default:
ASSERT(FALSE);
}
/* Now copy the prefix and the buffer */
@ -592,7 +594,7 @@ RtlpDosPathNameToRelativeNtPathName_Ustr(IN BOOLEAN HaveRelative,
NtName->Length = (USHORT)Length;
NtName->MaximumLength = (USHORT)MaxLength;
NewBuffer[LengthChars] = UNICODE_NULL;
DPRINT("new buffer: %S\n", NewBuffer);
DPRINT("New buffer: %S\n", NewBuffer);
DPRINT("NT Name: %wZ\n", NtName);
/* 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.Length = (USHORT)(PathLength - FullPath.Length);
/* 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.Length -= sizeof(WCHAR);
@ -1121,7 +1123,7 @@ RtlSetCurrentDirectory_U(IN PUNICODE_STRING Path)
FullPath.Length = (USHORT)FullPathLength;
/* 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)
{
@ -1129,7 +1131,7 @@ RtlSetCurrentDirectory_U(IN PUNICODE_STRING Path)
goto Leave;
}
FullPath.Buffer[CharLength] = L'\\';
FullPath.Buffer[CharLength] = OBJ_NAME_PATH_SEPARATOR;
FullPath.Buffer[CharLength + 1] = UNICODE_NULL;
FullPath.Length += sizeof(WCHAR);
}
@ -1500,6 +1502,9 @@ ULONG NTAPI RtlGetFullPathName_U(
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;
/* check for DOS device name */
@ -1733,9 +1738,9 @@ RtlDosSearchPath_U(IN PCWSTR Path,
}
/* 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 */
@ -2051,6 +2056,7 @@ RtlDosSearchPath_Ustr(IN ULONG Flags,
/* Initialize optional arguments */
if (FullNameOut) *FullNameOut = NULL;
if (FilePartSize) *FilePartSize = 0;
if (LengthNeeded) *LengthNeeded = 0;
if (DynamicString)
{
DynamicString->Length = DynamicString->MaximumLength = 0;
@ -2322,7 +2328,7 @@ RtlDosSearchPath_Ustr(IN ULONG Flags,
&StaticCandidateString,
Status);
}
DPRINT("STatus: %lx BUFFER: %S\n", Status, CallerBuffer->Buffer);
DPRINT("Status: %lx BUFFER: %S\n", Status, CallerBuffer->Buffer);
goto Quickie;
}
else