win32-process 0.6.6 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/CHANGES CHANGED
@@ -1,8 +1,13 @@
1
- = 0.6.6 - 19-Jul-2012
2
- * Fixed a param bug in the Process.fork method caused by a prototype change
3
- in the Windows::Process library of the windows-pr gem. Thanks go to
4
- mzverev for the spot.
5
- * Updated the gemspec, including updates to the windows-pr dependency.
1
+ = 0.7.0 - 22-Aug-2012
2
+ * Converted to use FFI instead of win32-api.
3
+ * Now requires Ruby 1.9.x or later.
4
+ * Removed the experimental Process.fork function. This obviated the necessity
5
+ of custom implementations of other methods, like Process.waitpid, so those
6
+ no longer have custom implementations either. These also proved to be
7
+ somewhat problematic with Ruby 1.9.x anyway.
8
+ * Removed the custom Process.ppid method because Ruby 1.9.x now supports it.
9
+ * The Process.kill method now supports the :exit_proc, :dll_module and
10
+ :wait_time options for signals 1 and 4-8.
6
11
 
7
12
  = 0.6.5 - 27-Dec-2010
8
13
  * Fixed getpriority and setpriority so that the underlying process handle is
data/MANIFEST CHANGED
@@ -1,11 +1,9 @@
1
- * CHANGES
2
- * README
3
- * MANIFEST
4
- * Rakefile
5
- * win32-process.gemspec
6
- * examples/example_create.rb
7
- * examples/example_fork_wait.rb
8
- * examples/example_fork_waitpid.rb
9
- * examples/example_kill.rb
10
- * lib/win32/process.rb
11
- * test/test_process.rb
1
+ * CHANGES
2
+ * README
3
+ * MANIFEST
4
+ * Rakefile
5
+ * win32-process.gemspec
6
+ * examples/example_create.rb
7
+ * examples/example_kill.rb
8
+ * lib/win32/process.rb
9
+ * test/test_process.rb
data/README CHANGED
@@ -1,12 +1,10 @@
1
1
  = Description
2
- This library provides the fork, wait, wait2, waitpid, and waitpid2 methods
3
- for MS Windows. In addition, it provides a different implementation of the
4
- kill method, a proper implementation of Process.ppid, and decent analogues
5
- of Process.getpriority, Process.setpriority, Process.getrlimit and
6
- Process.setrlimit.
7
-
2
+ This library provides analogues of the :getpriority, :setpriority, :getrlimit,
3
+ :setrlimit and :uid methods for MS Windows. It also adds the new methods :job?,
4
+ :get_affinity, and :create, and redefines the :kill method.
5
+
8
6
  = Prerequisites
9
- * windows-pr
7
+ * ffi
10
8
  * sys-proctable (dev only)
11
9
  * test-unit 2 (dev only)
12
10
 
@@ -19,92 +17,53 @@
19
17
  = Synopsis
20
18
  require 'win32/process'
21
19
 
22
- Process.fork{
23
- 3.times{
24
- puts 'In the child'
25
- sleep 1
26
- }
27
- }
20
+ p Process.job? # => true or false
28
21
 
29
- Process.wait
30
- puts 'Done'
31
-
32
- = Developer's Notes
33
- == The Process.fork and Process.wait methods
34
- The fork method is emulated on Windows by spawning another Ruby process
35
- against $PROGRAM_NAME via the CreateProcess() Win32 API function. It will
36
- use its parent's environment and starting directory.
37
-
38
- The various wait methods are a wrapper for the WaitForSingleObject() or
39
- WaitForMultipleObjects() Win32 API functions, for the wait* and waitpid*
40
- methods, respectively. In the case of wait2 and waitpid2, the exit value
41
- is returned via the GetExitCodeProcess() Win32API function.
42
-
43
- For now the waitpid and waitpid2 calls do not accept a second argument.
44
- That's because we haven't yet determined if there's a signal we should
45
- allow to be sent.
22
+ info = Process.create(
23
+ :app_name => "notepad.exe",
24
+ :creation_flags => Process::DETACHED_PROCESS,
25
+ :process_inherit => false,
26
+ :thread_inherit => true,
27
+ :cwd => "C:\\"
28
+ )
46
29
 
