首页
社区
课程
招聘
[旧帖] [原创] win7的磁盘扇区读写。。。。申请邀请码 0.00雪花
发表于: 2011-5-26 10:42 1775

[旧帖] [原创] win7的磁盘扇区读写。。。。申请邀请码 0.00雪花

2011-5-26 10:42
1775
此文原发
http://blog.csdn.net/power_YQ/archive/2011/04/28/6369580.aspx
此博客属于本人的,应该还算原创吧?

以下是win7  驱动写扇区的相关代码,win7用户模式不能直接读写部分扇区,内核模式下就没有此限制了
/*用户模式 函数
参数1 磁盘号 physicaldriveXX
参数2        扇区索引
参数3 写入字节,因为扇区是512字节,所以写入字节必须为512整数倍
*/
DWORD        WINAPI  WriteSection(DWORD dwDiskIndex,DWORD dwSectionIndex,IN PBYTE buffer,DWORD dwCount)//dwCount字节数,必须为512整数倍
{
       
        if (dwCount%512!=0)
        {
                return 0;
        }
        DWORD dwRet=0;
        BOOL bRet=FALSE;

        bRet=DeviceIoControl(gHandle,IOCTL_OLS_SET_DISK_INDEX,&dwDiskIndex,sizeof(DWORD),NULL,0,&dwRet,NULL);
        if (bRet==FALSE)
        {
                return 0;
        }
        bRet=DeviceIoControl(gHandle,IOCTL_OLS_SET_SECTION,&dwSectionIndex,sizeof(DWORD),NULL,0,&dwRet,NULL);
        if (bRet==FALSE)
        {
                //MessageBoxA(NULL,"IOCTL_OLS_SET_SECTION","IOCTL_OLS_SET_SECTION",MB_OK);
                return 0;
        }
        bRet=WriteFile(gHandle,buffer,dwCount,&dwRet,NULL);
        if (bRet==FALSE || dwRet==0)
        {
                //MessageBoxA(NULL,"IOCTL_OLS_SET_SECTION","IOCTL_OLS_SET_SECTION",MB_OK);
                return 0;
        }
       
        return dwRet;
}
以下是驱动部分的相关代码
NTSTATUS        OlsWriteSection(
                                                        IN PDEVICE_OBJECT pDO,
                                                        IN PIRP pIrp
                                                        )
{
        PIO_STACK_LOCATION    pIrpSp;
        PDEVICE_OBJECT pDev_Obj_PhyDrv=NULL;
        PFILE_OBJECT pFile_Obj=NULL;
        UNICODE_STRING uniNameString;
        PIO_STACK_LOCATION pIrpStack;
        NTSTATUS status=STATUS_SUCCESS;
        ULONG ul_mdl_length=0;
        ULONG ul_WriteLength=0;
        PVOID pAdd=NULL;
        ULONGLONG ull_Temp=0;
        WCHAR wsz_temp[64]={0};
        pIrp->IoStatus.Information = 0;
        if (g_dwWriteType!=OLS_READ_WRTIE_SECTION)
        {
                return STATUS_UNSUCCESSFUL;
        }
        pIrpStack = IoGetCurrentIrpStackLocation(pIrp);
        ul_mdl_length=MmGetMdlByteCount(pIrp->MdlAddress);
        ul_WriteLength=pIrpStack->Parameters.Write.Length;
        if (ul_mdl_length!=ul_WriteLength)
        {
                KdPrint(("ul_mdl_length!=ul_WriteLength"));
                status=STATUS_UNSUCCESSFUL;
        }
        else
        {
                KdPrint(("%s",pAdd));
                g_dwWriteType=OLS_WRITE_UNKNOWN;
                RtlStringCchPrintfW(wsz_temp,64,L"\\??\\PhysicalDrive%d",g_ulDiskIndex);//打开相关磁盘设备
                RtlInitUnicodeString(&uniNameString, wsz_temp);
                status=IoGetDeviceObjectPointer(&uniNameString,FILE_ALL_ACCESS,&pFile_Obj,&pDev_Obj_PhyDrv);
                if (status==STATUS_SUCCESS)
                {
                        //__asm int 3;
                        pIrpSp=IoGetCurrentIrpStackLocation(pIrp);
                        //写入的扇区对应字节的偏移号,Sections_To_Byte是自定义函数,将扇区转为字节,比如1扇区,那就是512个字节偏移开始写入
                        //Length就是写入字节的长度
                        //如果读的话就是pIrpSp->Parameters.Read
                        pIrpSp->Parameters.Write.ByteOffset=Sections_To_Byte(g_dwSectionIndex);
                        status=fastFsdRequest(pFile_Obj->DeviceObject,IRP_MJ_WRITE,pIrp,TRUE);
                        ObReferenceObject(pFile_Obj);
                }
                else
                {
                        pIrp->IoStatus.Status=STATUS_UNSUCCESSFUL;
                        pIrp->IoStatus.Information=0;
                }
               
        }
        //__asm int 3;
        IoCompleteRequest(pIrp, IO_NO_INCREMENT);
        return status;
}

