A bug in FAT/FAT32 driver?

Hello.

I found out an interesting thing. NtQueryDirectoryFile may return wrong
amount of data returned if it is called from a directory from a FAT volume
and ReturnSingleEntry parameter is FALSE.

//
// Let’s say we open '??\C:' and it is a FAT volume.
// We prepared ‘ObjectAttributes’ beforehand.
//

HANDLE file = NULL;

NtCreateFile(
&file,
SYNCHRONIZE | FILE_READ_DATA,
&ObjectAttributes,
&IoStatusBlock,
NULL,
FILE_ATTRIBUTE_NORMAL,
FILE_SHARE_READ | FILE_SHARE_WRITE,
FILE_OPEN,
FILE_DIRECTORY_FILE,
NULL,
0);

WCHAR templname = L"*";

UNICODE_STRING templateString;
templateString.Buffer = templname;
templateString.MaximumLength = sizeof(templname);
templateString.Length = sizeof(templname) - sizeof(WCHAR);

//
// Suppose that buffer will be enough for all data returned…
//

char buf[0x10000];
memset(buf, 0x5a, sizeof(buf));

NTSTATUS status =
NtQueryDirectoryFile(
file,
0,
0,
0,
&IoStatusBlock,
buf,
sizeof(buf),
FileBothDirectoryInformation,
FALSE,
&templateString,
TRUE);

The function succeeds. The buffer is filled properly but
IoStatusBlock.Information is set to a value two or four bytes less than
amount of data written to the buffer. As result the last file name is
truncated.

I was able to repeat this for FileDirectoryInformation,
FileFullDirectoryInformation, FileBothDirectoryInformation and
FileNamesInformation classes. NTFS, CDFS, UDF work properly.

OS: Win XP Professional, SP1.

Does anyone came across with it before?

Best regards,
Alexey.

Hello.

I found out an interesting thing. NtQueryDirectoryFile may return wrong amount of data returned if it is called from a directory from a FAT volume and ReturnSingleEntry parameter is FALSE.

//
// Let’s say we open '??\C:' and it is a FAT volume. We prepared ‘ObjectAttributes’ beforehand.
//

HANDLE file = NULL;

NtCreateFile(
&file,
SYNCHRONIZE | FILE_READ_DATA,
&ObjectAttributes,
&IoStatusBlock,
NULL,
FILE_ATTRIBUTE_NORMAL,
FILE_SHARE_READ | FILE_SHARE_WRITE,
FILE_OPEN,
FILE_DIRECTORY_FILE,
NULL,
0);

WCHAR templname = L"*";

UNICODE_STRING templateString;
templateString.Buffer = templname;
templateString.MaximumLength = sizeof(templname);
templateString.Length = sizeof(templname) - sizeof(WCHAR);

//
// Suppose that buffer will be enough for all data returned…
//

char buf[0x10000];
memset(buf, 0x5a, sizeof(buf));

NTSTATUS status =
NtQueryDirectoryFile(
file,
0,
0,
0,
&IoStatusBlock,
buf,
sizeof(buf),
FileBothDirectoryInformation,
FALSE,
&templateString,
TRUE);

The function succeeds. The buffer is filled properly but IoStatusBlock.Information is set to a value two or four bytes less than amount of data written to the buffer. As result the last file name is truncated.

I was able to repeat this for FileDirectoryInformation, FileFullDirectoryInformation, FileBothDirectoryInformation and FileNamesInformation classes. NTFS, CDFS, UDF work properly.

OS: Win XP Professional, SP1.

Does anyone came across with it before?

Best regards,
Alexey.

If I recall correctly this bug was discussed on this list a year or two ago.
FAT doesn’t take in account alignment of the last entry when calculating
Status.Information.
Data itself is copied to the buffer properly, so if you ignore
Status.Information and parse output buffer relying on NextEntryOffset /
FileNameLength fields you get correct information. Probably it is the reason
why it was not discovered for a while.
I believe that the bug was fixed in the latest version of FAT.

Alexei.

