Synchronize with trunk r58457.
[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 WIN32_NO_STATUS
20 #define _INC_WINDOWS
21 #define COM_NO_WINDOWS_H
22
23 #define COBJMACROS
24
25 #include <stdarg.h>
26 #include <windef.h>
27 #include <winbase.h>
28 #include <objbase.h>
29
30 //#include "oaidl.h"
31 //#include "rpcproxy.h"
32 #include <atlbase.h>
33
34 #include <wine/debug.h>
35 //#include "wine/unicode.h"
36
37 WINE_DEFAULT_DEBUG_CHANNEL(atl);
38
39 /**************************************************************
40 * ClassFactory implementation
41 */
42
43 static HRESULT WINAPI RegistrarCF_QueryInterface(IClassFactory *iface, REFIID riid, void **ppvObject)
44 {
45 TRACE("(%p)->(%s %p)\n", iface, debugstr_guid(riid), ppvObject);
46
47 if(IsEqualGUID(&IID_IUnknown, riid) || IsEqualGUID(&IID_IClassFactory, riid)) {
48 *ppvObject = iface;
49 IClassFactory_AddRef( iface );
50 return S_OK;
51 }
52
53 return E_NOINTERFACE;
54 }
55
56 static ULONG WINAPI RegistrarCF_AddRef(IClassFactory *iface)
57 {
58 return 2;
59 }
60
61 static ULONG WINAPI RegistrarCF_Release(IClassFactory *iface)
62 {
63 return 1;
64 }
65
66 static HRESULT WINAPI RegistrarCF_CreateInstance(IClassFactory *iface, LPUNKNOWN pUnkOuter,
67 REFIID riid, void **ppv)
68 {
69 IRegistrar *registrar;
70 HRESULT hres;
71
72 TRACE("(%p)->(%s %p)\n", iface, debugstr_guid(riid), ppv);
73
74 if(pUnkOuter) {
75 *ppv = NULL;
76 return CLASS_E_NOAGGREGATION;
77 }
78
79 hres = AtlCreateRegistrar(&registrar);
80 if(FAILED(hres))
81 return hres;
82
83 hres = IRegistrar_QueryInterface(registrar, riid, ppv);
84 IRegistrar_Release(registrar);
85 return hres;
86 }
87
88 static HRESULT WINAPI RegistrarCF_LockServer(IClassFactory *iface, BOOL lock)
89 {
90 TRACE("(%p)->(%x)\n", iface, lock);
91 return S_OK;
92 }
93
94 static const IClassFactoryVtbl IRegistrarCFVtbl = {
95 RegistrarCF_QueryInterface,
96 RegistrarCF_AddRef,
97 RegistrarCF_Release,
98 RegistrarCF_CreateInstance,
99 RegistrarCF_LockServer
100 };
101
102 static IClassFactory RegistrarCF = { &IRegistrarCFVtbl };
103
104 /**************************************************************
105 * DllGetClassObject (ATL.2)
106 */
107 HRESULT WINAPI DllGetClassObject(REFCLSID clsid, REFIID riid, LPVOID *ppvObject)
108 {
109 TRACE("(%s %s %p)\n", debugstr_guid(clsid), debugstr_guid(riid), ppvObject);
110
111 if(IsEqualGUID(&CLSID_Registrar, clsid))
112 return IClassFactory_QueryInterface( &RegistrarCF, riid, ppvObject );
113
114 FIXME("Not supported class %s\n", debugstr_guid(clsid));
115 return CLASS_E_CLASSNOTAVAILABLE;
116 }
117
118 extern HINSTANCE hInst;
119
120 static HRESULT do_register_dll_server(IRegistrar *pRegistrar, LPCOLESTR wszDll,
121 LPCOLESTR wszId, BOOL do_register,
122 const struct _ATL_REGMAP_ENTRY* pMapEntries)
123 {
124 IRegistrar *registrar;
125 HRESULT hres;
126 const struct _ATL_REGMAP_ENTRY *pMapEntry;
127
128 static const WCHAR wszModule[] = {'M','O','D','U','L','E',0};
129 static const WCHAR wszRegistry[] = {'R','E','G','I','S','T','R','Y',0};
130
131 if(pRegistrar) {
132 registrar = pRegistrar;
133 }else {
134 hres = AtlCreateRegistrar(&registrar);
135 if(FAILED(hres))
136 return hres;
137 }
138
139 IRegistrar_AddReplacement(registrar, wszModule, wszDll);
140
141 for (pMapEntry = pMapEntries; pMapEntry && pMapEntry->szKey; pMapEntry++)
142 IRegistrar_AddReplacement(registrar, pMapEntry->szKey, pMapEntry->szData);
143
144 if(do_register)
145 hres = IRegistrar_ResourceRegisterSz(registrar, wszDll, wszId, wszRegistry);
146 else
147 hres = IRegistrar_ResourceUnregisterSz(registrar, wszDll, wszId, wszRegistry);
148
149 if(registrar != pRegistrar)
150 IRegistrar_Release(registrar);
151 return hres;
152 }
153
154 static HRESULT do_register_server(BOOL do_register)
155 {
156 static const WCHAR CLSID_RegistrarW[] =
157 {'C','L','S','I','D','_','R','e','g','i','s','t','r','a','r',0};
158 static const WCHAR atl_dllW[] = {'a','t','l','.','d','l','l',0};
159
160 WCHAR clsid_str[40];
161 const struct _ATL_REGMAP_ENTRY reg_map[] = {{CLSID_RegistrarW, clsid_str}, {NULL,NULL}};
162
163 StringFromGUID2(&CLSID_Registrar, clsid_str, sizeof(clsid_str)/sizeof(WCHAR));
164 return do_register_dll_server(NULL, atl_dllW, MAKEINTRESOURCEW(101), do_register, reg_map);
165 }
166
167 /***********************************************************************
168 * AtlModuleUpdateRegistryFromResourceD [ATL.@]
169 *
170 */
171 HRESULT WINAPI AtlModuleUpdateRegistryFromResourceD(_ATL_MODULEW* pM, LPCOLESTR lpszRes,
172 BOOL bRegister, struct _ATL_REGMAP_ENTRY* pMapEntries, IRegistrar* pReg)
173 {
174 HINSTANCE lhInst = pM->m_hInst;
175 /* everything inside this function below this point
176 * should go into atl71.AtlUpdateRegistryFromResourceD
177 */
178 WCHAR module_name[MAX_PATH];
179
180 if(!GetModuleFileNameW(lhInst, module_name, MAX_PATH)) {
181 FIXME("hinst %p: did not get module name\n",
182 lhInst);
183 return E_FAIL;
184 }
185
186 TRACE("%p (%s), %s, %d, %p, %p\n", hInst, debugstr_w(module_name),
187 debugstr_w(lpszRes), bRegister, pMapEntries, pReg);
188
189 return do_register_dll_server(pReg, module_name, lpszRes, bRegister, pMapEntries);
190 }
191
192 /***********************************************************************
193 * DllRegisterServer (ATL.@)
194 */
195 HRESULT WINAPI DllRegisterServer(void)
196 {
197 /* Note: we can't use __wine_register_server here because it uses CLSID_Registrar which isn't registred yet */
198 return do_register_server(TRUE);
199 }
200
201 /***********************************************************************
202 * DllUnRegisterServer (ATL.@)
203 */
204 HRESULT WINAPI DllUnregisterServer(void)
205 {
206 return do_register_server(FALSE);
207 }
208
209 /***********************************************************************
210 * DllCanUnloadNow (ATL.@)
211 */
212 HRESULT WINAPI DllCanUnloadNow(void)
213 {
214 return S_FALSE;
215 }