david
david

Reputation: 141

Why is CreateProcess API call causing memory access violations?

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

Answers (1)

Ben Voigt
Ben Voigt

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

Related Questions