Sign in to follow this  
Followers 0
Strawgate

Calculating Free Space at End of Physical Disk (Creating a partition map)

10 posts in this topic

#1 ·  Posted (edited)

Hey,

I'm currently trying to calculate the free space at the end of a physical hard disk using AutoIT

I'm experiencing a problem not with AutoIT but with Windows Partitions and disks and was wondering if anyone had any insight on this..

I have a hard disk which WMI reports having a size of 256052966400 bytes (31130 Cylinders * 255 Heads * 63 Sectors * 512 Bytes per Sector).

This Hard Disk has 2 partitions:

Part 1:

Offset: 1048576 Bytes
Size: 107374182400 Bytes

Part 2: 

Offset: 107375230976 bytes

Size: 148682833920 Bytes

The problem I'm experiencing is that 1048576 + 107374182400 + 148682833920 = 256052966400 Total Partitioned Bytes

256052966400 Drive Size
256058064896 Partitioned Bytes

-------------------

-5098496 Free Space

Whenever I sum the size of the partitions I end up with a value that's larger than the reported disk size.

Any ideas why I might be encountering this?

Thanks,

-Easton

Edited by Strawgate

Share this post


Link to post
Share on other sites



#2 ·  Posted (edited)

#Include <WinAPIEx.au3>
#include <array.au3>


$AfreeC = _WinAPI_GetDiskFreeSpaceEx("C:")
$AfreeD = _WinAPI_GetDiskFreeSpaceEx("D:")

_ArrayDisplay($AfreeC)
_ArrayDisplay($afreeD)

;total

$Adisk = _WinAPI_GetDriveGeometryEx(0)

_ArrayDisplay($Adisk)

I use winapiEx for all disk space needs, you may get more desirable results with this method as well.

Edited by boththose

