WinIoCtl [Windows]

Share your advanced PureBasic knowledge/code with the community.
User avatar
Dreamland Fantasy
Enthusiast
Enthusiast
Posts: 335
Joined: Fri Jun 11, 2004 9:35 pm
Location: Glasgow, UK
Contact:

WinIoCtl [Windows]

Post by Dreamland Fantasy »

Hi there,

While searching through the forums I found some examples of 'WinIoCtl.h' being adapted to PureBasic, but these only contained specific parts of it and not everything from the include file. I have adapted the file found here for PureBasic:

Code: Select all

; 'WinIoCtl.h' adapted for PureBasic by Francis G. Loch, 10th Feb 2016

Global DEVICE_TYPE.l

Enumeration FILE_DEVICE 1
  #FILE_DEVICE_BEEP
  #FILE_DEVICE_CD_ROM
  #FILE_DEVICE_CD_ROM_FILE_SYSTEM
  #FILE_DEVICE_CONTROLLER
  #FILE_DEVICE_DATALINK
  #FILE_DEVICE_DFS
  #FILE_DEVICE_DISK
  #FILE_DEVICE_DISK_FILE_SYSTEM
  #FILE_DEVICE_FILE_SYSTEM
  #FILE_DEVICE_INPORT_PORT
  #FILE_DEVICE_KEYBOARD
  #FILE_DEVICE_MAILSLOT
  #FILE_DEVICE_MIDI_IN
  #FILE_DEVICE_MIDI_OUT
  #FILE_DEVICE_MOUSE
  #FILE_DEVICE_MULTI_UNC_PROVIDER
  #FILE_DEVICE_NAMED_PIPE
  #FILE_DEVICE_NETWORK
  #FILE_DEVICE_NETWORK_BROWSER
  #FILE_DEVICE_NETWORK_FILE_SYSTEM
  #FILE_DEVICE_NULL
  #FILE_DEVICE_PARALLEL_PORT
  #FILE_DEVICE_PHYSICAL_NETCARD
  #FILE_DEVICE_PRINTER
  #FILE_DEVICE_SCANNER
  #FILE_DEVICE_SERIAL_MOUSE_PORT
  #FILE_DEVICE_SERIAL_PORT
  #FILE_DEVICE_SCREEN
  #FILE_DEVICE_SOUND
  #FILE_DEVICE_STREAMS
  #FILE_DEVICE_TAPE
  #FILE_DEVICE_TAPE_FILE_SYSTEM
  #FILE_DEVICE_TRANSPORT
  #FILE_DEVICE_UNKNOWN
  #FILE_DEVICE_VIDEO
  #FILE_DEVICE_VIRTUAL_DISK
  #FILE_DEVICE_WAVE_IN
  #FILE_DEVICE_WAVE_OUT
  #FILE_DEVICE_8042_PORT
  #FILE_DEVICE_NETWORK_REDIRECTOR
  #FILE_DEVICE_BATTERY
  #FILE_DEVICE_BUS_EXTENDER
  #FILE_DEVICE_MODEM
  #FILE_DEVICE_VDM
  #FILE_DEVICE_MASS_STORAGE
  #FILE_DEVICE_SMB
  #FILE_DEVICE_KS
  #FILE_DEVICE_CHANGER
  #FILE_DEVICE_SMARTCARD
  #FILE_DEVICE_ACPI
  #FILE_DEVICE_DVD
  #FILE_DEVICE_FULLSCREEN_VIDEO
  #FILE_DEVICE_DFS_FILE_SYSTEM
  #FILE_DEVICE_DFS_VOLUME
  #FILE_DEVICE_SERENUM
  #FILE_DEVICE_TERMSRV
  #FILE_DEVICE_KSEC
EndEnumeration

Enumeration PARTITION
  #PARTITION_ENTRY_UNUSED
  #PARTITION_FAT_12
  #PARTITION_XENIX_1
  #PARTITION_XENIX_2
  #PARTITION_FAT_16
  #PARTITION_EXTENDED
  #PARTITION_HUGE
  #PARTITION_IFS
  #PARTITION_PREP = $41
  #PARTITION_UNIX = $63
  #PARTITION_NTFT = 128
EndEnumeration

#VALID_NTFT = $C0

