win32-process 0.5.4 → 0.5.5

Sign up to get free protection for your applications and to get access to all the features.
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