Author: ion
Date: Thu Jul 27 04:13:14 2006
New Revision: 23302
URL: http://svn.reactos.org/svn/reactos?rev=23302&view=rev
Log:
- 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.
Modified:
trunk/reactos/drivers/filesystems/vfat/finfo.c
trunk/reactos/ntoskrnl/io/iomgr/file.c
trunk/reactos/ntoskrnl/ob/obname.c
Modified: trunk/reactos/drivers/filesystems/vfat/finfo.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/filesystems/vfat/f…
==============================================================================
--- trunk/reactos/drivers/filesystems/vfat/finfo.c (original)
+++ trunk/reactos/drivers/filesystems/vfat/finfo.c Thu Jul 27 04:13:14 2006
@@ -341,14 +341,13 @@
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;
}
Modified: trunk/reactos/ntoskrnl/io/iomgr/file.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/io/iomgr/file.c?r…
==============================================================================
--- trunk/reactos/ntoskrnl/io/iomgr/file.c (original)
+++ trunk/reactos/ntoskrnl/io/iomgr/file.c Thu Jul 27 04:13:14 2006
@@ -915,7 +915,7 @@
LocalInfo,
Length,
&LocalReturnLength);
- if (!NT_SUCCESS (Status))
+ if (!NT_SUCCESS(Status))
{
/* Free the buffer and fail */
ExFreePool(LocalInfo);
@@ -935,6 +935,14 @@
/* 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 @@
/* Query the File name */
Status = IoQueryFileInformation(FileObject,
FileNameInformation,
- Length,
+ FileLength,
LocalFileInfo,
&LocalReturnLength);
if (NT_ERROR(Status))
@@ -953,6 +961,9 @@
ExFreePool(LocalInfo);
return Status;
}
+
+ /* ROS HACK. VFAT SUCKS */
+ if (NT_WARNING(Status)) LocalReturnLength = FileLength;
/* Now calculate the new lenghts left */
FileLength = LocalReturnLength -
@@ -972,7 +983,7 @@
/* 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);
Modified: trunk/reactos/ntoskrnl/ob/obname.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ob/obname.c?rev=2…
==============================================================================
--- trunk/reactos/ntoskrnl/ob/obname.c (original)
+++ trunk/reactos/ntoskrnl/ob/obname.c Thu Jul 27 04:13:14 2006
@@ -620,7 +620,7 @@
}
/* 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);