Пример #1
0
bool Mapper_WinUPnP::add(const unsigned short port, const Protocol protocol, const string& description) {
	IStaticPortMappingCollection* pSPMC = getStaticPortMappingCollection();
	if(!pSPMC)
		return false;

	/// @todo use a BSTR wrapper
	BSTR protocol_ = SysAllocString(Text::toT(protocols[protocol]).c_str());
	BSTR description_ = SysAllocString(Text::toT(description).c_str());
	BSTR localIP = SysAllocString(Text::toT(Util::getLocalIp()).c_str());

	IStaticPortMapping* pSPM = 0;
	HRESULT hr = pSPMC->Add(port, protocol_, port, localIP, VARIANT_TRUE, description_, &pSPM);

	SysFreeString(protocol_);
	SysFreeString(description_);
	SysFreeString(localIP);

	bool ret = SUCCEEDED(hr);
	if(ret) {
		pSPM->Release();

		lastPort = port;
		lastProtocol = protocol;
	}
	pSPMC->Release();
	return ret;
}
Пример #2
0
bool UPNPCheckDlg::WinUPnP_add(const unsigned short port, const string& protocol, const string& description, IUPnPNAT* pUN)
{
#ifdef HAVE_NATUPNP_H
	IStaticPortMappingCollection* pSPMC = WinUPnP_getStaticPortMappingCollection(pUN);
	if (!pSPMC)
		return false;
		
	/// @todo use a BSTR wrapper
	BSTR protocol_ = SysAllocString(Text::toT(protocol).c_str());
	BSTR description_ = SysAllocString(Text::toT(description).c_str());
	BSTR localIP = SysAllocString(Text::toT(Util::getLocalOrBindIp(false)).c_str());
	
	IStaticPortMapping* pSPM = 0;
	HRESULT hr = pSPMC->Add(port, protocol_, port, localIP, VARIANT_TRUE, description_, &pSPM);
	
	SysFreeString(protocol_);
	SysFreeString(description_);
	SysFreeString(localIP);
	
	bool ret = SUCCEEDED(hr);
	if (ret)
	{
		safe_release(pSPM);
	}
	safe_release(pSPMC);
	return ret;
#else
	return false;
#endif
}
Пример #3
0
void UPnP::ClosePort()
{
    if(remote_port_ == 0)
        return;

#ifdef _MSC_VER
    HRESULT hr;

    IUPnPNAT* upnpnat;
    hr = CoCreateInstance (CLSID_UPnPNAT, NULL, CLSCTX_INPROC_SERVER, IID_IUPnPNAT, (void**)&upnpnat);
    if(FAILED(hr) || !upnpnat)
        return;

    IStaticPortMappingCollection* upnpspmc = NULL;
    hr = upnpnat->get_StaticPortMappingCollection(&upnpspmc);
    if(FAILED(hr) || !upnpspmc)
        return;

    BSTR bstrProtocol = A2BSTR("TCP");

    hr = upnpspmc->Remove(remote_port_, bstrProtocol);

    if(FAILED(hr))
        LOG.getlasterror("Automatisches Entfernen des Portforwardings mit UPnP fehlgeschlagen\nFehler");

    SysFreeString(bstrProtocol);

    if(FAILED(hr))
        return;
#else
    int hr;
    UPNPDev* devicelist = NULL;
#ifdef UPNPDISCOVER_SUCCESS
    int upnperror = 0;
    devicelist = upnpDiscover(2000, NULL, NULL, 0, 0 /* ipv6 */, &upnperror);
#else
    devicelist = upnpDiscover(2000, NULL, NULL, 0);
#endif
    if(!devicelist)
        return;

    UPNPUrls urls;
    IGDdatas data;
    hr = UPNP_GetValidIGD(devicelist, &urls, &data, NULL, 0);
    if(hr == 1 || hr == 2)
    {
        std::stringstream p;
        p << remote_port_;
        hr = UPNP_DeletePortMapping(urls.controlURL, data.first.servicetype, p.str().c_str(), "TCP", NULL);
    }

    freeUPNPDevlist(devicelist);

    if(hr != 0)
        return;
#endif

    remote_port_ = 0;
}
Пример #4
0
// Opens the UPnP ports defined when the object was created
HRESULT UPnP::OpenPorts(bool log) {
	CoInitializeEx ( NULL ,COINIT_MULTITHREADED);
	HRESULT hr = CoCreateInstance (__uuidof(UPnPNAT),
		NULL,
		CLSCTX_INPROC_SERVER,
		__uuidof(IUPnPNAT),
		(void**)&pUN);

	if(SUCCEEDED(hr)) {
		IStaticPortMappingCollection * pSPMC = NULL;
		hr = pUN->get_StaticPortMappingCollection (&pSPMC);
		int counter=0;
		while(SUCCEEDED(hr) && !pSPMC && counter<20)
		{
			debug("Retry StaticPortMappingCollection");
			hr = pUN->get_StaticPortMappingCollection (&pSPMC);
			counter++;
			Sleep(1500);
		}
		if(SUCCEEDED(hr) && pSPMC) {
			// see comment in "else"
			if(bstrProtocol && bstrInternalClient && bstrDescription) {
				IStaticPortMapping * pSPM = NULL;
				hr = pSPMC->Add(PortNumber,
					bstrProtocol,
					PortNumber,
					bstrInternalClient,
					VARIANT_TRUE,
					bstrDescription,
					&pSPM
				);

				if(SUCCEEDED(hr)) {
					if(log)debug("UPNP: open port %i",PortNumber);
					PortsAreOpen = true;
				}
				else
				{
					if(log)debug("UpNP: fail %s, Ignore external IP",_com_error(hr).ErrorMessage());
				}
			} else {
				hr = E_OUTOFMEMORY;
				debug("UPNP: Failed ");
			}
		} else {
			debug("UPNP: Failed ");
			hr = E_FAIL;    // work around a known bug here:  in some error
			// conditions, get_SPMC NULLs out the pointer, but incorrectly returns a success code.
		}
		pUN->Release();
		pUN=NULL;
	}
	CoUninitialize();
	return hr;
}
Пример #5
0
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;
	}
}
Пример #6
0
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;
}
Пример #7
0
bool Mapper_WinUPnP::remove(const unsigned short port, const Protocol protocol) {
	IStaticPortMappingCollection* pSPMC = getStaticPortMappingCollection();
	if(!pSPMC)
		return false;

	/// @todo use a BSTR wrapper
	BSTR protocol_ = SysAllocString(Text::toT(protocols[protocol]).c_str());

	HRESULT hr = pSPMC->Remove(port, protocol_);
	pSPMC->Release();

	SysFreeString(protocol_);

	bool ret = SUCCEEDED(hr);
	if(ret && port == lastPort && protocol == lastProtocol) {
		lastPort = 0;
	}
	return ret;
}
Пример #8
0
bool UPNPCheckDlg::WinUPnP_remove(const unsigned short port, const string& protocol, IUPnPNAT* pUN)
{
#ifdef HAVE_NATUPNP_H
	IStaticPortMappingCollection* pSPMC = WinUPnP_getStaticPortMappingCollection(pUN);
	if (!pSPMC)
		return false;
		
	/// @todo use a BSTR wrapper
	BSTR protocol_ = SysAllocString(Text::toT(protocol).c_str());
	
	HRESULT hr = pSPMC->Remove(port, protocol_);
	safe_release(pSPMC);
	SysFreeString(protocol_);
	
	return SUCCEEDED(hr);
#else
	return false;
#endif
}
Пример #9
0
// Closes the UPnP ports defined when the object was created
HRESULT UPnP::ClosePorts(bool log) {
//	if(PortsAreOpen == false) {
//		return S_OK;
//	}

	HRESULT hr = E_FAIL;
	HRESULT hr2 = E_FAIL;

	CoInitializeEx ( NULL ,COINIT_MULTITHREADED);
	hr = CoCreateInstance (__uuidof(UPnPNAT),
		NULL,
		CLSCTX_INPROC_SERVER,
		__uuidof(IUPnPNAT),
		(void**)&pUN);

	if(SUCCEEDED(hr)) {

			if(bstrProtocol && bstrInternalClient && bstrDescription) {
				IStaticPortMappingCollection * pSPMC = NULL;
				hr2 = pUN->get_StaticPortMappingCollection (&pSPMC);

				if(SUCCEEDED(hr2) && pSPMC) {
					hr = pSPMC->Remove(PortNumber, bstrProtocol);
					if(SUCCEEDED(hr)) if(log)debug("UPNP: closed port %i",PortNumber);
					pSPMC->Release();
				}

				SysFreeString(bstrProtocol);
				SysFreeString(bstrInternalClient);
				SysFreeString(bstrDescription);
				SysFreeString(bstrExternalIP);
			}
			pUN->Release();
			pUN=NULL;
	}
	CoUninitialize();
	return hr;
}
Пример #10
0
/**
 *  Erstellt per UPnP ein Portforwarding.
 *
 *  @author FloSoft
 */
