0

I am trying to open a file and read its content using the Win32 API:

HANDLE hFileRead = CreateFileA(FilePath,
                               GENERIC_READ,
                               0,
                               NULL,
                               OPEN_EXISTING,
                               FILE_ATTRIBUTE_NORMAL,
                               NULL);

LARGE_INTEGER fileSize = { 0 };
DWORD cbFileSize = GetFileSizeEx(hFileRead, &fileSize);

PBYTE buffer = (PBYTE)HeapAlloc(GetProcessHeap(), 0, fileSize.QuadPart);
DWORD dwBytesRead = 0;

NTSTATUS s = ReadFile(hFileRead,
                      buffer,
                      fileSize.QuadPart,
                      &dwBytesRead,
                      NULL);

std::cout << buffer << "\n"; // <<< expect to print "asdasd" but prints "asdasd"+random chars (1 or more each run)

What I want to get is the file content (.txt in this case). What I get is the content of a .txt file + some more random chars (its different for each run).

I tried to write the buffer indexed, it seems that the buffer prints more than its size (?)

What am I doing wrong?

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
B00t
  • 9
  • 3
  • 4
    Hint: when you `cout <<` a char array, how does it know how much to print? – user253751 Nov 16 '22 at 09:17
  • ok, so i add - buffer[dwBytesRead] = '\0'; now it warns me about dereferencing NULL pointer 'buffer' @user253751 – B00t Nov 16 '22 at 09:27
  • 3
    Let's say `size == 10`, so you allocate 10 bytes, then say `buffer[size] = 0;` and you've written past the end of the allocated space. You need to allocate `size + 1` to leave space for the terminator. – Retired Ninja Nov 16 '22 at 09:35
  • Or, you can use `cout.write()` instead, then no null-terminator is needed – Remy Lebeau Nov 16 '22 at 15:55

1 Answers1

1

std::cout << buffer expects buffer to be null-terminated, but it is not. You need to allocate space for the terminator, eg:

PBYTE buffer = (PBYTE)HeapAlloc(GetProcessHeap(), 0, fileSize.QuadPart + 1);
...
buffer[dwBytesRead] = 0;

Alternatively, you can use cout.write() instead, then you don't need a terminator, eg:

std::cout.write(buffer,dwBytesRead);
Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770