Enumeration METHOD
  #METHOD_BUFFERED
  #METHOD_IN_DIRECT
  #METHOD_OUT_DIRECT
  #METHOD_NEITHER
EndEnumeration

Enumeration SERIAL
  #SERIAL_LSRMST_ESCAPE
  #SERIAL_LSRMST_LSR_DATA
  #SERIAL_LSRMST_LSR_NODATA
  #SERIAL_LSRMST_MST
EndEnumeration

Enumeration FILE
  #FILE_ANY_ACCESS
  #FILE_READ_ACCESS
  #FILE_WRITE_ACCESS
EndEnumeration

Enumeration DISK
  #DISK_LOGGING_START
  #DISK_LOGGING_STOP
  #DISK_LOGGING_DUMP
  #DISK_BINNING
EndEnumeration

Global.w BAD_TRACK_NUMBER

Enumeration BIN_TYPES
  #RequestSize
  #RequestLocation
EndEnumeration

Structure BIN_RANGE Align #PB_Structure_AlignC
  StartValue.q
  Length.q
EndStructure

Structure BIN_COUNT Align #PB_Structure_AlignC
  BinRange.BIN_RANGE
  BinCount.l
EndStructure

Structure BIN_RESULTS Align #PB_Structure_AlignC
  NumberOfBins.l
  BinCounts.BIN_COUNT [1]
EndStructure

Enumeration MEDIA_TYPE
  #Unknown          ; Format is unknown
  #F5_1Pt2_512      ; A 5.25" floppy, with 1.2MB and 512 bytes/sector.
  #F3_1Pt44_512     ; A 3.5" floppy, with 1.44MB and 512 bytes/sector.
  #F3_2Pt88_512     ; A 3.5" floppy, with 2.88MB and 512 bytes/sector.
  #F3_20Pt8_512     ; A 3.5" floppy, with 20.8MB and 512 bytes/sector.
  #F3_720_512       ; A 3.5" floppy, with 720KB and 512 bytes/sector.
  #F5_360_512       ; A 5.25" floppy, with 360KB and 512 bytes/sector.
  #F5_320_512       ; A 5.25" floppy, with 320KB and 512 bytes/sector.
  #F5_320_1024      ; A 5.25" floppy, with 320KB and 1024 bytes/sector.
  #F5_180_512       ; A 5.25" floppy, with 180KB and 512 bytes/sector.
  #F5_160_512       ; A 5.25" floppy, with 160KB and 512 bytes/sector.
  #RemovableMedia   ; Removable media other than floppy.
  #FixedMedia       ; Fixed hard disk media.
  #F3_120M_512      ; A 3.5" floppy, with 120MB and 512 bytes/sector.
  #F3_640_512       ; A 3.5" floppy, with 640KB and 512 bytes/sector.
  #F5_640_512       ; A 5.25" floppy, with 640KB and 512 bytes/sector.
  #F5_720_512       ; A 5.25" floppy, with 720KB and 512 bytes/sector.
  #F3_1Pt2_512      ; A 3.5" floppy, with 1.2MB and 512 bytes/sector.
  #F3_1Pt23_1024    ; A 3.5" floppy, with 1.23MB and 1024 bytes/sector.
  #F5_1Pt23_1024    ; A 5.25" floppy, with 1.23MB and 1024 bytes/sector.
  #F3_128Mb_512     ; A 3.5" floppy, with 128MB and 512 bytes/sector.
  #F3_230Mb_512     ; A 3.5" floppy, with 230MB and 512 bytes/sector.
  #F8_256_128       ; An 8" floppy, with 256KB and 128 bytes/sector.
  #F3_200Mb_512     ; A 3.5" floppy, with 200MB and 512 bytes/sector. (HiFD).
  #F3_240M_512      ; A 3.5" floppy, with 240MB and 512 bytes/sector. (HiFD).
  #F3_32M_512       ; A 3.5" floppy, with 32MB and 512 bytes/sector.
EndEnumeration

Enumeration PARTITION_STYLE
  #PARTITION_STYLE_MBR
  #PARTITION_STYLE_GPT
  #PARTITION_STYLE_RAW
EndEnumeration

Structure DISK_GEOMETRY Align #PB_Structure_AlignC
  Cylinders.q
  MediaType.l
  TracksPerCylinder.l
  SectorsPerTrack.l
  BytesPerSector.l
