From 449833b48aabe25ef500fe12b2b00e83bd9b2efd Mon Sep 17 00:00:00 2001 From: Alistair Leslie-Hughes Date: Sun, 14 Oct 2018 23:27:06 +0000 Subject: [PATCH] hnetcfg: Support IUPnPNAT interface. Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=34711 Signed-off-by: Alistair Leslie-Hughes Signed-off-by: Alexandre Julliard --- dlls/hnetcfg/apps.c | 4 +- dlls/hnetcfg/hnetcfg.c | 7 ++ dlls/hnetcfg/hnetcfg_private.h | 2 + dlls/hnetcfg/manager.c | 1 + dlls/hnetcfg/port.c | 167 +++++++++++++++++++++++++++++++++++++++++ 5 files changed, 180 insertions(+), 1 deletion(-) diff --git a/dlls/hnetcfg/apps.c b/dlls/hnetcfg/apps.c index e671e8ca8de..99724687a35 100644 --- a/dlls/hnetcfg/apps.c +++ b/dlls/hnetcfg/apps.c @@ -27,6 +27,7 @@ #include "winuser.h" #include "ole2.h" #include "netfw.h" +#include "natupnp.h" #include "wine/debug.h" #include "wine/heap.h" @@ -115,7 +116,8 @@ static REFIID tid_id[] = &IID_INetFwOpenPorts, &IID_INetFwPolicy, &IID_INetFwPolicy2, - &IID_INetFwProfile + &IID_INetFwProfile, + &IID_IUPnPNAT }; HRESULT get_typeinfo( enum type_id tid, ITypeInfo **ret ) diff --git a/dlls/hnetcfg/hnetcfg.c b/dlls/hnetcfg/hnetcfg.c index e56dbab9e74..5cc24a1447b 100644 --- a/dlls/hnetcfg/hnetcfg.c +++ b/dlls/hnetcfg/hnetcfg.c @@ -25,6 +25,7 @@ #include "objbase.h" #include "rpcproxy.h" #include "netfw.h" +#include "natupnp.h" #include "wine/debug.h" #include "hnetcfg_private.h" @@ -114,6 +115,8 @@ static hnetcfg_cf fw_manager_cf = { { &hnetcfg_cf_vtbl }, NetFwMgr_create }; static hnetcfg_cf fw_app_cf = { { &hnetcfg_cf_vtbl }, NetFwAuthorizedApplication_create }; static hnetcfg_cf fw_openport_cf = { { &hnetcfg_cf_vtbl }, NetFwOpenPort_create }; static hnetcfg_cf fw_policy2_cf = { { &hnetcfg_cf_vtbl }, NetFwPolicy2_create }; +static hnetcfg_cf upnpnat_cf = { { &hnetcfg_cf_vtbl }, IUPnPNAT_create }; + BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID reserved) { @@ -156,6 +159,10 @@ HRESULT WINAPI DllGetClassObject( REFCLSID rclsid, REFIID iid, LPVOID *ppv ) { cf = &fw_policy2_cf.IClassFactory_iface; } + else if (IsEqualGUID( rclsid, &CLSID_UPnPNAT )) + { + cf = &upnpnat_cf.IClassFactory_iface; + } if (!cf) return CLASS_E_CLASSNOTAVAILABLE; return IClassFactory_QueryInterface( cf, iid, ppv ); diff --git a/dlls/hnetcfg/hnetcfg_private.h b/dlls/hnetcfg/hnetcfg_private.h index 5245883e3db..be2d0f3c7c6 100644 --- a/dlls/hnetcfg/hnetcfg_private.h +++ b/dlls/hnetcfg/hnetcfg_private.h @@ -27,6 +27,7 @@ enum type_id INetFwPolicy2_tid, INetFwProfile_tid, INetFwRules_tid, + IUPnPNAT_tid, last_tid }; @@ -42,3 +43,4 @@ HRESULT NetFwAuthorizedApplications_create(IUnknown *, LPVOID *) DECLSPEC_HIDDEN HRESULT NetFwOpenPorts_create(IUnknown *, LPVOID *) DECLSPEC_HIDDEN; HRESULT NetFwOpenPort_create(IUnknown *, LPVOID *) DECLSPEC_HIDDEN; HRESULT NetFwServices_create(IUnknown *, LPVOID *) DECLSPEC_HIDDEN; +HRESULT IUPnPNAT_create(IUnknown *, void **) DECLSPEC_HIDDEN; diff --git a/dlls/hnetcfg/manager.c b/dlls/hnetcfg/manager.c index 1d548b41a94..d3f089e3b57 100644 --- a/dlls/hnetcfg/manager.c +++ b/dlls/hnetcfg/manager.c @@ -28,6 +28,7 @@ #include "initguid.h" #include "ole2.h" #include "netfw.h" +#include "natupnp.h" #include "wine/debug.h" #include "wine/unicode.h" diff --git a/dlls/hnetcfg/port.c b/dlls/hnetcfg/port.c index 7d749650763..f497bcbd958 100644 --- a/dlls/hnetcfg/port.c +++ b/dlls/hnetcfg/port.c @@ -27,7 +27,9 @@ #include "winuser.h" #include "ole2.h" #include "netfw.h" +#include "natupnp.h" +#include "wine/heap.h" #include "wine/debug.h" #include "wine/unicode.h" #include "hnetcfg_private.h" @@ -603,3 +605,168 @@ HRESULT NetFwOpenPorts_create( IUnknown *pUnkOuter, LPVOID *ppObj ) TRACE("returning iface %p\n", *ppObj); return S_OK; } + +typedef struct _upnpnat +{ + IUPnPNAT IUPnPNAT_iface; + LONG ref; +} upnpnat; + +static inline upnpnat *impl_from_IUPnPNAT( IUPnPNAT *iface ) +{ + return CONTAINING_RECORD(iface, upnpnat, IUPnPNAT_iface); +} + +static HRESULT WINAPI upnpnat_QueryInterface(IUPnPNAT *iface, REFIID riid, void **object) +{ + upnpnat *This = impl_from_IUPnPNAT( iface ); + + TRACE("%p %s %p\n", This, debugstr_guid( riid ), object ); + + if ( IsEqualGUID( riid, &IID_IUPnPNAT ) || + IsEqualGUID( riid, &IID_IDispatch ) || + IsEqualGUID( riid, &IID_IUnknown ) ) + { + *object = iface; + } + else + { + FIXME("interface %s not implemented\n", debugstr_guid(riid)); + return E_NOINTERFACE; + } + IUPnPNAT_AddRef( iface ); + return S_OK; +} + +static ULONG WINAPI upnpnat_AddRef(IUPnPNAT *iface) +{ + upnpnat *This = impl_from_IUPnPNAT( iface ); + return InterlockedIncrement( &This->ref ); +} + +static ULONG WINAPI upnpnat_Release(IUPnPNAT *iface) +{ + upnpnat *This = impl_from_IUPnPNAT( iface ); + LONG refs = InterlockedDecrement( &This->ref ); + if (!refs) + { + heap_free( This ); + } + return refs; +} + +static HRESULT WINAPI upnpnat_GetTypeInfoCount(IUPnPNAT *iface, UINT *pctinfo) +{ + upnpnat *This = impl_from_IUPnPNAT( iface ); + + TRACE("%p %p\n", This, pctinfo); + *pctinfo = 1; + return S_OK; +} + +static HRESULT WINAPI upnpnat_GetTypeInfo(IUPnPNAT *iface, UINT iTInfo, LCID lcid, ITypeInfo **ppTInfo) +{ + upnpnat *This = impl_from_IUPnPNAT( iface ); + + TRACE("%p %u %u %p\n", This, iTInfo, lcid, ppTInfo); + return get_typeinfo( IUPnPNAT_tid, ppTInfo ); +} + +static HRESULT WINAPI upnpnat_GetIDsOfNames(IUPnPNAT *iface, REFIID riid, LPOLESTR *rgszNames, + UINT cNames, LCID lcid, DISPID *rgDispId) +{ + upnpnat *This = impl_from_IUPnPNAT( iface ); + ITypeInfo *typeinfo; + HRESULT hr; + + TRACE("%p %s %p %u %u %p\n", This, debugstr_guid(riid), rgszNames, cNames, lcid, rgDispId); + + hr = get_typeinfo( IUPnPNAT_tid, &typeinfo ); + if (SUCCEEDED(hr)) + { + hr = ITypeInfo_GetIDsOfNames( typeinfo, rgszNames, cNames, rgDispId ); + ITypeInfo_Release( typeinfo ); + } + return hr; +} + +static HRESULT WINAPI upnpnat_Invoke(IUPnPNAT *iface, DISPID dispIdMember, REFIID riid, LCID lcid, + WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo, + UINT *puArgErr) +{ + upnpnat *This = impl_from_IUPnPNAT( iface ); + ITypeInfo *typeinfo; + HRESULT hr; + + TRACE("%p %d %s %d %d %p %p %p %p\n", This, dispIdMember, debugstr_guid(riid), + lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr); + + hr = get_typeinfo( IUPnPNAT_tid, &typeinfo ); + if (SUCCEEDED(hr)) + { + hr = ITypeInfo_Invoke( typeinfo, &This->IUPnPNAT_iface, dispIdMember, + wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr ); + ITypeInfo_Release( typeinfo ); + } + return hr; +} + +static HRESULT WINAPI upnpnat_get_StaticPortMappingCollection(IUPnPNAT *iface, IStaticPortMappingCollection **collection) +{ + upnpnat *This = impl_from_IUPnPNAT( iface ); + FIXME("%p, %p\n", This, collection); + if(collection) + *collection = NULL; + return E_NOTIMPL; +} + +static HRESULT WINAPI upnpnat_get_DynamicPortMappingCollection(IUPnPNAT *iface, IDynamicPortMappingCollection **collection) +{ + upnpnat *This = impl_from_IUPnPNAT( iface ); + FIXME("%p, %p\n", This, collection); + if(collection) + *collection = NULL; + return E_NOTIMPL; +} + +static HRESULT WINAPI upnpnat_get_NATEventManager(IUPnPNAT *iface, INATEventManager **manager) +{ + upnpnat *This = impl_from_IUPnPNAT( iface ); + FIXME("%p, %p\n", This, manager); + if(manager) + *manager = NULL; + return E_NOTIMPL; +} + +const static IUPnPNATVtbl upnpnat_vtbl = +{ + upnpnat_QueryInterface, + upnpnat_AddRef, + upnpnat_Release, + upnpnat_GetTypeInfoCount, + upnpnat_GetTypeInfo, + upnpnat_GetIDsOfNames, + upnpnat_Invoke, + upnpnat_get_StaticPortMappingCollection, + upnpnat_get_DynamicPortMappingCollection, + upnpnat_get_NATEventManager +}; + + +HRESULT IUPnPNAT_create(IUnknown *outer, void **object) +{ + upnpnat *nat; + + TRACE("(%p,%p)\n", outer, object); + + nat = heap_alloc( sizeof(*nat) ); + if (!nat) return E_OUTOFMEMORY; + + nat->IUPnPNAT_iface.lpVtbl = &upnpnat_vtbl; + nat->ref = 1; + + *object = &nat->IUPnPNAT_iface; + + TRACE("returning iface %p\n", *object); + return S_OK; +} -- 2.11.4.GIT