Problem with FAT(16) on WIN2K

Hi Everybody
I have written a driver for Win2K and is running perfectly well on FAT32 and
NTFS partitions
but when I try to install 2K on FAT-Partition then its not performing all of
its functionalities,
What I think is I need to take some special care for FAT-16(FAT) partition,
so anybody of u if
can provide me some support it would be of great help, here is my code
snippet…

ULONG GetVolInfo(PWCHAR DriveLetter,int*IsFat32,PULONG ClusterSize )
{
FILE_FS_SIZE_INFORMATION FsInformation;

Status =
ZwQueryVolumeInformationFile(FileHandle,&IoStatusBlock,&FsInformation,sizeof(FILE_FS_SIZE_INFORMATION),FileFsSizeInformation
);

SectorsPerAllocationUnit = FsInformation.SectorsPerAllocationUnit;

BytesPerSector = FsInformation.BytesPerSector;

CLUSTER_SIZE=SectorsPerAllocationUnit*BytesPerSector; // IN NO OF BYTES
*ClusterSize=CLUSTER_SIZE;

Status =
ZwQueryVolumeInformationFile(FileHandle,&IoStatusBlock,&Buffer,sizeof(Buffer
),FileFsAttributeInformation);

FsName = ((PFILE_FS_ATTRIBUTE_INFORMATION)Buffer)->FileSystemName;

FsNameLen = ((PFILE_FS_ATTRIBUTE_INFORMATION)Buffer)->FileSystemNameLength;

// Compare the name
if( ( FsNameLen >= 3 * sizeof(WCHAR) ) && RtlEqualMemory(FsName, L"FAT",
3 * sizeof(WCHAR)) )
{
// Check for FAT32
if( ( FsNameLen >= 5 * sizeof(WCHAR) ) && RtlEqualMemory(FsName +
3, L"32", 2 * sizeof(WCHAR)) )
{
//DbgPrint((“FAT32 volume\n”));
*IsFat32 = 2;
}

else
{
*IsFat32=1;
// FAT12/16
//DbgPrint((“FAT volume\n”));
}

}

else
{
*IsFat32=3;
// Not FAT
//DbgPrint((“Not a FAT volume\r\n”));
}

*ClusterSize=CLUSTER_SIZE;
return 1;
}

In the above code, I am finding the type of Partition/file system and the
CLUSTER_SIZE and using this information
for further processing. Do i need to modify the ‘*ClusterSize’ or something
in the code given below…

if(fat32flag==2)
{
pTempBuffer = ExAllocatePool(NonPagedPool,*ClusterSize);
pMdl = IoAllocateMdl(pTempBuffer, *ClusterSize, FALSE, TRUE, 0);
MmBuildMdlForNonPagedPool(pMdl);

//for fat32 type

StartingBPBOffset.QuadPart=0;

ReadFromVolume(gOSDriveobject,NULL,StartingBPBOffset,512,pMdl,pTempBuffer,&iosb);
pBPB_Buffer=(PDISKFAT32BPB)pTempBuffer;
pBPB_EXTENDED_BUFFER=(PEXTENDED_BPB)((UCHAR*)pTempBuffer+36);
x=(unsigned short int *)(pBPB_Buffer->ReservedSectors);
y=(unsigned char*)(pBPB_Buffer->NumberOfFats);
z=(unsigned int*)(pBPB_EXTENDED_BUFFER->BigSectorsPerFat);

offset=(LONGLONG)(((ULONG)(*x) + ((ULONG)(*y)* (ULONG)(*z) ))*512);
IoFreeMdl(pMdl);
ExFreePool(pTempBuffer);

}

if(fat32flag==1)
{
pTempBuffer = ExAllocatePool(NonPagedPool,*ClusterSize);
pMdl = IoAllocateMdl(pTempBuffer, *ClusterSize, FALSE, TRUE, 0);
MmBuildMdlForNonPagedPool(pMdl);

//for fat16 type

StartingBPBOffset.QuadPart=0;

ReadFromVolume(gOSDriveobject,NULL,StartingBPBOffset,512,pMdl,pTempBuffer,&iosb);
pBPB_Buffer=(PDISKFAT32BPB)pTempBuffer;
pBPB_EXTENDED_BUFFER=(PEXTENDED_BPB)((UCHAR*)pTempBuffer+36);
x=(unsigned short int *)(pBPB_Buffer->ReservedSectors);
y=(unsigned char*)(pBPB_Buffer->NumberOfFats);
z=(unsigned int*)(pBPB_Buffer->SectorsPerFat);

offset=(LONGLONG)(((ULONG)(*x) + ((ULONG)(*y)* (ULONG)(*z) ))*512);
IoFreeMdl(pMdl);
ExFreePool(pTempBuffer);
}

Thanks.

Regards
Anuj Agarwal

Anuj Agarwal wrote:

I have written a driver for Win2K and is running perfectly well on
FAT32 and NTFS partitions
but when I try to install 2K on FAT-Partition then its not performing
all of its functionalities,
What I think is I need to take some special care for FAT-16(FAT)
partition, so anybody of u if
can provide me some support it would be of great help, here is my code
snippet…

ULONG GetVolInfo(PWCHAR DriveLetter,int*IsFat32,PULONG ClusterSize )

Why would you have a variable called IsFat32, and then use it to store
the values 1, 2, and 3? You are just asking for trouble. A variable
called IsSomething should be a boolean, with only “true” or “false”
values. A much better solution is to use an enumeration::

enum FileSystem {
fsFAT16 = 0,
fsFAT32,
fsOther
};

Or, better yet, use the symbols PARTITION_FAT_16 and PARTITION_FAT32
which already exist in ntdddisk.h.

