Class: HawatelPS::Windows::ProcFetch

Inherits:
Object
  • Object
show all
Defined in:
lib/hawatel_ps/windows/proc_fetch.rb

Overview

Process Fetch

Provides functionality to fetch process information from raw source using WMI client.

Class Method Summary collapse

Class Method Details

.cpu_percent(cpu_time) ⇒ String (private)

Calculate %CPU usage per process

Parameters:

  • cpu_time (String/Integer)

    CPU time consumed by process since system boot

Returns:

  • (String)

    %CPU usage per process since system boot



197
198
199
200
201
202
203
# File 'lib/hawatel_ps/windows/proc_fetch.rb', line 197

def cpu_percent(cpu_time)
  if !cpu_time.zero?
    return (( cpu_time.to_f  / @system_idle_time.to_f) * 100).round(2).to_s
  else
    return "0.0"
  end
end

.cpu_time(args) ⇒ Integer (private)

Reports processor use time, in seconds, for each process running on a computer.

Parameters:

  • args (Hash)

    attributes

  • opt (Hash)

    a customizable set of options

Returns:

  • (Integer)

    processor time for a process in seconds

See Also:



211
212
213
# File 'lib/hawatel_ps/windows/proc_fetch.rb', line 211

def cpu_time(args)
  return ((args[:usermodetime].to_i + args[:kernelmodetime].to_i) / 10000000)
end

.extract_wmi_property(wmi_object) ⇒ Hash (private)

Get property from WIN32OLE object about process

Examples:

extract_wmi_property(wmi_object)

Parameters:

Returns:

  • (Hash)


92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
# File 'lib/hawatel_ps/windows/proc_fetch.rb', line 92

def extract_wmi_property(wmi_object)
  property_map = wmi_object.properties.dup
  property_map[:wmi_object] = wmi_object.wmi_ole_object
  property_map[:childs] = Array.new

  property_map[:sid] = get_owner_sid(wmi_object)

  get_owner(property_map)
  property_map[:availablevirtualsize] = get_avail_virtual_size(wmi_object)
  property_map[:memorypercent] = memory_percent(@memory_total, property_map[:workingsetsize])

  property_map[:cpupercent] = cpu_percent(cpu_time(
      :usermodetime => property_map[:usermodetime],
      :kernelmodetime => property_map[:kernelmodetime]))

  hash_value_to_string(property_map)

  property_map.delete(:status) if property_map.key?(:status)

  property_map
end

.get_avail_virtual_size(wmi_object) ⇒ String (private)

Invoke GetAvailableVirtualSize method of the Win32_Process class

Parameters:

Returns:

  • (String)

    AvailableVirtualSize from WMI

See Also:



161
162
163
164
165
166
# File 'lib/hawatel_ps/windows/proc_fetch.rb', line 161

def get_avail_virtual_size(wmi_object)
  obj = wmi_object.execMethod('GetAvailableVirtualSize')
  return obj.AvailableVirtualSize.to_s if !obj.nil?
rescue WmiCliException
  return nil
end

.get_owner(property_map) ⇒ Object (private)

Find information about user instance variable @users_list must be set get_users

Parameters:

  • property_map (Hash)

    Atributes of process



133
134
135
136
137
138
139
140
141
# File 'lib/hawatel_ps/windows/proc_fetch.rb', line 133

def get_owner(property_map)
  property_map[:user] = nil
  property_map[:domain] = nil

  if !property_map[:sid].nil? and !@users_list[property_map[:sid]].nil?
    property_map[:user] = @users_list[property_map[:sid]][:name]
    property_map[:domain] = @users_list[property_map[:sid]][:domain]
  end
end

.get_owner_sid(wmi_object) ⇒ String (private)

Invoke GetOwnerSid method of the Win32_Process class

Parameters:

Returns:

  • (String)

    SID of user

See Also:



148
149
150
151
152
153
154
# File 'lib/hawatel_ps/windows/proc_fetch.rb', line 148

def get_owner_sid(wmi_object)
  # TODO performance problem (it takes ~10 seconds but the native wmi takes similar time)
  owner = wmi_object.execMethod('GetOwnerSid')
  return owner.Sid if !owner.nil?
rescue WmiCliException
  return nil
end

.get_process(args = nil) ⇒ Array<Hash>

Return attributes of all processes from WMI

Each process has attributes which are standardized in this document: msdn.microsoft.com/en-us/library/windows/desktop/aa394372 Each attribute name is converted to lowercase.

Examples:

Get process list (access to attributes by index array)

processes = get_process()
processes.each do | process |
  pid = process['processid']
  name = process['name']
  puts "#{pid.to_s.ljust(10)} #{name}"
