Checking for an internet connection - Programmer

This is a discussion on Checking for an internet connection - Programmer ; I want to find out if the machine currently has an internet connection that's up. From reading the docs, it looks like you have to allocate a buffer, then cast the pointer as below. So, is this the right way ...

+ Reply to Thread
Results 1 to 4 of 4

Thread: Checking for an internet connection

  1. Checking for an internet connection

    I want to find out if the machine currently has an internet
    connection that's up. From reading the docs, it looks like you
    have to allocate a buffer, then cast the pointer as below.

    So, is this the right way to do this?

    - Paul

    bool hasConnection() {
    DWORD size = 0;
    BOOL success = InternetQueryOption(
    NULL, INTERNET_OPTION_CONNECTED_STATE, NULL, &size
    );
    if ( !success )
    return false;

    char *buf = new char[ size ];

    success = InternetQueryOption(
    NULL, INTERNET_OPTION_CONNECTED_STATE, buf, &size
    );
    if ( !success )
    return false;

    LPINTERNET_CONNECTED_INFO info = (LPINTERNET_CONNECTED_INFO)buf;
    DWORD state = info->dwConnectedState;
    delete[] buf;

    switch ( state ) {
    case INTERNET_STATE_DISCONNECTED:
    case INTERNET_STATE_DISCONNECTED_BY_USER:
    return false;
    default:
    return true;
    }
    }

  2. Re: Checking for an internet connection

    Paul J. Lucas wrote:
    > I want to find out if the machine currently has an internet
    > connection that's up. From reading the docs, it looks like you
    > have to allocate a buffer, then cast the pointer as below.
    >
    > So, is this the right way to do this?
    >
    > bool hasConnection() {
    > DWORD size = 0;
    > BOOL success = InternetQueryOption(
    > NULL, INTERNET_OPTION_CONNECTED_STATE, NULL, &size
    > );


    After some experimentation, I've discovered 2 things:

    1. That call fails complaining that the size is too small.
    2. It sets size to 4.

    The funny thing is that sizeof( INTERNET_CONNECTED_INFO ) = 8,
    so it's not clear why it's returning 4.

    Any ideas?

    - Paul

  3. Re: Checking for an internet connection


    In article , pauljlucas.removethis@removethistoo.mac.com (Paul J. Lucas) writes:
    > Paul J. Lucas wrote:
    > > I want to find out if the machine currently has an internet
    > > connection that's up. From reading the docs, it looks like you
    > > have to allocate a buffer, then cast the pointer as below.


    In C++, you'll have to cast the buffer pointer unless it's a void*;
    in C you wouldn't, since C will implicitly convert other object
    pointer types to and from void*.

    You appear to be using C++, so your approach to buffer allocation
    appears to be OK, though it's not the way I'd do it. This looks to
    me like a case for using malloc rather than new in C++ code; you're
    not allocating an instance of a class, but a chunk of untyped
    storage, as far as the compiler is concerned.

    So I would:

    - declare a pointer to an object of the type you expect to receive
    - get the size from the first call to InternetQueryOption
    - malloc storage of that size, assigning it to your pointer (with
    the appropriate cast, since this is C++; there would be no cast
    in C)
    - populate the object with the second call to InternetQueryOption
    - process it
    - free it

    > > bool hasConnection() {
    > > DWORD size = 0;
    > > BOOL success = InternetQueryOption(
    > > NULL, INTERNET_OPTION_CONNECTED_STATE, NULL, &size
    > > );

    >
    > After some experimentation, I've discovered 2 things:
    >
    > 1. That call fails complaining that the size is too small.


    As it should, since you initialized size to 0.

    > 2. It sets size to 4.


    As it should, since INTERNET_OPTION_CONNECTED_STATE returns an
    "unsigned long integer value", per the MS documentation for the
    options for InternetQueryOption. Now, I did find a VB example in
    MSDN that showed InternetQueryOption with INTERNET_OPTION_
    CONNECTED_STATE being used to return an INTERNET_CONNECTED_INFO, but
    other examples showed it being used to return just a DWORD.

    I see a couple of possibilities:

    1. The VB example is simply wrong. Since IOCS populates the first
    DWORD of the target buffer, however, it's setting the only part of
    the ICI structure that the example code uses, so it "works".

    2. IOCS will populate as much of an ICI structure as the caller
    passes. The caller needs to pass in a buffer that's at least 4
    bytes long, so that IOCS can return at least the connection state;
    if the caller supplies a buffer of at least 8 bytes, the caller
    will get the whole ICI structure.

    I suspect #2, though it'd be nice if MS could produce complete
    documentation for this sort of thing.

    > The funny thing is that sizeof( INTERNET_CONNECTED_INFO ) = 8,
    > so it's not clear why it's returning 4.


    It's probably putting 4 in size because that's the minimum length.
    Since you know that IOCS is supposed to return a full ICI structure,
    though, you could skip that step, and indeed skip the dynamic
    memory allocation, as in:

    INTERNET_CONNECTED_INFO conninfo = {0};
    DWORD size = sizeof conninfo;
    BOOL success = InternetQueryOption(
    NULL, INTERNET_OPTION_CONNECTED_STATE, (void *)&conninfo, &size);

    NB. I haven't tried this; in particular, I haven't verified my
    suspicions about the behavior of the call when given buffers of
    various sizes, and I haven't tested to see whether this call requires
    a non-null HINTERNET handle for the first parameter (which is not
    clear from the documentation).

    --
    Michael Wojcik michael.wojcik@microfocus.com

    An intense imaginative activity accompanied by a psychological and moral
    passivity is bound eventually to result in a curbing of the growth to
    maturity and in consequent artistic repetitiveness and stultification.
    -- D. S. Savage

  4. Re: Checking for an internet connection

    Paul J. Lucas wrote:
    > I want to find out if the machine currently has an internet
    > connection that's up. From reading the docs, it looks like you
    > have to allocate a buffer, then cast the pointer as below.
    >
    > So, is this the right way to do this?
    >
    > - Paul
    >
    > bool hasConnection() {
    > DWORD size = 0;
    > BOOL success = InternetQueryOption(
    > NULL, INTERNET_OPTION_CONNECTED_STATE, NULL, &size
    > );
    > if ( !success )
    > return false;
    >


    Take out that

    if ( !succes )
    return false;

    and it works.

    John

+ Reply to Thread