阅读:1233回复:5
为什么我挂载C盘成功,但是却收不到IRP_MJ_DIRECTORY_CONTRO呢?L
#include <ntddk.h>
//设备扩展定义 typedef struct _DEVICE_EXTENSION { PDEVICE_OBJECT AttachedToDevice; //绑定的设备 PDEVICE_OBJECT PhysicDevice; //实际的设备 UNICODE_STRING DeviceName; //设备名称 WCHAR DeviceNameBuffer[512]; } DEVICE_EXTENSION, *PDEVICE_EXTENSION; NTSTATUS SfPassThrough( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp); VOID SfGetObjectName( IN PVOID Object, IN OUT PUNICODE_STRING Name); BOOLEAN IS_MY_DEVICE_OBJECT( IN PDEVICE_OBJECT DeviceObject); BOOLEAN AttachToDiskDevice( IN PUNICODE_STRING pDiskName, OUT PDEVICE_OBJECT *pOurDevice); BOOLEAN AttachDeviceToDeviceStack( IN PDEVICE_OBJECT DstDevice, IN PDEVICE_OBJECT OurDevice); PDEVICE_OBJECT g_CDO; //全局控制设备 VOID DriverUnload( IN PDRIVER_OBJECT DriverObject); NTSTATUS FsDirectoryControl( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp); //申明未存档的API函数 NTSYSAPI NTSTATUS ObQueryNameString( IN PVOID Object, OUT POBJECT_NAME_INFORMATION ObjectNameInfo, IN ULONG Length, OUT PULONG ReturnLength ); NTSYSAPI NTSTATUS ObReferenceObjectByName( IN PUNICODE_STRING ObjectPath, IN ULONG Attributes, IN PACCESS_STATE PassedAccessState OPTIONAL, IN ACCESS_MASK DesiredAccess OPTIONAL, IN POBJECT_TYPE ObjectType, IN KPROCESSOR_MODE AccessMode, IN OUT PVOID ParseContext OPTIONAL, OUT PVOID *ObjectPtr); NTSYSAPI VOID RtlInitEmptyUnicodeString( IN OUT PUNICODE_STRING DestinationString, IN PCWSTR Buffer, IN USHORT BufferSize); //驱动主入口函数 NTSTATUS DriverEntry( IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath) { int i; NTSTATUS status; UNICODE_STRING nameString; PDEVICE_OBJECT FilterDevice; //首先创建一个CDO RtlInitUnicodeString(&nameString, L"\\FileSystem\\SFilter"); status = IoCreateDevice( DriverObject, 0, &nameString, FILE_DEVICE_DISK_FILE_SYSTEM, FILE_DEVICE_SECURE_OPEN, FALSE, &g_CDO ); if (!NT_SUCCESS(status)) { KdPrint(("DriverEntry:Error Create cdo, status = %08x\n", status)); return status; } //安装分发函数 for (i=0; i<=IRP_MJ_MAXIMUM_FUNCTION; i++) { DriverObject->MajorFunction = SfPassThrough; } DriverObject->MajorFunction[IRP_MJ_DIRECTORY_CONTROL] = FsDirectoryControl; DriverObject->DriverUnload = DriverUnload; //准备绑定C:\的设备 RtlInitUnicodeString(&nameString, L"\\??\\C:"); if (!AttachToDiskDevice(&nameString, &FilterDevice)) { KdPrint(("DrierEntry Failed..\n")); IoDeleteDevice(FilterDevice); return STATUS_DEVICE_CONFIGURATION_ERROR; } return status;//STATUS_DEVICE_CONFIGURATION_ERROR; } VOID DriverUnload(IN PDRIVER_OBJECT DriverObject) { //卸载资源 PDEVICE_OBJECT DO = DriverObject->DeviceObject; PDEVICE_OBJECT NextDO = NULL; UNICODE_STRING DeviceName; WCHAR NameBuffer[512]; DeviceName.Length = 0; DeviceName.MaximumLength = sizeof(NameBuffer); DeviceName.Buffer = NameBuffer; if (DriverObject) { do { SfGetObjectName(DO, &DeviceName); KdPrint (("Unload %wZ Device...\n", &DeviceName)); NextDO = DO->NextDevice; IoDeleteDevice(DO); DO = NextDO; } while(DO); } } NTSTATUS FsDirectoryControl(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) { NTSTATUS status; PIO_STACK_LOCATION irpSp = IoGetCurrentIrpStackLocation(Irp); //当前Irp(IO_STACK_LOCATION)的参数 //UNICODE_STRING path; ASSERT(IS_MY_DEVICE_OBJECT(DeviceObject)); if (IRP_MN_QUERY_DIRECTORY == irpSp->MinorFunction) { //Irp->UserBuffer; KdPrint(("QUERY_DIRECTORY: %s\n", Irp->UserBuffer)); } else { KdPrint(("FsDirectoryControl: ...\n")); } IoSkipCurrentIrpStackLocation(Irp); status = IoCallDriver( ((PDEVICE_EXTENSION)DeviceObject->DeviceExtension)->AttachedToDevice, Irp); return status; } BOOLEAN IS_MY_DEVICE_OBJECT(PDEVICE_OBJECT DeviceObject) { return DeviceObject->DriverObject == g_CDO->DriverObject; } BOOLEAN AttachToDiskDevice(IN PUNICODE_STRING pDiskName, OUT PDEVICE_OBJECT *pOurDevice) { NTSTATUS status; PFILE_OBJECT file = NULL; PDEVICE_OBJECT DiskDeviceObject; status = IoGetDeviceObjectPointer( pDiskName, FILE_READ_ATTRIBUTES, &file, &DiskDeviceObject); if (!NT_SUCCESS(status)) { KdPrint (("Error To Get Disk Device,status = %08x\n", status)); return FALSE; } else { KdPrint(("Disk Found OK!\n")); } //准备创建设备挂载到该设备 status = IoCreateDevice( g_CDO->DriverObject, sizeof(DEVICE_EXTENSION), NULL, DiskDeviceObject->DeviceType, FILE_DEVICE_SECURE_OPEN, FALSE, pOurDevice ); if (!NT_SUCCESS(status)) { KdPrint(("AttachToDiskDevice CreateDevice Error:status = %08x", status)); return FALSE; } return AttachDeviceToDeviceStack(DiskDeviceObject, *pOurDevice); } BOOLEAN AttachDeviceToDeviceStack(IN PDEVICE_OBJECT DstDevice, IN PDEVICE_OBJECT OurDevice) { //将一个设备挂载到设备栈 //记录我们的设备扩展数据 PDEVICE_EXTENSION DevEx = OurDevice->DeviceExtension; DevEx->DeviceName.Length = 0; DevEx->DeviceName.MaximumLength = sizeof(DevEx->DeviceNameBuffer); DevEx->DeviceName.Buffer = DevEx->DeviceNameBuffer; SfGetObjectName(DstDevice, &DevEx->DeviceName); // //IoAttachDeviceToDeviceStack 返回值是紧接着你下面的任何设备对象的地址 //返回值不一定就是AttachedDevice,参考DDK文档 DevEx->PhysicDevice = DstDevice; DevEx->AttachedToDevice = IoAttachDeviceToDeviceStack(OurDevice, DstDevice); if (NULL == DevEx->AttachedToDevice) { KdPrint(("Failded To Attached Device!\n")); return FALSE; } //上层过滤器应该复制DO_DIRECT_IO和DO_BUFFERED_IO标志 OurDevice->Flags |= DstDevice->Flags & (DO_DIRECT_IO | DO_BUFFERED_IO); OurDevice->Flags &= ~DO_DEVICE_INITIALIZING; //完成初始化 KdPrint(("The AttachedDevice Name is:%wZ", &DevEx->DeviceName)); return TRUE; } NTSTATUS SfPassThrough(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) { //不处理 ASSERT(IS_MY_DEVICE_OBJECT(DeviceObject)); IoSkipCurrentIrpStackLocation(Irp); return IoCallDriver(((PDEVICE_EXTENSION)DeviceObject->DeviceExtension)->AttachedToDevice, Irp); } VOID SfGetObjectName( IN PVOID Object, IN OUT PUNICODE_STRING Name ) { NTSTATUS status; CHAR nibuf[512]; //buffer that receives NAME information and name POBJECT_NAME_INFORMATION nameInfo = (POBJECT_NAME_INFORMATION)nibuf; ULONG retLength; status = ObQueryNameString(Object, nameInfo, sizeof(nibuf), &retLength); Name->Length = 0; if (NT_SUCCESS( status )) { RtlCopyUnicodeString(Name, &nameInfo->Name); //KdPrint(("Object %wZ,Len = %d.[%d]\n", Name, retLength, Name->Length)); } } |
|
沙发#
发布于:2007-08-24 16:11
我在虚拟机中DebugViewer显示
0 0.00000000 Disk Found OK! 1 0.00294618 The AttachedDevice Name is:\Device\HarddiskVolume1 但我在C盘打开目录就是没有任何输出啊,到底是哪里没有搞好啊???? |
|
板凳#
发布于:2007-08-24 16:24
我的思路是
首先根据c盘的名称得到其设备, 然后用AttachDeviceToDeviceStack附载在该设备上, 然后处理Dirver的MJ_DIRECTORY_CONTROL,关键就是什么也没有啊,郁闷~~~,哪个N人点拨一下 |
|
地板#
发布于:2007-08-25 07:32
哪个大哥给帮忙看看啊
|
|
地下室#
发布于:2007-10-28 00:45
Re:为什么我挂载C盘成功,但是却收不到IRP_MJ_DIRECTORY_CONTRO呢?
首先应该挂接文件系统,然后再挂接目录或盘符,参考sfilter->SfFsNotification() |
|
5楼#
发布于:2007-11-12 23:44
我的卷加载了,可是驱动层取不到卷信息,郁闷
|
|