|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#include "BackgroundDesktop.h" |
|
|
|
#include <memory> |
|
|
|
#include "DebugClient.h" |
|
#include "StringUtil.h" |
|
#include "WinptyException.h" |
|
|
|
namespace { |
|
|
|
static std::wstring getObjectName(HANDLE object) { |
|
BOOL success; |
|
DWORD lengthNeeded = 0; |
|
GetUserObjectInformationW(object, UOI_NAME, |
|
nullptr, 0, |
|
&lengthNeeded); |
|
ASSERT(lengthNeeded % sizeof(wchar_t) == 0); |
|
std::unique_ptr<wchar_t[]> tmp( |
|
new wchar_t[lengthNeeded / sizeof(wchar_t)]); |
|
success = GetUserObjectInformationW(object, UOI_NAME, |
|
tmp.get(), lengthNeeded, |
|
nullptr); |
|
if (!success) { |
|
throwWindowsError(L"GetUserObjectInformationW failed"); |
|
} |
|
return std::wstring(tmp.get()); |
|
} |
|
|
|
static std::wstring getDesktopName(HWINSTA winsta, HDESK desk) { |
|
return getObjectName(winsta) + L"\\" + getObjectName(desk); |
|
} |
|
|
|
} |
|
|
|
|
|
|
|
BackgroundDesktop::BackgroundDesktop() { |
|
try { |
|
m_originalStation = GetProcessWindowStation(); |
|
if (m_originalStation == nullptr) { |
|
throwWindowsError( |
|
L"BackgroundDesktop ctor: " |
|
L"GetProcessWindowStation returned NULL"); |
|
} |
|
m_newStation = |
|
CreateWindowStationW(nullptr, 0, WINSTA_ALL_ACCESS, nullptr); |
|
if (m_newStation == nullptr) { |
|
throwWindowsError( |
|
L"BackgroundDesktop ctor: CreateWindowStationW returned NULL"); |
|
} |
|
if (!SetProcessWindowStation(m_newStation)) { |
|
throwWindowsError( |
|
L"BackgroundDesktop ctor: SetProcessWindowStation failed"); |
|
} |
|
m_newDesktop = CreateDesktopW( |
|
L"Default", nullptr, nullptr, 0, GENERIC_ALL, nullptr); |
|
if (m_newDesktop == nullptr) { |
|
throwWindowsError( |
|
L"BackgroundDesktop ctor: CreateDesktopW failed"); |
|
} |
|
m_newDesktopName = getDesktopName(m_newStation, m_newDesktop); |
|
TRACE("Created background desktop: %s", |
|
utf8FromWide(m_newDesktopName).c_str()); |
|
} catch (...) { |
|
dispose(); |
|
throw; |
|
} |
|
} |
|
|
|
void BackgroundDesktop::dispose() WINPTY_NOEXCEPT { |
|
if (m_originalStation != nullptr) { |
|
SetProcessWindowStation(m_originalStation); |
|
m_originalStation = nullptr; |
|
} |
|
if (m_newDesktop != nullptr) { |
|
CloseDesktop(m_newDesktop); |
|
m_newDesktop = nullptr; |
|
} |
|
if (m_newStation != nullptr) { |
|
CloseWindowStation(m_newStation); |
|
m_newStation = nullptr; |
|
} |
|
} |
|
|
|
std::wstring getCurrentDesktopName() { |
|
|
|
|
|
|
|
const HWINSTA winsta = GetProcessWindowStation(); |
|
if (winsta == nullptr) { |
|
throwWindowsError( |
|
L"getCurrentDesktopName: " |
|
L"GetProcessWindowStation returned NULL"); |
|
} |
|
const HDESK desk = GetThreadDesktop(GetCurrentThreadId()); |
|
if (desk == nullptr) { |
|
throwWindowsError( |
|
L"getCurrentDesktopName: " |
|
L"GetThreadDesktop returned NULL"); |
|
} |
|
return getDesktopName(winsta, desk); |
|
} |
|
|