EndStructure

Structure DISK_PERFORMANCE Align #PB_Structure_AlignC
  BytesRead.q
  BytesWritten.q
  ReadTime.q
  WriteTime.q
  ReadCount.l
  WriteCount.l
  QueueDepth.l
EndStructure
  
Structure DISK_RECORD Align #PB_Structure_AlignC
  ByteOffset.q
  StartTime.q
  EndTime.q
  *VirtualAddress
  NumberOfBytes.l
  DeviceNumber.b
  ReadRequest.b
EndStructure
  
Structure DISK_LOGGING Align #PB_Structure_AlignC
  Function.b
  *BufferAddress
  BufferSize.l
EndStructure
  
Structure FORMAT_PARAMETERS Align #PB_Structure_AlignC
  MediaType.l
  StartCylinderNumber.l
  EndCylinderNumber.l
  StartHeadNumber.l
  EndHeadNumber.l
EndStructure
  
Structure FORMAT_EX_PARAMETERS Align #PB_Structure_AlignC
  MediaType.l
  StartCylinderNumber.l
  EndCylinderNumber.l
  StartHeadNumber.l
  EndHeadNumber.l
  FormatGapLength.w
  SectorsPerTrack.w
  SectorNumber.w[1]
EndStructure
  
Structure HISTOGRAM_BUCKET Align #PB_Structure_AlignC
  Reads.l
  Writes.l
EndStructure
  
Structure DISK_HISTOGRAM Align #PB_Structure_AlignC
  DiskSize.q 
  Start.q 
  End.q 
  Average.q 
  AverageRead.q 
  AverageWrite.q 
  Granularity.l
  Size.l
  ReadCount.l
  WriteCount.l
  Histogram.HISTOGRAM_BUCKET 
EndStructure
  
Structure PARTITION_INFORMATION Align #PB_Structure_AlignC
  StartingOffset.q
  PartitionLength.q
  HiddenSectors.l
  PartitionNumber.l
  PartitionType.b
  BootIndicator.b
  RecognizedPartition.b
  RewritePartition.b
EndStructure
  
Structure DRIVE_LAYOUT_INFORMATION Align #PB_Structure_AlignC
  PartitionCount.l
  Signature.l
  PartitionEntry.PARTITION_INFORMATION[1]
EndStructure
  
Structure PERF_BIN Align #PB_Structure_AlignC
  NumberOfBins.l
  TypeOfBin.l
  BinsRanges.BIN_RANGE[1]
EndStructure
  
Structure PREVENT_MEDIA_REMOVAL Align #PB_Structure_AlignC
  PreventMediaRemoval.b
EndStructure
  
Structure REASSIGN_BLOCKS Align #PB_Structure_AlignC
  Reserved.w
  Count.w
  BlockNumber.l[1]
EndStructure
  
Structure SET_PARTITION_INFORMATION Align #PB_Structure_AlignC
  PartitionType.b
EndStructure
  
Structure VERIFY_INFORMATION Align #PB_Structure_AlignC
  StartingOffset.q
  Length.l
EndStructure

Structure CREATE_DISK_MBR Align #PB_Structure_AlignC
  Signature.l
EndStructure

Structure CREATE_DISK_GPT Align #PB_Structure_AlignC
  DiskId.GUID
  MaxPartitionCount.l
EndStructure

Structure CREATE_DISK Align #PB_Structure_AlignC
  PartitionStyle.l
  StructureUnion
    Mbr.CREATE_DISK_MBR
    Gpt.CREATE_DISK_GPT
  EndStructureUnion
EndStructure

