黑客防线,在攻与防的对立统一中寻求突破!2001年创刊的黑客技术专业刊物!

设为首页
收藏本站
联系我们
网站导航

黑客论坛 - 公共交流区 - 技术交流 - 浏览 - [砖头]丢个驱动,大家帮忙看看
用户体验升级,欢迎参与!        您是本贴第 439 位浏览者 本版版主

帖子主题: [砖头]丢个驱动,大家帮忙看看

  • Fireworm
  • 等级: 金牌VIP
  • 发贴: 132 贴
  • 货币: 0 金币
  • 积分: 3145 分
  • 经验: 745 点
  • 体力: 28120 点
  • 注册: 2008-07-01
[砖头]丢个驱动,大家帮忙看看
这个驱动我曾经给过ColdZenLeft,是一个U盘文件过滤的玩意,高手略过,我就这么点水平,写的烂很正常。
  先说点题外话,过不了几天就要闪人上大学去了,这估计是8月份最后一次发贴了,不知道上了大学会遭受怎样的磨难啊(军训……)
  这个驱动是把U盘变成一个只读的存储器,U盘插入的过程就是一个枚举PDO以及加载FDO的过程,之后就是创建物理设备,过滤驱动要建立和加载只能在PDO和磁盘驱动之间进行,安装可以使用inf文件来进行。
  再多说一句,某人的C烂到一定境界了,驱动本来就不是强项,所以一直不敢投稿,怕误人子弟……这个驱动也一定有很多谬误之处,还望各位高手多指教。(还好有人一起帮忙做,要不我绝对弄不出来的)
  #include "stddcls.h"
#include "driver.h"

#include <srb.h>
#include <scsi.h>

NTSTATUS AddDevice(IN PDRIVER_OBJECT DriverObject, IN PDEVICE_OBJECT pdo);
VOID DriverUnload(IN PDRIVER_OBJECT fido);
NTSTATUS DispatchAny(IN PDEVICE_OBJECT fido, IN PIRP Irp);
NTSTATUS DispatchPower(IN PDEVICE_OBJECT fido, IN PIRP Irp);
NTSTATUS DispatchPnp(IN PDEVICE_OBJECT fido, IN PIRP Irp);
NTSTATUS DispatchWmi(IN PDEVICE_OBJECT fido, IN PIRP Irp);
ULONG GetDeviceTypeToUse(PDEVICE_OBJECT pdo);
NTSTATUS StartDeviceCompletionRoutine(PDEVICE_OBJECT fido, PIRP Irp, PDEVICE_EXTENSION pdx);
NTSTATUS UsageNotificationCompletionRoutine(PDEVICE_OBJECT fido, PIRP Irp, PDEVICE_EXTENSION pdx);

///////////////////////////////////////////////////////////////////////////////
#pragma INITCODE
extern "C" NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject,
        IN PUNICODE_STRING RegistryPath)
{                                                        
        KdPrint((DRIVERNAME " - Entering DriverEntry: DriverObject %8.8lX\n", DriverObject));
        // Initialize function pointers
        DriverObject->DriverUnload = DriverUnload;
        DriverObject->DriverExtension->AddDevice = AddDevice;
        for (int i = 0; i < arraysize(DriverObject->MajorFunction); ++i)
                DriverObject->MajorFunction[i] = DispatchAny;
        DriverObject->MajorFunction[IRP_MJ_POWER] = DispatchPower;
        DriverObject->MajorFunction[IRP_MJ_PNP] = DispatchPnp;
        DriverObject->MajorFunction[IRP_MJ_SCSI] = DispatchForSCSI;
        return STATUS_SUCCESS;
}                                                        // 驱动的入口点


///////////////////////////////////////////////////////////////////////////////
#pragma PAGEDCODE
VOID DriverUnload(IN PDRIVER_OBJECT DriverObject)
{                                                        // DriverUnload
        PAGED_CODE();
        KdPrint((DRIVERNAME " - Entering DriverUnload: DriverObject %8.8lX\n", DriverObject));
}                                                        // DriverUnload

///////////////////////////////////////////////////////////////////////////////

NTSTATUS AddDevice(IN PDRIVER_OBJECT DriverObject, IN PDEVICE_OBJECT pdo)
{                                                        // AddDevice
        PAGED_CODE();
        NTSTATUS status;

        PDEVICE_OBJECT fido;
        status = IoCreateDevice(DriverObject, sizeof(DEVICE_EXTENSION), NULL,
                GetDeviceTypeToUse(pdo), 0, FALSE, &fido);
        if (!NT_SUCCESS(status))
        {                                                // 无法建立设备对象
                KdPrint((DRIVERNAME " - IoCreateDevice failed - %X\n", status));
                return status;
        }                                                // 同上
        PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) fido->DeviceExtension;

        do
        {                                                // 初始化
                IoInitializeRemoveLock(&pdx->RemoveLock, 0, 0, 0);
                pdx->DeviceObject = fido;
                pdx->Pdo = pdo;
                //将过滤驱动附加在底层驱动之上
                PDEVICE_OBJECT fdo = IoAttachDeviceToDeviceStack(fido, pdo);
                if (!fdo)
                {                                        // 无法加载                                                                
                        KdPrint((DRIVERNAME " - IoAttachDeviceToDeviceStack failed\n"));
                        status = STATUS_DEVICE_REMOVED;
                        break;
                }                                        // 同上
                //记录底层驱动
                pdx->LowerDeviceObject = fdo;
                //由于不知道底层驱动是直接IO还是BufferIO,因此将标志都置上
                fido->Flags |= fdo->Flags & (DO_DIRECT_IO | DO_BUFFERED_IO | DO_POWER_PAGABLE);
                // Clear the "initializing" flag so that we can get IRPs
                fido->Flags &= ~DO_DEVICE_INITIALIZING;
        }        while (FALSE);                                        // 初始化
        if (!NT_SUCCESS(status))
        {                                        // need to cleanup
                if (pdx->LowerDeviceObject)
                        IoDetachDevice(pdx->LowerDeviceObject);
                IoDeleteDevice(fido);
        }                                        // need to cleanup

        return status;
}                                                        // AddDevice


