void UPnP::Destroy() { IUPnPNAT * Nat = NULL; IStaticPortMappingCollection * PortMappingCollection = NULL; HRESULT Result; wchar_t Protocol[256]; WORD Port; if(m_Port == 0) return; Port = m_Port; m_Port = 0; #ifdef MFC TRACE("UPnP: Removing Port\n"); #endif wcscpy_s(Protocol, L"TCP"); // Create IUPnPNat Result = CoCreateInstance(CLSID_UPnPNAT, NULL, CLSCTX_INPROC_SERVER, IID_IUPnPNAT, (void **)&Nat); if(FAILED(Result)) { #ifdef MFC TRACE("UPnP: Unable to create UPnPNAT interface\n"); #endif return; } Result = Nat->get_StaticPortMappingCollection(&PortMappingCollection); if(!PortMappingCollection || FAILED(Result)) { if(PortMappingCollection) PortMappingCollection->Release(); Nat->Release(); #ifdef MFC TRACE("UPnP: Unable to acquire a static portmapping collection\n"); #endif return; } Result = PortMappingCollection->Remove(Port, Protocol); if(FAILED(Result)) { PortMappingCollection->Release(); Nat->Release(); #ifdef MFC TRACE("UPnP: Unable to remove port\n"); #endif return; } }
// Add a UPnP port bool Win32UPnPAddPort(UINT outside_port, UINT inside_port, bool udp, char *local_ip, wchar_t *description, bool remove_before_add) { bool ret = false; HRESULT hr; IUPnPNAT *nat = NULL; wchar_t ip_str[MAX_SIZE]; BSTR bstr_ip, bstr_description, bstr_protocol; wchar_t *protocol_str = (udp ? L"UDP" : L"TCP"); // Validate arguments if (outside_port == 0 || outside_port >= 65536 || inside_port == 0 || inside_port >= 65536 || IsEmptyStr(local_ip) || UniIsEmptyStr(description)) { return false; } StrToUni(ip_str, sizeof(ip_str), local_ip); bstr_ip = SysAllocString(ip_str); bstr_description = SysAllocString(description); bstr_protocol = SysAllocString(protocol_str); hr = CoCreateInstance(CLSID_UPnPNAT, NULL, CLSCTX_INPROC_SERVER, IID_IUPnPNAT, (void **)&nat); if (SUCCEEDED(hr)) { if (nat != NULL) { IStaticPortMappingCollection *collection = NULL; hr = nat->get_StaticPortMappingCollection(&collection); if (SUCCEEDED(hr)) { if (collection != NULL) { IStaticPortMapping *mapping = NULL; if (remove_before_add) { hr = collection->Remove((long)outside_port, bstr_protocol); } hr = collection->Add((long)outside_port, bstr_protocol, (long)inside_port, bstr_ip, VARIANT_TRUE, bstr_description, &mapping); if (SUCCEEDED(hr)) { ret = true; if (mapping != NULL) { mapping->Release(); } } collection->Release(); } else { WHERE; } } else { WHERE; } nat->Release(); } else { WHERE; } } else { WHERE; } SysFreeString(bstr_ip); SysFreeString(bstr_description); SysFreeString(bstr_protocol); return ret; }
bool UPnP::Create(u16 Port) { IUPnPNAT * Nat = NULL; IStaticPortMappingCollection * PortMappingCollection = NULL; IStaticPortMapping * PortMap = NULL; HRESULT Result; wchar_t Protocol[256]; wchar_t InternalClient[256]; wchar_t Description[256]; Destroy(); #ifdef MFC TRACE("UPnP: Adding port\n"); #endif if(!GetIp()) { return false; } size_t num_chars_converted{}; mbstowcs_s(&num_chars_converted, InternalClient, m_Address, 256); wcscpy_s(Protocol, L"UDP"); wcscpy_s(Description, L"Gunz"); // Create IUPnPNat Result = CoCreateInstance(CLSID_UPnPNAT, NULL, CLSCTX_INPROC_SERVER, IID_IUPnPNAT, (void **)&Nat); if(FAILED(Result)) { #ifdef MFC TRACE("UPnP: Unable to create UPnPNAT interface\n"); #endif return false; } Result = Nat->get_StaticPortMappingCollection(&PortMappingCollection); if(!PortMappingCollection || FAILED(Result)) { if(PortMappingCollection) PortMappingCollection->Release(); Nat->Release(); #ifdef MFC TRACE("UPnP: Unable to acquire a static portmapping collection\n"); #endif return false; } Result = PortMappingCollection->Add(Port, Protocol, Port, InternalClient, VARIANT_TRUE, Description, &PortMap); if(!PortMap || FAILED(Result)) { if(PortMap) PortMap->Release(); PortMappingCollection->Release(); Nat->Release(); #ifdef MFC TRACE("UPnP: Unable add port\n"); #endif return false; } #ifdef MFC TRACE("UPnP: Port %d forwarded to %s\n", Port, m_Address); #endif PortMap->Release(); PortMappingCollection->Release(); Nat->Release(); m_Port = Port; return true; }
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; }