Paul Gofman : hnetcfg: Implement static_ports_Add().

Alexandre Julliard julliard at winehq.org
Wed Feb 2 16:38:02 CST 2022


Module: wine
Branch: master
Commit: 8f8fe74f89ec5e76e03d702e67dd3233d0b6af4c
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=8f8fe74f89ec5e76e03d702e67dd3233d0b6af4c

Author: Paul Gofman <pgofman at codeweavers.com>
Date:   Wed Feb  2 11:32:59 2022 +0300

hnetcfg: Implement static_ports_Add().

Signed-off-by: Paul Gofman <pgofman at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/hnetcfg/port.c         | 76 +++++++++++++++++++++++++++++++++++++++++++--
 dlls/hnetcfg/tests/policy.c |  6 ++--
 2 files changed, 76 insertions(+), 6 deletions(-)

diff --git a/dlls/hnetcfg/port.c b/dlls/hnetcfg/port.c
index 88816b7ee34..def77621764 100644
--- a/dlls/hnetcfg/port.c
+++ b/dlls/hnetcfg/port.c
@@ -638,6 +638,51 @@ static BOOL remove_port_mapping( LONG port, BSTR protocol )
     return ret;
 }
 
+static BOOL add_port_mapping( LONG external, BSTR protocol, LONG internal, BSTR client,
+                              VARIANT_BOOL enabled, BSTR description )
+{
+    struct xml_value_desc mapping_desc[PM_LAST];
+    WCHAR externalW[6], internalW[6];
+    DWORD status = 0;
+    BSTR error_str;
+    BOOL ret;
+
+    AcquireSRWLockExclusive( &upnp_gateway_connection_lock );
+    memcpy( mapping_desc, port_mapping_template, sizeof(mapping_desc) );
+    swprintf( externalW, ARRAY_SIZE(externalW), L"%u", external );
+    swprintf( internalW, ARRAY_SIZE(internalW), L"%u", internal );
+    mapping_desc[PM_EXTERNAL_IP].value = SysAllocString( L"" );
+    mapping_desc[PM_EXTERNAL].value = SysAllocString( externalW );
+    mapping_desc[PM_PROTOCOL].value = protocol;
+    mapping_desc[PM_INTERNAL].value = SysAllocString( internalW );
+    mapping_desc[PM_CLIENT].value = client;
+    mapping_desc[PM_ENABLED].value = SysAllocString( enabled ? L"1" : L"0" );
+    mapping_desc[PM_DESC].value = description;
+    mapping_desc[PM_LEASE_DURATION].value = SysAllocString( L"0" );
+
+    ret = request_service( L"AddPortMapping", mapping_desc, PM_LAST,
+                           NULL, 0, &status, &error_str );
+    if (ret && status != HTTP_STATUS_OK)
+    {
+        WARN( "status %u, server returned error %s.\n", status, debugstr_w(error_str) );
+        SysFreeString( error_str );
+        ret = FALSE;
+    }
+    else if (!ret)
+    {
+        WARN( "Request failed.\n" );
+    }
+    update_mapping_list();
+    ReleaseSRWLockExclusive( &upnp_gateway_connection_lock );
+
+    SysFreeString( mapping_desc[PM_EXTERNAL_IP].value );
+    SysFreeString( mapping_desc[PM_EXTERNAL].value );
+    SysFreeString( mapping_desc[PM_INTERNAL].value );
+    SysFreeString( mapping_desc[PM_ENABLED].value );
+    SysFreeString( mapping_desc[PM_LEASE_DURATION].value );
+    return ret;
+}
+
 static BOOL init_gateway_connection(void)
 {
     static const char upnp_search_request[] =
@@ -1458,12 +1503,37 @@ static HRESULT WINAPI static_ports_Add(
     BSTR description,
     IStaticPortMapping **mapping )
 {
-    FIXME( "iface %p, external %d, protocol %s, internal %d, client %s, enabled %d, descritption %s, mapping %p stub.\n",
+    struct port_mapping mapping_data;
+    HRESULT ret;
+
+    TRACE( "iface %p, external %d, protocol %s, internal %d, client %s, enabled %d, descritption %s, mapping %p.\n",
            iface, external, debugstr_w(protocol), internal, debugstr_w(client), enabled, debugstr_w(description),
            mapping );
 
-    if (mapping) *mapping = NULL;
-    return E_NOTIMPL;
+    if (!mapping) return E_POINTER;
+    *mapping = NULL;
+
+    if (!is_valid_protocol( protocol )) return E_INVALIDARG;
+    if (external < 0 || external > 65535) return E_INVALIDARG;
+    if (internal < 0 || internal > 65535) return E_INVALIDARG;
+    if (!client || !description) return E_INVALIDARG;
+
+    if (!add_port_mapping( external, protocol, internal, client, enabled, description )) return E_FAIL;
+
+    mapping_data.external_ip = NULL;
+    mapping_data.external = external;
+    mapping_data.protocol = SysAllocString( protocol );
+    mapping_data.internal = internal;
+    mapping_data.client = SysAllocString( client );
+    mapping_data.enabled = enabled;
+    mapping_data.descr = SysAllocString( description );
+    if (!mapping_data.protocol || !mapping_data.client || !mapping_data.descr)
+    {
+        free_port_mapping( &mapping_data );
+        return E_OUTOFMEMORY;
+    }
+    if (FAILED(ret = static_port_mapping_create( &mapping_data, mapping ))) free_port_mapping( &mapping_data );
+    return ret;
 }
 
 static const IStaticPortMappingCollectionVtbl static_ports_vtbl =
diff --git a/dlls/hnetcfg/tests/policy.c b/dlls/hnetcfg/tests/policy.c
index f9178f9b07b..b6b353ac87d 100644
--- a/dlls/hnetcfg/tests/policy.c
+++ b/dlls/hnetcfg/tests/policy.c
@@ -212,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",
             VARIANT_TRUE, (BSTR)L"wine_test", &pm);
-    todo_wine ok(hr == E_INVALIDARG, "Got unexpected hr %#x.\n", hr);
+    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",
             VARIANT_TRUE, (BSTR)L"wine_test", &pm);
-    todo_wine ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
+    ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
 
     hr = IStaticPortMappingCollection_get_Count(ports, &count2);
     ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
-    todo_wine ok(count2 == expected_count, "Got unexpected count2 %u, expected %u.\n", count2, expected_count);
+    ok(count2 == expected_count, "Got unexpected count2 %u, expected %u.\n", count2, expected_count);
 
     hr = IStaticPortMappingCollection_get_Item(ports, 12345, NULL, &pm);
     ok(hr == E_INVALIDARG, "Got unexpected hr %#x.\n", hr);




More information about the wine-cvs mailing list