I am trying to read data from a process using the Win32 API function ReadFile()
. I am not using the standard library function because I'm using a source code from a public repo. Here I provide the specific snippet I have trouble with..
//Those are Globals
HANDLE pipin_w, pipin_r, pipout_w, pipout_r;
DWORD write, read, available;
BYTE buffer[2048];
std::string myFunction(){
std::string out="";
PeekNamedPipe ( pipout_r, buffer, sizeof(buffer), &read, &available, NULL);
sleep(300);
do {
ZeroMemory(*buffer, sizeof(buffer));
ReadFile( pipout_r, buffer, sizeof(buffer), &read, NULL);
if (!read) { return std::string("error"); }
buffer[read]=0;
out += (char*)buffer;
} while(read >= sizeof(buffer));
return out;
}
The first two calls respond correctly, than "error"
gets returned.
I wasn't able to use and understand the standard library function because I have no experience in C++ programming. What I'm trying to do is to fill the BYTE
buffer that has size 2048.
This code works for the first two calls, then the read
variable gets corrupted. I know that my initialization is correct because I am able to connect with the process which opens itself in the Task Manager, and also I am able to retrieve data from it, but after a pair of calls the read
variable gets corrupted.
That causes hangs or crashes in my code. There are a few things which I don't like about this code. For example, I was not able to use the standard library functions like fstream
, so I have decided to stick with this setting for now. Also, I don't know if it is correct to read from the process with the ReadFile()
function, but that sort of works. And the while
loop feels quiet uncomfortable for me, I can't understand why I need it.
Anyone who wants to know how I have initialized this code, feel free to ask, I will provide every missing info, but I don't think that is an issue because I am able to make a couple of readings from the process itself. I can provide a link to the source code that I am using since that's a public source code repository.
Maybe Asked Questions (from you):
Does your process support reading?
Yes It does
Do you have enough permissions to run and read the process?
Yes I have
Maybe you need to write some data to tell the process to start the communication..
That's not the case, I have another function to write data, and I use it before this call, but I still receive data even if I don't write to it
How do you create your process?
I can provide that snippet, just ask me, but essentialy I create two pipes, one for Reading and another for writing, then I start the process by calling CreateProcess, and that works.
What are you trying to do with your code?
I am trying to build a class which can handle the creation, the writing, and the reading of a process in a Windows platform environment with c++, nothing more..
What can possibly cause the corruption of the read
variable? I am struggling to understand that, and how I can avoid it. Also, if someone can explain to me good practices for this kind of situations, I really appreciate that, or at least to have a link to some resources I can look at, or to study how that works.
ZeroMemory(*buffer, sizeof(buffer));
should be ZeroMemory(buffer, sizeof(buffer));
BYTE
in buffer
and use that as the address to start zeroing at. This causes undefined behavior.buffer[read]=0;
is potentially writing out of bounds. If you've read 2048
BYTE
s, you have undefined behavior.out += (char*)buffer;
reads buffer
until it finds \0
- but there's no need for that since you already know how many BYTE
s you've read.Fixes:
ZeroMemory
- you will only read memory that's been filled by ReadFile
so it's just a waste of time to zero it out first.buffer[read]=0; out += (char*)buffer;
without.append(reinterpret_cast<char*>(buffer), read);
Also, check the return value of the functions you call. ReadFile
may fail for example.
The crashes all gone, after i reverted the casting to a char pointer, i did not understand quite well cast conversion, but since i allocated memory by first initializing the char pointer to nullptr, then i used memset to allocate a bigger buffer, somehow my approce works with this kind of situation, as i do not use it anywhere else in my code, if i need it, i just copy it to a new initialized string using std::string, so that solved the continous crash problem, and onestly i cant figure out a better approch to this.
Next, what i premused was also a crash, it was really an infinite loop by the ReadFile function, and it occures in two kind of situation.
when i pass a "wrong" string to communicate with it, some kind of special caharcters (such as \ or /)
When the buffer has nothing to read from the application, and the application returns empty output
Still not sure how to handle the second case:( but at least i can continue debugging... :)
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.