There is a useful function called GetDiskFreeSpaceEx( ).

The GetDiskFreeSpaceEx function retrieves information about the amount of space that is available on a disk volume, which is the total amount of space, the total amount of free space, and the total amount of free space available to the user that is associated with the calling thread.

BOOL GetDiskFreeSpaceEx(
  LPCTSTR lpDirectoryName,
  PULARGE_INTEGER lpFreeBytesAvailable,
  PULARGE_INTEGER lpTotalNumberOfBytes,
  PULARGE_INTEGER lpTotalNumberOfFreeBytes
);

A non-trivial question is: why the directory name? After all, the free space is supposed to be the same given a certain volume. There are several answers:

1) Mount points

Remember that starting with Windows 2000 you can mount volumes undera certain directory. For example, c:\ and c:\foo might be located in separate volumes. So, a GetDiskFreeSpaceEx query on C:\ will return different results than C:\foo

2) Directory Quotas

Starting with Windows Server 2003 R2, we include a new feature called directory quotas. it is possible to define soft/hard quota limits on any directory. This means that the free space is different depending on the actual path. For example, if c:\foo has 100 GB free space and c:\foo\bar has a hard quota of only 100 MB, then a GetDiskFreeSpaceEx will return only 100 MB under c:\foo\bar. You can surface this behavior when you are using the DIR command, for example.

One important note, though. The free space computation works correctly when the path is local. On UNC paths, the call above does not return the quota-restricted space - it returns the total volume space instead. This is a known issue, related more with the SMB protocol limitations.