ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

inputprocessor.c
Go to the documentation of this file.
00001 /*
00002  *  ITfInputProcessorProfiles implementation
00003  *
00004  *  Copyright 2009 Aric Stewart, CodeWeavers
00005  *
00006  * This library is free software; you can redistribute it and/or
00007  * modify it under the terms of the GNU Lesser General Public
00008  * License as published by the Free Software Foundation; either
00009  * version 2.1 of the License, or (at your option) any later version.
00010  *
00011  * This library is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014  * Lesser General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU Lesser General Public
00017  * License along with this library; if not, write to the Free Software
00018  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
00019  */
00020 
00021 #include "config.h"
00022 
00023 #include <stdarg.h>
00024 
00025 #define COBJMACROS
00026 
00027 #include "wine/debug.h"
00028 #include "windef.h"
00029 #include "winbase.h"
00030 #include "winreg.h"
00031 #include "winuser.h"
00032 #include "shlwapi.h"
00033 #include "winerror.h"
00034 #include "objbase.h"
00035 #include "olectl.h"
00036 
00037 #include "wine/unicode.h"
00038 #include "wine/list.h"
00039 
00040 #include "msctf.h"
00041 #include "msctf_internal.h"
00042 
00043 WINE_DEFAULT_DEBUG_CHANNEL(msctf);
00044 
00045 static const WCHAR szwLngp[] = {'L','a','n','g','u','a','g','e','P','r','o','f','i','l','e',0};
00046 static const WCHAR szwEnable[] = {'E','n','a','b','l','e',0};
00047 static const WCHAR szwTipfmt[] = {'%','s','\\','%','s',0};
00048 static const WCHAR szwFullLangfmt[] = {'%','s','\\','%','s','\\','%','s','\\','0','x','%','0','8','x','\\','%','s',0};
00049 
00050 static const WCHAR szwAssemblies[] = {'A','s','s','e','m','b','l','i','e','s',0};
00051 static const WCHAR szwDefault[] = {'D','e','f','a','u','l','t',0};
00052 static const WCHAR szwProfile[] = {'P','r','o','f','i','l','e',0};
00053 static const WCHAR szwDefaultFmt[] = {'%','s','\\','%','s','\\','0','x','%','0','8','x','\\','%','s',0};
00054 
00055 typedef struct tagInputProcessorProfilesSink {
00056     struct list         entry;
00057     union {
00058         /* InputProcessorProfile Sinks */
00059         IUnknown            *pIUnknown;
00060         ITfLanguageProfileNotifySink *pITfLanguageProfileNotifySink;
00061     } interfaces;
00062 } InputProcessorProfilesSink;
00063 
00064 typedef struct tagInputProcessorProfiles {
00065     const ITfInputProcessorProfilesVtbl *InputProcessorProfilesVtbl;
00066     const ITfSourceVtbl *SourceVtbl;
00067     /* const ITfInputProcessorProfileMgrVtbl *InputProcessorProfileMgrVtbl; */
00068     /* const ITfInputProcessorProfilesExVtbl *InputProcessorProfilesExVtbl; */
00069     /* const ITfInputProcessorProfileSubstituteLayoutVtbl *InputProcessorProfileSubstituteLayoutVtbl; */
00070     LONG refCount;
00071 
00072     LANGID  currentLanguage;
00073 
00074     struct list     LanguageProfileNotifySink;
00075 } InputProcessorProfiles;
00076 
00077 typedef struct tagProfilesEnumGuid {
00078     const IEnumGUIDVtbl *Vtbl;
00079     LONG refCount;
00080 
00081     HKEY key;
00082     DWORD next_index;
00083 } ProfilesEnumGuid;
00084 
00085 typedef struct tagEnumTfLanguageProfiles {
00086     const IEnumTfLanguageProfilesVtbl *Vtbl;
00087     LONG refCount;
00088 
00089     HKEY    tipkey;
00090     DWORD   tip_index;
00091     WCHAR   szwCurrentClsid[39];
00092 
00093     HKEY    langkey;
00094     DWORD   lang_index;
00095 
00096     LANGID  langid;
00097     ITfCategoryMgr *catmgr;
00098 } EnumTfLanguageProfiles;
00099 
00100 static HRESULT ProfilesEnumGuid_Constructor(IEnumGUID **ppOut);
00101 static HRESULT EnumTfLanguageProfiles_Constructor(LANGID langid, IEnumTfLanguageProfiles **ppOut);
00102 
00103 static inline InputProcessorProfiles *impl_from_ITfSourceVtbl(ITfSource *iface)
00104 {
00105     return (InputProcessorProfiles *)((char *)iface - FIELD_OFFSET(InputProcessorProfiles,SourceVtbl));
00106 }
00107 
00108 static void free_sink(InputProcessorProfilesSink *sink)
00109 {
00110         IUnknown_Release(sink->interfaces.pIUnknown);
00111         HeapFree(GetProcessHeap(),0,sink);
00112 }
00113 
00114 static void InputProcessorProfiles_Destructor(InputProcessorProfiles *This)
00115 {
00116     struct list *cursor, *cursor2;
00117     TRACE("destroying %p\n", This);
00118 
00119     /* free sinks */
00120     LIST_FOR_EACH_SAFE(cursor, cursor2, &This->LanguageProfileNotifySink)
00121     {
00122         InputProcessorProfilesSink* sink = LIST_ENTRY(cursor,InputProcessorProfilesSink,entry);
00123         list_remove(cursor);
00124         free_sink(sink);
00125     }
00126 
00127     HeapFree(GetProcessHeap(),0,This);
00128 }
00129 
00130 static void add_userkey( REFCLSID rclsid, LANGID langid,
00131                                 REFGUID guidProfile)
00132 {
00133     HKEY key;
00134     WCHAR buf[39];
00135     WCHAR buf2[39];
00136     WCHAR fullkey[168];
00137     DWORD disposition = 0;
00138     ULONG res;
00139 
00140     TRACE("\n");
00141 
00142     StringFromGUID2(rclsid, buf, 39);
00143     StringFromGUID2(guidProfile, buf2, 39);
00144     sprintfW(fullkey,szwFullLangfmt,szwSystemTIPKey,buf,szwLngp,langid,buf2);
00145 
00146     res = RegCreateKeyExW(HKEY_CURRENT_USER,fullkey, 0, NULL, 0,
00147                    KEY_READ | KEY_WRITE, NULL, &key, &disposition);
00148 
00149     if (!res && disposition == REG_CREATED_NEW_KEY)
00150     {
00151         DWORD zero = 0x0;
00152         RegSetValueExW(key, szwEnable, 0, REG_DWORD, (LPBYTE)&zero, sizeof(DWORD));
00153     }
00154 
00155     if (!res)
00156         RegCloseKey(key);
00157 }
00158 
00159 static HRESULT WINAPI InputProcessorProfiles_QueryInterface(ITfInputProcessorProfiles *iface, REFIID iid, LPVOID *ppvOut)
00160 {
00161     InputProcessorProfiles *This = (InputProcessorProfiles *)iface;
00162     *ppvOut = NULL;
00163 
00164     if (IsEqualIID(iid, &IID_IUnknown) || IsEqualIID(iid, &IID_ITfInputProcessorProfiles))
00165     {
00166         *ppvOut = This;
00167     }
00168     else if (IsEqualIID(iid, &IID_ITfSource))
00169     {
00170         *ppvOut = &This->SourceVtbl;
00171     }
00172 
00173     if (*ppvOut)
00174     {
00175         IUnknown_AddRef(iface);
00176         return S_OK;
00177     }
00178 
00179     WARN("unsupported interface: %s\n", debugstr_guid(iid));
00180     return E_NOINTERFACE;
00181 }
00182 
00183 static ULONG WINAPI InputProcessorProfiles_AddRef(ITfInputProcessorProfiles *iface)
00184 {
00185     InputProcessorProfiles *This = (InputProcessorProfiles *)iface;
00186     return InterlockedIncrement(&This->refCount);
00187 }
00188 
00189 static ULONG WINAPI InputProcessorProfiles_Release(ITfInputProcessorProfiles *iface)
00190 {
00191     InputProcessorProfiles *This = (InputProcessorProfiles *)iface;
00192     ULONG ret;
00193 
00194     ret = InterlockedDecrement(&This->refCount);
00195     if (ret == 0)
00196         InputProcessorProfiles_Destructor(This);
00197     return ret;
00198 }
00199 
00200 /*****************************************************
00201  * ITfInputProcessorProfiles functions
00202  *****************************************************/
00203 static HRESULT WINAPI InputProcessorProfiles_Register(
00204         ITfInputProcessorProfiles *iface, REFCLSID rclsid)
00205 {
00206     InputProcessorProfiles *This = (InputProcessorProfiles*)iface;
00207     HKEY tipkey;
00208     WCHAR buf[39];
00209     WCHAR fullkey[68];
00210 
00211     TRACE("(%p) %s\n",This,debugstr_guid(rclsid));
00212 
00213     StringFromGUID2(rclsid, buf, 39);
00214     sprintfW(fullkey,szwTipfmt,szwSystemTIPKey,buf);
00215 
00216     if (RegCreateKeyExW(HKEY_LOCAL_MACHINE,fullkey, 0, NULL, 0,
00217                     KEY_READ | KEY_WRITE, NULL, &tipkey, NULL) != ERROR_SUCCESS)
00218         return E_FAIL;
00219 
00220     RegCloseKey(tipkey);
00221 
00222     return S_OK;
00223 }
00224 
00225 static HRESULT WINAPI InputProcessorProfiles_Unregister(
00226         ITfInputProcessorProfiles *iface, REFCLSID rclsid)
00227 {
00228     WCHAR buf[39];
00229     WCHAR fullkey[68];
00230     InputProcessorProfiles *This = (InputProcessorProfiles*)iface;
00231 
00232     TRACE("(%p) %s\n",This,debugstr_guid(rclsid));
00233 
00234     StringFromGUID2(rclsid, buf, 39);
00235     sprintfW(fullkey,szwTipfmt,szwSystemTIPKey,buf);
00236 
00237     RegDeleteTreeW(HKEY_LOCAL_MACHINE, fullkey);
00238     RegDeleteTreeW(HKEY_CURRENT_USER, fullkey);
00239 
00240     return S_OK;
00241 }
00242 
00243 static HRESULT WINAPI InputProcessorProfiles_AddLanguageProfile(
00244         ITfInputProcessorProfiles *iface, REFCLSID rclsid,
00245         LANGID langid, REFGUID guidProfile, const WCHAR *pchDesc,
00246         ULONG cchDesc, const WCHAR *pchIconFile, ULONG cchFile,
00247         ULONG uIconIndex)
00248 {
00249     HKEY tipkey,fmtkey;
00250     WCHAR buf[39];
00251     WCHAR fullkey[100];
00252     ULONG res;
00253     DWORD disposition = 0;
00254 
00255     static const WCHAR fmt2[] = {'%','s','\\','0','x','%','0','8','x','\\','%','s',0};
00256     static const WCHAR desc[] = {'D','e','s','c','r','i','p','t','i','o','n',0};
00257     static const WCHAR icnf[] = {'I','c','o','n','F','i','l','e',0};
00258     static const WCHAR icni[] = {'I','c','o','n','I','n','d','e','x',0};
00259 
00260     InputProcessorProfiles *This = (InputProcessorProfiles*)iface;
00261 
00262     TRACE("(%p) %s %x %s %s %s %i\n",This,debugstr_guid(rclsid), langid,
00263             debugstr_guid(guidProfile), debugstr_wn(pchDesc,cchDesc),
00264             debugstr_wn(pchIconFile,cchFile),uIconIndex);
00265 
00266     StringFromGUID2(rclsid, buf, 39);
00267     sprintfW(fullkey,szwTipfmt,szwSystemTIPKey,buf);
00268 
00269     if (RegOpenKeyExW(HKEY_LOCAL_MACHINE,fullkey, 0, KEY_READ | KEY_WRITE,
00270                 &tipkey ) != ERROR_SUCCESS)
00271         return E_FAIL;
00272 
00273     StringFromGUID2(guidProfile, buf, 39);
00274     sprintfW(fullkey,fmt2,szwLngp,langid,buf);
00275 
00276     res = RegCreateKeyExW(tipkey,fullkey, 0, NULL, 0, KEY_READ | KEY_WRITE,
00277             NULL, &fmtkey, &disposition);
00278 
00279     if (!res)
00280     {
00281         DWORD zero = 0x0;
00282         RegSetValueExW(fmtkey, desc, 0, REG_SZ, (const BYTE*)pchDesc, cchDesc * sizeof(WCHAR));
00283         RegSetValueExW(fmtkey, icnf, 0, REG_SZ, (const BYTE*)pchIconFile, cchFile * sizeof(WCHAR));
00284         RegSetValueExW(fmtkey, icni, 0, REG_DWORD, (LPBYTE)&uIconIndex, sizeof(DWORD));
00285         if (disposition == REG_CREATED_NEW_KEY)
00286             RegSetValueExW(fmtkey, szwEnable, 0, REG_DWORD, (LPBYTE)&zero, sizeof(DWORD));
00287         RegCloseKey(fmtkey);
00288 
00289         add_userkey(rclsid, langid, guidProfile);
00290     }
00291     RegCloseKey(tipkey);
00292 
00293     if (!res)
00294         return S_OK;
00295     else
00296         return E_FAIL;
00297 }
00298 
00299 static HRESULT WINAPI InputProcessorProfiles_RemoveLanguageProfile(
00300         ITfInputProcessorProfiles *iface, REFCLSID rclsid, LANGID langid,
00301         REFGUID guidProfile)
00302 {
00303     InputProcessorProfiles *This = (InputProcessorProfiles*)iface;
00304     FIXME("STUB:(%p)\n",This);
00305     return E_NOTIMPL;
00306 }
00307 
00308 static HRESULT WINAPI InputProcessorProfiles_EnumInputProcessorInfo(
00309         ITfInputProcessorProfiles *iface, IEnumGUID **ppEnum)
00310 {
00311     InputProcessorProfiles *This = (InputProcessorProfiles*)iface;
00312     TRACE("(%p) %p\n",This,ppEnum);
00313     return ProfilesEnumGuid_Constructor(ppEnum);
00314 }
00315 
00316 static HRESULT WINAPI InputProcessorProfiles_GetDefaultLanguageProfile(
00317         ITfInputProcessorProfiles *iface, LANGID langid, REFGUID catid,
00318         CLSID *pclsid, GUID *pguidProfile)
00319 {
00320     WCHAR fullkey[168];
00321     WCHAR buf[39];
00322     HKEY hkey;
00323     DWORD count;
00324     ULONG res;
00325     InputProcessorProfiles *This = (InputProcessorProfiles*)iface;
00326 
00327     TRACE("%p) %x %s %p %p\n",This, langid, debugstr_guid(catid),pclsid,pguidProfile);
00328 
00329     if (!catid || !pclsid || !pguidProfile)
00330         return E_INVALIDARG;
00331 
00332     StringFromGUID2(catid, buf, 39);
00333     sprintfW(fullkey, szwDefaultFmt, szwSystemCTFKey, szwAssemblies, langid, buf);
00334 
00335     if (RegOpenKeyExW(HKEY_CURRENT_USER, fullkey, 0, KEY_READ | KEY_WRITE,
00336                 &hkey ) != ERROR_SUCCESS)
00337         return S_FALSE;
00338 
00339     count = sizeof(buf);
00340     res = RegQueryValueExW(hkey, szwDefault, 0, NULL, (LPBYTE)buf, &count);
00341     if (res != ERROR_SUCCESS)
00342     {
00343         RegCloseKey(hkey);
00344         return S_FALSE;
00345     }
00346     CLSIDFromString(buf,pclsid);
00347 
00348     res = RegQueryValueExW(hkey, szwProfile, 0, NULL, (LPBYTE)buf, &count);
00349     if (res == ERROR_SUCCESS)
00350         CLSIDFromString(buf,pguidProfile);
00351 
00352     RegCloseKey(hkey);
00353 
00354     return S_OK;
00355 }
00356 
00357 static HRESULT WINAPI InputProcessorProfiles_SetDefaultLanguageProfile(
00358         ITfInputProcessorProfiles *iface, LANGID langid, REFCLSID rclsid,
00359         REFGUID guidProfiles)
00360 {
00361     WCHAR fullkey[168];
00362     WCHAR buf[39];
00363     HKEY hkey;
00364     GUID catid;
00365     HRESULT hr;
00366     ITfCategoryMgr *catmgr;
00367     InputProcessorProfiles *This = (InputProcessorProfiles*)iface;
00368     static const GUID * tipcats[3] = { &GUID_TFCAT_TIP_KEYBOARD,
00369                                        &GUID_TFCAT_TIP_SPEECH,
00370                                        &GUID_TFCAT_TIP_HANDWRITING };
00371 
00372     TRACE("%p) %x %s %s\n",This, langid, debugstr_guid(rclsid),debugstr_guid(guidProfiles));
00373 
00374     if (!rclsid || !guidProfiles)
00375         return E_INVALIDARG;
00376 
00377     hr = CategoryMgr_Constructor(NULL,(IUnknown**)&catmgr);
00378 
00379     if (FAILED(hr))
00380         return hr;
00381 
00382     if (ITfCategoryMgr_FindClosestCategory(catmgr, rclsid,
00383             &catid, tipcats, 3) != S_OK)
00384         hr = ITfCategoryMgr_FindClosestCategory(catmgr, rclsid,
00385                 &catid, NULL, 0);
00386     ITfCategoryMgr_Release(catmgr);
00387 
00388     if (FAILED(hr))
00389         return E_FAIL;
00390 
00391     StringFromGUID2(&catid, buf, 39);
00392     sprintfW(fullkey, szwDefaultFmt, szwSystemCTFKey, szwAssemblies, langid, buf);
00393 
00394     if (RegCreateKeyExW(HKEY_CURRENT_USER, fullkey, 0, NULL, 0, KEY_READ | KEY_WRITE,
00395                 NULL, &hkey, NULL ) != ERROR_SUCCESS)
00396         return E_FAIL;
00397 
00398     StringFromGUID2(rclsid, buf, 39);
00399     RegSetValueExW(hkey, szwDefault, 0, REG_SZ, (LPBYTE)buf, sizeof(buf));
00400     StringFromGUID2(guidProfiles, buf, 39);
00401     RegSetValueExW(hkey, szwProfile, 0, REG_SZ, (LPBYTE)buf, sizeof(buf));
00402     RegCloseKey(hkey);
00403 
00404     return S_OK;
00405 }
00406 
00407 static HRESULT WINAPI InputProcessorProfiles_ActivateLanguageProfile(
00408         ITfInputProcessorProfiles *iface, REFCLSID rclsid, LANGID langid,
00409         REFGUID guidProfiles)
00410 {
00411     HRESULT hr;
00412     BOOL enabled;
00413     TF_LANGUAGEPROFILE LanguageProfile;
00414     InputProcessorProfiles *This = (InputProcessorProfiles*)iface;
00415 
00416     TRACE("(%p) %s %x %s\n",This,debugstr_guid(rclsid),langid,debugstr_guid(guidProfiles));
00417 
00418     if (langid != This->currentLanguage) return E_INVALIDARG;
00419 
00420     if (get_active_textservice(rclsid,NULL))
00421     {
00422         TRACE("Already Active\n");
00423         return E_FAIL;
00424     }
00425 
00426     hr = ITfInputProcessorProfiles_IsEnabledLanguageProfile(iface, rclsid,
00427             langid, guidProfiles, &enabled);
00428     if (FAILED(hr) || !enabled)
00429     {
00430         TRACE("Not Enabled\n");
00431         return E_FAIL;
00432     }
00433 
00434     LanguageProfile.clsid = *rclsid;
00435     LanguageProfile.langid = langid;
00436     LanguageProfile.guidProfile = *guidProfiles;
00437 
00438     hr = add_active_textservice(&LanguageProfile);
00439 
00440     return hr;
00441 }
00442 
00443 static HRESULT WINAPI InputProcessorProfiles_GetActiveLanguageProfile(
00444         ITfInputProcessorProfiles *iface, REFCLSID rclsid, LANGID *plangid,
00445         GUID *pguidProfile)
00446 {
00447     TF_LANGUAGEPROFILE profile;
00448     InputProcessorProfiles *This = (InputProcessorProfiles*)iface;
00449 
00450     TRACE("(%p) %s %p %p\n",This,debugstr_guid(rclsid),plangid,pguidProfile);
00451 
00452     if (!rclsid || !plangid || !pguidProfile)
00453         return E_INVALIDARG;
00454 
00455     if (get_active_textservice(rclsid, &profile))
00456     {
00457         *plangid = profile.langid;
00458         *pguidProfile = profile.guidProfile;
00459         return S_OK;
00460     }
00461     else
00462     {
00463         *pguidProfile = GUID_NULL;
00464         return S_FALSE;
00465     }
00466 }
00467 
00468 static HRESULT WINAPI InputProcessorProfiles_GetLanguageProfileDescription(
00469         ITfInputProcessorProfiles *iface, REFCLSID rclsid, LANGID langid,
00470         REFGUID guidProfile, BSTR *pbstrProfile)
00471 {
00472     InputProcessorProfiles *This = (InputProcessorProfiles*)iface;
00473     FIXME("STUB:(%p)\n",This);
00474     return E_NOTIMPL;
00475 }
00476 
00477 static HRESULT WINAPI InputProcessorProfiles_GetCurrentLanguage(
00478         ITfInputProcessorProfiles *iface, LANGID *plangid)
00479 {
00480     InputProcessorProfiles *This = (InputProcessorProfiles*)iface;
00481     TRACE("(%p) 0x%x\n",This,This->currentLanguage);
00482 
00483     if (!plangid)
00484         return E_INVALIDARG;
00485 
00486     *plangid = This->currentLanguage;
00487 
00488     return S_OK;
00489 }
00490 
00491 static HRESULT WINAPI InputProcessorProfiles_ChangeCurrentLanguage(
00492         ITfInputProcessorProfiles *iface, LANGID langid)
00493 {
00494     struct list *cursor;
00495     InputProcessorProfiles *This = (InputProcessorProfiles*)iface;
00496     BOOL accept;
00497 
00498     FIXME("STUB:(%p)\n",This);
00499 
00500     LIST_FOR_EACH(cursor, &This->LanguageProfileNotifySink)
00501     {
00502         InputProcessorProfilesSink* sink = LIST_ENTRY(cursor,InputProcessorProfilesSink,entry);
00503         accept = TRUE;
00504         ITfLanguageProfileNotifySink_OnLanguageChange(sink->interfaces.pITfLanguageProfileNotifySink, langid, &accept);
00505         if (!accept)
00506             return  E_FAIL;
00507     }
00508 
00509     /* TODO:  On successful language change call OnLanguageChanged sink */
00510     return E_NOTIMPL;
00511 }
00512 
00513 static HRESULT WINAPI InputProcessorProfiles_GetLanguageList(
00514         ITfInputProcessorProfiles *iface, LANGID **ppLangId, ULONG *pulCount)
00515 {
00516     InputProcessorProfiles *This = (InputProcessorProfiles*)iface;
00517     FIXME("Semi-STUB:(%p)\n",This);
00518     *ppLangId = CoTaskMemAlloc(sizeof(LANGID));
00519     **ppLangId = This->currentLanguage;
00520     *pulCount = 1;
00521     return S_OK;
00522 }
00523 
00524 static HRESULT WINAPI InputProcessorProfiles_EnumLanguageProfiles(
00525         ITfInputProcessorProfiles *iface, LANGID langid,
00526         IEnumTfLanguageProfiles **ppEnum)
00527 {
00528     InputProcessorProfiles *This = (InputProcessorProfiles*)iface;
00529     TRACE("(%p) %x %p\n",This,langid,ppEnum);
00530     return EnumTfLanguageProfiles_Constructor(langid, ppEnum);
00531 }
00532 
00533 static HRESULT WINAPI InputProcessorProfiles_EnableLanguageProfile(
00534         ITfInputProcessorProfiles *iface, REFCLSID rclsid, LANGID langid,
00535         REFGUID guidProfile, BOOL fEnable)
00536 {
00537     HKEY key;
00538     WCHAR buf[39];
00539     WCHAR buf2[39];
00540     WCHAR fullkey[168];
00541     ULONG res;
00542 
00543     InputProcessorProfiles *This = (InputProcessorProfiles*)iface;
00544     TRACE("(%p) %s %x %s %i\n",This, debugstr_guid(rclsid), langid, debugstr_guid(guidProfile), fEnable);
00545 
00546     StringFromGUID2(rclsid, buf, 39);
00547     StringFromGUID2(guidProfile, buf2, 39);
00548     sprintfW(fullkey,szwFullLangfmt,szwSystemTIPKey,buf,szwLngp,langid,buf2);
00549 
00550     res = RegOpenKeyExW(HKEY_CURRENT_USER, fullkey, 0, KEY_READ | KEY_WRITE, &key);
00551 
00552     if (!res)
00553     {
00554         RegSetValueExW(key, szwEnable, 0, REG_DWORD, (LPBYTE)&fEnable, sizeof(DWORD));
00555         RegCloseKey(key);
00556     }
00557     else
00558         return E_FAIL;
00559 
00560     return S_OK;
00561 }
00562 
00563 static HRESULT WINAPI InputProcessorProfiles_IsEnabledLanguageProfile(
00564         ITfInputProcessorProfiles *iface, REFCLSID rclsid, LANGID langid,
00565         REFGUID guidProfile, BOOL *pfEnable)
00566 {
00567     HKEY key;
00568     WCHAR buf[39];
00569     WCHAR buf2[39];
00570     WCHAR fullkey[168];
00571     ULONG res;
00572 
00573     InputProcessorProfiles *This = (InputProcessorProfiles*)iface;
00574     TRACE("(%p) %s, %i, %s, %p\n",This,debugstr_guid(rclsid),langid,debugstr_guid(guidProfile),pfEnable);
00575 
00576     if (!pfEnable)
00577         return E_INVALIDARG;
00578 
00579     StringFromGUID2(rclsid, buf, 39);
00580     StringFromGUID2(guidProfile, buf2, 39);
00581     sprintfW(fullkey,szwFullLangfmt,szwSystemTIPKey,buf,szwLngp,langid,buf2);
00582 
00583     res = RegOpenKeyExW(HKEY_CURRENT_USER, fullkey, 0, KEY_READ | KEY_WRITE, &key);
00584 
00585     if (!res)
00586     {
00587         DWORD count = sizeof(DWORD);
00588         res = RegQueryValueExW(key, szwEnable, 0, NULL, (LPBYTE)pfEnable, &count);
00589         RegCloseKey(key);
00590     }
00591 
00592     if (res)  /* Try Default */
00593     {
00594         res = RegOpenKeyExW(HKEY_LOCAL_MACHINE, fullkey, 0, KEY_READ | KEY_WRITE, &key);
00595 
00596         if (!res)
00597         {
00598             DWORD count = sizeof(DWORD);
00599             res = RegQueryValueExW(key, szwEnable, 0, NULL, (LPBYTE)pfEnable, &count);
00600             RegCloseKey(key);
00601         }
00602     }
00603 
00604     if (!res)
00605         return S_OK;
00606     else
00607         return E_FAIL;
00608 }
00609 
00610 static HRESULT WINAPI InputProcessorProfiles_EnableLanguageProfileByDefault(
00611         ITfInputProcessorProfiles *iface, REFCLSID rclsid, LANGID langid,
00612         REFGUID guidProfile, BOOL fEnable)
00613 {
00614     HKEY key;
00615     WCHAR buf[39];
00616     WCHAR buf2[39];
00617     WCHAR fullkey[168];
00618     ULONG res;
00619 
00620     InputProcessorProfiles *This = (InputProcessorProfiles*)iface;
00621     TRACE("(%p) %s %x %s %i\n",This,debugstr_guid(rclsid),langid,debugstr_guid(guidProfile),fEnable);
00622 
00623     StringFromGUID2(rclsid, buf, 39);
00624     StringFromGUID2(guidProfile, buf2, 39);
00625     sprintfW(fullkey,szwFullLangfmt,szwSystemTIPKey,buf,szwLngp,langid,buf2);
00626 
00627     res = RegOpenKeyExW(HKEY_LOCAL_MACHINE, fullkey, 0, KEY_READ | KEY_WRITE, &key);
00628 
00629     if (!res)
00630     {
00631         RegSetValueExW(key, szwEnable, 0, REG_DWORD, (LPBYTE)&fEnable, sizeof(DWORD));
00632         RegCloseKey(key);
00633     }
00634     else
00635         return E_FAIL;
00636 
00637     return S_OK;
00638 }
00639 
00640 static HRESULT WINAPI InputProcessorProfiles_SubstituteKeyboardLayout(
00641         ITfInputProcessorProfiles *iface, REFCLSID rclsid, LANGID langid,
00642         REFGUID guidProfile, HKL hKL)
00643 {
00644     InputProcessorProfiles *This = (InputProcessorProfiles*)iface;
00645     FIXME("STUB:(%p)\n",This);
00646     return E_NOTIMPL;
00647 }
00648 
00649 
00650 static const ITfInputProcessorProfilesVtbl InputProcessorProfiles_InputProcessorProfilesVtbl =
00651 {
00652     InputProcessorProfiles_QueryInterface,
00653     InputProcessorProfiles_AddRef,
00654     InputProcessorProfiles_Release,
00655 
00656     InputProcessorProfiles_Register,
00657     InputProcessorProfiles_Unregister,
00658     InputProcessorProfiles_AddLanguageProfile,
00659     InputProcessorProfiles_RemoveLanguageProfile,
00660     InputProcessorProfiles_EnumInputProcessorInfo,
00661     InputProcessorProfiles_GetDefaultLanguageProfile,
00662     InputProcessorProfiles_SetDefaultLanguageProfile,
00663     InputProcessorProfiles_ActivateLanguageProfile,
00664     InputProcessorProfiles_GetActiveLanguageProfile,
00665     InputProcessorProfiles_GetLanguageProfileDescription,
00666     InputProcessorProfiles_GetCurrentLanguage,
00667     InputProcessorProfiles_ChangeCurrentLanguage,
00668     InputProcessorProfiles_GetLanguageList,
00669     InputProcessorProfiles_EnumLanguageProfiles,
00670     InputProcessorProfiles_EnableLanguageProfile,
00671     InputProcessorProfiles_IsEnabledLanguageProfile,
00672     InputProcessorProfiles_EnableLanguageProfileByDefault,
00673     InputProcessorProfiles_SubstituteKeyboardLayout
00674 };
00675 
00676 /*****************************************************
00677  * ITfSource functions
00678  *****************************************************/
00679 static HRESULT WINAPI IPPSource_QueryInterface(ITfSource *iface, REFIID iid, LPVOID *ppvOut)
00680 {
00681     InputProcessorProfiles *This = impl_from_ITfSourceVtbl(iface);
00682     return InputProcessorProfiles_QueryInterface((ITfInputProcessorProfiles *)This, iid, *ppvOut);
00683 }
00684 
00685 static ULONG WINAPI IPPSource_AddRef(ITfSource *iface)
00686 {
00687     InputProcessorProfiles *This = impl_from_ITfSourceVtbl(iface);
00688     return InputProcessorProfiles_AddRef((ITfInputProcessorProfiles*)This);
00689 }
00690 
00691 static ULONG WINAPI IPPSource_Release(ITfSource *iface)
00692 {
00693     InputProcessorProfiles *This = impl_from_ITfSourceVtbl(iface);
00694     return InputProcessorProfiles_Release((ITfInputProcessorProfiles *)This);
00695 }
00696 
00697 static HRESULT WINAPI IPPSource_AdviseSink(ITfSource *iface,
00698         REFIID riid, IUnknown *punk, DWORD *pdwCookie)
00699 {
00700     InputProcessorProfilesSink *ipps;
00701     InputProcessorProfiles *This = impl_from_ITfSourceVtbl(iface);
00702 
00703     TRACE("(%p) %s %p %p\n",This,debugstr_guid(riid),punk,pdwCookie);
00704 
00705     if (!riid || !punk || !pdwCookie)
00706         return E_INVALIDARG;
00707 
00708     if (IsEqualIID(riid, &IID_ITfLanguageProfileNotifySink))
00709     {
00710         ipps = HeapAlloc(GetProcessHeap(),0,sizeof(InputProcessorProfilesSink));
00711         if (!ipps)
00712             return E_OUTOFMEMORY;
00713         if (FAILED(IUnknown_QueryInterface(punk, riid, (LPVOID *)&ipps->interfaces.pITfLanguageProfileNotifySink)))
00714         {
00715             HeapFree(GetProcessHeap(),0,ipps);
00716             return CONNECT_E_CANNOTCONNECT;
00717         }
00718         list_add_head(&This->LanguageProfileNotifySink,&ipps->entry);
00719         *pdwCookie = generate_Cookie(COOKIE_MAGIC_IPPSINK, ipps);
00720     }
00721     else
00722     {
00723         FIXME("(%p) Unhandled Sink: %s\n",This,debugstr_guid(riid));
00724         return E_NOTIMPL;
00725     }
00726 
00727     TRACE("cookie %x\n",*pdwCookie);
00728 
00729     return S_OK;
00730 }
00731 
00732 static HRESULT WINAPI IPPSource_UnadviseSink(ITfSource *iface, DWORD pdwCookie)
00733 {
00734     InputProcessorProfilesSink *sink;
00735     InputProcessorProfiles *This = impl_from_ITfSourceVtbl(iface);
00736 
00737     TRACE("(%p) %x\n",This,pdwCookie);
00738 
00739     if (get_Cookie_magic(pdwCookie)!=COOKIE_MAGIC_IPPSINK)
00740         return E_INVALIDARG;
00741 
00742     sink = (InputProcessorProfilesSink*)remove_Cookie(pdwCookie);
00743     if (!sink)
00744         return CONNECT_E_NOCONNECTION;
00745 
00746     list_remove(&sink->entry);
00747     free_sink(sink);
00748 
00749     return S_OK;
00750 }
00751 
00752 static const ITfSourceVtbl InputProcessorProfiles_SourceVtbl =
00753 {
00754     IPPSource_QueryInterface,
00755     IPPSource_AddRef,
00756     IPPSource_Release,
00757 
00758     IPPSource_AdviseSink,
00759     IPPSource_UnadviseSink,
00760 };
00761 
00762 HRESULT InputProcessorProfiles_Constructor(IUnknown *pUnkOuter, IUnknown **ppOut)
00763 {
00764     InputProcessorProfiles *This;
00765     if (pUnkOuter)
00766         return CLASS_E_NOAGGREGATION;
00767 
00768     This = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(InputProcessorProfiles));
00769     if (This == NULL)
00770         return E_OUTOFMEMORY;
00771 
00772     This->InputProcessorProfilesVtbl= &InputProcessorProfiles_InputProcessorProfilesVtbl;
00773     This->SourceVtbl = &InputProcessorProfiles_SourceVtbl;
00774     This->refCount = 1;
00775     This->currentLanguage = GetUserDefaultLCID();
00776 
00777     list_init(&This->LanguageProfileNotifySink);
00778 
00779     TRACE("returning %p\n", This);
00780     *ppOut = (IUnknown *)This;
00781     return S_OK;
00782 }
00783 
00784 /**************************************************
00785  * IEnumGUID implementation for ITfInputProcessorProfiles::EnumInputProcessorInfo
00786  **************************************************/
00787 static void ProfilesEnumGuid_Destructor(ProfilesEnumGuid *This)
00788 {
00789     TRACE("destroying %p\n", This);
00790     RegCloseKey(This->key);
00791     HeapFree(GetProcessHeap(),0,This);
00792 }
00793 
00794 static HRESULT WINAPI ProfilesEnumGuid_QueryInterface(IEnumGUID *iface, REFIID iid, LPVOID *ppvOut)
00795 {
00796     ProfilesEnumGuid *This = (ProfilesEnumGuid *)iface;
00797     *ppvOut = NULL;
00798 
00799     if (IsEqualIID(iid, &IID_IUnknown) || IsEqualIID(iid, &IID_IEnumGUID))
00800     {
00801         *ppvOut = This;
00802     }
00803 
00804     if (*ppvOut)
00805     {
00806         IUnknown_AddRef(iface);
00807         return S_OK;
00808     }
00809 
00810     WARN("unsupported interface: %s\n", debugstr_guid(iid));
00811     return E_NOINTERFACE;
00812 }
00813 
00814 static ULONG WINAPI ProfilesEnumGuid_AddRef(IEnumGUID *iface)
00815 {
00816     ProfilesEnumGuid *This = (ProfilesEnumGuid*)iface;
00817     return InterlockedIncrement(&This->refCount);
00818 }
00819 
00820 static ULONG WINAPI ProfilesEnumGuid_Release(IEnumGUID *iface)
00821 {
00822     ProfilesEnumGuid *This = (ProfilesEnumGuid *)iface;
00823     ULONG ret;
00824 
00825     ret = InterlockedDecrement(&This->refCount);
00826     if (ret == 0)
00827         ProfilesEnumGuid_Destructor(This);
00828     return ret;
00829 }
00830 
00831 /*****************************************************
00832  * IEnumGuid functions
00833  *****************************************************/
00834 static HRESULT WINAPI ProfilesEnumGuid_Next( LPENUMGUID iface,
00835     ULONG celt, GUID *rgelt, ULONG *pceltFetched)
00836 {
00837     ProfilesEnumGuid *This = (ProfilesEnumGuid *)iface;
00838     ULONG fetched = 0;
00839 
00840     TRACE("(%p)\n",This);
00841 
00842     if (rgelt == NULL) return E_POINTER;
00843 
00844     if (This->key) while (fetched < celt)
00845     {
00846         LSTATUS res;
00847         HRESULT hr;
00848         WCHAR catid[39];
00849         DWORD cName = 39;
00850 
00851         res = RegEnumKeyExW(This->key, This->next_index, catid, &cName,
00852                     NULL, NULL, NULL, NULL);
00853         if (res != ERROR_SUCCESS && res != ERROR_MORE_DATA) break;
00854         ++(This->next_index);
00855 
00856         hr = CLSIDFromString(catid, rgelt);
00857         if (FAILED(hr)) continue;
00858 
00859         ++fetched;
00860         ++rgelt;
00861     }
00862 
00863     if (pceltFetched) *pceltFetched = fetched;
00864     return fetched == celt ? S_OK : S_FALSE;
00865 }
00866 
00867 static HRESULT WINAPI ProfilesEnumGuid_Skip( LPENUMGUID iface, ULONG celt)
00868 {
00869     ProfilesEnumGuid *This = (ProfilesEnumGuid *)iface;
00870     TRACE("(%p)\n",This);
00871 
00872     This->next_index += celt;
00873     return S_OK;
00874 }
00875 
00876 static HRESULT WINAPI ProfilesEnumGuid_Reset( LPENUMGUID iface)
00877 {
00878     ProfilesEnumGuid *This = (ProfilesEnumGuid *)iface;
00879     TRACE("(%p)\n",This);
00880     This->next_index = 0;
00881     return S_OK;
00882 }
00883 
00884 static HRESULT WINAPI ProfilesEnumGuid_Clone( LPENUMGUID iface,
00885     IEnumGUID **ppenum)
00886 {
00887     ProfilesEnumGuid *This = (ProfilesEnumGuid *)iface;
00888     HRESULT res;
00889 
00890     TRACE("(%p)\n",This);
00891 
00892     if (ppenum == NULL) return E_POINTER;
00893 
00894     res = ProfilesEnumGuid_Constructor(ppenum);
00895     if (SUCCEEDED(res))
00896     {
00897         ProfilesEnumGuid *new_This = (ProfilesEnumGuid *)*ppenum;
00898         new_This->next_index = This->next_index;
00899     }
00900     return res;
00901 }
00902 
00903 static const IEnumGUIDVtbl IEnumGUID_Vtbl ={
00904     ProfilesEnumGuid_QueryInterface,
00905     ProfilesEnumGuid_AddRef,
00906     ProfilesEnumGuid_Release,
00907 
00908     ProfilesEnumGuid_Next,
00909     ProfilesEnumGuid_Skip,
00910     ProfilesEnumGuid_Reset,
00911     ProfilesEnumGuid_Clone
00912 };
00913 
00914 static HRESULT ProfilesEnumGuid_Constructor(IEnumGUID **ppOut)
00915 {
00916     ProfilesEnumGuid *This;
00917 
00918     This = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(ProfilesEnumGuid));
00919     if (This == NULL)
00920         return E_OUTOFMEMORY;
00921 
00922     This->Vtbl= &IEnumGUID_Vtbl;
00923     This->refCount = 1;
00924 
00925     if (RegCreateKeyExW(HKEY_LOCAL_MACHINE, szwSystemTIPKey, 0, NULL, 0,
00926                     KEY_READ | KEY_WRITE, NULL, &This->key, NULL) != ERROR_SUCCESS)
00927     {
00928         HeapFree(GetProcessHeap(), 0, This);
00929         return E_FAIL;
00930     }
00931 
00932     TRACE("returning %p\n", This);
00933     *ppOut = (IEnumGUID*)This;
00934     return S_OK;
00935 }
00936 
00937 /**************************************************
00938  * IEnumTfLanguageProfiles implementation
00939  **************************************************/
00940 static void EnumTfLanguageProfiles_Destructor(EnumTfLanguageProfiles *This)
00941 {
00942     TRACE("destroying %p\n", This);
00943     RegCloseKey(This->tipkey);
00944     if (This->langkey)
00945         RegCloseKey(This->langkey);
00946     ITfCategoryMgr_Release(This->catmgr);
00947     HeapFree(GetProcessHeap(),0,This);
00948 }
00949 
00950 static HRESULT WINAPI EnumTfLanguageProfiles_QueryInterface(IEnumTfLanguageProfiles *iface, REFIID iid, LPVOID *ppvOut)
00951 {
00952     EnumTfLanguageProfiles *This = (EnumTfLanguageProfiles *)iface;
00953     *ppvOut = NULL;
00954 
00955     if (IsEqualIID(iid, &IID_IUnknown) || IsEqualIID(iid, &IID_IEnumTfLanguageProfiles))
00956     {
00957         *ppvOut = This;
00958     }
00959 
00960     if (*ppvOut)
00961     {
00962         IUnknown_AddRef(iface);
00963         return S_OK;
00964     }
00965 
00966     WARN("unsupported interface: %s\n", debugstr_guid(iid));
00967     return E_NOINTERFACE;
00968 }
00969 
00970 static ULONG WINAPI EnumTfLanguageProfiles_AddRef(IEnumTfLanguageProfiles *iface)
00971 {
00972     EnumTfLanguageProfiles *This = (EnumTfLanguageProfiles*)iface;
00973     return InterlockedIncrement(&This->refCount);
00974 }
00975 
00976 static ULONG WINAPI EnumTfLanguageProfiles_Release(IEnumTfLanguageProfiles *iface)
00977 {
00978     EnumTfLanguageProfiles *This = (EnumTfLanguageProfiles *)iface;
00979     ULONG ret;
00980 
00981     ret = InterlockedDecrement(&This->refCount);
00982     if (ret == 0)
00983         EnumTfLanguageProfiles_Destructor(This);
00984     return ret;
00985 }
00986 
00987 /*****************************************************
00988  * IEnumGuid functions
00989  *****************************************************/
00990 static INT next_LanguageProfile(EnumTfLanguageProfiles *This, CLSID clsid, TF_LANGUAGEPROFILE *tflp)
00991 {
00992     WCHAR fullkey[168];
00993     ULONG res;
00994     WCHAR profileid[39];
00995     DWORD cName = 39;
00996     GUID  profile;
00997 
00998     static const WCHAR fmt[] = {'%','s','\\','%','s','\\','0','x','%','0','8','x',0};
00999 
01000     if (This->langkey == NULL)
01001     {
01002         sprintfW(fullkey,fmt,This->szwCurrentClsid,szwLngp,This->langid);
01003         res = RegOpenKeyExW(This->tipkey, fullkey, 0, KEY_READ | KEY_WRITE, &This->langkey);
01004         if (res)
01005         {
01006             This->langkey = NULL;
01007             return -1;
01008         }
01009         This->lang_index = 0;
01010     }
01011     res = RegEnumKeyExW(This->langkey, This->lang_index, profileid, &cName,
01012                 NULL, NULL, NULL, NULL);
01013     if (res != ERROR_SUCCESS && res != ERROR_MORE_DATA)
01014     {
01015         RegCloseKey(This->langkey);
01016         This->langkey = NULL;
01017         return -1;
01018     }
01019     ++(This->lang_index);
01020 
01021     if (tflp)
01022     {
01023         static const GUID * tipcats[3] = { &GUID_TFCAT_TIP_KEYBOARD,
01024                                            &GUID_TFCAT_TIP_SPEECH,
01025                                            &GUID_TFCAT_TIP_HANDWRITING };
01026         res = CLSIDFromString(profileid, &profile);
01027         if (FAILED(res)) return 0;
01028 
01029         tflp->clsid = clsid;
01030         tflp->langid = This->langid;
01031         tflp->fActive = get_active_textservice(&clsid, NULL);
01032         tflp->guidProfile = profile;
01033         if (ITfCategoryMgr_FindClosestCategory(This->catmgr, &clsid,
01034                 &tflp->catid, tipcats, 3) != S_OK)
01035             ITfCategoryMgr_FindClosestCategory(This->catmgr, &clsid,
01036                     &tflp->catid, NULL, 0);
01037     }
01038 
01039     return 1;
01040 }
01041 
01042 static HRESULT WINAPI EnumTfLanguageProfiles_Next(IEnumTfLanguageProfiles *iface,
01043     ULONG ulCount, TF_LANGUAGEPROFILE *pProfile, ULONG *pcFetch)
01044 {
01045     EnumTfLanguageProfiles *This = (EnumTfLanguageProfiles *)iface;
01046     ULONG fetched = 0;
01047 
01048     TRACE("(%p)\n",This);
01049 
01050     if (pProfile == NULL) return E_POINTER;
01051 
01052     if (This->tipkey) while (fetched < ulCount)
01053     {
01054         LSTATUS res;
01055         HRESULT hr;
01056         DWORD cName = 39;
01057         GUID clsid;
01058 
01059         res = RegEnumKeyExW(This->tipkey, This->tip_index,
01060                     This->szwCurrentClsid, &cName, NULL, NULL, NULL, NULL);
01061         if (res != ERROR_SUCCESS && res != ERROR_MORE_DATA) break;
01062         ++(This->tip_index);
01063         hr = CLSIDFromString(This->szwCurrentClsid, &clsid);
01064         if (FAILED(hr)) continue;
01065 
01066         while ( fetched < ulCount)
01067         {
01068             INT res = next_LanguageProfile(This, clsid, pProfile);
01069             if (res == 1)
01070             {
01071                 ++fetched;
01072                 ++pProfile;
01073             }
01074             else if (res == -1)
01075                 break;
01076             else
01077                 continue;
01078         }
01079     }
01080 
01081     if (pcFetch) *pcFetch = fetched;
01082     return fetched == ulCount ? S_OK : S_FALSE;
01083 }
01084 
01085 static HRESULT WINAPI EnumTfLanguageProfiles_Skip( IEnumTfLanguageProfiles* iface, ULONG celt)
01086 {
01087     EnumTfLanguageProfiles *This = (EnumTfLanguageProfiles *)iface;
01088     FIXME("STUB (%p)\n",This);
01089     return E_NOTIMPL;
01090 }
01091 
01092 static HRESULT WINAPI EnumTfLanguageProfiles_Reset( IEnumTfLanguageProfiles* iface)
01093 {
01094     EnumTfLanguageProfiles *This = (EnumTfLanguageProfiles *)iface;
01095     TRACE("(%p)\n",This);
01096     This->tip_index = 0;
01097     if (This->langkey)
01098         RegCloseKey(This->langkey);
01099     This->langkey = NULL;
01100     This->lang_index = 0;
01101     return S_OK;
01102 }
01103 
01104 static HRESULT WINAPI EnumTfLanguageProfiles_Clone( IEnumTfLanguageProfiles *iface,
01105     IEnumTfLanguageProfiles **ppenum)
01106 {
01107     EnumTfLanguageProfiles *This = (EnumTfLanguageProfiles *)iface;
01108     HRESULT res;
01109 
01110     TRACE("(%p)\n",This);
01111 
01112     if (ppenum == NULL) return E_POINTER;
01113 
01114     res = EnumTfLanguageProfiles_Constructor(This->langid, ppenum);
01115     if (SUCCEEDED(res))
01116     {
01117         EnumTfLanguageProfiles *new_This = (EnumTfLanguageProfiles *)*ppenum;
01118         new_This->tip_index = This->tip_index;
01119         lstrcpynW(new_This->szwCurrentClsid,This->szwCurrentClsid,39);
01120 
01121         if (This->langkey)
01122         {
01123             WCHAR fullkey[168];
01124             static const WCHAR fmt[] = {'%','s','\\','%','s','\\','0','x','%','0','8','x',0};
01125 
01126             sprintfW(fullkey,fmt,This->szwCurrentClsid,szwLngp,This->langid);
01127             res = RegOpenKeyExW(new_This->tipkey, fullkey, 0, KEY_READ | KEY_WRITE, &This->langkey);
01128             new_This->lang_index = This->lang_index;
01129         }
01130     }
01131     return res;
01132 }
01133 
01134 static const IEnumTfLanguageProfilesVtbl IEnumTfLanguageProfiles_Vtbl ={
01135     EnumTfLanguageProfiles_QueryInterface,
01136     EnumTfLanguageProfiles_AddRef,
01137     EnumTfLanguageProfiles_Release,
01138 
01139     EnumTfLanguageProfiles_Clone,
01140     EnumTfLanguageProfiles_Next,
01141     EnumTfLanguageProfiles_Reset,
01142     EnumTfLanguageProfiles_Skip
01143 };
01144 
01145 static HRESULT EnumTfLanguageProfiles_Constructor(LANGID langid, IEnumTfLanguageProfiles **ppOut)
01146 {
01147     HRESULT hr;
01148     EnumTfLanguageProfiles *This;
01149 
01150     This = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(EnumTfLanguageProfiles));
01151     if (This == NULL)
01152         return E_OUTOFMEMORY;
01153 
01154     This->Vtbl= &IEnumTfLanguageProfiles_Vtbl;
01155     This->refCount = 1;
01156     This->langid = langid;
01157 
01158     hr = CategoryMgr_Constructor(NULL,(IUnknown**)&This->catmgr);
01159     if (FAILED(hr))
01160     {
01161         HeapFree(GetProcessHeap(),0,This);
01162         return hr;
01163     }
01164 
01165     if (RegCreateKeyExW(HKEY_LOCAL_MACHINE, szwSystemTIPKey, 0, NULL, 0,
01166                     KEY_READ | KEY_WRITE, NULL, &This->tipkey, NULL) != ERROR_SUCCESS)
01167     {
01168         HeapFree(GetProcessHeap(), 0, This);
01169         return E_FAIL;
01170     }
01171 
01172     TRACE("returning %p\n", This);
01173     *ppOut = (IEnumTfLanguageProfiles*)This;
01174     return S_OK;
01175 }

Generated on Sun May 27 2012 04:24:49 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.