Sync with trunk r58033.
[reactos.git] / dll / win32 / atl / registrar.c
1 /*
2 * Copyright 2005 Jacek Caban
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
17 */
18
19 #define COBJMACROS
20
21 #include "oaidl.h"
22 #include "rpcproxy.h"
23 #include "atlbase.h"
24
25 #include "wine/debug.h"
26 #include "wine/unicode.h"
27
28 WINE_DEFAULT_DEBUG_CHANNEL(atl);
29
30 /**************************************************************
31 * ClassFactory implementation
32 */
33
34 static HRESULT WINAPI RegistrarCF_QueryInterface(IClassFactory *iface, REFIID riid, void **ppvObject)
35 {
36 TRACE("(%p)->(%s %p)\n", iface, debugstr_guid(riid), ppvObject);
37
38 if(IsEqualGUID(&IID_IUnknown, riid) || IsEqualGUID(&IID_IClassFactory, riid)) {
39 *ppvObject = iface;
40 IClassFactory_AddRef( iface );
41 return S_OK;
42 }
43
44 return E_NOINTERFACE;
45 }
46
47 static ULONG WINAPI RegistrarCF_AddRef(IClassFactory *iface)
48 {
49 return 2;
50 }
51
52 static ULONG WINAPI RegistrarCF_Release(IClassFactory *iface)
53 {
54 return 1;
55 }
56
57 static HRESULT WINAPI RegistrarCF_CreateInstance(IClassFactory *iface, LPUNKNOWN pUnkOuter,
58 REFIID riid, void **ppv)
59 {
60 IRegistrar *registrar;
61 HRESULT hres;
62
63 TRACE("(%p)->(%s %p)\n", iface, debugstr_guid(riid), ppv);
64
65 if(pUnkOuter) {
66 *ppv = NULL;
67 return CLASS_E_NOAGGREGATION;
68 }
69
70 hres = AtlCreateRegistrar(&registrar);
71 if(FAILED(hres))
72 return hres;
73
74 hres = IRegistrar_QueryInterface(registrar, riid, ppv);
75 IRegistrar_Release(registrar);
76 return hres;
77 }
78
79 static HRESULT WINAPI RegistrarCF_LockServer(IClassFactory *iface, BOOL lock)
80 {
81 TRACE("(%p)->(%x)\n", iface, lock);
82 return S_OK;
83 }
84
85 static const IClassFactoryVtbl IRegistrarCFVtbl = {
86 RegistrarCF_QueryInterface,
87 RegistrarCF_AddRef,
88 RegistrarCF_Release,
89 RegistrarCF_CreateInstance,
90 RegistrarCF_LockServer
91 };
92
93 static IClassFactory RegistrarCF = { &IRegistrarCFVtbl };
94
95 /**************************************************************
96 * DllGetClassObject (ATL.2)
97 */
98 HRESULT WINAPI DllGetClassObject(REFCLSID clsid, REFIID riid, LPVOID *ppvObject)
99 {
100 TRACE("(%s %s %p)\n", debugstr_guid(clsid), debugstr_guid(riid), ppvObject);
101
102 if(IsEqualGUID(&CLSID_Registrar, clsid))
103 return IClassFactory_QueryInterface( &RegistrarCF, riid, ppvObject );
104
105 FIXME("Not supported class %s\n", debugstr_guid(clsid));
106 return CLASS_E_CLASSNOTAVAILABLE;
107 }
108
109 extern HINSTANCE hInst;
110
111 static HRESULT do_register_dll_server(IRegistrar *pRegistrar, LPCOLESTR wszDll,
112 LPCOLESTR wszId, BOOL do_register,
113 const struct _ATL_REGMAP_ENTRY* pMapEntries)
114 {
115 IRegistrar *registrar;
116 HRESULT hres;
117 const struct _ATL_REGMAP_ENTRY *pMapEntry;
118
119 static const WCHAR wszModule[] = {'M','O','D','U','L','E',0};
120 static const WCHAR wszRegistry[] = {'R','E','G','I','S','T','R','Y',0};
121
122 if(pRegistrar) {
123 registrar = pRegistrar;
124 }else {
125 hres = AtlCreateRegistrar(&registrar);
126 if(FAILED(hres))
127 return hres;
128 }
129
130 IRegistrar_AddReplacement(registrar, wszModule, wszDll);
131
132 for (pMapEntry = pMapEntries; pMapEntry && pMapEntry->szKey; pMapEntry++)
133 IRegistrar_AddReplacement(registrar, pMapEntry->szKey, pMapEntry->szData);
134
135 if(do_register)
136 hres = IRegistrar_ResourceRegisterSz(registrar, wszDll, wszId, wszRegistry);
137 else
138 hres = IRegistrar_ResourceUnregisterSz(registrar, wszDll, wszId, wszRegistry);
139
140 if(registrar != pRegistrar)
141 IRegistrar_Release(registrar);
142 return hres;
143 }
144
145 static HRESULT do_register_server(BOOL do_register)
146 {
147 static const WCHAR CLSID_RegistrarW[] =
148 {'C','L','S','I','D','_','R','e','g','i','s','t','r','a','r',0};
149 static const WCHAR atl_dllW[] = {'a','t','l','.','d','l','l',0};
150
151 WCHAR clsid_str[40];
152 const struct _ATL_REGMAP_ENTRY reg_map[] = {{CLSID_RegistrarW, clsid_str}, {NULL,NULL}};
153
154 StringFromGUID2(&CLSID_Registrar, clsid_str, sizeof(clsid_str)/sizeof(WCHAR));
155 return do_register_dll_server(NULL, atl_dllW, MAKEINTRESOURCEW(101), do_register, reg_map);
156 }
157
158 /***********************************************************************
159 * AtlModuleUpdateRegistryFromResourceD [ATL.@]
160 *
161 */
162 HRESULT WINAPI AtlModuleUpdateRegistryFromResourceD(_ATL_MODULEW* pM, LPCOLESTR lpszRes,
163 BOOL bRegister, struct _ATL_REGMAP_ENTRY* pMapEntries, IRegistrar* pReg)
164 {
165 HINSTANCE lhInst = pM->m_hInst;
166 /* everything inside this function below this point
167 * should go into atl71.AtlUpdateRegistryFromResourceD
168 */
169 WCHAR module_name[MAX_PATH];
170
171 if(!GetModuleFileNameW(lhInst, module_name, MAX_PATH)) {
172 FIXME("hinst %p: did not get module name\n",
173 lhInst);
174 return E_FAIL;
175 }
176
177 TRACE("%p (%s), %s, %d, %p, %p\n", hInst, debugstr_w(module_name),
178 debugstr_w(lpszRes), bRegister, pMapEntries, pReg);
179
180 return do_register_dll_server(pReg, module_name, lpszRes, bRegister, pMapEntries);
181 }
182
183 /***********************************************************************
184 * DllRegisterServer (ATL.@)
185 */
186 HRESULT WINAPI DllRegisterServer(void)
187 {
188 /* Note: we can't use __wine_register_server here because it uses CLSID_Registrar which isn't registred yet */
189 return do_register_server(TRUE);
190 }
191
192 /***********************************************************************
193 * DllUnRegisterServer (ATL.@)
194 */
195 HRESULT WINAPI DllUnregisterServer(void)
196 {
197 return do_register_server(FALSE);
198 }
199
200 /***********************************************************************
201 * DllCanUnloadNow (ATL.@)
202 */
203 HRESULT WINAPI DllCanUnloadNow(void)
204 {
205 return S_FALSE;
206 }