urlmon: Added [Un]RegisterNamespace implementation.
[wine] / dlls / urlmon / session.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 #include <stdarg.h>
20
21 #define COBJMACROS
22
23 #include "windef.h"
24 #include "winbase.h"
25 #include "winuser.h"
26 #include "winreg.h"
27 #include "ole2.h"
28 #include "urlmon.h"
29 #include "urlmon_main.h"
30
31 #include "wine/debug.h"
32 #include "wine/unicode.h"
33
34 WINE_DEFAULT_DEBUG_CHANNEL(urlmon);
35
36 typedef struct name_space {
37     LPWSTR protocol;
38     IClassFactory *cf;
39
40     struct name_space *next;
41 } name_space;
42
43 static name_space *name_space_list = NULL;
44
45 HRESULT get_protocol_iface(LPCWSTR url, IUnknown **ret)
46 {
47     WCHAR schema[64], str_clsid[64];
48     HKEY hkey = NULL;
49     DWORD res, type, size, schema_len;
50     CLSID clsid;
51     LPWSTR wszKey;
52     HRESULT hres;
53
54     static const WCHAR wszProtocolsKey[] =
55         {'P','R','O','T','O','C','O','L','S','\\','H','a','n','d','l','e','r','\\'};
56     static const WCHAR wszCLSID[] = {'C','L','S','I','D',0};
57
58     hres = CoInternetParseUrl(url, PARSE_SCHEMA, 0, schema, sizeof(schema)/sizeof(schema[0]),
59             &schema_len, 0);
60     if(FAILED(hres) || !schema_len)
61         return E_FAIL;
62
63     wszKey = HeapAlloc(GetProcessHeap(), 0, sizeof(wszProtocolsKey)+(schema_len+1)*sizeof(WCHAR));
64     memcpy(wszKey, wszProtocolsKey, sizeof(wszProtocolsKey));
65     memcpy(wszKey + sizeof(wszProtocolsKey)/sizeof(WCHAR), schema, (schema_len+1)*sizeof(WCHAR));
66
67     res = RegOpenKeyW(HKEY_CLASSES_ROOT, wszKey, &hkey);
68     HeapFree(GetProcessHeap(), 0, wszKey);
69     if(res != ERROR_SUCCESS) {
70         TRACE("Could not open key %s\n", debugstr_w(wszKey));
71         return E_FAIL;
72     }
73     
74     size = sizeof(str_clsid);
75     res = RegQueryValueExW(hkey, wszCLSID, NULL, &type, (LPBYTE)str_clsid, &size);
76     RegCloseKey(hkey);
77     if(res != ERROR_SUCCESS || type != REG_SZ) {
78         WARN("Could not get protocol CLSID res=%ld\n", res);
79         return E_FAIL;
80     }
81
82     hres = CLSIDFromString(str_clsid, &clsid);
83     if(FAILED(hres)) {
84         WARN("CLSIDFromString failed: %08lx\n", hres);
85         return hres;
86     }
87
88     return CoGetClassObject(&clsid, CLSCTX_INPROC_SERVER, NULL, &IID_IUnknown, (void**)ret);
89 }
90
91 static HRESULT WINAPI InternetSession_QueryInterface(IInternetSession *iface,
92         REFIID riid, void **ppv)
93 {
94     TRACE("(%s %p)\n", debugstr_guid(riid), ppv);
95
96     if(IsEqualGUID(&IID_IUnknown, riid) || IsEqualGUID(&IID_IInternetSession, riid)) {
97         *ppv = iface;
98         IInternetSession_AddRef(iface);
99         return S_OK;
100     }
101
102     *ppv = NULL;
103     return E_NOINTERFACE;
104 }
105
106 static ULONG WINAPI InternetSession_AddRef(IInternetSession *iface)
107 {
108     TRACE("()\n");
109     URLMON_LockModule();
110     return 2;
111 }
112
113 static ULONG WINAPI InternetSession_Release(IInternetSession *iface)
114 {
115     TRACE("()\n");
116     URLMON_UnlockModule();
117     return 1;
118 }
119
120 static HRESULT WINAPI InternetSession_RegisterNameSpace(IInternetSession *iface,
121         IClassFactory *pCF, REFCLSID rclsid, LPCWSTR pwzProtocol, ULONG cPatterns,
122         const LPCWSTR *ppwzPatterns, DWORD dwReserved)
123 {
124     name_space *new_name_space;
125     int size;
126
127     TRACE("(%p %s %s %ld %p %ld)\n", pCF, debugstr_guid(rclsid), debugstr_w(pwzProtocol),
128           cPatterns, ppwzPatterns, dwReserved);
129
130     if(cPatterns || ppwzPatterns)
131         FIXME("patterns not supported\n");
132     if(dwReserved)
133         WARN("dwReserved = %ld\n", dwReserved);
134
135     if(!pCF || !pwzProtocol)
136         return E_INVALIDARG;
137
138     new_name_space = HeapAlloc(GetProcessHeap(), 0, sizeof(name_space));
139
140     size = (strlenW(pwzProtocol)+1)*sizeof(WCHAR);
141     new_name_space->protocol = HeapAlloc(GetProcessHeap(), 0, size);
142     memcpy(new_name_space->protocol, pwzProtocol, size);
143
144     IClassFactory_AddRef(pCF);
145     new_name_space->cf = pCF;
146
147     new_name_space->next = name_space_list;
148     name_space_list = new_name_space;
149     return S_OK;
150 }
151
152 static HRESULT WINAPI InternetSession_UnregisterNameSpace(IInternetSession *iface,
153         IClassFactory *pCF, LPCWSTR pszProtocol)
154 {
155     name_space *iter, *last = NULL;
156
157     TRACE("(%p %s)\n", pCF, debugstr_w(pszProtocol));
158
159     if(!pCF || !pszProtocol)
160         return E_INVALIDARG;
161
162     for(iter = name_space_list; iter; iter = iter->next) {
163         if(iter->cf == pCF && !strcmpW(iter->protocol, pszProtocol))
164             break;
165         last = iter;
166     }
167
168     if(!iter)
169         return S_OK;
170
171     if(last)
172         last->next = iter->next;
173     else
174         name_space_list = iter->next;
175
176     IClassFactory_Release(iter->cf);
177     HeapFree(GetProcessHeap(), 0, iter->protocol);
178     HeapFree(GetProcessHeap(), 0, iter);
179
180     return S_OK;
181 }
182
183 static HRESULT WINAPI InternetSession_RegisterMimeFilter(IInternetSession *iface,
184         IClassFactory *pCF, REFCLSID rclsid, LPCWSTR pwzType)
185 {
186     FIXME("(%p %s %s)\n", pCF, debugstr_guid(rclsid), debugstr_w(pwzType));
187     return E_NOTIMPL;
188 }
189
190 static HRESULT WINAPI InternetSession_UnregisterMimeFilter(IInternetSession *iface,
191         IClassFactory *pCF, LPCWSTR pwzType)
192 {
193     FIXME("(%p %s)\n", pCF, debugstr_w(pwzType));
194     return E_NOTIMPL;
195 }
196
197 static HRESULT WINAPI InternetSession_CreateBinding(IInternetSession *iface,
198         LPBC pBC, LPCWSTR szUrl, IUnknown *pUnkOuter, IUnknown **ppUnk,
199         IInternetProtocol **ppOInetProt, DWORD dwOption)
200 {
201     FIXME("(%p %s %p %p %p %08lx)\n", pBC, debugstr_w(szUrl), pUnkOuter, ppUnk,
202             ppOInetProt, dwOption);
203     return E_NOTIMPL;
204 }
205
206 static HRESULT WINAPI InternetSession_SetSessionOption(IInternetSession *iface,
207         DWORD dwOption, LPVOID pBuffer, DWORD dwBufferLength, DWORD dwReserved)
208 {
209     FIXME("(%08lx %p %ld %ld)\n", dwOption, pBuffer, dwBufferLength, dwReserved);
210     return E_NOTIMPL;
211 }
212
213 static const IInternetSessionVtbl InternetSessionVtbl = {
214     InternetSession_QueryInterface,
215     InternetSession_AddRef,
216     InternetSession_Release,
217     InternetSession_RegisterNameSpace,
218     InternetSession_UnregisterNameSpace,
219     InternetSession_RegisterMimeFilter,
220     InternetSession_UnregisterMimeFilter,
221     InternetSession_CreateBinding,
222     InternetSession_SetSessionOption
223 };
224
225 static IInternetSession InternetSession = { &InternetSessionVtbl };
226
227 /***********************************************************************
228  *           CoInternetGetSession (URLMON.@)
229  *
230  * Create a new internet session and return an IInternetSession interface
231  * representing it.
232  *
233  * PARAMS
234  *    dwSessionMode      [I] Mode for the internet session
235  *    ppIInternetSession [O] Destination for creates IInternetSession object
236  *    dwReserved         [I] Reserved, must be 0.
237  *
238  * RETURNS
239  *    Success: S_OK. ppIInternetSession contains the IInternetSession interface.
240  *    Failure: E_INVALIDARG, if any argument is invalid, or
241  *             E_OUTOFMEMORY if memory allocation fails.
242  */
243 HRESULT WINAPI CoInternetGetSession(DWORD dwSessionMode, IInternetSession **ppIInternetSession,
244         DWORD dwReserved)
245 {
246     TRACE("(%ld %p %ld)\n", dwSessionMode, ppIInternetSession, dwReserved);
247
248     if(dwSessionMode)
249         ERR("dwSessionMode=%ld\n", dwSessionMode);
250     if(dwReserved)
251         ERR("dwReserved=%ld\n", dwReserved);
252
253     *ppIInternetSession = &InternetSession;
254     return S_OK;
255 }