end

Get process list (access to attributes by methods)

processes = get_process()
processes.each do | process |
  pid = process.processid
  name = process.name
  puts "#{pid.to_s.ljust(10)} #{name}"
end

Returns:

  • (Array<Hash>)


32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
# File 'lib/hawatel_ps/windows/proc_fetch.rb', line 32

def get_process(args = nil)
  if args.nil?
    wql = prepare_wql("SELECT * FROM Win32_Process")
  else
    wql = prepare_wql('SELECT * FROM Win32_Process', args)
  end

  proc_table = Array.new

  # TODO maybe the better way will be put user info to class variable?
  @users_list = get_users
  @system_info = system_info
  @memory_total = @system_info[:totalvisiblememorysize]
  @system_idle_time = system_idle_time

  WmiCli.new.query(wql).each do |proc_instance|
    proc = extract_wmi_property(proc_instance)
    # if proces no longer exists it won't be added to the resulting array
    # sometimes it happens when the Win32_Process query returned process but
    # when this program tries invoke execMethod_ on it the WmiCli class raises an exception
    # because the process disappeared
    proc_table.push(proc) if !proc.nil?
  end
  proc_table
end

.get_usersHash (private)

Get users list from Win32_UserAccount class

Returns:

  • (Hash)

    @users_list



122
123
124
125
126
127
128
# File 'lib/hawatel_ps/windows/proc_fetch.rb', line 122

def get_users
  users_list = Hash.new
  WmiCli.new.query('SELECT * FROM Win32_UserAccount').each do |user|
    users_list[user.properties[:sid]] = user.properties if !user.nil?
  end
  users_list
end

.hash_value_to_string(hash) ⇒ Object (private)

Convert hash values to string if is the Integer type

Parameters:

  • hash (Hash)


116
117
118
# File 'lib/hawatel_ps/windows/proc_fetch.rb', line 116

def hash_value_to_string(hash)
  hash.each {|k,v| hash[k] = v.to_s if v.is_a?(Integer)}
end

.memory_percent(mem_total_kb, workingsetsize) ⇒ String (private)

Return percent of memory usage by process

Returns:

  • (String)


178
179
180
181
182
183
# File 'lib/hawatel_ps/windows/proc_fetch.rb', line 178

def memory_percent(mem_total_kb, workingsetsize)
  if !mem_total_kb.nil? && !workingsetsize.nil? && mem_total_kb.to_i > 0
    rss_kb = workingsetsize.to_f / 1024
    return (rss_kb / mem_total_kb.to_f * 100).round(2).to_s
  end
end

.prepare_wql(query, args = nil) ⇒ String (private)

Prepare WMI Query Language

Examples:

prepare_wql('SELECT * FROM Win32_Process')
prepare_wql('SELECT * FROM Win32_Process', {:processid => 1020})
prepare_wql('SELECT * FROM Win32_Process', {:name => 'notepad.exe', :executablepath => 'C:\\\\WINDOWS\\\\system32\\\\notepad.exe'})

Parameters:

  • query (String)

    WQL string

  • args (Hash) (defaults to: nil)

    conditions to WHERE clause (conditions are combined only with AND operator)

  • name (Hash)

    a customizable set of options

Returns:

  • (String)

    WQL string



69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
# File 'lib/hawatel_ps/windows/proc_fetch.rb', line 69

def prepare_wql(query, args = nil)
  if args.nil?
    return query
  else
    query += " WHERE "
    args.each_with_index do |(k, v), index|
      if index == 0 && args.length == 1
        query += "#{k.to_s.downcase} = '#{v}'"
      elsif index == args.length - 1
        query += "#{k.to_s.downcase} = '#{v}'"
      else
        query += "#{k.to_s.downcase} = '#{v}' AND "
      end
    end
    return query
  end
end

.system_idle_timeInteger (private)

Calculate cpu time for System Idle Process

Returns:

  • (Integer)

    system idle time in seconds



187
188
189
190
191
192
# File 'lib/hawatel_ps/windows/proc_fetch.rb', line 187

def system_idle_time
  WmiCli.new.query("SELECT KernelModeTime FROM Win32_Process WHERE ProcessId = '0'").each do |idle|
    return (idle.properties[:kernelmodetime].to_i / 10000000)
  end
  return nil
end

.system_infoHash (private)

System information from Win32_OperatingSystem class

Returns:

  • (Hash)


170
171
172
173
174
# File 'lib/hawatel_ps/windows/proc_fetch.rb', line 170

def system_info
  WmiCli.new.query('SELECT * FROM Win32_OperatingSystem').each do |result|
   return result.properties if !result.nil?
  end
end