string Mapper_WinUPnP::getExternalIP() { // Get the External IP from the last added mapping if(!lastPort) return Util::emptyString; IStaticPortMappingCollection* pSPMC = getStaticPortMappingCollection(); if(!pSPMC) return Util::emptyString; /// @todo use a BSTR wrapper BSTR protocol_ = SysAllocString(Text::toT(protocols[lastProtocol]).c_str()); // Lets Query our mapping IStaticPortMapping* pSPM; HRESULT hr = pSPMC->get_Item(lastPort, protocol_, &pSPM); SysFreeString(protocol_); // Query failed! if(FAILED(hr) || !pSPM) { pSPMC->Release(); return Util::emptyString; } BSTR bstrExternal = 0; hr = pSPM->get_ExternalIPAddress(&bstrExternal); if(FAILED(hr) || !bstrExternal) { pSPM->Release(); pSPMC->Release(); return Util::emptyString; } // convert the result string ret = Text::wideToAcp(bstrExternal); // no longer needed SysFreeString(bstrExternal); // no longer needed pSPM->Release(); pSPMC->Release(); return ret; }
// Returns the current external IP address _bstr_t UPnP::GetExternalIP() { HRESULT hr; // Check if we opened the desired port, 'cause we use it for getting the IP // This shouldn't be a problem because we only try to get the external IP when // we opened the mapping // This function is not used somewhere else, hence it is "save" to do it like this if(!PortsAreOpen) { return ""; } BSTR bstrExternal = NULL; _bstr_t bstrWrapper; CoInitializeEx ( NULL ,COINIT_MULTITHREADED); hr = CoCreateInstance (__uuidof(UPnPNAT), NULL, CLSCTX_INPROC_SERVER, __uuidof(IUPnPNAT), (void**)&pUN); if(SUCCEEDED(hr)) { // Get the Collection IStaticPortMappingCollection *pIMaps = NULL; hr = pUN->get_StaticPortMappingCollection(&pIMaps); // Check it // We also check against that bug mentioned in OpenPorts() if(!SUCCEEDED(hr) || !pIMaps ) { // Only release when OK if(pIMaps != NULL) { pIMaps->Release(); } pUN->Release(); pUN=NULL; CoUninitialize(); return ""; } // Lets Query our mapping IStaticPortMapping *pISM; hr = pIMaps->get_Item( PortNumber, bstrProtocol, &pISM ); // Query failed! if(!SUCCEEDED(hr)) { pIMaps->Release(); pUN->Release(); pUN=NULL; CoUninitialize(); return ""; } // Get the External IP from our mapping hr = pISM->get_ExternalIPAddress(&bstrExternal); // D'OH. Failed if(!SUCCEEDED(hr)) { pIMaps->Release(); pISM->Release(); pUN->Release(); pUN=NULL; CoUninitialize(); return ""; } // Check and convert the result if(bstrExternal != NULL) { bstrWrapper.Assign(bstrExternal); } else { bstrWrapper = ""; } // no longer needed SysFreeString(bstrExternal); // no longer needed pIMaps->Release(); pISM->Release(); pUN->Release(); pUN=NULL; CoUninitialize(); } return bstrWrapper; }
int SetPortForwarding(char *localIP, char *description, int internalPort, int *externalPort) { CoInitialize(NULL); int errorCode = 0; IUPnPNAT *nat = NULL; IStaticPortMappingCollection *mappingCollection = NULL; IStaticPortMapping *mapping = NULL; if( !SUCCEEDED( CoCreateInstance(__uuidof(UPnPNAT), NULL, CLSCTX_ALL, __uuidof(IUPnPNAT), (void **)&nat) ) || ( nat==NULL ) ) { errorCode = ERROR_COCREATEINSTANCE; goto ERROR_EXIT; } if ( !SUCCEEDED( nat->get_StaticPortMappingCollection(&mappingCollection) ) || (mappingCollection==NULL ) ) { errorCode = ERROR_UPNP_NOT_FOUNDED; goto ERROR_EXIT; } while( TRUE ) { IStaticPortMapping *existMapping = NULL; BOOL hasMappingInformation = SUCCEEDED( mappingCollection->get_Item(*externalPort, L"TCP", &existMapping) ); if ( hasMappingInformation ) { //printf( "hasMappingInformation \n" ); BSTR bStrIP = NULL; existMapping->get_InternalClient(&bStrIP); BSTR bstrDescryption = NULL; existMapping->get_Description(&bstrDescryption); long iExistInternalPort = 0; existMapping->get_InternalPort(&iExistInternalPort); if( bStrIP != NULL && bstrDescryption != NULL ) { //printf( "bStrIP != NULL && bstrDescryption != NULL \n" ); USES_CONVERSION; char *sClientIP = OLE2A(bStrIP); char *sDescryption = OLE2A(bstrDescryption); BOOL hasMapping = ( strcmp(sClientIP, localIP) == 0 ) && ( strcmp(sDescryption, description) == 0) && ( iExistInternalPort == internalPort ); if ( hasMapping ) { //printf( "hasMapping \n" ); SysFreeString(bStrIP); SysFreeString(bstrDescryption); break; } SysFreeString(bStrIP); SysFreeString(bstrDescryption); } existMapping->Release(); (*externalPort)++; //printf( "(*externalPort)++: %d \n", *externalPort ); } else { //printf( "not hasMappingInformation \n" ); VARIANT_BOOL vb = VARIANT_TRUE; USES_CONVERSION; BOOL isNewMappingRegistered = SUCCEEDED( mappingCollection->Add(*externalPort, L"TCP", internalPort, A2W(localIP), vb, A2W(description), &mapping) ); if( ! isNewMappingRegistered ) { //printf( "not isNewMappingRegistered \n" ); errorCode = ERROR_PORTMAPPING_FAILED; goto ERROR_EXIT; } break; } } ERROR_EXIT: if ( NULL != mapping ) { mapping->Release(); mapping = NULL; } if ( NULL != mappingCollection ) { mappingCollection->Release(); mappingCollection = NULL; } if ( NULL != nat ) { nat->Release(); nat = NULL; } CoUninitialize(); return errorCode; }