From: Shashank Date Date: 2003-03-20T12:15:55+09:00 Subject: Re: win32api createprocess trouble This is a multi-part message in MIME format. ------=_NextPart_000_0014_01C2EE5A.B120CF60 Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: quoted-printable # Try this out: I have tested it on Win2K and Win XP (Pro) # using ruby 1.6.8 (2002-12-24) [i586-mswin32] # Does more than what you asked for ... require 'Win32API' =20 STDOUT.sync =3D true NORMAL_PRIORITY_CLASS =3D 0x00000020 STARTUP_INFO_SIZE =3D 68 PROCESS_INFO_SIZE =3D 16 ERROR_SUCCESS =3D 0x00 FORMAT_MESSAGE_FROM_SYSTEM =3D 0x1000 FORMAT_MESSAGE_ARGUMENT_ARRAY =3D 0x2000 PROCESSENTRY32_SIZE =3D 296 def process_running?(pid,ppid =3D -1) params =3D [ 'L', # IN DWORD dwFlags 'L' # IN DWORD th32ProcessID ] retVal =3D 'L' # HANDLE =20 getProcessSnapShot =3D Win32API.new("kernel32", = "CreateToolhelp32Snapshot", params, retVal) hProcess =3D getProcessSnapShot.call(8,0) =20 params =3D [ 'L', # hSnapshot [in] Handle to the snapshot returned = from a previous call to the CreateToolhelp32Snapshot function.=20 'P' # lppe [in, out] Pointer to a PROCESSENTRY32 = structure ] retVal =3D 'I' # BOOL =20 # Dim hSnapshot As Long, uProcess As PROCESSENTRY32 # uProcess.dwSize =3D Len(uProcess) uProcess =3D [PROCESSENTRY32_SIZE].pack('I') + ([0].pack('I') * = (PROCESSENTRY32_SIZE - 4)) =20 getProcessFirst =3D Win32API.new("kernel32", "Process32First", params, = retVal) getProcessNext =3D Win32API.new("kernel32", "Process32Next", params, = retVal) r =3D getProcessFirst.call(hProcess,uProcess) found =3D false while (r !=3D 0) =20 puts r gotPid =3D uProcess.th32ProcessID=20 gotPpid =3D uProcess.th32ParentProcessID (found =3D true; break) if (gotPid =3D=3D pid) and ((ppid >=3D 0) ? = (ppid =3D=3D gotPpid) : true) r =3D getProcessNext.call(hProcess,uProcess) end =20 return found end def raise_last_win_32_error errorCode =3D Win32API.new("kernel32", "GetLastError", [], 'L').call if errorCode !=3D ERROR_SUCCESS params =3D [ 'L', # IN DWORD dwFlags, 'P', # IN LPCVOID lpSource, 'L', # IN DWORD dwMessageId, 'L', # IN DWORD dwLanguageId, 'P', # OUT LPSTR lpBuffer, 'L', # IN DWORD nSize, 'P', # IN va_list *Arguments ] formatMessage =3D Win32API.new("kernel32", "FormatMessage", params, = 'L') msg =3D ' ' * 255 msgLength =3D formatMessage.call(FORMAT_MESSAGE_FROM_SYSTEM + FORMAT_MESSAGE_ARGUMENT_ARRAY, '', errorCode, 0, = msg, 255, '') msg.gsub!(/\000/, '') msg.strip! raise msg else raise 'GetLastError returned ERROR_SUCCESS' end end def create_process(command,redirStdout=3D"", redirStderr=3D"") if redirStdout.length > 0 tmpfile =3D File.new(redirStdout,"w") save_stdout =3D $stdout.clone $stdout.reopen(tmpfile) end if redirStderr.length > 0 tmpfile =3D File.new(redirStderr,"w") save_stderr =3D $stderr.clone $stderr.reopen(tmpfile) end params =3D [ 'L', # IN LPCSTR lpApplicationName 'P', # IN LPSTR lpCommandLine 'L', # IN LPSECURITY_ATTRIBUTES lpProcessAttributes 'L', # IN LPSECURITY_ATTRIBUTES lpThreadAttributes 'L', # IN BOOL bInheritHandles 'L', # IN DWORD dwCreationFlags 'L', # IN LPVOID lpEnvironment 'L', # IN LPCSTR lpCurrentDirectory 'P', # IN LPSTARTUPINFOA lpStartupInfo 'P' # OUT LPPROCESS_INFORMATION lpProcessInformation ] returnValue =3D 'I' # BOOL startupInfo =3D [STARTUP_INFO_SIZE].pack('I') + ([0].pack('I') * = (STARTUP_INFO_SIZE - 4)) processInfo =3D [0].pack('I') * PROCESS_INFO_SIZE createProcess =3D Win32API.new("kernel32", "CreateProcess", params, = returnValue) if createProcess.call(0, command, 0, 0, 0, NORMAL_PRIORITY_CLASS, 0, = 0, startupInfo, processInfo) =3D=3D 0 raise_last_win_32_error end =20 if redirStdout.length > 0 $stdout.reopen(save_stdout) end =20 save_stdout.close if save_stdout if redirStderr.length > 0 $stderr.reopen(save_stderr) end =20 save_stderr.close if save_stderr =20 ($0 =3D=3D __FILE__ ) ? processInfo : processInfo.unpack("LLLL")[2] end if $0 =3D=3D __FILE__ begin cmd =3D 'ping -n 15 localhost' pi =3D create_process(cmd,"","C:\\stderr.txt") p pi.unpack("LLLL") #if $DEBUG hProcess =3D pi.unpack("LLLL")[0] hThread =3D pi.unpack("LLLL")[1] dwProcessId =3D pi.unpack("LLLL")[2] puts dwProcessId dwThreadId =3D pi.unpack("LLLL")[3] puts process_running?(4) =20 # Now kill the process kill =3D false if kill sleep(10) OpenProcess =3D = Win32API.new("kernel32","OpenProcess",['L','L','L'],'L') TerminateProcess =3D = Win32API.new("kernel32","TerminateProcess",['L','L'],'L') TerminateProcess.Call(OpenProcess.Call(0x00100001, 0 = ,dwProcessId),0) else sleep(20) end =20 rescue RuntimeError =3D> err puts 'Aborting: ' + err=20 end end "LeRoy, Brian D." wrote in message = news:B307D1E87003D511A89700B0D0B0326A0116A201@CIS-DUBLIN-EX1... I've been struggling to get the CreateProcess Win32API call to run. I = get this error: =20 998 Invalid access to memory location. ERROR_NOACCESS =20 I've since attempted CreateProcessWithLogon, but this call expects a = clear text password which is not so nice. Any help is greatly = appreciated! =20 Brian LeRoy =20 ------=_NextPart_000_0014_01C2EE5A.B120CF60 Content-Type: text/html; charset="iso-8859-1" Content-Transfer-Encoding: quoted-printable
# Try this out: I have tested it on = Win2K and Win=20 XP (Pro)
# using ruby 1.6.8 (2002-12-24)=20 [i586-mswin32]
# Does more than what you asked for=20 ....
 
