How to check line state using WMI with C/C++

This article was contributed by Arkady Frenkel , Microsoft MVP [ Windows SDK /Networking ].

 

Overview

Environment: VS6 on W2K / XP

NetConnect dll is ATL COM object which use WMI ( Windows Management Instrumentation ) to receive status of network connection and through connection point fire event into MFC client application - CheckNet.exe .

NetConnect dll enumerate network adapters in the computer to work with . I set fix buffer of 5 adapters because I never used more than 2 , but it can be easy be change to free number by CSimpleArray of ATL or by API allocations . When StartPolling member function of main object ( CNetConnectobj ) called , It starts working thread which do polling of network connection for each adapter in the system and fire event to container ( CheckNet.exe ) through connection point interface ( Fire_Connection of Event class proxy CProxy_INetConnectobjEvents ) , After polling each adapter thread make a 1 sec sleep. So if higher precision needed change of sleep time to low value will make the deal. I choose connection point because I realized polling process inside in-process server where such communication is efficient enough ( "Effective Com" by Don Box, Keith Brown,Tim Ewalds and Chris Sells ) Because the process done on additional ( working ) thread and not on main thread of object I was need to use one of advices from http://www.mvps.org/vcfaq/com/1.htm. I used method 2 of Q196026 of KB MSDN "PRB: Firing Event in Second Thread Causes IPF or GPF" to fire event correctly for different containers , because the data I need to send is number of adapter and state , so it can easy be packet into wParam of message.

As was asked on microsoft.public.win32.programmer.networks newsgroup about possibility to ask network state in using C programming language - CheckNetwork.c is source code to ask the state. CheckNetwork - is next member-function of CNetConnectobj which allow to ask connection state of needed adapter.

I didn't derive the main class object from IProvideClassInfo2 , because I decided ( on create ) that it will be dual interface ( for VB and script languages using ), but if custom interface used , the object have to be derived from IProvideClassInfo2 to give needed information in run-time( "ATL internals" by Brent Rector and Chris Sells )

I choose to use dispinterface because opposite to of being slow ( in compare to VTBL (custom) interface ) it has option to work with VB and script languages ( VBA , VBscript , JScript ).

Needed wbemcli.h and wbemuuid.lib taken from DDK Windows 2000.

I did NetConnect.dll in debug mode but in the case of Release ( Mindependency or Min Size ) don't forget to remove ATL_CRT_MIN ( ) . Look at Q166480 "PRB: Link Error LNK2001: Unresolved External Symbol _main" of KB MSDN .

 

Code Overview

To work with NetConnect.dll it have to registered so let's say directory where NetConnect.dll is C:\NetworkCheck the regsvr32 have to be called like this :

regsvr32 C:\NetworkCheck\NetConnect.dll

And to remove the registration of NetConnect.dll possible by :

regsvr32 /u C:\NetworkCheck\NetConnect.dll

Client ( container ) is MFC application CheckNet.exe which implement connection sync in it to receive event when cable plugged/unplugged on each of network adapters.

Next steps done to dialog box application checknet to implement the sink ( receiver of event from ATL COM object ( NetConnect.dll ) :

1) First added line 23 to stdafx.h to generate object's smart pointer

#import "netconnct.tlb" no_namespace raw_interfaces_only named_guids

2) Initialization of smart pointer m_pIM possible to see in line 123 of CheckNetDlg.cpp m_pIM = INetConnectobjPtr(CLSID_NetConnectobj);

3) After line 23 in stdafx.h added next lines :

#include
//You may derive a class from CComModule and use it if you want to override
//something, but do not change the name of _Module extern CComModule _Module;
#include

4) AfxOleInit(); - Line 49 added to CCheckNetApp::InitInstance() in CheckNet.cpp

5) CComModule _Module ; - Line 15 added to CheckNet.cpp

6) _Module.Init(NULL , m_hInstance ) ; - Line 62 added to CheckNet.cpp

7) _Module.Term( ) ; - Line 76 added to CheckNet.cpp

8) Next lines added to CheckNetDlg.cpp from line 121 to CCheckNetDlg::OnInitDialog() try { m_pIM = INetConnectobjPtr(CLSID_NetConnectobj); // Create the sink object, and advise the server m_pHandler = new CEventHandler; IUnknownPtr pUnk = m_pIM; m_pHandler->DispEventAdvise(pUnk); } catch (_com_error &e) { MessageBox(e.ErrorMessage()); } to initialize smart pointer on ATL COM object as was written before ( point 2 ) , and creation and advising of sink to connection point of object

9) EventHandler.h & EventHandler.cpp realized sink class CEnentHandler

10) Added handler CCheckNetDlg::OnButton1( ) to CheckNetDlg.cpp where by line : m_pIM->StartPolling() ; Advice of sink done and from now all changes in line status ( plug/unplug ) received .

11) Added handler CCheckNetDlg::OnButton2( ) to CheckNetDlg.cpp where line : m_pIM->CheckNetwork(&i) ; responsible to checking connection of first ( usually single ) network adaptor

12) Next lines added to CCheckNetDlg::OnDestroy() IUnknownPtr pUnk = m_pIM; m_pHandler->DispEventUnadvise(pUnk); delete m_pHandler; to unadvise sink and delete CEventHandler class when client ( CheckNet ) closed.

I believe that these are all steps before compiling/linking of CheckNet.exe , but if I forgot something the code with you :)

 

Using CheckNet Application

To start receive notification events button "Start Check Net" have to be pressed . Button "Check Net" - to ask network state on first adapter on demand.

Here is the CheckNet dialog when the first adapter cable is connected:

 

Here is the CheckNet dialog when the first adapter cable is disconnected:

Downloads

Download source code of ATL COM dll server- 821Kb
Download ATL COM dll server - 61 Kb
Download source code of MFC client ( container ) application - 259 Kb
Download MFC client ( container ) application - 12 Kb

 

Topic Status

January 6, 2003 Initial release.
October 15, 2002 Submitted by Arkady.

 

 

PCAUSA Home · Privacy Statement · Products · Ordering · Support · Utilities · Resources
Mailing Lists  · PCAUSA Newsletter · PCAUSA Discussion List
Rawether for Windows, Rawether .NET, WinDis 32 and NDIS Press are trademarks of Printing Communications Assoc., Inc. (PCAUSA)
Microsoft, MS, Windows, Windows Vista, Windows 95, Windows 98, Windows Millennium, Windows 2000, and Win32 are registered trademarks and Visual C++ and Windows NT are trademarks of the Microsoft Corporation.
Copyright © 1996-2007 Printing Communications Assoc., Inc. (PCAUSA)
Last modified: January 20, 2007