0

I came across this excellent article that solves the problem of enumerating disconnected drives in C#: Mapped network drives cannot be listed in C#

The problem is that it seems like this code will NOT include NTFS-formatted drives (only FAT)

As I'm not a C++/WinAPI techie, I find it hard to fix the code (if possible at all). Any chance anyone already look into it and solved it, or at least give me a hint?

Thanks! Busi

Community
  • 1
  • 1
baruchl
  • 219
  • 2
  • 13
  • I'm not sure what you mean : a network share is a network share, nothing more, it abstracts the underlying filesystem through the SMB protocol (eg. you can access ext2 drives from Windows using SMB). I also tried running that code from my workstation (all my mounted drives are NTFS), and it works fine. Or did you mean your local drives ? – T. Fabre Dec 06 '12 at 16:15
  • Hi @t-fabre, thanks for your comment. I meant network drives and not local drives. When running on Windows server 2008 R2, I have 2 network drives O (NTFS) and I (FAT), and the code above returns only the I drive – baruchl Dec 06 '12 at 19:45
  • Odd. Just tested the code I posted 2008R2, returns all the local drives and mapped network drives. FS type should not matter. Are the shares on the same server or another one ? – T. Fabre Dec 06 '12 at 21:17
  • Thanks @T.Fabre this please see my answer below. I was wrong and it has nothing to do with the FAT/NTFS. – baruchl Dec 07 '12 at 00:05

2 Answers2

2

OK, I have an answer. It has nothing to do with NTFS and FAT.

This is the code I used to enumerate the drives:

WNetOpenEnum( RESOURCE_SCOPE.RESOURCE_REMEMBERED, RESOURCE_TYPE.RESOURCETYPE_DISK, 0, resource, out ptrHandle);

Please note the first parameter, RESOURCE_SCOPE.RESOURCE_REMEMBERED. This mean that the method will only enumerate those mapped drives that were set as PERSISTED (which means, re-connect at logon).

If I change for example the parameter to RESOURCE_SCOPE.RESOURCE_CONNECTED, it will enumerate the non-persisted drives, if they are connected.

If you want all the combinations, you can do: WNetOpenEnum(RESOURCE_SCOPE.RESOURCE_REMEMBERED | RESOURCE_SCOPE.RESOURCE_RECENT | RESOURCE_SCOPE.RESOURCE_CONNECTED, RESOURCE_TYPE.RESOURCETYPE_DISK, 0, resource, out ptrHandle);

Thank you!

baruchl
  • 219
  • 2
  • 13
  • Note that the last example is wrong. To quote the current documentation on MSDN: `Scope of the enumeration. This parameter can be one of the following values.`. You can't combine the values for `dwScope` which becomes obvious if you look at the actual values for that argument. – Max Truxa Apr 02 '20 at 14:38
1

If you want to list your local NTFS drives, the article you mentionned won't cut it : the Win32 functions it uses are meant to enumerate network ressources.

So if you want to list all local drives and network drives, you have to use both the code from your link, and also call DriveInfo.GetDrives() (or Environment.GetDrives()) from the System.IO namespace.

However, since GetDrives() will also return connected network drives, you need to merge the results of both lists to avoid duplicates :

    static void Main(string[] args)
    {
        List<string> drives = new List<string>();
        // Assuming you put the API calls in Class1
        foreach (var item in Class1.WNetResource())
        {
            // WNetResource returns the drive letters without a trailing slash
            drives.Add(String.Concat(item.Key, @"\"));
        }

        foreach (var item in Environment.GetLogicalDrives())
        {
            if (!drives.Contains(item))
                drives.Add(item);
        }

        drives.Sort();

        foreach (var drive in drives)
        {
            Console.WriteLine(drive);
        }
    }

Hope that helps.

T. Fabre
  • 1,517
  • 14
  • 20
  • 1
    Thanks @t-fabre, I'm afraid that this is not enough. GetDrives doesn't enumerate the disconnected drives. That's why I wanted to update the WNetResource code to return the NTFS drives as well. – baruchl Dec 06 '12 at 19:45