Index: reactos/dll/win32/imm32/imm.c =================================================================== --- reactos/dll/win32/imm32/imm.c (revision 75861) +++ reactos/dll/win32/imm32/imm.c (working copy) @@ -3,6 +3,7 @@ * * Copyright 1998 Patrik Stridvall * Copyright 2002, 2003, 2007 CodeWeavers, Aric Stewart + * Copyright 2017 Katayama Hirofumi MZ * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -1881,53 +1882,110 @@ INT lcid = GetUserDefaultLCID(); INT count; HKL hkl; - DWORD rc; - HKEY hkey; - WCHAR regKey[sizeof(szImeRegFmt)/sizeof(WCHAR)+8]; + DWORD rc, dwIndex; + HKEY hkeyBase, hkey; + WCHAR szName[MAX_PATH + 1], regKey[_countof(szImeRegFmt) + 8]; + WCHAR szFile[MAX_PATH + 1]; + static const WCHAR s_szLayoutsBase[] = + L"SYSTEM\\CurrentControlSet\\Control\\Keyboard Layouts"; TRACE ("(%s, %s):\n", debugstr_w(lpszIMEFileName), debugstr_w(lpszLayoutText)); - /* Start with 2. e001 will be blank and so default to the wine internal IME */ - count = 2; + if (GetFileAttributesW(lpszIMEFileName) == (DWORD)-1) + { + WARN("The IME file was not found\n"); + return 0; + } - while (count < 0xfff) + /* Check pre-existent keys */ + rc = RegOpenKeyW(HKEY_LOCAL_MACHINE, s_szLayoutsBase, &hkeyBase); + if (rc == ERROR_SUCCESS) { - DWORD disposition = 0; + /* Scan keys */ + for (dwIndex = 0; dwIndex <= 0xFFF; ++dwIndex) + { + const DWORD cchName = _countof(szName); + rc = RegEnumKeyW(hkeyBase, dwIndex, szName, cchName); + if (rc != ERROR_SUCCESS) + break; /* no more key */ - hkl = (HKL)MAKELPARAM( lcid, 0xe000 | count ); - wsprintfW( regKey, szImeRegFmt, (ULONG_PTR)hkl); + hkl = (HKL)wcstoul(szName, NULL, 16); + if ((HIWORD(hkl) & 0xF000) != 0xE000) + { + continue; /* invalid */ + } - rc = RegCreateKeyExW(HKEY_LOCAL_MACHINE, regKey, 0, NULL, 0, KEY_WRITE, NULL, &hkey, &disposition); - if (rc == ERROR_SUCCESS && disposition == REG_CREATED_NEW_KEY) - break; - else if (rc == ERROR_SUCCESS) - RegCloseKey(hkey); - - count++; + rc = RegOpenKeyW(hkeyBase, szName, &hkey); + if (rc == ERROR_SUCCESS) + { + DWORD cbValue = sizeof(szFile); + rc = RegQueryValueExW(hkey, szImeFileW, NULL, NULL, (LPBYTE)szFile, &cbValue); + if (rc == ERROR_SUCCESS) + { + WCHAR *pch; + if (GetFullPathNameW(lpszIMEFileName, _countof(szName), szName, &pch) && + lstrcmpiW(pch, szFile) == 0) + { + break; /* found */ + } + } + /* mismatch */ + RegCloseKey(hkey); + hkey = NULL; + } + } } - if (count == 0xfff) + if (rc != ERROR_SUCCESS) { - WARN("Unable to find slot to install IME\n"); - return 0; + /* Start with 2. e001 will be blank and so default to the wine internal IME */ + count = 2; + + while (count < 0xfff) + { + DWORD disposition = 0; + + hkl = (HKL)MAKELPARAM( lcid, 0xe000 | count ); + wsprintfW( regKey, szImeRegFmt, (ULONG_PTR)hkl); + + rc = RegCreateKeyExW(HKEY_LOCAL_MACHINE, regKey, 0, NULL, 0, KEY_WRITE, NULL, &hkey, &disposition); + if (rc == ERROR_SUCCESS && disposition == REG_CREATED_NEW_KEY) + break; + else if (rc == ERROR_SUCCESS) + RegCloseKey(hkey); + + count++; + } + + if (count == 0xfff) + { + WARN("Unable to find slot to install IME\n"); + RegCloseKey(hkeyBase); + return 0; + } } if (rc == ERROR_SUCCESS) { - rc = RegSetValueExW(hkey, szImeFileW, 0, REG_SZ, (const BYTE*)lpszIMEFileName, - (lstrlenW(lpszIMEFileName) + 1) * sizeof(WCHAR)); - if (rc == ERROR_SUCCESS) - rc = RegSetValueExW(hkey, szLayoutTextW, 0, REG_SZ, (const BYTE*)lpszLayoutText, - (lstrlenW(lpszLayoutText) + 1) * sizeof(WCHAR)); - RegCloseKey(hkey); - return hkl; + WCHAR *pchTitle = NULL; + if (GetFullPathNameW(lpszIMEFileName, _countof(szName), szName, &pchTitle)) + { + rc = RegSetValueExW(hkey, szImeFileW, 0, REG_SZ, (const BYTE*)pchTitle, + (lstrlenW(pchTitle) + 1) * sizeof(WCHAR)); + if (rc == ERROR_SUCCESS) + rc = RegSetValueExW(hkey, szLayoutTextW, 0, REG_SZ, (const BYTE*)lpszLayoutText, + (lstrlenW(lpszLayoutText) + 1) * sizeof(WCHAR)); + /* FIXME: Fix "Layout File" value if wrong */ + RegCloseKey(hkey); + RegCloseKey(hkeyBase); + return hkl; + } } - else - { - WARN("Unable to set IME registry values\n"); - return 0; - } + + WARN("Unable to set IME registry values\n"); + RegCloseKey(hkeyBase); + return 0; } /***********************************************************************