mirror of
https://github.com/reactos/reactos.git
synced 2025-05-08 19:27:00 +00:00
- Fix multiple bugs in VfatGetNameInformation:
* Return the file name length even if the buffer is too small, that's the whole point of the "Query length before comitting a buffer" principle. * FSDs are not supposed to null-terminate the buffer, nor expect the caller to send a buffer large enough for null-termination. * Added a hack in IopQueryFile to handle another VFAT bug which makes it return the total number of bytes written in IoStatus.Information instead of the total number of bytes *left untouched*.There are probably many other broken things due to this. - Fix some length calculation bugs in IopQueryFile. svn path=/trunk/; revision=23302
This commit is contained in:
parent
c0e140d91b
commit
f0166aaf6e
3 changed files with 18 additions and 8 deletions
|
@ -341,14 +341,13 @@ VfatGetNameInformation(PFILE_OBJECT FileObject,
|
|||
ASSERT(NameInfo != NULL);
|
||||
ASSERT(FCB != NULL);
|
||||
|
||||
if (*BufferLength < sizeof(FILE_NAME_INFORMATION) + FCB->PathNameU.Length + sizeof(WCHAR))
|
||||
NameInfo->FileNameLength = FCB->PathNameU.Length;
|
||||
if (*BufferLength < FIELD_OFFSET(FILE_NAME_INFORMATION, FileName[0]) + FCB->PathNameU.Length)
|
||||
return STATUS_BUFFER_OVERFLOW;
|
||||
|
||||
NameInfo->FileNameLength = FCB->PathNameU.Length;
|
||||
RtlCopyMemory(NameInfo->FileName, FCB->PathNameU.Buffer, FCB->PathNameU.Length);
|
||||
NameInfo->FileName[FCB->PathNameU.Length / sizeof(WCHAR)] = 0;
|
||||
|
||||
*BufferLength -= (sizeof(FILE_NAME_INFORMATION) + FCB->PathNameU.Length + sizeof(WCHAR));
|
||||
*BufferLength -= (FIELD_OFFSET(FILE_NAME_INFORMATION, FileName[0]) + FCB->PathNameU.Length);
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
|
|
@ -915,7 +915,7 @@ IopQueryNameFile(IN PVOID ObjectBody,
|
|||
LocalInfo,
|
||||
Length,
|
||||
&LocalReturnLength);
|
||||
if (!NT_SUCCESS (Status))
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
/* Free the buffer and fail */
|
||||
ExFreePool(LocalInfo);
|
||||
|
@ -935,6 +935,14 @@ IopQueryNameFile(IN PVOID ObjectBody,
|
|||
/* Advance in buffer */
|
||||
p += (LocalInfo->Name.Length / sizeof(WCHAR));
|
||||
|
||||
/* Check if this already filled our buffer */
|
||||
if (LocalReturnLength > Length)
|
||||
{
|
||||
/* Free the buffer and fail */
|
||||
ExFreePool(LocalInfo);
|
||||
return STATUS_BUFFER_OVERFLOW;
|
||||
}
|
||||
|
||||
/* Now get the file name buffer and check the length needed */
|
||||
LocalFileInfo = (PFILE_NAME_INFORMATION)LocalInfo;
|
||||
FileLength = Length -
|
||||
|
@ -944,7 +952,7 @@ IopQueryNameFile(IN PVOID ObjectBody,
|
|||
/* Query the File name */
|
||||
Status = IoQueryFileInformation(FileObject,
|
||||
FileNameInformation,
|
||||
Length,
|
||||
FileLength,
|
||||
LocalFileInfo,
|
||||
&LocalReturnLength);
|
||||
if (NT_ERROR(Status))
|
||||
|
@ -954,6 +962,9 @@ IopQueryNameFile(IN PVOID ObjectBody,
|
|||
return Status;
|
||||
}
|
||||
|
||||
/* ROS HACK. VFAT SUCKS */
|
||||
if (NT_WARNING(Status)) LocalReturnLength = FileLength;
|
||||
|
||||
/* Now calculate the new lenghts left */
|
||||
FileLength = LocalReturnLength -
|
||||
FIELD_OFFSET(FILE_NAME_INFORMATION, FileName);
|
||||
|
@ -972,7 +983,7 @@ IopQueryNameFile(IN PVOID ObjectBody,
|
|||
|
||||
/* Setup the length and maximum length */
|
||||
FileLength = (ULONG_PTR)p - (ULONG_PTR)ObjectNameInfo;
|
||||
ObjectNameInfo->Name.Length = Length - sizeof(OBJECT_NAME_INFORMATION);
|
||||
ObjectNameInfo->Name.Length = FileLength - sizeof(OBJECT_NAME_INFORMATION);
|
||||
ObjectNameInfo->Name.MaximumLength = ObjectNameInfo->Name.Length +
|
||||
sizeof(UNICODE_NULL);
|
||||
|
||||
|
|
|
@ -620,7 +620,7 @@ ObQueryNameString(IN PVOID Object,
|
|||
}
|
||||
|
||||
/* Check if the object doesn't even have a name */
|
||||
if (!LocalInfo || !LocalInfo->Name.Buffer)
|
||||
if (!(LocalInfo) || !(LocalInfo->Name.Buffer))
|
||||
{
|
||||
/* We're returning the name structure */
|
||||
*ReturnLength = sizeof(OBJECT_NAME_INFORMATION);
|
||||
|
|
Loading…
Reference in a new issue