bool UPnP::OpenPort(const unsigned short& port)
{
    if(remote_port_ != 0)
        ClosePort();

    remote_port_ = port;

#ifdef _MSC_VER
    HRESULT hr;

    CoInitialize(NULL);

    IUPnPNAT* upnpnat;
    hr = CoCreateInstance (CLSID_UPnPNAT, NULL, CLSCTX_INPROC_SERVER, IID_IUPnPNAT, (void**)&upnpnat);
    if(FAILED(hr) || !upnpnat)
    {
        if(!upnpnat)
            hr = E_NOINTERFACE;
        SetLastError(hr);
        return false;
    }

    IStaticPortMappingCollection* upnpspmc = NULL;
    hr = upnpnat->get_StaticPortMappingCollection(&upnpspmc);
    if(FAILED(hr) || !upnpspmc)
    {
        if(!upnpspmc)
            hr = E_NOINTERFACE;
        SetLastError(hr);
        return false;
    }

    std::string local_address;
    std::vector<std::string> addresses = GetAllv4Addresses();

    // if we have multiple addresses, search the private one
    if(addresses.size() > 1)
    {
        for(std::vector<std::string>::iterator addr = addresses.begin(); addr != addresses.end(); ++addr)
        {
            std::string ss = *addr;
            std::stringstream s, sc;
            s << ss;
            std::getline(s, ss, '.');
            sc << ss << " ";
            std::getline(s, ss, '.');
            sc << ss << " ";

            int a, b;
            sc >> a;
            sc >> b;

            int ab = (a << 24) | (b << 16);

            if( (ab & 0xff000000) == 0x0a000000 || // 10.0.0.0/8
                    (ab & 0xff000000) == 0x7f000000 || // 127.0.0.0/8
                    (ab & 0xfff00000) == 0xac100000 || // 172.16.0.0/12
                    (ab & 0xffff0000) == 0xc0a80000 )  // 192.168.0.0/16
                local_address = *addr;
        }
    }

    // otherwise use the first one
    if(local_address == "" && !addresses.empty())
        local_address = addresses.front();

    // I hope we found one ...
    if(local_address == "")
    {
        SetLastError(E_FAIL);
        return false;
    }

    BSTR bstrProtocol = A2BSTR("TCP");
    BSTR bstrLocalAddress = A2BSTR(local_address.c_str());
    BSTR bstrDescription = A2BSTR("Return To The Roots");

    IStaticPortMapping* upnpspm = NULL;
    hr = upnpspmc->Add(port, bstrProtocol, port, bstrLocalAddress, VARIANT_TRUE, bstrDescription, &upnpspm);

    SysFreeString(bstrProtocol);
    SysFreeString(bstrLocalAddress);
    SysFreeString(bstrDescription);

    if(SUCCEEDED(hr) && !upnpspm)
        hr = E_NOINTERFACE;

    SetLastError(hr);

    if(SUCCEEDED(hr) && upnpspm)
        return true;
#else
    int hr;
    UPNPDev* devicelist = NULL;
#ifdef UPNPDISCOVER_SUCCESS
    int upnperror = 0;
    devicelist = upnpDiscover(2000, NULL, NULL, 0, 0 /* ipv6 */, &upnperror);
#else
    devicelist = upnpDiscover(2000, NULL, NULL, 0);
#endif
    if(!devicelist)
        return false;

    UPNPUrls urls;
    IGDdatas data;
    char lanAddr[64];
    hr = UPNP_GetValidIGD(devicelist, &urls, &data, lanAddr, sizeof(lanAddr));

    if(hr == 1 || hr == 2)
    {
        std::stringstream p;
        p << port;

#ifdef UPNPDISCOVER_SUCCESS
        hr = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype, p.str().c_str(), p.str().c_str(), lanAddr, "Return To The Roots", "TCP", NULL, NULL);
#else
        hr = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype, p.str().c_str(), p.str().c_str(), lanAddr, "Return To The Roots", "TCP", NULL);
#endif
    }

    freeUPNPDevlist(devicelist);

    if(hr == 0)
        return true;
#endif
    return false;
}
Пример #11
0
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;
}
Пример #12
0
// 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;
}
Пример #13
0
// 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;
}
Пример #14
0
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;
}