From 1d5880bbf83c50b03a7a5d6eaf6482426ec2266b Mon Sep 17 00:00:00 2001 From: Jean Gautier Date: Wed, 10 Jun 2020 11:24:27 +0200 Subject: [PATCH] OrcLib: add CommandLine and Parent process access --- src/OrcLib/SystemDetails.cpp | 74 +++++++++++++++++++++++++++++ src/OrcLib/SystemDetails.h | 5 ++ src/OrcLib/SystemIdentity.cpp | 6 +-- src/OrcLib/SystemIdentity.h | 2 +- tests/OrcLibTest/system_details.cpp | 17 +++++++ 5 files changed, 100 insertions(+), 4 deletions(-) diff --git a/src/OrcLib/SystemDetails.cpp b/src/OrcLib/SystemDetails.cpp index 360ebfcf..46189365 100644 --- a/src/OrcLib/SystemDetails.cpp +++ b/src/OrcLib/SystemDetails.cpp @@ -24,6 +24,7 @@ #include #include +#include namespace fs = std::filesystem; @@ -615,6 +616,79 @@ HRESULT Orc::SystemDetails::UserSID(std::wstring& strSID) return S_OK; } +Result Orc::SystemDetails::GetParentProcessId(const logger& pLog) +{ + WMI wmi(pLog); + + if (auto hr = wmi.Initialize(); FAILED(hr)) + { + log::Error(pLog, hr, L"Failed to initialize WMI\r\n"); + return hr; + } + + auto query = fmt::format(L"SELECT ParentProcessId FROM Win32_Process WHERE ProcessId = {}", GetCurrentProcessId()); + + auto result = wmi.Query(query.c_str()); + if (result.is_err()) + return result.err(); + + auto pEnum = result.unwrap(); + if (!pEnum) + return HRESULT_FROM_WIN32(ERROR_OBJECT_NOT_FOUND); + CComPtr pclsObj; + ULONG uReturn = 0; + + HRESULT hr = pEnum->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn); + if (0 == uReturn) + return HRESULT_FROM_WIN32(ERROR_OBJECT_NOT_FOUND); + + if (auto parent_id = WMI::GetProperty(pclsObj, L"ParentProcessId"); parent_id.is_err()) + return HRESULT_FROM_WIN32(ERROR_OBJECT_NOT_FOUND); + else + return (DWORD)parent_id.unwrap(); +} + +Result Orc::SystemDetails::GetCmdLine() +{ + return std::wstring(GetCommandLineW()); +} + +Result Orc::SystemDetails::GetCmdLine(const logger& pLog, DWORD dwPid) +{ + WMI wmi(pLog); + + if (auto hr = wmi.Initialize(); FAILED(hr)) + { + log::Error(pLog, hr, L"Failed to initialize WMI\r\n"); + return hr; + } + + if (dwPid == 0) + return E_INVALIDARG; + + // We can now look for the parent command line + auto query = fmt::format(L"SELECT CommandLine FROM Win32_Process WHERE ProcessId = {}", dwPid); + + auto result = wmi.Query(query.c_str()); + if (result.is_err()) + return result.err(); + + auto pEnum = result.unwrap(); + if (!pEnum) + return HRESULT_FROM_WIN32(ERROR_OBJECT_NOT_FOUND); + CComPtr pclsObj; + ULONG uReturn = 0; + + HRESULT hr = pEnum->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn); + if (0 == uReturn) + return HRESULT_FROM_WIN32(ERROR_OBJECT_NOT_FOUND); + + if (auto cmdLine = WMI::GetProperty(pclsObj, L"CommandLine"); cmdLine.is_err()) + return HRESULT_FROM_WIN32(ERROR_OBJECT_NOT_FOUND); + else + return cmdLine.unwrap(); +} + HRESULT Orc::SystemDetails::GetSystemLocale(std::wstring& strLocale) { wchar_t szName[MAX_PATH]; diff --git a/src/OrcLib/SystemDetails.h b/src/OrcLib/SystemDetails.h index e88875c8..54428009 100644 --- a/src/OrcLib/SystemDetails.h +++ b/src/OrcLib/SystemDetails.h @@ -82,6 +82,11 @@ class ORCLIB_API SystemDetails static HRESULT AmIElevated(bool& bIsElevated); static HRESULT UserSID(std::wstring& strSID); + static Result GetParentProcessId(const logger& pLog); + + static Result GetCmdLine(); + static Result GetCmdLine(const logger& pLog, DWORD dwPid); + static HRESULT GetSystemLocale(std::wstring& strLocale); static HRESULT GetUserLocale(std::wstring& strLocale); static HRESULT GetSystemLanguage(std::wstring& strLocale); diff --git a/src/OrcLib/SystemIdentity.cpp b/src/OrcLib/SystemIdentity.cpp index 99d22189..c32d5f3b 100644 --- a/src/OrcLib/SystemIdentity.cpp +++ b/src/OrcLib/SystemIdentity.cpp @@ -412,17 +412,17 @@ HRESULT Orc::SystemIdentity::PhysicalDrives(const std::shared_ptr& writer, const LPCWSTR elt) { - return E_NOTIMPL; + return S_OK; } HRESULT Orc::SystemIdentity::PhysicalMemory(const std::shared_ptr& writer, const LPCWSTR elt) { - return E_NOTIMPL; + return S_OK; } HRESULT Orc::SystemIdentity::CPU(const std::shared_ptr& writer, const LPCWSTR elt) { - return E_NOTIMPL; + return S_OK; } HRESULT Orc::SystemIdentity::Profiles(const std::shared_ptr& writer, LPCWSTR elt) diff --git a/src/OrcLib/SystemIdentity.h b/src/OrcLib/SystemIdentity.h index ee16c829..c4e3f9a7 100644 --- a/src/OrcLib/SystemIdentity.h +++ b/src/OrcLib/SystemIdentity.h @@ -63,7 +63,7 @@ class SystemIdentity static HRESULT CPU(const std::shared_ptr& writer, const LPCWSTR elt = L"cpu"); static HRESULT - Profiles(const std::shared_ptr& writer, const LPCWSTR elt = L"profiles"); + Profiles(const std::shared_ptr& writer, const LPCWSTR elt = L"profile"); }; diff --git a/tests/OrcLibTest/system_details.cpp b/tests/OrcLibTest/system_details.cpp index c685bd57..78a6fc7a 100644 --- a/tests/OrcLibTest/system_details.cpp +++ b/tests/OrcLibTest/system_details.cpp @@ -103,11 +103,28 @@ TEST_CLASS(SystemDetailsTest) Assert::IsTrue(result.is_ok()); auto envs = result.unwrap(); + Assert::IsFalse(envs.empty()); for (const auto& env : envs) { Assert::IsFalse(env.Name.empty()); } } + TEST_METHOD(GetCommandLineTest) + { + auto cmdLine = SystemDetails::GetCmdLine(); + auto cmdLineWMI = SystemDetails::GetCmdLine(_L_, GetCurrentProcessId()); + Assert::IsTrue(cmdLine.is_ok()); + Assert::IsTrue(cmdLineWMI.is_ok()); + Assert::AreEqual(cmdLine.unwrap(), cmdLineWMI.unwrap()); + + auto parent_id = SystemDetails::GetParentProcessId(_L_); + Assert::IsTrue(parent_id.is_ok()); + auto parentCmdLine = SystemDetails::GetCmdLine(_L_, parent_id.unwrap()); + Assert::IsTrue(parentCmdLine.is_ok()); + Assert::IsFalse(parentCmdLine.unwrap().empty()); + + } + }; } // namespace Orc::Test