,-. .--. ________ .-. .-. ,---. ,-. .-. .-. .-.
|(| / /\ \ |\ /| |__ __||| | | || .-' | |/ / \ \_/ )/
(_) / /__\ \ |(\ / | )| | | `-' | | `-. | | / __ \ (_)
| | | __ | (_)\/ | (_) | | .-. | | .-' | | \ |__| ) (
| | | | |)| | \ / | | | | | |)| | `--. | |) \ | |
`-' |_| (_) | |\/| | `-' /( (_)/( __.' |((_)-' /(_|
'-' '-' (__) (__) (_) (__)

Share this post


Link to post
Share on other sites
#Include <WinAPIEx.au3>
#include <array.au3>


$AfreeC = _WinAPI_GetDiskFreeSpaceEx("C:")
$AfreeD = _WinAPI_GetDiskFreeSpaceEx("D:")

_ArrayDisplay($AfreeC)
_ArrayDisplay($afreeD)

;total

$Adisk = _WinAPI_GetDriveGeometryEx(0)

_ArrayDisplay($Adisk)

I use winapiEx for all disk space needs, you may get more desirable results with this method as well.

 

I seem to now get a third number: 256060514304 which results in ~7mb of free space when doing the partition calculation.

The problem with using GetDiskFreeSpaceEx is that I need to find the free space on the physical disk not on the partitions.

My goal is to produce something like Diskmgmt.msc: 

post-80932-0-58882400-1373060530_thumb.p

 

Where I can interrogate the layout of partitions and the free space between them.

post-80932-0-58882400-1373060530_thumb.p

Share this post


Link to post
Share on other sites

so $AfreeC[2] + $AfreeD[2] doesnt give you the total free space on the disk?


,-. .--. ________ .-. .-. ,---. ,-. .-. .-. .-.
|(| / /\ \ |\ /| |__ __||| | | || .-' | |/ / \ \_/ )/
(_) / /__\ \ |(\ / | )| | | `-' | | `-. | | / __ \ (_)
| | | __ | (_)\/ | (_) | | .-. | | .-' | | \ |__| ) (
| | | | |)| | \ / | | | | | |)| | `--. | |) \ | |
`-' |_| (_) | |\/| | `-' /( (_)/( __.' |((_)-' /(_|
'-' '-' (__) (__) (_) (__)

Share this post


Link to post
Share on other sites

so $AfreeC[2] + $AfreeD[2] doesnt give you the total free space on the disk?

 

It wouldn't if the partitions aren't assigned labels, aren't formatted FAT or NTFS, or if partitions C: and D: don't fill the disk...

Share this post


Link to post
Share on other sites
$iFreeSpace = DriveSpaceFree(@HomeDrive & "\")
MsgBox(0, ";)", $iFreeSpace & " MB")

 

Thanks but that's not what I'm asking for.

As I said just prior I'm looking for information on the physical disk not the logical volume...

Share this post


Link to post
Share on other sites

Without seeing how you wrote your query to WMI and how you calculated the total size/free space left it's hard to determine where the issue might be. Post your code.


If I posted any code, assume that code was written using the latest release version unless stated otherwise. Also, if it doesn't work on XP I can't help with that because I don't have access to XP, and I'm not going to.
Give a programmer the correct code and he can do his work for a day. Teach a programmer to debug and he can do his work for a lifetime - by Chirag Gude
How to ask questions the smart way!

I hereby grant any person the right to use any code I post, that I am the original author of, on the autoitscript.com forums, unless I've specifically stated otherwise in the code or the thread post. If you do use my code all I ask, as a courtesy, is to make note of where you got it from.

Back up and restore Windows user files _Array.au3 - Modified array functions that include support for 2D arrays.  -  ColorChooser - An add-on for SciTE that pops up a color dialog so you can select and paste a color code into a script.  -  Customizable Splashscreen GUI w/Progress Bar - Create a custom "splash screen" GUI with a progress bar and custom label.  -  _FileGetProperty - Retrieve the properties of a file  -  SciTE Toolbar - A toolbar demo for use with the SciTE editor  -  GUIRegisterMsg demo - Demo script to show how to use the Windows messages to interact with controls and your GUI.  -   Latin Square password generator

Share this post


Link to post
Share on other sites

Please note, you will have to verify using diskpart.exe that there is no free space at the end of your drive otherwise you will not be able to replicate the issue.

#include <array.au3>
$WMI_Tools = ObjGet("WinMgmts:")

$Test_arr = _GetDiskLayout(0)

Func _GetDiskLayout($Disk)
    Local $Arr_Return[63][3]
    ;   $Position = 0
    ;   local $temp_reserved = 0
    $Disk_Size = _GetDiskSize($Disk)

    $count = 0
    $Pointer = 0
    $Disk_Partition_Count = _GetDiskPartsCount($Disk)
    $Disk_Reserved_Space = Default
    For $index = 0 To $Disk_Partition_Count - 1 Step 0
        Local $Disk_Specific_Partition_Details = _GetDiskPartDetails($Disk, $index)
        Local $Disk_Specific_Partition_Offset = $Disk_Specific_Partition_Details[2]
        Local $Disk_Specific_Partition_Size = $Disk_Specific_Partition_Details[3]

        If $Disk_Reserved_Space = Default Then
            $Disk_Reserved_Space = $Disk_Specific_Partition_Offset
            consolewriteline("Reserved Space Detected: " & $Disk_Reserved_Space)
            $Pointer = $Disk_Specific_Partition_Offset
            ContinueLoop
        EndIf

        If $Disk_Specific_Partition_Offset <> $Pointer Then
            if $Disk_Specific_Partition_Offset - $Pointer > 1048576 then
                $Arr_Return[$count][0] = "Free"
                $Arr_Return[$count][1] = $Disk_Specific_Partition_Offset
                $Arr_Return[$count][2] = $Disk_Specific_Partition_Offset - $Pointer
                consolewriteline("Free Space Offset: " & $Disk_Specific_Partition_Offset)
                consolewriteline("Free Space Size: " & $Disk_Specific_Partition_Offset - $Pointer)
                $count += 1
            EndIf
;           consolewriteline("Unused Inside Space: " & $Disk_Specific_Partition_Offset - $Pointer)
            $Pointer = $Disk_Specific_Partition_Offset
            ContinueLoop
        EndIf
        $Arr_Return[$count][0] = $index
        $Arr_Return[$count][1] = $Disk_Specific_Partition_Offset
        $Arr_Return[$count][2] = $Disk_Specific_Partition_Size
        consolewriteline("Partition Offset: " & $Disk_Specific_Partition_Offset)
        consolewriteline("Partition Size: " & $Disk_Specific_Partition_Size)
        $Pointer = $Disk_Specific_Partition_Offset + $Disk_Specific_Partition_Size
        $index += 1
        $count += 1
    Next
    ;At this point all partitions have been mapped out -- if $Pointer <> Disk Size we have free space...

    $Trailing_Space = $Disk_Size - $Pointer
    $Arr_Return[$count][0] = "Free"
    $Arr_Return[$count][1] = $Pointer
    $Arr_Return[$count][2] = $Trailing_Space
    $count += 1
    consolewriteline("Unused Space at end of disk: " & $Trailing_Space)


    ReDim $Arr_Return[$count][3]

    return $Arr_Return
EndFunc   ;==>_GetDiskLayout

Func _GetDiskPartDetails($Disk, $Part)
    Local $partArr[5]
    Local $oColItems = $WMI_Tools.ExecQuery("Select * From Win32_DiskPartition", "WQL", 0x30)
    For $oObjectItem In $oColItems
        If $oObjectItem.DiskIndex = $Disk And $oObjectItem.index = $Part Then
            $partArr[0] = $oObjectItem.DiskIndex
            $partArr[1] = $oObjectItem.index
            $partArr[2] = $oObjectItem.StartingOffset
            $partArr[3] = $oObjectItem.Size
            $partArr[4] = $oObjectItem.Description
        EndIf
    Next
    Return $partArr
EndFunc   ;==>_GetDiskPartDetails

Func _GetDiskSize($Disk)
    Local $oColItems = $WMI_Tools.ExecQuery("Select * From Win32_DiskDrive", "WQL", 0x30)
    For $oObjectItem In $oColItems
        If $oObjectItem.index = $Disk Then Return $oObjectItem.Size
    Next
EndFunc   ;==>_GetDiskSize

Func _GetDiskPartsCount($Disk)
    Local $oColItems = $WMI_Tools.ExecQuery("Select * From Win32_DiskDrive", "WQL", 0x30)
    For $oObjectItem In $oColItems
        If $oObjectItem.index = $Disk Then Return $oObjectItem.Partitions
    Next
EndFunc   ;==>_GetDiskPartsCount

Func consolewriteline($text)
    ConsoleWrite($text & @CRLF)
EndFunc   ;==>consolewriteline

Thanks!

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0