📄 hxnetif.cpp
字号:
if (!_hxWSAStartup || !_hxWSACleanup || !_pInetAddr)#else if (!_hxsocket || !_hxclosesocket || !_hxWSAStartup || !_hxWSACleanup || !_raWSAIoctl)#endif /* _WINCE */ { rc = HXR_FAILED; goto cleanup; } wVersionRequested = (1 << 8) + 1; _hxWSAStartup(wVersionRequested, &wsaData);#ifndef _WINCE s = _hxsocket(AF_INET, SOCK_DGRAM, 0); if (s == INVALID_SOCKET) { rc = HXR_FAILED; goto cleanup; } pInfo = new INTERFACE_INFO[MAX_INTERFACES]; // get interfaces list if (_raWSAIoctl(s, SIO_GET_INTERFACE_LIST, NULL, NULL, pInfo, sizeof(INTERFACE_INFO)*MAX_INTERFACES, &ulBytes, NULL, NULL)) { rc = HXR_FAILED; goto cleanup; } // caculate # of interfaces we have iStructures = ulBytes / sizeof(INTERFACE_INFO); // iterate through the interface list for (iPosition = 0; iPosition < iStructures; iPosition++) { lFlags = pInfo[iPosition].iiFlags; if (lFlags & IFF_LOOPBACK) { continue; } else if ((lFlags & IFF_POINTTOPOINT) && (lFlags & IFF_UP)) { type = POINTTOPOINT; } else if ((lFlags & IFF_BROADCAST) && (lFlags & IFF_UP)) { type = BROADCAST; } else { continue; } ulNetAddress = ((sockaddr_in*)&(pInfo[iPosition].iiAddress))->sin_addr.s_addr; ulNetMask = ((sockaddr_in*)&(pInfo[iPosition].iiNetmask))->sin_addr.s_addr; // ignore the net interface with invalid IP/Mask if (ulNetAddress == 0 || ulNetMask == 0) { continue; } pNIInfo = new NIInfo; pNIInfo->bActive = TRUE; pNIInfo->type = type; pNIInfo->ulNetAddress = ulNetAddress; pNIInfo->ulNetMask = ulNetMask; if (!pNetInterfaceList) { pNetInterfaceList = new CHXSimpleList(); } pNetInterfaceList->AddTail(pNIInfo); }cleanup: if (_hxclosesocket) { _hxclosesocket(s); } if (_hxWSACleanup) { _hxWSACleanup(); } HX_VECTOR_DELETE(pInfo);#else// WinCE does not support Winsock2, yet. Also, it has many variations for registry settings.// Thus, it is better to use GetAdapterInfo defined in iphlpapi.h.// Note: This call is supported only in WinCE 3.0 or later. if (NULL == m_hIPLib) m_hIPLib = LoadLibrary(OS_STRING("IPHLPAPI.DLL")); if (m_hIPLib) _pGetAdaptersInfo = (GETADAPTERSINFO) ::GetProcAddress(m_hIPLib, OS_STRING("GetAdaptersInfo")); if (NULL == _pGetAdaptersInfo) { rc = HXR_FAILED; goto cleanup; } // first make a call with ulSize = 0 to get the exact size needed dwResult = _pGetAdaptersInfo(pAdapterInfo, &ulSize); if (ERROR_BUFFER_OVERFLOW == dwResult) { // allocate right amount of space for adapter info pAdapterInfo = (PIP_ADAPTER_INFO)(new char[ulSize]); if (!pAdapterInfo) { rc = HXR_OUTOFMEMORY; goto cleanup; } // fill up adapters info dwResult= _pGetAdaptersInfo(pAdapterInfo, &ulSize); if (ERROR_SUCCESS != dwResult) { rc = HXR_FAILED; goto cleanup; } // step thru the adapters list that we received while (pAdapterInfo != NULL) { if (MIB_IF_TYPE_PPP == pAdapterInfo->Type) type = POINTTOPOINT; else if (MIB_IF_TYPE_ETHERNET == pAdapterInfo->Type) type = BROADCAST; else continue; // step thru all IP addresses for each adapter pAddrList = &(pAdapterInfo->IpAddressList); do { ulNetAddress = _pInetAddr(pAddrList->IpAddress.String); ulNetMask = _pInetAddr(pAddrList->IpMask.String); // ignore the net interface with invalid IP/Mask if (INADDR_NONE != ulNetAddress && 0 != ulNetAddress && INADDR_NONE != ulNetMask && 0 != ulNetMask) { pNIInfo = new NIInfo; if (!pAdapterInfo) { rc = HXR_OUTOFMEMORY; goto cleanup; } pNIInfo->bActive = TRUE; pNIInfo->type = type; pNIInfo->ulNetAddress = ulNetAddress; pNIInfo->ulNetMask = ulNetMask; if (!pNetInterfaceList) { pNetInterfaceList = new CHXSimpleList(); if (!pAdapterInfo) { rc = HXR_OUTOFMEMORY; goto cleanup; } } pNetInterfaceList->AddTail(pNIInfo); pAddrList = pAddrList->Next; } }while (pAddrList != NULL); pAdapterInfo = pAdapterInfo->Next; } } else { rc = HXR_FAILED; goto cleanup; }cleanup: HX_VECTOR_DELETE(pAdapterInfo); if (_hxWSACleanup) { _hxWSACleanup(); }#endif /* _WINCE */ return rc;} voidHXNetInterface::CheckAddrChange(void){ DWORD dwResult = 0; if (WAIT_OBJECT_0 == WaitForSingleObject(m_hAddrChangeEvent, 0)) { Reset(m_pNetInterfaceList); RetrieveNetInterface0(m_pNetInterfaceList); if (m_pSinkList) { CHXSimpleList::Iterator ndx = m_pSinkList->Begin(); for (; ndx != m_pSinkList->End(); ++ndx) { IHXNetInterfacesAdviseSink* pSink = (IHXNetInterfacesAdviseSink*) (*ndx); pSink->NetInterfacesUpdated(); } }#ifdef _WINCE // Overlapped param is not supported in wince 3.0 in the second param to NotifyAddrChange if(NO_ERROR == _pNotifyAddrChange(&m_hAddrChangeEvent, NULL))#else if (ERROR_IO_PENDING == _pNotifyAddrChange(&m_handle, &m_overLapped))#endif /* _WINCE */ { m_pAddrChangeCallback->m_bIsCallbackPending = TRUE; m_pAddrChangeCallback->m_PendingHandle = m_pScheduler->RelativeEnter(m_pAddrChangeCallback, CHECK_ADDR_CHANGE_INTERVAL); } } else { m_pAddrChangeCallback->m_bIsCallbackPending = TRUE; m_pAddrChangeCallback->m_PendingHandle = m_pScheduler->RelativeEnter(m_pAddrChangeCallback, CHECK_ADDR_CHANGE_INTERVAL); } return;}BOOLHXNetInterface::IsNetInterfaceChanged(void){ BOOL bResult = FALSE; CHXSimpleList* pTempNetInterfaceList = NULL; if (m_pAddrChangeCallback && m_pAddrChangeCallback->m_bIsCallbackPending) { if (WAIT_OBJECT_0 == WaitForSingleObject(m_hAddrChangeEvent, 0)) { bResult = TRUE; Reset(m_pNetInterfaceList); RetrieveNetInterface0(m_pNetInterfaceList);#ifdef _WINCE // Overlapped param is not supported in wince 3.0 in the second param to NotifyAddrChange if(NO_ERROR == _pNotifyAddrChange(&m_hAddrChangeEvent, NULL))#else if (ERROR_IO_PENDING == _pNotifyAddrChange(&m_handle, &m_overLapped))#endif /* _WINCE */ { m_pScheduler->Remove(m_pAddrChangeCallback->m_PendingHandle); m_pAddrChangeCallback->m_PendingHandle = m_pScheduler->RelativeEnter(m_pAddrChangeCallback, CHECK_ADDR_CHANGE_INTERVAL); } } goto cleanup; } else { pTempNetInterfaceList = new CHXSimpleList(); RetrieveNetInterface0(pTempNetInterfaceList); if (!pTempNetInterfaceList || pTempNetInterfaceList->GetCount() == 0) { // try the generic method RetrieveNetInterface1(pTempNetInterfaceList); } if (pTempNetInterfaceList && m_pNetInterfaceList) { if (pTempNetInterfaceList->GetCount() != m_pNetInterfaceList->GetCount()) { bResult = TRUE; } else { CHXSimpleList::Iterator ndx0 = pTempNetInterfaceList->Begin(); CHXSimpleList::Iterator ndx1 = m_pNetInterfaceList->Begin(); for (; ndx0 != pTempNetInterfaceList->End() && ndx1 != m_pNetInterfaceList->End(); ++ndx0, ++ndx1) { NIInfo* pInfo0 = (NIInfo*)(*ndx0); NIInfo* pInfo1 = (NIInfo*)(*ndx1); if (pInfo0->ulNetAddress != pInfo1->ulNetAddress || pInfo0->ulNetMask != pInfo1->ulNetMask) { bResult = TRUE; } } } } else if (pTempNetInterfaceList != m_pNetInterfaceList) { bResult = TRUE; } if (bResult) { Reset(m_pNetInterfaceList); HX_DELETE(m_pNetInterfaceList); m_pNetInterfaceList = pTempNetInterfaceList; } else { Reset(pTempNetInterfaceList); HX_DELETE(pTempNetInterfaceList); } }cleanup: return bResult;}voidHXNetInterface::Reset(CHXSimpleList* pNetInterfaceList){ if (pNetInterfaceList) { while (pNetInterfaceList->GetCount()) { NIInfo* pNIInfo = (NIInfo*)pNetInterfaceList->RemoveHead(); HX_DELETE(pNIInfo); } }}voidHXNetInterface::Close(void){ if (m_pAddrChangeCallback) { if (m_pAddrChangeCallback->m_bIsCallbackPending) { m_pAddrChangeCallback->m_bIsCallbackPending = FALSE; m_pScheduler->Remove(m_pAddrChangeCallback->m_PendingHandle); m_pAddrChangeCallback->m_PendingHandle = 0; } HX_RELEASE(m_pAddrChangeCallback); } if (m_hAddrChangeEvent) { CloseHandle(m_hAddrChangeEvent); m_hAddrChangeEvent = NULL; } if (m_handle) {#ifndef _WINCE CancelIo(m_handle);#else CloseHandle(m_handle);#endif /* _WINCE */ // XXX HP // Confirmed with MS TS that the caller doesn't need to // call CloseHandle() on m_handle, it's taken care of by // the FreeLibrary() m_handle = NULL; } Reset(m_pNetInterfaceList); HX_DELETE(m_pNetInterfaceList); if (m_pSinkList) { HX_ASSERT(m_pSinkList->GetCount() == 0); CHXSimpleList::Iterator ndx = m_pSinkList->Begin(); for (; ndx != m_pSinkList->End(); ++ndx) { IHXNetInterfacesAdviseSink* pSink = (IHXNetInterfacesAdviseSink*) (*ndx); HX_RELEASE(pSink); } HX_DELETE(m_pSinkList); } if (m_hIPLib) { FreeLibrary(m_hIPLib); m_hIPLib = NULL; } if (m_hWinSockLib) { FreeLibrary(m_hWinSockLib); m_hWinSockLib = NULL; } HX_RELEASE(m_pScheduler); HX_RELEASE(m_pContext);}AddrChangeCallback::AddrChangeCallback() : m_lRefCount (0) ,m_pParent (0) ,m_PendingHandle (0) ,m_bIsCallbackPending (FALSE){}AddrChangeCallback::~AddrChangeCallback(){}/* * IUnknown methods *//////////////////////////////////////////////////////////////////////////// Method:// IUnknown::QueryInterface// Purpose:// Implement this to export the interfaces supported by your// object.//STDMETHODIMP AddrChangeCallback::QueryInterface(REFIID riid, void** ppvObj){ QInterfaceList qiList[] = { { GET_IIDHANDLE(IID_IUnknown), this }, { GET_IIDHANDLE(IID_IHXCallback), (IHXCallback*) this }, { GET_IIDHANDLE(IID_IHXInterruptSafe), (IHXInterruptSafe*) this }, }; return QIFind(qiList, QILISTSIZE(qiList), riid, ppvObj);}/////////////////////////////////////////////////////////////////////////// Method:// IUnknown::AddRef// Purpose:// Everyone usually implements this the same... feel free to use// this implementation.//STDMETHODIMP_(ULONG32) AddrChangeCallback::AddRef(){ return InterlockedIncrement(&m_lRefCount);}/////////////////////////////////////////////////////////////////////////// Method:// IUnknown::Release// Purpose:// Everyone usually implements this the same... feel free to use// this implementation.//STDMETHODIMP_(ULONG32) AddrChangeCallback::Release(){ if (InterlockedDecrement(&m_lRefCount) > 0) { return m_lRefCount; } delete this; return 0;}STDMETHODIMP AddrChangeCallback::Func(void){ m_PendingHandle = 0; m_bIsCallbackPending = FALSE; if (m_pParent) { m_pParent->CheckAddrChange(); } return HXR_OK;}STDMETHODIMP_(BOOL) AddrChangeCallback::IsInterruptSafe(){ return FALSE;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -