First commit.

This commit is contained in:
fanlumaster committed 2023-10-12 23:53:17 +08:00
commit 7b83802bb2
103 files changed
+19016

No files matched your search

+283
View File
@@ -0,0 +1,283 @@
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
//
// Copyright (c) Microsoft Corporation. All rights reserved
#include "Private.h"
#include "Globals.h"
static const WCHAR RegInfo_Prefix_CLSID[] = L"CLSID\\";
static const WCHAR RegInfo_Key_InProSvr32[] = L"InProcServer32";
static const WCHAR RegInfo_Key_ThreadModel[] = L"ThreadingModel";
static const WCHAR TEXTSERVICE_DESC[] = L"Sample IME";
static const GUID SupportCategories[] = {
GUID_TFCAT_TIP_KEYBOARD,
GUID_TFCAT_DISPLAYATTRIBUTEPROVIDER,
GUID_TFCAT_TIPCAP_UIELEMENTENABLED,
GUID_TFCAT_TIPCAP_SECUREMODE,
GUID_TFCAT_TIPCAP_COMLESS,
GUID_TFCAT_TIPCAP_INPUTMODECOMPARTMENT,
GUID_TFCAT_TIPCAP_IMMERSIVESUPPORT,
GUID_TFCAT_TIPCAP_SYSTRAYSUPPORT,
};
//+---------------------------------------------------------------------------
//
// RegisterProfiles
//
//----------------------------------------------------------------------------
BOOL RegisterProfiles()
{
HRESULT hr = S_FALSE;
ITfInputProcessorProfileMgr *pITfInputProcessorProfileMgr = nullptr;
hr = CoCreateInstance(CLSID_TF_InputProcessorProfiles, NULL, CLSCTX_INPROC_SERVER,
IID_ITfInputProcessorProfileMgr, (void**)&pITfInputProcessorProfileMgr);
if (FAILED(hr))
{
return FALSE;
}
WCHAR achIconFile[MAX_PATH] = {'\0'};
DWORD cchA = 0;
cchA = GetModuleFileName(Global::dllInstanceHandle, achIconFile, MAX_PATH);
cchA = cchA >= MAX_PATH ? (MAX_PATH - 1) : cchA;
achIconFile[cchA] = '\0';
size_t lenOfDesc = 0;
hr = StringCchLength(TEXTSERVICE_DESC, STRSAFE_MAX_CCH, &lenOfDesc);
if (hr != S_OK)
{
goto Exit;
}
hr = pITfInputProcessorProfileMgr->RegisterProfile(Global::SampleIMECLSID,
TEXTSERVICE_LANGID,
Global::SampleIMEGuidProfile,
TEXTSERVICE_DESC,
static_cast<ULONG>(lenOfDesc),
achIconFile,
cchA,
(UINT)TEXTSERVICE_ICON_INDEX, NULL, 0, TRUE, 0);
if (FAILED(hr))
{
goto Exit;
}
Exit:
if (pITfInputProcessorProfileMgr)
{
pITfInputProcessorProfileMgr->Release();
}
return (hr == S_OK);
}
//+---------------------------------------------------------------------------
//
// UnregisterProfiles
//
//----------------------------------------------------------------------------
void UnregisterProfiles()
{
HRESULT hr = S_OK;
ITfInputProcessorProfileMgr *pITfInputProcessorProfileMgr = nullptr;
hr = CoCreateInstance(CLSID_TF_InputProcessorProfiles, NULL, CLSCTX_INPROC_SERVER,
IID_ITfInputProcessorProfileMgr, (void**)&pITfInputProcessorProfileMgr);
if (FAILED(hr))
{
goto Exit;
}
hr = pITfInputProcessorProfileMgr->UnregisterProfile(Global::SampleIMECLSID, TEXTSERVICE_LANGID, Global::SampleIMEGuidProfile, 0);
if (FAILED(hr))
{
goto Exit;
}
Exit:
if (pITfInputProcessorProfileMgr)
{
pITfInputProcessorProfileMgr->Release();
}
return;
}
//+---------------------------------------------------------------------------
//
// RegisterCategories
//
//----------------------------------------------------------------------------
BOOL RegisterCategories()
{
ITfCategoryMgr* pCategoryMgr = nullptr;
HRESULT hr = S_OK;
hr = CoCreateInstance(CLSID_TF_CategoryMgr, NULL, CLSCTX_INPROC_SERVER, IID_ITfCategoryMgr, (void**)&pCategoryMgr);
if (FAILED(hr))
{
return FALSE;
}
for each(GUID guid in SupportCategories)
{
hr = pCategoryMgr->RegisterCategory(Global::SampleIMECLSID, guid, Global::SampleIMECLSID);
}
pCategoryMgr->Release();
return (hr == S_OK);
}
//+---------------------------------------------------------------------------
//
// UnregisterCategories
//
//----------------------------------------------------------------------------
void UnregisterCategories()
{
ITfCategoryMgr* pCategoryMgr = S_OK;
HRESULT hr = S_OK;
hr = CoCreateInstance(CLSID_TF_CategoryMgr, NULL, CLSCTX_INPROC_SERVER, IID_ITfCategoryMgr, (void**)&pCategoryMgr);
if (FAILED(hr))
{
return;
}
for each(GUID guid in SupportCategories)
{
pCategoryMgr->UnregisterCategory(Global::SampleIMECLSID, guid, Global::SampleIMECLSID);
}
pCategoryMgr->Release();
return;
}
//+---------------------------------------------------------------------------
//
// RecurseDeleteKey
//
// RecurseDeleteKey is necessary because on NT RegDeleteKey doesn't work if the
// specified key has subkeys
//----------------------------------------------------------------------------
LONG RecurseDeleteKey(_In_ HKEY hParentKey, _In_ LPCTSTR lpszKey)
{
HKEY regKeyHandle = nullptr;
LONG res = 0;
FILETIME time;
WCHAR stringBuffer[256] = {'\0'};
DWORD size = ARRAYSIZE(stringBuffer);
if (RegOpenKey(hParentKey, lpszKey, &regKeyHandle) != ERROR_SUCCESS)
{
return ERROR_SUCCESS;
}
res = ERROR_SUCCESS;
while (RegEnumKeyEx(regKeyHandle, 0, stringBuffer, &size, NULL, NULL, NULL, &time) == ERROR_SUCCESS)
{
stringBuffer[ARRAYSIZE(stringBuffer)-1] = '\0';
res = RecurseDeleteKey(regKeyHandle, stringBuffer);
if (res != ERROR_SUCCESS)
{
break;
}
size = ARRAYSIZE(stringBuffer);
}
RegCloseKey(regKeyHandle);
return res == ERROR_SUCCESS ? RegDeleteKey(hParentKey, lpszKey) : res;
}
//+---------------------------------------------------------------------------
//
// RegisterServer
//
//----------------------------------------------------------------------------
BOOL RegisterServer()
{
DWORD copiedStringLen = 0;
HKEY regKeyHandle = nullptr;
HKEY regSubkeyHandle = nullptr;
BOOL ret = FALSE;
WCHAR achIMEKey[ARRAYSIZE(RegInfo_Prefix_CLSID) + CLSID_STRLEN] = {'\0'};
WCHAR achFileName[MAX_PATH] = {'\0'};
if (!CLSIDToString(Global::SampleIMECLSID, achIMEKey + ARRAYSIZE(RegInfo_Prefix_CLSID) - 1))
{
return FALSE;
}
memcpy(achIMEKey, RegInfo_Prefix_CLSID, sizeof(RegInfo_Prefix_CLSID) - sizeof(WCHAR));
if (RegCreateKeyEx(HKEY_CLASSES_ROOT, achIMEKey, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &regKeyHandle, &copiedStringLen) == ERROR_SUCCESS)
{
if (RegSetValueEx(regKeyHandle, NULL, 0, REG_SZ, (const BYTE *)TEXTSERVICE_DESC, (_countof(TEXTSERVICE_DESC))*sizeof(WCHAR)) != ERROR_SUCCESS)
{
goto Exit;
}
if (RegCreateKeyEx(regKeyHandle, RegInfo_Key_InProSvr32, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &regSubkeyHandle, &copiedStringLen) == ERROR_SUCCESS)
{
copiedStringLen = GetModuleFileNameW(Global::dllInstanceHandle, achFileName, ARRAYSIZE(achFileName));
copiedStringLen = (copiedStringLen >= (MAX_PATH - 1)) ? MAX_PATH : (++copiedStringLen);
if (RegSetValueEx(regSubkeyHandle, NULL, 0, REG_SZ, (const BYTE *)achFileName, (copiedStringLen)*sizeof(WCHAR)) != ERROR_SUCCESS)
{
goto Exit;
}
if (RegSetValueEx(regSubkeyHandle, RegInfo_Key_ThreadModel, 0, REG_SZ, (const BYTE *)TEXTSERVICE_MODEL, (_countof(TEXTSERVICE_MODEL)) * sizeof(WCHAR)) != ERROR_SUCCESS)
{
goto Exit;
}
ret = TRUE;
}
}
Exit:
if (regSubkeyHandle)
{
RegCloseKey(regSubkeyHandle);
regSubkeyHandle = nullptr;
}
if (regKeyHandle)
{
RegCloseKey(regKeyHandle);
regKeyHandle = nullptr;
}
return ret;
}
//+---------------------------------------------------------------------------
//
// UnregisterServer
//
//----------------------------------------------------------------------------
void UnregisterServer()
{
WCHAR achIMEKey[ARRAYSIZE(RegInfo_Prefix_CLSID) + CLSID_STRLEN] = {'\0'};
if (!CLSIDToString(Global::SampleIMECLSID, achIMEKey + ARRAYSIZE(RegInfo_Prefix_CLSID) - 1))
{
return;
}
memcpy(achIMEKey, RegInfo_Prefix_CLSID, sizeof(RegInfo_Prefix_CLSID) - sizeof(WCHAR));
RecurseDeleteKey(HKEY_CLASSES_ROOT, achIMEKey);
}