Make TSF initialization fully fallible (#19958)

Apparently, on some (internal) variants of Windows `TF_CategoryMgr`
can exist while `TF_DisplayAttributeMgr` is absent. This is likely
a variant configuration error, but we shouldn't crash anyway.

Closes MSFT-61309810
This commit is contained in:
Leonard Hecker
2026-03-10 21:31:54 +01:00
committed by GitHub
parent 5bd9e9fd89
commit 30b1456ffe
3 changed files with 13 additions and 19 deletions

View File

@@ -12,7 +12,7 @@ Handle Handle::Create()
{
Handle handle;
handle._impl = new Implementation();
if (!handle._impl->Initialize())
if (FAILED(handle._impl->Initialize()))
{
delete handle._impl;
handle._impl = nullptr;

View File

@@ -71,33 +71,27 @@ void Implementation::SetDefaultScopeAlphanumericHalfWidth(bool enable) noexcept
s_wantsAnsiInputScope.store(enable, std::memory_order_relaxed);
}
bool Implementation::Initialize()
HRESULT Implementation::Initialize()
{
_categoryMgr = wil::CoCreateInstanceNoThrow<ITfCategoryMgr>(CLSID_TF_CategoryMgr);
if (!_categoryMgr)
{
return false;
}
_displayAttributeMgr = wil::CoCreateInstance<ITfDisplayAttributeMgr>(CLSID_TF_DisplayAttributeMgr);
RETURN_IF_FAILED_EXPECTED(CoCreateInstance(CLSID_TF_CategoryMgr, nullptr, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(_categoryMgr.addressof())));
RETURN_IF_FAILED_EXPECTED(CoCreateInstance(CLSID_TF_DisplayAttributeMgr, nullptr, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(_displayAttributeMgr.addressof())));
// There's no point in calling TF_GetThreadMgr. ITfThreadMgr is a per-thread singleton.
_threadMgrEx = wil::CoCreateInstance<ITfThreadMgrEx>(CLSID_TF_ThreadMgr, CLSCTX_INPROC_SERVER);
RETURN_IF_FAILED_EXPECTED(CoCreateInstance(CLSID_TF_ThreadMgr, nullptr, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(_threadMgrEx.addressof())));
THROW_IF_FAILED(_threadMgrEx->ActivateEx(&_clientId, s_activationFlags.load(std::memory_order_relaxed)));
THROW_IF_FAILED(_threadMgrEx->CreateDocumentMgr(_documentMgr.addressof()));
RETURN_IF_FAILED(_threadMgrEx->ActivateEx(&_clientId, s_activationFlags.load(std::memory_order_relaxed)));
RETURN_IF_FAILED(_threadMgrEx->CreateDocumentMgr(_documentMgr.addressof()));
TfEditCookie ecTextStore;
THROW_IF_FAILED(_documentMgr->CreateContext(_clientId, 0, static_cast<ITfContextOwnerCompositionSink*>(this), _context.addressof(), &ecTextStore));
RETURN_IF_FAILED(_documentMgr->CreateContext(_clientId, 0, static_cast<ITfContextOwnerCompositionSink*>(this), _context.addressof(), &ecTextStore));
_ownerCompositionServices = _context.try_query<ITfContextOwnerCompositionServices>();
_contextSource = _context.query<ITfSource>();
THROW_IF_FAILED(_contextSource->AdviseSink(IID_ITfContextOwner, static_cast<ITfContextOwner*>(this), &_cookieContextOwner));
THROW_IF_FAILED(_contextSource->AdviseSink(IID_ITfTextEditSink, static_cast<ITfTextEditSink*>(this), &_cookieTextEditSink));
RETURN_IF_FAILED(_contextSource->AdviseSink(IID_ITfContextOwner, static_cast<ITfContextOwner*>(this), &_cookieContextOwner));
RETURN_IF_FAILED(_contextSource->AdviseSink(IID_ITfTextEditSink, static_cast<ITfTextEditSink*>(this), &_cookieTextEditSink));
THROW_IF_FAILED(_documentMgr->Push(_context.get()));
return true;
RETURN_IF_FAILED(_documentMgr->Push(_context.get()));
return S_OK;
}
void Implementation::Uninitialize() noexcept

View File

@@ -21,7 +21,7 @@ namespace Microsoft::Console::TSF
virtual ~Implementation() = default;
bool Initialize();
HRESULT Initialize();
void Uninitialize() noexcept;
HWND FindWindowOfActiveTSF() noexcept;
void AssociateFocus(IDataProvider* provider);