Get partition letter?

Just starting out? Need help? Post your questions and find answers here.
User avatar
doctorized
Addict
Addict
Posts: 854
Joined: Fri Mar 27, 2009 9:41 am
Location: Athens, Greece

Get partition letter?

Post by doctorized »

I have a code that retrieves info from hard drives. (http://purebasic.fr/english/viewtopic.p ... &start=105)
I want to get the letter of every partition, if there is one. A google search revealed that it is possible using WMI.
Is there any way to do it without WMI? GetVolumeInformation_() cannot help as I don't have the "X:" to give it as parameter. This is what I look for.
RASHAD
PureBasic Expert
PureBasic Expert
Posts: 4622
Joined: Sun Apr 12, 2009 6:27 am

Re: Get partition letter?

Post by RASHAD »

I hope it is as per your request

Code: Select all

mask = GetLogicalDrives_()
For i = 0 To 31 
  If mask  & (1 << i  )
      Drive$ = Chr(65+i)+":\"
      Result = GetDriveType_(@Drive$)
      If Result = 3
          Debug Drive$
      EndIf
  EndIf
Next
Egypt my love
User avatar
TI-994A
Addict
Addict
Posts: 2512
Joined: Sat Feb 19, 2011 3:47 am
Location: Singapore
Contact:

Re: Get partition letter?

Post by TI-994A »

doctorized wrote:I want to get the letter of every partition...
Hi doctorized. Perhaps this might help; it demonstrates the use of the Windows API functions GetLogicalDriveStrings() and GetDriveType():

Code: Select all

bufferLen = 255
driveList.s = Space(bufferLen)
GetLogicalDriveStrings_(bufferLen, driveList)

While PeekS(@driveList + nextDrive, 4)
  driveLetter.s = PeekS(@driveList + nextDrive, 4)
  Restore driveDescription
  For readType = 0 To GetDriveType_(driveLetter)
    Read.s drvType.s
  Next
  Debug "Drive " + driveLetter + "  (" + drvType +" drive)"
  nextDrive + 4
Wend

DataSection
  driveDescription:
  Data.s "Unknown", "No Root", "Removable", "Fixed", "Remote", "CD-Rom", "RAM Disk"
EndDataSection
Texas Instruments TI-99/4A Home Computer: the first home computer with a 16bit processor, crammed into an 8bit architecture. Great hardware - Poor design - Wonderful BASIC engine. And it could talk too! Please visit my YouTube Channel :D
User avatar
doctorized
Addict
Addict
Posts: 854
Joined: Fri Mar 27, 2009 9:41 am
Location: Athens, Greece

Re: Get partition letter?

Post by doctorized »

This is the code I have:

Code: Select all

Structure PARTITION_INFORMATION
    StartingOffset.q
    PartitionLength.q
    HiddenSectors.l
    PartitionNumber.l
    PartitionType.b
    BootIndicator.b
    RecognizedPartition.b
    RewritePartition.b
    dummy.l
EndStructure

Structure DRIVE_LAYOUT_INFORMATION
   PartitionCount.l
   Signature.l
   PartitionEntry.PARTITION_INFORMATION[50]
EndStructure
   
Procedure.s GetPartitionType(type.b)
Select type
   Case 0
      ProcedureReturn "Unused"
   Case 1
      ProcedureReturn "12-bit FAT"
   Case 2, 3
      ProcedureReturn "Xenix"
   Case 4
      ProcedureReturn "16-bit FAT"
   Case 5
      ProcedureReturn "Extended"
   Case 6
      ProcedureReturn "Huge partition MS-DOS V4"
   Case 7
      ProcedureReturn "Installable File System (NTFS/HPFS/FAT64)"
   Case 8
      ProcedureReturn "OS/2 (v1.0-1.3 only)/AIX boot partition/Commodore DOS/SplitDrive/DELL partition spanning multiple drives/QNX 1.x and 2.x (qny)"
   Case 9
      ProcedureReturn "AIX data partition/Coherent filesystem/QNX 1.x and 2.x (qnz)"
   Case $A
      ProcedureReturn "OS/2 Boot Manager/OPUS/Coherent swap"
   Case $B
      ProcedureReturn "FAT32"
   Case $C
      ProcedureReturn "FAT32 using extended int13 services"
   Case $E
      ProcedureReturn "Win95 partition using extended int13 services"
   Case $F
      ProcedureReturn "Extended using extended int13 services"
   Case $41
      ProcedureReturn "PowerPC Reference Platform (PReP) Boot Partition"
   Case $42
      ProcedureReturn "Logical Disk Manager partition"
   Case $63
      ProcedureReturn "Unix"
   Case $C0
      ProcedureReturn "NTFT uses high order bits"
   Case $80
      ProcedureReturn "NTFT"
EndSelect
EndProcedure

Procedure.s SpaceDivider(space.q)
tm.s:mt.d=space: GroupDemicals.s = ","
If mt>1000: mt / 1024:tm = " KB":EndIf
If mt>1000: mt / 1024:tm = " MB":EndIf
If mt>1000: mt / 1024:tm = " GB":EndIf
If mt>1000: mt / 1024:tm = " TB":EndIf
ProcedureReturn ReplaceString(StrD(mt,3), ".", GroupDemicals) + tm
EndProcedure

IOCTL_DISK_GET_DRIVE_LAYOUT.l = 475148
aa.DRIVE_LAYOUT_INFORMATION
BytesRet.l:tmp.l
For ii=0 To 49
   BytesRet = 0: tmp = 0
   hdh.l = CreateFile_("\\.\PhysicalDrive" + Str(ii),#GENERIC_READ | #GENERIC_WRITE, #FILE_SHARE_READ | #FILE_SHARE_WRITE,0, #OPEN_EXISTING, 0, 0)
   DeviceIoControl_(hdh,IOCTL_DISK_GET_DRIVE_LAYOUT, #Null,0,@aa, SizeOf(DRIVE_LAYOUT_INFORMATION), @BytesRet,0)
   
   If BytesRet > 0
   	Debug "disk #" + Str(ii)
   	;Debug "Signature" + Str(aa\Signature)
      Debug "==============="
      For i=0 To aa\PartitionCount-1
      	;If aa\PartitionEntry[i]\RecognizedPartition = 1
      	If aa\PartitionEntry[i]\PartitionNumber > 0 And aa\PartitionEntry[i]\StartingOffset > 0
          Debug "Partition #" + Str(aa\PartitionEntry[i]\PartitionNumber) + "  :  " + GetPartitionType(aa\PartitionEntry[i]\PartitionType) + " , length  =  " + Str(aa\PartitionEntry[i]\PartitionLength) + " bytes (" + SpaceDivider(aa\PartitionEntry[i]\PartitionLength) + ")"
          ;Debug "Starting Offset = " + Str(aa\PartitionEntry[i]\StartingOffset)
		    ;Debug "Partition Length = " + Str(aa\PartitionEntry[i]\PartitionLength)
		    ;Debug "Hidden Sectors = " + Str(aa\PartitionEntry[i]\HiddenSectors)
		    ;Debug "Partition Number = " + Str(aa\PartitionEntry[i]\PartitionNumber)
		    ;Debug "Partition Type = " + Str(aa\PartitionEntry[i]\PartitionType)
		    ;Debug "Boot Indicator = " + Str(aa\PartitionEntry[i]\BootIndicator)
		    ;Debug "Recognized Partition = " + Str(aa\PartitionEntry[i]\RecognizedPartition)
		    ;Debug "Rewrite Partition = " + Str(aa\PartitionEntry[i]\RewritePartition)
		    ;Debug "dummy = " + Str(aa\PartitionEntry[i]\dummy)
		    ;Debug "================"
         EndIf
      Next
      Debug ""
   EndIf
Next
And this is what I get:
disk #0
===============
Partition #1 : Installable File System (NTFS/HPFS/FAT64) , length = 104857600 bytes (100,000 MB)
Partition #2 : Installable File System (NTFS/HPFS/FAT64) , length = 127928369152 bytes (119,143 GB)

disk #1
===============
Partition #1 : Installable File System (NTFS/HPFS/FAT64) , length = 128848978944 bytes (120,000 GB)
Partition #2 : Installable File System (NTFS/HPFS/FAT64) , length = 128849011200 bytes (120,000 GB)
Partition #3 : Installable File System (NTFS/HPFS/FAT64) , length = 128849011200 bytes (120,000 GB)
Partition #4 : Installable File System (NTFS/HPFS/FAT64) , length = 113558215680 bytes (105,759 GB)
All I want is to add the drive letter of each partition in the end, or at least to be able to get the letters of the partitions of one disk without telling which letter goes to each partition.
RASHAD
PureBasic Expert
PureBasic Expert
Posts: 4622
Joined: Sun Apr 12, 2009 6:27 am

Re: Get partition letter?

Post by RASHAD »

Hi
Adapt it for your needs

Code: Select all

Global Drive$,TotalMB.q,FreeMB.q,Oldoffset.q
Global Dim FreeBytesAvailable.q(0),Dim TotalBytes.q(0),Dim TotalFreeBytes.q(0)

Structure PARTITION_INFORMATION
    StartingOffset.q
    PartitionLength.q
    HiddenSectors.l
    PartitionNumber.l
    PartitionType.b
    BootIndicator.b
    RecognizedPartition.b
    RewritePartition.b
    dummy.l
EndStructure

Structure DRIVE_LAYOUT_INFORMATION
   PartitionCount.l
   Signature.l
   PartitionEntry.PARTITION_INFORMATION[50]
EndStructure

Procedure GetDiskFreeSpace(drive$)
SetErrorMode_(#SEM_FAILCRITICALERRORS)
GetDiskFreeSpaceEx_(@drive$, FreeBytesAvailable(), TotalBytes(), TotalFreeBytes())
SetErrorMode_(0)
TotalMB = TotalBytes(0) + 4096
EndProcedure
   
Procedure.s GetPartitionType(type.b)
Select type
   Case 0
      ProcedureReturn "Unused"
   Case 1
      ProcedureReturn "12-bit FAT"
   Case 2, 3
      ProcedureReturn "Xenix"
   Case 4
      ProcedureReturn "16-bit FAT"
   Case 5
      ProcedureReturn "Extended"
   Case 6
      ProcedureReturn "Huge partition MS-DOS V4"
   Case 7
      ProcedureReturn "Installable File System (NTFS/HPFS/FAT64)"
   Case 8
      ProcedureReturn "OS/2 (v1.0-1.3 only)/AIX boot partition/Commodore DOS/SplitDrive/DELL partition spanning multiple drives/QNX 1.x and 2.x (qny)"
   Case 9
      ProcedureReturn "AIX data partition/Coherent filesystem/QNX 1.x and 2.x (qnz)"
   Case $A
      ProcedureReturn "OS/2 Boot Manager/OPUS/Coherent swap"
   Case $B
      ProcedureReturn "FAT32"
   Case $C
      ProcedureReturn "FAT32 using extended int13 services"
   Case $E
      ProcedureReturn "Win95 partition using extended int13 services"
   Case $F
      ProcedureReturn "Extended using extended int13 services"
   Case $41
      ProcedureReturn "PowerPC Reference Platform (PReP) Boot Partition"
   Case $42
      ProcedureReturn "Logical Disk Manager partition"
   Case $63
      ProcedureReturn "Unix"
   Case $C0
      ProcedureReturn "NTFT uses high order bits"
   Case $80
      ProcedureReturn "NTFT"
EndSelect
EndProcedure

Procedure.s SpaceDivider(space.q)
tm.s:mt.d=space: GroupDemicals.s = ","
If mt>1000: mt / 1024:tm = " KB":EndIf
If mt>1000: mt / 1024:tm = " MB":EndIf
If mt>1000: mt / 1024:tm = " GB":EndIf
If mt>1000: mt / 1024:tm = " TB":EndIf
ProcedureReturn ReplaceString(StrD(mt,3), ".", GroupDemicals) + tm
EndProcedure

IOCTL_DISK_GET_DRIVE_LAYOUT.l = 475148
aa.DRIVE_LAYOUT_INFORMATION
BytesRet.l:tmp.l
For ii=0 To 49
    BytesRet = 0: tmp = 0
   hdh.l = CreateFile_("\\.\PhysicalDrive" + Str(ii),#GENERIC_READ | #GENERIC_WRITE, #FILE_SHARE_READ | #FILE_SHARE_WRITE,0, #OPEN_EXISTING, 0, 0)
   DeviceIoControl_(hdh,IOCTL_DISK_GET_DRIVE_LAYOUT, #Null,0,@aa, SizeOf(DRIVE_LAYOUT_INFORMATION), @BytesRet,0)
   
   If BytesRet > 0
      Debug "disk #" + Str(ii)
      ;Debug "Signature" + Str(aa\Signature)
      Debug "==============="
      For i=0 To aa\PartitionCount-1 
         ;If aa\PartitionEntry[i]\RecognizedPartition = 1
         If aa\PartitionEntry[i]\PartitionNumber > 0 And aa\PartitionEntry[i]\StartingOffset > 0         
          mask = GetLogicalDrives_()
          For HDSpace = 0 To 31
            If mask  & (1 << HDSpace )
                Drive$ = Chr(65+HDSpace)+":\"
                Result = GetDriveType_(@Drive$)
                If Result = 3
                    GetDiskFreeSpace(Drive$)
                    If TotalMB = aa\PartitionEntry[i]\PartitionLength And aa\PartitionEntry[i]\StartingOffset <> Oldoffset
                        DriveLabel$ = Drive$
                    EndIf
                EndIf
            EndIf
          Next
          If  aa\PartitionEntry[i]\StartingOffset  <> Oldoffset
              Oldoffset = aa\PartitionEntry[i]\StartingOffset 
          EndIf  
   
          Debug DriveLabel$ + "   " + GetPartitionType(aa\PartitionEntry[i]\PartitionType) + " , length  =  " + Str(aa\PartitionEntry[i]\PartitionLength) + " bytes (" + SpaceDivider(aa\PartitionEntry[i]\PartitionLength) + ")"
;           Debug "Starting Offset = " + Str(aa\PartitionEntry[i]\StartingOffset)
;           Debug "Partition Length = " + Str(aa\PartitionEntry[i]\PartitionLength)
;           Debug "Hidden Sectors = " + Str(aa\PartitionEntry[i]\HiddenSectors)
;           Debug "Partition Number = " + Str(aa\PartitionEntry[i]\PartitionNumber)
;           Debug "Partition Type = " + Str(aa\PartitionEntry[i]\PartitionType)
;           Debug "Boot Indicator = " + Str(aa\PartitionEntry[i]\BootIndicator)
;           Debug "Recognized Partition = " + Str(aa\PartitionEntry[i]\RecognizedPartition)
;           Debug "Rewrite Partition = " + Str(aa\PartitionEntry[i]\RewritePartition)
;           Debug "dummy = " + Str(aa\PartitionEntry[i]\dummy)
          Debug "================"
         EndIf
      Next
      Debug ""
   EndIf
Next
Edit :Code modified
Edit 2:Modified again
Last edited by RASHAD on Mon Sep 29, 2014 8:01 pm, edited 2 times in total.
Egypt my love
juror
Enthusiast
Enthusiast
Posts: 228
Joined: Mon Jul 09, 2007 4:47 pm
Location: Courthouse

Re: Get partition letter?

Post by juror »

When I run this code on my system which has 6 fixed drives, I only get info on the 2 which are ssd. Is this correct?

(The other 4 are all 3TB or greater).

And it doesn't work at all on PB5.22? Or is my system hosed?
User avatar
doctorized
Addict
Addict
Posts: 854
Joined: Fri Mar 27, 2009 9:41 am
Location: Athens, Greece

Re: Get partition letter?

Post by doctorized »

RASHAD wrote:Hi
Adapt it for your needs

Code: Select all

....
I tried your code and I get this:
disk #0
===============
Installable File System (NTFS/HPFS/FAT64) , length = 104857600 bytes (100,000 MB)
C:\ Installable File System (NTFS/HPFS/FAT64) , length = 127928369152 bytes (119,143 GB)

disk #1
===============
C:\ Installable File System (NTFS/HPFS/FAT64) , length = 128848978944 bytes (120,000 GB)
C:\ Installable File System (NTFS/HPFS/FAT64) , length = 128849011200 bytes (120,000 GB)
C:\ Installable File System (NTFS/HPFS/FAT64) , length = 128849011200 bytes (120,000 GB)
C:\ Installable File System (NTFS/HPFS/FAT64) , length = 113558215680 bytes (105,759 GB)
juror wrote:When I run this code on my system which has 6 fixed drives, I only get info on the 2 which are ssd. Is this correct?
What are these drives? Internal or external? Give any info available.
RASHAD
PureBasic Expert
PureBasic Expert
Posts: 4622
Joined: Sun Apr 12, 2009 6:27 am

Re: Get partition letter?

Post by RASHAD »

- Previous post just updated check
- @doctorized
I think you should use
PARTITION_INFORMATION_EX
PARTITION_INFORMATION_GPT
PARTITION_INFORMATION_MBR
To handle the new Hard disks over 2TB

Run the next snippet and confirm if it report all your system Partitions Label

Code: Select all

mask = GetLogicalDrives_()
For i = 0 To 31 
  If mask  & (1 << i  )
      Drive$ = Chr(65+i)+":\"
      Result = GetDriveType_(@Drive$)
      If Result = 3
          Debug Drive$
      EndIf
  EndIf
Next

Edit :Previous Post modified again
Last edited by RASHAD on Mon Sep 29, 2014 8:02 pm, edited 1 time in total.
Egypt my love
User avatar
doctorized
Addict
Addict
Posts: 854
Joined: Fri Mar 27, 2009 9:41 am
Location: Athens, Greece

Re: Get partition letter?

Post by doctorized »

RASHAD wrote:- Previous post just updated check
- @doctorized
I think you should use
PARTITION_INFORMATION_EX
PARTITION_INFORMATION_GPT
PARTITION_INFORMATION_MBR
To handle the new Hard disks over 2TB

Run the next snippet and confirm if it report all your system Partitions Label

Code: Select all

mask = GetLogicalDrives_()
For i = 0 To 31 
  If mask  & (1 << i  )
      Drive$ = Chr(65+i)+":\"
      Result = GetDriveType_(@Drive$)
      If Result = 3
          Debug Drive$
      EndIf
  EndIf
Next

Yes, it returns correct data:
C:\
D:\
E:\
F:\
G:\
TotalMB seems to be the problem. I did a small change:

Code: Select all

If Result = 3
	GetDiskFreeSpace(Drive$)
	Debug TotalMB
	Debug aa\PartitionEntry[i]\PartitionLength
	Debug aa\PartitionEntry[i]\StartingOffset
	Debug Oldoffset
	Debug "=========="
	If TotalMB = aa\PartitionEntry[i]\PartitionLength And aa\PartitionEntry[i]\StartingOffset <> Oldoffset
		DriveLabel$ = Drive$
		Break
	EndIf
EndIf
and I get these:
disk #0
===============
TotalMB = 127928369152
PartitionLength = 104857600
StartingOffset = 1048576
Oldoffset = 0
==========
TotalMB = 128848982016
PartitionLength = 104857600
StartingOffset = 1048576
Oldoffset = 0
==========
TotalMB = 128849014784
PartitionLength = 104857600
StartingOffset = 1048576
Oldoffset = 0
==========
TotalMB = 128849014784
PartitionLength = 104857600
StartingOffset = 1048576
Oldoffset = 0
==========
TotalMB = 113558216704
PartitionLength = 104857600
StartingOffset = 1048576
Oldoffset = 0
==========
Installable File System (NTFS/HPFS/FAT64) , length = 104857600 bytes (100,000 MB)
================
TotalMB = 127928369152
PartitionLength = 127928369152
StartingOffset = 105906176
Oldoffset = 1048576
==========
C:\ Installable File System (NTFS/HPFS/FAT64) , length = 127928369152 bytes (119,143 GB)
================

disk #1
===============
TotalMB = 127928369152
PartitionLength = 128848978944
StartingOffset = 32256
Oldoffset = 105906176
==========
TotalMB = 128848982016
PartitionLength = 128848978944
StartingOffset = 32256
Oldoffset = 105906176
==========
TotalMB = 128849014784
PartitionLength = 128848978944
StartingOffset = 32256
Oldoffset = 105906176
==========
TotalMB = 128849014784
PartitionLength = 128848978944
StartingOffset = 32256
Oldoffset = 105906176
==========
TotalMB = 113558216704
PartitionLength = 128848978944
StartingOffset = 32256
Oldoffset = 105906176
==========
C:\ Installable File System (NTFS/HPFS/FAT64) , length = 128848978944 bytes (120,000 GB)
================
TotalMB = 127928369152
PartitionLength = 128849011200
StartingOffset = 128849011200
Oldoffset = 32256
==========
TotalMB = 128848982016
PartitionLength = 128849011200
StartingOffset = 128849011200
Oldoffset = 32256
==========
TotalMB = 128849014784
PartitionLength = 128849011200
StartingOffset = 128849011200
Oldoffset = 32256
==========
TotalMB = 128849014784
PartitionLength = 128849011200
StartingOffset = 128849011200
Oldoffset = 32256
==========
TotalMB = 113558216704
PartitionLength = 128849011200
StartingOffset = 128849011200
Oldoffset = 32256
==========
C:\ Installable File System (NTFS/HPFS/FAT64) , length = 128849011200 bytes (120,000 GB)
================
TotalMB = 127928369152
PartitionLength = 128849011200
StartingOffset = 257698022400
Oldoffset = 128849011200
==========
TotalMB = 128848982016
PartitionLength = 128849011200
StartingOffset = 257698022400
Oldoffset = 128849011200
==========
TotalMB = 128849014784
PartitionLength = 128849011200
StartingOffset = 257698022400
Oldoffset = 128849011200
==========
TotalMB = 128849014784
PartitionLength = 128849011200
StartingOffset = 257698022400
Oldoffset = 128849011200
==========
TotalMB = 113558216704
PartitionLength = 128849011200
StartingOffset = 257698022400
Oldoffset = 128849011200
==========
C:\ Installable File System (NTFS/HPFS/FAT64) , length = 128849011200 bytes (120,000 GB)
================
TotalMB = 127928369152
PartitionLength = 113558215680
StartingOffset = 386547033600
Oldoffset = 257698022400
==========
TotalMB = 128848982016
PartitionLength = 113558215680
StartingOffset = 386547033600
Oldoffset = 257698022400
==========
TotalMB = 128849014784
PartitionLength = 113558215680
StartingOffset = 386547033600
Oldoffset = 257698022400
==========
TotalMB = 128849014784
PartitionLength = 113558215680
StartingOffset = 386547033600
Oldoffset = 257698022400
==========
TotalMB = 113558216704
PartitionLength = 113558215680
StartingOffset = 386547033600
Oldoffset = 257698022400
==========
C:\ Installable File System (NTFS/HPFS/FAT64) , length = 113558215680 bytes (105,759 GB)
================
In some case numbers seem to be very close but not the same. Maybe "+ 4096" in GetDiskFreeSpace() is the problem.
RASHAD
PureBasic Expert
PureBasic Expert
Posts: 4622
Joined: Sun Apr 12, 2009 6:27 am

Re: Get partition letter?

Post by RASHAD »

:mrgreen:
Sorry friend
I did a modification while you was posting
Try again sorry
Egypt my love
User avatar
doctorized
Addict
Addict
Posts: 854
Joined: Fri Mar 27, 2009 9:41 am
Location: Athens, Greece

Re: Get partition letter?

Post by doctorized »

RASHAD wrote::mrgreen:
Sorry friend
I did a modification while you was posting
Try again sorry
No need to apology. I tried it and I get the same.
disk #0
===============
Installable File System (NTFS/HPFS/FAT64) , length = 104857600 bytes (100,000 MB)
================
C:\ Installable File System (NTFS/HPFS/FAT64) , length = 127928369152 bytes (119,143 GB)
================

disk #1
===============
C:\ Installable File System (NTFS/HPFS/FAT64) , length = 128848978944 bytes (120,000 GB)
================
C:\ Installable File System (NTFS/HPFS/FAT64) , length = 128849011200 bytes (120,000 GB)
================
C:\ Installable File System (NTFS/HPFS/FAT64) , length = 128849011200 bytes (120,000 GB)
================
C:\ Installable File System (NTFS/HPFS/FAT64) , length = 113558215680 bytes (105,759 GB)
================
RASHAD
PureBasic Expert
PureBasic Expert
Posts: 4622
Joined: Sun Apr 12, 2009 6:27 am

Re: Get partition letter?

Post by RASHAD »

Can you provide me with
1- TotalMB for each partition
2- aa\PartitionEntry\PartitionLength for each partition
Egypt my love
User avatar
doctorized
Addict
Addict
Posts: 854
Joined: Fri Mar 27, 2009 9:41 am
Location: Athens, Greece

Re: Get partition letter?

Post by doctorized »

RASHAD wrote:Can you provide me with
1- TotalMB for each partition
2- aa\PartitionEntry\PartitionLength for each partition

I did it in my pre-last post, isn't it what you need?
RASHAD
PureBasic Expert
PureBasic Expert
Posts: 4622
Joined: Sun Apr 12, 2009 6:27 am

Re: Get partition letter?

Post by RASHAD »

I guess that the difference in the partition size is due to the format type
I mean :
1- The Sectors per Cluster
2- The no. of Bytes per Sector
So I changed the code to be fixable
You can play with Procedure GetDiskFreeSpace(drive$)
Plus 1 cluster or Minus one cluster (Maybe.. :) )
Good luck

Code: Select all

Global Drive$,TotalPlus.q,TotalMinus.q
Global Dim sectors_per_cluster.q(0),Dim bytes_per_sector.q(0),Dim  number_of_free_clusters.q(0),Dim  total_number_of_clusters .q(0)

Structure PARTITION_INFORMATION
    StartingOffset.q
    PartitionLength.q
    HiddenSectors.l
    PartitionNumber.l
    PartitionType.b
    BootIndicator.b
    RecognizedPartition.b
    RewritePartition.b
    dummy.l
EndStructure

Structure DRIVE_LAYOUT_INFORMATION
   PartitionCount.l
   Signature.l
   PartitionEntry.PARTITION_INFORMATION[50]
EndStructure

Procedure GetDiskFreeSpace(drive$)
    SetErrorMode_(#SEM_FAILCRITICALERRORS)
    GetDiskFreeSpace_(@drive$, sectors_per_cluster(), bytes_per_sector(), number_of_free_clusters(),total_number_of_clusters())
    SetErrorMode_(0)
    TotalPlus = (total_number_of_clusters(0)+1)*sectors_per_cluster(0)*bytes_per_sector(0)
    TotalMinus = (total_number_of_clusters(0)-1)*sectors_per_cluster(0)*bytes_per_sector(0)
EndProcedure

   
Procedure.s GetPartitionType(type.b)
Select type
   Case 0
      ProcedureReturn "Unused"
   Case 1
      ProcedureReturn "12-bit FAT"
   Case 2, 3
      ProcedureReturn "Xenix"
   Case 4
      ProcedureReturn "16-bit FAT"
   Case 5
      ProcedureReturn "Extended"
   Case 6
      ProcedureReturn "Huge partition MS-DOS V4"
   Case 7
      ProcedureReturn "Installable File System (NTFS/HPFS/FAT64)"
   Case 8
      ProcedureReturn "OS/2 (v1.0-1.3 only)/AIX boot partition/Commodore DOS/SplitDrive/DELL partition spanning multiple drives/QNX 1.x and 2.x (qny)"
   Case 9
      ProcedureReturn "AIX data partition/Coherent filesystem/QNX 1.x and 2.x (qnz)"
   Case $A
      ProcedureReturn "OS/2 Boot Manager/OPUS/Coherent swap"
   Case $B
      ProcedureReturn "FAT32"
   Case $C
      ProcedureReturn "FAT32 using extended int13 services"
   Case $E
      ProcedureReturn "Win95 partition using extended int13 services"
   Case $F
      ProcedureReturn "Extended using extended int13 services"
   Case $41
      ProcedureReturn "PowerPC Reference Platform (PReP) Boot Partition"
   Case $42
      ProcedureReturn "Logical Disk Manager partition"
   Case $63
      ProcedureReturn "Unix"
   Case $C0
      ProcedureReturn "NTFT uses high order bits"
   Case $80
      ProcedureReturn "NTFT"
EndSelect
EndProcedure

Procedure.s SpaceDivider(space.q)
tm.s:mt.d=space: GroupDemicals.s = ","
If mt>1000: mt / 1024:tm = " KB":EndIf
If mt>1000: mt / 1024:tm = " MB":EndIf
If mt>1000: mt / 1024:tm = " GB":EndIf
If mt>1000: mt / 1024:tm = " TB":EndIf
ProcedureReturn ReplaceString(StrD(mt,3), ".", GroupDemicals) + tm
EndProcedure

IOCTL_DISK_GET_DRIVE_LAYOUT.l = 475148
aa.DRIVE_LAYOUT_INFORMATION
BytesRet.l:tmp.l
For ii=0 To 49
    BytesRet = 0: tmp = 0
   hdh.l = CreateFile_("\\.\PhysicalDrive" + Str(ii),#GENERIC_READ | #GENERIC_WRITE, #FILE_SHARE_READ | #FILE_SHARE_WRITE,0, #OPEN_EXISTING, 0, 0)
   Result = DeviceIoControl_(hdh,IOCTL_DISK_GET_DRIVE_LAYOUT, #Null,0,@aa, SizeOf(DRIVE_LAYOUT_INFORMATION), @BytesRet,0)
   
   If Result = 1
;       Debug "disk #" + Str(ii)
;       ;Debug "Signature" + Str(aa\Signature)
;       Debug "==============="
      For i=0 To aa\PartitionCount-1 
         ;If aa\PartitionEntry[i]\RecognizedPartition = 1
         If aa\PartitionEntry[i]\PartitionNumber > 0 And aa\PartitionEntry[i]\StartingOffset > 0         
          mask = GetLogicalDrives_()
          For HDSpace = 0 To 31
            If mask  & (1 << HDSpace )
                Drive$ = Chr(65+HDSpace)+":\"
                Result = GetDriveType_(@Drive$)
                If Result = 3
                    GetDiskFreeSpace(Drive$)
                    If TotalPlus = aa\PartitionEntry[i]\PartitionLength Or TotalMinus =  aa\PartitionEntry[i]\PartitionLength
                        DriveLabel$ = Drive$
                    EndIf
                EndIf
            EndIf
          Next
   
          Debug DriveLabel$ + "   " + GetPartitionType(aa\PartitionEntry[i]\PartitionType) + " , length  =  " + Str(aa\PartitionEntry[i]\PartitionLength) + " bytes (" + SpaceDivider(aa\PartitionEntry[i]\PartitionLength) + ")"
;           Debug "Starting Offset = " + Str(aa\PartitionEntry[i]\StartingOffset)
;           Debug "Partition Length = " + Str(aa\PartitionEntry[i]\PartitionLength)
;           Debug "Hidden Sectors = " + Str(aa\PartitionEntry[i]\HiddenSectors)
;           Debug "Partition Number = " + Str(aa\PartitionEntry[i]\PartitionNumber)
;           Debug "Partition Type = " + Str(aa\PartitionEntry[i]\PartitionType)
;           Debug "Boot Indicator = " + Str(aa\PartitionEntry[i]\BootIndicator)
;           Debug "Recognized Partition = " + Str(aa\PartitionEntry[i]\RecognizedPartition)
;           Debug "Rewrite Partition = " + Str(aa\PartitionEntry[i]\RewritePartition)
;           Debug "dummy = " + Str(aa\PartitionEntry[i]\dummy)
          Debug "================"
         EndIf
      Next
      Debug ""
   EndIf
Next
Egypt my love
User avatar
doctorized
Addict
Addict
Posts: 854
Joined: Fri Mar 27, 2009 9:41 am
Location: Athens, Greece

Re: Get partition letter?

Post by doctorized »

Still the same. I will try to do some tests.
Post Reply