///////////////////////////////////////////////////////////////////////////////
#pragma LOCKEDCODE
NTSTATUS CompleteRequest(IN PIRP Irp, IN NTSTATUS status, IN ULONG_PTR info)
{                                                        // 完成请求
        Irp->IoStatus.Status = status;
        Irp->IoStatus.Information = info;
        IoCompleteRequest(Irp, IO_NO_INCREMENT);
        return status;
}                                                        
NTSTATUS
USBSCSICompletion( IN PDEVICE_OBJECT DeviceObject,
                   IN PIRP Irp,
                   IN PVOID Context )
{
    PDEVICE_EXTENSION pdx = ( PDEVICE_EXTENSION )
                                   DeviceObject->DeviceExtension;

        IoAcquireRemoveLock(&pdx->RemoveLock,Irp);

    PIO_STACK_LOCATION irpStack = IoGetCurrentIrpStackLocation( Irp );

        PSCSI_REQUEST_BLOCK CurSrb=irpStack->Parameters.Scsi.Srb;
        PCDB cdb = (PCDB)CurSrb->Cdb;
        UCHAR opCode=cdb->CDB6GENERIC.OperationCode;

        if(opCode==SCSIOP_MODE_SENSE  && CurSrb->DataBuffer
                && CurSrb->DataTransferLength >=
                sizeof(MODE_PARAMETER_HEADER))
        {
                KdPrint(("SCSIOP_MODE_SENSE comming!\n"));

                PMODE_PARAMETER_HEADER modeData = (PMODE_PARAMETER_HEADER)CurSrb->DataBuffer;

                modeData->DeviceSpecificParameter |= MODE_DSP_WRITE_PROTECT;
        }

        if ( Irp->PendingReturned )
        {
                IoMarkIrpPending( Irp );
        }

        IoReleaseRemoveLock(&pdx->RemoveLock,Irp);

        return Irp->IoStatus.Status ;
}

#pragma LOCKEDCODE
NTSTATUS DispatchForSCSI(IN PDEVICE_OBJECT fido, IN PIRP Irp)
{
//        KdPrint((DRIVERNAME " - Enter DispatchForSCSI \n"));

        PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) fido->DeviceExtension;
        
        PIO_STACK_LOCATION irpStack = IoGetCurrentIrpStackLocation(Irp);

        // Pass request down without additional processing
        NTSTATUS status;
        status = IoAcquireRemoveLock(&pdx->RemoveLock, Irp);
        if (!NT_SUCCESS(status))
                return CompleteRequest(Irp, status, 0);

        IoCopyCurrentIrpStackLocationToNext(Irp);
        
        IoSetCompletionRoutine( Irp,
                                                        USBSCSICompletion,
                                                        NULL,
                                                        TRUE,
                                                        TRUE,
                                                        TRUE );
        status = IoCallDriver(pdx->LowerDeviceObject, Irp);
        IoReleaseRemoveLock(&pdx->RemoveLock, Irp);
        return status;
}
///////////////////////////////////////////////////////////////////////////////
#pragma LOCKEDCODE                                NTSTATUS DispatchAny(IN PDEVICE_OBJECT fido, IN PIRP Irp)
{                                                        
        PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) fido->DeviceExtension;
        PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(Irp);
#if DBG
        static char* irpname[] =
        {
                "IRP_MJ_CREATE",
                "IRP_MJ_CREATE_NAMED_PIPE",
                "IRP_MJ_CLOSE",
                "IRP_MJ_READ",
                "IRP_MJ_WRITE",
                "IRP_MJ_QUERY_INFORMATION",
                "IRP_MJ_SET_INFORMATION",
                "IRP_MJ_QUERY_EA",
                "IRP_MJ_SET_EA",
                "IRP_MJ_FLUSH_BUFFERS",
                "IRP_MJ_QUERY_VOLUME_INFORMATION",
                "IRP_MJ_SET_VOLUME_INFORMATION",
                "IRP_MJ_DIRECTORY_CONTROL",
                "IRP_MJ_FILE_SYSTEM_CONTROL",
                "IRP_MJ_DEVICE_CONTROL",
                "IRP_MJ_INTERNAL_DEVICE_CONTROL",
                "IRP_MJ_SHUTDOWN",
                "IRP_MJ_LOCK_CONTROL",
                "IRP_MJ_CLEANUP",
                "IRP_MJ_CREATE_MAILSLOT",
                "IRP_MJ_QUERY_SECURITY",
                "IRP_MJ_SET_SECURITY",
                "IRP_MJ_POWER",
                "IRP_MJ_SYSTEM_CONTROL",
                "IRP_MJ_DEVICE_CHANGE",
                "IRP_MJ_QUERY_QUOTA",
                "IRP_MJ_SET_QUOTA",
                "IRP_MJ_PNP",
        };

        UCHAR type = stack->MajorFunction;
