976 lines
23 KiB
C++
976 lines
23 KiB
C++
//+---------------------------------------------------------------------------
|
|
//
|
|
// Microsoft Windows
|
|
// Copyright (C) Microsoft Corporation, 2001
|
|
//
|
|
// File : CNATStaticPortMappingService.cpp
|
|
//
|
|
// Contents : CNATStaticPortMappingService implementation
|
|
//
|
|
// Notes :
|
|
//
|
|
// Author : savasg 28 February 2001
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
#include "pch.h"
|
|
#pragma hdrstop
|
|
|
|
#include "CNATStaticPortMappingService.h"
|
|
|
|
#include "ipnat.h"
|
|
#include "winsock2.h"
|
|
#include "debug.h"
|
|
|
|
|
|
|
|
|
|
//
|
|
// GLOBALS
|
|
//
|
|
IHNetIcsSettings* g_IcsSettingsp = NULL;
|
|
|
|
|
|
|
|
HRESULT
|
|
SeekPortMapping(
|
|
IN OPTIONAL LPOLESTR searchNamep,
|
|
IN OPTIONAL USHORT searchPort,
|
|
OUT IHNetPortMappingProtocol **Protocolpp
|
|
)
|
|
//
|
|
// Seeks and retrieves a MappingProtocol by Name or Port
|
|
//
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
IHNetProtocolSettings* ProtocolSettingsp = NULL;
|
|
|
|
IEnumHNetPortMappingProtocols* EnumProtocolsp = NULL;
|
|
|
|
IHNetPortMappingProtocol* Protocolp = NULL;
|
|
|
|
LPOLESTR ProtocolNamep = NULL;
|
|
|
|
USHORT ProtocolPort = 0;
|
|
|
|
BOOLEAN bFound = FALSE;
|
|
|
|
DBG_SPEW(TM_STATIC, TL_ERROR, L" > SeekPortMapping \n");
|
|
|
|
do
|
|
{
|
|
hr = g_IcsSettingsp->QueryInterface(IID_IHNetProtocolSettings,
|
|
reinterpret_cast<void**>(&ProtocolSettingsp));
|
|
|
|
if( FAILED(hr) )
|
|
{
|
|
DBG_SPEW(TM_STATIC, TL_ERROR, L"Query Interface failed for ProtocolSettingsp e:%X", hr);
|
|
|
|
break;
|
|
}
|
|
|
|
hr = ProtocolSettingsp->EnumPortMappingProtocols(&EnumProtocolsp);
|
|
|
|
if ( FAILED(hr) )
|
|
{
|
|
DBG_SPEW(TM_STATIC, TL_ERROR, L"Enum Interface can't be retrieved \n");
|
|
|
|
break;
|
|
}
|
|
|
|
while(
|
|
(FALSE == bFound) &&
|
|
(S_OK == EnumProtocolsp->Next(1, &Protocolp, NULL))
|
|
)
|
|
{
|
|
hr = Protocolp->GetName(&ProtocolNamep);
|
|
|
|
if( FAILED(hr) )
|
|
{
|
|
DBG_SPEW(TM_STATIC, TL_ERROR, L"problemo name\n");
|
|
}
|
|
|
|
|
|
hr = Protocolp->GetPort(&ProtocolPort);
|
|
|
|
if( FAILED(hr) )
|
|
{
|
|
DBG_SPEW(TM_STATIC, TL_ERROR, L" problemo ");
|
|
|
|
break;
|
|
}
|
|
|
|
if(searchNamep &&
|
|
!( wcscmp(ProtocolNamep, searchNamep) )
|
|
)
|
|
{
|
|
DBG_SPEW(TM_STATIC, TL_ERROR, L"The Name is hit %S\n", searchNamep);
|
|
|
|
bFound = TRUE;
|
|
}
|
|
|
|
if(searchPort &&
|
|
(searchPort == ProtocolPort))
|
|
{
|
|
bFound = TRUE;
|
|
}
|
|
|
|
CoTaskMemFree(ProtocolNamep);
|
|
|
|
ProtocolNamep = NULL;
|
|
|
|
if (FALSE == bFound) Protocolp->Release();
|
|
}
|
|
|
|
EnumProtocolsp->Release();
|
|
|
|
} while ( FALSE );
|
|
|
|
if(ProtocolSettingsp != NULL)
|
|
{
|
|
ProtocolSettingsp->Release();
|
|
}
|
|
|
|
if(Protocolpp && (bFound == TRUE) )
|
|
{
|
|
*Protocolpp = Protocolp;
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
HRESULT
|
|
DeleteMappingByName(LPOLESTR ProtocolNamep)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
IHNetPortMappingProtocol* Protocolp = NULL;
|
|
|
|
DBG_SPEW(TM_STATIC, TL_ERROR, L" > DeleteMappingByName \n");
|
|
|
|
do
|
|
{
|
|
if(ProtocolNamep == NULL)
|
|
{
|
|
break;
|
|
}
|
|
|
|
hr = SeekPortMapping(ProtocolNamep,
|
|
0,
|
|
&Protocolp);
|
|
if( FAILED(hr) ||
|
|
(Protocolp == NULL))
|
|
{
|
|
DBG_SPEW(TM_STATIC, TL_ERROR, L"No Such Protocol %S: %X", ProtocolNamep, hr);
|
|
|
|
break;
|
|
}
|
|
|
|
DBG_SPEW(TM_STATIC, TL_ERROR, L"DELETING\n");
|
|
|
|
hr = Protocolp->Delete();
|
|
|
|
Protocolp->Release();
|
|
|
|
} while ( FALSE );
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
CNATStaticPortMappingService::CNATStaticPortMappingService()
|
|
{
|
|
m_pEventSink = NULL;
|
|
|
|
m_pHNetConnection = NULL;
|
|
}
|
|
|
|
HRESULT CNATStaticPortMappingService::FinalConstruct()
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
return hr;
|
|
}
|
|
|
|
HRESULT CNATStaticPortMappingService::FinalRelease()
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
if(NULL != m_pHNetConnection)
|
|
{
|
|
m_pHNetConnection->Release();
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
HRESULT
|
|
CNATStaticPortMappingService::Initialize(IHNetConnection* pHNetConnection)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
|
|
Arguments:
|
|
|
|
none
|
|
|
|
Return Value:
|
|
|
|
none
|
|
|
|
--*/
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
IHNetConnection* HomenetConnectionp = NULL;
|
|
|
|
IEnumHNetIcsPublicConnections* EnumIcsPublicConnectionsp = NULL;
|
|
|
|
IHNetIcsPublicConnection* PublicConnectionp = NULL;
|
|
|
|
DBG_SPEW(TM_STATIC, TL_ERROR, L" > Initialize \n");
|
|
|
|
do
|
|
{
|
|
hr = CoCreateInstance(CLSID_HNetCfgMgr,
|
|
NULL,
|
|
CLSCTX_SERVER,
|
|
IID_IHNetIcsSettings,
|
|
reinterpret_cast<void**>(&g_IcsSettingsp));
|
|
|
|
if( FAILED(hr) )
|
|
{
|
|
DBG_SPEW(TM_STATIC, TL_ERROR, L" CoCreateInstance for IID_IHNetIcsSettings failed \n");
|
|
|
|
break;
|
|
}
|
|
|
|
//
|
|
// Get the Enumeration Interface
|
|
//
|
|
hr = g_IcsSettingsp->EnumIcsPublicConnections(&EnumIcsPublicConnectionsp);
|
|
|
|
if( FAILED(hr) )
|
|
{
|
|
DBG_SPEW(TM_STATIC, TL_ERROR, L"Getting Interface for Enumeration of Public Connections has failed \n");
|
|
|
|
break;
|
|
}
|
|
|
|
//
|
|
// Find the Interface .. for now there is only one Public Interface
|
|
// This is not the RRAS case
|
|
//
|
|
hr = EnumIcsPublicConnectionsp->Next(1,
|
|
&PublicConnectionp,
|
|
NULL);
|
|
if( FAILED(hr) )
|
|
{
|
|
DBG_SPEW(TM_STATIC, TL_ERROR, L"There is no Public Connection.. how come?\n");
|
|
|
|
break;
|
|
}
|
|
|
|
|
|
hr = PublicConnectionp->QueryInterface(IID_IHNetConnection,
|
|
reinterpret_cast<void**>(&HomenetConnectionp));
|
|
|
|
_ASSERT( SUCCEEDED(hr) );
|
|
|
|
if( FAILED(hr) )
|
|
{
|
|
EnumIcsPublicConnectionsp->Release();
|
|
|
|
PublicConnectionp->Release();
|
|
|
|
DBG_SPEW(TM_STATIC, TL_ERROR, L"Can't Get the IID_IHNetConnection Interface from the Public Connection\n");
|
|
|
|
break;
|
|
}
|
|
|
|
} while( FALSE );
|
|
|
|
//
|
|
// Release the Ref counts
|
|
//
|
|
if(PublicConnectionp != NULL)
|
|
{
|
|
PublicConnectionp->Release();
|
|
}
|
|
|
|
if(EnumIcsPublicConnectionsp != NULL)
|
|
{
|
|
EnumIcsPublicConnectionsp->Release();
|
|
}
|
|
|
|
m_pHNetConnection = HomenetConnectionp;
|
|
|
|
/* Instead of Using the existing
|
|
m_pHNetConnection = pHNetConnection;
|
|
m_pHNetConnection->AddRef();
|
|
*/
|
|
return hr;
|
|
}
|
|
|
|
|
|
HRESULT CNATStaticPortMappingService::Advise(IUPnPEventSink* pesSubscriber)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
m_pEventSink = pesSubscriber;
|
|
|
|
m_pEventSink->AddRef();
|
|
|
|
return hr;
|
|
}
|
|
|
|
HRESULT CNATStaticPortMappingService::Unadvise(IUPnPEventSink* pesSubscriber)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
m_pEventSink->Release();
|
|
|
|
m_pEventSink = NULL;
|
|
|
|
return hr;
|
|
}
|
|
|
|
HRESULT CNATStaticPortMappingService::get_StaticPortDescriptionList(BSTR* pStaticPortDescriptionList)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
*pStaticPortDescriptionList = NULL;
|
|
|
|
typedef struct tagNameEnablePair
|
|
{
|
|
LIST_ENTRY LinkField;
|
|
LPOLESTR pName;
|
|
ULONG ulNameSize;
|
|
BOOLEAN bEnabled;
|
|
} NameEnablePair;
|
|
|
|
LIST_ENTRY PairList;
|
|
InitializeListHead(&PairList);
|
|
|
|
// First construct a linklist of NameEnablePairs with the info needed
|
|
|
|
IEnumHNetPortMappingBindings *pBindingEnum = NULL;
|
|
hr = m_pHNetConnection->EnumPortMappings(FALSE, &pBindingEnum);
|
|
if(SUCCEEDED(hr))
|
|
{
|
|
IHNetPortMappingBinding* pBinding;
|
|
while(S_OK == pBindingEnum->Next(1, &pBinding, NULL))
|
|
{
|
|
BOOLEAN bEnabled;
|
|
|
|
hr = pBinding->GetEnabled(&bEnabled);
|
|
if(SUCCEEDED(hr))
|
|
{
|
|
IHNetPortMappingProtocol* pProtocol;
|
|
hr = pBinding->GetProtocol(&pProtocol);
|
|
if(SUCCEEDED(hr))
|
|
{
|
|
LPOLESTR pName;
|
|
hr = pProtocol->GetName(&pName);
|
|
if(SUCCEEDED(hr))
|
|
{
|
|
NameEnablePair* pPair = new NameEnablePair;
|
|
if(NULL != pPair)
|
|
{
|
|
pPair->pName = pName;
|
|
pPair->bEnabled = bEnabled;
|
|
|
|
InsertTailList(&PairList, &pPair->LinkField);
|
|
}
|
|
//CoTaskMemFree(pName);
|
|
}
|
|
pProtocol->Release();
|
|
}
|
|
}
|
|
pBinding->Release();
|
|
}
|
|
pBindingEnum->Release();
|
|
}
|
|
|
|
|
|
LIST_ENTRY* pCount;
|
|
NameEnablePair* pContainingPair;
|
|
|
|
if(SUCCEEDED(hr))
|
|
{
|
|
// Count the space needed in the return string
|
|
|
|
unsigned int uSizeNeeded = 0;
|
|
pCount = PairList.Flink;
|
|
while(&PairList != pCount)
|
|
{
|
|
pContainingPair = CONTAINING_RECORD(pCount, NameEnablePair, LinkField);
|
|
pContainingPair->ulNameSize = lstrlen(pContainingPair->pName);
|
|
uSizeNeeded += 3 + pContainingPair->ulNameSize; //Name:1,
|
|
pCount = pCount->Flink;
|
|
}
|
|
|
|
BSTR pReturnString;
|
|
if(0 != uSizeNeeded)
|
|
{
|
|
pReturnString = SysAllocStringLen(NULL, uSizeNeeded);
|
|
}
|
|
else
|
|
{
|
|
pReturnString = SysAllocString(L"");
|
|
}
|
|
|
|
if(NULL != pReturnString)
|
|
{
|
|
*pStaticPortDescriptionList = pReturnString;
|
|
|
|
// Fill in the string
|
|
pCount = PairList.Flink;
|
|
while(&PairList != pCount)
|
|
{
|
|
pContainingPair = CONTAINING_RECORD(pCount, NameEnablePair, LinkField);
|
|
|
|
|
|
lstrcpy(pReturnString, pContainingPair->pName);
|
|
pReturnString += pContainingPair->ulNameSize;
|
|
|
|
*pReturnString = L':';
|
|
pReturnString++;
|
|
|
|
*pReturnString = pContainingPair->bEnabled ? L'1' : L'0';
|
|
pReturnString++;
|
|
|
|
*pReturnString = (&PairList == pCount->Flink) ? L'\0' : L',';
|
|
pReturnString++;
|
|
|
|
pCount = pCount->Flink;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
hr = E_OUTOFMEMORY;
|
|
}
|
|
|
|
}
|
|
|
|
// Clean up the linked list
|
|
pCount = PairList.Flink;
|
|
while(&PairList != pCount)
|
|
{
|
|
NameEnablePair* pDelete = CONTAINING_RECORD(pCount, NameEnablePair, LinkField);
|
|
pCount = pCount->Flink;
|
|
CoTaskMemFree(pDelete->pName);
|
|
delete pDelete;
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
HRESULT CNATStaticPortMappingService::get_StaticPort(ULONG* pulStaticPort)
|
|
{
|
|
return E_UNEXPECTED;
|
|
}
|
|
|
|
HRESULT CNATStaticPortMappingService::get_StaticPortProtocol(BSTR* pStaticPortProtocol)
|
|
{
|
|
*pStaticPortProtocol = NULL;
|
|
return E_UNEXPECTED;
|
|
}
|
|
|
|
HRESULT CNATStaticPortMappingService::get_StaticPortClient(BSTR* pStaticPortClient)
|
|
{
|
|
*pStaticPortClient = NULL;
|
|
return E_UNEXPECTED;
|
|
}
|
|
|
|
HRESULT CNATStaticPortMappingService::get_StaticPortEnable(VARIANT_BOOL* pbStaticPortEnable)
|
|
{
|
|
return E_UNEXPECTED;
|
|
}
|
|
|
|
HRESULT CNATStaticPortMappingService::get_StaticPortDescription(BSTR* pStaticPortDescription)
|
|
{
|
|
*pStaticPortDescription = NULL;
|
|
return E_UNEXPECTED;
|
|
}
|
|
|
|
HRESULT CNATStaticPortMappingService::GetStaticPortMappingList(BSTR* pStaticPortMappingList)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
SysFreeString(*pStaticPortMappingList);
|
|
|
|
*pStaticPortMappingList = NULL;
|
|
|
|
hr = get_StaticPortDescriptionList(pStaticPortMappingList);
|
|
|
|
return hr;
|
|
}
|
|
|
|
HRESULT
|
|
CNATStaticPortMappingService::GetStaticPortMapping(
|
|
BSTR StaticPortMappingDescription,
|
|
ULONG* pulStaticPort,
|
|
BSTR* pStaticPortClient,
|
|
BSTR* pStaticPortProtocol
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Retrieves the Port, Client Name/Address and the Protocol for a given
|
|
Mapping (redirect in NAT context)... Note that a Binding may not exist
|
|
for a Mapping.. Thus There might not be a Client Name/Address.
|
|
|
|
Arguments:
|
|
|
|
none
|
|
|
|
Return Value:
|
|
|
|
none
|
|
|
|
--*/
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
IHNetPortMappingProtocol* Protocolp = NULL;
|
|
|
|
IHNetPortMappingBinding* Bindingp = NULL;
|
|
|
|
LPOLESTR ClientNamep = NULL;
|
|
|
|
ULONG ClientAddress = 0;
|
|
|
|
USHORT ProtocolPort = 0;
|
|
|
|
UCHAR ProtocolType = 0;
|
|
|
|
|
|
|
|
DBG_SPEW(TM_STATIC, TL_ERROR, L" > GetStaticPortMapping");
|
|
|
|
_ASSERT( StaticPortMappingDescription != NULL );
|
|
_ASSERT( pulStaticPort != NULL );
|
|
_ASSERT( pStaticPortClient != NULL );
|
|
_ASSERT( pStaticPortProtocol != NULL );
|
|
|
|
SysFreeString(*pStaticPortClient);
|
|
|
|
SysFreeString(*pStaticPortProtocol);
|
|
|
|
*pStaticPortClient = NULL;
|
|
|
|
*pStaticPortProtocol = NULL;
|
|
|
|
do
|
|
{
|
|
hr = SeekPortMapping((LPOLESTR)StaticPortMappingDescription,
|
|
0,
|
|
&Protocolp);
|
|
|
|
if( FAILED(hr) )
|
|
{
|
|
DBG_SPEW(TM_STATIC, TL_ERROR, L"There is no such Port Mapping");
|
|
|
|
break;
|
|
}
|
|
|
|
hr = Protocolp->GetPort(&ProtocolPort); //USHORT
|
|
|
|
_ASSERT( SUCCEEDED(hr) );
|
|
|
|
*pulStaticPort = ProtocolPort;
|
|
|
|
//
|
|
// Get the Type of the Protocol Mapping and put the appropriate
|
|
// String
|
|
//
|
|
hr = Protocolp->GetIPProtocol(&ProtocolType); //UCHAR
|
|
|
|
_ASSERT( SUCCEEDED(hr) );
|
|
|
|
if ( ProtocolType == NAT_PROTOCOL_TCP )
|
|
{
|
|
*pStaticPortProtocol = SysAllocString(L"TCP");
|
|
}
|
|
else if ( ProtocolType == NAT_PROTOCOL_UDP )
|
|
{
|
|
*pStaticPortProtocol = SysAllocString(L"UDP");
|
|
}
|
|
else
|
|
{
|
|
_ASSERT( FALSE );
|
|
}
|
|
|
|
|
|
//
|
|
// A Binding may not exist.. That's Ok..
|
|
//
|
|
hr = m_pHNetConnection->GetBindingForPortMappingProtocol(Protocolp, &Bindingp);
|
|
|
|
if ( FAILED(hr) )
|
|
{
|
|
DBG_SPEW(TM_STATIC, TL_ERROR, L" No Such Binding for that protocol.");
|
|
|
|
hr = S_OK;
|
|
|
|
break;
|
|
}
|
|
|
|
//
|
|
// If the Address exist just process that.
|
|
// Convert the Name to a OLESTR
|
|
//
|
|
hr = Bindingp->GetTargetComputerAddress(&ClientAddress);
|
|
|
|
if ( SUCCEEDED(hr) )
|
|
{
|
|
ClientNamep = (LPOLESTR) CoTaskMemAlloc( (wcslen(INET_NTOW(ClientAddress)) + 1) * sizeof(WCHAR) );
|
|
|
|
_ASSERT(ClientNamep != NULL);
|
|
|
|
wcscpy( ClientNamep, INET_NTOW(ClientAddress) );
|
|
}
|
|
else
|
|
{
|
|
hr = Bindingp->GetTargetComputerName(&ClientNamep);
|
|
}
|
|
|
|
if( FAILED( hr ) || (ClientNamep == NULL))
|
|
{
|
|
DBG_SPEW(TM_STATIC, TL_ERROR, L"Can't Retrieve Name or Address of Client from Binding ");
|
|
|
|
break;
|
|
}
|
|
|
|
*pStaticPortClient = SysAllocString( ClientNamep );
|
|
|
|
if (*pStaticPortClient == NULL)
|
|
{
|
|
hr = E_OUTOFMEMORY;
|
|
}
|
|
|
|
} while ( FALSE );
|
|
|
|
if ( ClientNamep != NULL)
|
|
{
|
|
CoTaskMemFree( ClientNamep );
|
|
}
|
|
|
|
if ( Bindingp != NULL)
|
|
{
|
|
Bindingp->Release();
|
|
}
|
|
|
|
if ( Protocolp != NULL )
|
|
{
|
|
Protocolp->Release();
|
|
}
|
|
|
|
//
|
|
// If there was a failure then clear up the allocated Strings
|
|
//
|
|
if ( FAILED(hr) && ( *pStaticPortProtocol != NULL ) )
|
|
{
|
|
SysFreeString( *pStaticPortProtocol );
|
|
|
|
*pStaticPortProtocol = NULL;
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
HRESULT
|
|
CNATStaticPortMappingService::SetStaticPortMappingEnabled(
|
|
BSTR StaticPortMappingDescription,
|
|
VARIANT_BOOL bStaticPortEnable
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
|
|
Arguments:
|
|
|
|
none
|
|
|
|
Return Value:
|
|
|
|
none
|
|
|
|
--*/
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
IHNetPortMappingProtocol* Protocolp = NULL;
|
|
|
|
IHNetPortMappingBinding* Bindingp = NULL;
|
|
|
|
|
|
|
|
DBG_SPEW(TM_STATIC, TL_ERROR, L" > SetStaticPortMappingEnabled");
|
|
|
|
do
|
|
{
|
|
hr = SeekPortMapping((LPOLESTR)StaticPortMappingDescription,
|
|
NULL,
|
|
&Protocolp);
|
|
|
|
if( FAILED(hr) )
|
|
{
|
|
DBG_SPEW(TM_STATIC, TL_ERROR, L"There is no such Port Mapping");
|
|
|
|
break;
|
|
}
|
|
|
|
hr = m_pHNetConnection->GetBindingForPortMappingProtocol(Protocolp, &Bindingp);
|
|
|
|
if ( FAILED(hr) )
|
|
{
|
|
DBG_SPEW(TM_STATIC, TL_ERROR, L" No Such Binding for that protocol.");
|
|
|
|
break;
|
|
}
|
|
|
|
if ( VARIANT_TRUE == bStaticPortEnable )
|
|
{
|
|
hr = Bindingp->SetEnabled(TRUE);
|
|
}
|
|
else if ( VARIANT_FALSE == bStaticPortEnable )
|
|
{
|
|
hr = Bindingp->SetEnabled(FALSE);
|
|
}
|
|
|
|
_ASSERT( SUCCEEDED(hr) );
|
|
|
|
} while ( FALSE );
|
|
|
|
if (Protocolp != NULL)
|
|
{
|
|
Protocolp->Release();
|
|
}
|
|
|
|
if (Bindingp != NULL)
|
|
{
|
|
Bindingp->Release();
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
HRESULT
|
|
CNATStaticPortMappingService::CreateStaticPortMapping(
|
|
BSTR StaticPortMappingDescription,
|
|
ULONG ulStaticPort,
|
|
BSTR StaticPortClient,
|
|
BSTR StaticPortProtocol
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
|
|
Arguments:
|
|
|
|
none
|
|
|
|
Return Value:
|
|
|
|
none
|
|
|
|
--*/
|
|
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
UCHAR ProtocolType = 0;
|
|
|
|
IHNetProtocolSettings* ProtocolSettingsp = NULL;
|
|
|
|
IHNetPortMappingProtocol* PortMappingProtocolp = NULL;
|
|
|
|
IHNetPortMappingBinding* PortMappingBindingp = NULL;
|
|
|
|
ULONG ClientAddr = 0;
|
|
|
|
|
|
ASSERT( StaticPortMappingDescription != NULL );
|
|
ASSERT( ulStaticPort == 0 );
|
|
// ASSERT( StaticPortClient != NULL );
|
|
ASSERT( StaticPortProtocol );
|
|
|
|
DBG_SPEW(TM_STATIC, TL_ERROR, L" > CreateStaticPortMapping");
|
|
|
|
//
|
|
// Check and transform the Protocol Value to its correct type.
|
|
//
|
|
if( wcscmp(StaticPortProtocol, L"TCP") == 0)
|
|
{
|
|
ProtocolType = NAT_PROTOCOL_TCP;
|
|
}
|
|
else if ( wcscmp(StaticPortProtocol, L"UDP") == 0)
|
|
{
|
|
ProtocolType = NAT_PROTOCOL_UDP;
|
|
}
|
|
else
|
|
{
|
|
DBG_SPEW(TM_STATIC, TL_ERROR, L"Unknown Protocol Type\n");
|
|
|
|
_ASSERT(FALSE);
|
|
|
|
return E_INVALIDARG;
|
|
}
|
|
|
|
do
|
|
{
|
|
hr = g_IcsSettingsp->QueryInterface(IID_IHNetProtocolSettings,
|
|
reinterpret_cast<void**>(&ProtocolSettingsp));
|
|
|
|
_ASSERT( SUCCEEDED(hr) );
|
|
|
|
if( FAILED(hr) )
|
|
{
|
|
break;
|
|
}
|
|
|
|
|
|
hr = ProtocolSettingsp->CreatePortMappingProtocol((LPOLESTR)StaticPortMappingDescription,
|
|
ProtocolType,
|
|
(USHORT)ulStaticPort,
|
|
&PortMappingProtocolp);
|
|
|
|
if( FAILED(hr) )
|
|
{
|
|
DBG_SPEW(TM_STATIC, TL_ERROR, L"Creating the PortMapping has failed");
|
|
|
|
break;
|
|
}
|
|
|
|
//
|
|
// If there is no
|
|
//
|
|
if ( StaticPortClient != NULL )
|
|
{
|
|
hr = m_pHNetConnection->GetBindingForPortMappingProtocol(PortMappingProtocolp,
|
|
&PortMappingBindingp);
|
|
|
|
if( FAILED(hr) )
|
|
{
|
|
DBG_SPEW(TM_STATIC, TL_ERROR, L" GetBinding for PORT Mapping has failed ");
|
|
|
|
break;
|
|
}
|
|
|
|
//
|
|
// Decide wether the given address is a Name or an valid IP address
|
|
// ient_addrw will return an INADDR_NONE if the address is not
|
|
// decimal doted IP address
|
|
//
|
|
ClientAddr = INET_ADDR((LPOLESTR)StaticPortClient);
|
|
|
|
if( ClientAddr == INADDR_NONE)
|
|
{
|
|
hr = PortMappingBindingp->SetTargetComputerName(StaticPortClient);
|
|
|
|
_ASSERT( SUCCEEDED(hr) );
|
|
}
|
|
else
|
|
{
|
|
hr = PortMappingBindingp->SetTargetComputerAddress(ClientAddr);
|
|
|
|
_ASSERT( SUCCEEDED(hr) );
|
|
}
|
|
|
|
//
|
|
// It creates it enabled
|
|
//
|
|
hr = PortMappingBindingp->SetEnabled(TRUE);
|
|
}
|
|
} while (FALSE);
|
|
|
|
if( PortMappingProtocolp != NULL)
|
|
{
|
|
PortMappingProtocolp->Release();
|
|
}
|
|
|
|
if( ProtocolSettingsp != NULL)
|
|
{
|
|
ProtocolSettingsp->Release();
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
HRESULT
|
|
CNATStaticPortMappingService::DeleteStaticPortMapping(BSTR StaticPortMappingDescription)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
|
|
Arguments:
|
|
|
|
none
|
|
|
|
Return Value:
|
|
|
|
none
|
|
|
|
--*/
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
DBG_SPEW(TM_STATIC, TL_ERROR, L"> DeleteStaticPortMapping");
|
|
|
|
_ASSERT( StaticPortMappingDescription != NULL );
|
|
|
|
hr = DeleteMappingByName( (LPOLESTR) StaticPortMappingDescription );
|
|
|
|
return hr;
|
|
}
|
|
|
|
HRESULT
|
|
CNATStaticPortMappingService::SetStaticPortMapping(
|
|
BSTR StaticPortMappingDescription,
|
|
ULONG ulStaticPort,
|
|
BSTR StaticPortClient,
|
|
BSTR StaticPortProtocol
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
|
|
Arguments:
|
|
|
|
none
|
|
|
|
Return Value:
|
|
|
|
none
|
|
|
|
--*/
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
hr = DeleteMappingByName((LPOLESTR) StaticPortMappingDescription);
|
|
|
|
if ( SUCCEEDED(hr) )
|
|
{
|
|
hr = this->CreateStaticPortMapping(StaticPortMappingDescription,
|
|
ulStaticPort,
|
|
StaticPortClient,
|
|
StaticPortProtocol);
|
|
|
|
_ASSERT( SUCCEEDED(hr) );
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|