Disc Information

Everything else that doesn't fall into one of the other PB categories.
AZJIO
Addict
Addict
Posts: 1360
Joined: Sun May 14, 2017 1:48 am

Disc Information

Post by AZJIO »

WM_DEVICECHANGE
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:")
User avatar
Kwai chang caine
Always Here
Always Here
Posts: 5353
Joined: Sun Nov 05, 2006 11:42 pm
Location: Lyon - France

Re: Disc Information

Post by Kwai chang caine »

Works nice here
Thanks for sharing 8)
ImageThe happiness is a road...
Not a destination
Post Reply