//         if (type >= arraysize(irpname))
//                 KdPrint((DRIVERNAME " - Unknown IRP, major type %X\n", type));
//         else
//                 KdPrint((DRIVERNAME " - %s\n", irpname[type]));

#endif
        
        //传送请求而不调用额外进程
        NTSTATUS status;
        status = IoAcquireRemoveLock(&pdx->RemoveLock, Irp);
        if (!NT_SUCCESS(status))
                return CompleteRequest(Irp, status, 0);
        IoSkipCurrentIrpStackLocation(Irp);
        status = IoCallDriver(pdx->LowerDeviceObject, Irp);
        IoReleaseRemoveLock(&pdx->RemoveLock, Irp);
        return status;
}                                                        // DispatchAny


///////////////////////////////////////////////////////////////////////////////
NTSTATUS DispatchPower(IN PDEVICE_OBJECT fido, IN PIRP Irp)
{                                                        // DispatchPower
#if DBG
        PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(Irp);
        ULONG fcn = stack->MinorFunction;
        static char* fcnname[] =
        {
                "IRP_MN_WAIT_WAKE",
                "IRP_MN_POWER_SEQUENCE",
                "IRP_MN_SET_POWER",
                "IRP_MN_QUERY_POWER",
        };

        if (fcn == IRP_MN_SET_POWER || fcn == IRP_MN_QUERY_POWER)
        {
                static char* sysstate[] =
                {
                        "PowerSystemUnspecified",
                        "PowerSystemWorking",
                        "PowerSystemSleeping1",
                        "PowerSystemSleeping2",
                        "PowerSystemSleeping3",
                        "PowerSystemHibernate",
                        "PowerSystemShutdown",
                        "PowerSystemMaximum",
                };

                static char* devstate[] =
                {
                        "PowerDeviceUnspecified",
                        "PowerDeviceD0",
                        "PowerDeviceD1",
                        "PowerDeviceD2",
                        "PowerDeviceD3",
                        "PowerDeviceMaximum",
                };

                ULONG context = stack->Parameters.Power.SystemContext;
                POWER_STATE_TYPE type = stack->Parameters.Power.Type;
                KdPrint((DRIVERNAME " - IRP_MJ_POWER (%s)", fcnname[fcn]));
                if (type == SystemPowerState)
                        KdPrint((", SystemPowerState = %s\n", sysstate[stack->Parameters.Power.State.SystemState]));
                else
                        KdPrint((", DevicePowerState = %s\n", devstate[stack->Parameters.Power.State.DeviceState]));
        }
        else if (fcn < arraysize(fcnname))
                KdPrint((DRIVERNAME " - IRP_MJ_POWER (%s)\n", fcnname[fcn]));
        else
                KdPrint((DRIVERNAME " - IRP_MJ_POWER (%2.2X)\n", fcn));
#endif // DBG

        PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) fido->DeviceExtension;
        PoStartNextPowerIrp(Irp);        // 拥有IRP即输入输出请求包时才能完成
        NTSTATUS status;
        status = IoAcquireRemoveLock(&pdx->RemoveLock, Irp);
        if (!NT_SUCCESS(status))
                return CompleteRequest(Irp, status, 0);
        IoSkipCurrentIrpStackLocation(Irp);
        status = PoCallDriver(pdx->LowerDeviceObject, Irp);
        IoReleaseRemoveLock(&pdx->RemoveLock, Irp);
        return status;
}                                                        


///////////////////////////////////////////////////////////////////////////////
NTSTATUS DispatchPnp(IN PDEVICE_OBJECT fido, IN PIRP Irp)
{                                                        
        PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(Irp);
        ULONG fcn = stack->MinorFunction;
        NTSTATUS status;
        PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) fido->DeviceExtension;
        status = IoAcquireRemoveLock(&pdx->RemoveLock, Irp);
        if (!NT_SUCCESS(status))
                return CompleteRequest(Irp, status, 0);
#if DBG
        static char* pnpname[] =
        {
                "IRP_MN_START_DEVICE",
                "IRP_MN_QUERY_REMOVE_DEVICE",
                "IRP_MN_REMOVE_DEVICE",
                "IRP_MN_CANCEL_REMOVE_DEVICE",
                "IRP_MN_STOP_DEVICE",
                "IRP_MN_QUERY_STOP_DEVICE",
                "IRP_MN_CANCEL_STOP_DEVICE",
                "IRP_MN_QUERY_DEVICE_RELATIONS",
                "IRP_MN_QUERY_INTERFACE",
                "IRP_MN_QUERY_CAPABILITIES",
                "IRP_MN_QUERY_RESOURCES",
                "IRP_MN_QUERY_RESOURCE_REQUIREMENTS",
                "IRP_MN_QUERY_DEVICE_TEXT",
                "IRP_MN_FILTER_RESOURCE_REQUIREMENTS",
                "",
                "IRP_MN_READ_CONFIG",
                "IRP_MN_WRITE_CONFIG",
                "IRP_MN_EJECT",
                "IRP_MN_SET_LOCK",
                "IRP_MN_QUERY_ID",
                "IRP_MN_QUERY_PNP_DEVICE_STATE",
                "IRP_MN_QUERY_BUS_INFORMATION",
                "IRP_MN_DEVICE_USAGE_NOTIFICATION",
                "IRP_MN_SURPRISE_REMOVAL",
                "IRP_MN_QUERY_LEGACY_BUS_INFORMATION",
        };

        if (fcn < arraysize(pnpname))
                KdPrint((DRIVERNAME " - IRP_MJ_PNP (%s)\n", pnpname[fcn]));
        else
                KdPrint((DRIVERNAME " - IRP_MJ_PNP (%2.2X)\n", fcn));
#endif // DBG

        // Handle usage notification specially in order to track power pageable
        // flag correctly. We need to avoid allowing a non-pageable handler to be
        // layered on top of a pageable handler.
        if (fcn == IRP_MN_DEVICE_USAGE_NOTIFICATION)
        {                                                // 用法报告
                if (!fido->AttachedDevice || (fido->AttachedDevice->Flags & DO_POWER_PAGABLE))
                        fido->Flags |= DO_POWER_PAGABLE;
                IoCopyCurrentIrpStackLocationToNext(Irp);
                IoSetCompletionRoutine(Irp, (PIO_COMPLETION_ROUTINE) UsageNotificationCompletionRoutine,
                        (PVOID) pdx, TRUE, TRUE, TRUE);
                return IoCallDriver(pdx->LowerDeviceObject, Irp);
        }                                                

        // Handle start device specially in order to correctly inherit
        // FILE_REMOVABLE_MEDIA
        if (fcn == IRP_MN_START_DEVICE)
        {                                                //设备开始
                IoCopyCurrentIrpStackLocationToNext(Irp);
                IoSetCompletionRoutine(Irp, (PIO_COMPLETION_ROUTINE) StartDeviceCompletionRoutine,
                        (PVOID) pdx, TRUE, TRUE, TRUE);
                return IoCallDriver(pdx->LowerDeviceObject, Irp);
        }                                                

        // Handle remove device specially in order to cleanup device stack
        if (fcn == IRP_MN_REMOVE_DEVICE)
        {                                                //移除设备
                IoSkipCurrentIrpStackLocation(Irp);
                status = IoCallDriver(pdx->LowerDeviceObject, Irp);
                IoReleaseRemoveLockAndWait(&pdx->RemoveLock, Irp);
                RemoveDevice(fido);
                return status;
        }                                                

        // Simply forward any other type of PnP request
        IoSkipCurrentIrpStackLocation(Irp);
        status = IoCallDriver(pdx->LowerDeviceObject, Irp);
        IoReleaseRemoveLock(&pdx->RemoveLock, Irp);
        return status;
}                                                        

///////////////////////////////////////////////////////////////////////////////
#pragma PAGEDCODE
ULONG GetDeviceTypeToUse(PDEVICE_OBJECT pdo)
{                                                        
        PDEVICE_OBJECT ldo = IoGetAttachedDeviceReference(pdo);
        if (!ldo)
                return FILE_DEVICE_UNKNOWN;
        ULONG devtype = ldo->DeviceType;
        ObDereferenceObject(ldo);
        return devtype;
}                                                        

///////////////////////////////////////////////////////////////////////////////
#pragma PAGEDCODE
VOID RemoveDevice(IN PDEVICE_OBJECT fido)
{                                                        
        KdPrint(("Enter RemoveDevice"));
        PAGED_CODE();
        PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) fido->DeviceExtension;
        if (pdx->LowerDeviceObject)
                IoDetachDevice(pdx->LowerDeviceObject);
        IoDeleteDevice(fido);
}                                                        

///////////////////////////////////////////////////////////////////////////////
#pragma LOCKEDCODE
NTSTATUS StartDeviceCompletionRoutine(PDEVICE_OBJECT fido, PIRP Irp, PDEVICE_EXTENSION pdx)
{                                                        
        if (Irp->PendingReturned)
                IoMarkIrpPending(Irp);
                if (pdx->LowerDeviceObject->Characteristics & FILE_REMOVABLE_MEDIA)
                fido->Characteristics |= FILE_REMOVABLE_MEDIA;
        IoReleaseRemoveLock(&pdx->RemoveLock, Irp);
        return STATUS_SUCCESS;
}                                                        

///////////////////////////////////////////////////////////////////////////////
#pragma LOCKEDCODE
NTSTATUS UsageNotificationCompletionRoutine(PDEVICE_OBJECT fido, PIRP Irp, PDEVICE_EXTENSION pdx)
{                                                        
        if (Irp->PendingReturned)
                IoMarkIrpPending(Irp);
        // If lower driver cleared pageable flag, we must do the same
        if (!(pdx->LowerDeviceObject->Flags & DO_POWER_PAGABLE))
                fido->Flags &= ~DO_POWER_PAGABLE;
        IoReleaseRemoveLock(&pdx->RemoveLock, Irp);
        return STATUS_SUCCESS;
}                                                        // UsageNotificationCompletionRoutine

  这个驱动我曾经给过ColdZenLeft,是一个U盘文件过滤的玩意,高手略过,我就这么点水平,写的烂很正常。
  先说点题外话,过不了几天就要闪人上大学去了,这估计是8月份最后一次发贴了,不知道上了大学会遭受怎样的磨难啊(军训……)
  这个驱动是把U盘变成一个只读的存储器,U盘插入的过程就是一个枚举PDO以及加载FDO的过程,之后就是创建物理设备,过滤驱动要建立和加载只能在PDO和磁盘驱动之间进行,安装可以使用inf文件来进行。
  再多说一句,某人的C烂到一定境界了,驱动本来就不是强项,所以一直不敢投稿,怕误人子弟……这个驱动也一定有很多谬误之处,还望各位高手多指教。(还好有人一起帮忙做,要不我绝对弄不出来的)
  #include "stddcls.h"
