“ReadFile Function” is there a way that I can no l

2019-07-25 20:53发布

问题:

I'm trying to make a program using windows API in C++ The goal is to read the content of the text file that I've created and able to manipulate the content using bitwise XOR (change to lowercase and uppercase, vice versa) then put the manipulated content again inside of a text file. Here the flow of the program that I've used:

  1. Open text file using CreateFile.
  2. Put the content of the text file on a created malloc.
  3. Manipulate the content of the text file using bitwise XOR (xor = 20).
  4. Then put the xor value to the text file again.

Here's the code:

#include "pch.h"
#include <iostream>
#include <windows.h>
using namespace std;

int main()
{
    HANDLE openFile;
    HANDLE ovewriFile;
    BOOL readwriFile;
    DWORD dwNoByteRead = 0;
    DWORD dwNoByteWritten = 0;
    char *strVal;
    //allocate memory
    strVal = (char*)malloc(sizeof(strVal));
    memset(strVal, '0x00', sizeof(strVal));

    //open a file
    openFile = CreateFile(L"C:\\Users\\John.Doe\\Documents\\test.txt", GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
    //reading the content
    readwriFile = ReadFile(openFile, strVal, 34, &dwNoByteRead, NULL);
    cout << "original content is " << strVal << endl;

    CloseHandle(openFile);

    //manipulate data using xor
    for (int i = 0; i != strlen(strVal); i++) {
        if (strVal[i] == 0x20)
        {
            continue;
        }
        strVal[i] ^= 0x20;
    }
    cout << "xor value: " << strVal << endl;

    //overwrite a file
    ovewriFile = CreateFile(L"C:\\Users\\farrel.moje\\Documents\\test.txt", GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
    //write the content
    readwriFile = WriteFile(ovewriFile, strVal, 34, &dwNoByteWritten, NULL);

    //just a way to know if successful yung writefile
    if (readwriFile == FALSE) {

        cout << "ERROR WRITING " << GetLastError() << endl;
    }
    else {
        cout << "Success Overwrite " << endl;
    }
    cout << "Modified content " << strVal << endl;

    CloseHandle(ovewriFile);
    free(strVal);

    return 0;
}

This program is working but when I tried to change the nNumberOfBytesToRead (The maximum number of bytes to be read) from 34 to sizeof(strVal) or strlen(strVal)

readwriFile = ReadFile(openFile, strVal, 34, &dwNoByteRead, NULL);

but using sizeof and strlen, it didn't show the full content of the text file. Is there a way that I can no longer declare specific number of bytes to be read?

Thanks in advance!

回答1:

Remove yours

strVal = (char*)malloc(sizeof(strVal));
memset(strVal, '0x00', sizeof(strVal));

because it's a bad idea.

Change some code to get size of your file:

openFile = CreateFile(L"C:\\Users\\John.Doe\\Documents\\test.txt", GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);

LARGE_INTEGER fs;
GetFileSizeEx(openFile, &fs);
unsigned long long fSize = fs.QuadPart;
strVal = new char[fSize+1];
memset(strVal, 0, fSize+1);

//reading the content
readwriFile = ReadFile(openFile, strVal, fSize, &dwNoByteRead, NULL)

And at the end don't forget to

delete []strVal;

instead of yours free(strVal)



回答2:

You can use the API GetFileSizeEx() to get the File size first. Also, sizeof(point) always return 4/8 because it's the size of this point, but not the size you want allocate. Add and change your code like below:

LARGE_INTEGER liFileSize;
//open a file
openFile = CreateFile(L"C:\\Users\\John.Doe\\Documents\\test.txt", GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
GetFileSizeEx(openFile, &liFileSize);
//allocate memory
strVal = (char*)malloc(liFileSize.QuadPart);
memset(strVal, 0, liFileSize.QuadPart);

Then You can use "liFileSize.QuadPart" to replace the "nNumberOfBytesToRead"(34)