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.