#include "driver.h"

#include <srb.h>
#include <scsi.h>

NTSTATUS AddDevice(IN PDRIVER_OBJECT DriverObject, IN PDEVICE_OBJECT pdo);
VOID DriverUnload(IN PDRIVER_OBJECT fido);
NTSTATUS DispatchAny(IN PDEVICE_OBJECT fido, IN PIRP Irp);
NTSTATUS DispatchPower(IN PDEVICE_OBJECT fido, IN PIRP Irp);
NTSTATUS DispatchPnp(IN PDEVICE_OBJECT fido, IN PIRP Irp);
NTSTATUS DispatchWmi(IN PDEVICE_OBJECT fido, IN PIRP Irp);
ULONG GetDeviceTypeToUse(PDEVICE_OBJECT pdo);
NTSTATUS StartDeviceCompletionRoutine(PDEVICE_OBJECT fido, PIRP Irp, PDEVICE_EXTENSION pdx);
NTSTATUS UsageNotificationCompletionRoutine(PDEVICE_OBJECT fido, PIRP Irp, PDEVICE_EXTENSION pdx);

///////////////////////////////////////////////////////////////////////////////
#pragma INITCODE
extern "C" NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject,
        IN PUNICODE_STRING RegistryPath)
{                                                        
        KdPrint((DRIVERNAME " - Entering DriverEntry: DriverObject %8.8lX\n", DriverObject));
        // Initialize function pointers
        DriverObject->DriverUnload = DriverUnload;
        DriverObject->DriverExtension->AddDevice = AddDevice;
        for (int i = 0; i < arraysize(DriverObject->MajorFunction); ++i)
                DriverObject->MajorFunction[i] = DispatchAny;
        DriverObject->MajorFunction[IRP_MJ_POWER] = DispatchPower;
        DriverObject->MajorFunction[IRP_MJ_PNP] = DispatchPnp;
        DriverObject->MajorFunction[IRP_MJ_SCSI] = DispatchForSCSI;
        return STATUS_SUCCESS;
}                                                        // 驱动的入口点


///////////////////////////////////////////////////////////////////////////////
#pragma PAGEDCODE
VOID DriverUnload(IN PDRIVER_OBJECT DriverObject)
{                                                        // DriverUnload
        PAGED_CODE();
        KdPrint((DRIVERNAME " - Entering DriverUnload: DriverObject %8.8lX\n", DriverObject));
}                                                        // DriverUnload

///////////////////////////////////////////////////////////////////////////////

NTSTATUS AddDevice(IN PDRIVER_OBJECT DriverObject, IN PDEVICE_OBJECT pdo)
{                                                        // AddDevice
        PAGED_CODE();
        NTSTATUS status;

        PDEVICE_OBJECT fido;
        status = IoCreateDevice(DriverObject, sizeof(DEVICE_EXTENSION), NULL,
                GetDeviceTypeToUse(pdo), 0, FALSE, &fido);
        if (!NT_SUCCESS(status))
        {                                                // 无法建立设备对象
                KdPrint((DRIVERNAME " - IoCreateDevice failed - %X\n", status));
                return status;
        }                                                // 同上
        PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) fido->DeviceExtension;

        do
        {                                                // 初始化
                IoInitializeRemoveLock(&pdx->RemoveLock, 0, 0, 0);
                pdx->DeviceObject = fido;
                pdx->Pdo = pdo;
                //将过滤驱动附加在底层驱动之上
                PDEVICE_OBJECT fdo = IoAttachDeviceToDeviceStack(fido, pdo);
                if (!fdo)
                {                                        // 无法加载                                                                
                        KdPrint((DRIVERNAME " - IoAttachDeviceToDeviceStack failed\n"));
                        status = STATUS_DEVICE_REMOVED;
                        break;
                }                                        // 同上
                //记录底层驱动
                pdx->LowerDeviceObject = fdo;
                //由于不知道底层驱动是直接IO还是BufferIO,因此将标志都置上
                fido->Flags |= fdo->Flags & (DO_DIRECT_IO | DO_BUFFERED_IO | DO_POWER_PAGABLE);
                // Clear the "initializing" flag so that we can get IRPs
                fido->Flags &= ~DO_DEVICE_INITIALIZING;
        }        while (FALSE);                                        // 初始化
        if (!NT_SUCCESS(status))
        {                                        // need to cleanup
                if (pdx->LowerDeviceObject)
                        IoDetachDevice(pdx->LowerDeviceObject);
                IoDeleteDevice(fido);
        }                                        // need to cleanup

        return status;
}                                                        // AddDevice