require = 'Win32API'
 
STDOUT.sync =3D=20 true
 
NORMAL_PRIORITY_CLASS =3D=20 0x00000020
STARTUP_INFO_SIZE =3D 68
PROCESS_INFO_SIZE =3D = 16
ERROR_SUCCESS=20 =3D 0x00
FORMAT_MESSAGE_FROM_SYSTEM =3D = 0x1000
FORMAT_MESSAGE_ARGUMENT_ARRAY =3D=20 0x2000
PROCESSENTRY32_SIZE =3D 296
 
def process_running?(pid,ppid =3D = -1)
 =20 params =3D  [ 'L', # IN DWORD=20 dwFlags
          &n= bsp;  =20 'L'  # IN DWORD=20 th32ProcessID
         &n= bsp; =20 ]
  retVal =3D 'L' # HANDLE    
 =20 getProcessSnapShot =3D Win32API.new("kernel32", = "CreateToolhelp32Snapshot",=20 params, retVal)
  hProcess =3D = getProcessSnapShot.call(8,0)
 =20
  params =3D  [ 'L', # hSnapshot [in] Handle to the = snapshot=20 returned from a previous call to the CreateToolhelp32Snapshot function.=20
           &nb= sp; =20 'P'  # lppe [in, out] Pointer to a PROCESSENTRY32=20 structure
          =  =20 ]
  retVal =3D 'I' # BOOL
 
# Dim hSnapshot As Long, = uProcess=20 As PROCESSENTRY32
# uProcess.dwSize =3D Len(uProcess)
 
  uProcess =3D = [PROCESSENTRY32_SIZE].pack('I') +=20 ([0].pack('I') * (PROCESSENTRY32_SIZE - 4))
 
  = getProcessFirst=20 =3D Win32API.new("kernel32", "Process32First", params, retVal)
  = getProcessNext  =3D Win32API.new("kernel32", "Process32Next", = params,=20 retVal)
 
  r =3D=20 getProcessFirst.call(hProcess,uProcess)
  found =3D = false
  while=20 (r !=3D 0)     
    puts=20 r
    gotPid =3D uProcess.th32ProcessID =
   =20 gotPpid =3D uProcess.th32ParentProcessID
    (found = =3D true;=20 break) if (gotPid =3D=3D pid) and ((ppid >=3D 0) ? (ppid =3D=3D = gotPpid) :=20 true)
    r =3D = getProcessNext.call(hProcess,uProcess)
 =20 end
 
  return found
end
 
