https://git.reactos.org/?p=reactos.git;a=commitdiff;h=a8a47036995ccaff4f02a922ab2d1fa8f849339d

commit a8a47036995ccaff4f02a922ab2d1fa8f849339d
Author:     Katayama Hirofumi MZ <katayama.hirofumi...@gmail.com>
AuthorDate: Tue Dec 26 10:31:53 2023 +0900
Commit:     GitHub <nore...@github.com>
CommitDate: Tue Dec 26 10:31:53 2023 +0900

    [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
---
 dll/win32/msctf/CMakeLists.txt       |   7 ++-
 dll/win32/msctf/msctf.spec           |   2 +
 dll/win32/msctf/utils.cpp            | 102 +++++++++++++++++++++++++++++++++++
 sdk/include/reactos/cicero/cicbase.h |   2 +-
 sdk/include/reactos/cicero/cicreg.h  |  37 ++++++++++++-
 5 files changed, 146 insertions(+), 4 deletions(-)

diff --git a/dll/win32/msctf/CMakeLists.txt b/dll/win32/msctf/CMakeLists.txt
index 863559f5270..d8caf9a8e04 100644
--- a/dll/win32/msctf/CMakeLists.txt
+++ b/dll/win32/msctf/CMakeLists.txt
@@ -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)
diff --git a/dll/win32/msctf/msctf.spec b/dll/win32/msctf/msctf.spec
index e5a1a714c00..186e1cadac2 100644
--- a/dll/win32/msctf/msctf.spec
+++ b/dll/win32/msctf/msctf.spec
@@ -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)
diff --git a/dll/win32/msctf/utils.cpp b/dll/win32/msctf/utils.cpp
new file mode 100644
index 00000000000..9d0d455f8ad
--- /dev/null
+++ b/dll/win32/msctf/utils.cpp
@@ -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 
<katayama.hirofumi...@gmail.com>
+ */
+
+#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;
+}
diff --git a/sdk/include/reactos/cicero/cicbase.h 
b/sdk/include/reactos/cicero/cicbase.h
index 6bf6a491e80..28f5f96543f 100644
--- a/sdk/include/reactos/cicero/cicbase.h
+++ b/sdk/include/reactos/cicero/cicbase.h
@@ -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
     {
diff --git a/sdk/include/reactos/cicero/cicreg.h 
b/sdk/include/reactos/cicero/cicreg.h
index 674d1d27ed2..da18e0bd49e 100644
--- a/sdk/include/reactos/cicero/cicreg.h
+++ b/sdk/include/reactos/cicero/cicreg.h
@@ -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);
+}

Reply via email to