“Alexey Pakhunov” wrote in message news:xxxxx@ntfsd…
> Hello.
>
> I found out an interesting thing. NtQueryDirectoryFile may return wrong
> amount of data returned if it is called from a directory from a FAT volume
> and ReturnSingleEntry parameter is FALSE.
>
> //
> // Let’s say we open '??\C:' and it is a FAT volume.
> // We prepared ‘ObjectAttributes’ beforehand.
> //
>
> HANDLE file = NULL;
>
> NtCreateFile(
> &file,
> SYNCHRONIZE | FILE_READ_DATA,
> &ObjectAttributes,
> &IoStatusBlock,
> NULL,
> FILE_ATTRIBUTE_NORMAL,
> FILE_SHARE_READ | FILE_SHARE_WRITE,
> FILE_OPEN,
> FILE_DIRECTORY_FILE,
> NULL,
> 0);
>
> WCHAR templname = L"*";
>
> UNICODE_STRING templateString;
> templateString.Buffer = templname;
> templateString.MaximumLength = sizeof(templname);
> templateString.Length = sizeof(templname) - sizeof(WCHAR);
>
> //
> // Suppose that buffer will be enough for all data returned…
> //
>
> char buf[0x10000];
> memset(buf, 0x5a, sizeof(buf));
>
> NTSTATUS status =
> NtQueryDirectoryFile(
> file,
> 0,
> 0,
> 0,
> &IoStatusBlock,
> buf,
> sizeof(buf),
> FileBothDirectoryInformation,
> FALSE,
> &templateString,
> TRUE);
>
> The function succeeds. The buffer is filled properly but
> IoStatusBlock.Information is set to a value two or four bytes less than
> amount of data written to the buffer. As result the last file name is
> truncated.
>
> I was able to repeat this for FileDirectoryInformation,
> FileFullDirectoryInformation, FileBothDirectoryInformation and
> FileNamesInformation classes. NTFS, CDFS, UDF work properly.
>
> OS: Win XP Professional, SP1.
>
> Does anyone came across with it before?
>
> Best regards,
> Alexey.
>

Hello.

Data itself is copied to the buffer properly, so if you ignore
Status.Information and parse output buffer relying on NextEntryOffset /
FileNameLength fields you get correct information. Probably it is the reason

Thanks. I use the same workaround now.

Best regards,
Alexey.

“Alexei Jelvis” wrote in message news:…
> If I recall correctly this bug was discussed on this list a year or two ago.
> FAT doesn’t take in account alignment of the last entry when calculating
> Status.Information.
> Data itself is copied to the buffer properly, so if you ignore
> Status.Information and parse output buffer relying on NextEntryOffset /
> FileNameLength fields you get correct information. Probably it is the reason
> why it was not discovered for a while.
> I believe that the bug was fixed in the latest version of FAT.
>
> Alexei.
>
> “Alexey Pakhunov” wrote in message news:xxxxx@ntfsd…
> > Hello.
> >
> > I found out an interesting thing. NtQueryDirectoryFile may return wrong
> > amount of data returned if it is called from a directory from a FAT volume
> > and ReturnSingleEntry parameter is FALSE.

Just to confirm what Alexei said earlier, this bug was fixed in FASTFAT
for Server 2003.

Thanks,
Molly Brown
Microsoft Corporation

This posting is provided “AS IS” with no warranties and confers no
rights.


From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Alexey Pakhunov
Sent: Tuesday, May 18, 2004 10:52 PM
To: Windows File Systems Devs Interest List
Subject: Re:[ntfsd] A bug in FAT/FAT32 driver?

Hello.

Data itself is copied to the buffer properly, so if you ignore
Status.Information and parse output buffer relying on NextEntryOffset
/
FileNameLength fields you get correct information. Probably it is the
reason

Thanks. I use the same workaround now.

Best regards,
Alexey.

“Alexei Jelvis” wrote in message news:…
> If I recall correctly this bug was discussed on this list a year or
two ago.
> FAT doesn’t take in account alignment of the last entry when
calculating
> Status.Information.
> Data itself is copied to the buffer properly, so if you ignore
> Status.Information and parse output buffer relying on NextEntryOffset
/
> FileNameLength fields you get correct information. Probably it is the
reason
> why it was not discovered for a while.
> I believe that the bug was fixed in the latest version of FAT.
>
> Alexei.
>
> “Alexey Pakhunov” wrote in message
news:xxxxx@ntfsd…
> > Hello.
> >
> > I found out an interesting thing. NtQueryDirectoryFile may return
wrong
> > amount of data returned if it is called from a directory from a FAT
volume
> > and ReturnSingleEntry parameter is FALSE.


Questions? First check the IFS FAQ at
https://www.osronline.com/article.cfm?id=17

You are currently subscribed to ntfsd as: xxxxx@windows.microsoft.com

To unsubscribe send a blank email to xxxxx@lists.osr.com