Jörgen Sigvardsson
Jörgen Sigvardsson

Reputation: 4887

Detect whether a path points to an NTFS partition or not

Given an absolute file system path, how would I detect whether it's on an NTFS partition or not? I would prefer a helping hand in C#, but Win32/C would do. The system which the software will run on, is Windows Vista or later.

Upvotes: 1

Views: 1997

Answers (5)

Harry Johnston
Harry Johnston

Reputation: 36318

You can use FSCTL_FILESYSTEM_GET_STATISTICS to determine the file system type.

Here's some sample code. I've checked that this handles mount points properly, i.e., it detects the type of the target volume, not the source volume. You don't need to specify the mount point itself (although you can) but the file or directory you specify must exist.

#define _WIN32_WINNT 0x0502

#include <windows.h>

#include <stdio.h>

int wmain(int argc, wchar_t ** argv)
{
    HANDLE h;
    FILESYSTEM_STATISTICS * fs;
    BYTE buffer[32768];
    DWORD dw;

    h = CreateFile(argv[1], 0, 
        FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, 
        NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);

    if (h == INVALID_HANDLE_VALUE)
    {
        printf("CreateFile: %u\n", GetLastError());
        return 1;
    }

    if (!DeviceIoControl(h, FSCTL_FILESYSTEM_GET_STATISTICS, NULL, 0, buffer, sizeof(buffer), &dw, NULL))
    {
        dw = GetLastError();
        CloseHandle(h);
        printf("DeviceIoControl: %u\n", dw);
        if (dw == ERROR_INVALID_FUNCTION)
        {
            printf("This probably means the specified file or directory is not on an NTFS volume.\n");
            printf("For example, this happens if you specify a file on a CD-ROM.\n");
        }
        return 1;
    }

    CloseHandle(h);

    fs = (FILESYSTEM_STATISTICS *)buffer;
    printf("Filesystem type: %u\n", fs->FileSystemType);

    if (fs->FileSystemType == FILESYSTEM_STATISTICS_TYPE_NTFS)
    {
        printf("The file or directory is on an NTFS volume.\n");
    }
    else
    {
        printf("The file or directory is not on an NTFS volume.\n");
    }
    return 0;
}

Upvotes: 2

Bukes
Bukes

Reputation: 3708

The Win32 GetVolumeInformation() API will give you the name of the filesystem for a given root directory path.

Note that this will follow symbolic links/joins, and return information for the target of such links.

Upvotes: 1

ScottTx
ScottTx

Reputation: 1483

using System.Management;

string logDisk= "c:";
string CIMObject = String.Format("win32_LogicalDisk.DeviceId='{0}'", logDisk);
using(ManagementObject mo = new ManagementObject(CIMObject))
{
    mo.Get();
    Console.WriteLine(mo["FileSystem"]);
}

Upvotes: 0

Gromer
Gromer

Reputation: 9931

You want to look into the DriveInfo class. Something like:

var drive = DriveInfo.GetDrives().SingleOrDefault(di => di.Name.StartsWith("C"));
Console.WriteLine("C drive: {0}", drive.DriveFormat);

drive.DriveFormat will output the format, so you can check to see if it's NTFS.

Upvotes: 1

Justin Helgerson
Justin Helgerson

Reputation: 25521

//Get all the drives on the local machine.
DriveInfo[] allDrives = DriveInfo.GetDrives();

//Get the path root.
var pathRoot = Path.GetPathRoot(absoluteFilePath);
//Find the drive based on the path root.
var driveBasedOnPath = allDrives.FirstOrDefault(d => d.RootDirectory.Name == pathRoot);
//Determine if NTFS  
var isNTFS = driveBasedOnPath != null ? driveBasedOnPath.DriveFormat == "NTFS" : false;

Upvotes: 3

Related Questions