Remove redundant check.
[wine] / dlls / urlmon / internet.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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  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 "shlwapi.h"
28 #include "ole2.h"
29 #include "urlmon.h"
30 #include "urlmon_main.h"
31
32 #include "wine/debug.h"
33 #include "wine/unicode.h"
34
35 WINE_DEFAULT_DEBUG_CHANNEL(urlmon);
36
37 static HRESULT parse_schema(LPCWSTR url, DWORD flags, LPWSTR result, DWORD size, DWORD *rsize)
38 {
39     WCHAR *ptr;
40     DWORD len = 0;
41
42     TRACE("(%s %08lx %p %ld %p)\n", debugstr_w(url), flags, result, size, rsize);
43
44     if(flags)
45         ERR("wrong flags\n");
46     
47     ptr = strchrW(url, ':');
48     if(ptr)
49         len = ptr-url;
50
51     if(len >= size)
52         return E_POINTER;
53
54     if(len)
55         memcpy(result, url, len*sizeof(WCHAR));
56     result[len] = 0;
57
58     if(rsize)
59         *rsize = len;
60
61     return S_OK;
62 }
63
64 static IInternetProtocolInfo *get_protocol_info(LPCWSTR url)
65 {
66     IInternetProtocolInfo *ret = NULL;
67     WCHAR schema[64], str_clsid[64];
68     HKEY hkey = NULL;
69     DWORD res, type, size, schema_len;
70     CLSID clsid;
71     LPWSTR wszKey;
72     HRESULT hres;
73
74     static const WCHAR wszProtocolsKey[] =
75         {'P','R','O','T','O','C','O','L','S','\\','H','a','n','d','l','e','r','\\'};
76     static const WCHAR wszCLSID[] = {'C','L','S','I','D',0};
77
78     hres = parse_schema(url, 0, schema, sizeof(schema)/sizeof(schema[0]), &schema_len);
79     if(FAILED(hres) || !schema_len)
80         return NULL;
81
82     wszKey = HeapAlloc(GetProcessHeap(), 0, sizeof(wszProtocolsKey)+(schema_len+1)*sizeof(WCHAR));
83     memcpy(wszKey, wszProtocolsKey, sizeof(wszProtocolsKey));
84     memcpy(wszKey + sizeof(wszProtocolsKey)/sizeof(WCHAR), schema, (schema_len+1)*sizeof(WCHAR));
85
86     res = RegOpenKeyW(HKEY_CLASSES_ROOT, wszKey, &hkey);
87     HeapFree(GetProcessHeap(), 0, wszKey);
88     if(res != ERROR_SUCCESS) {
89         ERR("Could not open key %s\n", debugstr_w(wszProtocolsKey));
90         return NULL;
91     }
92     
93     size = sizeof(str_clsid);
94     res = RegQueryValueExW(hkey, wszCLSID, NULL, &type, (LPBYTE)str_clsid, &size);
95     RegCloseKey(hkey);
96     if(res != ERROR_SUCCESS || type != REG_SZ) {
97         WARN("Could not get protocol CLSID res=%ld\n", res);
98         return NULL;
99     }
100
101     hres = CLSIDFromString(str_clsid, &clsid);
102     if(FAILED(hres)) {
103         WARN("CLSIDFromString failed: %08lx\n", hres);
104         return NULL;
105     }
106
107     CoGetClassObject(&clsid, CLSCTX_INPROC_SERVER, NULL, &IID_IInternetProtocolInfo, (void**)&ret);
108     return ret;
109 }
110
111 static HRESULT parse_encode(LPCWSTR url, DWORD flags, LPWSTR result, DWORD size, DWORD *rsize)
112 {
113     IInternetProtocolInfo *protocol_info;
114     DWORD prsize;
115     HRESULT hres;
116
117     TRACE("(%s %08lx %p %ld %p)\n", debugstr_w(url), flags, result, size, rsize);
118
119     protocol_info = get_protocol_info(url);
120
121     if(protocol_info) {
122         hres = IInternetProtocolInfo_ParseUrl(protocol_info, url, PARSE_ENCODE,
123                 flags, result, size, rsize, 0);
124         if(SUCCEEDED(hres))
125             return hres;
126     }
127
128     prsize = size;
129     hres = UrlUnescapeW((LPWSTR)url, result, &prsize, flags);
130
131     if(rsize)
132         *rsize = prsize;
133
134     return hres;
135 }
136
137 HRESULT WINAPI CoInternetParseUrl(LPCWSTR pwzUrl, PARSEACTION ParseAction, DWORD dwFlags,
138         LPWSTR pszResult, DWORD cchResult, DWORD *pcchResult, DWORD dwReserved)
139 {
140     if(dwReserved)
141         WARN("dwReserved = %ld\n", dwReserved);
142
143     switch(ParseAction) {
144     case PARSE_ENCODE:
145         return parse_encode(pwzUrl, dwFlags, pszResult, cchResult, pcchResult);
146     case PARSE_SCHEMA:
147         return parse_schema(pwzUrl, dwFlags, pszResult, cchResult, pcchResult);
148     default:
149         FIXME("not supported action %d\n", ParseAction);
150     }
151
152     return E_NOTIMPL;
153 }