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=SectorsPerAllocationUnitBytesPerSector; // 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
>