bump product version to 5.0.4.1
[LibreOffice.git] / shell / source / backends / wininetbe / wininetbackend.cxx
blob23aed71fcf01a341e5a0bc5c5b4f388028de8b16
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <cppuhelper/supportsservice.hxx>
21 #include "rtl/ustrbuf.hxx"
23 #include "wininetbackend.hxx"
25 #if defined _MSC_VER
26 #pragma warning(push, 1)
27 #endif
28 #include <windows.h>
29 #include <wininet.h>
30 #include <sal/alloca.h>
31 #if defined _MSC_VER
32 #pragma warning(pop)
33 #endif
35 #define WININET_DLL_NAME "wininet.dll"
36 #define EQUAL_SIGN '='
37 #define COLON ':'
38 #define SPACE ' '
39 #define SEMI_COLON ';'
41 namespace {
43 struct Library {
44 HMODULE module;
46 Library(HMODULE theModule): module(theModule) {}
48 ~Library() { if (module) FreeLibrary(module); }
53 typedef struct
55 OUString Server;
56 OUString Port;
57 } ProxyEntry;
60 // helper functions
63 namespace // private
65 ProxyEntry ReadProxyEntry(const OUString& aProxy, sal_Int32& i)
67 ProxyEntry aProxyEntry;
69 aProxyEntry.Server = aProxy.getToken( 0, COLON, i );
70 if ( i > -1 )
71 aProxyEntry.Port = aProxy.getToken( 0, COLON, i );
73 return aProxyEntry;
76 ProxyEntry FindProxyEntry(const OUString& aProxyList, const OUString& aType)
78 sal_Int32 nIndex = 0;
82 // get the next token, e.g. ftp=server:port
83 OUString nextToken = aProxyList.getToken( 0, SPACE, nIndex );
85 // split the next token again into the parts separated
86 // through '=', e.g. ftp=server:port -> ftp and server:port
87 sal_Int32 i = 0;
88 if( nextToken.indexOf( EQUAL_SIGN ) > -1 )
90 if( aType.equals( nextToken.getToken( 0, EQUAL_SIGN, i ) ) )
91 return ReadProxyEntry(nextToken, i);
93 else if( aType.isEmpty())
94 return ReadProxyEntry(nextToken, i);
96 } while ( nIndex >= 0 );
98 return ProxyEntry();
101 } // end private namespace
105 WinInetBackend::WinInetBackend()
107 Library hWinInetDll( LoadLibrary( WININET_DLL_NAME ) );
108 if( hWinInetDll.module )
110 typedef BOOL ( WINAPI *InternetQueryOption_Proc_T )( HINTERNET, DWORD, LPVOID, LPDWORD );
112 InternetQueryOption_Proc_T lpfnInternetQueryOption =
113 reinterpret_cast< InternetQueryOption_Proc_T >(
114 GetProcAddress( hWinInetDll.module, "InternetQueryOptionA" ) );
115 if (lpfnInternetQueryOption)
117 // Some Windows versions would fail the InternetQueryOption call
118 // with ERROR_OUTOFMEMORY when the initial dwLength were zero (and
119 // are apparently fine with the initial sizeof (INTERNET_PROXY_INFO)
120 // and need no reallocation), while other versions fail with
121 // ERROR_INSUFFICIENT_BUFFER upon that initial dwLength and need a
122 // reallocation:
123 INTERNET_PROXY_INFO pi;
124 LPINTERNET_PROXY_INFO lpi = &pi;
125 DWORD dwLength = sizeof (INTERNET_PROXY_INFO);
126 BOOL ok = lpfnInternetQueryOption(
127 NULL,
128 INTERNET_OPTION_PROXY,
129 (LPVOID)lpi,
130 &dwLength );
131 if (!ok)
133 DWORD err = GetLastError();
134 if (err == ERROR_INSUFFICIENT_BUFFER)
136 // allocate sufficient space on the heap
137 // insufficient space on the heap results
138 // in a stack overflow exception, we assume
139 // this never happens, because of the relatively
140 // small amount of memory we need
141 // alloca is nice because it is fast and we don't
142 // have to free the allocated memory, it will be
143 // automatically done
144 lpi = reinterpret_cast< LPINTERNET_PROXY_INFO >(
145 alloca( dwLength ) );
146 ok = lpfnInternetQueryOption(
147 NULL,
148 INTERNET_OPTION_PROXY,
149 (LPVOID)lpi,
150 &dwLength );
151 if (!ok)
153 err = GetLastError();
156 if (!ok)
158 SAL_WARN(
159 "shell",
160 "InternetQueryOption INTERNET_OPTION_PROXY"
161 " GetLastError=" << err);
162 return;
166 // if a proxy is disabled, InternetQueryOption returns
167 // an empty proxy list, so we don't have to check if
168 // proxy is enabled or not
170 OUString aProxyList = OUString::createFromAscii( lpi->lpszProxy );
171 OUString aProxyBypassList = OUString::createFromAscii( lpi->lpszProxyBypass );
173 // override default for ProxyType, which is "0" meaning "No proxies".
174 sal_Int32 nProperties = 1;
176 valueProxyType_.IsPresent = true;
177 valueProxyType_.Value <<= nProperties;
179 // fill proxy bypass list
180 if( aProxyBypassList.getLength() > 0 )
182 OUStringBuffer aReverseList;
183 sal_Int32 nIndex = 0;
186 OUString aToken = aProxyBypassList.getToken( 0, SPACE, nIndex );
187 if ( aProxyList.indexOf( aToken ) == -1 )
189 if ( aReverseList.getLength() )
191 aReverseList.insert( 0, sal_Unicode( SEMI_COLON ) );
192 aReverseList.insert( 0, aToken );
194 else
195 aReverseList = aToken;
198 while ( nIndex >= 0 );
200 aProxyBypassList = aReverseList.makeStringAndClear();
202 valueNoProxy_.IsPresent = true;
203 valueNoProxy_.Value <<= aProxyBypassList.replace( SPACE, SEMI_COLON );
206 if( aProxyList.getLength() > 0 )
209 // this implementation follows the algorithm
210 // of the internet explorer
211 // if there are type-dependent proxy settings
212 // and type independent proxy settings in the
213 // registry the internet explorer chooses the
214 // type independent proxy for all settings
215 // e.g. imagine the following registry entry
216 // ftp=server:port;http=server:port;server:port
217 // the last token server:port is type independent
218 // so the ie chooses this proxy server
220 // if there is no port specified for a type independent
221 // server the ie uses the port of an http server if
222 // there is one and it has a port
225 ProxyEntry aTypeIndepProxy = FindProxyEntry( aProxyList, OUString());
226 ProxyEntry aHttpProxy = FindProxyEntry( aProxyList, OUString(
227 "http" ) );
228 ProxyEntry aHttpsProxy = FindProxyEntry( aProxyList, OUString(
229 "https" ) );
231 ProxyEntry aFtpProxy = FindProxyEntry( aProxyList, OUString(
232 "ftp" ) );
234 if( aTypeIndepProxy.Server.getLength() )
236 aHttpProxy.Server = aTypeIndepProxy.Server;
237 aHttpsProxy.Server = aTypeIndepProxy.Server;
238 aFtpProxy.Server = aTypeIndepProxy.Server;
240 if( aTypeIndepProxy.Port.getLength() )
242 aHttpProxy.Port = aTypeIndepProxy.Port;
243 aHttpsProxy.Port = aTypeIndepProxy.Port;
244 aFtpProxy.Port = aTypeIndepProxy.Port;
246 else
248 aFtpProxy.Port = aHttpProxy.Port;
249 aHttpsProxy.Port = aHttpProxy.Port;
253 // http proxy name
254 if( aHttpProxy.Server.getLength() > 0 )
256 valueHttpProxyName_.IsPresent = true;
257 valueHttpProxyName_.Value <<= aHttpProxy.Server;
260 // http proxy port
261 if( aHttpProxy.Port.getLength() > 0 )
263 valueHttpProxyPort_.IsPresent = true;
264 valueHttpProxyPort_.Value <<= aHttpProxy.Port.toInt32();
267 // https proxy name
268 if( aHttpsProxy.Server.getLength() > 0 )
270 valueHttpsProxyName_.IsPresent = true;
271 valueHttpsProxyName_.Value <<= aHttpsProxy.Server;
274 // https proxy port
275 if( aHttpsProxy.Port.getLength() > 0 )
277 valueHttpsProxyPort_.IsPresent = true;
278 valueHttpsProxyPort_.Value <<= aHttpsProxy.Port.toInt32();
281 // ftp proxy name
282 if( aFtpProxy.Server.getLength() > 0 )
284 valueFtpProxyName_.IsPresent = true;
285 valueFtpProxyName_.Value <<= aFtpProxy.Server;
288 // ftp proxy port
289 if( aFtpProxy.Port.getLength() > 0 )
291 valueFtpProxyPort_.IsPresent = true;
292 valueFtpProxyPort_.Value <<= aFtpProxy.Port.toInt32();
301 WinInetBackend::~WinInetBackend()
307 WinInetBackend* WinInetBackend::createInstance()
309 return new WinInetBackend;
314 void WinInetBackend::setPropertyValue(
315 OUString const &, css::uno::Any const &)
316 throw (
317 css::beans::UnknownPropertyException, css::beans::PropertyVetoException,
318 css::lang::IllegalArgumentException, css::lang::WrappedTargetException,
319 css::uno::RuntimeException)
321 throw css::lang::IllegalArgumentException(
322 OUString(
323 "setPropertyValue not supported"),
324 static_cast< cppu::OWeakObject * >(this), -1);
327 css::uno::Any WinInetBackend::getPropertyValue(
328 OUString const & PropertyName)
329 throw (
330 css::beans::UnknownPropertyException, css::lang::WrappedTargetException,
331 css::uno::RuntimeException)
333 if ( PropertyName == "ooInetFTPProxyName" )
335 return css::uno::makeAny(valueFtpProxyName_);
336 } else if ( PropertyName == "ooInetFTPProxyPort" )
338 return css::uno::makeAny(valueFtpProxyPort_);
339 } else if ( PropertyName == "ooInetHTTPProxyName" )
341 return css::uno::makeAny(valueHttpProxyName_);
342 } else if ( PropertyName == "ooInetHTTPProxyPort" )
344 return css::uno::makeAny(valueHttpProxyPort_);
345 } else if ( PropertyName == "ooInetHTTPSProxyName" )
347 return css::uno::makeAny(valueHttpsProxyName_);
348 } else if ( PropertyName == "ooInetHTTPSProxyPort" )
350 return css::uno::makeAny(valueHttpsProxyPort_);
351 } else if ( PropertyName == "ooInetNoProxy" )
353 return css::uno::makeAny(valueNoProxy_);
354 } else if ( PropertyName == "ooInetProxyType" )
356 return css::uno::makeAny(valueProxyType_);
357 } else {
358 throw css::beans::UnknownPropertyException(
359 PropertyName, static_cast< cppu::OWeakObject * >(this));
365 OUString SAL_CALL WinInetBackend::getBackendName() {
366 return OUString("com.sun.star.comp.configuration.backend.WinInetBackend") ;
371 OUString SAL_CALL WinInetBackend::getImplementationName()
372 throw (uno::RuntimeException)
374 return getBackendName() ;
377 uno::Sequence<OUString> SAL_CALL WinInetBackend::getBackendServiceNames()
379 uno::Sequence<OUString> aServiceNameList(1);
380 aServiceNameList[0] = "com.sun.star.configuration.backend.WinInetBackend";
382 return aServiceNameList ;
385 sal_Bool SAL_CALL WinInetBackend::supportsService(const OUString& aServiceName)
386 throw (uno::RuntimeException)
388 return cppu::supportsService(this, aServiceName);
391 uno::Sequence<OUString> SAL_CALL WinInetBackend::getSupportedServiceNames()
392 throw (uno::RuntimeException)
394 return getBackendServiceNames() ;
397 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */