Reputation: 141
I have a function that is supposed to launch another process:
DWORD WINAPI StartCalc(LPVOID lpParam) {
STARTUPINFOW info;
PROCESS_INFORMATION processInfo;
std::wstring cmd = L"C:\\Windows\\System32\\calc.exe";
BOOL hR = CreateProcessW(NULL, (LPWSTR)cmd.c_str(), NULL, NULL, TRUE, 0, NULL, NULL,
&info, &processInfo);
if (hR == 0) {
DWORD errorMessageID = ::GetLastError();
printf("Error creating process\n");
return 1;
}
return 0;
}
I get an exception in ntdll.dll "Access violation reading location 0xFFFFFFFFFFFFFFFF". I know there are a few common mistakes that might cause this:
What am i doing wrong?
EDIT: This actually isn't a problem with casting cmd.c_str()
as a (LPWSTR)
, that part appears to be fine. I needed to initialize the STARTUPINFO struct: STARTUPINFO info = { 0 };
Upvotes: 1
Views: 837
Reputation: 283634
BOOL hR = CreateProcessW(NULL, (LPWSTR)cmd.c_str(), NULL, NULL, TRUE, 0, NULL, NULL, &info, &processInfo);
^^^^^
That's a cast. A great rule of thumb is "spot the cast, you spot the error".
It's true here. CreateProcessW
must be passed a writable string. That means, no literal, and also no c_str()
result.
From 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.
Pass a real non-const
pointer, don't play hide-the-const
. &cmd[0]
should work, that's guaranteed to be a writable string. To be super-safe, increase your wstring
capacity beyond just what you needed, because CreateProcessW
is going to use it as a working buffer.
Upvotes: 2