DeviceIoControl API call with FSCTL_GET_VOLUME_BITMAP
DeviceIoControl API call with FSCTL_GET_VOLUME_BITMAP
Would anyone have an example of how to call the DeviceIoControl Windows API with FSCTL_GET_VOLUME_BITMAP?
Ref: https://docs.microsoft.com/fr-fr/window ... ume_bitmap
Thanks!
(example code in C - see my next post)
Ref: https://docs.microsoft.com/fr-fr/window ... ume_bitmap
Thanks!
(example code in C - see my next post)
Last edited by firace on Sun Sep 18, 2022 8:55 am, edited 1 time in total.
Re: DeviceIoControl API call with FSCTL_GET_VOLUME_BITMAP
Hello, here :I think you have to replace 0 with #Generic_Read (1 << 31).
Code: Select all
hDevice = CreateFile_ ("\\.\PhysicalDrive0", 0, #FILE_SHARE_READ | #FILE_SHARE_WRITE, #Null, #OPEN_EXISTING, 0, #Null)
Re: DeviceIoControl API call with FSCTL_GET_VOLUME_BITMAP
Hi, I've removed the code in the OP as it is not so relevant to the topic.
More info about the cluster map (volume bitmap):
https://redcircle.blog/2008/11/26/cluster-map/
https://codeistry.wordpress.com/2015/01 ... fs-volume/
This is what I would like to write in PB:
My main obstacle is the VOLUME_BITMAP_BUFFER type I guess.
More info about the cluster map (volume bitmap):
https://redcircle.blog/2008/11/26/cluster-map/
https://codeistry.wordpress.com/2015/01 ... fs-volume/
This is what I would like to write in PB:
Code: Select all
const int bitmapSize = 65536;
byte bitmapBuffer[bitmapSize + sizeof (VOLUME_BITMAP_BUFFER)];
VOLUME_BITMAP_BUFFER *bitmap = (VOLUME_BITMAP_BUFFER *) bitmapBuffer;
startLcn.q = 0;
DWORD bytesReturned;
DeviceIoControl (volumeHandle, FSCTL_GET_VOLUME_BITMAP, &startLcn, sizeof (startLcn), &bitmapBuffer, sizeof (bitmapBuffer), &bytesReturned, NULL)
Re: DeviceIoControl API call with FSCTL_GET_VOLUME_BITMAP
You need 'Administrator mode' in compiler options.
Else LastError is 6 (0x6): The handle is invalid.
If LastError is 234 (0xEA): More data is available.
then the buffer is to small,
And you can not open a 'physical drive', you need to open a Volume.
In my case, this works:
(222GB Volume returns 7288861 bytes -> clustersize is 32768)
Else LastError is 6 (0x6): The handle is invalid.
If LastError is 234 (0xEA): More data is available.
then the buffer is to small,
And you can not open a 'physical drive', you need to open a Volume.
In my case, this works:
(222GB Volume returns 7288861 bytes -> clustersize is 32768)
Code: Select all
EnableExplicit
#FSCTL_GET_VOLUME_BITMAP = $0009006F
Define.i hVolume, Result, LastError
Define.q startLcn, bytesReturned
Define *bitmapBuffer
hVolume = CreateFile_ ("\\.\c:", #GENERIC_READ | #GENERIC_WRITE, #FILE_SHARE_READ | #FILE_SHARE_WRITE, #Null, #OPEN_EXISTING, 0, #Null)
If hVolume
*bitmapBuffer = AllocateMemory($800000)
If *bitmapBuffer
Result = DeviceIoControl_(hVolume, #FSCTL_GET_VOLUME_BITMAP, @startLcn, SizeOf(startLcn), *bitmapBuffer, MemorySize(*bitmapBuffer), @bytesReturned, #Null)
LastError = GetLastError_()
If LastError
MessageRequester("Last Error", Str(LastError) + " (" + Hex(LastError) + ") " + Str(bytesReturned))
Else
MessageRequester("Info", "Bytes returned: " + Str(bytesReturned))
EndIf
FreeMemory(*bitmapBuffer)
EndIf
CloseHandle_(hVolume)
EndIf
Re: DeviceIoControl API call with FSCTL_GET_VOLUME_BITMAP
Thanks a lot infratec, great answer as usual!
Re: DeviceIoControl API call with FSCTL_GET_VOLUME_BITMAP
A bit more extended:
In front of the real data is the Starting LCN and the BitMap size.
Code: Select all
EnableExplicit
#IOCTL_STORAGE_READ_CAPACITY = $2D5140
#FSCTL_GET_VOLUME_BITMAP = $0009006F
Structure STORAGE_READ_CAPACITY Align #PB_Structure_AlignC
Version.l
Size.l
BlockLength.l
NumberOfBlocks.LARGE_INTEGER
DiskLength.LARGE_INTEGER
EndStructure
Structure STARTING_VCN_INPUT_BUFFER Align #PB_Structure_AlignC
StartingVcn.LARGE_INTEGER
EndStructure
Structure VOLUME_BITMAP_BUFFER Align #PB_Structure_AlignC
StartingLcn.LARGE_INTEGER
BitmapSize.LARGE_INTEGER
Buffer.a[0]
EndStructure
Define.i hVolume, Result, LastError
Define.q startLcn, bytesReturned
Define *bitmapBuffer.VOLUME_BITMAP_BUFFER
Define StorageReadCapacity.STORAGE_READ_CAPACITY
Define Msg$
hVolume = CreateFile_ ("\\.\c:", #GENERIC_READ, #FILE_SHARE_READ | #FILE_SHARE_WRITE, #Null, #OPEN_EXISTING, 0, #Null)
If hVolume
Result = DeviceIoControl_(hVolume, #IOCTL_STORAGE_READ_CAPACITY, #Null, 0, @StorageReadCapacity, SizeOf(STORAGE_READ_CAPACITY), @bytesReturned, #Null)
LastError = GetLastError_()
If LastError
MessageRequester("Last Error", Str(LastError) + " (" + Hex(LastError) + ") " + Str(bytesReturned))
Else
Msg$ = "Bytes returned: " + Str(bytesReturned) + #LF$
Msg$ + "Size: " + Str(StorageReadCapacity\Size) + #LF$
Msg$ + "BlockLength: " + Str(StorageReadCapacity\BlockLength) + #LF$
Msg$ + "NumberOfBlocks: " + Str(StorageReadCapacity\NumberOfBlocks\QuadPart) + #LF$
Msg$ + "DiskLength: " + Str(StorageReadCapacity\DiskLength\QuadPart)
MessageRequester("Info", Msg$)
EndIf
*bitmapBuffer = AllocateMemory(StorageReadCapacity\DiskLength\QuadPart / 4096 / 8)
If *bitmapBuffer
Result = DeviceIoControl_(hVolume, #FSCTL_GET_VOLUME_BITMAP, @startLcn, SizeOf(startLcn), *bitmapBuffer, MemorySize(*bitmapBuffer), @bytesReturned, #Null)
LastError = GetLastError_()
If LastError
MessageRequester("Last Error", Str(LastError) + " (" + Hex(LastError) + ") " + Str(bytesReturned))
Else
Msg$ = "Bytes returned: " + Str(bytesReturned) + #LF$
Msg$ + "StartingLcn: " + Str(*bitmapBuffer\StartingLcn\QuadPart) + #LF$
Msg$ + "BitMapSize: " + Str(*bitmapBuffer\BitmapSize\QuadPart)
MessageRequester("Info", Msg$)
EndIf
FreeMemory(*bitmapBuffer)
EndIf
CloseHandle_(hVolume)
EndIf
Re: DeviceIoControl API call with FSCTL_GET_VOLUME_BITMAP
Very good subject, very good questions, and very good answers.
Thanks to you two, firace and infratec. I cannot test it actually, but just the name of "cluster" makes me remember the hundreds hours I spent more than twenty years ago, to format and repair freely harddisks. Imagine the start of this very strange session, as the children of my time were playing "PSX" or football outdoor : a message I discovered on a stick on a side of a harddisk in a garbage, just this << 11 megabytes Execute C800:0005 >> !
When I had only 3 floppy disks of 1.44MB, 11 megabytes was the paradise ! I did not remember if it was a seagate (ST), but I read the "cluster" word, for the first time on its stick.
It was noisy like a vacuum cleaner, took about twenty seconds to initialize in a din, and was so bulky, but I loved this first hard drive! Thank you so, just to read a so interesting subject !
Without computer, I cannot give a lot, to complete your work, certainly less than you already know :Here, is a linear bit reader (from long or from quad). But I am even not sure it is okay, depending of the endianness of the API...
Thanks to you two, firace and infratec. I cannot test it actually, but just the name of "cluster" makes me remember the hundreds hours I spent more than twenty years ago, to format and repair freely harddisks. Imagine the start of this very strange session, as the children of my time were playing "PSX" or football outdoor : a message I discovered on a stick on a side of a harddisk in a garbage, just this << 11 megabytes Execute C800:0005 >> !
When I had only 3 floppy disks of 1.44MB, 11 megabytes was the paradise ! I did not remember if it was a seagate (ST), but I read the "cluster" word, for the first time on its stick.
It was noisy like a vacuum cleaner, took about twenty seconds to initialize in a din, and was so bulky, but I loved this first hard drive! Thank you so, just to read a so interesting subject !
Without computer, I cannot give a lot, to complete your work, certainly less than you already know :
Code: Select all
Structure bit32
i.L[0]
EndStructure
Structure bit64
i.q[0]
EndStructure
Procedure bit32GetBit(*this.bit32, i)
ProcedureReturn *this\i[i >> 5] >> (i & 31) & 1
EndProcedure
Procedure bit64GetBit(*this.bit64, i)
ProcedureReturn *this\i[i >> 6] >> (i & 63) & 1
EndProcedure
Re: DeviceIoControl API call with FSCTL_GET_VOLUME_BITMAP
infratec wrote: Sun Sep 18, 2022 3:37 pm A bit more extended:In front of the real data is the Starting LCN and the BitMap size.Code: Select all
EnableExplicit #IOCTL_STORAGE_READ_CAPACITY = $2D5140 #FSCTL_GET_VOLUME_BITMAP = $0009006F Structure STORAGE_READ_CAPACITY Align #PB_Structure_AlignC Version.l Size.l BlockLength.l NumberOfBlocks.LARGE_INTEGER DiskLength.LARGE_INTEGER EndStructure Structure STARTING_VCN_INPUT_BUFFER Align #PB_Structure_AlignC StartingVcn.LARGE_INTEGER EndStructure Structure VOLUME_BITMAP_BUFFER Align #PB_Structure_AlignC StartingLcn.LARGE_INTEGER BitmapSize.LARGE_INTEGER Buffer.a[0] EndStructure Define.i hVolume, Result, LastError Define.q startLcn, bytesReturned Define *bitmapBuffer.VOLUME_BITMAP_BUFFER Define StorageReadCapacity.STORAGE_READ_CAPACITY Define Msg$ hVolume = CreateFile_ ("\\.\c:", #GENERIC_READ, #FILE_SHARE_READ | #FILE_SHARE_WRITE, #Null, #OPEN_EXISTING, 0, #Null) If hVolume Result = DeviceIoControl_(hVolume, #IOCTL_STORAGE_READ_CAPACITY, #Null, 0, @StorageReadCapacity, SizeOf(STORAGE_READ_CAPACITY), @bytesReturned, #Null) LastError = GetLastError_() If LastError MessageRequester("Last Error", Str(LastError) + " (" + Hex(LastError) + ") " + Str(bytesReturned)) Else Msg$ = "Bytes returned: " + Str(bytesReturned) + #LF$ Msg$ + "Size: " + Str(StorageReadCapacity\Size) + #LF$ Msg$ + "BlockLength: " + Str(StorageReadCapacity\BlockLength) + #LF$ Msg$ + "NumberOfBlocks: " + Str(StorageReadCapacity\NumberOfBlocks\QuadPart) + #LF$ Msg$ + "DiskLength: " + Str(StorageReadCapacity\DiskLength\QuadPart) MessageRequester("Info", Msg$) EndIf *bitmapBuffer = AllocateMemory(StorageReadCapacity\DiskLength\QuadPart / 4096 / 8) If *bitmapBuffer Result = DeviceIoControl_(hVolume, #FSCTL_GET_VOLUME_BITMAP, @startLcn, SizeOf(startLcn), *bitmapBuffer, MemorySize(*bitmapBuffer), @bytesReturned, #Null) LastError = GetLastError_() If LastError MessageRequester("Last Error", Str(LastError) + " (" + Hex(LastError) + ") " + Str(bytesReturned)) Else Msg$ = "Bytes returned: " + Str(bytesReturned) + #LF$ Msg$ + "StartingLcn: " + Str(*bitmapBuffer\StartingLcn\QuadPart) + #LF$ Msg$ + "BitMapSize: " + Str(*bitmapBuffer\BitmapSize\QuadPart) MessageRequester("Info", Msg$) EndIf FreeMemory(*bitmapBuffer) EndIf CloseHandle_(hVolume) EndIf
; PB 6.0 LTS (x86) & (x64) ASM Backend
; OK
; PB 6.0 LTS (x86) & (x64) C Backend:
; Error: Negative DiskLength (and the NumberOfBlocks also not correct)
The disk length is determined correctly if I change the structure.:
Code: Select all
Structure STORAGE_READ_CAPACITY Align #PB_Structure_AlignC
Version.l
Size.l
BlockLength.l
NumberOfBlocks.q
DiskLength.q
EndStructure
Re: DeviceIoControl API call with FSCTL_GET_VOLUME_BITMAP
My apologize, it was a Western Digital... 0.000011 terabytes. And it is Microsoft DBLSPACE which has killed my vacuum cleaner... I had been too greedy... It had fins like moped engines...
Re: DeviceIoControl API call with FSCTL_GET_VOLUME_BITMAP
I was typing the extended version of infratec, when I stopped on front of "4096"...
On one level we have 512, and on a second level we habe 4096 : does this mean, there are two allocating table ?
On one level we have 512, and on a second level we habe 4096 : does this mean, there are two allocating table ?