win32-process 0.5.4 → 0.5.5

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,3 +1,10 @@
1
+ == 0.5.5 - 12-Dec-2007
2
+ * The Process.create method now automatically closes the process and thread
3
+ handles in the ProcessInfo struct before returning, unless you explicitly
4
+ tell it not to via the 'close_handles' option.
5
+ * The Process.create method now supports creating a process as another user
6
+ via the 'with_logon', 'password' and 'domain' options.
7
+
1
8
  == 0.5.4 - 23-Nov-2007
2
9
  * Changed ProcessError to Process::Error.
3
10
  * Now requires windows-pr 0.7.3 or later because of some reorganization in
data/lib/win32/process.rb CHANGED
@@ -6,11 +6,12 @@ require 'windows/handle'
6
6
  require 'windows/library'
7
7
  require 'windows/console'
8
8
  require 'windows/window'
9
+ require 'windows/unicode'
9
10
 
10
11
  module Process
11
12
  class Error < RuntimeError; end
12
13
 
13
- WIN32_PROCESS_VERSION = '0.5.4'
14
+ WIN32_PROCESS_VERSION = '0.5.5'
14
15
 
15
16
  include Windows::Process
16
17
  include Windows::Thread
@@ -20,6 +21,7 @@ module Process
20
21
  include Windows::Handle
21
22
  include Windows::Synchronize
22
23
  include Windows::Window
24
+ include Windows::Unicode
23
25
  extend Windows::Error
24
26
  extend Windows::Process
25
27
  extend Windows::Thread
@@ -27,6 +29,7 @@ module Process
27
29
  extend Windows::Handle
28
30
  extend Windows::Library
29
31
  extend Windows::Console
32
+ extend Windows::Unicode
30
33
 
31
34
  # Used by Process.create