Macro IsRecognizedPartition(t)
  (((t & #PARTITION_NTFT) & ((t & ~$C0) = #PARTITION_FAT_12)) |
   ((t & #PARTITION_NTFT) & ((t & ~$C0) = #PARTITION_FAT_16)) |
   ((t & #PARTITION_NTFT) & ((t & ~$C0) = #PARTITION_IFS   )) |
   ((t & #PARTITION_NTFT) & ((t & ~$C0) = #PARTITION_HUGE  )) |
   ((t &~#PARTITION_NTFT)               = #PARTITION_FAT_12 ) |
   ((t &~#PARTITION_NTFT)               = #PARTITION_FAT_16 ) |
   ((t &~#PARTITION_NTFT)               = #PARTITION_IFS    ) |
   ((t &~#PARTITION_NTFT)               = #PARTITION_HUGE   ))
EndMacro

#HIST_NO_OF_BUCKETS = 24
Define HISTOGRAM_BUCKET_SIZE = SizeOf(HISTOGRAM_BUCKET)
Define DISK_HISTOGRAM_SIZE = SizeOf(DISK_HISTOGRAM)

#IOCTL_STORAGE_BASE = #FILE_DEVICE_MASS_STORAGE
#IOCTL_STORAGE_CHECK_VERIFY       = $2D4800
#IOCTL_STORAGE_CHECK_VERIFY2      = $2D0800
#IOCTL_STORAGE_MEDIA_REMOVAL      = $2D4804
#IOCTL_STORAGE_EJECT_MEDIA        = $2D4808
#IOCTL_STORAGE_LOAD_MEDIA         = $2D480C
#IOCTL_STORAGE_LOAD_MEDIA2        = $2D080C
#IOCTL_STORAGE_RESERVE            = $2D4810
#IOCTL_STORAGE_RELEASE            = $2D4814
#IOCTL_STORAGE_FIND_NEW_DEVICES   = $2D4818
#IOCTL_STORAGE_EJECTION_CONTROL   = $2D0940
#IOCTL_STORAGE_MCN_CONTROL        = $2D0944
#IOCTL_STORAGE_GET_MEDIA_TYPES    = $2D0C00
#IOCTL_STORAGE_GET_MEDIA_TYPES_EX = $2D0C04
#IOCTL_STORAGE_RESET_BUS          = $2D5000
#IOCTL_STORAGE_RESET_DEVICE       = $2D5004
#IOCTL_STORAGE_GET_DEVICE_NUMBER  = $2D1080
#IOCTL_STORAGE_PREDICT_FAILURE    = $2D1100

#IOCTL_DISK_BASE = #FILE_DEVICE_DISK
#IOCTL_DISK_GET_DRIVE_GEOMETRY    = $70000
#IOCTL_DISK_GET_PARTITION_INFO    = $74004
#IOCTL_DISK_SET_PARTITION_INFO    = $7C008
#IOCTL_DISK_GET_DRIVE_LAYOUT      = $7400C
#IOCTL_DISK_SET_DRIVE_LAYOUT      = $7C010
#IOCTL_DISK_VERIFY                = $70014
#IOCTL_DISK_FORMAT_TRACKS         = $7C018
#IOCTL_DISK_REASSIGN_BLOCKS       = $7C01C
#IOCTL_DISK_PERFORMANCE           = $70020
#IOCTL_DISK_IS_WRITABLE           = $70024
#IOCTL_DISK_LOGGING               = $70028
#IOCTL_DISK_FORMAT_TRACKS_EX      = $7C02C
#IOCTL_DISK_HISTOGRAM_STRUCTURE   = $70030
#IOCTL_DISK_HISTOGRAM_DATA        = $70034
#IOCTL_DISK_HISTOGRAM_RESET       = $70038
#IOCTL_DISK_REQUEST_STRUCTURE     = $7003C
#IOCTL_DISK_REQUEST_DATA          = $70040
#IOCTL_DISK_CHECK_VERIFY          = $74800
#IOCTL_DISK_MEDIA_REMOVAL         = $74804
#IOCTL_DISK_EJECT_MEDIA           = $74808
#IOCTL_DISK_LOAD_MEDIA            = $7480C
#IOCTL_DISK_RESERVE               = $74810
#IOCTL_DISK_RELEASE               = $74814
#IOCTL_DISK_FIND_NEW_DEVICES      = $74818
#IOCTL_DISK_REMOVE_DEVICE         = $7481C
#IOCTL_DISK_GET_MEDIA_TYPES       = $70C00
#IOCTL_DISK_CREATE_DISK           = $7C058

#IOCTL_SERIAL_LSRMST_INSERT       = $1B007C

#FSCTL_LOCK_VOLUME                = $90018
#FSCTL_UNLOCK_VOLUME              = $9001C
#FSCTL_DISMOUNT_VOLUME            = $90020
#FSCTL_MOUNT_DBLS_VOLUME          = $90034
#FSCTL_GET_COMPRESSION            = $9003C
#FSCTL_SET_COMPRESSION            = $9C040
#FSCTL_READ_COMPRESSION           = $94047
#FSCTL_WRITE_COMPRESSION          = $9804B
#FSCTL_GET_REPARSE_POINT          = $900A8
#FSCTL_SET_REPARSE_POINT          = $980A4
#FSCTL_DELETE_REPARSE_POINT       = $980AC
And here is an example file to try it out:

Code: Select all

; 'WinIoCtl' PureBasic example
; Adapted by Francis G. Loch, 11th Feb 2016, from the C++ example given at
; https://msdn.microsoft.com/en-us/library/windows/desktop/aa363147(v=vs.85).aspx

; The code of interest is in the subroutine GetDriveGeometry. The 
; code in main shows how to interpret the results of the call.

EnableExplicit

XIncludeFile "winioctl.pbi"

Define Path$ = "\\.\C:"

Procedure GetDriveGeometry(Path$, *pdg.DISK_GEOMETRY)
  
  Protected.i hDevice = #INVALID_HANDLE_VALUE   ; handle to the drive to be examined
  Protected.a bResult = #False                  ; results flag
  Protected.l junk    = 0                       ; discard results
  
  hDevice = CreateFile_(Path$,                  ; drive to open
                        0,                      ; No access to drive
                        #FILE_SHARE_READ |      ; share mode
                        #FILE_SHARE_WRITE,
                        #Null,                  ; default security attributes
                        #OPEN_EXISTING,         ; disposition
                        0,                      ; file attributes
                        #Null)                  ; do not copy file attributes
  
  If (hDevice = #INVALID_HANDLE_VALUE)          ; cannot open the drive
    ProcedureReturn #False
  EndIf
  
  bResult = DeviceIoControl_(hDevice,                               ; device to be queried
                             #IOCTL_DISK_GET_DRIVE_GEOMETRY,        ; operation to perform
                             #Null, 0,                              ; no input buffer
                             *pdg, SizeOf(DISK_GEOMETRY),           ; output buffer
                             @junk,                                 ; # bytes returned
                             #Null)                                 ; synchronous I/O
  
  CloseHandle_(hDevice)
  
  ProcedureReturn bResult
   
EndProcedure

Define pdg.DISK_GEOMETRY    ; disk drive geometry structure
Define bResult.a = #False   ; generic results flag
Define DiskSize.q = 0       ; size of the drive, in bytes

bResult = GetDriveGeometry(Path$, @pdg)

OpenConsole("'WinIoCtl' PureBasic example")
If bResult
  PrintN("Drive path      = " + Path$)
  PrintN("Cylinders       = " + Str(pdg\Cylinders))
  PrintN("Tracks/cylinder = " + Str(pdg\TracksPerCylinder))
  PrintN("Sectors/track   = " + Str(pdg\SectorsPerTrack))
  PrintN("Bytes/sector    = " + Str(pdg\BytesPerSector))
  
  DiskSize = pdg\Cylinders * pdg\TracksPerCylinder * pdg\SectorsPerTrack * pdg\BytesPerSector
  PrintN("Disk size       = " + Str(DiskSize) + " (Bytes)")
  PrintN("                = " + Str(DiskSize / (1024 * 1024 * 1024)) + " (Gb)")
Else
  PrintN("GetDriveGeometry failed. Error code " + Str(GetLastError_()))
EndIf

PrintN(Chr(10) + "Press ENTER to exit")
Input()
Kind regards,

Francis
User avatar
Kwai chang caine
Always Here
Always Here
Posts: 5494
Joined: Sun Nov 05, 2006 11:42 pm
Location: Lyon - France

Re: WinIoCtl [Windows]

Post by Kwai chang caine »

Works well on XP PRO
Thanks for sharing 8)
ImageThe happiness is a road...
Not a destination
User avatar
Dreamland Fantasy
Enthusiast
Enthusiast
Posts: 335
Joined: Fri Jun 11, 2004 9:35 pm
Location: Glasgow, UK
Contact:

Re: WinIoCtl [Windows]

Post by Dreamland Fantasy »

You're welcome. :)

Kind regards,

Francis
Post Reply