module Win32::Pdh
Constants
- ItemEnum
Structure of instances and counters, for
::enum_object_items
Public Class Methods
Simple convenience method that checks the status and raises an exception unless it's a successful status.
# File lib/win32/pdh.rb, line 19 def self.check_status(status) raise PdhError, status unless status == Constants::ERROR_SUCCESS end
Enumerates an object's counter and instance names. Returns an ItemEnum
with the results.
Uses PdhEnumObjectItems: msdn.microsoft.com/en-us/library/windows/desktop/aa372595(v=vs.85).aspx
# File lib/win32/pdh.rb, line 159 def self.enum_object_items(object:, source: nil, machine: nil, detail: :novice) object = (object + "\0").encode('UTF-16LE') source = if source.nil? FFI::Pointer::NULL else (source + "\0").encode('UTF-16LE') end machine = if machine.nil? FFI::Pointer::NULL else (machine + "\0").encode('UTF-16LE') end detail = case detail when :wizard Constants::PERF_DETAIL_WIZARD when :expert Constants::PERF_DETAIL_EXPERT when :advanced Constants::PERF_DETAIL_ADVANCED else Constants::PERF_DETAIL_NOVICE end countersize = FFI::MemoryPointer.new(:uint) instancesize = FFI::MemoryPointer.new(:uint) countersize.write_uint(0) instancesize.write_uint(0) counterbuffer = FFI::Pointer::NULL instancebuffer = FFI::Pointer::NULL status = nil while status.nil? || status == Constants::PDH_MORE_DATA unless status.nil? counterbuffer = FFI::Buffer.new(:uint16, countersize.read_uint) instancebuffer = FFI::Buffer.new(:uint16, instancesize.read_uint) end status = PdhFFI.PdhEnumObjectItemsW( source, machine, object, counterbuffer, countersize, instancebuffer, instancesize, detail, 0, ) end Pdh.check_status status counterstring = counterbuffer.read_bytes(countersize.read_uint * 2).force_encoding('UTF-16LE').encode('UTF-8') instancestring = instancebuffer.read_bytes(instancesize.read_uint * 2).force_encoding('UTF-16LE').encode('UTF-8') enum = ItemEnum.new enum.counters = counterstring.split("\0").map(&:freeze).freeze enum.instances = instancestring.split("\0").map(&:freeze).freeze enum.freeze end
Uses PdhEnumObjects to enumerate objects at the given target. Returns the objects as an array of strings.
PdhEnumObjects: msdn.microsoft.com/en-us/library/windows/desktop/aa372600(v=vs.85).aspx
Params:
- source
-
The same as szDataSource
- machine
-
The same as szMachineName
- detail
-
Alias for dwDetailLevel, as a symbol. May be :novice, :advanced, :expert, or :wizard. Defaults to :novice.
# File lib/win32/pdh.rb, line 100 def self.enum_objects(source: nil, machine: nil, detail: :novice) source = if source.nil? FFI::Pointer::NULL else (source + "\0").encode('UTF-16LE') end machine = if machine.nil? FFI::Pointer::NULL else (machine + "\0").encode('UTF-16LE') end detail = case detail when :wizard Constants::PERF_DETAIL_WIZARD when :expert Constants::PERF_DETAIL_EXPERT when :advanced Constants::PERF_DETAIL_ADVANCED else Constants::PERF_DETAIL_NOVICE end listsize = FFI::MemoryPointer.new(:uint) listsize.write_uint(0) listbuffer = FFI::Pointer::NULL status = nil while status.nil? || status == Constants::PDH_MORE_DATA listbuffer = FFI::Buffer.new(:uint16, listsize.read_uint) unless status.nil? status = PdhFFI.PdhEnumObjectsW( source, machine, listbuffer, listsize, detail, status.nil? ? :true : :false, ) end Pdh.check_status status string = listbuffer.read_bytes(listsize.read_uint * 2).force_encoding('UTF-16LE').encode('UTF-8') # Split and return objects string.split("\0") end
Expands a wildcard path into all matching counter paths.
Returns a frozen array of frozen strings.
Uses PdhExpandWildCardPath: msdn.microsoft.com/en-us/library/windows/desktop/aa372606(v=vs.85).aspx
# File lib/win32/pdh.rb, line 227 def self.expand_wildcards(path:, source: nil, expand_counters: true, expand_instances: true) path = (path + "\0").encode('UTF-16LE') source = if source.nil? FFI::Pointer::NULL else (source + "\0").encode('UTF-16LE') end flags = 0 flags |= PDH_NOEXPANDCOUNTERS unless expand_counters flags |= PDH_NOEXPANDINSTANCES unless expand_instances listsize = FFI::MemoryPointer.new(:uint) listsize.write_uint(0) listbuffer = FFI::Pointer::NULL status = nil while status.nil? || status == Constants::PDH_MORE_DATA listbuffer = FFI::Buffer.new(:uint16, listsize.read_uint) unless status.nil? status = PdhFFI.PdhExpandWildCardPathW( source, path, listbuffer, listsize, flags, ) end Pdh.check_status status liststring = listbuffer.read_bytes(listsize.read_uint * 2).force_encoding('UTF-16LE').encode('UTF-8') liststring.split("\0").map(&:freeze).freeze end
Takes a pointer to null-terminated utf-16 data and reads it into a utf-8 encoded string.
If pointer is null, return nil instead of a string.
# File lib/win32/pdh.rb, line 48 def self.read_cwstr(pointer) return nil if pointer.null? # length in wchars length = strlen_cwstr(pointer) pointer.read_bytes(length * 2).force_encoding('UTF-16LE').encode('UTF-8') end
Gets the length of a cwstr (null-terminated UTF-16 string) in characters (16-bit units).
Returns nil if the pointer is null
# File lib/win32/pdh.rb, line 28 def self.strlen_cwstr(pointer) return nil if pointer.null? # Clone pointer, so we don't modify the original. pointer = FFI::Pointer.new(pointer) length = 0 until pointer.get_uint16(0) == 0 length += 1 # Need to proceed 2 bytes at a time; Ruby ffi gives no special pointer # arithmetic by type. pointer += 2 end length end