0

I am getting an exception when I run this code:

STARTUPINFO si;
PROCESS_INFORMATION pi;

ZeroMemory(&si, sizeof(si));
si.cb = sizeof(si);
ZeroMemory(&pi, sizeof(pi));

CreateProcess(NULL, L"program.dat", NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi);

// Wait until child process exits.
WaitForSingleObject( pi.hProcess, INFINITE );

// Close process and thread handles. 
CloseHandle( pi.hProcess );
CloseHandle( pi.hThread );

I get the exception on WaitForSingleObject.

Thanks :)

user2696392
  • 97
  • 1
  • 2
  • 12
  • 6
    You're not checking if `CreateProcess()` was actually able to create the process. I would recommend checking its return value and invoking `GetLastError()` if it is `FALSE`. – Frédéric Hamidi Nov 12 '13 at 11:38
  • 1
    `program.dat` I don't think it will launch dat files like executables. – ta.speot.is Nov 12 '13 at 11:40
  • 3
    `CreateProcess` is for launching executables. It looks like you're trying to launch a non-executable, so you should use `ShellExecute` instead. Because of this my guess is that `CreateProcess` is failing. Check that the return value isn't zero, and if it is (ie it failed) call `GetLastError` to see why. – Sean Nov 12 '13 at 11:49
  • When I use ShellExecute, I get this error: http://qs.lc/81xt – user2696392 Nov 12 '13 at 12:02
  • This is my current code: http://qs.lc/wjj2; and this is the exception I get with current code: http://qs.lc/gehj – user2696392 Nov 12 '13 at 12:05
  • I have fixed the issue, thanks to 1st answer: http://stackoverflow.com/questions/11339186/createprocess-fails-with-an-access-violation?rq=1 – user2696392 Nov 12 '13 at 12:08
  • I'm surprised you didn't find [CreateProcess fails with an access violation](http://stackoverflow.com/questions/11339186/createprocess-fails-with-an-access-violation) which is the #1 hit for `CreateProcess access violation`. – Raymond Chen Nov 12 '13 at 15:27

2 Answers2

6

As clearly as much that can be stated in the documentation::

The Unicode version of this function, CreateProcessW, can modify the contents of this string. Therefore, this parameter cannot be a pointer to read-only memory (such as a const variable or a literal string). If this parameter is a constant string, the function may cause an access violation.

Yours L"program.dat" falls under this rule. Copy the string in some WCHAR variable and pass that instead.

Community
  • 1
  • 1
Abhineet
  • 5,320
  • 1
  • 25
  • 43
4

I can reproduce the exception using your code. I think the problem is that the second arg to CreateProcess is an in/out one. The doc states:

The system adds a terminating null character to the command-line string to separate the file name from the arguments. This divides the original string into two strings for internal processing.

See CreateProcess function

The second arg must NOT point to read-only memory.

Using the Visual Studio debugger and stepping in assembler code, the trap is indeed caused by the _CreateProcessInternal function in Kernel32 trying to write 0x to the end of L"program.dat", which, as a string constant, is in a "non writable" section.

Use below code:

wchar_t * pCommandLine = L"program.dat";
wchar_t CommandLine[ 64 ];
wcscpy( CommandLine,  pCommandLine );
CreateProcess(NULL, CommandLine, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi);

and the exception will vanish.

As for Creating a Child Process with "program.dat" ?!? That's another story.

manuell
  • 7,528
  • 5
  • 31
  • 58