Page 1 of 2
Get partitions of a hard disk drive
Posted: Sun Sep 20, 2009 1:39 pm
by doctorized
I tried to find a way to get the number of partitions of my hard drives. After a search here, in this forum, I found nothing.
So, gathering many info, I wrote the following code:
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
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 "==============="
For i=0 To aa\PartitionCount-1
If aa\PartitionEntry[i]\RecognizedPartition = 1
tmp + 1
Debug "Partition #" + Str(tmp) + " : " + GetPartitionType(aa\PartitionEntry[i]\PartitionType) + " , length = " + Str(aa\PartitionEntry[i]\PartitionLength) + " bytes"
EndIf
Next
Debug ""
EndIf
Next
Re: Get partitions of a hard disk drive
Posted: Sun Sep 20, 2009 1:56 pm
by Thorium
Does it need admin privilegs?
Because it don't work on my system: Vista 64
BytesRet = 0
Re: Get partitions of a hard disk drive
Posted: Sun Sep 20, 2009 2:03 pm
by rsts
same on win 7 64 bit; PB4.4b3
cheers
Re: Get partitions of a hard disk drive
Posted: Sun Sep 20, 2009 2:19 pm
by doctorized
According to Microsoft, the caller must have administrative privileges for CreateFile to succeed on a hard disk drive.
Can anyone find a way to bypass it?
Re: Get partitions of a hard disk drive
Posted: Sun Sep 20, 2009 2:32 pm
by rsts
Running with admin, I get a command window, which ends too quickly to read, followed by
---------------------------
PureBasic Debugger
---------------------------
The debugged executable quit unexpectedly.
---------------------------
OK
---------------------------
No debug output.
OK - problems debugging - too much output- replaced debug with messagerequester and works fine.
Nice
cheers
Re: Get partitions of a hard disk drive
Posted: Sun Sep 20, 2009 2:47 pm
by doctorized
rsts wrote:OK - problems debugging - too much output- replaced debug with messagerequester and works fine.
I suppose you are using console debugger. This one shows nothing. I use the integrated IDE debugger and a debugging window
pops up showing the info. The use of MessageRequester is the only solution for this kind of problems, as we do not use the "Debug"
command in our apps. I used "Debug" beacause I only wanted to show the way to take the data, not to show how to handle them, this
lies on everyone's needs.
Re: Get partitions of a hard disk drive
Posted: Sun Sep 20, 2009 2:57 pm
by PB
> According to Microsoft, the caller must have administrative privileges for CreateFile to succeed on a hard disk drive.
What? No way. None of our apps would work on limited accounts if it did!
Re: Get partitions of a hard disk drive
Posted: Sun Sep 20, 2009 3:10 pm
by rsts
PB wrote:> According to Microsoft, the caller must have administrative privileges for CreateFile to succeed on a hard disk drive.
What? No way. None of our apps would work on limited accounts if it did!
Appears this use may require admin-
Direct access to the disk or to a volume is restricted. For more information, see "Changes to the file system and to the storage stack to restrict direct disk access and direct volume access in Windows Vista and in Windows Server 2008" in the Help and Support Knowledge Base at
http://support.microsoft.com/kb/942448.
http://msdn.microsoft.com/en-us/library ... S.85).aspx
"The following requirements must be met for such a call to succeed:
* The caller must have administrative privileges. For more information, see Running with Special Privileges."
BTW - works fine with admin.
cheers
Re: Get partitions of a hard disk drive
Posted: Sun Sep 20, 2009 5:14 pm
by SFSxOI
doesn't return correct information for RAID0 configurations
Re: Get partitions of a hard disk drive
Posted: Sun Sep 20, 2009 6:44 pm
by flaith
Thanks for the code, i needed it
i just modified (and added) the procedure GetPartitionType:
Code: Select all
Procedure.s GetPartitionType(type.b)
Select type & $ff
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"
Case $82
ProcedureReturn "Linux Swap"
Case $83
ProcedureReturn "Linux native partition"
Case $85
ProcedureReturn "Linux extended partition"
Default
ProcedureReturn "$"+Hex(type, #PB_Byte)
EndSelect
EndProcedure
Added Linux cause i have the ext3 drivers for windows installed

Re: Get partitions of a hard disk drive
Posted: Mon Sep 21, 2009 2:31 am
by Rook Zimbabwe
OK so once you have it...
How do you delete a partition? (I plan on making a secure delete application!)
ALSO: Isn't NTFT supposed to be
NTFS????
Re: Get partitions of a hard disk drive
Posted: Mon Sep 21, 2009 9:20 am
by doctorized
Rook Zimbabwe wrote:Isn't NTFT supposed to be NTFS????
No, "A NTFT Patition is different to NTFS file system", as I saw at:
http://social.msdn.microsoft.com/Forums ... f42cdf09b0
Delete Partition? You gave me idea to search more!! If I find something, I'll tell.
Re: Get partitions of a hard disk drive
Posted: Mon Sep 21, 2009 12:13 pm
by SFSxOI
In Windows a NTFT partition is not really anything, not really a partition. Its just basically a value intended to be OR'ed with other values in the table at >
http://msdn.microsoft.com/en-us/library ... S.85).aspx. People try to treat it as a seperate partition in their code, I think because of the way its presented in the MSDN without explaination, but its not really a partition all by its self. I ran into this myself a while back and I asked one of the Microsoft consultants we have here where I work, he chuckled a little and said it wasn't really anything (and then told me the above). It has to be logically OR'd with the other values in the table. PARTITION_NTFT is for non-striped (RAID) drives like IDE or SATA drives for example, VALID_NTFT is for striped (RAID) mirrored drive configurations - Which might explain why the above code presented doesn't get the correct information for RAID0 drives - because the correct value isn't OR'ed maybe (dunno as i haven't played with it yet) ? In the presented code this;
Code: Select all
Case $C0
ProcedureReturn "NTFT uses high order bits" ; <<<< for striped (RAID) mirrored configurations
Case $80
ProcedureReturn "NTFT" ; <<<< for non-striped configurations
WMI returns the correct format without resorting to this or creating files, I posted some code using srods COmate in the tricks and tips previously for computer information, part of that contains getting the drive information which includes parameters of the drive including the file system, if it helps anyone.
One simple way to "secure" delete a partition is to format the partition first then overwrite with random 1's and 0's then delete the mount point with the 'DeleteVolumeMountPoint()' API. This is for general purpose everyday plain old 'secure delete' but its not for really-really-really secure purposes which I won't go into here as there is a thread in the Off Topic that discusses this aspect. There are faster ways, but the general rule of thumb in terms of infosec is the faster a delete is the less secure it is although thats not always true in only about 10% of the cases but it depends on how its done too. (NOTE: I edited this part of this post because I got it backwards, temporary lack of brain power and not enough coffee, if you read it previously what I wrote previously was backwards so do it as written now is correct for the general purpose secure delete.)
Ok, I think i said all this right now. Don't kill me if I didn't

, i'm going off memory as I don't have the information with me right now.
Re: Get partitions of a hard disk drive
Posted: Wed Sep 23, 2009 10:13 am
by Joakim Christiansen
Sweet!
I made some tweaks to it:
In the
GetPartitionType procedure I changed
Select type to
Select type & $FF to make it work with unsigned hex values.
I also added
Default: ProcedureReturn "Unknown ($"+byteToHex(type)+")"
Code: Select all
Procedure.s byteToHex(byte.b)
ProcedureReturn RSet(Hex(PeekB(@byte),#PB_Byte),2,"0")
EndProcedure
I also removed any "write" stuff from the API to open the file:
Code: Select all
hdh = CreateFile_("\\.\PhysicalDrive"+Str(ii),#GENERIC_READ,#FILE_SHARE_READ,0,#OPEN_EXISTING,0,0)
So maybe this helps with the admin privileges issue (haven't tested on Vista yet...).
Edit: Nah, didn't help. Seems accessing "PhysicalDrive" always need admin priv.
And in the debug output I also formatted the size into KB, MB and GB...
Code: Select all
Debug "Partition #"+Str(tmp)+" - "+GetPartitionType(aa\PartitionEntry[i]\PartitionType)+" - "+SizeString(aa\PartitionEntry[i]\PartitionLength)
Code: Select all
Procedure.s SizeString(Bytes.q)
Protected Result$, KB.f = Bytes / 1024, Sign$
If KB < 1
Result$ = Str(Bytes): Sign$ = " B"
ElseIf KB < 1000
Result$ = StrF(KB,1): Sign$ = " KB"
ElseIf KB < 1000000
Result$ = StrF(KB/1000,1): Sign$ = " MB"
Else
Result$ = StrF(KB/1000000,1): Sign$ = " GB"
EndIf
If Len(StringField(Result$,1,".")) > 1
Result$ = StrF(ValF(Result$),0)
EndIf
ProcedureReturn Result$+Sign$
EndProcedure
For more info on partition ID's I found this site btw:
http://www.win.tue.nl/~aeb/partitions/p ... pes-1.html
But I guess we better use it in combination with the GUIDS (how?).
http://en.wikipedia.org/wiki/GUID_Partition_Table
Code with my changes:
Code: Select all
EnableExplicit
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 byteToHex(byte.b)
ProcedureReturn RSet(Hex(PeekB(@byte),#PB_Byte),2,"0")
EndProcedure
Procedure.s GetPartitionType(type.b)
;More here: http://www.win.tue.nl/~aeb/partitions/partition_types-1.html
Select type & $FF ;make it unsigned
Case $0
ProcedureReturn "Unused"
Case $01
ProcedureReturn "12-bit FAT"
Case $02, $03
ProcedureReturn "Xenix"
Case $04
ProcedureReturn "16-bit FAT"
Case $05
ProcedureReturn "Extended"
Case $06
ProcedureReturn "Huge partition MS-DOS V4"
Case $07
ProcedureReturn "Installable File System (NTFS/HPFS/FAT64)"
Case $08
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 $09
ProcedureReturn "AIX data partition/Coherent filesystem/QNX 1.x and 2.x (qnz)"
Case $0A
ProcedureReturn "OS/2 Boot Manager/OPUS/Coherent swap"
Case $0B
ProcedureReturn "FAT32"
Case $0C
ProcedureReturn "FAT32 using extended int13 services"
Case $0E
ProcedureReturn "Win95 partition using extended int13 services"
Case $0F
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"
Case $AF
ProcedureReturn "HFS+ (Mac OS)"
Case $83
ProcedureReturn "Linux"
Case $82
ProcedureReturn "Linux Swap"
Default
ProcedureReturn "Unknown ($"+byteToHex(type)+")"
EndSelect
EndProcedure
Procedure.s SizeString(Bytes.q)
Protected Result$, KB.f = Bytes / 1024, Sign$
If KB < 1
Result$ = Str(Bytes): Sign$ = " B"
ElseIf KB < 1000
Result$ = StrF(KB,1): Sign$ = " KB"
ElseIf KB < 1000000
Result$ = StrF(KB/1000,1): Sign$ = " MB"
Else
Result$ = StrF(KB/1000000,1): Sign$ = " GB"
EndIf
If Len(StringField(Result$,1,".")) > 1
Result$ = StrF(ValF(Result$),0)
EndIf
ProcedureReturn Result$+Sign$
EndProcedure
Define IOCTL_DISK_GET_DRIVE_LAYOUT.l = 475148
Define aa.DRIVE_LAYOUT_INFORMATION
Define BytesRet, tmp
Define ii, i, hdh
For ii=0 To 49
BytesRet = 0: tmp = 0
hdh = CreateFile_("\\.\PhysicalDrive" + Str(ii),#GENERIC_READ, #FILE_SHARE_READ ,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 "==============="
For i=0 To aa\PartitionCount-1
If aa\PartitionEntry[i]\RecognizedPartition = 1
tmp + 1
Debug "Partition #"+Str(tmp)+" - "+GetPartitionType(aa\PartitionEntry[i]\PartitionType)+" - "+SizeString(aa\PartitionEntry[i]\PartitionLength)
EndIf
Next
Debug ""
EndIf
Next
Re: Get partitions of a hard disk drive
Posted: Wed Sep 23, 2009 2:39 pm
by doctorized
I use this code to read sectors:
Code: Select all
StartingLogicalSector.l=0; Set the starting sector
NumberOfSectors.l=3; Set the number of sectors to be read.
Dim buffer.b(512*NumberOfSectors)
hdh.l = CreateFile_("\\.\C:",#GENERIC_READ, #FILE_SHARE_READ, 0, #OPEN_EXISTING, 0, 0)
SetFilePointer_(hdh, (StartingLogicalSector*512), #Null, 0); I use 512 because every sector should have 512 bytes. In some cases, like floppy disks, we have 1024bytes/sector.
ReadFile_(hdh, @buffer(), 512*NumberOfSectors, @bytesread.l, #Null)
CloseHandle_(hdh)
CreateFile(0,"c:\sector.txt")
For i=0 To bytesread-1
WriteByte(0,buffer(i))
Next
CloseFile(0)
Debug "OK"; let us know when you finished.
I did a small check but non of the GUIDs provided by wikipedia is found in the third sector (sector 2 starting from 0) of my partitions.