[Bug 17796] Citavi: No network access (wininet.dll InternetGetConnectedStateExW returns incorrect network connection state)

wine-bugs at winehq.org wine-bugs at winehq.org
Fri Mar 22 13:56:49 CDT 2013


http://bugs.winehq.org/show_bug.cgi?id=17796

Anastasius Focht <focht at gmx.net> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Keywords|                            |dotnet
             Status|UNCONFIRMED                 |NEW
                 CC|                            |focht at gmx.net
          Component|-unknown                    |wininet
            Summary|Citavi: No network access   |Citavi: No network access
                   |                            |(wininet.dll
                   |                            |InternetGetConnectedStateEx
                   |                            |W returns incorrect network
                   |                            |connection state)
     Ever Confirmed|0                           |1

--- Comment #6 from Anastasius Focht <focht at gmx.net> 2013-03-22 13:56:49 CDT ---
Hello folks,

confirming.

I extracted the .NET code the app uses to check for network connectivity with
"Reflector" tool from "$WINEPREFIX/drive_c/Program Files/Citavi/bin/Asz.dll":

--- snip ---
[DllImport("wininet.dll")]
public static extern int InternetGetConnectedStateEx(out int lpdwFlags,
StringBuilder lpszConnectionName, int dwNameLen, int dwReserved);

[DllImport("sensapi.dll")]
public static extern bool IsNetworkAlive(ref int flags);

public bool HasLAN()
{
    if (!_detectConnectedState)
    {
        Diagnostics.Trace(_detectConnectedState, "Value of
\"_detectConnectedState\" flag.");
        return true;
    }
    bool flag = false;
    try
    {
        int lpdwFlags = 0;
        StringBuilder lpszConnectionName = new StringBuilder(0x100);
        int dwNameLen = 0;
        int dwReserved = 0;
        if (Native.InternetGetConnectedStateEx(out lpdwFlags,
lpszConnectionName, dwNameLen, dwReserved) == 1)
        {
            flag = true;
        }
    }
    catch (Exception exception)
    {
        Diagnostics.Trace(exception);
    }
    Diagnostics.Trace(flag, "Value of \"hasLAN\" flag");
    bool flag2 = Native.IsNetworkAlive(ref Native.NETWORK_ALIVE_LAN);
    Diagnostics.Trace(flag2, "Value of \"isNetworkAlive\" flag");
    return (flag && flag2);
}
...
--- snip ---

The problem is the way Wine's wininet InternetGetConnectedStateEx() is written.

Source:
http://source.winehq.org/git/wine.git/blob/ae77b3d368519b5518dbe485dfac2e8123b5a477:/dlls/wininet/internet.c#l1131

--- snip ---
1131 /***********************************************************************
1132  *           InternetGetConnectedStateExW (WININET.@)
1133  *
1134  * Return connected state
1135  *
1136  * PARAMS
1137  *
1138  * lpdwStatus         [O] Flags specifying the status of the internet
connection.
1139  * lpszConnectionName [O] Pointer to buffer to receive the friendly name
of the internet connection.
1140  * dwNameLen          [I] Size of the buffer, in characters.
1141  * dwReserved         [I] Reserved. Must be set to 0.
1142  *
1143  * RETURNS
1144  *    TRUE if connected
1145  *    if lpdwStatus is not null, return the status (off line,
1146  *    modem, lan...) in it.
1147  *    FALSE if not connected
1148  *
1149  * NOTES
1150  *   If the system has no available network connections, an empty string
is
1151  *   stored in lpszConnectionName. If there is a LAN connection, a
localized
1152  *   "LAN Connection" string is stored. Presumably, if only a dial-up
1153  *   connection is available then the name of the dial-up connection is
1154  *   returned. Why any application, other than the "Internet Settings"
CPL,
1155  *   would want to use this function instead of the simpler
InternetGetConnectedStateW
1156  *   function is beyond me.
1157  */
1158 BOOL WINAPI InternetGetConnectedStateExW(LPDWORD lpdwStatus, LPWSTR
lpszConnectionName,
1159                                          DWORD dwNameLen, DWORD
dwReserved)
1160 {
1161     TRACE("(%p, %p, %d, 0x%08x)\n", lpdwStatus, lpszConnectionName,
dwNameLen, dwReserved);
1162 
1163     /* Must be zero */
1164     if(dwReserved)
1165         return FALSE;
1166 
1167     if (lpdwStatus) {
1168         WARN("always returning LAN connection.\n");
1169         *lpdwStatus = INTERNET_CONNECTION_LAN;
1170     }
1171     return LoadStringW(WININET_hModule, IDS_LANCONNECTION,
lpszConnectionName, dwNameLen);
1172 }
--- snip ---