///////////////////////////////////////////////////////////////////////////////
#pragma LOCKEDCODE
NTSTATUS CompleteRequest(IN PIRP Irp, IN NTSTATUS status, IN ULONG_PTR info)
{                                                        // 完成请求
        Irp->IoStatus.Status = status;
        Irp->IoStatus.Information = info;
        IoCompleteRequest(Irp, IO_NO_INCREMENT);
        return status;
}                                                        
NTSTATUS
USBSCSICompletion( IN PDEVICE_OBJECT DeviceObject,
                   IN PIRP Irp,
                   IN PVOID Context )
{
    PDEVICE_EXTENSION pdx = ( PDEVICE_EXTENSION )
                                   DeviceObject->DeviceExtension;

        IoAcquireRemoveLock(&pdx->RemoveLock,Irp);

    PIO_STACK_LOCATION irpStack = IoGetCurrentIrpStackLocation( Irp );

        PSCSI_REQUEST_BLOCK CurSrb=irpStack->Parameters.Scsi.Srb;
        PCDB cdb = (PCDB)CurSrb->Cdb;
        UCHAR opCode=cdb->CDB6GENERIC.OperationCode;

        if(opCode==SCSIOP_MODE_SENSE  && CurSrb->DataBuffer
                && CurSrb->DataTransferLength >=
                sizeof(MODE_PARAMETER_HEADER))
        {
                KdPrint(("SCSIOP_MODE_SENSE comming!\n"));

                PMODE_PARAMETER_HEADER modeData = (PMODE_PARAMETER_HEADER)CurSrb->DataBuffer;

                modeData->DeviceSpecificParameter |= MODE_DSP_WRITE_PROTECT;
        }

        if ( Irp->PendingReturned )
        {
                IoMarkIrpPending( Irp );
        }

        IoReleaseRemoveLock(&pdx->RemoveLock,Irp);

        return Irp->IoStatus.Status ;
}

#pragma LOCKEDCODE
NTSTATUS DispatchForSCSI(IN PDEVICE_OBJECT fido, IN PIRP Irp)
{
//        KdPrint((DRIVERNAME " - Enter DispatchForSCSI \n"));

        PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) fido->DeviceExtension;
        
        PIO_STACK_LOCATION irpStack = IoGetCurrentIrpStackLocation(Irp);

        // Pass request down without additional processing
        NTSTATUS status;
        status = IoAcquireRemoveLock(&pdx->RemoveLock, Irp);
        if (!NT_SUCCESS(status))
                return CompleteRequest(Irp, status, 0);

        IoCopyCurrentIrpStackLocationToNext(Irp);
        
        IoSetCompletionRoutine( Irp,
                                                        USBSCSICompletion,
                                                        NULL,
                                                        TRUE,
                                                        TRUE,
                                                        TRUE );
        status = IoCallDriver(pdx->LowerDeviceObject, Irp);
        IoReleaseRemoveLock(&pdx->RemoveLock, Irp);
        return status;
}
///////////////////////////////////////////////////////////////////////////////
#pragma LOCKEDCODE                                NTSTATUS DispatchAny(IN PDEVICE_OBJECT fido, IN PIRP Irp)
{                                                        
        PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) fido->DeviceExtension;
        PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(Irp);
#if DBG
        static char* irpname[] =
        {
                "IRP_MJ_CREATE",
                "IRP_MJ_CREATE_NAMED_PIPE",
                "IRP_MJ_CLOSE",
                "IRP_MJ_READ",
                "IRP_MJ_WRITE",
                "IRP_MJ_QUERY_INFORMATION",
                "IRP_MJ_SET_INFORMATION",
                "IRP_MJ_QUERY_EA",
                "IRP_MJ_SET_EA",
                "IRP_MJ_FLUSH_BUFFERS",
                "IRP_MJ_QUERY_VOLUME_INFORMATION",
                "IRP_MJ_SET_VOLUME_INFORMATION",
                "IRP_MJ_DIRECTORY_CONTROL",
                "IRP_MJ_FILE_SYSTEM_CONTROL",
                "IRP_MJ_DEVICE_CONTROL",
                "IRP_MJ_INTERNAL_DEVICE_CONTROL",
                "IRP_MJ_SHUTDOWN",
                "IRP_MJ_LOCK_CONTROL",
                "IRP_MJ_CLEANUP",
                "IRP_MJ_CREATE_MAILSLOT",
                "IRP_MJ_QUERY_SECURITY",
                "IRP_MJ_SET_SECURITY",
                "IRP_MJ_POWER",
                "IRP_MJ_SYSTEM_CONTROL",
                "IRP_MJ_DEVICE_CHANGE",
                "IRP_MJ_QUERY_QUOTA",
                "IRP_MJ_SET_QUOTA",
                "IRP_MJ_PNP",
        };

        UCHAR type = stack->MajorFunction;
//         if (type >= arraysize(irpname))
//                 KdPrint((DRIVERNAME " - Unknown IRP, major type %X\n", type));
//         else
//                 KdPrint((DRIVERNAME " - %s\n", irpname[type]));

#endif
        
        //传送请求而不调用额外进程
        NTSTATUS status;
        status = IoAcquireRemoveLock(&pdx->RemoveLock, Irp);
        if (!NT_SUCCESS(status))
                return CompleteRequest(Irp, status, 0);
        IoSkipCurrentIrpStackLocation(Irp);
        status = IoCallDriver(pdx->LowerDeviceObject, Irp);
        IoReleaseRemoveLock(&pdx->RemoveLock, Irp);
        return status;
}                                                        // DispatchAny


