mirror of
https://github.com/ApfelTeeSaft/reactos.git
synced 2026-09-02 04:13:34 +00:00
[MSCTF][SDK] Implement TF_RegisterLangBarAddIn etc. (#6229)
- Add dll/win32/msctf/utils.cpp. - Implement TF_RegisterLangBarAddIn and TF_UnregisterLangBarAddIn. - Strengthen <cicero/cicreg.h>. - Modify msctf.spec. CORE-19361
This commit is contained in:
@@ -20,13 +20,18 @@ list(APPEND SOURCE
|
||||
precomp.h
|
||||
${CMAKE_CURRENT_BINARY_DIR}/msctf_stubs.c)
|
||||
|
||||
list(APPEND PCH_SKIP_SOURCE
|
||||
utils.cpp)
|
||||
|
||||
add_library(msctf MODULE
|
||||
${SOURCE}
|
||||
${PCH_SKIP_SOURCE}
|
||||
version.rc
|
||||
${CMAKE_CURRENT_BINARY_DIR}/msctf.def)
|
||||
|
||||
set_module_type(msctf win32dll)
|
||||
target_link_libraries(msctf uuid wine)
|
||||
add_importlibs(msctf ole32 oleaut32 user32 advapi32 advapi32_vista msvcrt kernel32 ntdll)
|
||||
add_importlibs(msctf user32 advapi32 advapi32_vista msvcrt kernel32 ntdll)
|
||||
add_delay_importlibs(msctf ole32 oleaut32)
|
||||
add_pch(msctf precomp.h SOURCE)
|
||||
add_cd_file(TARGET msctf DESTINATION reactos/system32 FOR all)
|
||||
|
||||
@@ -34,3 +34,5 @@
|
||||
@ stub TF_MlngInfoCount
|
||||
@ stub TF_RunInputCPL
|
||||
@ stdcall -stub TF_PostAllThreadMsg(long long)
|
||||
@ stdcall TF_RegisterLangBarAddIn(ptr wstr long)
|
||||
@ stdcall TF_UnregisterLangBarAddIn(ptr long)
|
||||
|
||||
@@ -0,0 +1,102 @@
|
||||
/*
|
||||
* PROJECT: ReactOS msctf.dll
|
||||
* LICENSE: LGPL-2.1-or-later (https://spdx.org/licenses/LGPL-2.1-or-later)
|
||||
* PURPOSE: Text Framework Services
|
||||
* COPYRIGHT: Copyright 2023 Katayama Hirofumi MZ <[email protected]>
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#define WIN32_NO_STATUS
|
||||
#define COBJMACROS
|
||||
#define INITGUID
|
||||
#define _EXTYPES_H
|
||||
|
||||
#include <windows.h>
|
||||
#include <imm.h>
|
||||
#include <ddk/immdev.h>
|
||||
#include <cguid.h>
|
||||
#include <msctf.h>
|
||||
#include <ctffunc.h>
|
||||
#include <shlwapi.h>
|
||||
#include <strsafe.h>
|
||||
|
||||
#include <cicero/cicreg.h>
|
||||
|
||||
#include <wine/debug.h>
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(msctf);
|
||||
|
||||
/***********************************************************************
|
||||
* TF_RegisterLangBarAddIn (MSCTF.@)
|
||||
*
|
||||
* @implemented
|
||||
*/
|
||||
EXTERN_C HRESULT WINAPI
|
||||
TF_RegisterLangBarAddIn(
|
||||
_In_ REFGUID rguid,
|
||||
_In_ LPCWSTR pszFilePath,
|
||||
_In_ DWORD dwFlags)
|
||||
{
|
||||
TRACE("(%s, %s, 0x%lX)\n", debugstr_guid(&rguid), debugstr_w(pszFilePath), dwFlags);
|
||||
|
||||
if (!pszFilePath || IsEqualGUID(rguid, GUID_NULL))
|
||||
{
|
||||
ERR("E_INVALIDARG\n");
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
|
||||
WCHAR szBuff[MAX_PATH], szGUID[40];
|
||||
StringCchCopyW(szBuff, _countof(szBuff), L"SOFTWARE\\Microsoft\\CTF\\LangBarAddIn\\");
|
||||
StringFromGUID2(rguid, szGUID, _countof(szGUID));
|
||||
StringCchCatW(szBuff, _countof(szBuff), szGUID);
|
||||
|
||||
CicRegKey regKey;
|
||||
HKEY hBaseKey = ((dwFlags & 1) ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER);
|
||||
LSTATUS error = regKey.Create(hBaseKey, szBuff);
|
||||
if (error == ERROR_SUCCESS)
|
||||
{
|
||||
error = regKey.SetSz(L"FilePath", pszFilePath);
|
||||
if (error == ERROR_SUCCESS)
|
||||
error = regKey.SetDword(L"Enable", !!(dwFlags & 4));
|
||||
}
|
||||
|
||||
return ((error == ERROR_SUCCESS) ? S_OK : E_FAIL);
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* TF_UnregisterLangBarAddIn (MSCTF.@)
|
||||
*
|
||||
* @implemented
|
||||
*/
|
||||
EXTERN_C HRESULT WINAPI
|
||||
TF_UnregisterLangBarAddIn(
|
||||
_In_ REFGUID rguid,
|
||||
_In_ DWORD dwFlags)
|
||||
{
|
||||
TRACE("(%s, 0x%lX)\n", debugstr_guid(&rguid), dwFlags);
|
||||
|
||||
if (IsEqualGUID(rguid, GUID_NULL))
|
||||
{
|
||||
ERR("E_INVALIDARG\n");
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
|
||||
WCHAR szSubKey[MAX_PATH];
|
||||
StringCchCopyW(szSubKey, _countof(szSubKey), L"SOFTWARE\\Microsoft\\CTF\\LangBarAddIn\\");
|
||||
|
||||
CicRegKey regKey;
|
||||
HKEY hBaseKey = ((dwFlags & 1) ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER);
|
||||
LSTATUS error = regKey.Open(hBaseKey, szSubKey, KEY_ALL_ACCESS);
|
||||
HRESULT hr = E_FAIL;
|
||||
if (error == ERROR_SUCCESS)
|
||||
{
|
||||
WCHAR szGUID[40];
|
||||
StringFromGUID2(rguid, szGUID, _countof(szGUID));
|
||||
regKey.RecurseDeleteKey(szGUID);
|
||||
hr = S_OK;
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
@@ -191,7 +191,7 @@ CicSystemModulePath::Init(
|
||||
if (bSysWinDir)
|
||||
{
|
||||
// Usually C:\Windows or C:\ReactOS
|
||||
cchPath = ::GetSystemWindowsDirectory(m_szPath, _countof(m_szPath));
|
||||
cchPath = ::GetSystemWindowsDirectoryW(m_szPath, _countof(m_szPath));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -15,7 +15,7 @@ public:
|
||||
HKEY m_hKey;
|
||||
|
||||
CicRegKey() : m_hKey(NULL) { }
|
||||
~CicRegKey() { Close(); }
|
||||
virtual ~CicRegKey() { Close(); }
|
||||
|
||||
operator HKEY() { return m_hKey; }
|
||||
|
||||
@@ -43,7 +43,7 @@ public:
|
||||
|
||||
LSTATUS SetDword(LPCWSTR pszValueName, DWORD dwValue)
|
||||
{
|
||||
return ::RegSetValueExW(m_hKey, pszValueName, 0, REG_DWORD, &dwValue, sizeof(dwValue));
|
||||
return ::RegSetValueExW(m_hKey, pszValueName, 0, REG_DWORD, (LPBYTE)&dwValue, sizeof(dwValue));
|
||||
}
|
||||
|
||||
LSTATUS QuerySz(LPCWSTR pszValueName, LPWSTR pszValue, DWORD cchValueMax);
|
||||
@@ -53,6 +53,13 @@ public:
|
||||
DWORD cbValue = (lstrlenW(pszValue) + 1) * sizeof(WCHAR);
|
||||
return ::RegSetValueExW(m_hKey, pszValueName, 0, REG_SZ, (LPBYTE)pszValue, cbValue);
|
||||
}
|
||||
|
||||
LSTATUS DeleteSubKey(LPCWSTR lpSubKey)
|
||||
{
|
||||
return ::RegDeleteKeyW(m_hKey, lpSubKey);
|
||||
}
|
||||
|
||||
LSTATUS RecurseDeleteKey(LPCWSTR lpSubKey);
|
||||
};
|
||||
|
||||
/******************************************************************************/
|
||||
@@ -124,3 +131,29 @@ CicRegKey::QuerySz(LPCWSTR pszValueName, LPWSTR pszValue, DWORD cchValueMax)
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
inline LSTATUS
|
||||
CicRegKey::RecurseDeleteKey(LPCWSTR lpSubKey)
|
||||
{
|
||||
CicRegKey regKey;
|
||||
LSTATUS error = regKey.Open(m_hKey, lpSubKey, KEY_READ | KEY_WRITE);
|
||||
if (error != ERROR_SUCCESS)
|
||||
return error;
|
||||
|
||||
WCHAR szName[MAX_PATH];
|
||||
DWORD cchName;
|
||||
do
|
||||
{
|
||||
cchName = _countof(szName);
|
||||
error = ::RegEnumKeyExW(regKey, 0, szName, &cchName, NULL, NULL, NULL, NULL);
|
||||
if (error != ERROR_SUCCESS)
|
||||
break;
|
||||
|
||||
szName[_countof(szName) - 1] = UNICODE_NULL;
|
||||
error = regKey.RecurseDeleteKey(szName);
|
||||
} while (error == ERROR_SUCCESS);
|
||||
|
||||
regKey.Close();
|
||||
|
||||
return DeleteSubKey(lpSubKey);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user