无法按顺序处理文件> 250kb使用Windows文件映射与n大小的块

时间:2018-05-22 10:36:05

标签: c windows winapi memory-mapped-files

我正在尝试制作一个带有txt文件的软件,xor每4字节带有一个预定义的数字。
我正在这个映射文件在内存中并使用大小为n的MapViewOfFile打开文件的块 I&#m;附着算法适用于小于250 kb的txt文件。但对于文件> 250kb它只是文件的某些部分,我无法理解为什么以及如何解决这个问题 有人能帮我吗?

#include "stdafx.h"
#include "Windows.h"
#include <stdio.h>
#include <stdint.h>
#include <iso646.h>
#include <math.h>

unsigned int strToUl(char *s)
{
    int size = 4;
    unsigned int ul = 0;
    memcpy(&ul, (unsigned int *)s, size);
    return ul;
}

char *ulToStr(unsigned int *ul)
{
    int size = 4;
    char *tch = (char *)calloc(size, sizeof(char *));
    memcpy(tch, (char *)ul, size);
    return tch;
}

unsigned int uixor(unsigned int n, unsigned int seed)
{
    srand(seed);
    unsigned int mask = rand();
    char ch[5] = { 0 };
    strcpy_s(ch, 5, ulToStr(&n));
    for (int j = 0; j < 5; j++)
    {
        ch[j] = ch[j] ^ mask;
    }
    return strToUl(ch);
}

BOOL mapWriteChunk(PHANDLE phFile, DWORD dwFileSize, int start, int buffsize, uint32_t xork)
{
    DWORD offset = start;// / 4;// / sizeof(DWORD);
    SYSTEM_INFO SysInfo;
    GetSystemInfo(&SysInfo);
    DWORD dwSysGran = SysInfo.dwAllocationGranularity;
    DWORD dwFileMapStart = (offset/dwSysGran) * dwSysGran;
    DWORD dwMapViewSize = (offset % dwSysGran) + buffsize;
    DWORD dwFileMapSize = offset + buffsize;

    unsigned int *ulMVBuffer = (unsigned int *)MapViewOfFile(*phFile, FILE_MAP_ALL_ACCESS, 0, dwFileMapStart, 0);
    if (ulMVBuffer == NULL)
    {
        printf("ulMVBuffer = NULL\n");
    }

    int iViewDelta = offset - dwFileMapStart;

    for (int i = 0; i < buffsize; i++)
    {
        unsigned int *u = (unsigned int *)ulMVBuffer + (iViewDelta + i);
        unsigned int u1 = *u;
        unsigned int u2 = uixor(u1, xork);
        *u = u2;
        printf("write on %d -> ", iViewDelta);
    }

    UnmapViewOfFile(ulMVBuffer);

    return TRUE;
}

int main()
{
    char name[] = "test.txt";

    OFSTRUCT tOfStrIn;
    tOfStrIn.cBytes = sizeof tOfStrIn;
    HANDLE hFile = (HANDLE)OpenFile(name, &tOfStrIn, OF_READWRITE);
    DWORD dwFileSize = GetFileSize(hFile, NULL);

    HANDLE hFileMap = CreateFileMapping(hFile, NULL, PAGE_READWRITE, 0, dwFileSize, NULL);
    if (hFileMap == NULL)
    {
        printf("hFileMap = NULL\n");
    }


    int pos = 0;
    int chunk = 4;
    int bSize = dwFileSize / sizeof(DWORD);
    int rseed = 10;

    for (pos = 0; pos < bSize; pos+=chunk)
    {
        mapWriteChunk(&hFileMap, dwFileSize, pos, chunk, rseed);
    }

    CloseHandle(hFile);
    CloseHandle(hFileMap);
    system("PAUSE");
    return 0;
}

1 个答案:

答案 0 :(得分:0)

好的,我想出了问题,我在这里写,所以任何有同样问题的人都知道错了。 谈话很便宜,我告诉你代码(然后我会解释):

char *ulMVBuffer = (char *)MapViewOfFile(phFile, FILE_MAP_ALL_ACCESS, 0, dwFileMapStart, 0);
if (ulMVBuffer == NULL)
{
    printf("ulMVBuffer = NULL\n");
}

int iViewDelta = offset - dwFileMapStart;

unsigned int mask = myrand(xork);
for(int i = 0; i < buffsize; i++)
{
    unsigned int c = ulMVBuffer[iViewDelta + i] ^ mask;
    ulMVBuffer[iViewDelta + i] = c;
}

所以你必须使用char指针映射内存然后,当你像这样使用XOR运算符时:

unsigned int c = ulMVBuffer[iViewDelta + i] ^ mask;

你获得的XOR应用于一组4个字节,而不仅仅是1个字节,因为 - 据我所知,在一个char(1个字节)和一个unsigned int(4个字节)之间的XOR强制操作员从内存中选取3个字节,并将其用于按位操作。 这不能使用指向unsigned int的指针,因为我想,它以不同的方式存储来自内存的字节(可能是OS或机器相关的?),所以你能够每4个XOR只有1个字节,而不是组共有4个字节。

如果有人对此有更好的了解或想要在此解决方案中添加更多内容,我将非常乐意阅读它!