def raise_last_win_32_error
  = errorCode =3D=20 Win32API.new("kernel32", "GetLastError", [], 'L').call
  if = errorCode !=3D=20 ERROR_SUCCESS
    params =3D = [
     =20 'L', # IN DWORD dwFlags,
      'P', # IN = LPCVOID=20 lpSource,
      'L', # IN DWORD=20 dwMessageId,
      'L', # IN DWORD=20 dwLanguageId,
      'P', # OUT LPSTR=20 lpBuffer,
      'L', # IN DWORD=20 nSize,
      'P', # IN va_list=20 *Arguments
    ]
 
    formatMessage =3D=20 Win32API.new("kernel32", "FormatMessage", params, = 'L')
    msg=20 =3D ' ' * 255
    msgLength =3D=20 formatMessage.call(FORMAT_MESSAGE_FROM_SYSTEM=20 +
           &n= bsp;       =20 FORMAT_MESSAGE_ARGUMENT_ARRAY, '', errorCode, 0, msg, 255, = '')
 
    msg.gsub!(/\000/,=20 '')
    msg.strip!
    raise = msg
 =20 else
    raise 'GetLastError returned = ERROR_SUCCESS'
 =20 end
end
 
def = create_process(command,redirStdout=3D"",=20 redirStderr=3D"")
 
  if redirStdout.length >=20 0
    tmpfile =3D=20 File.new(redirStdout,"w")
    save_stdout =3D=20 $stdout.clone
    $stdout.reopen(tmpfile)
 =20 end
 
  if redirStderr.length >=20 0
    tmpfile =3D=20 File.new(redirStderr,"w")
    save_stderr =3D=20 $stderr.clone
    $stderr.reopen(tmpfile)
 =20 end
 
  params =3D = [
    'L', # IN=20 LPCSTR lpApplicationName
    'P', # IN LPSTR=20 lpCommandLine
    'L', # IN LPSECURITY_ATTRIBUTES=20 lpProcessAttributes
    'L', # IN = LPSECURITY_ATTRIBUTES=20 lpThreadAttributes
    'L', # IN BOOL=20 bInheritHandles
    'L', # IN DWORD=20 dwCreationFlags
    'L', # IN LPVOID=20 lpEnvironment
    'L', # IN LPCSTR=20 lpCurrentDirectory
    'P', # IN LPSTARTUPINFOA=20 lpStartupInfo
    'P'  # OUT = LPPROCESS_INFORMATION=20 lpProcessInformation
  ]
  returnValue =3D 'I' # = BOOL
 
  startupInfo =3D = [STARTUP_INFO_SIZE].pack('I')=20 + ([0].pack('I') * (STARTUP_INFO_SIZE - 4))
  processInfo =3D=20 [0].pack('I') * PROCESS_INFO_SIZE
  createProcess =3D=20 Win32API.new("kernel32", "CreateProcess", params, returnValue)
  = if=20 createProcess.call(0, command, 0, 0, 0, NORMAL_PRIORITY_CLASS, 0, 0,=20 startupInfo, processInfo) =3D=3D 0
   =20 raise_last_win_32_error
  end
 
  if = redirStdout.length=20 > 0
    $stdout.reopen(save_stdout)
  = end
 =20
  save_stdout.close if save_stdout
 
  if redirStderr.length >=20 0
    $stderr.reopen(save_stderr)
  = end
 =20
  save_stderr.close if save_stderr
 
  ($0 = =3D=3D __FILE__=20 ) ? processInfo : processInfo.unpack("LLLL")[2]
end
 
if $0 =3D=3D = __FILE__
begin
   =20 cmd =3D 'ping -n 15 localhost'
    pi =3D=20 create_process(cmd,"","C:\\stderr.txt")
    p=20 pi.unpack("LLLL") #if $DEBUG
 
    hProcess =3D=20 pi.unpack("LLLL")[0]
    hThread  =3D=20 pi.unpack("LLLL")[1]
    dwProcessId =3D=20 pi.unpack("LLLL")[2]
    puts=20 dwProcessId
    dwThreadId =3D = pi.unpack("LLLL")[3]
 
    puts=20 process_running?(4)
   
    # Now = kill the=20 process
    kill =3D false
    if=20 kill
       =20 sleep(10)
        OpenProcess =3D=20 Win32API.new("kernel32","OpenProcess",['L','L','L'],'L')
  &= nbsp;    =20 TerminateProcess =3D=20 Win32API.new("kernel32","TerminateProcess",['L','L'],'L')
  =      =20 TerminateProcess.Call(OpenProcess.Call(0x00100001, 0=20 ,dwProcessId),0)
   =20 else
       =20 sleep(20)
    end
   
rescue=20 RuntimeError =3D> err
    puts 'Aborting: '  + = err=20
end
end
"LeRoy, Brian D." <brian.leroy@cendant.com> = wrote in=20 message new= s:B307D1E87003D511A89700B0D0B0326A0116A201@CIS-DUBLIN-EX1...

I've been struggling to = get the=20 CreateProcess Win32API call to run.  I get this=20 error:

 

998 Invalid access to memory location.=20 ERROR_NOACCESS

 

I've since attempted = CreateProcessWithLogon, but this call expects a = clear text=20 password which is not so nice.  = Any help is greatly appreciated!

 

Brian = LeRoy

 

------=_NextPart_000_0014_01C2EE5A.B120CF60--