readfile读写磁盘扇区时偏移量超出DWORD范围怎么办

现在我正在通过createfile和readfile函数直接读磁盘扇区,OVERLAPPED结构的offset是DWORD类型,最大值为4294967295,当需要读取的扇区号大于8388607时,偏移量超出这个最大值,读取失败,请问这种情况应该如何解决呢?setfilepointer有用吗?
代码如下

//作用:打开逻辑磁盘设备
//参数:逻辑盘符  
//返回值:该逻辑磁盘的句柄  
HANDLE OpenDisk(char devName[7]) {
    HANDLE handle = CreateFile(devName, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
    if (handle == INVALID_HANDLE_VALUE)
        return 0;
    else
        return handle;
}

//作用:读磁盘的指定扇区
//参数:逻辑磁盘句柄,输出的字符串指针,起始扇区号,长度  
//返回值:读取的大小  
DWORD ReadDisk(HANDLE handle, unsigned char*& out, DWORD start, DWORD size)
{
    OVERLAPPED over = { 0 };
    over.Offset = start * 512;
    unsigned char* buffer = new unsigned char[size + 1];
    DWORD readsize;
    ReadFile(handle, buffer, size, &readsize, &over);
    buffer[size] = 0;
    out = buffer;
    return size;
}  

2个回答

分两个32DWORD存储。

需要磁盘映射文件
看看这个代码

// ****************************************************************************************************
// 文件: fs32demo\\main.cpp
// 作者: 虎胆游侠(blog.csdn.net/prsniper; cto@renshenguo.com)
// 时间: 2015-12-30 06:02:11
// 注释:
// Win32下超大文件读写演示程序, Demonstration for large file operation in win32
// ****************************************************************************************************
#include <windows.h>
#include <stdio.h>

// FS是起初想做File Splitter, 将大文件分割, 虽然只有部分数据无意义, 但对于断点续传很关键
#define FS_ARG_COUNT        5

// 用GUID作为共享内存名称避免重复
#define FS_OPEN_NAME        "Global\\LargeFileOpen{E4FCF358-8BF8-4b59-A046-CCF85620AC36}"
#define FS_SAVE_NAME        "Global\\LargeFileSave{E4FCF358-8BF8-4b59-A046-CCF85620AC36}"

// 默认的文件参数(本机调试使用)
#define FS_FILE_OPEN        "F:\\Win2003Ent.rar"
#define FS_FILE_SAVE        "F:\\Win2003Ent.rar.bak"
#define FS_FILE_SIZE        8316302716
#define FS_FILE_BYTE        0x10000000      // 256 MB (268435456)

// 进程退出代码
#define FS_ERROR_SUCCESS            0
#define FS_ERROR_OPEN_FILE          1
#define FS_ERROR_OPEN_MAPPING       2
#define FS_ERROR_MULTI_OPEN         3
#define FS_ERROR_SAVE_FILE          4
#define FS_ERROR_SAVE_MAPPING       5
#define FS_ERROR_MULTI_SAVE         6
#define FS_ERROR_VIEW_OPEN          7
#define FS_ERROR_VIEW_SAVE          8
#define FS_ERROR_CLOSE_FILE         9

// 类型定义
typedef unsigned __int64    QWORD;

typedef struct tagLargeFile{
    HANDLE File;
    HANDLE Mapping;
    LPBYTE Buffer;
    union {
        struct {
            DWORD Bit32;
            DWORD Bit64;
        };
        QWORD Offset;
        QWORD Length;
    };
} LARGEFILE, *PLARGEFILE;

// 入口函数, 用法: fs32demo[.exe][ inputfile outputfile filesize cachesize]
int main(int argc, char **argv)
{
    LARGEFILE lfOpen;
    LARGEFILE lfSave;

    char *szOpen;
    char *szSave;
    //QWORD nLength;    // use lfSave.Length
    DWORD dwSize;

    union {
        struct {
            DWORD dwSizeLow;
            DWORD dwSizeHigh;
        };
        QWORD nSize;    // temp var
    };
    BOOL dwRet;

    if(argc == FS_ARG_COUNT)
    {
        // 处理运行参数, 自动过滤引号: argv[0] == ...\\fs32demo.exe
        szOpen = argv[1];
        szSave = argv[2];
        lfSave.Length = _atoi64(argv[3]);   // 文件大小
        dwSize = atoi(argv[4]);             // 不应超过2GB, 且小于文件大小
    }else
    {
        szOpen = FS_FILE_OPEN;
        szSave = FS_FILE_SAVE;
        lfSave.Length = FS_FILE_SIZE;
        dwSize = FS_FILE_BYTE;
    }
    // 输出参数信息
    printf(" Input file: %s\r\n", szOpen);
    printf("Output file: %s\r\n", szSave);
    printf("  File size: 0x%I64X (%I64d bytes)\r\n", lfSave.Length, lfSave.Length);
    printf(" Cache size: 0x%08X (%d bytes)\r\n", dwSize, dwSize);
    printf("Press any key to fuck: \r\n");
    getchar();  // 任意键继续

    lfOpen.File = CreateFile(szOpen,        // file to fuck with
        GENERIC_READ,                       // 只读打开
        FILE_SHARE_READ,                    // 共享读取
        NULL,                               // &sa(默认不能继承)
        OPEN_EXISTING,                      // CREATE_ALWAYS
        FILE_ATTRIBUTE_NORMAL,
        NULL);
    if(lfOpen.File == INVALID_HANDLE_VALUE)
    {
        return FS_ERROR_OPEN_FILE;
    }

    lfOpen.Mapping = CreateFileMapping(lfOpen.File,
        NULL,               // &sa
        PAGE_READONLY,      // 只读共享内存
        0,                  // 高双字
        0,                  // 低双字, 自动使用文件大小
        FS_OPEN_NAME);
    if(lfOpen.Mapping == NULL)
    {
        CloseHandle(lfOpen.File);   // system holds the corresponding file open until the last view of the file is unmapped.
        //lfOpen.File = NULL;
        return FS_ERROR_OPEN_MAPPING;
    }
    if(GetLastError() == ERROR_ALREADY_EXISTS)
    {
        // FS_ERROR_MULTI_OPEN, Proceed..
    }

    lfSave.File = CreateFile(szSave,        // file to fuck with
        GENERIC_READ | GENERIC_WRITE,       // 读写打开
        FILE_SHARE_READ,                    // 共享读取(不共享写入)
        NULL,                               // &sa(默认不能继承)
        CREATE_ALWAYS,                      // OPEN_EXISTING
        FILE_ATTRIBUTE_NORMAL,
        NULL);
    if(lfSave.File == INVALID_HANDLE_VALUE)
    {
        CloseHandle(lfOpen.Mapping);
        CloseHandle(lfOpen.File);
        return FS_ERROR_SAVE_FILE;
    }

    //lfSave.Offset = lfSave.Length;        
    lfSave.Mapping = CreateFileMapping(lfSave.File,
        NULL,                       // &sa
        PAGE_READWRITE,             // 读写共享内存
        lfSave.Bit64,               // 高双字
        lfSave.Bit32,               // 低双字
        FS_SAVE_NAME);
    if(lfSave.Mapping == NULL)
    {
        CloseHandle(lfSave.File);
        CloseHandle(lfOpen.Mapping);
        CloseHandle(lfOpen.File);
        return FS_ERROR_SAVE_MAPPING;
    }
    if(GetLastError() == ERROR_ALREADY_EXISTS)
    {
        CloseHandle(lfSave.Mapping);
        CloseHandle(lfSave.File);
        CloseHandle(lfOpen.Mapping);
        CloseHandle(lfOpen.File);
        return FS_ERROR_MULTI_SAVE;
    }

    dwRet = FS_ERROR_SUCCESS;   // 默认成功
    lfOpen.Offset = 0;
    while(lfOpen.Offset < lfSave.Length)
    {
        nSize = lfSave.Length - lfOpen.Offset;
        if(nSize > dwSize)
        {
            nSize = dwSize;
        }
        // 映射
        lfOpen.Buffer = (LPBYTE)MapViewOfFile(lfOpen.Mapping, FILE_MAP_READ, lfOpen.Bit64, lfOpen.Bit32, dwSizeLow);
        if(lfOpen.Buffer == NULL)
        {
            dwRet = FS_ERROR_VIEW_OPEN;
            break;
        }
        lfSave.Buffer = (LPBYTE)MapViewOfFile(lfSave.Mapping, FILE_MAP_ALL_ACCESS, lfOpen.Bit64, lfOpen.Bit32, dwSizeLow);
        if(lfOpen.Buffer == NULL)
        {
            UnmapViewOfFile(lfSave.Buffer);
            dwRet = FS_ERROR_VIEW_SAVE;
            break;
        }
        // memcpy & unmap
        printf("Offset: 0x%I64X, Size: 0x%08X; (%d bytes from %I64d)\r\n", lfOpen.Offset, dwSizeLow, dwSizeLow, lfOpen.Offset);
        CopyMemory(lfSave.Buffer, lfOpen.Buffer, dwSizeLow);
        UnmapViewOfFile(lfSave.Buffer);
        UnmapViewOfFile(lfOpen.Buffer);
        // next
        lfOpen.Offset += FS_FILE_BYTE;
    }

    CloseHandle(lfSave.Mapping);
    CloseHandle(lfSave.File);
    CloseHandle(lfOpen.Mapping);
    if(CloseHandle(lfOpen.File) == FALSE)
    {
        return FS_ERROR_CLOSE_FILE; // ...
    }
    return dwRet;
}

立即提问