NTSTATUS
fastFsdRequest(
                           IN PDEVICE_OBJECT DeviceObject,
                           ULONG majorFunction,
                           PIRP pIrp,
                           IN BOOLEAN Wait
                           )
{
        PIRP                irp;
        KEVENT                event;
        NTSTATUS            status;
        PIO_STACK_LOCATION pIrpSp=NULL;
        PIO_STACK_LOCATION pIrpSpCur=NULL;
        pIrpSpCur=IoGetCurrentIrpStackLocation(pIrp);
        irp=IoAllocateIrp(DeviceObject->StackSize,FALSE        );//创建写扇区IRP
        if (!irp) {
                return STATUS_INSUFFICIENT_RESOURCES;
        }
        irp->UserIosb=&pIrp->IoStatus;
        pIrpSp=IoGetNextIrpStackLocation(irp);
        pIrpSp->MajorFunction=majorFunction;
        pIrpSp->MinorFunction=IRP_MN_NORMAL;
        pIrpSp->DeviceObject =DeviceObject;
        irp->MdlAddress=pIrp->MdlAddress;
        pIrpSp->Parameters= pIrpSpCur->Parameters;
        //irp->Flags        =irp->Flags|SL_OVERRIDE_VERIFY_VOLUME;
        // win7 对直接磁盘写入进行了保护, 驱动操作需要在IRP的FLAGS加上SL_FORCE_DIRECT_WRITE标志
        if (IRP_MJ_WRITE == majorFunction)
        {
               
                pIrpSp->Flags |= SL_FORCE_DIRECT_WRITE; //这是写关键
        }
        if (Wait) {
                KeInitializeEvent(&event, NotificationEvent, FALSE);
                IoSetCompletionRoutine(irp, FltReadWriteSectorsCompletion,
                        &event, TRUE, TRUE, TRUE);
                status = IoCallDriver(DeviceObject,irp);
                if (STATUS_PENDING == status) {
                        KeWaitForSingleObject(&event, Executive, KernelMode, FALSE, NULL);
                        status = irp->IoStatus.Status;
                }
        } else {
                IoSetCompletionRoutine(irp, FltReadWriteSectorsCompletion,
                        NULL, TRUE, TRUE, TRUE);
                irp->UserIosb = NULL;
                status = IoCallDriver(DeviceObject, irp);
        }
        if (!NT_SUCCESS(status))
        {
                KdPrint(("IoCallDriver 0x%x fail 0x%x\n", majorFunction, status));
        }
        return status;
}

//完成例程
NTSTATUS
FltReadWriteSectorsCompletion(
                                                          IN PDEVICE_OBJECT DeviceObject,
                                                          IN PIRP Irp,
                                                          IN PVOID Context
                                                          )
                                                          /*++
                                                          Routine Description:
                                                          A completion routine for use when calling the lower device objects to
                                                          which our filter deviceobject is attached.
                                                          Arguments:
                                                          DeviceObject - Pointer to deviceobject
                                                          Irp        - Pointer to a PnP Irp.
                                                          Context    - NULL or PKEVENT
                                                          Return Value:
                                                          NT Status is returned.
                                                          --*/
{
        PMDL    mdl;
        UNREFERENCED_PARAMETER(DeviceObject);
        if (Irp->IoStatus.Status)
        {
                DbgPrint("!!!!!!!!!!Read Or Write HD Error Code====0x%x\n", Irp->IoStatus.Status);
        }
        if (Irp->MdlAddress)
        {
                Irp->MdlAddress=NULL;
        }
        if (Irp->PendingReturned && (Context != NULL)) {
                *Irp->UserIosb = Irp->IoStatus        ;
                KeSetEvent((PKEVENT) Context, IO_DISK_INCREMENT, FALSE);
        }
        IoFreeIrp(Irp);
        return STATUS_MORE_PROCESSING_REQUIRED;
}

[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

收藏
免费 0
支持
分享
最新回复 (5)
雪    币: 220
活跃值: (711)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
内核又是内核,人家不让进,杂办?
2011-5-26 11:05
0
雪    币: 237
活跃值: (25)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
3
光用DeviceIoControl不行吗?
驱动有必要吗?
2011-5-26 11:07
0
雪    币: 3
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
XP可以,但同样的方法 win7就不行了,所以改成驱动。
2011-5-26 11:20
0
雪    币: 29
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
win7没有管理员的权限能安装驱动么?
2011-5-26 11:44
0
雪    币: 3
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
不能,而且64位的win7 还需要驱动签名。。。
本人只是说说方法,安全和权限方面是另外回事,呵呵
所以大家不必计较实用性如何,谢谢。
2011-5-26 12:26
0
游客
登录 | 注册 方可回帖
返回
//