I’m seeing error when I call FltCreateFile/Ex() function from Minifilter. I’m new to this and adding changes to Passthrough WDK example. What I would like to do is to send DeviceIOCtl(FSCTL_*) to NTFS and get data from it.
Here is the code I’m using.
++++
NTSTATUS GetNTFSVolData(
__in PCFLT_RELATED_OBJECTS FltObjects
)
{
NTSTATUS ntStatus;
ULONG dwOutputSize = 0;
// UCHAR volDataBuffer[sizeof(NTFS_VOLUME_DATA_BUFFER)];
// PNTFS_VOLUME_DATA_BUFFER pNtfsVolData = (PNTFS_VOLUME_DATA_BUFFER)volDataBuffer;
NTFS_VOLUME_DATA_BUFFER NtfsVolData;
ULONG dwInputSize = sizeof(NTFS_VOLUME_DATA_BUFFER);
ULONG dwBytesPerCluster = 0;
PFLT_FILE_NAME_INFORMATION nameInfo;
HANDLE hFile;
PFILE_OBJECT fileObject;
UNICODE_STRING fileName;
OBJECT_ATTRIBUTES objectAttributes;
IO_STATUS_BLOCK ioStatus;
DbgPrint(“Opening volume: %wZ\n”, gVolumeRoot);
// This prints “\DosDevices\E:”
InitializeObjectAttributes( &objectAttributes, &gVolumeRoot, OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE, NULL, NULL );
// ntStatus = FltCreateFileEx(gFilterHandle, FltObjects->Instance, &hFile, &fileObject, FILE_READ_ATTRIBUTES,
ntStatus = FltCreateFile(gFilterHandle, FltObjects->Instance, &hFile, FILE_READ_ATTRIBUTES,
&objectAttributes, &ioStatus, (PLARGE_INTEGER) NULL, FILE_ATTRIBUTE_NORMAL,
FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN, 0L, NULL, 0L, 0);
// ntStatus is set to 0xc000000d
// ZwCreateFile() would work.
// ntStatus = ZwCreateFile(&hFile, FILE_READ_ATTRIBUTES, &objectAttributes, &ioStatus, NULL, FILE_ATTRIBUTE_NORMAL,
// FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN, FILE_NON_DIRECTORY_FILE, NULL, 0);
ntStatus = ObReferenceObjectByHandle(hFile, FILE_READ_ATTRIBUTES, *IoFileObjectType, KernelMode, (PVOID*)&fileObject, NULL); // This would also work.
ntStatus = FltDeviceIoControlFile(FltObjects->Instance, fileObject, FSCTL_GET_NTFS_VOLUME_DATA,
(PVOID)NULL, 0, (PVOID)&NtfsVolData, dwInputSize, &dwOutputSize);
// This call to FltDeviceIoControlFile() would return ntStatus = 0xc0000002.
// FltOpenVolume() would be successful.
ntStatus = FltOpenVolume(FltObjects->Instance, &hFile, &fileObject);
if( NT_SUCCESS(ntStatus) ) {
DbgPrint(“FltOpenVolume() successful.\n”);
// But this call to FltDeviceIoControlFile() would return ntStatus = 0xc0000002.
ntStatus = FltDeviceIoControlFile(FltObjects->Instance, fileObject, FSCTL_GET_NTFS_VOLUME_DATA,
(PVOID)NULL, 0, (PVOID)&NtfsVolData, dwInputSize, &dwOutputSize);
if( NT_SUCCESS(ntStatus) )
DbgPrint(“FltDeviceIoControlFile::FSCTL_GET_NTFS_VOLUME_DATA successful.\n”);
else {
DbgPrint(“FltDeviceIoControlFile::FSCTL_GET_NTFS_VOLUME_DATA return status: 0x%x\n”, ntStatus);
// Query API would work fine.
ntStatus = FltQueryVolumeInformation(FltObjects->Instance, &ioStatus, (PVOID)&fsVolSize,
sizeof(fsVolSize), FileFsSizeInformation);
if( NT_SUCCESS(ntStatus) ) {
DbgPrint(“FltQueryVolumeInformation successful.\n”);
DbgPrint(“Cluster size: %d\n”, fsVolSize.SectorsPerAllocationUnit * fsVolSize.BytesPerSector);
}
else
DbgPrint(“FltQueryVolumeInformation return status: 0x%x\n”, ntStatus);
}
FltClose(hFile);
}
}
++++++
I’m calling the above function, GetNTFSVolData(), from Pre IRP_MJ_WRITE and PtInstanceTeardownStart() in Passthrough.sys. But same result.
I’m not sure why FltCreateFile() would fail but ZwCreateFile would work. I need to send more FSCTL to NTFS ultimately and would like to avoid sending IRP.
Any idea what I’m doing wrong.