argcv
argcv

Reputation: 51

Windows API, C++: Is there a way to create a HANDLE to redirect output to a string using WriteFile()?

I have Base64 encoded data in the form of const void*. When I write the data to a file using the WriteFile() function, the data gets written in a correct format. However, when I try to print it by using std::cout (directly, or after typecasting it to char*), the format is different/undesired. So, I changed the HANDLE passed to the WriteFile() to print correct output to the console and it worked.

Is there any way to keep/redirect the equivalent data in a string(or char array)? I tried searching for a HANDLE to write the output to a string variable using the WriteFile(), but have been unsuccessful so far. Here's the code:

    void Write(const void* data, int size)
    {

        /* filePath is a local variable here */
        HANDLE mFile = CreateFileA(filePath, FILE_APPEND_DATA, 0, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
        if ((mFile != NULL) && (size > 0))
        {
            std:: cout << data;                         // incorrect/undesired output
            char* stringData = (char *)data;
            std::cout << stringData;                    // incorrect/undesired output
            DWORD bytesWritten = 0;
            /* Writes output to the file */
            WriteFile(mFile, data, static_cast<DWORD>(size), &bytesWritten, NULL);

            /* Writes output to the console */
            HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);
            WriteFile(hStdOut, data, static_cast<DWORD>(size), &bytesWritten, NULL);

        }
    }

WriteFile() function:

BOOL WINAPI WriteFile(
  _In_         HANDLE hFile,
  _In_         LPCVOID lpBuffer,
  _In_         DWORD nNumberOfBytesToWrite,
  _Out_opt_    LPDWORD lpNumberOfBytesWritten,
  _Inout_opt_  LPOVERLAPPED lpOverlapped
);

Here's the output required(base64 encoded): enter image description here

And this is the output(incorrect/undesired) when we try to print the data directly using std::cout enter image description here

Upvotes: 0

Views: 320

Answers (1)

MikeCAT
MikeCAT

Reputation: 75062

std:: cout << data;

Prints the address passed because the type of data is void* (or precisely const void*).

char* stringData = (char *)data;
std::cout << stringData;

Requires the data to write NUL-terminated.

You can use write() function to put byte streams to std::basic_ostream (including std::cout).

std::cout.write(reinterpret_cast<const char*>(data), size);

Upvotes: 2

Related Questions