pinvoke GetDiskFreeSpaceEx with UNC

R

Rogas69

Hi all,

I am using VS 2005, .Net 2.0., Windows XP Pro SP2

I encountered a problem for which I couldn't find answer in google.
I want to get colume size information - total, free and available. I am
using GetDiskFreeSpaceEx API function to do this.
So far, so good. Specification says that this function returns BOOL with 0
on failure, nonzero on success.
I took code posted on
http://www.experts-exchange.com/Programming/Programming_Languages/C_Sharp/Q_21447681.html
(thanks!)
and after slight modification i can use it, yet there is problem with
result: if called disk is local, the result equals to 1, if the disk is an
UNC path the result is big, but returned values seem to be ok, and if the
path doesn't exist, the result is huge (long), returned values equal to 0.
I check also Marshall.GetLastWin32Error() and it ALWAYS is non zero - here
are examples:
under debugger (F5)
c:\, free space: 3051442176, result: 1, error >>5<< desc: Access is denied
_______________________________________________________________
\\pg11\c$, free space: 28002582528, result: 25769803777, error >>5<< desc:
Acces
s is denied
_______________________________________________________________
aargh, free space: 0, result: 75998243711877120, error >>3<< desc: The
system ca
nnot find the path specified
_______________________________________________________________
c:\, free space: 3051442176, result: 1, error >>3<< desc: The system cannot
find
the path specified
_______________________________________________________________
\\pg11\c$, free space: 28002582528, result: 25769803777, error >>3<< desc:
The s
ystem cannot find the path specified
_______________________________________________________________
aargh, free space: 0, result: 76842668642009088, error >>3<< desc: The
system ca
nnot find the path specified
_______________________________________________________________


Start without debugging (Ctrl-F5)
c:\, free space: 3051438080, result: 1, error >>2<< desc: The system cannot
find the file specified
_______________________________________________________________
\\pg11\c$, free space: 28002582528, result: 25769803777, error >>1004<<
desc: Invalid flags
_______________________________________________________________
aargh, free space: 0, result: 33495522228568064, error >>3<< desc: The
system cannot find the path specified
_______________________________________________________________
c:\, free space: 3051438080, result: 1, error >>3<< desc: The system cannot
find the path specified
_______________________________________________________________
\\pg11\c$, free space: 28002582528, result: 25769803777, error >>3<< desc:
The system cannot find the path specified
_______________________________________________________________
aargh, free space: 0, result: 34339947158700032, error >>3<< desc: The
system cannot find the path specified
_______________________________________________________________


It is worth to see that after 'aaargh' 'directory' :) the last error always
shows 'The system cannot find the path specified'. I'd expect that result
should be 0 in this case so I could thow an exception.

Anyone has any idea? :)

Peter

Here is my sample code:


using System;

using System.Collections.Generic;

using System.Text;

using System.Runtime.InteropServices;

namespace ConsoleApplication1

{

class Program

{

static void Main(string[] args)

{

try

{

DriveInfo.GetInfo("c:\\");

DriveInfo.GetInfo("\\\\pg11\\c$");

DriveInfo.GetInfo("aargh");

DriveInfo.GetInfo("c:\\");

DriveInfo.GetInfo("\\\\pg11\\c$");

DriveInfo.GetInfo("aargh");

}

catch (Exception e)

{

Console.WriteLine("An error occured during operation:\n " + e.ToString());

}

Console.ReadKey();

}

}

/// <summary>

/// Contains methods to retrieve capacity information for disks or UNC paths

/// </summary>

public sealed class DriveInfo

{

[DllImport("kernel32.dll", EntryPoint = "GetDiskFreeSpaceExW",
CharSet=CharSet.Unicode, SetLastError=true)]

private static extern long GetDiskFreeSpaceEx(string lpDirectoryName,

out long lpFreeBytesAvailableToCaller,

out long lpTotalNumberOfBytes,

out long lpTotalNumberOfFreeBytes);

/// <summary>

/// Returns amount of available, total and free space for given disk

/// <para>Disk may be specified as 'd:' or '\\server\disk$'</para>

/// </summary>

/// <param name="drive"></param>

/// <param name="available"></param>

/// <param name="total"></param>

/// <param name="free"></param>

/// <returns></returns>

public static long GetInfo(string drive, out long available, out long total,
out long free)

{

long result = GetDiskFreeSpaceEx(drive, out available, out total, out free);

if (result!= 1)

throw new System.ComponentModel.Win32Exception(Marshal.GetLastWin32Error());

return result;

}



/// <summary>

/// Returns amount of available, total and free space for given disk

/// <para>Disk may be specified as 'd:' or '\\server\disk$'</para>

/// The information is returned in <see cref="DriveInfoSystem"/> structure

/// </summary>

/// <param name="drive"></param>

/// <returns></returns>

public static DriveInfoSystem GetInfo(string drive)

{

long result = 0, available = 0, total = 0, free = 0;

result = GetDiskFreeSpaceEx(drive, out available, out total, out free);

//Debug only

int nError = Marshal.GetLastWin32Error();

Console.WriteLine(drive + ", free space: " + free.ToString() +

", result: " + result.ToString() + ", error >>" +

nError.ToString() + "<< desc: " +

new System.ComponentModel.Win32Exception(nError).Message +

"\n_______________________________________________________________");

//end

//if (result != 1)

// throw new
System.ComponentModel.Win32Exception(Marshal.GetLastWin32Error());

return new DriveInfoSystem(drive, result, available, total, free);

}

}

/// <summary>

/// Stores values returned by <see cref="GetInfo"/> method of <see
cref="DriveInfo"/> object

/// </summary>

public struct DriveInfoSystem

{

public readonly string Drive;

private readonly long Result;

private readonly long Available;

private readonly long Total;

private readonly long Free;

/// <summary>

/// Returns free space in megabytes

/// </summary>

public double FreeMB { get { return Free / 1024.0 / 1024.0; } }

/// <summary>

/// Returns available space in megabytes

/// </summary>

public double AvailableMB { get { return Available / 1024.0 / 1024.0; } }

/// <summary>

/// Returns total size in megabytes

/// </summary>

public double TotalMB { get { return Total / 1024.0 / 1024.0; } }

public DriveInfoSystem(string drive, long result, long available, long
total, long free)

{

this.Drive = drive;

this.Result = result;

this.Available = available;

this.Total = total;

this.Free = free;

}

}

}
 
