if RUBY_PLATFORM == "java" require "rubygems" unless defined?(Gem) gem "ffi" end require "ffi" unless defined?(FFI) module Process::Structs extend FFI::Library typedef :ulong, :dword typedef :uintptr_t, :handle typedef :short, :word # sizeof(LARGE_INTEGER) == 8 class LARGE_INTEGER < FFI::Union layout(:QuadPart, :long_long) end # sizeof(IO_COUNTERS) == 48 class IO_COUNTERS < FFI::Struct layout( :ReadOperationCount, :ulong_long, :WriteOperationCount, :ulong_long, :OtherOperationCount, :ulong_long, :ReadTransferCount, :ulong_long, :WriteTransferCount, :ulong_long, :OtherTransferCount, :ulong_long ) end class JOBJECT_BASIC_LIMIT_INFORMATION < FFI::Struct layout( :PerProcessUserTimeLimit, LARGE_INTEGER, :PerJobUserTimeLimit, LARGE_INTEGER, :LimitFlags, :dword, :MinimumWorkingSetSize, :size_t, :MaximumWorkingSetSize, :size_t, :ActiveProcessLimit, :dword, :Affinity, :pointer, :PriorityClass, :dword, :SchedulingClass, :dword ) end class JOBJECT_EXTENDED_LIMIT_INFORMATION < FFI::Struct layout( :BasicLimitInformation, JOBJECT_BASIC_LIMIT_INFORMATION, :IoInfo, IO_COUNTERS, :ProcessMemoryLimit, :size_t, :JobMemoryLimit, :size_t, :PeakProcessMemoryUsed, :size_t, :PeakJobMemoryUsed, :size_t ) end class SECURITY_ATTRIBUTES < FFI::Struct layout( :nLength, :dword, :lpSecurityDescriptor, :pointer, :bInheritHandle, :int ) end # sizeof(STARTUPINFO) == 68 class STARTUPINFO < FFI::Struct layout( :cb, :ulong, :lpReserved, :string, :lpDesktop, :string, :lpTitle, :string, :dwX, :dword, :dwY, :dword, :dwXSize, :dword, :dwYSize, :dword, :dwXCountChars, :dword, :dwYCountChars, :dword, :dwFillAttribute, :dword, :dwFlags, :dword, :wShowWindow, :word, :cbReserved2, :word, :lpReserved2, :pointer, :hStdInput, :handle, :hStdOutput, :handle, :hStdError, :handle ) end class PROCESS_INFORMATION < FFI::Struct layout( :hProcess, :handle, :hThread, :handle, :dwProcessId, :ulong, :dwThreadId, :ulong ) end class OSVERSIONINFO < FFI::Struct layout( :dwOSVersionInfoSize, :dword, :dwMajorVersion, :dword, :dwMinorVersion, :dword, :dwBuildNumber, :dword, :dwPlatformId, :dword, :szCSDVersion, [:char, 128] ) end class THREADENTRY32 < FFI::Struct layout( :dwSize, :dword, :cntUsage, :dword, :th32ThreadID, :dword, :th32OwnerProcessID, :dword, :tpBasePri, :long, :tpDeltaPri, :long, :dwFlags, :dword ) end class HEAPLIST32 < FFI::Struct layout( :dwSize, :size_t, :th32ProcessID, :dword, :th32HeapID, :uintptr_t, :dwFlags, :dword ) end class HEAPENTRY32 < FFI::Struct layout( :dwSize, :size_t, :hHandle, :handle, :dwAddress, :uintptr_t, :dwBlockSize, :size_t, :dwFlags, :dword, :dwLockCount, :dword, :dwResvd, :dword, :th32ProcessID, :dword, :th32HeapID, :uintptr_t ) end class MODULEENTRY32 < FFI::Struct layout( :dwSize, :dword, :th32ModuleID, :dword, :th32ProcessID, :dword, :GlblcntUsage, :dword, :ProccntUsage, :dword, :modBaseAddr, :pointer, :modBaseSize, :dword, :hModule, :handle, :szModule, [:char, 256], :szExePath, [:char, 260] ) end class PROCESSENTRY32 < FFI::Struct layout( :dwSize, :dword, :cntUsage, :dword, :th32ProcessID, :dword, :th32DefaultHeapID, :uintptr_t, :th32ModuleID, :dword, :cntThreads, :dword, :th32ParentProcessID, :dword, :pcPriClassBase, :long, :dwFlags, :dword, :szExeFile, [:char, 260] ) end # Used by Process.create ProcessInfo = Struct.new("ProcessInfo", :process_handle, :thread_handle, :process_id, :thread_id) # Used by Process.snapshot ThreadSnapInfo = Struct.new("ThreadSnapInfo", :thread_id, :process_id, :base_priority) HeapSnapInfo = Struct.new("HeapSnapInfo", :address, :block_size, :flags, :process_id, :heap_id) ModuleSnapInfo = Struct.new("ModuleSnapInfo", :process_id, :address, :module_size, :handle, :name, :path) ProcessSnapInfo = Struct.new("ProcessSnapInfo", :process_id, :threads, :parent_process_id, :priority, :flags, :path) end