- 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:
Alex Ionescu 2006-07-27 00:13:14 +00:00
parent c0e140d91b
commit f0166aaf6e
3 changed files with 18 additions and 8 deletions

View file

@ -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;
}

View file

@ -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);

View file

@ -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);