Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 8 years ago.
Improve this question
I'm using Visual Studio 2010 to work on a Win32 app that attempts to read from stdin. It retrieves a valid handle from GetStdHandle(STD_INPUT_HANDLE) and immediately calls WaitForSingleObject() with the handle as a parameter, but the return value is always WAIT_FAILED. I have verified that the value of the file handle is 01, which is odd bc stdin is usually 0, stdout 1, and stderr 2, so this is probably an important clue.
When I used the "Error Lookup" tool the code (6) means that the handle is invalid. In the VS output window I get "WAIT_FAILED. GetLastError() returned: 6" from the code below. Any help greatly appreciated.
hStdIn = GetStdHandle( STD_INPUT_HANDLE );
XTrace (L"hStdIn: %ul\r\n", hStdIn );
if (INVALID_HANDLE_VALUE != hStdIn)
{
INPUT_RECORD inputRecord[512];
DWORD nNumBytesRead;
switch ( WaitForSingleObject( hStdIn, 1000 ) )
{
case( WAIT_TIMEOUT ):
XTrace (L"WAIT_TIMEOUT\r\n" );
break; // return from this function to allow thread to terminate
case( WAIT_OBJECT_0 ):
// clear events
ReadConsoleInput( hStdIn, inputRecord, 512, &nNumBytesRead );
XTrace (L"Called ReadConsoleInput(). WAIT_OBJECT_0\r\n" );
break;
case( WAIT_FAILED ):
XTrace (L"WAIT_FAILED. GetLastError() returned: %d\r\n", GetLastError() );
break;
case( WAIT_ABANDONED ):
XTrace (L"WAIT_ABANDONED\r\n" );
break;
default:
XTrace (L"Unexpected result from WaitForSingleObject\r\n" );
}
}
GetStdHandle says:
The handle has GENERIC_READ and GENERIC_WRITE access rights
WaitForSingleObject says:
The handle must have the SYNCHRONIZE access right.
Related
This question already has answers here:
Error 998 (Invalid access to memory location) for when calling GetPointerFrameTouchInfo [duplicate]
(1 answer)
WriteConsole access violation in function call but not from main()
(2 answers)
VirtualProtectEx fails with ERROR_NOACCESS (error code 998)
(1 answer)
Invalid access to memory location with ReadFile
(2 answers)
Closed 2 years ago.
I am trying to get the PIO_COUNTERS for the current process by doing:
DWORD pid = GetCurrentProcessId();
auto handle = OpenProcess(PROCESS_ALL_ACCESS, 0, pid);
PIO_COUNTERS ctr = nullptr;
if (!GetProcessIoCounters(handle, ctr)) {
DWORD dw = GetLastError();
}
I get value of dw as 998 which is "Invalid access of the memory location". This essentially means that the handle I am using does not have enough privileges, but this is the flag with the max access control privileges. I also tried using the handle given by "GetCurrentProcess" (which is different from the one I got above) but that also gave error code 998 after passing it to GetProcessIoCounters.
Can somebody please help me out here?
Thanks in advance.
The 'invalid access' error is occurring because you are passing a nullptr value for the address of the IO_COUNTERS structure into which to write the information you are retrieving. You need to give the address of an actual structure for this:
DWORD pid = GetCurrentProcessId();
auto handle = OpenProcess(PROCESS_ALL_ACCESS, 0, pid);
IO_COUNTERS info;
if (!GetProcessIoCounters(handle, &info)) { // Pass the address of your structure!
DWORD dw = GetLastError();
}
You can then access the various members of the info structure to get the information you want.
I know lots of similar questions on this topic have been asked before but so far I have been unable to find a solution that actually works. I want to start a console program from my program and capture its output. My implementation should be in a way that is compatible with WaitForMultipleObjects(), i.e. I want to get notified whenever there is new data to read in the pipe.
My implementation is based on this example from MSDN. However, I had to modify it a little because I need overlapped I/O in order to be able to wait for ReadFile() to finish. So I'm using named pipes created using Dave Hart's MyCreatePipeEx() function from here.
This is my actual code. I have removed error checks for readability reasons.
HANDLE hReadEvent;
HANDLE hStdIn_Rd, hStdIn_Wr;
HANDLE hStdOut_Rd, hStdOut_Wr;
SECURITY_ATTRIBUTES saAttr;
PROCESS_INFORMATION piProcInfo;
STARTUPINFO siStartInfo;
OVERLAPPED ovl;
HANDLE hEvt[2];
DWORD mask, gotbytes;
BYTE buf[4097];
saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
saAttr.bInheritHandle = TRUE;
saAttr.lpSecurityDescriptor = NULL;
MyCreatePipeEx(&hStdOut_Rd, &hStdOut_Wr, &saAttr, 0, FILE_FLAG_OVERLAPPED, FILE_FLAG_OVERLAPPED);
MyCreatePipeEx(&hStdIn_Rd, &hStdIn_Wr, &saAttr, 0, FILE_FLAG_OVERLAPPED, FILE_FLAG_OVERLAPPED);
SetHandleInformation(hStdOut_Rd, HANDLE_FLAG_INHERIT, 0);
SetHandleInformation(hStdIn_Wr, HANDLE_FLAG_INHERIT, 0);
memset(&piProcInfo, 0, sizeof(PROCESS_INFORMATION));
memset(&siStartInfo, 0, sizeof(STARTUPINFO));
siStartInfo.cb = sizeof(STARTUPINFO);
siStartInfo.hStdError = hStdOut_Wr;
siStartInfo.hStdOutput = hStdOut_Wr;
siStartInfo.hStdInput = hStdIn_Rd;
siStartInfo.dwFlags |= STARTF_USESTDHANDLES;
CreateProcess(NULL, "test.exe", NULL, NULL, TRUE, 0, NULL, NULL, &siStartInfo, &piProcInfo);
hReadEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
for(;;) {
int i = 0;
hEvt[i++] = piProcInfo.hProcess;
memset(&ovl, 0, sizeof(OVERLAPPED));
ovl.hEvent = hReadEvent;
if(!ReadFile(hStdOut_Rd, buf, 4096, &gotbytes, &ovl)) {
if(GetLastError() == ERROR_IO_PENDING) hEvt[i++] = hReadEvent;
} else {
buf[gotbytes] = 0;
printf("%s", buf);
}
mask = WaitForMultipleObjects(i, hEvt, FALSE, INFINITE);
if(mask == WAIT_OBJECT_0 + 1) {
if(GetOverlappedResult(hStdOut_Rd, &ovl, &gotbytes, FALSE)) {
buf[gotbytes] = 0;
printf("%s", buf);
}
} else if(mask == WAIT_OBJECT_0) {
break;
}
}
The problem with this code is the following: As you can see, I'm reading in chunks of 4kb using ReadFile() because I obviously don't know how much data the external program test.exe will output. Doing it this way was suggested here:
To read a variable amount of data from the client process just issue
read requests of whatever size you find convenient and be prepared to
handle read events that are shorter than you requested. Don't
interpret a short but non-zero length as EOF. Keep issuing read
requests until you get a zero length read or an error.
However, this doesn't work. The event object passed to ReadFile() as part of the OVERLAPPED structure will only trigger once there are 4kb in the buffer. If the external program just prints "Hello", the event won't trigger at all. There need to be 4kb in the buffer for hReadEvent to actually trigger.
So I thought I should read byte by byte instead and modified my program to use ReadFile() like this:
if(!ReadFile(hStdOut_Rd, buf, 1, &gotbytes, &ovl)) {
However, this doesn't work either. If I do it like this, the read event is not triggered at all which is really confusing me. When using 4096 bytes, the event does indeed trigger as soon as there are 4096 bytes in the pipe, but when using 1 byte it doesn't work at all.
So how am I supposed to solve this? I'm pretty much out of ideas here. Is there no way to have the ReadFile() event trigger whenever there is some new data in the pipe? Can't be that difficult, can it?
Just for the record, while there are some problems with my code (see discussion in comments below the OP), the general problem is that it's not really possible to capture the output of arbitrary external programs because they will typically use block buffering when their output is redirected to a pipe, which means that output will only arrive at the capturing program once that buffer is flushed so real time capturing is not really possible.
Some workarounds have been suggested though:
1) (Windows) Here is a workaround that uses GetConsoleScreenBuffer() to capture the output from arbitrary console programs but it currently only supports one console page of output.
2) (Linux) On Linux, it's apparently possible to use pseudo-terminals to force the external program to use unbuffered output. Here is an example.
Closed. This question is off-topic. It is not currently accepting answers.
Want to improve this question? Update the question so it's on-topic for Stack Overflow.
Closed 9 years ago.
Improve this question
I have an PIC18f i2c Master and some other devices as slaves.
I want to detect if a slave is not on the bus or if he doesn't responds.
Right now, the communication Master<->Slaves works well except when a slave doesn't responds. When this happens, the PIC stays in a waiting state and the whole program is stopped.
How can I detect and fix that ? (In a software way)
For information, I'm working on a PIC18f25k22.
I assume you are using MPLAB with C18. The source for all the I2C functions can be found in: C:\Program Files (x86)\Microchip\mplabc18\v3.46\src\pmc_common\i2c
Next, you'll need to figure out what functions are hanging and then write your own versions that don't go into endless loops if the slave doesn't respond. Most like ReadI2C is hanging waiting for a slave to respond. So you could replace it with myReadI2C that takes a timeout parameter. A modified version of the code in i2c_read.c.
#if defined (I2C_V1)
int myReadI2C( long timeout )
{
if( ((SSPCON1&0x0F)==0x08) || ((SSPCON1&0x0F)==0x0B) ) //master mode only
SSPCON2bits.RCEN = 1; // enable master for 1 byte reception
while ( !SSPSTATbits.BF && timeout > 0) timeout--; // wait until byte received
return timeout == 0 ? (-1) : ( SSPBUF ); // return with read byte
}
#endif
#if defined (I2C_V4)
int myReadI2C( long timeout)
{
while ( !SSPSTATbits.BF && timeout > 0) timeout--; // wait until byte received
return timeout == 0 ? (-1) : ( SSPBUF ); // return with read byte
}
#endif
myReadI2C will return -1 on timeout and unsigned char value (0 - 255) on success. You will need to modify the other I2C functions you use in a similar way to avoid loops that only test register status values. As for a value for timeout, you need to find a value through experimentation depending on your devices clock speed and your peripherals response time.
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
We don’t allow questions seeking recommendations for books, tools, software libraries, and more. You can edit the question so it can be answered with facts and citations.
Closed 4 years ago.
Improve this question
I am trying to replace the deprecated API PBHCopyFileSync with PBFSCopyFileSync as recommend in Files.h header.
Surprisingly, Apple only says several lines for this new API:
PBFSCopyFileSync
Duplicates a file and optionally renames it.
OSStatus PBFSCopyFileSync (
FSRefParamPtr paramBlock
);
Availability
Available in Mac OS X v10.5 and later.
Declared In
Files.h
And I couldn't find more about how to use this function.
Specially, what should be filled into the parameter FSRefParamPtr? I tried code below, but keeps getting an error of -50.
paramErr -50
Invalid value passed in a parameter. Your application
passed an invalid parameter for dialog options.
Here is the code:
OSStatus res = noErr;
FSRefParam param;
FSRef srcFile, dstDir, newFile;
const char *src = "$PATH_TO_A_EXISTING_FILE";
const char *dst = "/tmp";
res = FSPathMakeRef((const UInt8 *)src, &srcFile, NULL);
assert(res == noErr);
res = FSPathMakeRef((const UInt8 *)dst, &dstDir, NULL);
assert(res == noErr);
memset(¶m, 0, sizeof(FSRefParam));
param.ioCompletion = NULL;
param.ref = &srcFile;
param.parentRef = &dstDir;
param.newRef = &newFile;
res = PBFSCopyFileSync(¶m);
if (res == noErr) {
printf("SUCCESS!!!\n");
} else {
printf("FAILED!!! %d\n", res);
}
So, does anyone know some detailed documentation or sample codes about this API? Or is there any more popular/documented C++ API for copying files?
Thanks.
Quinn “The Eskimo!” says:
Always use FSCopyObjectSync. PBFSCopyFileSync/PBHCopyFileSync are low-level routines that are exported for legacy reasons. FSCopyObjectSync is a proper API that takes care of all of the nittygritty details of copying.
Notably, both PBFSCopyFileSync and PBHCopyFileSync are parameter block routines, with no nice wrappers. You should consider that a hint (-:
Is it possible to wait for all processes launched by a child process in Windows? I can't modify the child or grandchild processes.
Specifically, here's what I want to do. My process launches uninstallA.exe. The process uninistallA.exe launches uninstallB.exe and immediately exits, and uninstallB.exe runs for a while. I'd like to wait for uninstallB.exe to exit so that I can know when the uninstall is finished.
Create a Job Object with CreateJobObject. Use CreateProcess to start UninstallA.exe in a suspended state. Assign that new process to your job object with AssignProcessToJobObject. Start UninstallA.exe running by calling ResumeThread on the handle of the thread you got back from CreateProcess.
Then the hard part: wait for the job object to complete its execution. Unfortunately, this is quite a bit more complex than anybody would reasonably hope for. The basic idea is that you create an I/O completion port, then you create the object object, associate it with the I/O completion port, and finally wait on the I/O completion port (getting its status with GetQueuedCompletionStatus). Raymond Chen has a demonstration (and explanation of how this came about) on his blog.
Here's a technique that, while not infallible, can be useful if for some reason you can't use a job object. The idea is to create an anonymous pipe and let the child process inherit the handle to the write end of the pipe.
Typically, grandchild processes will also inherit the write end of the pipe. In particular, processes launched by cmd.exe (e.g., from a batch file) will inherit handles.
Once the child process has exited, the parent process closes its handle to the write end of the pipe, and then attempts to read from the pipe. Since nobody is writing to the pipe, the read operation will block indefinitely. (Of course you can use threads or asynchronous I/O if you want to keep doing stuff while waiting for the grandchildren.)
When (and only when) the last handle to the write end of the pipe is closed, the write end of the pipe is automatically destroyed. This breaks the pipe and the read operation completes and reports an ERROR_BROKEN_PIPE failure.
I've been using this code (and earlier versions of the same code) in production for a number of years.
// pwatch.c
//
// Written in 2011 by Harry Johnston, University of Waikato, New Zealand.
// This code has been placed in the public domain. It may be freely
// used, modified, and distributed. However it is provided with no
// warranty, either express or implied.
//
// Launches a process with an inherited pipe handle,
// and doesn't exit until (a) the process has exited
// and (b) all instances of the pipe handle have been closed.
//
// This effectively waits for any child processes to exit,
// PROVIDED the child processes were created with handle
// inheritance enabled. This is usually but not always
// true.
//
// In particular if you launch a command shell (cmd.exe)
// any commands launched from that command shell will be
// waited on.
#include <windows.h>
#include <stdio.h>
void error(const wchar_t * message, DWORD err) {
wchar_t msg[512];
swprintf_s(msg, sizeof(msg)/sizeof(*msg), message, err);
printf("pwatch: %ws\n", msg);
MessageBox(NULL, msg, L"Error in pwatch utility", MB_OK | MB_ICONEXCLAMATION | MB_SYSTEMMODAL);
ExitProcess(err);
}
int main(int argc, char ** argv) {
LPWSTR lpCmdLine = GetCommandLine();
wchar_t ch;
DWORD dw, returncode;
HANDLE piperead, pipewrite;
STARTUPINFO si;
PROCESS_INFORMATION pi;
SECURITY_ATTRIBUTES sa;
char buffer[1];
while (ch = *(lpCmdLine++)) {
if (ch == '"') while (ch = *(lpCmdLine++)) if (ch == '"') break;
if (ch == ' ') break;
}
while (*lpCmdLine == ' ') lpCmdLine++;
sa.nLength = sizeof(sa);
sa.bInheritHandle = TRUE;
sa.lpSecurityDescriptor = NULL;
if (!CreatePipe(&piperead, &pipewrite, &sa, 1)) error(L"Unable to create pipes: %u", GetLastError());
GetStartupInfo(&si);
if (!CreateProcess(NULL, lpCmdLine, NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi))
error(L"Error %u creating process.", GetLastError());
if (WaitForSingleObject(pi.hProcess, INFINITE) == WAIT_FAILED) error(L"Error %u waiting for process.", GetLastError());
if (!GetExitCodeProcess(pi.hProcess, &returncode)) error(L"Error %u getting exit code.", GetLastError());
CloseHandle(pipewrite);
if (ReadFile(piperead, buffer, 1, &dw, NULL)) {
error(L"Unexpected data received from pipe; bug in application being watched?", ERROR_INVALID_HANDLE);
}
dw = GetLastError();
if (dw != ERROR_BROKEN_PIPE) error(L"Unexpected error %u reading from pipe.", dw);
return returncode;
}
There is not a generic way to wait for all grandchildren but for your specific case you may be able to hack something together. You know you are looking for a specific process instance. I would first wait for uninstallA.exe to exit (using WaitForSingleObject) because at that point you know that uninstallB.exe has been started. Then use EnumProcesses and GetProcessImageFileName from PSAPI to find the running uninstallB.exe instance. If you don't find it you know it has already finished, otherwise you can wait for it.
An additional complication is that if you need to support versions of Windows older than XP you can't use GetProcessImageFileName, and for Windows NT you can't use PSAPI at all. For Windows 2000 you can use GetModuleFileNameEx but it has some caveats that mean it might fail sometimes (check docs). If you have to support NT then look up Toolhelp32.
Yes this is super ugly.
Use a named mutex.
One possibility is to install Cygwin and then use the ps command to watch for the grandchild to exit