W

Willy Denoyette [MVP]

UNC paths must end with a \
But you have other issues as well (error 5 - access denied), but without
seeing any code it's quite impossible to help you out with this.

Willy.

| Hi all,
|
| I am using VS 2005, .Net 2.0., Windows XP Pro SP2
|
| I encountered a problem for which I couldn't find answer in google.
| I want to get colume size information - total, free and available. I am
| using GetDiskFreeSpaceEx API function to do this.
| So far, so good. Specification says that this function returns BOOL with 0
| on failure, nonzero on success.
| I took code posted on
|
http://www.experts-exchange.com/Programming/Programming_Languages/C_Sharp/Q_21447681.html
| (thanks!)
| and after slight modification i can use it, yet there is problem with
| result: if called disk is local, the result equals to 1, if the disk is an
| UNC path the result is big, but returned values seem to be ok, and if the
| path doesn't exist, the result is huge (long), returned values equal to 0.
| I check also Marshall.GetLastWin32Error() and it ALWAYS is non zero - here
| are examples:
| under debugger (F5)
| c:\, free space: 3051442176, result: 1, error >>5<< desc: Access is denied
| _______________________________________________________________
| \\pg11\c$, free space: 28002582528, result: 25769803777, error >>5<< desc:
| Acces
| s is denied
| _______________________________________________________________
| aargh, free space: 0, result: 75998243711877120, error >>3<< desc: The
| system ca
| nnot find the path specified
| _______________________________________________________________
| c:\, free space: 3051442176, result: 1, error >>3<< desc: The system
cannot
| find
| the path specified
| _______________________________________________________________
| \\pg11\c$, free space: 28002582528, result: 25769803777, error >>3<< desc:
| The s
| ystem cannot find the path specified
| _______________________________________________________________
| aargh, free space: 0, result: 76842668642009088, error >>3<< desc: The
| system ca
| nnot find the path specified
| _______________________________________________________________
|
|
| Start without debugging (Ctrl-F5)
| c:\, free space: 3051438080, result: 1, error >>2<< desc: The system
cannot
| find the file specified
| _______________________________________________________________
| \\pg11\c$, free space: 28002582528, result: 25769803777, error >>1004<<
| desc: Invalid flags
| _______________________________________________________________
| aargh, free space: 0, result: 33495522228568064, error >>3<< desc: The
| system cannot find the path specified
| _______________________________________________________________
| c:\, free space: 3051438080, result: 1, error >>3<< desc: The system
cannot
| find the path specified
| _______________________________________________________________
| \\pg11\c$, free space: 28002582528, result: 25769803777, error >>3<< desc:
| The system cannot find the path specified
| _______________________________________________________________
| aargh, free space: 0, result: 34339947158700032, error >>3<< desc: The
| system cannot find the path specified
| _______________________________________________________________
|
|
| It is worth to see that after 'aaargh' 'directory' :) the last error
always
| shows 'The system cannot find the path specified'. I'd expect that result
| should be 0 in this case so I could thow an exception.
|
| Anyone has any idea? :)
|
| Peter
|
| Here is my sample code:
|
|
| using System;
|
| using System.Collections.Generic;
|
| using System.Text;
|
| using System.Runtime.InteropServices;
|
| namespace ConsoleApplication1
|
| {
|
| class Program
|
| {
|
| static void Main(string[] args)
|
| {
|
| try
|
| {
|
| DriveInfo.GetInfo("c:\\");
|
| DriveInfo.GetInfo("\\\\pg11\\c$");
|
| DriveInfo.GetInfo("aargh");
|
| DriveInfo.GetInfo("c:\\");
|
| DriveInfo.GetInfo("\\\\pg11\\c$");
|
| DriveInfo.GetInfo("aargh");
|
| }
|
| catch (Exception e)
|
| {
|
| Console.WriteLine("An error occured during operation:\n " + e.ToString());
|
| }
|
| Console.ReadKey();
|
| }
|
| }
|
| /// <summary>
|
| /// Contains methods to retrieve capacity information for disks or UNC
paths
|
| /// </summary>
|
| public sealed class DriveInfo
|
| {
|
| [DllImport("kernel32.dll", EntryPoint = "GetDiskFreeSpaceExW",
| CharSet=CharSet.Unicode, SetLastError=true)]
|
| private static extern long GetDiskFreeSpaceEx(string lpDirectoryName,
|
| out long lpFreeBytesAvailableToCaller,
|
| out long lpTotalNumberOfBytes,
|
| out long lpTotalNumberOfFreeBytes);
|
| /// <summary>
|
| /// Returns amount of available, total and free space for given disk
|
| /// <para>Disk may be specified as 'd:' or '\\server\disk$'</para>
|
| /// </summary>
|
| /// <param name="drive"></param>
|
| /// <param name="available"></param>
|
| /// <param name="total"></param>
|
| /// <param name="free"></param>
|
| /// <returns></returns>
|
| public static long GetInfo(string drive, out long available, out long
total,
| out long free)
|
| {
|
| long result = GetDiskFreeSpaceEx(drive, out available, out total, out
free);
|
| if (result!= 1)
|
| throw new
System.ComponentModel.Win32Exception(Marshal.GetLastWin32Error());
|
| return result;
|
| }
|
|
|
| /// <summary>
|
| /// Returns amount of available, total and free space for given disk
|
| /// <para>Disk may be specified as 'd:' or '\\server\disk$'</para>
|
| /// The information is returned in <see cref="DriveInfoSystem"/> structure
|
| /// </summary>
|
| /// <param name="drive"></param>
|
| /// <returns></returns>
|
| public static DriveInfoSystem GetInfo(string drive)
|
| {
|
| long result = 0, available = 0, total = 0, free = 0;
|
| result = GetDiskFreeSpaceEx(drive, out available, out total, out free);
|
| //Debug only
|
| int nError = Marshal.GetLastWin32Error();
|
| Console.WriteLine(drive + ", free space: " + free.ToString() +
|
| ", result: " + result.ToString() + ", error >>" +
|
| nError.ToString() + "<< desc: " +
|
| new System.ComponentModel.Win32Exception(nError).Message +
|
| "\n_______________________________________________________________");
|
| //end
|
| //if (result != 1)
|
| // throw new
| System.ComponentModel.Win32Exception(Marshal.GetLastWin32Error());
|
| return new DriveInfoSystem(drive, result, available, total, free);
|
| }
|
| }
|
| /// <summary>
|
| /// Stores values returned by <see cref="GetInfo"/> method of <see
| cref="DriveInfo"/> object
|
| /// </summary>
|
| public struct DriveInfoSystem
|
| {
|
| public readonly string Drive;
|
| private readonly long Result;
|
| private readonly long Available;
|
| private readonly long Total;
|
| private readonly long Free;
|
| /// <summary>
|
| /// Returns free space in megabytes
|
| /// </summary>
|
| public double FreeMB { get { return Free / 1024.0 / 1024.0; } }
|
| /// <summary>
|
| /// Returns available space in megabytes
|
| /// </summary>
|
| public double AvailableMB { get { return Available / 1024.0 / 1024.0; } }
|
| /// <summary>
|
| /// Returns total size in megabytes
|
| /// </summary>
|
| public double TotalMB { get { return Total / 1024.0 / 1024.0; } }
|
| public DriveInfoSystem(string drive, long result, long available, long
| total, long free)
|
| {
|
| this.Drive = drive;
|
| this.Result = result;
|
| this.Available = available;
|
| this.Total = total;
|
| this.Free = free;
|
| }
|
| }
|
| }
|
|
|
 