47
- IMPORTANT!
48
- Note that because fork is calling CreateProcess($PROGRAM_NAME), it will
49
- start again from the top of the script instead of from the point of the
50
- call. We will try to address this in a future release, if possible.
30
+ p info.process_id
51
31
 
52
- == The Process.kill method
53
- Initially, the kill method will try to get a HANDLE on the PID using the
54
- OpenProcess() function. If that succeeds, we know the process is running.
55
-
56
- In the event of signal 2 or signal 3, the GenerateConsoleCtrlEvent()
57
- function is used to send a signal to that process. These will not kill
58
- GUI processes. It will not (currently) send a signal to remote
59
- processes.
60
-
61
- In the event of signal 1 or 4-8, the CreateRemoteThread() function is used
62
- after the HANDLE's process has been identified to create a thread
63
- within that process. The ExitProcess() function is then sent to that
64
- thread.
65
-
66
- In the event of signal 9, the TerminateProcess() function is called. This
67
- will almost certainly kill the process, but doesn't give the process a
68
- chance to necessarily do any cleanup it might otherwise do.
32
+ = Developer's Notes
33
+ == Removal of Process.fork in release 0.7.0
34
+ The Process.fork method was originally experimental but it has never
35
+ been particularly useful in practice. On top of that, it required special
36
+ implementations of the Process.waitXXX methods, so it was a maintenance
37
+ issue as well.
69
38
 
70
- == The Process.ppid method
71
- In MRI the Process.ppid always returns 0 on MS Windows. With this library
72
- it returns the actual parent pid.
39
+ With Ruby 1.9 now becoming standard and its addition of Process.spawn
40
+ and friends (and concomitant support for the Process.waitXXX methods) I
41
+ felt it was time to remove it.
73
42
 
74
- == Differences between Ruby's kill and the Win32 Utils kill
75
- Ruby does not currently use the CreateRemoteThread() + ExitProcess()
76
- approach which is, according to everything I've read, a cleaner approach.
77
- This includes not only online research but also Jeffrey Richter's
78
- "Advanced Windows Programming, 3rd Edition."
43
+ You can still simulate Process.fork if you like using Process.create, which
44
+ is how it was implemented internally anyway. A better solution might be
45
+ to follow in the footsteps of ActiveState Perl, which uses native threads
46
+ to simulate fork on Windows.
79
47
 
80
- Also, the way Process.kill handles multiple pids works slightly differently
81
- (and better IMHO) in the Win32 Utils version than the way Ruby currently
82
- provides.
48
+ == Changes in the custom Process.kill method for 0.7.0
49
+ The Process.kill method in 0.7.0 more closely matches the spec now, but
50
+ the internal method for killing processes is still nicer for most signals.
51
+ With the release of 0.7.0 users can now specify options that provide finer
52
+ control over how a process is killed. See the documentation for details.
53
+
54
+ == The removal of the custom Process.ppid method
55
+ This was added at some point in the Ruby 1.9 dev cycle so it was removed
56
+ from this library.
83
57
 
84
- The reason Process.kill was originally added, in case anyone cares for
85
- historical trivia, is that Ruby 1.6.x did not support Process.kill on
86
- Windows at all.
87
-
88
- = Notes
89
- It is unlikely you will be able to kill system processes with this module.
90
- It's probably better that you don't.
91
-
92
58
  = Known Bugs
93
- None known (though please see the +Details+ section for quirks). Any
94
- bugs should be reported on the project page at
95
- http://rubyforge.org/projects/win32utils.
96
-
97
- = Future Plans
98
- Train Process.fork to execute from the point of the call rather than the
99
- top of the script (if possible).
100
-
101
- Other suggestions welcome.
59
+ None known. Any bugs should be reported on the project page at
60
+ https://github.com/djberg96/win32-process.
102
61
 
