Introduction
Sometimes our application needs to be aware of network availability or change in a network. This application will show how our application can get notification from NLA (which is a windows service).
There can be three states of network connection that is, no network connection and multiple network connections or there is a single network connection. Based on this there can be only one scenario from the following.
1) There is no network connection and a new connection is available.
2) There is already one or more network connection present on the system and new connection is available.
3) There are multiple connections presents and one or more is drops out
4) Network connection disappears and there is no network connection available.
The following APIs are used for NLA notification.
WSAStartup
WSALookupServiceBegin
WSALookupServiceNext
WSALookupServiceEnd
WSANSPIoctl
WSACleanup
WSACreateEvent
USAGE OF APIs
This section gives overview on how to use methods from the give code. To get the notification form the NLA service, follow the following steps
1) To get the instance of CNetworkAvailabilityCheck class call GetNetworkAvailability.
nsnla::CNetworkAvailabilityCheck *ptrNetworkAvailabilityCheck = nsnla::CNetworkAvailabilityCheck::GetNetworkAvailability();
if
{
(!ptrNetworkAvailabilityCheck)//couldn't get network availability check instance
}
2) Set notification type using SetNotificationType. There are five ways of getting notified. That are Pooling, Window Message, Event, APC and completion port (two notifications are implemented in this application - Event and APC).
ptrNetworkAvailabilityCheck->SetNotificationType(APCNotification);
3) Call EnumerateLogicalNetwork to enumerate logical network available on the system.
return;
if
This function will get all the information about available networks on the system. This function will get network information one by one and insert them into list. This function takes lLocalNetworkInfo as in parameter. Which is a structure of local netwrok information. That has the information about local netowrk.
4) Look for connection change
To get the notification call LookForConnectionChange. This function has one boolean argument which decides whether it's a blocking or non-blocking call (default is true that is it's a blocking call).
Before calling LookForConnectionChange, notification type can be set using SetNotificationType and also callbacks can be registered for APC notification using RegisterAPCNotification.
ptrNetworkAvailabilityCheck->RegisterAPCNotification(CUseNetworkAvailabilityDlg::APCInvoked, *
Callback fucntion should follow APCNotificationCallback defination
(!ptrNetworkAvailabilityCheck->EnumerateLogicalNetwork(m_lstNetworkInfo)) this);
typedef
If a function is registered, whenever a APC will get notified it will call registered function.
5) Call StopLookForConnectionChange to stop getting notification.
DETAILS ABOUT APIs
This section will give more details about NLA methods that were discussed in previous section
Initialization of NLA
Socket library needs to be initializes and also NLA uses events and that also needs to be created and initialize. It's done using InitializeNLA.
Following function will do the initialization
//Initializatin of NLA class
bool
{
WSAData wsaData;
WORD wVersionRequested = MAKEWORD(2,2);
{
CNetworkAvailabilityCheck::InitializeNLA()if(0 != WSAStartup(wVersionRequested, &wsaData))//Here we cann't call WSAGetLast Error as we are doing normally for windows socket //because socket library it self is not loaded in the case of the failure
OutputDebugString(_T(
}
m_hStopLookingForConnection = WSACreateEvent();
{
}
WSAResetEvent(m_hStopLookingForConnection);
}
"Cannot Initialize socket library"));return false;if(WSA_INVALID_EVENT == m_hStopLookingForConnection)int iError = WSAGetLastError();return false;return true;
Enumerating logical available networks
EnumerateLogicalNetwork will first initialize By calling InitializeNLA if that call gets successed it will enumerat currently available logical network using CheckAndGetNetworksAvailabilty. This function uses windows apis to get network information. It will initiates client query usign WSALookupServiceBegin which will return a handle. This handle can be used for subsequient call of WSALookupServiceNext
if
iResult = WSALookupServiceNext(hLookupHandle, LUP_RETURN_ALL, &dwBuffLen, ptrWsaQuerySet);
WSALookupServiceNext will return WSAQueryset structure in last out parameter. WSALookupServiceNext function should be called continuesly until it returns WSA_E_NO_MORE that indicates all information is returned. It will call WSALookupServiceEnd to free the handle return by WSALookupServiceBegin.
(0 != WSALookupServiceBegin(ptrWsaQuerySet, LUP_RETURN_ALL, &hLookupHandle))
Start look for new connection
There are two ways of calling this apis that is blocking and nonblocking call. Default it is a true that is it's a blocking call and it will wait till there is a change in network connection. If that default parameter is false it will return immediately that is it will wait in another thread. As this application supports two types of notification based on the notification type that is set by the application using SetNotificationType.
StartLookingForConnectionChange will start looking for connection change. Based on the notification type that is passed to this function it will either set event notification or APC notification. After setting the notification type it will call WSANSPIoctl and will wait on the event till it gets notification.
StartLookingForConnectionChange will set notification using WSANSPIoctl as shown in the following code.
if
To set the APC callback there must be one callback function which will get notified when there is a change in network. Following is how NLA Application sets APC callback. This callback will call client callback that is registered using RegisterAPCNotification.
(SOCKET_ERROR == WSANSPIoctl(hLookupHandle, SIO_NSP_NOTIFY_CHANGE, NULL, 0, NULL, 0, &dwBytesReturned, ptrWSACompletion))
//APC notification callback
void
CALLBACK NotifyAPC(DWORD dwError, DWORD cbTransferred, LPWSAOVERLAPPED lpOverlapped, DWORD dwFlags);
Stop looking for new connections
StopLookForConnectionChange will stop looking for connection change.
CleanUp
CleanUpNLA will do the clean up and close the handle.
There is one more class called CNLABlob which will hold the information about the NLA Blob and NLA Blob information can be retrived using available public methods in that class.