Module: Puppet::Util::Windows::Process
- Extended by:
- Windows::Handle, Windows::Process, Windows::Synchronize
- Defined in:
- lib/puppet/util/windows/process.rb
Defined Under Namespace
Modules: API
Constant Summary collapse
- TOKEN_ALL_ACCESS =
0xF01FF- ERROR_NO_SUCH_PRIVILEGE =
1313
Class Method Summary collapse
- .execute(command, arguments, stdin, stdout, stderr) ⇒ Object
- .get_current_process ⇒ Object
- .get_token_information(token_handle, token_information) ⇒ Object
- .lookup_privilege_value(name, system_name = '') ⇒ Object
- .open_process_token(handle, desired_access) ⇒ Object
- .process_privilege_symlink? ⇒ Boolean
- .wait_process(handle) ⇒ Object
Class Method Details
.execute(command, arguments, stdin, stdout, stderr) ⇒ Object
122 123 124 |
# File 'lib/puppet/util/windows/process.rb', line 122 def execute(command, arguments, stdin, stdout, stderr) Process.create( :command_line => command, :startup_info => {:stdin => stdin, :stdout => stdout, :stderr => stderr}, :close_handles => false ) end |
.get_current_process ⇒ Object
148 149 150 151 |
# File 'lib/puppet/util/windows/process.rb', line 148 def get_current_process # this pseudo-handle does not require closing per MSDN docs API.get_current_process end |
.get_token_information(token_handle, token_information) ⇒ Object
184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 |
# File 'lib/puppet/util/windows/process.rb', line 184 def get_token_information(token_handle, token_information) # to determine buffer size return_length_ptr = FFI::MemoryPointer.new(:uint, 1) result = API.get_token_information(token_handle, token_information, nil, 0, return_length_ptr) return_length = return_length_ptr.read_uint if return_length <= 0 raise Puppet::Util::Windows::Error.new( "GetTokenInformation(#{token_handle}, #{token_information}, nil, 0, #{return_length_ptr})") end # re-call API with properly sized buffer for all results token_information_buf = FFI::MemoryPointer.new(return_length) result = API.get_token_information(token_handle, token_information, token_information_buf, return_length, return_length_ptr) if !result raise Puppet::Util::Windows::Error.new( "GetTokenInformation(#{token_handle}, #{token_information}, #{token_information_buf}, " + "#{return_length}, #{return_length_ptr})") end raw_privileges = API::Token_Privileges.new(token_information_buf) privileges = { :count => raw_privileges[:privilege_count], :privileges => [] } offset = token_information_buf + API::Token_Privileges.offset_of(:privileges) privilege_ptr = FFI::Pointer.new(API::LUID_And_Attributes, offset) # extract each instance of LUID_And_Attributes 0.upto(privileges[:count] - 1) do |i| privileges[:privileges] << API::LUID_And_Attributes.new(privilege_ptr[i]) end privileges end |
.lookup_privilege_value(name, system_name = '') ⇒ Object
170 171 172 173 174 175 176 177 178 179 180 181 |
# File 'lib/puppet/util/windows/process.rb', line 170 def lookup_privilege_value(name, system_name = '') luid = FFI::MemoryPointer.new(API::LUID.size) result = API.lookup_privilege_value( system_name, name.to_s, luid ) return API::LUID.new(luid) if result raise Puppet::Util::Windows::Error.new( "LookupPrivilegeValue(#{system_name}, #{name}, #{luid})") end |
.open_process_token(handle, desired_access) ⇒ Object
154 155 156 157 158 159 160 161 162 163 164 165 166 167 |
# File 'lib/puppet/util/windows/process.rb', line 154 def open_process_token(handle, desired_access) token_handle_ptr = FFI::MemoryPointer.new(:uint, 1) result = API.open_process_token(handle, desired_access, token_handle_ptr) if !result raise Puppet::Util::Windows::Error.new( "OpenProcessToken(#{handle}, #{desired_access.to_s(8)}, #{token_handle_ptr})") end begin yield token_handle = token_handle_ptr.read_uint ensure API.close_handle(token_handle) end end |
.process_privilege_symlink? ⇒ Boolean
223 224 225 226 227 228 229 230 231 232 233 234 235 236 |
# File 'lib/puppet/util/windows/process.rb', line 223 def process_privilege_symlink? handle = get_current_process open_process_token(handle, TOKEN_ALL_ACCESS) do |token_handle| luid = lookup_privilege_value('SeCreateSymbolicLinkPrivilege') token_info = get_token_information(token_handle, :token_privileges) token_info[:privileges].any? { |p| p[:luid].values == luid.values } end rescue Puppet::Util::Windows::Error => e if e.code == ERROR_NO_SUCH_PRIVILEGE false # pre-Vista else raise e end end |
.wait_process(handle) ⇒ Object
127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 |
# File 'lib/puppet/util/windows/process.rb', line 127 def wait_process(handle) while WaitForSingleObject(handle, 0) == Windows::Synchronize::WAIT_TIMEOUT sleep(1) end exit_status = [0].pack('L') unless GetExitCodeProcess(handle, exit_status) raise Puppet::Util::Windows::Error.new("Failed to get child process exit code") end exit_status = exit_status.unpack('L').first # $CHILD_STATUS is not set when calling win32/process Process.create # and since it's read-only, we can't set it. But we can execute a # a shell that simply returns the desired exit status, which has the # desired effect. %x{#{ENV['COMSPEC']} /c exit #{exit_status}} exit_status end |