103
62
  = License
104
63
  Artistic 2.0
105
64
 
106
65
  = Copyright
107
- (C) 2003-2011 Daniel J. Berger
66
+ (C) 2003-2012 Daniel J. Berger
108
67
  All Rights Reserved
109
68
 
110
69
  = Warranty
data/Rakefile CHANGED
@@ -4,7 +4,7 @@ require 'rake/testtask'
4
4
  require 'rbconfig'
5
5
  include RbConfig
6
6
 
7
- CLEAN.include('**/*.gem', '**/*.rbc')
7
+ CLEAN.include('**/*.gem', '**/*.rbc', '**/*.log')
8
8
 
9
9
  namespace :gem do
10
10
  desc 'Create the win32-process gem'
@@ -42,6 +42,14 @@ namespace :example do
42
42
  end
43
43
  end
44
44
 
45
+ namespace :test do
46
+ Rake::TestTask.new(:kill) do |t|
47
+ t.verbose = true
48
+ t.warning = true
49
+ t.test_files = FileList['test/test_win32_process_kill.rb']
50
+ end
51
+ end
52
+
45
53
  Rake::TestTask.new do |t|
46
54
  t.verbose = true
47
55
  t.warning = true
@@ -1,35 +1,35 @@
1
- ##########################################################################
2
- # example_create.rb
3
- #
4
- # Simple test program for the Process.create() method. You can run this
5
- # code via the 'example:create' task.
6
- ##########################################################################
7
- require "win32/process"
8
-
9
- p Process::WIN32_PROCESS_VERSION
10
-
11
- struct = Process.create(
12
- :app_name => "notepad.exe",
13
- :creation_flags => Process::DETACHED_PROCESS,
14
- :process_inherit => false,
15
- :thread_inherit => true,
16
- :cwd => "C:\\",
17
- :inherit => true,
18
- :environment => "SYSTEMROOT=#{ENV['SYSTEMROOT']};PATH=C:\\"
19
- )
20
-
21
- p struct
22
-
23
- =begin
24
- # Don't run this from an existing terminal
25
- pid = Process.create(
26
- :app_name => "cmd.exe",
27
- :creation_flags => Process::DETACHED_PROCESS,
28
- :startf_flags => Process::USEPOSITION,
29
- :x => 0,
30
- :y => 0,
31
- :title => "Hi Dan"
32
- )
33
-
34
- puts "Pid of new process: #{pid}"
35
- =end
1
+ ##########################################################################
2
+ # example_create.rb
3
+ #
4
+ # Simple test program for the Process.create() method. You can run this
5
+ # code via the 'example:create' task.
6
+ ##########################################################################
7
+ require "win32/process"
8
+
9
+ p Process::WIN32_PROCESS_VERSION
10
+
11
+ struct = Process.create(
12
+ :app_name => "notepad.exe",
13
+ :creation_flags => Process::DETACHED_PROCESS,
14
+ :process_inherit => false,
15
+ :thread_inherit => true,
16
+ :cwd => "C:\\",
17
+ :inherit => true,
18
+ :environment => "SYSTEMROOT=#{ENV['SYSTEMROOT']};PATH=C:\\"
19
+ )
20
+
21
+ p struct
22
+
23
+ =begin
24
+ # Don't run this from an existing terminal
25
+ pid = Process.create(
26
+ :app_name => "cmd.exe",
27
+ :creation_flags => Process::DETACHED_PROCESS,
28
+ :startf_flags => Process::USEPOSITION,
29
+ :x => 0,
30
+ :y => 0,
31
+ :title => "Hi Dan"
32
+ )
33
+
34
+ puts "Pid of new process: #{pid}"
35
+ =end
@@ -1,34 +1,34 @@
1
- ##########################################################################
2
- # example_kill.rb
3
- #
4
- # Generic test script for futzing around Process.kill. This script
5
- # requires the sys-proctable library.
6
- #
7
- # You can run this example via the 'example:kill' task.
8
- ##########################################################################
9
- require "win32/process"
10
-
11
- begin
12
- require "sys/proctable"
13
- rescue LoadError
14
- STDERR.puts "Whoa there!"
15
- STDERR.puts "This script requires the sys-proctable package to work."
16
- STDERR.puts "You can find it at http://ruby-sysutils.sf.net"
17
- STDERR.puts "Exiting..."
18
- exit
19
- end
20
-
21
- include Sys
22
-
23
- puts "VERSION: " + Process::WIN32_PROCESS_VERSION
24
-
25
- IO.popen("notepad")
26
- sleep 1 # Give it a chance to start before checking for its pid
27
-
28
- pids = []
29
-
30
- ProcTable.ps{ |s|
31
- pids.push(s.pid) if s.cmdline =~ /notepad/i
32
- }
33
-
34
- p Process.kill(9,pids.last)
1
+ ##########################################################################
2
+ # example_kill.rb
3
+ #
4
+ # Generic test script for futzing around Process.kill. This script
5
+ # requires the sys-proctable library.
6
+ #
7
+ # You can run this example via the 'example:kill' task.
8
+ ##########################################################################
9
+ require "win32/process"
10
+
11
+ begin
12
+ require "sys/proctable"
13
+ rescue LoadError
14
+ STDERR.puts "Whoa there!"
15
+ STDERR.puts "This script requires the sys-proctable package to work."
16
+ STDERR.puts "You can find it at http://ruby-sysutils.sf.net"
17
+ STDERR.puts "Exiting..."
18
+ exit
19
+ end
20
+
21
+ include Sys
22
+
23
+ puts "VERSION: " + Process::WIN32_PROCESS_VERSION
24
+
25
+ IO.popen("notepad")
26
+ sleep 1 # Give it a chance to start before checking for its pid
27
+
28
+ pids = []
29
+
30
+ ProcTable.ps{ |s|
31
+ pids.push(s.pid) if s.cmdline =~ /notepad/i
32
+ }
33
+
34
+ p Process.kill(9,pids.last)
@@ -0,0 +1,105 @@
1
+ module Process::Constants
2
+ private
3
+
4
+ # Priority constants
5
+
6
+ ABOVE_NORMAL_PRIORITY_CLASS = 0x0008000
7
+ BELOW_NORMAL_PRIORITY_CLASS = 0x0004000
8
+ HIGH_PRIORITY_CLASS = 0x0000080
9
+ IDLE_PRIORITY_CLASS = 0x0000040
10
+ NORMAL_PRIORITY_CLASS = 0x0000020
11
+ REALTIME_PRIORITY_CLASS = 0x0000010
12
+
13
+ # Error constants
14
+
15
+ INVALID_HANDLE_VALUE = 0xffffffff
16
+ ERROR_ACCESS_DENIED = 0x00000005
17
+
18
+ # Process Access Rights
19
+
20
+ PROCESS_TERMINATE = 0x00000001
21
+ PROCESS_SET_INFORMATION = 0x00000200
22
+ PROCESS_QUERY_INFORMATION = 0x00000400
23
+ PROCESS_ALL_ACCESS = 0x001F0FFF
24
+ PROCESS_VM_READ = 0x00000010
25
+
26
+ # Process wait time for Process.kill
27
+
28
+ INFINITE = 0xFFFFFFFF
29
+
30
+ # Process creation flags
31
+
32
+ CREATE_BREAKAWAY_FROM_JOB = 0x01000000
33
+ CREATE_DEFAULT_ERROR_MODE = 0x04000000
34
+ CREATE_NEW_CONSOLE = 0x00000010
35
+ CREATE_NEW_PROCESS_GROUP = 0x00000200
36
+ CREATE_NO_WINDOW = 0x08000000
37
+ CREATE_PROTECTED_PROCESS = 0x00040000
38
+ CREATE_PRESERVE_CODE_AUTHZ_LEVEL = 0x02000000
39
+ CREATE_SEPARATE_WOW_VDM = 0x00000800
40
+ CREATE_SHARED_WOW_VDM = 0x00001000
41
+ CREATE_SUSPENDED = 0x00000004
42
+ CREATE_UNICODE_ENVIRONMENT = 0x00000400
43
+ DEBUG_ONLY_THIS_PROCESS = 0x00000002
44
+ DEBUG_PROCESS = 0x00000001
45
+ DETACHED_PROCESS = 0x00000008
46
+ INHERIT_PARENT_AFFINITY = 0x00010000
47
+
48
+ STARTF_USESHOWWINDOW = 0x00000001
49
+ STARTF_USESIZE = 0x00000002
50
+ STARTF_USEPOSITION = 0x00000004
51
+ STARTF_USECOUNTCHARS = 0x00000008
52
+ STARTF_USEFILLATTRIBUTE = 0x00000010
53
+ STARTF_RUNFULLSCREEN = 0x00000020
54
+ STARTF_FORCEONFEEDBACK = 0x00000040
55
+ STARTF_FORCEOFFFEEDBACK = 0x00000080
56
+ STARTF_USESTDHANDLES = 0x00000100
57
+ STARTF_USEHOTKEY = 0x00000200
58
+ STARTF_TITLEISLINKNAME = 0x00000800
59
+ STARTF_TITLEISAPPID = 0x00001000
60
+ STARTF_PREVENTPINNING = 0x00002000
61
+
62
+ LOGON_WITH_PROFILE = 0x00000001
63
+ LOGON_NETCREDENTIALS_ONLY = 0x00000002
64
+
65
+ SHUTDOWN_NORETRY = 0x00000001
66
+
67
+ # Security
68
+
69
+ TokenUser = 1
70
+ TOKEN_QUERY = 0x00000008
71
+
72
+ # Define these for Windows. They are not actually used but are defined
73
+ # for interface compatibility.
74
+
75
+ PRIO_PROCESS = 0
76
+ PRIO_PGRP = 1
77
+ PRIO_USER = 2
78
+
79
+ # Define these for Windows
80
+
81
+ RLIMIT_CPU = 0 # PerProcessUserTimeLimit
82
+ RLIMIT_FSIZE = 1 # Hard coded at 4TB - 64K (assumes NTFS)
83
+ RLIMIT_AS = 5 # ProcessMemoryLimit
84
+ RLIMIT_RSS = 5 # ProcessMemoryLimit
85
+ RLIMIT_VMEM = 5 # ProcessMemoryLimit
86
+
87
+ # Job constants
88
+
89
+ JOB_OBJECT_SET_ATTRIBUTES = 0x00000002
90
+ JOB_OBJECT_QUERY = 0x00000004
91
+ JOB_OBJECT_LIMIT_PROCESS_TIME = 0x00000002
92
+ JOB_OBJECT_LIMIT_PROCESS_MEMORY = 0x00000100
93
+ JobObjectExtendedLimitInformation = 9
94
+
95
+ # Console Events
96
+
97
+ CTRL_C_EVENT = 0
98
+ CTRL_BREAK_EVENT = 1
99
+
100
+ # Miscellaneous
101
+
102
+ HANDLE_FLAG_INHERIT = 0x00000001
103
+ SEM_FAILCRITICALERRORS = 0x00000001
104
+ SEM_NOGPFAULTERRORBOX = 0x00000002
105
+ end
@@ -0,0 +1,66 @@
1
+ if RUBY_PLATFORM == 'java'
2
+ require 'rubygems'
3
+ gem 'ffi'
4
+ end
5
+
6
+ require 'ffi'
7
+
8
+ module Process::Functions
9
+ module FFI::Library
10
+ # Wrapper method for attach_function + private
11
+ def attach_pfunc(*args)
12
+ attach_function(*args)
13
+ private args[0]
14
+ end
15
+ end
16
+
17
+ extend FFI::Library
18
+
19
+ ffi_lib :kernel32
20
+
21
+ attach_pfunc :CloseHandle, [:ulong], :bool
22
+ attach_pfunc :GenerateConsoleCtrlEvent, [:ulong, :ulong], :bool
23
+ attach_pfunc :GetCurrentProcess, [], :ulong
24
+ attach_pfunc :GetModuleHandle, :GetModuleHandleA, [:string], :ulong
25
+ attach_pfunc :GetProcessAffinityMask, [:ulong, :pointer, :pointer], :bool
26
+ attach_pfunc :GetPriorityClass, [:ulong], :ulong
27
+ attach_pfunc :GetProcAddress, [:ulong, :string], :ulong
28
+ attach_pfunc :IsProcessInJob, [:ulong, :pointer, :pointer], :void
29
+ attach_pfunc :OpenProcess, [:ulong, :bool, :ulong], :ulong
30
+ attach_pfunc :SetHandleInformation, [:ulong, :ulong, :ulong], :bool
31
+ attach_pfunc :SetErrorMode, [:uint], :uint
32
+ attach_pfunc :SetPriorityClass, [:ulong, :ulong], :bool
33
+ attach_pfunc :TerminateProcess, [:ulong, :uint], :bool
34
+ attach_pfunc :WaitForSingleObject, [:ulong, :ulong], :ulong
35
+
36
+ attach_pfunc :CreateRemoteThread,
37
+ [:ulong, :pointer, :size_t, :ulong, :pointer, :ulong, :pointer], :ulong
38
+
39
+ attach_pfunc :GetVolumeInformationA,
40
+ [:string, :pointer, :ulong, :pointer, :pointer, :pointer, :pointer, :ulong], :bool
41
+
42
+ attach_pfunc :CreateProcessW,
43
+ [:buffer_in, :buffer_in, :pointer, :pointer, :bool,
44
+ :ulong, :buffer_in, :buffer_in, :pointer, :pointer], :bool
45
+
46
+ attach_pfunc :AssignProcessToJobObject, [:ulong, :ulong], :bool
47
+ attach_pfunc :CreateJobObjectA, [:pointer, :string], :ulong
48
+ attach_pfunc :OpenJobObjectA, [:ulong, :bool, :string], :ulong
49
+ attach_pfunc :QueryInformationJobObject, [:ulong, :int, :pointer, :ulong, :pointer], :bool
50
+ attach_pfunc :SetInformationJobObject, [:ulong, :int, :pointer, :ulong], :bool
51
+
52
+ ffi_lib :advapi32
53
+
54
+ attach_pfunc :ConvertSidToStringSidA, [:buffer_in, :pointer], :bool
55
+ attach_pfunc :GetTokenInformation, [:ulong, :int, :pointer, :ulong, :pointer], :bool
56
+ attach_pfunc :OpenProcessToken, [:ulong, :ulong, :pointer], :bool
57
+
58
+ attach_pfunc :CreateProcessWithLogonW,
59
+ [:buffer_in, :buffer_in, :buffer_in, :ulong, :buffer_in, :buffer_in,
60
+ :ulong, :buffer_in, :buffer_in, :pointer, :pointer], :bool
61
+
62
+ ffi_lib FFI::Library::LIBC
63
+
64
+ attach_pfunc :get_errno, :_get_errno, [:pointer], :int
65
+ attach_pfunc :get_osfhandle, :_get_osfhandle, [:int], :ulong
66
+ end
@@ -0,0 +1,13 @@
1
+ class String
2
+ # Convert a regular string to a wide character string. This does not
3
+ # modify the receiver.
4
+ def to_wide_string
5
+ (self + 0.chr).encode('UTF-16LE')
6
+ end
7
+
8
+ # Convert a regular string to a wide character string. This modifies
9
+ # the receiver.
10
+ def to_wide_string!
11
+ replace((self + 0.chr).encode('UTF-16LE'))
12
+ end
13
+ end
@@ -0,0 +1,103 @@
1
+ if RUBY_PLATFORM == 'java'
2
+ require 'rubygems'
3
+ gem 'ffi'
4
+ end
5
+
6
+ require 'ffi'
7
+
8
+ module Process::Structs
9
+ extend FFI::Library
10
+
11
+ private
12
+
13
+ # sizeof(LARGE_INTEGER) == 8
14
+ class LARGE_INTEGER < FFI::Union
15
+ layout(:QuadPart, :long_long)
16
+ end
17
+
18
+ # sizeof(IO_COUNTERS) == 48
19
+ class IO_COUNTERS < FFI::Struct
20
+ layout(
21
+ :ReadOperationCount, :ulong_long,
22
+ :WriteOperationCount, :ulong_long,
23
+ :OtherOperationCount, :ulong_long,
24
+ :ReadTransferCount, :ulong_long,
25
+ :WriteTransferCount, :ulong_long,
26
+ :OtherTransferCount, :ulong_long
27
+ )
28
+ end
29
+
30
+ class JOBJECT_BASIC_LIMIT_INFORMATION < FFI::Struct
31
+ layout(
32
+ :PerProcessUserTimeLimit, LARGE_INTEGER,
33
+ :PerJobUserTimeLimit, LARGE_INTEGER,
34
+ :LimitFlags, :ulong,
35
+ :MinimumWorkingSetSize, :size_t,
36
+ :MaximumWorkingSetSize, :size_t,
37
+ :ActiveProcessLimit, :ulong,
38
+ :Affinity, :pointer,
39
+ :PriorityClass, :ulong,
40
+ :SchedulingClass, :ulong
41
+ )
42
+ end
43
+
44
+ class JOBJECT_EXTENDED_LIMIT_INFORMATION < FFI::Struct
45
+ layout(
46
+ :BasicLimitInformation, JOBJECT_BASIC_LIMIT_INFORMATION,
47
+ :IoInfo, IO_COUNTERS,
48
+ :ProcessMemoryLimit, :size_t,
49
+ :JobMemoryLimit, :size_t,
50
+ :PeakProcessMemoryUsed, :size_t,
51
+ :PeakJobMemoryUsed, :size_t
52
+ )
53
+ end
54
+
55
+ class SECURITY_ATTRIBUTES < FFI::Struct
56
+ layout(
57
+ :nLength, :ulong,
58
+ :lpSecurityDescriptor, :pointer,
59
+ :bInheritHandle, :bool
60
+ )
61
+ end
62
+
63
+ # sizeof(STARTUPINFO) == 68
64
+ class STARTUPINFO < FFI::Struct
65
+ layout(
66
+ :cb, :ulong,
67
+ :lpReserved, :string,
68
+ :lpDesktop, :string,
69
+ :lpTitle, :string,
70
+ :dwX, :ulong,
71
+ :dwY, :ulong,
72
+ :dwXSize, :ulong,
73
+ :dwYSize, :ulong,
74
+ :dwXCountChars, :ulong,
75
+ :dwYCountChars, :ulong,
76
+ :dwFillAttribute, :ulong,
77
+ :dwFlags, :ulong,
78
+ :wShowWindow, :short,
79
+ :cbReserved2, :short,
80
+ :lpReserved2, :pointer,
81
+ :hStdInput, :ulong,
82
+ :hStdOutput, :ulong,
83
+ :hStdError, :ulong
84
+ )
85
+ end
86
+
87
+ class PROCESS_INFORMATION < FFI::Struct
88
+ layout(
89
+ :hProcess, :ulong,
90
+ :hThread, :ulong,
91
+ :dwProcessId, :ulong,
92
+ :dwThreadId, :ulong
93
+ )
94
+ end
95
+
96
+ # Used by Process.create
97
+ ProcessInfo = Struct.new("ProcessInfo",
98
+ :process_handle,
99
+ :thread_handle,
100
+ :process_id,
101
+ :thread_id
102
+ )
103
+ end