32
35
  ProcessInfo = Struct.new("ProcessInfo",
@@ -216,9 +219,9 @@ module Process
216
219
 
217
220
  # Process.create(key => value, ...) => ProcessInfo
218
221
  #
219
- # This is a wrapper for the CreateProcess() function. It executes a process,
220
- # returning a ProcessInfo struct. It accepts a hash as an argument.
221
- # There are eight primary keys:
222
+ # This is a wrapper for the CreateProcess() function. It executes a process,
223
+ # returning a ProcessInfo struct. It accepts a hash as an argument.
224
+ # There are several primary keys:
222
225
  #
223
226
  # * app_name (mandatory)
224
227
  # * inherit (default: false)
@@ -228,12 +231,19 @@ module Process
228
231
  # * cwd (default: Dir.pwd)
229
232
  # * startup_info (default: nil)
230
233
  # * environment (default: nil)
234
+ # * close_handles (default: true)
235
+ # * with_logon (default: nil)
236
+ # * domain (default: nil)
237
+ # * password (default: nil)
231
238
  #
232
239
  # Of these, the 'app_name' must be specified or an error is raised.
240
+ #
241
+ # The 'domain' and 'password' options are only relevent in the context
242
+ # of 'with_logon'.
233
243
  #
234
- # The startup_info key takes a hash. Its keys are attributes that are
244
+ # The startup_info key takes a hash. Its keys are attributes that are
235
245
  # part of the StartupInfo struct, and are generally only meaningful for
236
- # GUI or console processes. See the documentation on CreateProcess()
246
+ # GUI or console processes. See the documentation on CreateProcess()
237
247
  # and the StartupInfo struct on MSDN for more information.
238
248
  #
239
249
  # * desktop
@@ -253,9 +263,9 @@ module Process
253
263
  #
254
264
  # The relevant constants for 'creation_flags', 'sw_flags' and 'startf_flags'
255
265
  # are included in the Windows::Process, Windows::Console and Windows::Window
256
- # modules. These come with the windows-pr package, a prerequisite of this
257
- # package. Note that the 'stdin', 'stdout' and 'stderr' options can be
258
- # either Ruby IO objects or file descriptors (i.e. a fileno). However,
266
+ # modules. These come with the windows-pr library, a prerequisite of this
267
+ # library. Note that the 'stdin', 'stdout' and 'stderr' options can be
268
+ # either Ruby IO objects or file descriptors (i.e. a fileno). However,
259
269
  # StringIO objects are not currently supported.
260
270
  #
261
271
  # The ProcessInfo struct contains the following members:
@@ -265,6 +275,13 @@ module Process
265
275
  # * process_id - Process ID.
266
276
  # * thread_id - Thread ID.
267
277
  #
278
+ # If the 'close_handles' option is set to true (the default) then the
279
+ # process_handle and the thread_handle are automatically closed for you
280
+ # before the ProcessInfo struct is returned.
281
+ #
282
+ # If the 'with_logon' option is set, then the process runs the specified
283
+ # executable file in the security context of the specified credentials.
284
+ #
268
285
  def create(args)
269
286
  unless args.kind_of?(Hash)
270
287
  raise TypeError, 'Expecting hash-style keyword arguments'
@@ -272,7 +289,8 @@ module Process
272
289
 
273
290
  valid_keys = %w/
274
291
  app_name inherit creation_flags cwd environment startup_info
275
- thread_inherit process_inherit
292
+ thread_inherit process_inherit close_handles with_logon domain
293
+ password
276
294
  /
277
295
 
278
296
  valid_si_keys = %/
@@ -280,15 +298,11 @@ module Process
280
298
  y_count_chars fill_attribute sw_flags stdin stdout stderr
281
299
  /
282
300
 
283
- # Set some default values
301
+ # Set default values
284
302
  hash = {
285
- 'inherit' => 0,
286
- 'process_inherit' => 0,
287
- 'thread_inherit' => 0,
288
- 'creation_flags' => 0,
289
- 'cwd' => 0
303
+ 'creation_flags' => 0,
304
+ 'close_handles' => true
290
305
  }
291
- env = 0
292
306
 
293
307
  # Validate the keys, and convert symbols and case to lowercase strings.
294
308
  args.each{ |key, val|
@@ -296,16 +310,7 @@ module Process
296
310
  unless valid_keys.include?(key)
297
311
  raise Error, "invalid key '#{key}'"
298
312
  end
299
-
300
- # Convert true to 1 and nil/false to 0.
301
- case val
302
- when true, false
303
- hash[key] = val == false ? 0 : 1
304
- when nil
305
- hash[key] = 0 # Win32API sometimes doesn't like nil
306
- else
307
- hash[key] = val
308
- end
313
+ hash[key] = val
309
314
  }
310
315
 
311
316
  si_hash = {}
@@ -330,7 +335,14 @@ module Process
330
335
  # paths.
331
336
  if hash['environment']
332
337
  env = hash['environment'].split(File::PATH_SEPARATOR) << 0.chr
333
- env = [env.join("\0")].pack('p*').unpack('L').first
338
+ if hash['with_logon']
339
+ env = env.map{ |e| multi_to_wide(e) }
340
+ env = [env.join("\0\0")].pack('p*').unpack('L').first
341
+ else
342
+ env = [env.join("\0")].pack('p*').unpack('L').first
343
+ end
344
+ else
345
+ env = nil
334
346
  end
335
347
 
336
348
  startinfo = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
@@ -390,23 +402,56 @@ module Process
390
402
  startinfo[64,4] = [si_hash['stderr']].pack('L') if si_hash['stderr']
391
403
  end
392
404
 
393
- bool = CreateProcess(
394
- 0, # App name
395
- hash['app_name'], # Command line
396
- process_security, # Process attributes
397
- thread_security, # Thread attributes
398
- hash['inherit'], # Inherit handles?
399
- hash['creation_flags'], # Creation flags
400
- env, # Environment
401
- hash['cwd'], # Working directory
402
- startinfo, # Startup Info
403
- procinfo # Process Info
404
- )
405
-
405
+ if hash['with_logon']
406
+ logon = multi_to_wide(hash['with_logon'])
407
+ domain = multi_to_wide(hash['domain'])
408
+ app = multi_to_wide(hash['app_name'])
409
+ cwd = multi_to_wide(hash['cwd'])
410
+ passwd = multi_to_wide(hash['password'])
411
+
412
+ hash['creation_flags'] |= CREATE_UNICODE_ENVIRONMENT
413
+
414
+ bool = CreateProcessWithLogonW(
415
+ logon, # User
416
+ domain, # Domain
417
+ passwd, # Password
418
+ LOGON_WITH_PROFILE, # Logon flags
419
+ nil, # App name
420
+ app, # Command line
421
+ hash['creation_flags'], # Creation flags
422
+ env, # Environment
423
+ cwd, # Working directory
424
+ startinfo, # Startup Info
425
+ procinfo # Process Info
426
+ )
427
+ else
428
+ bool = CreateProcess(
429
+ nil, # App name
430
+ hash['app_name'], # Command line
431
+ process_security, # Process attributes
432
+ thread_security, # Thread attributes
433
+ hash['inherit'], # Inherit handles?
434
+ hash['creation_flags'], # Creation flags
435
+ env, # Environment
436
+ hash['cwd'], # Working directory
437
+ startinfo, # Startup Info
438
+ procinfo # Process Info
439
+ )
440
+ end
441
+
442
+ # TODO: Close stdin, stdout and stderr handles in the si_hash unless
443
+ # they're pointing to one of the standard handles already.
406
444
  unless bool
407
445
  raise Error, "CreateProcess() failed: ", get_last_error
408
446
  end
409
447
 
448
+ # Automatically close the process and thread handles in the
449
+ # PROCESS_INFORMATION struct unless explicitly told not to.
450
+ if hash['close_handles']
451
+ CloseHandle(procinfo[8,4].unpack('L').first)
452
+ CloseHandle(procinfo[12,4].unpack('L').first)
453
+ end
454
+
410
455
  ProcessInfo.new(
411
456
  procinfo[0,4].unpack('L').first, # hProcess
412
457
  procinfo[4,4].unpack('L').first, # hThread
@@ -1,21 +1,22 @@
1
1
  require "rubygems"
2
2
 
3
3
  spec = Gem::Specification.new do |gem|
4
+ desc = "Adds create, fork, wait, wait2, waitpid, and a special kill method"
4
5
  gem.name = "win32-process"
5
- gem.version = "0.5.4"
6
+ gem.version = "0.5.5"
6
7
  gem.author = "Daniel J. Berger"
7
8
  gem.email = "djberg96@gmail.com"
8
9
  gem.homepage = "http://www.rubyforge.org/projects/win32utils"
9
10
  gem.platform = Gem::Platform::RUBY
10
- gem.summary = "Adds fork, wait, wait2, waitpid, waitpid2 and a special kill method"
11
- gem.description = "Adds fork, wait, wait2, waitpid, waitpid2 and a special kill method"
11
+ gem.summary = desc
12
+ gem.description = desc
12
13
  gem.test_file = "test/tc_process.rb"
13
14
  gem.has_rdoc = true
14
15
  gem.files = Dir["lib/win32/*.rb"] + Dir["test/*"] + Dir["[A-Z]*"]
15
16
  gem.files.reject! { |fn| fn.include? "CVS" }
16
17
  gem.require_path = "lib"
17
18
  gem.extra_rdoc_files = ["README", "CHANGES", "MANIFEST"]
18
- gem.add_dependency("windows-pr", ">= 0.7.3")
19
+ gem.add_dependency("windows-pr", ">= 0.7.4")
19
20
  end
20
21
 
21
22
  if $0 == __FILE__
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: win32-process
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.4
4
+ version: 0.5.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Daniel J. Berger
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2007-11-23 00:00:00 -07:00
12
+ date: 2007-12-12 00:00:00 -07:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -19,9 +19,9 @@ dependencies:
19
19
  requirements:
20
20
  - - ">="
21
21
  - !ruby/object:Gem::Version
22
- version: 0.7.3
22
+ version: 0.7.4
23
23
  version:
24
- description: Adds fork, wait, wait2, waitpid, waitpid2 and a special kill method
24
+ description: Adds create, fork, wait, wait2, waitpid, and a special kill method
25
25
  email: djberg96@gmail.com
26
26
  executables: []
27
27
 
@@ -69,6 +69,6 @@ rubyforge_project:
69
69
  rubygems_version: 0.9.5
70
70
  signing_key:
71
71
  specification_version: 2
72
- summary: Adds fork, wait, wait2, waitpid, waitpid2 and a special kill method
72
+ summary: Adds create, fork, wait, wait2, waitpid, and a special kill method
73
73
  test_files:
74
74
  - test/tc_process.rb