///////////////////////////////////////////////////////////////////////////////
NTSTATUS DispatchPower(IN PDEVICE_OBJECT fido, IN PIRP Irp)
{                                                        // DispatchPower
#if DBG
        PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(Irp);
        ULONG fcn = stack->MinorFunction;
        static char* fcnname[] =
        {
                "IRP_MN_WAIT_WAKE",
                "IRP_MN_POWER_SEQUENCE",
                "IRP_MN_SET_POWER",
                "IRP_MN_QUERY_POWER",
        };

        if (fcn == IRP_MN_SET_POWER || fcn == IRP_MN_QUERY_POWER)
        {
                static char* sysstate[] =
                {
                        "PowerSystemUnspecified",
                        "PowerSystemWorking",
                        "PowerSystemSleeping1",
                        "PowerSystemSleeping2",
                        "PowerSystemSleeping3",
                        "PowerSystemHibernate",
                        "PowerSystemShutdown",
                        "PowerSystemMaximum",
                };

                static char* devstate[] =
                {
                        "PowerDeviceUnspecified",
                        "PowerDeviceD0",
                        "PowerDeviceD1",
                        "PowerDeviceD2",
                        "PowerDeviceD3",
                        "PowerDeviceMaximum",
                };

                ULONG context = stack->Parameters.Power.SystemContext;
                POWER_STATE_TYPE type = stack->Parameters.Power.Type;
                KdPrint((DRIVERNAME " - IRP_MJ_POWER (%s)", fcnname[fcn]));
                if (type == SystemPowerState)
                        KdPrint((", SystemPowerState = %s\n", sysstate[stack->Parameters.Power.State.SystemState]));
                else
                        KdPrint((", DevicePowerState = %s\n", devstate[stack->Parameters.Power.State.DeviceState]));
        }
        else if (fcn < arraysize(fcnname))
                KdPrint((DRIVERNAME " - IRP_MJ_POWER (%s)\n", fcnname[fcn]));
        else
                KdPrint((DRIVERNAME " - IRP_MJ_POWER (%2.2X)\n", fcn));
#endif // DBG

        PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) fido->DeviceExtension;
        PoStartNextPowerIrp(Irp);        // 拥有IRP即输入输出请求包时才能完成
        NTSTATUS status;
        status = IoAcquireRemoveLock(&pdx->RemoveLock, Irp);
        if (!NT_SUCCESS(status))
                return CompleteRequest(Irp, status, 0);
        IoSkipCurrentIrpStackLocation(Irp);
        status = PoCallDriver(pdx->LowerDeviceObject, Irp);
        IoReleaseRemoveLock(&pdx->RemoveLock, Irp);
        return status;
}                                                        


///////////////////////////////////////////////////////////////////////////////
NTSTATUS DispatchPnp(IN PDEVICE_OBJECT fido, IN PIRP Irp)
{                                                        
        PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(Irp);
        ULONG fcn = stack->MinorFunction;
        NTSTATUS status;
        PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) fido->DeviceExtension;
        status = IoAcquireRemoveLock(&pdx->RemoveLock, Irp);
        if (!NT_SUCCESS(status))
                return CompleteRequest(Irp, status, 0);
#if DBG
        static char* pnpname[] =
        {
                "IRP_MN_START_DEVICE",
                "IRP_MN_QUERY_REMOVE_DEVICE",
                "IRP_MN_REMOVE_DEVICE",
                "IRP_MN_CANCEL_REMOVE_DEVICE",
                "IRP_MN_STOP_DEVICE",
                "IRP_MN_QUERY_STOP_DEVICE",
                "IRP_MN_CANCEL_STOP_DEVICE",
                "IRP_MN_QUERY_DEVICE_RELATIONS",
                "IRP_MN_QUERY_INTERFACE",
                "IRP_MN_QUERY_CAPABILITIES",
                "IRP_MN_QUERY_RESOURCES",
                "IRP_MN_QUERY_RESOURCE_REQUIREMENTS",
                "IRP_MN_QUERY_DEVICE_TEXT",
                "IRP_MN_FILTER_RESOURCE_REQUIREMENTS",
                "",
                "IRP_MN_READ_CONFIG",
                "IRP_MN_WRITE_CONFIG",
                "IRP_MN_EJECT",
                "IRP_MN_SET_LOCK",
                "IRP_MN_QUERY_ID",
                "IRP_MN_QUERY_PNP_DEVICE_STATE",
                "IRP_MN_QUERY_BUS_INFORMATION",
                "IRP_MN_DEVICE_USAGE_NOTIFICATION",
                "IRP_MN_SURPRISE_REMOVAL",
                "IRP_MN_QUERY_LEGACY_BUS_INFORMATION",
        };

        if (fcn < arraysize(pnpname))
                KdPrint((DRIVERNAME " - IRP_MJ_PNP (%s)\n", pnpname[fcn]));
        else
                KdPrint((DRIVERNAME " - IRP_MJ_PNP (%2.2X)\n", fcn));
