Page 1 of 1

real disk size with IOCTL_DISK_GET_DRIVE_GEOMETRY_EX

Posted: Mon Jul 17, 2006 1:38 pm
by bingo
Code updated for 5.20+

Code: Select all

Structure DISK_GEOMETRY
  Cylinders.q
  MediaType.l
  TracksPerCylinder.l
  SectorsPerTrack.l
  BytesPerSector.l 
EndStructure

Structure DISK_GEOMETRY_EX
  pp1.DISK_GEOMETRY
  DiskSize.q
  byte.b[1];
EndStructure

pp.DISK_GEOMETRY_EX

#IOCTL_DISK_BASE                = 7  
#METHOD_BUFFERED                = 0
#FILE_ANY_ACCESS                = 0

Procedure.l CTL_CODE(DeviceType, Function, Method, Access)
  ProcedureReturn ((DeviceType) << 16) | ((Access) << 14) | ((Function) << 2) | (Method)
EndProcedure

IOCTL_DISK_GET_DRIVE_GEOMETRY_EX = CTL_CODE(#IOCTL_DISK_BASE, $28, #METHOD_BUFFERED, #FILE_ANY_ACCESS) 


hDevice = CreateFile_("\\.\PhysicalDrive0", #GENERIC_READ,#FILE_SHARE_READ,0,#OPEN_EXISTING,0,0)

If hDevice
  
  DeviceIoControl_(hDevice, IOCTL_DISK_GET_DRIVE_GEOMETRY_EX,0,0,@pp,SizeOf(pp),@bytesret, 0)
  
EndIf

CloseHandle_(hDevice)

Debug pp\Disksize / (1024*1024*1024) ;in gb

;and other

Debug pp\pp1\cylinders
Debug pp\pp1\TracksPerCylinder
Debug pp\pp1\SectorsPerTrack
Debug pp\pp1\BytesPerSector
xp , vista (beta2) :D

Posted: Mon Jul 17, 2006 11:13 pm
by mskuma
Thanks. On my machine (XP) the code produced all zeros for the output until I changed:

Code: Select all

hDevice = CreateFile_("\\.\PhysicalDrive0", #GENERIC_READ,#FILE_SHARE_READ,0,#OPEN_EXISTING,0,0)
to:

Code: Select all

hDevice = CreateFile_("\\.\PhysicalDrive0", #GENERIC_READ | #GENERIC_WRITE, #FILE_SHARE_READ | #FILE_SHARE_WRITE,0, #OPEN_EXISTING, 0, 0) 
So perhaps the latter is safer.

Posted: Tue Jul 18, 2006 1:10 am
by Flype
it works for me.
but it seems a little bit cleaner this way :

Code: Select all

; winioctl.h

Structure DISK_GEOMETRY 
  Cylinders.q 
  MediaType.l 
  TracksPerCylinder.l 
  SectorsPerTrack.l 
  BytesPerSector.l 
EndStructure 

Structure DISK_GEOMETRY_EX Extends DISK_GEOMETRY 
  DiskSize.q 
  byte.b[1]
EndStructure 

#FILE_ANY_ACCESS = 0 
#METHOD_BUFFERED = 0 
#IOCTL_DISK_BASE = 7  

Macro CTL_CODE(DeviceType, Function, Method, Access) 
  ((DeviceType)<<16)|((Access)<<14)|((Function)<<2)|(Method) 
EndMacro

#IOCTL_DISK_GET_DRIVE_GEOMETRY_EX = CTL_CODE(#IOCTL_DISK_BASE, $28, #METHOD_BUFFERED, #FILE_ANY_ACCESS) 

ProcedureDLL.q GetDiskSize(PhysicalDrive.l)
  
  Protected device.l, bytes.l, os.OSVERSIONINFO, disk.DISK_GEOMETRY_EX 
  
  os\dwOSVersionInfoSize = SizeOf(OSVERSIONINFO) 
  
  If GetVersionEx_(os)
    
    If os\dwPlatformId = #VER_PLATFORM_WIN32_WINDOWS
      device = CreateFile_("\\.\SMARTVSD", #GENERIC_READ, #FILE_SHARE_READ, 0, #OPEN_EXISTING, 0, 0) 
    Else
      device = CreateFile_("\\.\PhysicalDrive" + Str(PhysicalDrive), #GENERIC_READ|#GENERIC_WRITE, #FILE_SHARE_READ|#FILE_SHARE_WRITE, 0, #OPEN_EXISTING, 0, 0) 
    EndIf
    
    If device <> #INVALID_HANDLE_VALUE
      DeviceIoControl_(device, #IOCTL_DISK_GET_DRIVE_GEOMETRY_EX, 0, 0, @disk, SizeOf(disk), @bytes, 0) 
      CloseHandle_(device) 
    EndIf 
    
  EndIf
  
  ProcedureReturn disk\Disksize

EndProcedure

Debug GetDiskSize(0)