Skip to content

Commit

Permalink
explorer library added
Browse files Browse the repository at this point in the history
- process_explorer implementation started - it's aimed to replace process::enumerate facility in injector library.
  • Loading branch information
tyoma committed Aug 1, 2022
1 parent 227ed54 commit 8f057f8
Show file tree
Hide file tree
Showing 15 changed files with 717 additions and 16 deletions.
2 changes: 2 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -147,13 +147,15 @@ if (WIN32 OR APPLE)
add_subdirectory(standalone)

if (WIN32)
add_subdirectory(explorer/src)
add_subdirectory(injector/src)

if (MP_BUILD_VSPACKAGE)
add_subdirectory(libraries/wpl.vs)
add_subdirectory(micro-profiler)
endif()

add_subdirectory(explorer/tests)
add_subdirectory(injector/tests)
endif ()
endif ()
Expand Down
58 changes: 58 additions & 0 deletions explorer/process.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
// Copyright (c) 2011-2022 by Artem A. Gevorkyan (gevorkyan.org)
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

#pragma once

#include <mt/chrono.h>
#include <common/types.h>
#include <cstdint>
#include <scheduler/private_queue.h>
#include <sdb/table.h>

namespace micro_profiler
{
struct process_info
{
enum architectures { x86, x64, };
typedef std::int64_t process_time_t;

id_t pid, parent_pid;
std::string path;
architectures architecture;
process_time_t started_at;
std::shared_ptr<void> handle;

unsigned int cycle;
};

class process_explorer : public sdb::table<process_info>
{
public:
process_explorer(mt::milliseconds update_interval, scheduler::queue &apartment_queue);

private:
void update();

private:
scheduler::private_queue _apartment;
mt::milliseconds _update_interval;
unsigned int _cycle;
};
}
7 changes: 7 additions & 0 deletions explorer/src/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
cmake_minimum_required(VERSION 2.8)

set(EXPLORER_SOURCES
process_win32.cpp
)

add_library(explorer STATIC ${EXPLORER_SOURCES})
52 changes: 52 additions & 0 deletions explorer/src/explorer.lib.vcxproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations" Condition="'$(VisualStudioVersion)'=='10.0'">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\process.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="process_win32.cpp" />
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{7F768E1B-51FB-46E9-88C6-43E9F136710A}</ProjectGuid>
</PropertyGroup>
<Import Project="$(SolutionDir)build.props\platform.props" />
<PropertyGroup Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="PropertySheets">
<Import Project="$(SolutionDir)build.props\config.props" />
<Import Project="$(SolutionDir)build.props\wpl.include.props" />
</ImportGroup>
<ItemDefinitionGroup>
<ClCompile>
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<DisableLanguageExtensions>false</DisableLanguageExtensions>
</ClCompile>
<ProjectReference>
<LinkLibraryDependencies>true</LinkLibraryDependencies>
</ProjectReference>
<Lib>
<AdditionalDependencies>psapi.lib</AdditionalDependencies>
</Lib>
</ItemDefinitionGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
</Project>
16 changes: 16 additions & 0 deletions explorer/src/explorer.lib.vcxproj.filters
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="src">
<UniqueIdentifier>{d322ec2c-728b-4052-96d0-b9e94732dc6b}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\process.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="process_win32.cpp">
<Filter>src</Filter>
</ClCompile>
</ItemGroup>
</Project>
92 changes: 92 additions & 0 deletions explorer/src/process_win32.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
// Copyright (c) 2011-2022 by Artem A. Gevorkyan (gevorkyan.org)
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

#include <explorer/process.h>

#include <common/string.h>
#include <sdb/integrated_index.h>
#include <windows.h>
#include <tlhelp32.h>

using namespace std;

namespace micro_profiler
{
namespace keyer
{
struct pid
{
id_t operator ()(const process_info &record) const { return record.pid; }

template <typename IndexT>
void operator ()(const IndexT &, process_info &record, id_t key) const
{ record.pid = key; }
};
}


process_explorer::process_explorer(mt::milliseconds update_interval, scheduler::queue &apartment_queue)
: _apartment(apartment_queue), _update_interval(update_interval), _cycle(0)
{ update(); }

void process_explorer::update()
{
auto &idx = sdb::unique_index(*this, keyer::pid());
shared_ptr<void> snapshot(::CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0), &::CloseHandle);
PROCESSENTRY32W entry = { sizeof(PROCESSENTRY32W), };

_cycle++;
for (auto lister = &::Process32FirstW;
lister(snapshot.get(), &entry);
lister = &::Process32NextW, entry.szExeFile[0] = 0)
{
auto rec = idx[entry.th32ProcessID];
auto &p = *rec;

p.parent_pid = entry.th32ParentProcessID;
p.path = unicode(entry.szExeFile);
if (!p.handle)
{
if (auto handle = ::OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, entry.th32ProcessID))
{
p.handle.reset(handle, &::CloseHandle);
}
else
{
rec.remove();
continue;
}
}
p.cycle = _cycle;
rec.commit();
}
for (auto i = begin(); i != end(); ++i)
{
if (i->cycle != _cycle)
{
auto rec = modify(i);

(*rec).handle.reset();
rec.commit();
}
}
_apartment.schedule([this] { update(); }, _update_interval);
}
}
19 changes: 19 additions & 0 deletions explorer/tests/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
cmake_minimum_required(VERSION 2.8)

set(MP_OUTDIR $<TARGET_FILE_DIR:explorer.tests>)

include(test)

set(EXPLORER_TEST_SOURCES
ProcessExplorerTests.cpp
)

add_custom_command(OUTPUT copy-guineas.x
COMMAND ${CMAKE_COMMAND} -E copy ${MP_OUTDIR}/guinea_runner.exe ${MP_OUTDIR}/guinea_runner2.exe
COMMAND ${CMAKE_COMMAND} -E copy ${MP_OUTDIR}/guinea_runner.exe ${MP_OUTDIR}/guinea_runner3.exe
COMMENT "Cloning guinea runners..."
)

add_library(explorer.tests SHARED ${EXPLORER_TEST_SOURCES} copy-guineas.x)
target_link_libraries(explorer.tests explorer ipc scheduler logger mt test-helpers)
add_dependencies(explorer.tests guinea_runner)
Loading

0 comments on commit 8f057f8

Please sign in to comment.