首页
社区
课程
招聘
想做个硬盘克隆软件,ZwWriteFile写硬盘速度慢,折腾了我2个多星期了,大侠帮帮忙啊!
发表于: 2011-8-24 17:26 10297

想做个硬盘克隆软件,ZwWriteFile写硬盘速度慢,折腾了我2个多星期了,大侠帮帮忙啊!

2011-8-24 17:26
10297
在创建的内核线程里,最简单的循环调用ZwWriteFile写二进制数据到\\??\\PhysicalDrive1,速度大概只有硬盘速度的40%。
ZwCreateFile参数调整过N多次了,异步同步方式都用了,还是慢啊!

如果将ZwWriteFile换成ZwReadFile,测试读取硬盘数据的速度,速度能达到硬盘速度的100%。

大侠帮帮忙,有什么更快的写入方式啊?

此情况是在单一线程,仅做写数据测试得出的速度。

网上听一朋友说,ZwWriteFile在写入数据到硬盘后,会再将数据读出来进行效验,所以慢,是这样的吗?
如果是这样,有什么方法可以不效验,仅写入吗?

VOID XThreadDiskCloneWrite(PVOID Context)
{
    XDiskCloneInformation *DiskClone = (XDiskCloneInformation *)Context;
    XCopyBuffer *CopyBuffer = DiskClone->CopyBuffer;

    if (KeGetCurrentIrql() != PASSIVE_LEVEL)
    {
        DiskClone->Status = STATUS_UNSUCCESSFUL;
        PsTerminateSystemThread(STATUS_UNSUCCESSFUL);
    }

    UNICODE_STRING DiskName;
    RtlInitUnicodeString(&DiskName, DiskClone->DestinationDiskName);

    OBJECT_ATTRIBUTES ObjectAttributes;
    InitializeObjectAttributes(&ObjectAttributes, &DiskName, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, 0, NULL);

    HANDLE DiskHandle;
    IO_STATUS_BLOCK IoStatusBlock;
    NTSTATUS status = ZwCreateFile(&DiskHandle, SYNCHRONIZE | FILE_WRITE_DATA, &ObjectAttributes, &IoStatusBlock, NULL, FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_OPEN, FILE_NON_DIRECTORY_FILE | FILE_WRITE_THROUGH | FILE_NO_INTERMEDIATE_BUFFERING/* | FILE_RANDOM_ACCESS*/, NULL, 0);
    if (!NT_SUCCESS(status))
    {
        xlogError2("Failed to ZwCreateFile()", status);
        DiskClone->Status = status;
        PsTerminateSystemThread(status);
    }

    int Index = 0;
    LARGE_INTEGER TotalWriteSize = {0, 0};
    int CopyBufferNumber = sizeof(DiskClone->CopyBuffer)/sizeof(XCopyBuffer);

    xlogInfo("磁盘克隆写开始");

    ULONG TickCount = XGetTickCount();
    while (TRUE)
    {
        XCopyBuffer *CopyBuffer = (XCopyBuffer*)&DiskClone->CopyBuffer[Index];

        status = ZwWriteFile(DiskHandle, NULL, NULL, Context, &IoStatusBlock, CopyBuffer->Buffer, CopyBuffer->Length, &TotalWriteSize, NULL);
        if (!NT_SUCCESS(status))
        {
            ZwClose(DiskHandle);
            DiskClone->Status = status;
            PsTerminateSystemThread(status);
        }

        TotalWriteSize.QuadPart += CopyBuffer->Length;
        if (TotalWriteSize.QuadPart >= DiskClone->SourceDiskTotalSize.QuadPart)
        {
            xlog("磁盘克隆写完成, index: [%d], write size: [%I64u], spare time: [%d]ms\n", Index, TotalWriteSize, XGetTickCount()-TickCount);

            ZwClose(DiskHandle);
            DiskClone->Status = STATUS_SUCCESS;
            PsTerminateSystemThread(STATUS_SUCCESS);
        }
        
        ++Index;
    }
}

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

收藏
免费 0
支持
分享
最新回复 (15)
雪    币: 8835
活跃值: (2404)
能力值: ( LV12,RANK:760 )
在线值:
发帖
回帖
粉丝
2
发送SRB~~
2011-8-24 18:01
0
雪    币: 53
活跃值: (29)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
感激啊,我研究下啊!
2011-8-24 19:24
0
雪    币: 202
活跃值: (69)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
4
能不能改用多线程,讲读到的内容放在一个队列里面,记录读的位置,大小,多线程从队列中取,根据位置和大小去写。
2011-8-24 19:46
0
雪    币: 53
活跃值: (29)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
谢谢啊!

但是我的设计,本来就是多线程的,问题不在这里,仅在于写入的速度慢!

我这个克隆是针对硬盘操作的。如果多线性写入不同位置,还要增加寻道的负担,更慢啊!
2011-8-25 10:10
0
雪    币: 57
活跃值: (41)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
最快的是dma你用系统肯定效率上不去 , 或者自己直接驱动读吧  普通pio
2011-8-25 10:16
0
雪    币: 53
活跃值: (29)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
这位大哥,有什么相关资料吗?能说的稍微详细点吗?我google没找到相关的编程实现信息啊!
2011-8-25 10:31
0
雪    币: 538
活跃值: (279)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
8
我在ring3下面做过这个东西,在单线程阻塞调用的情况下速度就可以达到硬盘的极限.不知道内核是怎么样的,但是在ring3下提高速度的关键就是调整每次读取写入的大小.你自己实际测试就知道了
2011-8-25 12:23
0
雪    币: 53
活跃值: (29)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
谢谢指点啊,我试试看咯,呵呵
2011-8-26 10:27
0
雪    币: 538
活跃值: (279)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
10
速度提上去了没???
2011-8-27 21:34
0
雪    币: 304
活跃值: (507)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
11
应用层都能达到很快。。你内核达不到?只能达到40%?费解。。
参考HDSpeed。
2011-8-27 22:00
0
雪    币: 53
活跃值: (29)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
12
速度提上去了,谢谢啊!

搞了半天,就是buffer大小的原因,╮(╯▽╰)╭

其实,我有个主要被误导的原因是,当时我用64K做buffer的时候,读是满速的,所以我就没想到这个原因上去,惭愧啊!
2011-8-29 16:27
0
雪    币: 53
活跃值: (29)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
13
谢谢支持,现在找到原因是了,是buffer大小的问题!
2011-8-29 16:28
0
雪    币: 3
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
14
那么buffer大小应该多大能达到最大写入
2011-8-31 09:02
0
雪    币: 238
活跃值: (11)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
15
哈哈。楼主是牛人呀。支持了。谢谢分享
2011-9-3 00:08
0
雪    币: 120
活跃值: (160)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
16
buff申请0x80扇区大小。。我用ring3 API测试速度在62M左右。。。DMA66最高速度是66M
2011-9-3 01:50
0
游客
登录 | 注册 方可回帖
返回