boywhp
驱动中牛
驱动中牛
  • 注册日期2007-08-09
  • 最后登录2015-04-24
  • 粉丝2
  • 关注0
  • 积分1105分
  • 威望515点
  • 贡献值0点
  • 好评度254点
  • 原创分1分
  • 专家分0分
阅读:1234回复:5

为什么我挂载C盘成功,但是却收不到IRP_MJ_DIRECTORY_CONTRO呢?L

楼主#
更多 发布于:2007-08-24 16:06
#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));
    }
}
boywhp
驱动中牛
驱动中牛
  • 注册日期2007-08-09
  • 最后登录2015-04-24
  • 粉丝2
  • 关注0
  • 积分1105分
  • 威望515点
  • 贡献值0点
  • 好评度254点
  • 原创分1分
  • 专家分0分
沙发#
发布于:2007-08-24 16:11
我在虚拟机中DebugViewer显示
0 0.00000000  Disk Found OK!
1 0.00294618  The AttachedDevice Name is:\Device\HarddiskVolume1

但我在C盘打开目录就是没有任何输出啊,到底是哪里没有搞好啊????
boywhp
驱动中牛
驱动中牛
  • 注册日期2007-08-09
  • 最后登录2015-04-24
  • 粉丝2
  • 关注0
  • 积分1105分
  • 威望515点
  • 贡献值0点
  • 好评度254点
  • 原创分1分
  • 专家分0分
板凳#
发布于:2007-08-24 16:24
我的思路是
首先根据c盘的名称得到其设备,
然后用AttachDeviceToDeviceStack附载在该设备上,
然后处理Dirver的MJ_DIRECTORY_CONTROL,关键就是什么也没有啊,郁闷~~~,哪个N人点拨一下
boywhp
驱动中牛
驱动中牛
  • 注册日期2007-08-09
  • 最后登录2015-04-24
  • 粉丝2
  • 关注0
  • 积分1105分
  • 威望515点
  • 贡献值0点
  • 好评度254点
  • 原创分1分
  • 专家分0分
地板#
发布于:2007-08-25 07:32
哪个大哥给帮忙看看啊
yaolixing
驱动小牛
驱动小牛
  • 注册日期2006-06-27
  • 最后登录2010-07-15
  • 粉丝1
  • 关注0
  • 积分991分
  • 威望135点
  • 贡献值0点
  • 好评度124点
  • 原创分0分
  • 专家分0分
地下室#
发布于:2007-10-28 00:45
Re:为什么我挂载C盘成功,但是却收不到IRP_MJ_DIRECTORY_CONTRO呢?
首先应该挂接文件系统,然后再挂接目录或盘符,参考sfilter->SfFsNotification()
flydragon_qian
驱动牛犊
驱动牛犊
  • 注册日期2007-09-01
  • 最后登录2008-06-29
  • 粉丝0
  • 关注0
  • 积分150分
  • 威望17点
  • 贡献值0点
  • 好评度16点
  • 原创分0分
  • 专家分0分
5楼#
发布于:2007-11-12 23:44
我的卷加载了,可是驱动层取不到卷信息,郁闷
游客

返回顶部