{
FILE_FS_SIZE_INFORMATION FsInformation;

Status =
ZwQueryVolumeInformationFile(FileHandle,&IoStatusBlock,&FsInformation,sizeof(FILE_FS_SIZE_INFORMATION),FileFsSizeInformation
);

Where did “FileHandle” come from?

SectorsPerAllocationUnit = FsInformation.SectorsPerAllocationUnit;
BytesPerSector = FsInformation.BytesPerSector;
CLUSTER_SIZE=SectorsPerAllocationUnit*BytesPerSector; // IN NO OF BYTES
*ClusterSize=CLUSTER_SIZE;

Status =
ZwQueryVolumeInformationFile(FileHandle,&IoStatusBlock,&Buffer,sizeof(Buffer
),FileFsAttributeInformation);

What’s “Buffer”?

FsName = ((PFILE_FS_ATTRIBUTE_INFORMATION)Buffer)->FileSystemName;

FsNameLen =
((PFILE_FS_ATTRIBUTE_INFORMATION)Buffer)->FileSystemNameLength;

// Compare the name
if( ( FsNameLen >= 3 * sizeof(WCHAR) ) && RtlEqualMemory(FsName,
L"FAT", 3 * sizeof(WCHAR)) )
{
// Check for FAT32
if( ( FsNameLen >= 5 * sizeof(WCHAR) ) &&
RtlEqualMemory(FsName + 3, L"32", 2 * sizeof(WCHAR)) )
{

Good grief. Why wouldn’t you just use:

if( wcsncmp( FsName, L"FAT", 3 ) == 0 )
{
if( wcscmp( FsName, L"FAT32" ) == 0 )
{

In the above code, I am finding the type of Partition/file system and
the CLUSTER_SIZE and using this information
for further processing. Do i need to modify the ‘*ClusterSize’ or
something in the code given below…

if(fat32flag==2)
{
pTempBuffer = ExAllocatePool(NonPagedPool,*ClusterSize);
pMdl = IoAllocateMdl(pTempBuffer, *ClusterSize, FALSE, TRUE, 0);
MmBuildMdlForNonPagedPool(pMdl);

//for fat32 type

StartingBPBOffset.QuadPart=0;

ReadFromVolume(gOSDriveobject,NULL,StartingBPBOffset,512,pMdl,pTempBuffer,&iosb);

Interesting; why would you allocate CLUSTER_SIZE bytes, and then read
only 512?

pBPB_Buffer=(PDISKFAT32BPB)pTempBuffer;
pBPB_EXTENDED_BUFFER=(PEXTENDED_BPB)((UCHAR*)pTempBuffer+36);
x=(unsigned short int *)(pBPB_Buffer->ReservedSectors);
y=(unsigned char*)(pBPB_Buffer->NumberOfFats);
z=(unsigned int*)(pBPB_EXTENDED_BUFFER->BigSectorsPerFat);

offset=(LONGLONG)(((ULONG)(*x) + ((ULONG)(*y)* (ULONG)(*z) ))*512);

That’s CERTAINLY not right. ReservedSectors, NumberOfFats, and
BigSectorsPerFat contain VALUES, not virtual ADDRESSES. That last
statement is going to explode, because you’re trying to derefence
invalid addresses. Further, your final computation is going to
overflow; you do all of the computations as unsigned longs, and only
when the computation is complete do you cast it to an __int64. By that
time, it is too late. You need to switch to __int64 BEFORE you expect
the overflow.

x = pBPB_Buffer->ReservedSectors;
y = pBPB_Buffer->NumberOfFats;
z = pBPB_EXTENDED_BUFFER->BigSectorsPerFat;

offset = ((LONGLONG)( x + y * z )) << 9;

Of course, at that point, there’s no point in using the
oh-so-mnemonically-named x, y, and z at all. Just use the values directly:

offset = ((LONGLONG)
(pBPB_Buffer->ReservedSectors +
pBPB_Buffer->NumberOfFats *
pBPB_EXTENDED_BUFFER->BigSectorsPerFat)
) << 9;

//for fat16 type

StartingBPBOffset.QuadPart=0;

ReadFromVolume(gOSDriveobject,NULL,StartingBPBOffset,512,pMdl,pTempBuffer,&iosb);
pBPB_Buffer=(PDISKFAT32BPB)pTempBuffer;
pBPB_EXTENDED_BUFFER=(PEXTENDED_BPB)((UCHAR*)pTempBuffer+36);
x=(unsigned short int *)(pBPB_Buffer->ReservedSectors);
y=(unsigned char*)(pBPB_Buffer->NumberOfFats);
z=(unsigned int*)(pBPB_Buffer->SectorsPerFat);

offset=(LONGLONG)(((ULONG)(*x) + ((ULONG)(*y)* (ULONG)(*z) ))*512);

The exact same problems apply here. Are you sure you’re going to find a
DISKFAT32BPB structure at that spot on a FAT16 volume?


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

Hello Tim
Thanks for the reply but I think you haven’t read my first line thats it is
running perfectly well on FAT32 and NTFS partitions so nothing much problem
in the code like this-

*** x = pBPB_Buffer->ReservedSectors;
y = pBPB_Buffer->NumberOfFats;
z = pBPB_EXTENDED_BUFFER->BigSectorsPerFat;

offset = ((LONGLONG)( x + y * z )) << 9; ***

its absolutely perfect what I want to know is that what changes I need to
do so as to run my driver perfectly on FAT(16) partition as well.

In another function, I’m using *ClusterSize and *IsFat32 variables and
storing them in ‘deviceExtension’.
func_name(…)
{
ULONG ulBitmapBufferSize=1024;


pVolBitmapBuff=ExAllocatePool(NonPagedPool,ulBitmapBufferSize);

status= ZwFsControlFile(
FileHandle,
NULL,// Event,
NULL,// ApcRoutine,
NULL,//IN ApcContext,
&IoStatusBlock,//OUT IoStatusBlock,
FSCTL_GET_VOLUME_BITMAP,//IN IoControlCode,
&oStartLCN, //IN PVOID InputBuffer,
sizeof(STARTING_LCN_INPUT_BUFFER), //IN VOID InputBufferLength,
pVolBitmapBuff, //OUT PVOID OutputBuffer,
ulBitmapBufferSize
); // OUT PVOID OutputBufferLength

if(status == STATUS_BUFFER_OVERFLOW)

{
ulBitmapSize = (ULONG)((pVolBitmapBuff->BitmapSize.QuadPart / 8)
+1);
ulBitmapBufferSize = (2*sizeof(ULONGLONG) + ulBitmapSize);

// total size of bitmap variable length structure
ExFreePool(pVolBitmapBuff);

pVolBitmapBuff = ExAllocatePool(NonPagedPool, ulBitmapBufferSize);

if(!pVolBitmapBuff)
{
DbgPrint(“Error while getting WHILE pVolBitmapBuff2\n”);
ExFreePool(TempDrivePath);
return STATUS_INSUFFICIENT_RESOURCES;
}
RtlZeroMemory(pVolBitmapBuff, ulBitmapBufferSize);
oStartLCN.StartingLcn.QuadPart = 0;
status= ZwFsControlFile(
FileHandle,
NULL,// Event,
NULL,// ApcRoutine,
NULL,//IN ApcContext,
&IoStatusBlock,//OUT IoStatusBlock,
FSCTL_GET_VOLUME_BITMAP,//IN IoControlCode,
&oStartLCN, //IN PVOID InputBuffer,
sizeof(STARTING_LCN_INPUT_BUFFER), //IN VOID InputBufferLength,
pVolBitmapBuff, //OUT PVOID OutputBuffer,
ulBitmapBufferSize // it cantains the true size
);

}

if (status!=STATUS_SUCCESS)
{
ExFreePool(pVolBitmapBuff);
ExFreePool(TempDrivePath);
ZwClose(FileHandle);
return status;
}

else
{
pVolBitmapBuff2=ExAllocatePool(NonPagedPool,ulBitmapBufferSize);

RtlInitializeBitMap(pBitMapHeader,(PULONG)(pVolBitmapBuff->Buffer),(ULONG)(pVolBitmapBuff->
BitmapSize.QuadPart));

RtlInitializeBitMap(pBitMapUser,(PULONG)(pVolBitmapBuff2->Buffer),(ULONG)(pVolBitmapBuff->
BitmapSize.QuadPart));
RtlClearAllBits(pBitMapUser);
DbgPrint(“Success while getting bitmap\n”);
}

}

And this code is running perfectly for FAt32 but may be have to do some more
calculations/modifications for FAT16.

Are you sure you’re going to find a
DISKFAT32BPB structure at that spot on a FAT16 volume?

Well for FAT16, ‘DISKFAT32BPB’ structure is almost same and in addition to
this it has an extended FAT structure that has variables
like’BigSectorsPerFat’ and
in case of FAT16, we can take the value from DISKFAT32BPB structure having
variable ‘SectorsPerFat’

Thanks.

Regards
Anuj Agarwal

On 12/29/05, Tim Roberts wrote:
>
> Anuj Agarwal wrote:
>
> >
> > I have written a driver for Win2K and is running perfectly well on
> > FAT32 and NTFS partitions
> > but when I try to install 2K on FAT-Partition then its not performing
> > all of its functionalities,
> > What I think is I need to take some special care for FAT-16(FAT)
> > partition, so anybody of u if
> > can provide me some support it would be of great help, here is my code
> > snippet…
> >
> >
> > ULONG GetVolInfo(PWCHAR DriveLetter,intIsFat32,PULONG ClusterSize )
>
>
> Why would you have a variable called IsFat32, and then use it to store
> the values 1, 2, and 3? You are just asking for trouble. A variable
> called IsSomething should be a boolean, with only “true” or “false”
> values. A much better solution is to use an enumeration::
>
> enum FileSystem {
> fsFAT16 = 0,
> fsFAT32,
> fsOther
> };
>
> Or, better yet, use the symbols PARTITION_FAT_16 and PARTITION_FAT32
> which already exist in ntdddisk.h.
>
> > {
> > FILE_FS_SIZE_INFORMATION FsInformation;
> >
> > Status =
> >
> ZwQueryVolumeInformationFile(FileHandle,&IoStatusBlock,&FsInformation,sizeof(FILE_FS_SIZE_INFORMATION),FileFsSizeInformation
> > );
>
>
> Where did “FileHandle” come from?
>
> > SectorsPerAllocationUnit = FsInformation.SectorsPerAllocationUnit;
> > BytesPerSector = FsInformation.BytesPerSector;
> > CLUSTER_SIZE=SectorsPerAllocationUnit
BytesPerSector; // IN NO OF BYTES
> > *ClusterSize=CLUSTER_SIZE;
> >
> > Status =
> >
> ZwQueryVolumeInformationFile(FileHandle,&IoStatusBlock,&Buffer,sizeof(Buffer
> > ),FileFsAttributeInformation);
>
>
> What’s “Buffer”?
>
> > FsName = ((PFILE_FS_ATTRIBUTE_INFORMATION)Buffer)->FileSystemName;
> >
> > FsNameLen =
> > ((PFILE_FS_ATTRIBUTE_INFORMATION)Buffer)->FileSystemNameLength;
> >
> > // Compare the name
> > if( ( FsNameLen >= 3 * sizeof(WCHAR) ) && RtlEqualMemory(FsName,
> > L"FAT", 3 * sizeof(WCHAR)) )
> > {
> > // Check for FAT32
> > if( ( FsNameLen >= 5 * sizeof(WCHAR) ) &&
> > RtlEqualMemory(FsName + 3, L"32", 2 * sizeof(WCHAR)) )
> > {
>
>
> Good grief. Why wouldn’t you just use:
>
> if( wcsncmp( FsName, L"FAT", 3 ) == 0 )
> {
> if( wcscmp( FsName, L"FAT32" ) == 0 )
> {
>
> > In the above code, I am finding the type of Partition/file system and
> > the CLUSTER_SIZE and using this information
> > for further processing. Do i need to modify the ‘*ClusterSize’ or
> > something in the code given below…
> >
> > if(fat32flag==2)
> > {
> > pTempBuffer = ExAllocatePool(NonPagedPool,ClusterSize);
> > pMdl = IoAllocateMdl(pTempBuffer, ClusterSize, FALSE, TRUE, 0);
> > MmBuildMdlForNonPagedPool(pMdl);
> >
> > //for fat32 type
> >
> > StartingBPBOffset.QuadPart=0;
> >
>
> > ReadFromVolume(gOSDriveobject,NULL,StartingBPBOffset,512,pMdl,pTempBuffer,&iosb);
>
>
> Interesting; why would you allocate CLUSTER_SIZE bytes, and then read
> only 512?
>
> > pBPB_Buffer=(PDISKFAT32BPB)pTempBuffer;
> > pBPB_EXTENDED_BUFFER=(PEXTENDED_BPB)((UCHAR
)pTempBuffer+36);
> > x=(unsigned short int )(pBPB_Buffer->ReservedSectors);
> > y=(unsigned char
)(pBPB_Buffer->NumberOfFats);
> > z=(unsigned int
)(pBPB_EXTENDED_BUFFER->BigSectorsPerFat);
> >
> > offset=(LONGLONG)(((ULONG)(*x) + ((ULONG)(y) (ULONG)(*z) ))512);
>
>
> That’s CERTAINLY not right. ReservedSectors, NumberOfFats, and
> BigSectorsPerFat contain VALUES, not virtual ADDRESSES. That last
> statement is going to explode, because you’re trying to derefence
> invalid addresses. Further, your final computation is going to
> overflow; you do all of the computations as unsigned longs, and only
> when the computation is complete do you cast it to an int64. By that
> time, it is too late. You need to switch to
int64 BEFORE you expect
> the overflow.
>
> x = pBPB_Buffer->ReservedSectors;
> y = pBPB_Buffer->NumberOfFats;
> z = pBPB_EXTENDED_BUFFER->BigSectorsPerFat;
>
> offset = ((LONGLONG)( x + y * z )) << 9;
>
> Of course, at that point, there’s no point in using the
> oh-so-mnemonically-named x, y, and z at all. Just use the values directly:
>
> offset = ((LONGLONG)
> (pBPB_Buffer->ReservedSectors +
> pBPB_Buffer->NumberOfFats
> pBPB_EXTENDED_BUFFER->BigSectorsPerFat)
> ) << 9;
>
> > //for fat16 type
> >
> > StartingBPBOffset.QuadPart=0;
> >
>
> > ReadFromVolume(gOSDriveobject,NULL,StartingBPBOffset,512,pMdl,pTempBuffer,&iosb);
> > pBPB_Buffer=(PDISKFAT32BPB)pTempBuffer;
> > pBPB_EXTENDED_BUFFER=(PEXTENDED_BPB)((UCHAR
)pTempBuffer+36);
> > x=(unsigned short int )(pBPB_Buffer->ReservedSectors);
> > y=(unsigned char
)(pBPB_Buffer->NumberOfFats);
> > z=(unsigned int
)(pBPB_Buffer->SectorsPerFat);
> >
> > offset=(LONGLONG)(((ULONG)(*x) + ((ULONG)(y) (ULONG)(*z) ))*512);
>
>
> The exact same problems apply here. Are you sure you’re going to find a
> DISKFAT32BPB structure at that spot on a FAT16 volume?
>
> –
> Tim Roberts, xxxxx@probo.com
> Providenza & Boekelheide, Inc.
>
>
>
> —
> Questions? First check the Kernel Driver FAQ at
> http://www.osronline.com/article.cfm?id=256
>
> You are currently subscribed to ntdev as: xxxxx@gmail.com
> To unsubscribe send a blank email to xxxxx@lists.osr.com
>

Run it under the debugger using the checked build of fastfat that you create.
“Anuj Agarwal” wrote in message news:xxxxx@ntdev…
Hello Tim
Thanks for the reply but I think you haven’t read my first line thats it is running perfectly well on FAT32 and NTFS partitions so nothing much problem in the code like this-

x = pBPB_Buffer->ReservedSectors;
y = pBPB_Buffer->NumberOfFats;
z = pBPB_EXTENDED_BUFFER->BigSectorsPerFat;

offset = ((LONGLONG)( x + y * z )) << 9;


its absolutely perfect what I want to know is that what changes I need to do so as to run my driver perfectly on FAT(16) partition as well.

In another function, I’m using ClusterSize and IsFat32 variables and storing them in ‘deviceExtension’.
func_name(…)
{
ULONG ulBitmapBufferSize=1024;


pVolBitmapBuff=ExAllocatePool(NonPagedPool,ulBitmapBufferSize);

status= ZwFsControlFile(
FileHandle,
NULL,// Event,
NULL,// ApcRoutine,
NULL,//IN ApcContext,
&IoStatusBlock,//OUT IoStatusBlock,
FSCTL_GET_VOLUME_BITMAP,//IN IoControlCode,
&oStartLCN, //IN PVOID InputBuffer,
sizeof(STARTING_LCN_INPUT_BUFFER), //IN VOID InputBufferLength,
pVolBitmapBuff, //OUT PVOID OutputBuffer,
ulBitmapBufferSize
); // OUT PVOID OutputBufferLength

if(status == STATUS_BUFFER_OVERFLOW)

{
ulBitmapSize = (ULONG)((pVolBitmapBuff->BitmapSize.QuadPart / 8) +1);
ulBitmapBufferSize = (2
sizeof(ULONGLONG) + ulBitmapSize);

// total size of bitmap variable length structure
ExFreePool(pVolBitmapBuff);

pVolBitmapBuff = ExAllocatePool(NonPagedPool, ulBitmapBufferSize);

if(!pVolBitmapBuff)
{
DbgPrint(“Error while getting WHILE pVolBitmapBuff2\n”);
ExFreePool(TempDrivePath);
return STATUS_INSUFFICIENT_RESOURCES;
}
RtlZeroMemory(pVolBitmapBuff, ulBitmapBufferSize);
oStartLCN.StartingLcn.QuadPart = 0;
status= ZwFsControlFile(
FileHandle,
NULL,// Event,
NULL,// ApcRoutine,
NULL,//IN ApcContext,
&IoStatusBlock,//OUT IoStatusBlock,
FSCTL_GET_VOLUME_BITMAP,//IN IoControlCode,
&oStartLCN, //IN PVOID InputBuffer,
sizeof(STARTING_LCN_INPUT_BUFFER), //IN VOID InputBufferLength,
pVolBitmapBuff, //OUT PVOID OutputBuffer,
ulBitmapBufferSize // it cantains the true size
);

}

if (status!=STATUS_SUCCESS)
{
ExFreePool(pVolBitmapBuff);
ExFreePool(TempDrivePath);
ZwClose(FileHandle);
return status;
}

else
{
pVolBitmapBuff2=ExAllocatePool(NonPagedPool,ulBitmapBufferSize);
RtlInitializeBitMap(pBitMapHeader,(PULONG)(pVolBitmapBuff->Buffer),(ULONG)(pVolBitmapBuff->BitmapSize.QuadPart));
RtlInitializeBitMap(pBitMapUser,(PULONG)(pVolBitmapBuff2->Buffer),(ULONG)(pVolBitmapBuff->BitmapSize.QuadPart));
RtlClearAllBits(pBitMapUser);
DbgPrint(“Success while getting bitmap\n”);
}

}

And this code is running perfectly for FAt32 but may be have to do some more calculations/modifications for FAT16.

Are you sure you’re going to find a
DISKFAT32BPB structure at that spot on a FAT16 volume?

Well for FAT16, ‘DISKFAT32BPB’ structure is almost same and in addition to this it has an extended FAT structure that has variables like ‘BigSectorsPerFat’ and in case of FAT16, we can take the value from DISKFAT32BPB structure having variable ‘SectorsPerFat’

Thanks.

Regards
Anuj Agarwal

On 12/29/05, Tim Roberts wrote:
Anuj Agarwal wrote:

>
> I have written a driver for Win2K and is running perfectly well on
> FAT32 and NTFS partitions
> but when I try to install 2K on FAT-Partition then its not performing
> all of its functionalities,
> What I think is I need to take some special care for FAT-16(FAT)
> partition, so anybody of u if
> can provide me some support it would be of great help, here is my code
> snippet…
>
>
> ULONG GetVolInfo(PWCHAR DriveLetter,int
IsFat32,PULONG ClusterSize )

Why would you have a variable called IsFat32, and then use it to store
the values 1, 2, and 3? You are just asking for trouble. A variable
called IsSomething should be a boolean, with only “true” or “false”
values. A much better solution is to use an enumeration::

enum FileSystem {
fsFAT16 = 0,
fsFAT32,
fsOther
};

Or, better yet, use the symbols PARTITION_FAT_16 and PARTITION_FAT32
which already exist in ntdddisk.h.

> {
> FILE_FS_SIZE_INFORMATION FsInformation;
>
> Status =
> ZwQueryVolumeInformationFile(FileHandle,&IoStatusBlock,&FsInformation,sizeof(FILE_FS_SIZE_INFORMATION),FileFsSizeInformation
> );

Where did “FileHandle” come from?

> SectorsPerAllocationUnit = FsInformation.SectorsPerAllocationUnit;
> BytesPerSector = FsInformation.BytesPerSector;
> CLUSTER_SIZE=SectorsPerAllocationUnit*BytesPerSector; // IN NO OF BYTES
> *ClusterSize=CLUSTER_SIZE;
>
> Status =
> ZwQueryVolumeInformationFile(FileHandle,&IoStatusBlock,&Buffer,sizeof(Buffer
> ),FileFsAttributeInformation);

What’s “Buffer”?

> FsName = ((PFILE_FS_ATTRIBUTE_INFORMATION)Buffer)->FileSystemName;
>
> FsNameLen =
> ((PFILE_FS_ATTRIBUTE_INFORMATION)Buffer)->FileSystemNameLength;
>
> // Compare the name
> if( ( FsNameLen >= 3 * sizeof(WCHAR) ) && RtlEqualMemory(FsName,
> L"FAT", 3 * sizeof(WCHAR)) )
> {
> // Check for FAT32
> if( ( FsNameLen >= 5 * sizeof(WCHAR) ) &&
> RtlEqualMemory(FsName + 3, L"32", 2 * sizeof(WCHAR)) )
> {

Good grief. Why wouldn’t you just use:

if( wcsncmp( FsName, L"FAT", 3 ) == 0 )
{
if( wcscmp( FsName, L"FAT32" ) == 0 )
{

> In the above code, I am finding the type of Partition/file system and
> the CLUSTER_SIZE and using this information
> for further processing. Do i need to modify the ‘*ClusterSize’ or
> something in the code given below…
>
> if(fat32flag==2)
> {
> pTempBuffer = ExAllocatePool(NonPagedPool,ClusterSize);
> pMdl = IoAllocateMdl(pTempBuffer, ClusterSize, FALSE, TRUE, 0);
> MmBuildMdlForNonPagedPool(pMdl);
>
> //for fat32 type
>
> StartingBPBOffset.QuadPart=0;
>
> ReadFromVolume(gOSDriveobject,NULL,StartingBPBOffset,512,pMdl,pTempBuffer,&iosb);

Interesting; why would you allocate CLUSTER_SIZE bytes, and then read
only 512?

> pBPB_Buffer=(PDISKFAT32BPB)pTempBuffer;
> pBPB_EXTENDED_BUFFER=(PEXTENDED_BPB)((UCHAR
)pTempBuffer+36);
> x=(unsigned short int )(pBPB_Buffer->ReservedSectors);
> y=(unsigned char
)(pBPB_Buffer->NumberOfFats);
> z=(unsigned int
)(pBPB_EXTENDED_BUFFER->BigSectorsPerFat);
>
> offset=(LONGLONG)(((ULONG)(*x) + ((ULONG)(y) (ULONG)(*z) ))512);

That’s CERTAINLY not right. ReservedSectors, NumberOfFats, and
BigSectorsPerFat contain VALUES, not virtual ADDRESSES. That last
statement is going to explode, because you’re trying to derefence
invalid addresses. Further, your final computation is going to
overflow; you do all of the computations as unsigned longs, and only
when the computation is complete do you cast it to an int64. By that
time, it is too late. You need to switch to
int64 BEFORE you expect
the overflow.

x = pBPB_Buffer->ReservedSectors;
y = pBPB_Buffer->NumberOfFats;
z = pBPB_EXTENDED_BUFFER->BigSectorsPerFat;

offset = ((LONGLONG)( x + y * z )) << 9;

Of course, at that point, there’s no point in using the
oh-so-mnemonically-named x, y, and z at all. Just use the values directly:

offset = ((LONGLONG)
(pBPB_Buffer->ReservedSectors +
pBPB_Buffer->NumberOfFats
pBPB_EXTENDED_BUFFER->BigSectorsPerFat)
) << 9;

> //for fat16 type
>
> StartingBPBOffset.QuadPart=0;
>
> ReadFromVolume(gOSDriveobject,NULL,StartingBPBOffset,512,pMdl,pTempBuffer,&iosb);
> pBPB_Buffer=(PDISKFAT32BPB)pTempBuffer;
> pBPB_EXTENDED_BUFFER=(PEXTENDED_BPB)((UCHAR
)pTempBuffer+36);
> x=(unsigned short int )(pBPB_Buffer->ReservedSectors);
> y=(unsigned char
)(pBPB_Buffer->NumberOfFats);
> z=(unsigned int
)(pBPB_Buffer->SectorsPerFat);
>
> offset=(LONGLONG)(((ULONG)(*x) + ((ULONG)(y) (ULONG)(*z) ))*512);

The exact same problems apply here. Are you sure you’re going to find a
DISKFAT32BPB structure at that spot on a FAT16 volume?


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.


Questions? First check the Kernel Driver FAQ at http://www.osronline.com/article.cfm?id=256

You are currently subscribed to ntdev as: xxxxx@gmail.com
To unsubscribe send a blank email to xxxxx@lists.osr.com

Hello David
Well I donot understand the relation of FAT(16) with checked build, and
Please clear me what you actually mean by ‘checked build of fastfat’.

Thanks.

Regards
Anuj Agarwal

On 12/30/05, David J. Craig wrote:
>
> Run it under the debugger using the checked build of fastfat that you
> create.
>
> “Anuj Agarwal” wrote in message
> news:xxxxx@ntdev…
> Hello Tim
> Thanks for the reply but I think you haven’t read my first line thats it
> is running perfectly well on FAT32 and NTFS partitions so nothing much
> problem in the code like this-
>
> x = pBPB_Buffer->ReservedSectors;
> y = pBPB_Buffer->NumberOfFats;
> z = pBPB_EXTENDED_BUFFER->BigSectorsPerFat;
>
> > offset = ((LONGLONG)( x + y * z )) << 9;

> >
>
> its absolutely perfect what I want to know is that what changes I need to
> do so as to run my driver perfectly on FAT(16) partition as well.
>
> In another function, I’m using ClusterSize and IsFat32 variables and
> storing them in ‘deviceExtension’.
> func_name(…)
> {
> ULONG ulBitmapBufferSize=1024;
> …
> …
> pVolBitmapBuff=ExAllocatePool(NonPagedPool,ulBitmapBufferSize);
>
> status= ZwFsControlFile(
> FileHandle,
> NULL,// Event,
> NULL,// ApcRoutine,
> NULL,//IN ApcContext,
> &IoStatusBlock,//OUT IoStatusBlock,
> FSCTL_GET_VOLUME_BITMAP,//IN IoControlCode,
> &oStartLCN, //IN PVOID InputBuffer,
> sizeof(STARTING_LCN_INPUT_BUFFER), //IN VOID InputBufferLength,
> pVolBitmapBuff, //OUT PVOID OutputBuffer,
> ulBitmapBufferSize
> ); // OUT PVOID OutputBufferLength
>
>
> if(status == STATUS_BUFFER_OVERFLOW)
>
> {
> ulBitmapSize = (ULONG)((pVolBitmapBuff->BitmapSize.QuadPart / 8)
> +1);
> ulBitmapBufferSize = (2
sizeof(ULONGLONG) + ulBitmapSize);
>
> // total size of bitmap variable length structure
> ExFreePool(pVolBitmapBuff);
>
> pVolBitmapBuff = ExAllocatePool(NonPagedPool, ulBitmapBufferSize);
>
> if(!pVolBitmapBuff)
> {
> DbgPrint(“Error while getting WHILE pVolBitmapBuff2\n”);
> ExFreePool(TempDrivePath);
> return STATUS_INSUFFICIENT_RESOURCES;
> }
> RtlZeroMemory(pVolBitmapBuff, ulBitmapBufferSize);
> oStartLCN.StartingLcn.QuadPart = 0;
> status= ZwFsControlFile(
> FileHandle,
> NULL,// Event,
> NULL,// ApcRoutine,
> NULL,//IN ApcContext,
> &IoStatusBlock,//OUT IoStatusBlock,
> FSCTL_GET_VOLUME_BITMAP,//IN IoControlCode,
> &oStartLCN, //IN PVOID InputBuffer,
> sizeof(STARTING_LCN_INPUT_BUFFER), //IN VOID
> InputBufferLength,
> pVolBitmapBuff, //OUT PVOID OutputBuffer,
> ulBitmapBufferSize // it cantains the true size
> );
>
> }
>
>
> if (status!=STATUS_SUCCESS)
> {
> ExFreePool(pVolBitmapBuff);
> ExFreePool(TempDrivePath);
> ZwClose(FileHandle);
> return status;
> }
>
> else
> {
> pVolBitmapBuff2=ExAllocatePool(NonPagedPool,ulBitmapBufferSize);
>
> RtlInitializeBitMap(pBitMapHeader,(PULONG)(pVolBitmapBuff->Buffer),(ULONG)(pVolBitmapBuff->
> BitmapSize.QuadPart));
>
> RtlInitializeBitMap(pBitMapUser,(PULONG)(pVolBitmapBuff2->Buffer),(ULONG)(pVolBitmapBuff->
> BitmapSize.QuadPart));
> RtlClearAllBits(pBitMapUser);
> DbgPrint(“Success while getting bitmap\n”);
> }
>
> }
>
> And this code is running perfectly for FAt32 but may be have to do some
> more calculations/modifications for FAT16.
>
> Are you sure you’re going to find a
> DISKFAT32BPB structure at that spot on a FAT16 volume?
>
> Well for FAT16, ‘DISKFAT32BPB’ structure is almost same and in addition
> to this it has an extended FAT structure that has variables like’BigSectorsPerFat’ and
> in case of FAT16, we can take the value from DISKFAT32BPB structure having
> variable ‘SectorsPerFat’
>
> Thanks.
>
> Regards
> Anuj Agarwal
>
>
>
> On 12/29/05, Tim Roberts wrote:
> >
> > Anuj Agarwal wrote:
> >
> > >
> > > I have written a driver for Win2K and is running perfectly well on
> > > FAT32 and NTFS partitions
> > > but when I try to install 2K on FAT-Partition then its not performing
> > > all of its functionalities,
> > > What I think is I need to take some special care for FAT-16(FAT)
> > > partition, so anybody of u if
> > > can provide me some support it would be of great help, here is my code
> >
> > > snippet…
> > >
> > >
> > > ULONG GetVolInfo(PWCHAR DriveLetter,int
IsFat32,PULONG ClusterSize )
> >
> >
> > Why would you have a variable called IsFat32, and then use it to store
> > the values 1, 2, and 3? You are just asking for trouble. A variable
> > called IsSomething should be a boolean, with only “true” or “false”
> > values. A much better solution is to use an enumeration::
> >
> > enum FileSystem {
> > fsFAT16 = 0,
> > fsFAT32,
> > fsOther
> > };
> >
> > Or, better yet, use the symbols PARTITION_FAT_16 and PARTITION_FAT32
> > which already exist in ntdddisk.h.
> >
> > > {
> > > FILE_FS_SIZE_INFORMATION FsInformation;
> > >
> > > Status =
> > >
> > ZwQueryVolumeInformationFile(FileHandle,&IoStatusBlock,&FsInformation,sizeof(FILE_FS_SIZE_INFORMATION),FileFsSizeInformation
> > > );
> >
> >
> > Where did “FileHandle” come from?
> >
> > > SectorsPerAllocationUnit = FsInformation.SectorsPerAllocationUnit;
> > > BytesPerSector = FsInformation.BytesPerSector;
> > > CLUSTER_SIZE=SectorsPerAllocationUnit*BytesPerSector; // IN NO OF
> > BYTES
> > > *ClusterSize=CLUSTER_SIZE;
> > >
> > > Status =
> > >
> > ZwQueryVolumeInformationFile(FileHandle,&IoStatusBlock,&Buffer,sizeof(Buffer
> > > ),FileFsAttributeInformation);
> >
> >
> > What’s “Buffer”?
> >
> > > FsName = ((PFILE_FS_ATTRIBUTE_INFORMATION)Buffer)->FileSystemName;
> > >
> > > FsNameLen =
> > > ((PFILE_FS_ATTRIBUTE_INFORMATION)Buffer)->FileSystemNameLength;
> > >
> > > // Compare the name
> > > if( ( FsNameLen >= 3 * sizeof(WCHAR) ) && RtlEqualMemory(FsName,
> > > L"FAT", 3 * sizeof(WCHAR)) )
> > > {
> > > // Check for FAT32
> > > if( ( FsNameLen >= 5 * sizeof(WCHAR) ) &&
> > > RtlEqualMemory(FsName + 3, L"32", 2 * sizeof(WCHAR)) )
> > > {
> >
> >
> > Good grief. Why wouldn’t you just use:
> >
> > if( wcsncmp( FsName, L"FAT", 3 ) == 0 )
> > {
> > if( wcscmp( FsName, L"FAT32" ) == 0 )
> > {
> >
> > > In the above code, I am finding the type of Partition/file system and
> > > the CLUSTER_SIZE and using this information
> > > for further processing. Do i need to modify the ‘*ClusterSize’ or
> > > something in the code given below…
> > >
> > > if(fat32flag==2)
> > > {
> > > pTempBuffer = ExAllocatePool(NonPagedPool,ClusterSize);
> > > pMdl = IoAllocateMdl(pTempBuffer, ClusterSize, FALSE, TRUE, 0);
> > > MmBuildMdlForNonPagedPool(pMdl);
> > >
> > > //for fat32 type
> > >
> > > StartingBPBOffset.QuadPart=0;
> > >
> >
> > > ReadFromVolume(gOSDriveobject,NULL,StartingBPBOffset,512,pMdl,pTempBuffer,&iosb);
> >
> >
> > Interesting; why would you allocate CLUSTER_SIZE bytes, and then read
> > only 512?
> >
> > > pBPB_Buffer=(PDISKFAT32BPB)pTempBuffer;
> > > pBPB_EXTENDED_BUFFER=(PEXTENDED_BPB)((UCHAR
)pTempBuffer+36);
> > > x=(unsigned short int )(pBPB_Buffer->ReservedSectors);
> > > y=(unsigned char
)(pBPB_Buffer->NumberOfFats);
> > > z=(unsigned int
)(pBPB_EXTENDED_BUFFER->BigSectorsPerFat);
> > >
> > > offset=(LONGLONG)(((ULONG)(*x) + ((ULONG)(y) (ULONG)(*z)
> > ))512);
> >
> >
> > That’s CERTAINLY not right. ReservedSectors, NumberOfFats, and
> > BigSectorsPerFat contain VALUES, not virtual ADDRESSES. That last
> > statement is going to explode, because you’re trying to derefence
> > invalid addresses. Further, your final computation is going to
> > overflow; you do all of the computations as unsigned longs, and only
> > when the computation is complete do you cast it to an int64. By that
> > time, it is too late. You need to switch to
int64 BEFORE you expect
> > the overflow.
> >
> > x = pBPB_Buffer->ReservedSectors;
> > y = pBPB_Buffer->NumberOfFats;
> > z = pBPB_EXTENDED_BUFFER->BigSectorsPerFat;
> >
> > offset = ((LONGLONG)( x + y * z )) << 9;
> >
> > Of course, at that point, there’s no point in using the
> > oh-so-mnemonically-named x, y, and z at all. Just use the values
> > directly:
> >
> > offset = ((LONGLONG)
> > (pBPB_Buffer->ReservedSectors +
> > pBPB_Buffer->NumberOfFats
> > pBPB_EXTENDED_BUFFER->BigSectorsPerFat)
> > ) << 9;
> >
> > > //for fat16 type
> > >
> > > StartingBPBOffset.QuadPart=0;
> > >
> >
> > > ReadFromVolume(gOSDriveobject,NULL,StartingBPBOffset,512,pMdl,pTempBuffer,&iosb);
> > > pBPB_Buffer=(PDISKFAT32BPB)pTempBuffer;
> > > pBPB_EXTENDED_BUFFER=(PEXTENDED_BPB)((UCHAR
)pTempBuffer+36);
> > > x=(unsigned short int )(pBPB_Buffer->ReservedSectors);
> > > y=(unsigned char
)(pBPB_Buffer->NumberOfFats);
> > > z=(unsigned int
)(pBPB_Buffer->SectorsPerFat);
> > >
> > > offset=(LONGLONG)(((ULONG)(*x) + ((ULONG)(y) (ULONG)(*z)
> > ))*512);
> >
> >
> > The exact same problems apply here. Are you sure you’re going to find a
> > DISKFAT32BPB structure at that spot on a FAT16 volume?
> >
> > –
> > Tim Roberts, xxxxx@probo.com
> > Providenza & Boekelheide, Inc.
> >
> >
> >
> > —
> > Questions? First check the Kernel Driver FAQ at
> > http://www.osronline.com/article.cfm?id=256
> >
> > You are currently subscribed to ntdev as: xxxxx@gmail.com
> > To unsubscribe send a blank email to xxxxx@lists.osr.com
> >
>
>
> —
> Questions? First check the Kernel Driver FAQ at
> http://www.osronline.com/article.cfm?id=256
>
> You are currently subscribed to ntdev as: unknown lmsubst tag argument: ‘’
>
> To unsubscribe send a blank email to xxxxx@lists.osr.com

He meant in your IFS kit, you have the fat source. Build it with the
checked enviroment, installed the checked version you build, and debug
away…

Anuj Agarwal wrote:

Hello David
Well I donot understand the relation of FAT(16) with checked build,
and Please clear me what you actually mean by ‘checked build of fastfat’.

Thanks.

Regards
Anuj Agarwal

On 12/30/05, *David J. Craig* > mailto:xxxxx> wrote:
>
> Run it under the debugger using the checked build of fastfat that
> you create.
>
> “Anuj Agarwal” > mailto:xxxxx> wrote in message
> news:xxxxx@ntdev…
> Hello Tim
> Thanks for the reply but I think you haven’t read my first
> line thats it is running perfectly well on FAT32 and NTFS
> partitions so nothing much problem in the code like this-
>
> x = pBPB_Buffer->ReservedSectors;
> y = pBPB_Buffer->NumberOfFats;
> z = pBPB_EXTENDED_BUFFER->BigSectorsPerFat;
>
> offset = ((LONGLONG)( x + y * z )) << 9;

>
>
> its absolutely perfect what I want to know is that what
> changes I need to do so as to run my driver perfectly on
> FAT(16) partition as well.
>
> In another function, I’m using ClusterSize and IsFat32
> variables and storing them in ‘deviceExtension’.
> func_name(…)
> {
> ULONG ulBitmapBufferSize=1024;
> …
> …
>
> pVolBitmapBuff=ExAllocatePool(NonPagedPool,ulBitmapBufferSize);
>
> status= ZwFsControlFile(
> FileHandle,
> NULL,// Event,
> NULL,// ApcRoutine,
> NULL,//IN ApcContext,
> &IoStatusBlock,//OUT IoStatusBlock,
> FSCTL_GET_VOLUME_BITMAP,//IN IoControlCode,
> &oStartLCN, //IN PVOID InputBuffer,
> sizeof(STARTING_LCN_INPUT_BUFFER), //IN VOID
> InputBufferLength,
> pVolBitmapBuff, //OUT PVOID OutputBuffer,
> ulBitmapBufferSize
> ); // OUT PVOID OutputBufferLength
>
>
> if(status == STATUS_BUFFER_OVERFLOW)
>
> {
> ulBitmapSize =
> (ULONG)((pVolBitmapBuff->BitmapSize.QuadPart / 8) +1);
> ulBitmapBufferSize = (2
sizeof(ULONGLONG) + ulBitmapSize);
>
> // total size of bitmap variable length structure
> ExFreePool(pVolBitmapBuff);
>
> pVolBitmapBuff = ExAllocatePool(NonPagedPool,
> ulBitmapBufferSize);
>
> if(!pVolBitmapBuff)
> {
> DbgPrint(“Error while getting WHILE pVolBitmapBuff2\n”);
> ExFreePool(TempDrivePath);
> return STATUS_INSUFFICIENT_RESOURCES;
> }
> RtlZeroMemory(pVolBitmapBuff, ulBitmapBufferSize);
> oStartLCN.StartingLcn.QuadPart = 0;
> status= ZwFsControlFile(
> FileHandle,
> NULL,// Event,
> NULL,// ApcRoutine,
> NULL,//IN ApcContext,
> &IoStatusBlock,//OUT IoStatusBlock,
> FSCTL_GET_VOLUME_BITMAP,//IN IoControlCode,
> &oStartLCN, //IN PVOID InputBuffer,
> sizeof(STARTING_LCN_INPUT_BUFFER), //IN VOID
> InputBufferLength,
> pVolBitmapBuff, //OUT PVOID OutputBuffer,
> ulBitmapBufferSize // it cantains the true size
> );
>
> }
>
>
> if (status!=STATUS_SUCCESS)
> {
> ExFreePool(pVolBitmapBuff);
> ExFreePool(TempDrivePath);
> ZwClose(FileHandle);
> return status;
> }
>
> else
> {
>
> pVolBitmapBuff2=ExAllocatePool(NonPagedPool,ulBitmapBufferSize);
>
> RtlInitializeBitMap(pBitMapHeader,(PULONG)(pVolBitmapBuff->Buffer),(ULONG)(pVolBitmapBuff->BitmapSize.QuadPart));
>
> RtlInitializeBitMap(pBitMapUser,(PULONG)(pVolBitmapBuff2->Buffer),(ULONG)(pVolBitmapBuff->BitmapSize.QuadPart));
> RtlClearAllBits(pBitMapUser);
> DbgPrint(“Success while getting bitmap\n”);
> }
>
> }
>
> And this code is running perfectly for FAt32 but may be have
> to do some more calculations/modifications for FAT16.
>
> Are you sure you’re going to find a
> DISKFAT32BPB structure at that spot on a FAT16 volume?
>
> Well for FAT16, ‘DISKFAT32BPB’ structure is almost same and
> in addition to this it has an extended FAT structure that
> has variables like ‘BigSectorsPerFat’ and in case of FAT16, we
> can take the value from DISKFAT32BPB structure having variable
> ‘SectorsPerFat’
>
> Thanks.
>
> Regards
> Anuj Agarwal
>
>
>
> On 12/29/05, Tim Roberts > mailto:xxxxx> wrote:
>
> Anuj Agarwal wrote:
>
>>
>> I have written a driver for Win2K and is running
> perfectly well on
>> FAT32 and NTFS partitions
>> but when I try to install 2K on FAT-Partition then its
> not performing
>> all of its functionalities,
>> What I think is I need to take some special care for
> FAT-16(FAT)
>> partition, so anybody of u if
>> can provide me some support it would be of great help,
> here is my code
>> snippet…
>>
>>
>> ULONG GetVolInfo(PWCHAR DriveLetter,int
IsFat32,PULONG
> ClusterSize )
>
>
> Why would you have a variable called IsFat32, and then use
> it to store
> the values 1, 2, and 3? You are just asking for
> trouble. A variable
> called IsSomething should be a boolean, with only “true”
> or “false”
> values. A much better solution is to use an enumeration::
>
> enum FileSystem {
> fsFAT16 = 0,
> fsFAT32,
> fsOther
> };
>
> Or, better yet, use the symbols PARTITION_FAT_16 and
> PARTITION_FAT32
> which already exist in ntdddisk.h.
>
>> {
>> FILE_FS_SIZE_INFORMATION FsInformation;
>>
>> Status =
>> ZwQueryVolumeInformationFile(FileHandle,&IoStatusBlock,&FsInformation,sizeof(FILE_FS_SIZE_INFORMATION),FileFsSizeInformation
>> );
>
>
> Where did “FileHandle” come from?
>
>> SectorsPerAllocationUnit =
> FsInformation.SectorsPerAllocationUnit;
>> BytesPerSector = FsInformation.BytesPerSector;
>> CLUSTER_SIZE=SectorsPerAllocationUnit*BytesPerSector; //
> IN NO OF BYTES
>> *ClusterSize=CLUSTER_SIZE;
>>
>> Status =
>> ZwQueryVolumeInformationFile(FileHandle,&IoStatusBlock,&Buffer,sizeof(Buffer
>> ),FileFsAttributeInformation);
>
>
> What’s “Buffer”?
>
>> FsName =
> ((PFILE_FS_ATTRIBUTE_INFORMATION)Buffer)->FileSystemName;
>>
>> FsNameLen =
>> ((PFILE_FS_ATTRIBUTE_INFORMATION)Buffer)->FileSystemNameLength;
>>
>> // Compare the name
>> if( ( FsNameLen >= 3 * sizeof(WCHAR) ) &&
> RtlEqualMemory(FsName,
>> L"FAT", 3 * sizeof(WCHAR)) )
>> {
>> // Check for FAT32
>> if( ( FsNameLen >= 5 * sizeof(WCHAR) ) &&
>> RtlEqualMemory(FsName + 3, L"32", 2 * sizeof(WCHAR)) )
>> {
>
>
> Good grief. Why wouldn’t you just use:
>
> if( wcsncmp( FsName, L"FAT", 3 ) == 0 )
> {
> if( wcscmp( FsName, L"FAT32" ) == 0 )
> {
>
>> In the above code, I am finding the type of
> Partition/file system and
>> the CLUSTER_SIZE and using this information
>> for further processing. Do i need to modify the
> ‘*ClusterSize’ or
>> something in the code given below…
>>
>> if(fat32flag==2)
>> {
>> pTempBuffer = ExAllocatePool(NonPagedPool,ClusterSize);
>> pMdl = IoAllocateMdl(pTempBuffer, ClusterSize,
> FALSE, TRUE, 0);
>> MmBuildMdlForNonPagedPool(pMdl);
>>
>> //for fat32 type
>>
>> StartingBPBOffset.QuadPart=0;
>>
>> ReadFromVolume(gOSDriveobject,NULL,StartingBPBOffset,512,pMdl,pTempBuffer,&iosb);
>
>
> Interesting; why would you allocate CLUSTER_SIZE bytes,
> and then read
> only 512?
>
>> pBPB_Buffer=(PDISKFAT32BPB)pTempBuffer;
>>
> pBPB_EXTENDED_BUFFER=(PEXTENDED_BPB)((UCHAR
)pTempBuffer+36);
>> x=(unsigned short int )(pBPB_Buffer->ReservedSectors);
>> y=(unsigned char
)(pBPB_Buffer->NumberOfFats);
>> z=(unsigned
> int
)(pBPB_EXTENDED_BUFFER->BigSectorsPerFat);
>>
>> offset=(LONGLONG)(((ULONG)(*x) + ((ULONG)(y)
> (ULONG)(*z) ))512);
>
>
> That’s CERTAINLY not right. ReservedSectors,
> NumberOfFats, and
> BigSectorsPerFat contain VALUES, not virtual
> ADDRESSES. That last
> statement is going to explode, because you’re trying to
> derefence
> invalid addresses. Further, your final computation is
> going to
> overflow; you do all of the computations as unsigned
> longs, and only
> when the computation is complete do you cast it to an
> int64. By that
> time, it is too late. You need to switch to
int64
> BEFORE you expect
> the overflow.
>
> x = pBPB_Buffer->ReservedSectors;
> y = pBPB_Buffer->NumberOfFats;
> z = pBPB_EXTENDED_BUFFER->BigSectorsPerFat;
>
> offset = ((LONGLONG)( x + y * z )) << 9;
>
> Of course, at that point, there’s no point in using the
> oh-so-mnemonically-named x, y, and z at all. Just use the
> values directly:
>
> offset = ((LONGLONG)
> (pBPB_Buffer->ReservedSectors +
> pBPB_Buffer->NumberOfFats
> pBPB_EXTENDED_BUFFER->BigSectorsPerFat)
> ) << 9;
>
>> //for fat16 type
>>
>> StartingBPBOffset.QuadPart=0;
>>
>> ReadFromVolume(gOSDriveobject,NULL,StartingBPBOffset,512,pMdl,pTempBuffer,&iosb);
>> pBPB_Buffer=(PDISKFAT32BPB)pTempBuffer;
>>
> pBPB_EXTENDED_BUFFER=(PEXTENDED_BPB)((UCHAR
)pTempBuffer+36);
>> x=(unsigned short int )(pBPB_Buffer->ReservedSectors);
>> y=(unsigned char
)(pBPB_Buffer->NumberOfFats);
>> z=(unsigned int
)(pBPB_Buffer->SectorsPerFat);
>>
>> offset=(LONGLONG)(((ULONG)(*x) + ((ULONG)(y)
> (ULONG)(*z) ))*512);
>
>
> The exact same problems apply here. Are you sure you’re
> going to find a
> DISKFAT32BPB structure at that spot on a FAT16 volume?
>
> –
> Tim Roberts, xxxxx@probo.com mailto:xxxxx
> Providenza & Boekelheide, Inc.
>
>
>
> —
> Questions? First check the Kernel Driver FAQ at
> http://www.osronline.com/article.cfm?id=256
>
> You are currently subscribed to ntdev as:
> xxxxx@gmail.com mailto:xxxxx
> To unsubscribe send a blank email to
> xxxxx@lists.osr.com
> mailto:xxxxx
>
>
>
> —
> Questions? First check the Kernel Driver FAQ at
> http://www.osronline.com/article.cfm?id=256
>
> You are currently subscribed to ntdev as: unknown lmsubst tag
> argument: ‘’
> To unsubscribe send a blank email to
> xxxxx@lists.osr.com
> mailto:xxxxx
>
>
> — Questions? First check the Kernel Driver FAQ at
> http://www.osronline.com/article.cfm?id=256 You are currently
> subscribed to ntdev as: unknown lmsubst tag argument: ‘’ To
> unsubscribe send a blank email to xxxxx@lists.osr.com</mailto:xxxxx></mailto:xxxxx></mailto:xxxxx></mailto:xxxxx></mailto:xxxxx></mailto:xxxxx></mailto:xxxxx>

Anuj Agarwal wrote:

Hello Tim
Thanks for the reply but I think you haven’t read my first line thats
it is running perfectly well on FAT32 and NTFS partitions so nothing
much problem in the code like this-

*** x = pBPB_Buffer->ReservedSectors;
y = pBPB_Buffer->NumberOfFats;
z = pBPB_EXTENDED_BUFFER->BigSectorsPerFat;

offset = ((LONGLONG)( x + y * z )) << 9; ***

its absolutely perfect

Yes, but that is most definitely *NOT* how your original code read. The
code as you posted it was wrong.


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

HI Tim
You may be right but I have used this code and is implementing on several
machines but only for FAT32 and NTFS partitions and showing just no problems
and showing some problems with only FAT(16) partitions. What I think is that
the main cause is due to wrong allocation of memory to some of the buffer or
some variable, either I’m allocating some less memory or too much so its
getting problems while reading and writing the files/disk.

Thanks.

Regards
Anuj Agarwal

On 12/30/05, Tim Roberts wrote:
>
> Anuj Agarwal wrote:
>
> > Hello Tim
> > Thanks for the reply but I think you haven’t read my first line thats
> > it is running perfectly well on FAT32 and NTFS partitions so nothing
> > much problem in the code like this-
> >
> > x = pBPB_Buffer->ReservedSectors;
> > y = pBPB_Buffer->NumberOfFats;
> > z = pBPB_EXTENDED_BUFFER->BigSectorsPerFat;
> >
> > offset = ((LONGLONG)( x + y * z )) << 9;

> >
> >
> > its absolutely perfect
>
>
> Yes, but that is most definitely NOT how your original code read. The
> code as you posted it was wrong.
>
> –
> Tim Roberts, xxxxx@probo.com
> Providenza & Boekelheide, Inc.
>
>
>
> —
> Questions? First check the Kernel Driver FAQ at
> http://www.osronline.com/article.cfm?id=256
>
> You are currently subscribed to ntdev as: xxxxx@gmail.com
> To unsubscribe send a blank email to xxxxx@lists.osr.com
>