R

Rogas69

well I provided you all code :) down there :)
|
|
| using System;
|
| using System.Collections.Generic;
|
| using System.Text;
|
| using System.Runtime.InteropServices;
|
| namespace ConsoleApplication1
|
| {
|
| class Program
|
| {
|
| static void Main(string[] args)
|
| {
|
| try
|
| {
|
| DriveInfo.GetInfo("c:\\");
|
| DriveInfo.GetInfo("\\\\pg11\\c$");
|
| DriveInfo.GetInfo("aargh");
|
| DriveInfo.GetInfo("c:\\");
|
| DriveInfo.GetInfo("\\\\pg11\\c$");
|
| DriveInfo.GetInfo("aargh");
|
| }
|
| catch (Exception e)
|
| {
|
| Console.WriteLine("An error occured during operation:\n " +
e.ToString());
|
| }
|
| Console.ReadKey();
|
| }
|
| }
|
| /// <summary>
|
| /// Contains methods to retrieve capacity information for disks or UNC
paths
|
| /// </summary>
|
| public sealed class DriveInfo
|
| {
|
| [DllImport("kernel32.dll", EntryPoint = "GetDiskFreeSpaceExW",
| CharSet=CharSet.Unicode, SetLastError=true)]
|
| private static extern long GetDiskFreeSpaceEx(string lpDirectoryName,
|
| out long lpFreeBytesAvailableToCaller,
|
| out long lpTotalNumberOfBytes,
|
| out long lpTotalNumberOfFreeBytes);
|
| /// <summary>
|
| /// Returns amount of available, total and free space for given disk
|
| /// <para>Disk may be specified as 'd:' or '\\server\disk$'</para>
|
| /// </summary>
|
| /// <param name="drive"></param>
|
| /// <param name="available"></param>
|
| /// <param name="total"></param>
|
| /// <param name="free"></param>
|
| /// <returns></returns>
|
| public static long GetInfo(string drive, out long available, out long
total,
| out long free)
|
| {
|
| long result = GetDiskFreeSpaceEx(drive, out available, out total, out
free);
|
| if (result!= 1)
|
| throw new
System.ComponentModel.Win32Exception(Marshal.GetLastWin32Error());
|
| return result;
|
| }
|
|
|
| /// <summary>
|
| /// Returns amount of available, total and free space for given disk
|
| /// <para>Disk may be specified as 'd:' or '\\server\disk$'</para>
|
| /// The information is returned in <see cref="DriveInfoSystem"/>
structure
|
| /// </summary>
|
| /// <param name="drive"></param>
|
| /// <returns></returns>
|
| public static DriveInfoSystem GetInfo(string drive)
|
| {
|
| long result = 0, available = 0, total = 0, free = 0;
|
| result = GetDiskFreeSpaceEx(drive, out available, out total, out free);
|
| //Debug only
|
| int nError = Marshal.GetLastWin32Error();
|
| Console.WriteLine(drive + ", free space: " + free.ToString() +
|
| ", result: " + result.ToString() + ", error >>" +
|
| nError.ToString() + "<< desc: " +
|
| new System.ComponentModel.Win32Exception(nError).Message +
|
| "\n_______________________________________________________________");
|
| //end
|
| //if (result != 1)
|
| // throw new
| System.ComponentModel.Win32Exception(Marshal.GetLastWin32Error());
|
| return new DriveInfoSystem(drive, result, available, total, free);
|
| }
|
| }
|
| /// <summary>
|
| /// Stores values returned by <see cref="GetInfo"/> method of <see
| cref="DriveInfo"/> object
|
| /// </summary>
|
| public struct DriveInfoSystem
|
| {
|
| public readonly string Drive;
|
| private readonly long Result;
|
| private readonly long Available;
|
| private readonly long Total;
|
| private readonly long Free;
|
| /// <summary>
|
| /// Returns free space in megabytes
|
| /// </summary>
|
| public double FreeMB { get { return Free / 1024.0 / 1024.0; } }
|
| /// <summary>
|
| /// Returns available space in megabytes
|
| /// </summary>
|
| public double AvailableMB { get { return Available / 1024.0 /
1024.0; } }
|
| /// <summary>
|
| /// Returns total size in megabytes
|
| /// </summary>
|
| public double TotalMB { get { return Total / 1024.0 / 1024.0; } }
|
| public DriveInfoSystem(string drive, long result, long available, long
| total, long free)
|
| {
|
| this.Drive = drive;
|
| this.Result = result;
|
| this.Available = available;
|
| this.Total = total;
|
| this.Free = free;
|
| }
|
| }
|
| }
|
|
|
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top