Returning the connection state through LoadStringW() result looks plain wrong
to me (using result of that function call and/or return type int (num of chars)
vs. bool).

MSDN:
http://msdn.microsoft.com/en-us/library/windows/desktop/aa384705%28v=vs.85%29.aspx

--- quote ---
BOOL InternetGetConnectedStateEx(
  _Out_  LPDWORD lpdwFlags,
  _Out_  LPTSTR lpszConnectionName,
  _In_   DWORD dwNameLen,
  _In_   DWORD dwReserved
);

...

Remarks

A return value of TRUE from InternetGetConnectedState indicates that at least
one connection to the Internet is available. It does not guarantee that a
connection to a specific host can be established. Applications should always
check for errors returned from API calls that connect to a server.
InternetCheckConnection can be called to determine if a connection to a
specific destination can be established.

A return value of TRUE indicates that either the modem connection is active, or
a LAN connection is active and a proxy is properly configured for the LAN. A
return value of FALSE indicates that neither the modem nor the LAN is
connected. If FALSE is returned, the INTERNET_CONNECTION_CONFIGURED flag may be
set to indicate that autodial is configured to "always dial" but is not
currently active. If autodial is not configured, the function returns FALSE.
--- quote ---

Digging through the application .NET code I also found a debug trace
capability:

--- snip ---
$ find . -name "Settings.xml"
./drive_c/users/focht/Application Data/Academic Software Zurich/Settings.xml
--- snip ---

Set "EnableTrace" in XML file to "true" and you can use +debugstr channel to
get more verbose diagnostics (OutputDebugString).

+debugstr with builtin wininet

--- snip ---
warn:debugstr:OutputDebugStringA "3/22/2013 7:28:02 PM - _activeControlResolved
is: OnlineSearchWaitDialog\r\n"
warn:debugstr:OutputDebugStringA "3/22/2013 7:28:02 PM - Value of \"hasLAN\"
flag: False\r\n"
warn:debugstr:OutputDebugStringA "3/22/2013 7:28:02 PM - Value of
\"isNetworkAlive\" flag: True\r\n"
--- snip ---

+debugstr with native wininet (winetricks wininet):

--- snip ---
warn:debugstr:OutputDebugStringA "3/22/2013 7:26:36 PM - _activeControlResolved
is: OnlineSearchWaitDialog\r\n"
fixme:ras:RasEnumConnectionsW (0x1e6ea0,0x32c68c,0x76c623e4),stub!
fixme:ras:RasEnumConnectionsW RAS support is not implemented! Configure program
to use LAN connection/winsock instead!
fixme:service:EnumServicesStatusW resume handle not supported
warn:debugstr:OutputDebugStringA "3/22/2013 7:26:37 PM - Value of \"hasLAN\"
flag: True\r\n"
warn:debugstr:OutputDebugStringA "3/22/2013 7:26:37 PM - Value of
\"isNetworkAlive\" flag: True\r\n"
warn:debugstr:OutputDebugStringA "3/22/2013 7:26:37 PM - Starting
RetrievalDefinitions.UpdateAllFavorites.\r\n"
...
--- snip ---

You can work around easily by either changing application setting:

"Extras" -> "Projektübergreifende Optionen" -> "Recherche" -> check
"Internet-Verbindungsmeldungen von WIndows ignorieren" near the proxy settings.

or use native wininet ('winetricks wininet').

$ du -sh CitaviSetup.exe 
26M    CitaviSetup.exe

$ sha1sum CitaviSetup.exe 
bf840b949f9210654a31ba8488046e1ac47d51e5  CitaviSetup.exe

$ wine --version
wine-1.5.26-19-g6ed2d9b

Regards

-- 
Configure bugmail: http://bugs.winehq.org/userprefs.cgi?tab=email
Do not reply to this email, post in Bugzilla using the
above URL to reply.
------- You are receiving this mail because: -------
You are watching all bug changes.


More information about the wine-bugs mailing list