title: Get size of volume on Windows
body: <p>I'm writing a library to extract information about physical disks, partitions, and volumes on a Windows system (XP or later).</p>
  
  <p>I'm trying to get the capacity of a volume.  Here are the approaches I know about and the reason each fails:</p>
  
  <ul>
  <li><a href="http://msdn.microsoft.com/en-us/library/windows/desktop/aa364937.aspx" rel="noreferrer"><code>GetDiskFreeSpaceEx</code></a> -- Affected by user quota.</li>
  <li><a href="http://msdn.microsoft.com/en-us/library/windows/desktop/aa365171.aspx" rel="noreferrer"><code>IOCTL_DISK_GET_DRIVE_GEOMETRY_EX</code></a> -- Gets size of entire physical disk, even when invoked using a volume handle.</li>
  <li><a href="http://msdn.microsoft.com/en-us/library/windows/desktop/aa365194.aspx" rel="noreferrer"><code>IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS</code></a> -- Doesn't account for RAID overhead.</li>
  <li><a href="http://msdn.microsoft.com/en-us/library/windows/desktop/aa365178.aspx" rel="noreferrer"><code>IOCTL_DISK_GET_LENGTH_INFO</code></a> -- Fails with access denied.  (Actually, it requires <code>GENERIC_READ</code> access, unlike all other queries, and <code>GENERIC_READ</code> requires administrator access.)</li>
  <li><a href="http://msdn.microsoft.com/en-us/library/aa363469.aspx" rel="noreferrer"><code>IOCTL_STORAGE_READ_CAPACITY</code></a> -- Not available on XP, also shares the drawbacks of <code>IOCTL_DISK_GET_LENGTH_INFO</code> and <code>IOCTL_DISK_GET_DRIVE_GEOMETRY_EX</code></li>
  <li><a href="http://msdn.microsoft.com/en-us/library/windows/desktop/aa364573%28v=vs.85%29.aspx" rel="noreferrer"><code>FSCTL_GET_VOLUME_BITMAP</code></a> + <code>GetFreeDiskSpace</code> for cluster size -- Requires <code>GENERIC_READ</code> (admin access) and gives the size of the data area of the filesystem, not the entire volume.</li>
  <li><a href="http://msdn.microsoft.com/en-us/library/aa365179%28v=vs.85%29.aspx" rel="noreferrer"><code>IOCTL_DISK_GET_PARTITION_INFO</code></a> -- Requires <code>GENERIC_READ</code> (admin access) and also failed on a USB-attached disk (possibly using superfloppy partitioning)</li>
  </ul>
  
  <p>Oddly, the number of clusters from <code>FSCTL_GET_VOLUME_BITMAP</code> and WMI's <code>CIM_LogicalDisk.Size</code> property agree, and both are 4096 bytes smaller than the value from <code>IOCTL_DISK_GET_LENGTH_INFO</code>.</p>
  
  <p>What is the correct way to get volume capacity?  Since all the other queries work without administrator access, I'm looking for a least-privilege solution for this too.</p>