Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor ConsoleProcessList #14421

Merged
6 commits merged into from
Dec 2, 2022
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
15 changes: 4 additions & 11 deletions src/server/ApiDispatchersInternal.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -90,17 +90,10 @@ using Microsoft::Console::Interactivity::ServiceLocator;
RETURN_IF_NTSTATUS_FAILED((NtPrivApi::s_GetProcessParentId(&ProcessId)));
ProcessHandle = gci.ProcessHandleList.FindProcessInList(ProcessId);
RETURN_HR_IF_NULL(E_INVALIDARG, ProcessHandle);

const auto hr = gci.ProcessHandleList.AllocProcessData(a->ProcessGroupId,
0,
a->ProcessGroupId,
nullptr);
// AllocProcessData returns E_FAIL if the given process ID already exists.
// The process ID already existing isn't really an error though so we ignore it.
if (FAILED(hr) && hr != E_FAIL)
{
RETURN_HR(hr);
}
RETURN_IF_FAILED(gci.ProcessHandleList.AllocProcessData(a->ProcessGroupId,
0,
a->ProcessGroupId,
nullptr));
}
}

Expand Down
18 changes: 9 additions & 9 deletions src/server/ProcessHandle.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,15 @@ Revision History:
class ConsoleProcessHandle
{
public:
ConsoleProcessHandle(const DWORD dwProcessId,
const DWORD dwThreadId,
const ULONG ulProcessGroupId);
~ConsoleProcessHandle() = default;
ConsoleProcessHandle(const ConsoleProcessHandle&) = delete;
ConsoleProcessHandle(ConsoleProcessHandle&&) = delete;
ConsoleProcessHandle& operator=(const ConsoleProcessHandle&) & = delete;
ConsoleProcessHandle& operator=(ConsoleProcessHandle&&) & = delete;

const std::unique_ptr<ConsoleWaitQueue> pWaitBlockQueue;
std::unique_ptr<ConsoleHandleData> pInputHandle;
std::unique_ptr<ConsoleHandleData> pOutputHandle;
Expand All @@ -47,15 +56,6 @@ class ConsoleProcessHandle
const ULONG64 GetProcessCreationTime() const;

private:
ConsoleProcessHandle(const DWORD dwProcessId,
const DWORD dwThreadId,
const ULONG ulProcessGroupId);
~ConsoleProcessHandle() = default;
ConsoleProcessHandle(const ConsoleProcessHandle&) = delete;
ConsoleProcessHandle(ConsoleProcessHandle&&) = delete;
ConsoleProcessHandle& operator=(const ConsoleProcessHandle&) & = delete;
ConsoleProcessHandle& operator=(ConsoleProcessHandle&&) & = delete;

ULONG _ulTerminateCount;
ULONG const _ulProcessGroupId;
wil::unique_handle const _hProcess;
Expand Down
57 changes: 27 additions & 30 deletions src/server/ProcessList.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ using namespace Microsoft::Console::Interactivity;
// - If not used, return code will specify whether this process is known to the list or not.
// Return Value:
// - S_OK if the process was recorded in the list successfully or already existed.
// - E_FAIL if we're running into an LPC port conflict by nature of the process chain.
// - S_FALSE if we're running into an LPC port conflict by nature of the process chain.
// - E_OUTOFMEMORY if there wasn't space to allocate a handle or push it into the list.
[[nodiscard]] HRESULT ConsoleProcessList::AllocProcessData(const DWORD dwProcessId,
const DWORD dwThreadId,
Expand All @@ -31,23 +31,20 @@ using namespace Microsoft::Console::Interactivity;
{
assert(ServiceLocator::LocateGlobals().getConsoleInformation().IsConsoleLocked());

auto pProcessData = FindProcessInList(dwProcessId);
if (pProcessData)
if (FindProcessInList(dwProcessId))
{
return E_FAIL;
return S_FALSE;
}

std::unique_ptr<ConsoleProcessHandle> pProcessData;
try
{
pProcessData = new ConsoleProcessHandle{ dwProcessId, dwThreadId, ulProcessGroupId };
_processes.emplace_back(pProcessData);
pProcessData = std::make_unique<ConsoleProcessHandle>(dwProcessId, dwThreadId, ulProcessGroupId);
_processes.emplace_back(pProcessData.get());
}
CATCH_RETURN();

if (ppProcessData)
{
*ppProcessData = pProcessData;
}
wil::assign_to_opt_param(ppProcessData, pProcessData.release());
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SCARY! This will delete the processdata if nobody asks for the optional output param

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

wait, no it won't. that's even scarier lol


return S_OK;
}
Expand Down Expand Up @@ -138,6 +135,26 @@ ConsoleProcessHandle* ConsoleProcessList::GetRootProcess() const
return nullptr;
}

// Routine Description:
// - Gets the first process in the list.
// - Used for reassigning a new root process.
// TODO: MSFT 9450737 - encapsulate root process logic. https://osgvsowi/9450737
// Arguments:
// - <none>
// Return Value:
// - Pointer to the first item in the list or nullptr if there are no items.
ConsoleProcessHandle* ConsoleProcessList::GetOldestProcess() const
{
assert(ServiceLocator::LocateGlobals().getConsoleInformation().IsConsoleLocked());

if (!_processes.empty())
{
return _processes.front();
}

return nullptr;
}

// Routine Description:
// - Retrieves the entire list of process IDs that is known to this list.
// Arguments:
Expand Down Expand Up @@ -230,26 +247,6 @@ ConsoleProcessHandle* ConsoleProcessList::GetRootProcess() const
CATCH_RETURN();
}

// Routine Description:
// - Gets the first process in the list.
// - Used for reassigning a new root process.
// TODO: MSFT 9450737 - encapsulate root process logic. https://osgvsowi/9450737
// Arguments:
// - <none>
// Return Value:
// - Pointer to the first item in the list or nullptr if there are no items.
ConsoleProcessHandle* ConsoleProcessList::GetOldestProcess() const
{
assert(ServiceLocator::LocateGlobals().getConsoleInformation().IsConsoleLocked());

if (!_processes.empty())
{
return _processes.front();
}

return nullptr;
}

// Routine Description:
// - Requests that the OS change the process priority for the console and all attached client processes
// Arguments:
Expand Down
3 changes: 1 addition & 2 deletions src/server/ProcessList.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,13 +44,12 @@ class ConsoleProcessList
ConsoleProcessHandle* FindProcessInList(const DWORD dwProcessId) const;
ConsoleProcessHandle* FindProcessByGroupId(_In_ ULONG ulProcessGroupId) const;
ConsoleProcessHandle* GetRootProcess() const;
ConsoleProcessHandle* GetOldestProcess() const;

[[nodiscard]] HRESULT GetTerminationRecordsByGroupId(const DWORD dwLimitingProcessId,
const bool fCtrlClose,
std::vector<ConsoleProcessTerminationRecord>& termRecords) const;

ConsoleProcessHandle* GetOldestProcess() const;

[[nodiscard]] HRESULT GetProcessList(_Inout_updates_(*pcProcessList) DWORD* const pProcessList,
_Inout_ size_t* const pcProcessList) const;

Expand Down