Success Send one email to gmail server
[TortoiseGit.git] / src / Utils / NetAdapterInfo.cpp
blobd993a907f497e4dff4d7379d3cc7d6286a2b1400
1 // OneNetAdapterInfo.cpp: implementation of the COneNetAdapterInfo class.
2 //
3 //////////////////////////////////////////////////////////////////////
5 #include "stdafx.h"
6 #include "SpeedPostEmail.h"
7 #include "NetAdapterInfo.h"
8 #include "Iphlpapi.h"
9 #include "IpTypes.h"
11 #ifdef _DEBUG
12 #undef THIS_FILE
13 static char THIS_FILE[]=__FILE__;
14 #define new DEBUG_NEW
15 #endif
17 #define MALLOC( bytes ) ::HeapAlloc( ::GetProcessHeap(), HEAP_ZERO_MEMORY, (bytes) )
18 #define FREE( ptr ) if( ptr ) ::HeapFree( ::GetProcessHeap(), 0, ptr )
19 #define REMALLOC( ptr, bytes ) ::HeapReAlloc( ::GetProcessHeap(), HEAP_ZERO_MEMORY, ptr, bytes )
21 #pragma comment ( lib, "iphlpapi.lib" )
23 //////////////////////////////////////////////////////////////////////
24 // Construction/Destruction
25 //////////////////////////////////////////////////////////////////////
26 COneNetAdapterInfo::COneNetAdapterInfo ( IP_ADAPTER_INFO *pAdptInfo )
28 m_bInitOk = FALSE;
29 memset ( &m_PhysicalAddress, 0, sizeof(m_PhysicalAddress) );
30 m_nPhysicalAddressLength = 0;
31 ASSERT ( pAdptInfo );
32 memcpy ( &m_AdptInfo, pAdptInfo, sizeof(IP_ADAPTER_INFO) );
33 if ( !Init() )
35 TRACE ( _T("[%s - %s] initialize failed."), Get_Name(), Get_Desc() );
39 COneNetAdapterInfo::~COneNetAdapterInfo()
45 // ¸ù¾Ý´«ÈëµÄ pAdptInfo ÐÅÏ¢À´»ñÈ¡Ö¸¶¨Íø¿¨µÄ»ù±¾ÐÅÏ¢
47 BOOL COneNetAdapterInfo::Init ()
49 IP_ADDR_STRING* pNext = NULL;
50 IP_PER_ADAPTER_INFO* pPerAdapt = NULL;
51 ULONG ulLen = 0;
52 DWORD dwErr = ERROR_SUCCESS;
53 ASSERT ( m_AdptInfo.AddressLength > 0 );
54 t_IPINFO iphold;
56 // ½«±äÁ¿Çå¿Õ
57 m_bInitOk = FALSE;
58 m_csName.Empty ();
59 m_csDesc.Empty ();
60 m_CurIPInfo.csIP.Empty ();
61 m_CurIPInfo.csSubnet.Empty ();
62 m_Ary_IP.RemoveAll ();
63 m_Ary_DNS.RemoveAll ();
64 m_Ary_Gateway.RemoveAll ();
66 #ifndef _UNICODE
67 m_csName = m_AdptInfo.AdapterName;
68 m_csDesc = m_AdptInfo.Description;
69 #else
70 USES_CONVERSION;
71 m_csName = A2W ( m_AdptInfo.AdapterName );
72 m_csDesc = A2W ( m_AdptInfo.Description );
73 #endif
75 // »ñÈ¡µ±Ç°ÕýÔÚʹÓõÄIPµØÖ·
76 if ( m_AdptInfo.CurrentIpAddress )
78 m_CurIPInfo.csIP = m_AdptInfo.CurrentIpAddress->IpAddress.String;
79 m_CurIPInfo.csSubnet = m_AdptInfo.CurrentIpAddress->IpMask.String;
81 else
83 m_CurIPInfo.csIP = _T("0.0.0.0");
84 m_CurIPInfo.csSubnet = _T("0.0.0.0");
87 // »ñÈ¡±¾Íø¿¨ÖÐËùÓеÄIPµØÖ·
88 pNext = &( m_AdptInfo.IpAddressList );
89 while ( pNext )
91 iphold.csIP = pNext->IpAddress.String;
92 iphold.csSubnet = pNext->IpMask.String;
93 m_Ary_IP.Add ( iphold );
94 pNext = pNext->Next;
97 // »ñÈ¡±¾Íø¿¨ÖÐËùÓеÄÍø¹ØÐÅÏ¢
98 pNext = &( m_AdptInfo.GatewayList );
99 while ( pNext )
101 m_Ary_Gateway.Add ( A2W( pNext->IpAddress.String ));
102 pNext = pNext->Next;
105 // »ñÈ¡±¾Íø¿¨ÖÐËùÓÐµÄ DNS
106 dwErr = ::GetPerAdapterInfo ( m_AdptInfo.Index, pPerAdapt, &ulLen );
107 if( dwErr == ERROR_BUFFER_OVERFLOW )
109 pPerAdapt = ( IP_PER_ADAPTER_INFO* ) MALLOC( ulLen );
110 dwErr = ::GetPerAdapterInfo( m_AdptInfo.Index, pPerAdapt, &ulLen );
112 // if we succeed than we need to drop into our loop
113 // and fill the dns array will all available IP
114 // addresses.
115 if( dwErr == ERROR_SUCCESS )
117 pNext = &( pPerAdapt->DnsServerList );
118 while( pNext )
120 m_Ary_DNS.Add( A2W( pNext->IpAddress.String ) );
121 pNext = pNext->Next;
123 m_bInitOk = TRUE;
126 // this is done outside the dwErr == ERROR_SUCCES just in case. the macro
127 // uses NULL pointer checking so it is ok if pPerAdapt was never allocated.
128 FREE( pPerAdapt );
131 return m_bInitOk;
135 // ÊÍ·Å»òˢб¾Íø¿¨µÄIPµØÖ·
137 BOOL COneNetAdapterInfo::RenewReleaseIP( Func_OperateIP func )
139 IP_INTERFACE_INFO* pInfo = NULL;
140 BOOL bDidIt = FALSE;
141 ULONG ulLen = 0;
142 int nNumInterfaces = 0;
143 int nCnt = 0;
144 DWORD dwErr = ERROR_SUCCESS;
146 dwErr = ::GetInterfaceInfo ( pInfo, &ulLen );
147 if( dwErr == ERROR_INSUFFICIENT_BUFFER )
149 pInfo = ( IP_INTERFACE_INFO* ) MALLOC( ulLen );
150 dwErr = ::GetInterfaceInfo ( pInfo, &ulLen );
152 if( dwErr != ERROR_SUCCESS )
154 return FALSE;
158 // we can assume from here out that we have a valid array
159 // of IP_INTERFACE_INFO structures due to the error
160 // checking one above.
161 nNumInterfaces = ulLen / sizeof( IP_INTERFACE_INFO );
162 for( nCnt = 0; nCnt < nNumInterfaces; nCnt++ )
164 if( pInfo[ nCnt ].Adapter[ 0 ].Index == m_AdptInfo.Index )
166 dwErr = func( &pInfo[ nCnt ].Adapter[ 0 ] );
168 // free all used memory since we don't need it any more.
169 FREE( pInfo );
171 bDidIt = ( dwErr == NO_ERROR );
172 if( ! bDidIt ) {
173 return FALSE;
176 break;
180 return bDidIt;
183 ////////////////////////////////////////////////////////////
184 // Desc:
185 // Releases the addresses held by this adapter.
186 ////////////////////////////////////////////////////////////
187 BOOL COneNetAdapterInfo::ReleaseIP()
189 return RenewReleaseIP ( ::IpReleaseAddress );
192 ////////////////////////////////////////////////////////////
193 // Desc:
194 // Renews the address being held by this adapter.
195 ////////////////////////////////////////////////////////////
196 BOOL COneNetAdapterInfo::RenewIP()
198 return RenewReleaseIP ( ::IpRenewAddress );
201 CString COneNetAdapterInfo::GetAdapterTypeString ()
203 UINT nType = m_AdptInfo.Type;
204 CString csType = _T("");
205 switch( nType )
207 case MIB_IF_TYPE_OTHER: csType = _T("Other"); break;
208 case MIB_IF_TYPE_ETHERNET: csType = _T("Ethernet"); break;
209 case MIB_IF_TYPE_TOKENRING: csType = _T("Token Ring"); break;
210 case MIB_IF_TYPE_FDDI: csType = _T("FDDI"); break;
211 case MIB_IF_TYPE_PPP: csType = _T("PPP"); break;
212 case MIB_IF_TYPE_LOOPBACK: csType = _T("Loopback"); break;
213 case MIB_IF_TYPE_SLIP: csType = _T("SLIP"); break;
214 default: csType = _T("Invalid Adapter Type"); break;
217 return csType;
220 time_t COneNetAdapterInfo::Get_LeaseObtained() const { return m_AdptInfo.LeaseObtained; }
221 time_t COneNetAdapterInfo::Get_LeaseExpired() const { return m_AdptInfo.LeaseExpires; }
222 int COneNetAdapterInfo::Get_IPCount() const { return (int)m_Ary_IP.GetSize(); }
223 int COneNetAdapterInfo::Get_DNSCount() const { return (int)m_Ary_DNS.GetSize(); }
224 CString COneNetAdapterInfo::Get_CurrentIP() const { return m_CurIPInfo.csIP; }
225 BOOL COneNetAdapterInfo::Is_DHCP_Used() const { return m_AdptInfo.DhcpEnabled; }
226 CString COneNetAdapterInfo::Get_DHCPAddr() const { return m_AdptInfo.DhcpServer.IpAddress.String; }
227 BOOL COneNetAdapterInfo::Is_Wins_Used() const { return m_AdptInfo.HaveWins; }
228 CString COneNetAdapterInfo::Get_PrimaryWinsServer() const { return m_AdptInfo.PrimaryWinsServer.IpAddress.String; }
229 CString COneNetAdapterInfo::Get_SecondaryWinsServer() const { return m_AdptInfo.SecondaryWinsServer.IpAddress.String; }
230 int COneNetAdapterInfo::Get_GatewayCount() const { return m_Ary_Gateway.GetSize(); }
231 DWORD COneNetAdapterInfo::Get_AdapterIndex() const { return m_AdptInfo.Index; }
232 UINT COneNetAdapterInfo::Get_AdapterType() const { return m_AdptInfo.Type; }
234 CString COneNetAdapterInfo::Get_IPAddr ( int nIndex ) const
236 CString csAddr = _T("");
237 if ( nIndex >= 0 && nIndex < m_Ary_IP.GetSize() )
239 csAddr = m_Ary_IP.GetAt(nIndex).csIP;
242 return csAddr;
245 CString COneNetAdapterInfo::Get_Subnet ( int nIndex ) const
247 CString csAddr = _T("");
248 if ( nIndex >= 0 && nIndex < m_Ary_IP.GetSize() )
250 csAddr = m_Ary_IP.GetAt(nIndex).csSubnet;
253 return csAddr;
256 CString COneNetAdapterInfo::Get_DNSAddr ( int nIndex ) const
258 CString csAddr = _T("");
259 if ( nIndex >= 0 && nIndex < m_Ary_DNS.GetSize() )
261 csAddr = m_Ary_DNS.GetAt(nIndex);
264 return csAddr;
267 CString COneNetAdapterInfo::Get_GatewayAddr ( int nIndex ) const
269 CString csAddr = _T("");
270 if ( nIndex >= 0 && nIndex < m_Ary_Gateway.GetSize() )
272 csAddr = m_Ary_Gateway.GetAt(nIndex);
275 return csAddr;
278 void COneNetAdapterInfo::Set_PhysicalAddress ( int nPhysicalAddressLength, BYTE *pPhysicalAddress )
280 if ( !pPhysicalAddress ) return;
281 m_nPhysicalAddressLength = __min(nPhysicalAddressLength,sizeof(m_PhysicalAddress));
282 memcpy ( m_PhysicalAddress, pPhysicalAddress, m_nPhysicalAddressLength );
285 //////////////////////////////////////////////////////////////////////
286 // Construction/Destruction
287 //////////////////////////////////////////////////////////////////////
289 CNetAdapterInfo::CNetAdapterInfo ()
293 CNetAdapterInfo::~CNetAdapterInfo()
295 DeleteAllNetAdapterInfo ();
298 void CNetAdapterInfo::DeleteAllNetAdapterInfo()
300 for ( int i=0; i<m_Ary_NetAdapterInfo.GetSize(); i++ )
302 COneNetAdapterInfo *pOneNetAdapterInfo = (COneNetAdapterInfo*)m_Ary_NetAdapterInfo.GetAt(i);
303 if ( pOneNetAdapterInfo ) delete pOneNetAdapterInfo;
305 m_Ary_NetAdapterInfo.RemoveAll ();
309 // ö¾ÙÍøÂçÊÊÅäÆ÷
310 // return : ------------------------------------------------------------
311 // -1 - ʧ°Ü
312 // >=0 - ÍøÂçÊÊÅäÆ÷ÊýÁ¿
314 int CNetAdapterInfo::EnumNetworkAdapters ()
316 DeleteAllNetAdapterInfo ();
318 IP_ADAPTER_INFO* pAdptInfo = NULL;
319 IP_ADAPTER_INFO* pNextAd = NULL;
320 ULONG ulLen = 0;
321 int nCnt = 0;
323 DWORD dwError = ::GetAdaptersInfo ( pAdptInfo, &ulLen );
324 if( dwError != ERROR_BUFFER_OVERFLOW ) return -1;
325 pAdptInfo = ( IP_ADAPTER_INFO* )MALLOC ( ulLen );
326 dwError = ::GetAdaptersInfo( pAdptInfo, &ulLen );
327 if ( dwError != ERROR_SUCCESS ) return -1;
329 pNextAd = pAdptInfo;
330 while( pNextAd )
332 COneNetAdapterInfo *pOneNetAdapterInfo = new COneNetAdapterInfo ( pNextAd );
333 if ( pOneNetAdapterInfo )
335 m_Ary_NetAdapterInfo.Add ( pOneNetAdapterInfo );
337 nCnt ++;
338 pNextAd = pNextAd->Next;
341 // free any memory we allocated from the heap before
342 // exit. we wouldn't wanna leave memory leaks now would we? ;p
343 FREE( pAdptInfo );
345 return nCnt;
348 COneNetAdapterInfo* CNetAdapterInfo::Get_OneNetAdapterInfo ( int nIndex )
350 if ( nIndex < 0 || nIndex >= m_Ary_NetAdapterInfo.GetSize() )
352 ASSERT ( FALSE );
353 return NULL;
356 return (COneNetAdapterInfo*)m_Ary_NetAdapterInfo.GetAt(nIndex);
359 COneNetAdapterInfo* CNetAdapterInfo::Get_OneNetAdapterInfo ( DWORD dwIndex )
361 for ( int i=0; i<m_Ary_NetAdapterInfo.GetSize(); i++ )
363 COneNetAdapterInfo *pOneNetAdapterInfo = (COneNetAdapterInfo*)m_Ary_NetAdapterInfo.GetAt(i);
364 if ( pOneNetAdapterInfo && pOneNetAdapterInfo->Get_AdapterIndex() == dwIndex )
365 return pOneNetAdapterInfo;
368 return NULL;
371 void CNetAdapterInfo::Refresh ()
373 DeleteAllNetAdapterInfo ();
374 EnumNetworkAdapters ();
375 GetAdapterAddress ();
379 // »ñÈ¡Íø¿¨µÄµØÖ·ÐÅÏ¢£¬Ö÷ÒªÊÇMACµØÖ·
381 BOOL CNetAdapterInfo::GetAdapterAddress ()
383 DWORD dwSize = 0;
384 DWORD dwRetVal = 0;
385 BOOL bRet = FALSE;
387 int i = 0;
389 // Set the flags to pass to GetAdaptersAddresses
390 ULONG flags = GAA_FLAG_INCLUDE_PREFIX;
392 // default to unspecified address family (both)
393 // AF_INET for IPv4, AF_INET6 for IPv6
394 ULONG family = AF_UNSPEC;
396 LPVOID lpMsgBuf = NULL;
398 PIP_ADAPTER_ADDRESSES pAddresses = NULL;
399 ULONG outBufLen = 0;
401 PIP_ADAPTER_ADDRESSES pCurrAddresses = NULL;
402 PIP_ADAPTER_UNICAST_ADDRESS pUnicast = NULL;
403 PIP_ADAPTER_ANYCAST_ADDRESS pAnycast = NULL;
404 PIP_ADAPTER_MULTICAST_ADDRESS pMulticast = NULL;
405 IP_ADAPTER_DNS_SERVER_ADDRESS *pDnServer = NULL;
406 IP_ADAPTER_PREFIX *pPrefix = NULL;
408 outBufLen = sizeof (IP_ADAPTER_ADDRESSES);
409 pAddresses = (IP_ADAPTER_ADDRESSES *) MALLOC(outBufLen);
410 if (pAddresses == NULL) return FALSE;
412 // Make an initial call to GetAdaptersAddresses to get the
413 // size needed into the outBufLen variable
414 if ( ::GetAdaptersAddresses ( family, flags, NULL, pAddresses, &outBufLen ) == ERROR_BUFFER_OVERFLOW )
416 FREE(pAddresses);
417 pAddresses = (IP_ADAPTER_ADDRESSES *) MALLOC(outBufLen);
419 if (pAddresses == NULL) return FALSE;
421 // Make a second call to GetAdapters Addresses to get the
422 // actual data we want
423 #ifdef _DEBUG
424 TRACE ( _T("Memory allocated for GetAdapterAddresses = %d bytes\n"), outBufLen);
425 TRACE ( _T("Calling GetAdaptersAddresses function with family = " ) );
426 if (family == AF_INET)
427 TRACE(_T("AF_INET\n"));
428 if (family == AF_INET6)
429 TRACE(_T("AF_INET6\n"));
430 if (family == AF_UNSPEC)
431 TRACE(_T("AF_UNSPEC\n\n"));
432 #endif
433 dwRetVal = GetAdaptersAddresses ( family, flags, NULL, pAddresses, &outBufLen );
435 if ( dwRetVal == NO_ERROR )
437 // If successful, output some information from the data we received
438 pCurrAddresses = pAddresses;
439 while (pCurrAddresses)
441 TRACE(_T("\tLength of the IP_ADAPTER_ADDRESS struct: %ld\n"),
442 pCurrAddresses->Length);
443 TRACE(_T("\tIfIndex (IPv4 interface): %u\n"), pCurrAddresses->IfIndex);
444 TRACE(_T("\tAdapter name: %s\n"), pCurrAddresses->AdapterName);
446 pUnicast = pCurrAddresses->FirstUnicastAddress;
447 if (pUnicast != NULL)
449 for (i = 0; pUnicast != NULL; i++)
450 pUnicast = pUnicast->Next;
451 TRACE(_T("\tNumber of Unicast Addresses: %d\n"), i);
453 else
455 TRACE(_T("\tNo Unicast Addresses\n"));
458 pAnycast = pCurrAddresses->FirstAnycastAddress;
459 if (pAnycast)
461 for (i = 0; pAnycast != NULL; i++)
462 pAnycast = pAnycast->Next;
463 TRACE(_T("\tNumber of Anycast Addresses: %d\n"), i);
465 else
467 TRACE(_T("\tNo Anycast Addresses\n"));
470 pMulticast = pCurrAddresses->FirstMulticastAddress;
471 if (pMulticast)
473 for (i = 0; pMulticast != NULL; i++)
474 pMulticast = pMulticast->Next;
475 TRACE(_T("\tNumber of Multicast Addresses: %d\n"), i);
477 else
479 TRACE(_T("\tNo Multicast Addresses\n"));
482 pDnServer = pCurrAddresses->FirstDnsServerAddress;
483 if (pDnServer)
485 for (i = 0; pDnServer != NULL; i++)
486 pDnServer = pDnServer->Next;
487 TRACE(_T("\tNumber of DNS Server Addresses: %d\n"), i);
489 else
491 TRACE(_T("\tNo DNS Server Addresses\n"));
494 TRACE(_T("\tDNS Suffix: %wS\n"), pCurrAddresses->DnsSuffix);
495 TRACE(_T("\tDescription: %wS\n"), pCurrAddresses->Description);
496 TRACE(_T("\tFriendly name: %wS\n"), pCurrAddresses->FriendlyName);
498 if (pCurrAddresses->PhysicalAddressLength != 0)
500 TRACE(_T("\tPhysical address: "));
501 for (i = 0; i < (int) pCurrAddresses->PhysicalAddressLength; i++)
503 if ( i == (int)(pCurrAddresses->PhysicalAddressLength - 1))
504 TRACE(_T("%.2X\n"), (int) pCurrAddresses->PhysicalAddress[i]);
505 else
506 TRACE(_T("%.2X-"), (int) pCurrAddresses->PhysicalAddress[i]);
509 COneNetAdapterInfo* pNetAdapterInfo = Get_OneNetAdapterInfo ( pCurrAddresses->IfIndex );
510 if ( pNetAdapterInfo )
512 pNetAdapterInfo->Set_PhysicalAddress ( pCurrAddresses->PhysicalAddressLength, pCurrAddresses->PhysicalAddress );
515 TRACE(_T("\tFlags: %ld\n"), pCurrAddresses->Flags);
516 TRACE(_T("\tMtu: %lu\n"), pCurrAddresses->Mtu);
517 TRACE(_T("\tIfType: %ld\n"), pCurrAddresses->IfType);
518 TRACE(_T("\tOperStatus: %ld\n"), pCurrAddresses->OperStatus);
519 TRACE(_T("\tIpv6IfIndex (IPv6 interface): %u\n"),
520 pCurrAddresses->Ipv6IfIndex);
521 TRACE(_T("\tZoneIndices (hex): "));
522 for (i = 0; i < 16; i++)
523 TRACE(_T("%lx "), pCurrAddresses->ZoneIndices[i]);
524 TRACE(_T("\n"));
526 pPrefix = pCurrAddresses->FirstPrefix;
527 if (pPrefix)
529 for (i = 0; pPrefix != NULL; i++)
530 pPrefix = pPrefix->Next;
531 TRACE(_T("\tNumber of IP Adapter Prefix entries: %d\n"), i);
533 else
535 TRACE(_T("\tNumber of IP Adapter Prefix entries: 0\n"));
538 TRACE(_T("\n"));
540 pCurrAddresses = pCurrAddresses->Next;
541 bRet = TRUE;
544 else
546 TRACE(_T("Call to GetAdaptersAddresses failed with error: %d\n"), dwRetVal );
547 if (dwRetVal == ERROR_NO_DATA)
549 TRACE(_T("\tNo addresses were found for the requested parameters\n"));
551 else
553 if (FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, dwRetVal, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
554 (LPTSTR) & lpMsgBuf, 0, NULL))
556 TRACE(_T("\tError: %s"), lpMsgBuf);
557 LocalFree(lpMsgBuf);
558 FREE(pAddresses);
561 bRet = FALSE;
563 FREE(pAddresses);
565 return bRet;
568 CString MacAddress2String ( int nPhysicalAddressLength, BYTE *pPhysicalAddress )
570 ASSERT ( nPhysicalAddressLength >= 6 );
571 AfxIsValidAddress(pPhysicalAddress,nPhysicalAddressLength,TRUE);
572 CString csMacAddress, csOneCell;
573 for ( int i=0; i<nPhysicalAddressLength; i++ )
575 csOneCell.Format ( _T("%.2X"), (int)pPhysicalAddress[i] );
576 if ( !csMacAddress.IsEmpty() ) csMacAddress += _T("-");
577 csMacAddress += csOneCell;
580 return csMacAddress;