#endif // DBG

        // Handle usage notification specially in order to track power pageable
        // flag correctly. We need to avoid allowing a non-pageable handler to be
        // layered on top of a pageable handler.
        if (fcn == IRP_MN_DEVICE_USAGE_NOTIFICATION)
        {                                                // 用法报告
                if (!fido->AttachedDevice || (fido->AttachedDevice->Flags & DO_POWER_PAGABLE))
                        fido->Flags |= DO_POWER_PAGABLE;
                IoCopyCurrentIrpStackLocationToNext(Irp);
                IoSetCompletionRoutine(Irp, (PIO_COMPLETION_ROUTINE) UsageNotificationCompletionRoutine,
                        (PVOID) pdx, TRUE, TRUE, TRUE);
                return IoCallDriver(pdx->LowerDeviceObject, Irp);
        }                                                

        // Handle start device specially in order to correctly inherit
        // FILE_REMOVABLE_MEDIA
        if (fcn == IRP_MN_START_DEVICE)
        {                                                //设备开始
                IoCopyCurrentIrpStackLocationToNext(Irp);
                IoSetCompletionRoutine(Irp, (PIO_COMPLETION_ROUTINE) StartDeviceCompletionRoutine,
                        (PVOID) pdx, TRUE, TRUE, TRUE);
                return IoCallDriver(pdx->LowerDeviceObject, Irp);
        }                                                

        // Handle remove device specially in order to cleanup device stack
        if (fcn == IRP_MN_REMOVE_DEVICE)
        {                                                //移除设备
                IoSkipCurrentIrpStackLocation(Irp);
                status = IoCallDriver(pdx->LowerDeviceObject, Irp);
                IoReleaseRemoveLockAndWait(&pdx->RemoveLock, Irp);
                RemoveDevice(fido);
                return status;
        }                                                

        // Simply forward any other type of PnP request
        IoSkipCurrentIrpStackLocation(Irp);
        status = IoCallDriver(pdx->LowerDeviceObject, Irp);
        IoReleaseRemoveLock(&pdx->RemoveLock, Irp);
        return status;
}                                                        

///////////////////////////////////////////////////////////////////////////////
#pragma PAGEDCODE
ULONG GetDeviceTypeToUse(PDEVICE_OBJECT pdo)
{                                                        
        PDEVICE_OBJECT ldo = IoGetAttachedDeviceReference(pdo);
        if (!ldo)
                return FILE_DEVICE_UNKNOWN;
        ULONG devtype = ldo->DeviceType;
        ObDereferenceObject(ldo);
        return devtype;
}                                                        

///////////////////////////////////////////////////////////////////////////////
#pragma PAGEDCODE
VOID RemoveDevice(IN PDEVICE_OBJECT fido)
{                                                        
        KdPrint(("Enter RemoveDevice"));
        PAGED_CODE();
        PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) fido->DeviceExtension;
        if (pdx->LowerDeviceObject)
                IoDetachDevice(pdx->LowerDeviceObject);
        IoDeleteDevice(fido);
}                                                        

///////////////////////////////////////////////////////////////////////////////
#pragma LOCKEDCODE
NTSTATUS StartDeviceCompletionRoutine(PDEVICE_OBJECT fido, PIRP Irp, PDEVICE_EXTENSION pdx)
{                                                        
        if (Irp->PendingReturned)
                IoMarkIrpPending(Irp);
                if (pdx->LowerDeviceObject->Characteristics & FILE_REMOVABLE_MEDIA)
                fido->Characteristics |= FILE_REMOVABLE_MEDIA;
        IoReleaseRemoveLock(&pdx->RemoveLock, Irp);
        return STATUS_SUCCESS;
}                                                        

///////////////////////////////////////////////////////////////////////////////
#pragma LOCKEDCODE
NTSTATUS UsageNotificationCompletionRoutine(PDEVICE_OBJECT fido, PIRP Irp, PDEVICE_EXTENSION pdx)
{                                                        
        if (Irp->PendingReturned)
                IoMarkIrpPending(Irp);
        // If lower driver cleared pageable flag, we must do the same
        if (!(pdx->LowerDeviceObject->Flags & DO_POWER_PAGABLE))
                fido->Flags &= ~DO_POWER_PAGABLE;
        IoReleaseRemoveLock(&pdx->RemoveLock, Irp);
        return STATUS_SUCCESS;
}                                                        // UsageNotificationCompletionRoutine

高考完了才发现写代码比做题更累……
2008-8-24 22:12:25
  • xfill
  • 等级: 黑客防线技术团队
  • 发贴: 150 贴
  • 货币: 0 金币
  • 积分: 1737 分
  • 经验: 1795 点
  • 体力: 9775 点
  • 注册: 2008-06-08
Re:[砖头]丢个驱动,大家帮忙看看
这个代码是一本书里的,我也看过。

通过设置只读位,实现类似SD卡写保护的效果。
今宵酒醒何处,杨柳岸晓风残月。 - 《雨霖霖》 &  晓风组 X.F.S.T
2008-8-25 0:50:36
  • Fireworm
  • 等级: 金牌VIP
  • 发贴: 132 贴
  • 货币: 0 金币
  • 积分: 3145 分
  • 经验: 745 点
  • 体力: 28120 点
  • 注册: 2008-07-01
Re:[砖头]丢个驱动,大家帮忙看看
哪本书?过几天看能不能找来看看……
倒塌,要别人帮忙,结果拿了一个现成的糊弄我……………………
RPWT
高考完了才发现写代码比做题更累……
2008-8-25 8:18:14
  • k0ma.1
  • 等级: 普通用户
  • 发贴: 3 贴
  • 货币: 0 金币
  • 积分: 15 分
  • 经验: 15 点
  • 体力: 280 点
  • 注册: 2008-08-26