How to detect Cluster Shared Volume in minifilter?

Hello.

I need to skip attach to Cluster Shared Volume (CSV). But I cannot figure out how to detect it. I looked on the parameters passed into my InstanceSetup, but I didn’t found any mark of the fact that volume belongs to CSV. And it looks like a regular NTFS volume for me:

from InstanceSetup:
Flags=0x5 // FLTFL_INSTANCE_SETUP_AUTOMATIC_ATTACHMENT|FLTFL_INSTANCE_SETUP_NEWLY_MOUNTED_VOLUME
VolumeDeviceType=0x8 // FILE_DEVICE_DISK_FILE_SYSTEM
VolumeFilesystemType=2 // FLT_FSTYPE_NTFS

from FltGetVolumeName:
VolumeName=<\Device\HarddiskVolume3>

from FltGetVolumeProperties:
DeviceType=8 // FILE_DEVICE_DISK_FILE_SYSTEM
DeviceCharacteristics=0x00000000
DeviceObjectFlags=0x00040000 // ? I didn’t found this flag
AlignmentRequirement=3
SectorSize=512
FileSystemDriverName=<\FileSystem\Ntfs>
FileSystemDeviceName=<\Ntfs>
RealDeviceName=<\Device\HarddiskVolume3>

from FltGetDeviceObject:
pDeviceObject=0xFFFFFA800FC50630

I want to ask, how to detect Cluster Shared Volume?
There is a discussion about CSV and minifilters (http://www.osronline.com/showThread.cfm?link=209672, “Cluster Shared Volume issue?”), but no info about how to detect such volumes.

Thanks for any tip.

Best regards,
Alexey Barabash

Unfortunately in Windows 2008 Server R2 there isn’t a way for a filter to detect that the underlying NTFS volume is actually for CSV.

One of the CSV devs suggested that a workaround for Win2k8R2 might be to not auto-attach to clustered disks and rely on a user-mode cluster-aware component that can detect whether the clustered disk is for CSV and have it control the attachment. This is a hack, at best, but at this time there’s not much else to do, as far as I know.

Christian [MSFT]
This posting is provided “AS IS” with no warranties, and confers no rights.

Thanks.

Best regards,
Alexey Barabash

Use this code in your InstanceSetup to detect CSV attach:

#define IOCTL_DISK_GET_CLUSTER_INFO CTL_CODE(IOCTL_DISK_BASE, 0x0085,
METHOD_BUFFERED, FILE_READ_ACCESS)
#define IOCTL_DISK_SET_CLUSTER_INFO CTL_CODE(IOCTL_DISK_BASE, 0x0086,
METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS)

typedef enum _DISK_CSV_STATE { DiskCsvUnknown, DiskCsvRedirected,
DiskCsvDirectIO } DISK_CSV_STATE, *PDISK_CSV_STATE;
typedef struct _DISK_CLUSTER_INFO {
ULONG Version; // specifies the size of the
structure for versioning.
BOOLEAN IsClustered; // indicates whether this disk is
clustered or not.
BOOLEAN IsCsv; // indicates whether this is a CSV
disk or not.
BOOLEAN InMaintenance; // indicates whether this disk is in
maintenance mode by cluster.
DISK_CSV_STATE CsvState; // indicates the Csv state of the
disk.
} DISK_CLUSTER_INFO, *PDISK_CLUSTER_INFO;

DISK_CLUSTER_INFO dci = {0};
if ( NT_SUCCESS( SendDiskIOCTL( fltObjects->Volume,
IOCTL_DISK_GET_CLUSTER_INFO, NULL, 0, &dci, sizeof( dci )))) {
if ( dci.IsCsv ) { … }
}

Where SendDiskIOCTL consists of
FltGetDiskDeviceObject/IoBuildDeviceIoControlRequest/…

Petr

Many thanks, Petr.

I tried your method, but I receive STATUS_INVALID_DEVICE_REQUEST for non-NTFS devices. And NTFS devices always cause BSOD STATUS_ACCESS_VIOLATION or it goes into __except block if I use structured exception handling. Maybe I made an error somewhere. Still searching.

Best regards,
Alexey Barabash

if you get STATUS_INVALID_DEVICE_REQUEST error, then it’s all right – it’s
not a CSV disk. CSV requires NTFS (you can check filesystem type in
InstanceSetup, but it’s not needed, use that IOCTL code instead). I tested
my code with CSV disks and it worked. Please look at callstack where exactly
you get BSOD, there must be a problem with your IOCTL sending fn.

