0

How can I get the exact size of the hard disk in bytes on the old Windows 2000?

IOCTL_DISK_GET_LENGTH_INFO works fine for volumes, but not on physical disk handles (stuff at //./PHYSICALDISKx) on Windows 2000. (Works fine for physical drives from XP or later)

We still have to support this ancient OS...

UPDATE:

The code is written in C, so I would use plain Windows API if possible.

Calmarius
  • 18,570
  • 18
  • 110
  • 157
  • In what manner does that ioctl not work? I assume it fails with a specific error code? Have you tried any of the other ioctls (GET_DRIVE_LAYOUT, GET_LENGTH_INFO, etc)? – Luke Sep 23 '13 at 20:36
  • @Luke On Windows 2000 it gives ERROR_INVALID_FUNCTION when I use it on a handle I got by opening a drive at //./PHYSICALDRIVEx. It works fine on XP later. So I'm looking for a workaround for that OS. Getting the exact number of bytes on disk is a requirement. – Calmarius Sep 23 '13 at 21:42
  • You can get this with IOCTL_DISK_GET_DRIVE_GEOMETRY. It gives you cylinders, tracks per cylinder, sectors per track, and bytes per sector. Multiply them all together and it gives you the total number of bytes for the disk. – Luke Sep 24 '13 at 14:39

3 Answers3

2

You could get the free space in C (without any API or etc)

If you run "dir c:\", the last line will give you the free disk space.

Better solution: "fsutil volume diskfree c:"

Or try the below code...

void main (int argc, wchar_t **argv)
       {
          BOOL  fResult;
          unsigned __int64 i64FreeBytesToCaller,
                           i64TotalBytes,
                           i64FreeBytes;
             fResult = GetDiskFreeSpaceEx (L"C:",
                                     (PULARGE_INTEGER)&i64FreeBytesToCaller,
                                     (PULARGE_INTEGER)&i64TotalBytes,
                                     (PULARGE_INTEGER)&i64FreeBytes);
             if (fResult)
             {
                printf ("\n\nGetDiskFreeSpaceEx reports\n\n");
                printf ("Available space to caller = %I64u MB\n",
                        i64FreeBytesToCaller / (1024*1024));
                printf ("Total space               = %I64u MB\n",
                        i64TotalBytes / (1024*1024));
                printf ("Free space on drive       = %I64u MB\n",
                        i64FreeBytes / (1024*1024));
             }
       }
Aby
  • 1,916
  • 1
  • 12
  • 18
  • The [GetDiskFreeSpaceEx](http://stackoverflow.com/questions/627131/getdiskfreespaceex-reports-wrong-number-of-free-bytes) is inaccurate. I want to know the size of the whole disk: all partitions and unallocated space included. We need to write disks directly and want to know the last valid sector number on the whole disk. – Calmarius Sep 23 '13 at 14:23
  • @Calmarius Whoah - low level operations without a heavy textbook. Bold! – PP. Sep 23 '13 at 15:32
  • @PP. There is no other way to remove those pesky boot viruses, that place their stuff into the last sectors... ;) – Calmarius Sep 23 '13 at 15:41
  • @Calmarius remove.. or install? – PP. Sep 23 '13 at 15:43
  • @PP FDISK /MBR will do. – Aby Sep 23 '13 at 15:45
0

Whenever I need to get this type of info, I typically use WMI as it provides a wealth of data on just about anything.

rrirower
  • 4,338
  • 4
  • 27
  • 45
0

It seems there is no IOCTL that give you the exact hard drive size on Windows 2000.

But there is a workaround, that worked:

I used IOCTL_DISK_GET_DRIVE_GEOMETRY to get cylinders, tracks/cyl, sectors/track, bytes/sector.

Multiplying them gave me a rough size of the HDD but not the exact size (little smaller). I can calculate the almost last sector id from this.

To get the exact size I used IOCTL_SCSI_PASS_THROUGH and sent SCSI read commands to attempt to read beyond the end of disk, so I had a sector number for a non-existing sector, then used binary search to get highest sector id where the read succeeds.

Multiplying it with the bytes/sector, I have the exact size of hard disk in bytes.

Calmarius
  • 18,570
  • 18
  • 110
  • 157