https://www.purebasic.fr/english/viewto ... 22#p580922
ChkDskGui
https://www.purebasic.fr/english/viewtopic.php?t=75231
Disc Information
Code: Select all
EnableExplicit
Structure STORAGE_PROPERTY_QUERY
PropertyId.l
QueryType.l
AdditionalParameters.l
EndStructure
Structure STORAGE_DEVICE_DESCRIPTOR
Version.l
Size.l
DeviceType.b
DeviceTypeModifier.b
RemovableMedia.b
CommandQueueing.b
VendorIdOffset.l
ProductIdOffset.l
ProductRevisionOffset.l
SerialNumberOffset.l
BusType.w
RawPropertiesLength.l
RawDeviceProperties.b
Reserved.b[1024]
EndStructure
Procedure.s DriveGetName(DriveLetter$)
#IOCTL_STORAGE_QUERY_PROPERTY = $2D1400
Protected dwOutBytes, hDevice, p, Ret$
Protected udtQuery.STORAGE_PROPERTY_QUERY
Protected udtOut.STORAGE_DEVICE_DESCRIPTOR
hDevice = CreateFile_("\\.\" + DriveLetter$, 0, #FILE_SHARE_READ | #FILE_SHARE_WRITE, 0, #OPEN_EXISTING, #NUL, #NUL)
If hDevice <> #INVALID_HANDLE_VALUE
For p = 0 To 1023
udtOut\Reserved[p] = 0
Next p
If DeviceIoControl_(hDevice, #IOCTL_STORAGE_QUERY_PROPERTY, udtQuery, SizeOf(udtQuery), @udtOut, SizeOf(udtout), @dwOutBytes, 0)
If udtOut\VendorIdOffset
Ret$ + Trim(PeekS(udtOut + udtOut\VendorIdOffset, -1, #PB_Ascii)) + " "
EndIf
If udtOut\ProductIdOffset
Ret$ + Trim(PeekS(udtOut + udtOut\ProductIdOffset, -1, #PB_Ascii))
EndIf
EndIf
CloseHandle_(hDevice)
EndIf
ProcedureReturn Ret$
EndProcedure
; ————————————————————————————————
Procedure.s DriveGetNumber(DriveLetter$)
Protected DriveInfo.STORAGE_DEVICE_NUMBER, Nul , Ret$="?:?", hDevice
hDevice = CreateFile_("\\.\" + DriveLetter$, 0, 0, 0, #OPEN_EXISTING, #FILE_ATTRIBUTE_NORMAL, #NUL)
If hDevice <> #INVALID_HANDLE_VALUE
If DeviceIoControl_(hDevice,#IOCTL_STORAGE_GET_DEVICE_NUMBER, 0, 0, DriveInfo, SizeOf(STORAGE_DEVICE_NUMBER), @Nul, #NUL)
Ret$=Str(DriveInfo\DeviceNumber) + ":" + Str(DriveInfo\PartitionNumber)
EndIf
CloseHandle_(hDevice)
EndIf
ProcedureReturn Ret$
EndProcedure
; ————————————————————————————————
; MBR/GPT
; https://www.purebasic.fr/english/viewtopic.php?t=25663&p=220673
#PARTITION_STYLE_MBR = 0
#PARTITION_STYLE_GPT = 1
#PARTITION_STYLE_RAW = 2
#IOCTL_DISK_GET_DRIVE_LAYOUT_EX = $70050
Structure PARTITION_INFORMATION_GPT Align #PB_Structure_AlignC
Partitiontype.GUID
PartitionId.GUID
Attributes.q
Name.b[36]
EndStructure
Structure PARTITION_INFORMATION_MBR Align #PB_Structure_AlignC
PartitionType.b
BootIndicator.b
RecognizedPartition.b
HiddenSectors.l
EndStructure
Structure DRIVE_LAYOUT_INFORMATION_GPT Align #PB_Structure_AlignC
PartitionStyle.GUID
StartingUsableOffset.LARGE_INTEGER
UsableLength.LARGE_INTEGER
MaxPartitionCount.l
EndStructure
Structure DRIVE_LAYOUT_INFORMATION_MBR Align #PB_Structure_AlignC
DiskId.l
PartitionCount.l
EndStructure
Structure PARTITION_INFORMATION_EX Align #PB_Structure_AlignC
PartitionStyle.l
StartingOffset.LARGE_INTEGER
PartitionLength.LARGE_INTEGER
PartitionNumber.l
RewritePartition.b
StructureUnion
ppmbr.PARTITION_INFORMATION_MBR
ppgpt.PARTITION_INFORMATION_GPT
EndStructureUnion
EndStructure
Structure DRIVE_LAYOUT_INFORMATION_EX Align #PB_Structure_AlignC
PartitionStyle.l
PartitionCount.l
StructureUnion
pdmbr.DRIVE_LAYOUT_INFORMATION_MBR
pdgpt.DRIVE_LAYOUT_INFORMATION_GPT
EndStructureUnion
PartitionEntry.PARTITION_INFORMATION_EX[255]
EndStructure
; конец => константы и структуры MBR/GPT
;Получение номера диска и раздела, из буквы раздела
Procedure.s Get_MBR_GPT(NumDrive$)
Protected pdl.DRIVE_LAYOUT_INFORMATION_EX, Bytes.l, hDrive, res$ = "---"
hDrive = CreateFile_("\\.\PhysicalDrive" + NumDrive$, 0, #FILE_SHARE_READ | #FILE_SHARE_WRITE, 0, #OPEN_EXISTING, 0, 0)
; hDrive = CreateFile_("\\?\C:\", 0, #FILE_SHARE_READ | #FILE_SHARE_WRITE, 0, #OPEN_EXISTING, 0, 0) ; буква вместо номера
If hDrive <> #INVALID_HANDLE_VALUE
If DeviceIoControl_(hDrive, #IOCTL_DISK_GET_DRIVE_LAYOUT_EX, 0, 0, @pdl, SizeOf(pdl), @Bytes, 0)
Select pdl\PartitionStyle
Case #PARTITION_STYLE_MBR
res$="MBR"
Case #PARTITION_STYLE_GPT
res$="GPT"
Case #PARTITION_STYLE_RAW
res$="RAW"
EndSelect
EndIf
CloseHandle_(hDrive)
EndIf
ProcedureReturn res$
EndProcedure
; ————————————————————————————————
; https://usbtor.ru/viewtopic.php?p=76839#76839
; https://www.purebasic.fr/english/viewtopic.php?p=153623#p153623
; Reading RAW disk size
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
; #FILE_READ_DATA = 1
; #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_READ_DATA)
#IOCTL_DISK_GET_DRIVE_GEOMETRY_EX = $740A0
Declare.q GetDriveSize(Drive.s)
Procedure.q GetDriveSize(Drive.s)
Protected device.l, bytes.l, os.OSVERSIONINFO, disk.DISK_GEOMETRY_EX
os\dwOSVersionInfoSize = SizeOf(OSVERSIONINFO)
device = CreateFile_("\\.\" + Drive, #GENERIC_READ | #GENERIC_WRITE, #FILE_SHARE_READ | #FILE_SHARE_WRITE, 0, #OPEN_EXISTING, 0, 0)
If device <> #INVALID_HANDLE_VALUE
DeviceIoControl_(device, #IOCTL_DISK_GET_DRIVE_GEOMETRY_EX, 0, 0, @disk, SizeOf(disk), @bytes, 0)
CloseHandle_(device)
EndIf
ProcedureReturn disk\Disksize
EndProcedure
Procedure.s GetDriveInfo(Drive2$)
Protected.s Lfwrk, FileSystem, VolName, r = Chr(10)
Protected.q total_bytes
Lfwrk = Drive2$ + ":\"
FileSystem = Space(256)
VolName = Space(256)
If GetVolumeInformation_(@Lfwrk, @VolName, 255, 0, 0, 0, @FileSystem, 255)
Drive2$ + r + VolName + r + FileSystem
If (GetDiskFreeSpaceEx_(Lfwrk, 0, @total_bytes, 0))
; Drive2$ + " "+ Str(total_bytes/1048576)+ " Мб"
Drive2$ + r + StrF(ValF(StrF(total_bytes / 1024)) / 1048576, 3)
Else
Drive2$ + r + "---"
EndIf
Else
Drive2$ + r + "---" + r + "---"
If OSVersion() < #PB_OS_Windows_Vista
total_bytes = GetDriveSize(Left(Drive2$, 2))
If total_bytes
Drive2$ + r + StrF(ValF(StrF(total_bytes / 1024)) / 1048576, 3)
Else
Drive2$ + r + "---"
EndIf
Else
Drive2$ + r + "---"
EndIf
EndIf
ProcedureReturn Drive2$
EndProcedure
; ————————————————————————————————
Procedure GetDrives(List Drive.s())
Protected i, drives_avail
drives_avail = GetLogicalDrives_()
For i = 0 To 25
If drives_avail >> i & 1
If AddElement(Drive())
Drive() = Chr(i + 65)
EndIf
EndIf
Next
EndProcedure
; ————————————————————————————————
Procedure.s GetDriveType(Drive2$)
Protected type.l
type = GetDriveType_(Drive2$ + ":\")
Select type
Case #DRIVE_REMOVABLE
Drive2$ = "Rem "
Case #DRIVE_FIXED
Drive2$ = "Fixed"
Case #DRIVE_REMOTE, #DRIVE_CDROM, #DRIVE_RAMDISK
Drive2$ = "-"
Case #DRIVE_NO_ROOT_DIR
Drive2$ = "No_Root_Dir"
Case #DRIVE_UNKNOWN
Drive2$ = "Unknown"
Default
Drive2$ = "---"
EndSelect
ProcedureReturn Drive2$
EndProcedure
; ————————————————————————————————
Procedure IsVirtualDisk(DriveLetter$)
Protected lpTargetPath$ = Space(#MAX_PATH)
QueryDosDevice_(@DriveLetter$, @lpTargetPath$, #MAX_PATH)
If Left(lpTargetPath$, 7) <> "\Device" Or (DriveLetter$ = "X:" And Left(lpTargetPath$, 15) = "\Device\Ramdisk")
ProcedureReturn 1
Else
ProcedureReturn 0
EndIf
EndProcedure
; ————————————————————————————————
; Example
Global NewList Drive.s()
GetDrives(Drive())
ForEach Drive()
Debug Drive()
Next
Debug #TAB$
Debug "Virtual:" + #TAB$ + IsVirtualDisk("C:")
Debug "Type:" + #TAB$ + GetDriveType("C")
Debug #TAB$
Debug "Info:"
Debug GetDriveInfo("C")
Debug #TAB$
Debug "MBR_GPT_RAW:" + #TAB$ + Get_MBR_GPT("0")
Debug "Number:" + #TAB$ + DriveGetNumber("C:")
Debug "Name:" + #TAB$ + DriveGetName("C:")