Hi @Sudhir Dubey ,
Thank you for posting your question.
You can free (or reuse) the buffer you passed in lpEnvironment as soon as CreateProcessW returns. This applies whether the call succeeded or failed, whether you used CREATE_SUSPENDED, and whether the child has finished initializing.
What the documentation says:
- The CreateProcessW reference annotates lpEnvironment as [in, optional]. An [in] parameter is read during the call and isn't kept by the function. The page puts no requirement on the buffer after the call returns.
- In the CreateEnvironmentBlock remarks. Once CreateProcessAsUser returns, the new process has its own copy of the environment block, and DestroyEnvironmentBlock can safely be called. That sentence is written for CreateProcessAsUser, but lpEnvironment and CREATE_UNICODE_ENVIRONMENT work the same way in CreateProcessW.
- The CreateProcessW page also says the function returns before the new process has finished initialization. That refers to the child's own startup, such as loading DLLs. It doesn't mean your input buffer is still in use. Creating the process suspended only stops the primary thread from running. It doesn't postpone the copy of the environment.
Please note this, the CreateProcessW page doesn't say "the environment block is copied before return" in so many words. The conclusion above is based on the [in] contract, the related CreateEnvironmentBlock statement, and how the function behaves.
What I recommend:
- Keeping the buffer alive for the whole native call, as you're doing now, is correct and enough. You don't need to wait for ResumeThread, for the child to finish initializing, or for it to exit.
- Free the buffer with the function that matches how it was allocated. Use DestroyEnvironmentBlock for blocks from CreateEnvironmentBlock. For your own allocations, use free, delete[], HeapFree and so on.
- If CreateProcessW fails, call GetLastError() before you free the buffer.
- The only resources that outlive the call are hProcess and hThread in PROCESS_INFORMATION. Close them with CloseHandle when you no longer need them.
BOOL created = CreateProcessW(app, cmdLine, nullptr, nullptr, FALSE,
CREATE_UNICODE_ENVIRONMENT | CREATE_SUSPENDED,
envBlock, nullptr, &si, &pi);
DWORD err = created ? ERROR_SUCCESS : GetLastError();
free(envBlock); // safe here; use the matching deallocator
if (created) {
// ... ResumeThread(pi.hThread) when ready ...
CloseHandle(pi.hThread);
CloseHandle(pi.hProcess);
}
If you found my support helpful, I’d really appreciate it if you could follow this guide so others with similar issue can benefit as well.
Thank you.