views:

49

answers:

2

I am trying to get the physical device size of a connected USB flash drive. I have tried using WMI.

        ManagementObjectSearcher mosDisks = new ManagementObjectSearcher("SELECT * FROM Win32_DiskDrive WHERE Model = '" + cmbHdd.SelectedItem + "'");
        foreach (ManagementObject moDisk in mosDisks.Get())
        {
            lblCapacity.Text = "Capacity: " + moDisk["Size"];
        }

I have tried using imports to get the geometry:

        var geo = new DiskGeometry();
        uint returnedBytes;
        DeviceIoControl(Handle, 0x70000, IntPtr.Zero, 0, ref geo, (uint)Marshal.SizeOf(typeof(DiskGeometry)), out returnedBytes, IntPtr.Zero);
        return geo.DiskSize;

They all do return a value.. but it is not correct.

For example, the above code returns 250056737280. When I dump the entire binary contents to a new file, FileStream.Length returns 250059350015

See how the last option is bigger? That is also the corrrect size I need to get for my code to work as expected. But I cannot dump 250gb of data just to get the full size. So is there another method to get proper size?

A: 

Hi there.

Is this any use for you?

using System;
using System.Runtime.InteropServices;

public class MainClass
{
    [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]
    static extern bool GetDiskFreeSpaceEx(string lpDirectoryName,
       out ulong lpFreeBytesAvailable,
       out ulong lpTotalNumberOfBytes,
       out ulong lpTotalNumberOfFreeBytes);
    public static void Main()
    {
        ulong freeBytesAvail;
        ulong totalNumOfBytes;
        ulong totalNumOfFreeBytes;

        if (!GetDiskFreeSpaceEx("C:\\", out freeBytesAvail, out totalNumOfBytes, out totalNumOfFreeBytes))
        {
            Console.Error.WriteLine("Error occurred: {0}",
                Marshal.GetExceptionForHR(Marshal.GetLastWin32Error()).Message);
        }
        else
        {
            Console.WriteLine("Free disk space:");
            Console.WriteLine("    Available bytes : {0}", freeBytesAvail);
            Console.WriteLine("    Total # of bytes: {0}", totalNumOfBytes);
            Console.WriteLine("    Total free bytes: {0}", totalNumOfFreeBytes);
        }
    }
}

Found the above example here: http://www.java2s.com/Tutorial/CSharp/0520__Windows/Getfreediskspace.htm

Cheers. Jas.

Jason Evans
Thanks, but I can't get it to open my device. http://nvsx.net/i/83679.png That path has always worked for me. And is correct.
Eaton
Damn. Oh well, worth a shot. I'm not sure what's happening there I'm afraid.
Jason Evans
It's alright. I don't think that would be right even if it worked. I want the total size, not free size. This device is also unformatted and not a logical drive letter. That's why I need to put the physical path in.
Eaton
A: 

You might consider trying IOCTL_DISK_GET_LENGTH_INFO with DevideIoControl.

Chris Taylor
Interesting. Where can I find those enums as integers so I can put the correct value in?
Eaton
The constants are defined in WinIoCtl.h. The value for IOCTL_DISK_GET_LENGTH_INFO is 0x0007405c
Chris Taylor
Thank you, I will try that soon and let you know of my results.
Eaton
Worked perfectly, it is now returning the full and proper disk size.
Eaton