Petr

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of xxxxx@gmail.com
Sent: Friday, January 06, 2012 6:57 PM
To: Windows File Systems Devs Interest List
Subject: RE:[ntfsd] How to detect Cluster Shared Volume in minifilter?

Many thanks, Petr.

I tried your method, but I receive STATUS_INVALID_DEVICE_REQUEST for
non-NTFS devices. And NTFS devices always cause BSOD STATUS_ACCESS_VIOLATION
or it goes into __except block if I use structured exception handling.
Maybe I made an error somewhere. Still searching.

Best regards,
Alexey Barabash


NTFSD is sponsored by OSR

For our schedule of debugging and file system seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at
http://www.osronline.com/page.cfm?name=ListServer

Part of stack:
fffff88001fa0e60 fffff8800149b0ae nt!KiPageFault+0x23a
fffff88001fa0ff0 fffff88001338bcf Ntfs!NtfsFsdDeviceControl+0x46
fffff88001fa1080 fffff880013376df fltmgr!FltpLegacyProcessingAfterPreCallbacksCompleted+0x24f
fffff88001fa1110 fffff88006882d4d fltmgr!FltpDispatch+0xcf

Failed instruction in ntfs.sys
fffff880`0149b0ae 488b4818 mov rcx,qword ptr [rax+18h]

rax=0000000000000000

I set parameter InternalDeviceIoControl of IoBuildDeviceIoControlRequest to FALSE - because I don’t need IRP_MJ_INTERNAL_DEVICE_CONTROL. But if I set it to TRUE - IoCallDriver never causes BSOD, but DISK_CLUSTER_INFO always contains only zero fields, even for CSVolume.

Best regards,
Alexey Barabash

-----Original Message-----
From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of Petr Kurtin
Sent: Friday, January 06, 2012 8:16 PM
To: Windows File Systems Devs Interest List
Subject: RE: [ntfsd] How to detect Cluster Shared Volume in minifilter?

if you get STATUS_INVALID_DEVICE_REQUEST error, then it’s all right – it’s not a CSV disk. CSV requires NTFS (you can check filesystem type in InstanceSetup, but it’s not needed, use that IOCTL code instead). I tested my code with CSV disks and it worked. Please look at callstack where exactly you get BSOD, there must be a problem with your IOCTL sending fn.

Petr

Found my mistake - I used FltGetDeviceObject instead of FltGetDiskDeviceObject, and it was completely wrong. But IoCallDriver still returns me STATUS_INVALID_DEVICE_REQUEST even for CSV.

Best regards,
Alexey Barabash

That’s because those IOCTLs aren’t implemented in Win7/W2k8R2.

One way to do it that hadn’t occurred to me before is that your filter can enumerate the instances attached to the device you’re interested in. If an instance of CsvFlt (or whatever it’s called) is there, then you’re on CSV.

It’s probably worth noting that we will be talking about how all this stuff will work in future versions of Windows at the upcoming Plugfest.

Christian [MSFT]
This posting is provided “AS IS” with no warranties, and confers no rights.

Christian, thanks. But method you suggest is not applicable for me. Because CsvFlt attaches not only to Cluster Shared Volume, but for other NTFS volumes also.

Before owning volume by cluster:
C:\>fltmc volumes
Dos Name Volume Name FileSystem Status


\Device\Mup Remote
C: \Device\HarddiskVolume2 NTFS
\Device\HarddiskVolume1 NTFS

C:\>fltmc instances
Filter Volume Name Altitude Instance Name


CSVFilter \Device\Mup 404900 CSVFilter Instance
CSVFilter C: 404900 CSVFilter Instance

*****************************************
After

C:\>fltmc volumes
Dos Name Volume Name FileSystem Status


\Device\Mup Remote
C: \Device\HarddiskVolume2 NTFS
\Device\HarddiskVolume1 NTFS
\Device\HarddiskVolume3 NTFS

C:\>fltmc instances
Filter Volume Name Altitude Instance Name


CSVFilter \Device\Mup 404900 CSVFilter Instance
CSVFilter C: 404900 CSVFilter Instance
CSVFilter 404900 CSVFilter Instance

FltEnumerateInstanceInformationByVolume invoked from my InstanceSetup says that no any instance of CSVFilter attached to \Device\HarddiskVolume3, which is used for CSV, I think because my filter has lower altitude and it receives InstanceSetup callback earlier.

So, user-mode component seems the only proper way for detection of CSV.

Thanks.

Best regards,
Alexey Barabash

Christian is correct that these IOCTLs are not implemented in Windows 2008 R2. User mode is your best bet since all the CSV volumes would be NTFS volumes underneath. No way to identify them as CSV volume in kernel mode. This might change in the next Windows though.