简体   繁体   中英

C++ Windows function "LockResource()" returns half the data in the resource

I am trying to read an embedded resource from a dll, it contains an encrypted file. Reading it from LockResource() , only returns half the data.

The funny thing is that I checked SizeOfResource() and the size of the resource is what it is supposed to be.

So I tried to access the file without it being an embedded resource:

 std::ifstream enc("Logs.enc" , std::ios::binary);              // Accessing encrypted file
    std::string ciphertext = std::string((std::istreambuf_iterator<char>(enc)), std::istreambuf_iterator<char>());
    int size = ciphertext.size();   //  Returns the correct size

This worked, I tried to find something they have in common and I tried to remove the std::ios::binary and it had similar behavior to when accessing the file as a resource.

Here is my attempt to Access it as a resource:

 HGLOBAL SHEET_DATA;      // Imagine this has the encrypted file
        if (SHEET_DATA) {
            char* datac = nullptr;
            datac = (char*)LockResource(SHEET_DATA);
             std::string data = datac;
            long size_sheet = SizeofResource(dll, SHEET);  // 

            int real_size = data.size();    // Returns the wrong size
        }

I tried to search if there was anything such as a LockResource() function that accessess the data in binary mode, but I couldn't find any results.

Thank you

strlen is assuming the parameter is a zero terminated string. It counts the chars until it gets to the zero termination.

In your case it seems like the resource is binary. In this case it may contain bytes with the value 0, which strlen treats as the end of the string.

Therefore what strlen returns is irrelevant. You can use size_sheet returned from SizeofResource to know the size of the data pointed by datac .

Update: The updated question does not contain a usage of strlen anymore. But the line:

std::string data = datac;

Create a similar problem. Initializing an std::string from a char* assumes the char* is pointing to a zero terminated string. So if the buffer contains zeroes the resulting string will contain only the characters till the first zero. You can initialize the std::string the following way to avoid the assumption of the zero termination:

std::string data(datac, size_sheet); 

Giving the length of the buffer to the ctor of std::string will force initializing with the complete buffer (ignoring the zeroes).

Update2: As @IInspectable commented below, if the data is not really a string, better hold it in a more suitable container - eg std::vector<char> . It also has a constructor accepting a char* and the buffer's length.

The problem is this line:

 std::string data = datac;

This constructs a std::string from a null-terminated string. But datac is not a null-terminated string, as you said it's binary data. Instead, use the string (const char* s, size_t n); ctor overload:

 std::string data(datac, size_sheet);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM