RAD Studio 2009에서 CreateProcess를 사용할 때 kernel32.dll access violation이 발생하는 개같은 일이 발생.
이전까진 잘 썼었는데.
호출코드는 대략 아래와 같음. (초기화 같은건 생략)

CreateProcess(
    nil, 'cmd.exe', @SecAttr, @SecAttr, True, DETACHED_PROCESS or NORMAL_PRIORITY_CLASS,
    nil, nil, StartupInfo, ProcessInfo
);



문제는 2번째 파라메터인 'cmd.exe' 때문이었다.
PChar를 파라메터로 받는건데, 이게 쫌 함정이다.
WideChar를 사용하는 내부함수인 ProcessCreateW 함수에서는 넘어온 변수를 WideString으로 바꾸는 일이 필요하므로,
2번째 파라메터가 const String 일 경우 손댈 수가 없어 access violation이 발생한다.

MSDN 원문은 다음과 같다.
링크: http://msdn.microsoft.com/en-us/library/ms682425(VS.85).aspx

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.



아래처럼 바꾸면 된다.
손댈 수 있는 놈으로 수정하는 것이다...

procedure TForm1.Button1Click(Sender: TObject);
var
  SecAttr: TSecurityAttributes;
  ProcessInfo: TProcessInformation;
  StartupInfo: TStartupInfo;
  cmd: array [0..1023] of WideChar;

begin
  SecAttr.nLength:=SizeOf(SecAttr);
  SecAttr.lpSecurityDescriptor:=nil;
  SecAttr.bInheritHandle:=True;

  ZeroMemory(@StartupInfo, SizeOf(StartupInfo));
  StartupInfo.cb:=SizeOf(StartupInfo);
  StartupInfo.dwFlags:=STARTF_USESHOWWINDOW or STARTF_USESTDHANDLES;
  StartupInfo.wShowWindow:=SW_SHOW;

  ZeroMemory(@cmd, SizeOf(cmd));
  cmd:='regedit.exe';

  CreateProcess(
    nil, cmd, @SecAttr, @SecAttr, True,
    DETACHED_PROCESS or NORMAL_PRIORITY_CLASS,
    nil, nil,
    StartupInfo, ProcessInfo
  );
end;



아 병신... ... ...








Posted by bloodguy
,