hnetcfg: Implement static_ports__NewEnum().
Signed-off-by: Paul Gofman <pgofman@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
7ed9fb0a68
commit
de05efdea2
|
@ -735,6 +735,22 @@ static BOOL find_port_mapping( LONG port, BSTR protocol, struct port_mapping *re
|
||||||
return found;
|
return found;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static unsigned int get_port_mapping_range( unsigned int index, unsigned int count, struct port_mapping *ret )
|
||||||
|
{
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
AcquireSRWLockExclusive( &upnp_gateway_connection_lock );
|
||||||
|
for (i = 0; i < count && index + i < upnp_gateway_connection.mapping_count; ++i)
|
||||||
|
if (!copy_port_mapping( &ret[i], &upnp_gateway_connection.mappings[index + i] ))
|
||||||
|
{
|
||||||
|
ERR( "No memory.\n" );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
ReleaseSRWLockExclusive( &upnp_gateway_connection_lock );
|
||||||
|
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
static unsigned int get_port_mapping_count(void)
|
static unsigned int get_port_mapping_count(void)
|
||||||
{
|
{
|
||||||
unsigned int ret;
|
unsigned int ret;
|
||||||
|
@ -1048,6 +1064,164 @@ static HRESULT static_port_mapping_create( const struct port_mapping *mapping_da
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct port_mapping_enum
|
||||||
|
{
|
||||||
|
IEnumVARIANT IEnumVARIANT_iface;
|
||||||
|
LONG refs;
|
||||||
|
unsigned int index;
|
||||||
|
};
|
||||||
|
|
||||||
|
static inline struct port_mapping_enum *impl_from_IEnumVARIANT( IEnumVARIANT *iface )
|
||||||
|
{
|
||||||
|
return CONTAINING_RECORD(iface, struct port_mapping_enum, IEnumVARIANT_iface);
|
||||||
|
}
|
||||||
|
|
||||||
|
static ULONG WINAPI port_mapping_enum_AddRef(
|
||||||
|
IEnumVARIANT *iface )
|
||||||
|
{
|
||||||
|
struct port_mapping_enum *mapping_enum = impl_from_IEnumVARIANT( iface );
|
||||||
|
return InterlockedIncrement( &mapping_enum->refs );
|
||||||
|
}
|
||||||
|
|
||||||
|
static ULONG WINAPI port_mapping_enum_Release(
|
||||||
|
IEnumVARIANT *iface )
|
||||||
|
{
|
||||||
|
struct port_mapping_enum *mapping_enum = impl_from_IEnumVARIANT( iface );
|
||||||
|
LONG refs = InterlockedDecrement( &mapping_enum->refs );
|
||||||
|
if (!refs)
|
||||||
|
{
|
||||||
|
TRACE("destroying %p\n", mapping_enum);
|
||||||
|
free( mapping_enum );
|
||||||
|
release_gateway_connection();
|
||||||
|
}
|
||||||
|
return refs;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT WINAPI port_mapping_enum_QueryInterface(
|
||||||
|
IEnumVARIANT *iface,
|
||||||
|
REFIID riid,
|
||||||
|
void **ppvObject )
|
||||||
|
{
|
||||||
|
struct port_mapping_enum *mapping_enum = impl_from_IEnumVARIANT( iface );
|
||||||
|
|
||||||
|
TRACE("%p %s %p\n", mapping_enum, debugstr_guid( riid ), ppvObject );
|
||||||
|
|
||||||
|
if ( IsEqualGUID( riid, &IID_IEnumVARIANT ) ||
|
||||||
|
IsEqualGUID( riid, &IID_IUnknown ) )
|
||||||
|
{
|
||||||
|
*ppvObject = iface;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
FIXME("interface %s not implemented\n", debugstr_guid(riid));
|
||||||
|
return E_NOINTERFACE;
|
||||||
|
}
|
||||||
|
IEnumVARIANT_AddRef( iface );
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT WINAPI port_mapping_enum_Next( IEnumVARIANT *iface, ULONG celt, VARIANT *var, ULONG *fetched )
|
||||||
|
{
|
||||||
|
struct port_mapping_enum *mapping_enum = impl_from_IEnumVARIANT( iface );
|
||||||
|
struct port_mapping *data;
|
||||||
|
IStaticPortMapping *pm;
|
||||||
|
unsigned int i, count;
|
||||||
|
HRESULT ret;
|
||||||
|
|
||||||
|
TRACE( "iface %p, celt %u, var %p, fetched %p.\n", iface, celt, var, fetched );
|
||||||
|
|
||||||
|
if (fetched) *fetched = 0;
|
||||||
|
if (!celt) return S_OK;
|
||||||
|
if (!var) return E_POINTER;
|
||||||
|
|
||||||
|
if (!(data = calloc( 1, celt * sizeof(*data) ))) return E_OUTOFMEMORY;
|
||||||
|
count = get_port_mapping_range( mapping_enum->index, celt, data );
|
||||||
|
TRACE( "count %u.\n", count );
|
||||||
|
for (i = 0; i < count; ++i)
|
||||||
|
{
|
||||||
|
if (FAILED(static_port_mapping_create( &data[i], &pm ))) break;
|
||||||
|
|
||||||
|
V_VT(&var[i]) = VT_DISPATCH;
|
||||||
|
V_DISPATCH(&var[i]) = (IDispatch *)pm;
|
||||||
|
}
|
||||||
|
mapping_enum->index += i;
|
||||||
|
if (fetched) *fetched = i;
|
||||||
|
ret = (i < celt) ? S_FALSE : S_OK;
|
||||||
|
for ( ; i < count; ++i)
|
||||||
|
{
|
||||||
|
free_port_mapping( &data[i] );
|
||||||
|
VariantInit( &var[i] );
|
||||||
|
}
|
||||||
|
for ( ; i < celt; ++i)
|
||||||
|
VariantInit( &var[i] );
|
||||||
|
|
||||||
|
free( data );
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT WINAPI port_mapping_enum_Skip( IEnumVARIANT *iface, ULONG celt )
|
||||||
|
{
|
||||||
|
struct port_mapping_enum *mapping_enum = impl_from_IEnumVARIANT( iface );
|
||||||
|
unsigned int count = get_port_mapping_count();
|
||||||
|
|
||||||
|
TRACE( "iface %p, celt %u.\n", iface, celt );
|
||||||
|
|
||||||
|
mapping_enum->index += celt;
|
||||||
|
return mapping_enum->index <= count ? S_OK : S_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT WINAPI port_mapping_enum_Reset( IEnumVARIANT *iface )
|
||||||
|
{
|
||||||
|
struct port_mapping_enum *mapping_enum = impl_from_IEnumVARIANT( iface );
|
||||||
|
|
||||||
|
TRACE( "iface %p.\n", iface );
|
||||||
|
|
||||||
|
mapping_enum->index = 0;
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT create_port_mapping_enum( IUnknown **ret );
|
||||||
|
|
||||||
|
static HRESULT WINAPI port_mapping_enum_Clone( IEnumVARIANT *iface, IEnumVARIANT **ret )
|
||||||
|
{
|
||||||
|
struct port_mapping_enum *mapping_enum = impl_from_IEnumVARIANT( iface );
|
||||||
|
HRESULT hr;
|
||||||
|
|
||||||
|
TRACE( "iface %p, ret %p.\n", iface, ret );
|
||||||
|
|
||||||
|
if (!ret) return E_POINTER;
|
||||||
|
*ret = NULL;
|
||||||
|
if (FAILED(hr = create_port_mapping_enum( (IUnknown **)ret ))) return hr;
|
||||||
|
impl_from_IEnumVARIANT( *ret )->index = mapping_enum->index;
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const IEnumVARIANTVtbl port_mapping_enum_vtbl =
|
||||||
|
{
|
||||||
|
port_mapping_enum_QueryInterface,
|
||||||
|
port_mapping_enum_AddRef,
|
||||||
|
port_mapping_enum_Release,
|
||||||
|
port_mapping_enum_Next,
|
||||||
|
port_mapping_enum_Skip,
|
||||||
|
port_mapping_enum_Reset,
|
||||||
|
port_mapping_enum_Clone,
|
||||||
|
};
|
||||||
|
|
||||||
|
static HRESULT create_port_mapping_enum( IUnknown **ret )
|
||||||
|
{
|
||||||
|
struct port_mapping_enum *mapping_enum;
|
||||||
|
|
||||||
|
if (!(mapping_enum = calloc( 1, sizeof(*mapping_enum) ))) return E_OUTOFMEMORY;
|
||||||
|
|
||||||
|
grab_gateway_connection();
|
||||||
|
|
||||||
|
mapping_enum->refs = 1;
|
||||||
|
mapping_enum->IEnumVARIANT_iface.lpVtbl = &port_mapping_enum_vtbl;
|
||||||
|
mapping_enum->index = 0;
|
||||||
|
*ret = (IUnknown *)&mapping_enum->IEnumVARIANT_iface;
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
struct static_port_mapping_collection
|
struct static_port_mapping_collection
|
||||||
{
|
{
|
||||||
IStaticPortMappingCollection IStaticPortMappingCollection_iface;
|
IStaticPortMappingCollection IStaticPortMappingCollection_iface;
|
||||||
|
@ -1183,11 +1357,12 @@ static HRESULT WINAPI static_ports__NewEnum(
|
||||||
IStaticPortMappingCollection *iface,
|
IStaticPortMappingCollection *iface,
|
||||||
IUnknown **ret )
|
IUnknown **ret )
|
||||||
{
|
{
|
||||||
FIXME( "iface %p, ret %p stub.\n", iface, ret );
|
TRACE( "iface %p, ret %p.\n", iface, ret );
|
||||||
|
|
||||||
if (ret) *ret = NULL;
|
if (!ret) return E_POINTER;
|
||||||
|
|
||||||
return E_NOTIMPL;
|
*ret = NULL;
|
||||||
|
return create_port_mapping_enum( ret );
|
||||||
}
|
}
|
||||||
|
|
||||||
static HRESULT WINAPI static_ports_get_Item(
|
static HRESULT WINAPI static_ports_get_Item(
|
||||||
|
|
|
@ -184,8 +184,7 @@ static void test_static_port_mapping_collection( IStaticPortMappingCollection *p
|
||||||
|
|
||||||
refcount = get_refcount((IUnknown *)ports);
|
refcount = get_refcount((IUnknown *)ports);
|
||||||
hr = IStaticPortMappingCollection_get__NewEnum(ports, &unk);
|
hr = IStaticPortMappingCollection_get__NewEnum(ports, &unk);
|
||||||
todo_wine ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
|
ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
|
||||||
if (FAILED(hr)) return;
|
|
||||||
|
|
||||||
hr = IUnknown_QueryInterface(unk, &IID_IEnumVARIANT, (void **)&enum_ports);
|
hr = IUnknown_QueryInterface(unk, &IID_IEnumVARIANT, (void **)&enum_ports);
|
||||||
ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
|
ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
|
||||||
|
@ -213,14 +212,14 @@ static void test_static_port_mapping_collection( IStaticPortMappingCollection *p
|
||||||
|
|
||||||
hr = IStaticPortMappingCollection_Add(ports, 12345, (BSTR)L"udp", 12345, (BSTR)L"1.2.3.4",
|
hr = IStaticPortMappingCollection_Add(ports, 12345, (BSTR)L"udp", 12345, (BSTR)L"1.2.3.4",
|
||||||
VARIANT_TRUE, (BSTR)L"wine_test", &pm);
|
VARIANT_TRUE, (BSTR)L"wine_test", &pm);
|
||||||
ok(hr == E_INVALIDARG, "Got unexpected hr %#x.\n", hr);
|
todo_wine ok(hr == E_INVALIDARG, "Got unexpected hr %#x.\n", hr);
|
||||||
hr = IStaticPortMappingCollection_Add(ports, 12345, (BSTR)L"UDP", 12345, (BSTR)L"1.2.3.4",
|
hr = IStaticPortMappingCollection_Add(ports, 12345, (BSTR)L"UDP", 12345, (BSTR)L"1.2.3.4",
|
||||||
VARIANT_TRUE, (BSTR)L"wine_test", &pm);
|
VARIANT_TRUE, (BSTR)L"wine_test", &pm);
|
||||||
ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
|
todo_wine ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
|
||||||
|
|
||||||
hr = IStaticPortMappingCollection_get_Count(ports, &count2);
|
hr = IStaticPortMappingCollection_get_Count(ports, &count2);
|
||||||
ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
|
ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
|
||||||
ok(count2 == expected_count, "Got unexpected count2 %u, expected %u.\n", count2, expected_count);
|
todo_wine ok(count2 == expected_count, "Got unexpected count2 %u, expected %u.\n", count2, expected_count);
|
||||||
|
|
||||||
hr = IStaticPortMappingCollection_get_Item(ports, 12345, NULL, &pm);
|
hr = IStaticPortMappingCollection_get_Item(ports, 12345, NULL, &pm);
|
||||||
ok(hr == E_INVALIDARG, "Got unexpected hr %#x.\n", hr);
|
ok(hr == E_INVALIDARG, "Got unexpected hr %#x.\n", hr);
|
||||||
|
@ -280,6 +279,8 @@ static void test_static_port_mapping_collection( IStaticPortMappingCollection *p
|
||||||
|
|
||||||
hr = IStaticPortMappingCollection_Remove(ports, 12345, (BSTR)L"UDP");
|
hr = IStaticPortMappingCollection_Remove(ports, 12345, (BSTR)L"UDP");
|
||||||
ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
|
ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
|
||||||
|
hr = IStaticPortMappingCollection_Remove(ports, 12345, (BSTR)L"UDP");
|
||||||
|
todo_wine ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
|
||||||
|
|
||||||
IEnumVARIANT_Release(enum_ports);
|
IEnumVARIANT_Release(enum_ports);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue