| /* |
| * ComCatMgr ICatRegister implementation for comcat.dll |
| * |
| * Copyright (C) 2002 John K. Hohm |
| * |
| * This library is free software; you can redistribute it and/or |
| * modify it under the terms of the GNU Lesser General Public |
| * License as published by the Free Software Foundation; either |
| * version 2.1 of the License, or (at your option) any later version. |
| * |
| * This library is distributed in the hope that it will be useful, |
| * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| * Lesser General Public License for more details. |
| * |
| * You should have received a copy of the GNU Lesser General Public |
| * License along with this library; if not, write to the Free Software |
| * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
| */ |
| |
| #include "comcat_private.h" |
| |
| #include "wine/debug.h" |
| |
| WINE_DEFAULT_DEBUG_CHANNEL(ole); |
| |
| /********************************************************************** |
| * File-scope string constants |
| */ |
| static const WCHAR comcat_keyname[21] = { |
| 'C', 'o', 'm', 'p', 'o', 'n', 'e', 'n', 't', ' ', 'C', 'a', |
| 't', 'e', 'g', 'o', 'r', 'i', 'e', 's', 0 }; |
| static const WCHAR impl_keyname[23] = { |
| 'I', 'm', 'p', 'l', 'e', 'm', 'e', 'n', |
| 't', 'e', 'd', ' ', 'C', 'a', 't', 'e', |
| 'g', 'o', 'r', 'i', 'e', 's', 0 }; |
| static const WCHAR req_keyname[20] = { |
| 'R', 'e', 'q', 'u', 'i', 'r', 'e', 'd', |
| ' ', 'C', 'a', 't', 'e', 'g', 'o', 'r', |
| 'i', 'e', 's', 0 }; |
| |
| static HRESULT COMCAT_RegisterClassCategories( |
| REFCLSID rclsid, LPCWSTR type, |
| ULONG cCategories, CATID *rgcatid); |
| static HRESULT COMCAT_UnRegisterClassCategories( |
| REFCLSID rclsid, LPCWSTR type, |
| ULONG cCategories, CATID *rgcatid); |
| |
| /********************************************************************** |
| * COMCAT_ICatRegister_QueryInterface |
| */ |
| static HRESULT WINAPI COMCAT_ICatRegister_QueryInterface( |
| LPCATREGISTER iface, |
| REFIID riid, |
| LPVOID *ppvObj) |
| { |
| ICOM_THIS_MULTI(ComCatMgrImpl, regVtbl, iface); |
| TRACE("\n\tIID:\t%s\n",debugstr_guid(riid)); |
| |
| if (This == NULL || ppvObj == NULL) return E_POINTER; |
| |
| return IUnknown_QueryInterface((LPUNKNOWN)&This->unkVtbl, riid, ppvObj); |
| } |
| |
| /********************************************************************** |
| * COMCAT_ICatRegister_AddRef |
| */ |
| static ULONG WINAPI COMCAT_ICatRegister_AddRef(LPCATREGISTER iface) |
| { |
| ICOM_THIS_MULTI(ComCatMgrImpl, regVtbl, iface); |
| TRACE("\n"); |
| |
| if (This == NULL) return E_POINTER; |
| |
| return IUnknown_AddRef((LPUNKNOWN)&This->unkVtbl); |
| } |
| |
| /********************************************************************** |
| * COMCAT_ICatRegister_Release |
| */ |
| static ULONG WINAPI COMCAT_ICatRegister_Release(LPCATREGISTER iface) |
| { |
| ICOM_THIS_MULTI(ComCatMgrImpl, regVtbl, iface); |
| TRACE("\n"); |
| |
| if (This == NULL) return E_POINTER; |
| |
| return IUnknown_Release((LPUNKNOWN)&This->unkVtbl); |
| } |
| |
| /********************************************************************** |
| * COMCAT_ICatRegister_RegisterCategories |
| */ |
| static HRESULT WINAPI COMCAT_ICatRegister_RegisterCategories( |
| LPCATREGISTER iface, |
| ULONG cCategories, |
| CATEGORYINFO *rgci) |
| { |
| /* ICOM_THIS_MULTI(ComCatMgrImpl, regVtbl, iface); */ |
| HKEY comcat_key; |
| HRESULT res; |
| |
| TRACE("\n"); |
| |
| if (iface == NULL || (cCategories && rgci == NULL)) |
| return E_POINTER; |
| |
| /* Create (or open) the component categories key. */ |
| res = RegCreateKeyExW(HKEY_CLASSES_ROOT, comcat_keyname, 0, NULL, 0, |
| KEY_READ | KEY_WRITE, NULL, &comcat_key, NULL); |
| if (res != ERROR_SUCCESS) return E_FAIL; |
| |
| for (; cCategories; --cCategories, ++rgci) { |
| WCHAR fmt[4] = { '%', 'l', 'X', 0 }; |
| WCHAR keyname[39]; |
| WCHAR valname[9]; |
| HKEY cat_key; |
| |
| /* Create (or open) the key for this category. */ |
| if (!StringFromGUID2(&rgci->catid, keyname, 39)) continue; |
| res = RegCreateKeyExW(comcat_key, keyname, 0, NULL, 0, |
| KEY_READ | KEY_WRITE, NULL, &cat_key, NULL); |
| if (res != ERROR_SUCCESS) continue; |
| |
| /* Set the value for this locale's description. */ |
| wsprintfW(valname, fmt, rgci->lcid); |
| RegSetValueExW(cat_key, valname, 0, REG_SZ, |
| (CONST BYTE*)(rgci->szDescription), |
| (lstrlenW(rgci->szDescription) + 1) * sizeof(WCHAR)); |
| |
| RegCloseKey(cat_key); |
| } |
| |
| RegCloseKey(comcat_key); |
| return S_OK; |
| } |
| |
| /********************************************************************** |
| * COMCAT_ICatRegister_UnRegisterCategories |
| */ |
| static HRESULT WINAPI COMCAT_ICatRegister_UnRegisterCategories( |
| LPCATREGISTER iface, |
| ULONG cCategories, |
| CATID *rgcatid) |
| { |
| /* ICOM_THIS_MULTI(ComCatMgrImpl, regVtbl, iface); */ |
| HKEY comcat_key; |
| HRESULT res; |
| |
| TRACE("\n"); |
| |
| if (iface == NULL || (cCategories && rgcatid == NULL)) |
| return E_POINTER; |
| |
| /* Open the component categories key. */ |
| res = RegOpenKeyExW(HKEY_CLASSES_ROOT, comcat_keyname, 0, |
| KEY_READ | KEY_WRITE, &comcat_key); |
| if (res != ERROR_SUCCESS) return E_FAIL; |
| |
| for (; cCategories; --cCategories, ++rgcatid) { |
| WCHAR keyname[39]; |
| |
| /* Delete the key for this category. */ |
| if (!StringFromGUID2(rgcatid, keyname, 39)) continue; |
| RegDeleteKeyW(comcat_key, keyname); |
| } |
| |
| RegCloseKey(comcat_key); |
| return S_OK; |
| } |
| |
| /********************************************************************** |
| * COMCAT_ICatRegister_RegisterClassImplCategories |
| */ |
| static HRESULT WINAPI COMCAT_ICatRegister_RegisterClassImplCategories( |
| LPCATREGISTER iface, |
| REFCLSID rclsid, |
| ULONG cCategories, |
| CATID *rgcatid) |
| { |
| /* ICOM_THIS_MULTI(ComCatMgrImpl, regVtbl, iface); */ |
| TRACE("\n"); |
| |
| return COMCAT_RegisterClassCategories( |
| rclsid, impl_keyname, cCategories, rgcatid); |
| } |
| |
| /********************************************************************** |
| * COMCAT_ICatRegister_UnRegisterClassImplCategories |
| */ |
| static HRESULT WINAPI COMCAT_ICatRegister_UnRegisterClassImplCategories( |
| LPCATREGISTER iface, |
| REFCLSID rclsid, |
| ULONG cCategories, |
| CATID *rgcatid) |
| { |
| /* ICOM_THIS_MULTI(ComCatMgrImpl, regVtbl, iface); */ |
| TRACE("\n"); |
| |
| return COMCAT_UnRegisterClassCategories( |
| rclsid, impl_keyname, cCategories, rgcatid); |
| } |
| |
| /********************************************************************** |
| * COMCAT_ICatRegister_RegisterClassReqCategories |
| */ |
| static HRESULT WINAPI COMCAT_ICatRegister_RegisterClassReqCategories( |
| LPCATREGISTER iface, |
| REFCLSID rclsid, |
| ULONG cCategories, |
| CATID *rgcatid) |
| { |
| /* ICOM_THIS_MULTI(ComCatMgrImpl, regVtbl, iface); */ |
| TRACE("\n"); |
| |
| return COMCAT_RegisterClassCategories( |
| rclsid, req_keyname, cCategories, rgcatid); |
| } |
| |
| /********************************************************************** |
| * COMCAT_ICatRegister_UnRegisterClassReqCategories |
| */ |
| static HRESULT WINAPI COMCAT_ICatRegister_UnRegisterClassReqCategories( |
| LPCATREGISTER iface, |
| REFCLSID rclsid, |
| ULONG cCategories, |
| CATID *rgcatid) |
| { |
| /* ICOM_THIS_MULTI(ComCatMgrImpl, regVtbl, iface); */ |
| TRACE("\n"); |
| |
| return COMCAT_UnRegisterClassCategories( |
| rclsid, req_keyname, cCategories, rgcatid); |
| } |
| |
| /********************************************************************** |
| * COMCAT_ICatRegister_Vtbl |
| */ |
| ICOM_VTABLE(ICatRegister) COMCAT_ICatRegister_Vtbl = |
| { |
| ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE |
| COMCAT_ICatRegister_QueryInterface, |
| COMCAT_ICatRegister_AddRef, |
| COMCAT_ICatRegister_Release, |
| COMCAT_ICatRegister_RegisterCategories, |
| COMCAT_ICatRegister_UnRegisterCategories, |
| COMCAT_ICatRegister_RegisterClassImplCategories, |
| COMCAT_ICatRegister_UnRegisterClassImplCategories, |
| COMCAT_ICatRegister_RegisterClassReqCategories, |
| COMCAT_ICatRegister_UnRegisterClassReqCategories |
| }; |
| |
| /********************************************************************** |
| * COMCAT_RegisterClassCategories |
| */ |
| static HRESULT COMCAT_RegisterClassCategories( |
| REFCLSID rclsid, |
| LPCWSTR type, |
| ULONG cCategories, |
| CATID *rgcatid) |
| { |
| WCHAR keyname[39]; |
| HRESULT res; |
| HKEY clsid_key, class_key, type_key; |
| |
| if (cCategories && rgcatid == NULL) return E_POINTER; |
| |
| /* Format the class key name. */ |
| res = StringFromGUID2(rclsid, keyname, 39); |
| if (FAILED(res)) return res; |
| |
| /* Create (or open) the CLSID key. */ |
| res = RegCreateKeyExW(HKEY_CLASSES_ROOT, clsid_keyname, 0, NULL, 0, |
| KEY_READ | KEY_WRITE, NULL, &clsid_key, NULL); |
| if (res != ERROR_SUCCESS) return E_FAIL; |
| |
| /* Create (or open) the class key. */ |
| res = RegCreateKeyExW(clsid_key, keyname, 0, NULL, 0, |
| KEY_READ | KEY_WRITE, NULL, &class_key, NULL); |
| if (res == ERROR_SUCCESS) { |
| /* Create (or open) the category type key. */ |
| res = RegCreateKeyExW(class_key, type, 0, NULL, 0, |
| KEY_READ | KEY_WRITE, NULL, &type_key, NULL); |
| if (res == ERROR_SUCCESS) { |
| for (; cCategories; --cCategories, ++rgcatid) { |
| HKEY key; |
| |
| /* Format the category key name. */ |
| res = StringFromGUID2(rgcatid, keyname, 39); |
| if (FAILED(res)) continue; |
| |
| /* Do the register. */ |
| res = RegCreateKeyExW(type_key, keyname, 0, NULL, 0, |
| KEY_READ | KEY_WRITE, NULL, &key, NULL); |
| if (res == ERROR_SUCCESS) RegCloseKey(key); |
| } |
| res = S_OK; |
| } else res = E_FAIL; |
| RegCloseKey(class_key); |
| } else res = E_FAIL; |
| RegCloseKey(clsid_key); |
| |
| return res; |
| } |
| |
| /********************************************************************** |
| * COMCAT_UnRegisterClassCategories |
| */ |
| static HRESULT COMCAT_UnRegisterClassCategories( |
| REFCLSID rclsid, |
| LPCWSTR type, |
| ULONG cCategories, |
| CATID *rgcatid) |
| { |
| WCHAR keyname[68] = { 'C', 'L', 'S', 'I', 'D', '\\' }; |
| HRESULT res; |
| HKEY type_key; |
| |
| if (cCategories && rgcatid == NULL) return E_POINTER; |
| |
| /* Format the class category type key name. */ |
| res = StringFromGUID2(rclsid, keyname + 6, 39); |
| if (FAILED(res)) return res; |
| keyname[44] = '\\'; |
| lstrcpyW(keyname + 45, type); |
| |
| /* Open the class category type key. */ |
| res = RegOpenKeyExW(HKEY_CLASSES_ROOT, keyname, 0, |
| KEY_READ | KEY_WRITE, &type_key); |
| if (res != ERROR_SUCCESS) return E_FAIL; |
| |
| for (; cCategories; --cCategories, ++rgcatid) { |
| /* Format the category key name. */ |
| res = StringFromGUID2(rgcatid, keyname, 39); |
| if (FAILED(res)) continue; |
| |
| /* Do the unregister. */ |
| RegDeleteKeyW(type_key, keyname); |
| } |
| RegCloseKey(type_key); |
| |
| return S_OK; |
| } |