xref: /reactos/dll/win32/hnetcfg/port.c (revision 53221834)
1 /*
2  * Copyright 2009 Hans Leidekker for CodeWeavers
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
17  */
18 
19 #include <stdarg.h>
20 #include <stdio.h>
21 
22 #define COBJMACROS
23 
24 #include "windef.h"
25 #include "winbase.h"
26 #include "winuser.h"
27 #include "ole2.h"
28 #include "netfw.h"
29 #include "natupnp.h"
30 
31 #include "wine/heap.h"
32 #include "wine/debug.h"
33 #include "hnetcfg_private.h"
34 
35 WINE_DEFAULT_DEBUG_CHANNEL(hnetcfg);
36 
37 typedef struct fw_port
38 {
39     INetFwOpenPort INetFwOpenPort_iface;
40     LONG refs;
41     BSTR name;
42     NET_FW_IP_PROTOCOL protocol;
43     LONG port;
44 } fw_port;
45 
46 static inline fw_port *impl_from_INetFwOpenPort( INetFwOpenPort *iface )
47 {
48     return CONTAINING_RECORD(iface, fw_port, INetFwOpenPort_iface);
49 }
50 
51 static ULONG WINAPI fw_port_AddRef(
52     INetFwOpenPort *iface )
53 {
54     fw_port *fw_port = impl_from_INetFwOpenPort( iface );
55     return InterlockedIncrement( &fw_port->refs );
56 }
57 
58 static ULONG WINAPI fw_port_Release(
59     INetFwOpenPort *iface )
60 {
61     fw_port *fw_port = impl_from_INetFwOpenPort( iface );
62     LONG refs = InterlockedDecrement( &fw_port->refs );
63     if (!refs)
64     {
65         TRACE("destroying %p\n", fw_port);
66         SysFreeString( fw_port->name );
67         HeapFree( GetProcessHeap(), 0, fw_port );
68     }
69     return refs;
70 }
71 
72 static HRESULT WINAPI fw_port_QueryInterface(
73     INetFwOpenPort *iface,
74     REFIID riid,
75     void **ppvObject )
76 {
77     fw_port *This = impl_from_INetFwOpenPort( iface );
78 
79     TRACE("%p %s %p\n", This, debugstr_guid( riid ), ppvObject );
80 
81     if ( IsEqualGUID( riid, &IID_INetFwOpenPort ) ||
82          IsEqualGUID( riid, &IID_IDispatch ) ||
83          IsEqualGUID( riid, &IID_IUnknown ) )
84     {
85         *ppvObject = iface;
86     }
87     else
88     {
89         FIXME("interface %s not implemented\n", debugstr_guid(riid));
90         return E_NOINTERFACE;
91     }
92     INetFwOpenPort_AddRef( iface );
93     return S_OK;
94 }
95 
96 static HRESULT WINAPI fw_port_GetTypeInfoCount(
97     INetFwOpenPort *iface,
98     UINT *pctinfo )
99 {
100     fw_port *This = impl_from_INetFwOpenPort( iface );
101 
102     TRACE("%p %p\n", This, pctinfo);
103     *pctinfo = 1;
104     return S_OK;
105 }
106 
107 static HRESULT WINAPI fw_port_GetTypeInfo(
108     INetFwOpenPort *iface,
109     UINT iTInfo,
110     LCID lcid,
111     ITypeInfo **ppTInfo )
112 {
113     fw_port *This = impl_from_INetFwOpenPort( iface );
114 
115     TRACE("%p %u %u %p\n", This, iTInfo, lcid, ppTInfo);
116     return get_typeinfo( INetFwOpenPort_tid, ppTInfo );
117 }
118 
119 static HRESULT WINAPI fw_port_GetIDsOfNames(
120     INetFwOpenPort *iface,
121     REFIID riid,
122     LPOLESTR *rgszNames,
123     UINT cNames,
124     LCID lcid,
125     DISPID *rgDispId )
126 {
127     fw_port *This = impl_from_INetFwOpenPort( iface );
128     ITypeInfo *typeinfo;
129     HRESULT hr;
130 
131     TRACE("%p %s %p %u %u %p\n", This, debugstr_guid(riid), rgszNames, cNames, lcid, rgDispId);
132 
133     hr = get_typeinfo( INetFwOpenPort_tid, &typeinfo );
134     if (SUCCEEDED(hr))
135     {
136         hr = ITypeInfo_GetIDsOfNames( typeinfo, rgszNames, cNames, rgDispId );
137         ITypeInfo_Release( typeinfo );
138     }
139     return hr;
140 }
141 
142 static HRESULT WINAPI fw_port_Invoke(
143     INetFwOpenPort *iface,
144     DISPID dispIdMember,
145     REFIID riid,
146     LCID lcid,
147     WORD wFlags,
148     DISPPARAMS *pDispParams,
149     VARIANT *pVarResult,
150     EXCEPINFO *pExcepInfo,
151     UINT *puArgErr )
152 {
153     fw_port *This = impl_from_INetFwOpenPort( iface );
154     ITypeInfo *typeinfo;
155     HRESULT hr;
156 
157     TRACE("%p %d %s %d %d %p %p %p %p\n", This, dispIdMember, debugstr_guid(riid),
158           lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
159 
160     hr = get_typeinfo( INetFwOpenPort_tid, &typeinfo );
161     if (SUCCEEDED(hr))
162     {
163         hr = ITypeInfo_Invoke( typeinfo, &This->INetFwOpenPort_iface, dispIdMember,
164                                wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr );
165         ITypeInfo_Release( typeinfo );
166     }
167     return hr;
168 }
169 
170 static HRESULT WINAPI fw_port_get_Name(
171     INetFwOpenPort *iface,
172     BSTR *name)
173 {
174     fw_port *This = impl_from_INetFwOpenPort( iface );
175 
176     FIXME("%p %p\n", This, name);
177     return E_NOTIMPL;
178 }
179 
180 static HRESULT WINAPI fw_port_put_Name(
181     INetFwOpenPort *iface,
182     BSTR name)
183 {
184     fw_port *This = impl_from_INetFwOpenPort( iface );
185 
186     TRACE("%p %s\n", This, debugstr_w(name));
187 
188     if (!(name = SysAllocString( name )))
189         return E_OUTOFMEMORY;
190 
191     SysFreeString( This->name );
192     This->name = name;
193     return S_OK;
194 }
195 
196 static HRESULT WINAPI fw_port_get_IpVersion(
197     INetFwOpenPort *iface,
198     NET_FW_IP_VERSION *ipVersion)
199 {
200     fw_port *This = impl_from_INetFwOpenPort( iface );
201 
202     FIXME("%p %p\n", This, ipVersion);
203     return E_NOTIMPL;
204 }
205 
206 static HRESULT WINAPI fw_port_put_IpVersion(
207     INetFwOpenPort *iface,
208     NET_FW_IP_VERSION ipVersion)
209 {
210     fw_port *This = impl_from_INetFwOpenPort( iface );
211 
212     FIXME("%p %u\n", This, ipVersion);
213     return E_NOTIMPL;
214 }
215 
216 static HRESULT WINAPI fw_port_get_Protocol(
217     INetFwOpenPort *iface,
218     NET_FW_IP_PROTOCOL *ipProtocol)
219 {
220     fw_port *This = impl_from_INetFwOpenPort( iface );
221 
222     FIXME("%p %p\n", This, ipProtocol);
223     return E_NOTIMPL;
224 }
225 
226 static HRESULT WINAPI fw_port_put_Protocol(
227     INetFwOpenPort *iface,
228     NET_FW_IP_PROTOCOL ipProtocol)
229 {
230     fw_port *This = impl_from_INetFwOpenPort( iface );
231 
232     TRACE("%p %u\n", This, ipProtocol);
233 
234     if (ipProtocol != NET_FW_IP_PROTOCOL_TCP && ipProtocol != NET_FW_IP_PROTOCOL_UDP)
235         return E_INVALIDARG;
236 
237     This->protocol = ipProtocol;
238     return S_OK;
239 }
240 
241 static HRESULT WINAPI fw_port_get_Port(
242     INetFwOpenPort *iface,
243     LONG *portNumber)
244 {
245     fw_port *This = impl_from_INetFwOpenPort( iface );
246 
247     FIXME("%p %p\n", This, portNumber);
248     return E_NOTIMPL;
249 }
250 
251 static HRESULT WINAPI fw_port_put_Port(
252     INetFwOpenPort *iface,
253     LONG portNumber)
254 {
255     fw_port *This = impl_from_INetFwOpenPort( iface );
256 
257     TRACE("%p %d\n", This, portNumber);
258     This->port = portNumber;
259     return S_OK;
260 }
261 
262 static HRESULT WINAPI fw_port_get_Scope(
263     INetFwOpenPort *iface,
264     NET_FW_SCOPE *scope)
265 {
266     fw_port *This = impl_from_INetFwOpenPort( iface );
267 
268     FIXME("%p %p\n", This, scope);
269     return E_NOTIMPL;
270 }
271 
272 static HRESULT WINAPI fw_port_put_Scope(
273     INetFwOpenPort *iface,
274     NET_FW_SCOPE scope)
275 {
276     fw_port *This = impl_from_INetFwOpenPort( iface );
277 
278     FIXME("%p %u\n", This, scope);
279     return E_NOTIMPL;
280 }
281 
282 static HRESULT WINAPI fw_port_get_RemoteAddresses(
283     INetFwOpenPort *iface,
284     BSTR *remoteAddrs)
285 {
286     fw_port *This = impl_from_INetFwOpenPort( iface );
287 
288     FIXME("%p %p\n", This, remoteAddrs);
289     return E_NOTIMPL;
290 }
291 
292 static HRESULT WINAPI fw_port_put_RemoteAddresses(
293     INetFwOpenPort *iface,
294     BSTR remoteAddrs)
295 {
296     fw_port *This = impl_from_INetFwOpenPort( iface );
297 
298     FIXME("%p %s\n", This, debugstr_w(remoteAddrs));
299     return E_NOTIMPL;
300 }
301 
302 static HRESULT WINAPI fw_port_get_Enabled(
303     INetFwOpenPort *iface,
304     VARIANT_BOOL *enabled)
305 {
306     fw_port *This = impl_from_INetFwOpenPort( iface );
307 
308     FIXME("%p %p\n", This, enabled);
309 
310     *enabled = VARIANT_TRUE;
311     return S_OK;
312 }
313 
314 static HRESULT WINAPI fw_port_put_Enabled(
315     INetFwOpenPort *iface,
316     VARIANT_BOOL enabled)
317 {
318     fw_port *This = impl_from_INetFwOpenPort( iface );
319 
320     FIXME("%p %d\n", This, enabled);
321     return S_OK;
322 }
323 
324 static HRESULT WINAPI fw_port_get_BuiltIn(
325     INetFwOpenPort *iface,
326     VARIANT_BOOL *builtIn)
327 {
328     fw_port *This = impl_from_INetFwOpenPort( iface );
329 
330     FIXME("%p %p\n", This, builtIn);
331     return E_NOTIMPL;
332 }
333 
334 static const struct INetFwOpenPortVtbl fw_port_vtbl =
335 {
336     fw_port_QueryInterface,
337     fw_port_AddRef,
338     fw_port_Release,
339     fw_port_GetTypeInfoCount,
340     fw_port_GetTypeInfo,
341     fw_port_GetIDsOfNames,
342     fw_port_Invoke,
343     fw_port_get_Name,
344     fw_port_put_Name,
345     fw_port_get_IpVersion,
346     fw_port_put_IpVersion,
347     fw_port_get_Protocol,
348     fw_port_put_Protocol,
349     fw_port_get_Port,
350     fw_port_put_Port,
351     fw_port_get_Scope,
352     fw_port_put_Scope,
353     fw_port_get_RemoteAddresses,
354     fw_port_put_RemoteAddresses,
355     fw_port_get_Enabled,
356     fw_port_put_Enabled,
357     fw_port_get_BuiltIn
358 };
359 
360 HRESULT NetFwOpenPort_create( IUnknown *pUnkOuter, LPVOID *ppObj )
361 {
362     fw_port *fp;
363 
364     TRACE("(%p,%p)\n", pUnkOuter, ppObj);
365 
366     fp = HeapAlloc( GetProcessHeap(), 0, sizeof(*fp) );
367     if (!fp) return E_OUTOFMEMORY;
368 
369     fp->INetFwOpenPort_iface.lpVtbl = &fw_port_vtbl;
370     fp->refs = 1;
371     fp->name = NULL;
372     fp->protocol = NET_FW_IP_PROTOCOL_TCP;
373     fp->port = 0;
374 
375     *ppObj = &fp->INetFwOpenPort_iface;
376 
377     TRACE("returning iface %p\n", *ppObj);
378     return S_OK;
379 }
380 
381 typedef struct fw_ports
382 {
383     INetFwOpenPorts INetFwOpenPorts_iface;
384     LONG refs;
385 } fw_ports;
386 
387 static inline fw_ports *impl_from_INetFwOpenPorts( INetFwOpenPorts *iface )
388 {
389     return CONTAINING_RECORD(iface, fw_ports, INetFwOpenPorts_iface);
390 }
391 
392 static ULONG WINAPI fw_ports_AddRef(
393     INetFwOpenPorts *iface )
394 {
395     fw_ports *fw_ports = impl_from_INetFwOpenPorts( iface );
396     return InterlockedIncrement( &fw_ports->refs );
397 }
398 
399 static ULONG WINAPI fw_ports_Release(
400     INetFwOpenPorts *iface )
401 {
402     fw_ports *fw_ports = impl_from_INetFwOpenPorts( iface );
403     LONG refs = InterlockedDecrement( &fw_ports->refs );
404     if (!refs)
405     {
406         TRACE("destroying %p\n", fw_ports);
407         HeapFree( GetProcessHeap(), 0, fw_ports );
408     }
409     return refs;
410 }
411 
412 static HRESULT WINAPI fw_ports_QueryInterface(
413     INetFwOpenPorts *iface,
414     REFIID riid,
415     void **ppvObject )
416 {
417     fw_ports *This = impl_from_INetFwOpenPorts( iface );
418 
419     TRACE("%p %s %p\n", This, debugstr_guid( riid ), ppvObject );
420 
421     if ( IsEqualGUID( riid, &IID_INetFwOpenPorts ) ||
422          IsEqualGUID( riid, &IID_IDispatch ) ||
423          IsEqualGUID( riid, &IID_IUnknown ) )
424     {
425         *ppvObject = iface;
426     }
427     else
428     {
429         FIXME("interface %s not implemented\n", debugstr_guid(riid));
430         return E_NOINTERFACE;
431     }
432     INetFwOpenPorts_AddRef( iface );
433     return S_OK;
434 }
435 
436 static HRESULT WINAPI fw_ports_GetTypeInfoCount(
437     INetFwOpenPorts *iface,
438     UINT *pctinfo )
439 {
440     fw_ports *This = impl_from_INetFwOpenPorts( iface );
441 
442     TRACE("%p %p\n", This, pctinfo);
443     *pctinfo = 1;
444     return S_OK;
445 }
446 
447 static HRESULT WINAPI fw_ports_GetTypeInfo(
448     INetFwOpenPorts *iface,
449     UINT iTInfo,
450     LCID lcid,
451     ITypeInfo **ppTInfo )
452 {
453     fw_ports *This = impl_from_INetFwOpenPorts( iface );
454 
455     TRACE("%p %u %u %p\n", This, iTInfo, lcid, ppTInfo);
456     return get_typeinfo( INetFwOpenPorts_tid, ppTInfo );
457 }
458 
459 static HRESULT WINAPI fw_ports_GetIDsOfNames(
460     INetFwOpenPorts *iface,
461     REFIID riid,
462     LPOLESTR *rgszNames,
463     UINT cNames,
464     LCID lcid,
465     DISPID *rgDispId )
466 {
467     fw_ports *This = impl_from_INetFwOpenPorts( iface );
468     ITypeInfo *typeinfo;
469     HRESULT hr;
470 
471     TRACE("%p %s %p %u %u %p\n", This, debugstr_guid(riid), rgszNames, cNames, lcid, rgDispId);
472 
473     hr = get_typeinfo( INetFwOpenPorts_tid, &typeinfo );
474     if (SUCCEEDED(hr))
475     {
476         hr = ITypeInfo_GetIDsOfNames( typeinfo, rgszNames, cNames, rgDispId );
477         ITypeInfo_Release( typeinfo );
478     }
479     return hr;
480 }
481 
482 static HRESULT WINAPI fw_ports_Invoke(
483     INetFwOpenPorts *iface,
484     DISPID dispIdMember,
485     REFIID riid,
486     LCID lcid,
487     WORD wFlags,
488     DISPPARAMS *pDispParams,
489     VARIANT *pVarResult,
490     EXCEPINFO *pExcepInfo,
491     UINT *puArgErr )
492 {
493     fw_ports *This = impl_from_INetFwOpenPorts( iface );
494     ITypeInfo *typeinfo;
495     HRESULT hr;
496 
497     TRACE("%p %d %s %d %d %p %p %p %p\n", This, dispIdMember, debugstr_guid(riid),
498           lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
499 
500     hr = get_typeinfo( INetFwOpenPorts_tid, &typeinfo );
501     if (SUCCEEDED(hr))
502     {
503         hr = ITypeInfo_Invoke( typeinfo, &This->INetFwOpenPorts_iface, dispIdMember,
504                                wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr );
505         ITypeInfo_Release( typeinfo );
506     }
507     return hr;
508 }
509 
510 static HRESULT WINAPI fw_ports_get_Count(
511     INetFwOpenPorts *iface,
512     LONG *count)
513 {
514     fw_ports *This = impl_from_INetFwOpenPorts( iface );
515 
516     FIXME("%p, %p\n", This, count);
517 
518     *count = 0;
519     return S_OK;
520 }
521 
522 static HRESULT WINAPI fw_ports_Add(
523     INetFwOpenPorts *iface,
524     INetFwOpenPort *port)
525 {
526     fw_ports *This = impl_from_INetFwOpenPorts( iface );
527 
528     FIXME("%p, %p\n", This, port);
529     return S_OK;
530 }
531 
532 static HRESULT WINAPI fw_ports_Remove(
533     INetFwOpenPorts *iface,
534     LONG portNumber,
535     NET_FW_IP_PROTOCOL ipProtocol)
536 {
537     fw_ports *This = impl_from_INetFwOpenPorts( iface );
538 
539     FIXME("%p, %d, %u\n", This, portNumber, ipProtocol);
540     return E_NOTIMPL;
541 }
542 
543 static HRESULT WINAPI fw_ports_Item(
544     INetFwOpenPorts *iface,
545     LONG portNumber,
546     NET_FW_IP_PROTOCOL ipProtocol,
547     INetFwOpenPort **openPort)
548 {
549     HRESULT hr;
550     fw_ports *This = impl_from_INetFwOpenPorts( iface );
551 
552     FIXME("%p, %d, %u, %p\n", This, portNumber, ipProtocol, openPort);
553 
554     hr = NetFwOpenPort_create( NULL, (void **)openPort );
555     if (SUCCEEDED(hr))
556     {
557         INetFwOpenPort_put_Protocol( *openPort, ipProtocol );
558         INetFwOpenPort_put_Port( *openPort, portNumber );
559     }
560     return hr;
561 }
562 
563 static HRESULT WINAPI fw_ports_get__NewEnum(
564     INetFwOpenPorts *iface,
565     IUnknown **newEnum)
566 {
567     fw_ports *This = impl_from_INetFwOpenPorts( iface );
568 
569     FIXME("%p, %p\n", This, newEnum);
570     return E_NOTIMPL;
571 }
572 
573 static const struct INetFwOpenPortsVtbl fw_ports_vtbl =
574 {
575     fw_ports_QueryInterface,
576     fw_ports_AddRef,
577     fw_ports_Release,
578     fw_ports_GetTypeInfoCount,
579     fw_ports_GetTypeInfo,
580     fw_ports_GetIDsOfNames,
581     fw_ports_Invoke,
582     fw_ports_get_Count,
583     fw_ports_Add,
584     fw_ports_Remove,
585     fw_ports_Item,
586     fw_ports_get__NewEnum
587 };
588 
589 HRESULT NetFwOpenPorts_create( IUnknown *pUnkOuter, LPVOID *ppObj )
590 {
591     fw_ports *fp;
592 
593     TRACE("(%p,%p)\n", pUnkOuter, ppObj);
594 
595     fp = HeapAlloc( GetProcessHeap(), 0, sizeof(*fp) );
596     if (!fp) return E_OUTOFMEMORY;
597 
598     fp->INetFwOpenPorts_iface.lpVtbl = &fw_ports_vtbl;
599     fp->refs = 1;
600 
601     *ppObj = &fp->INetFwOpenPorts_iface;
602 
603     TRACE("returning iface %p\n", *ppObj);
604     return S_OK;
605 }
606 
607 typedef struct _upnpnat
608 {
609     IUPnPNAT IUPnPNAT_iface;
610     LONG ref;
611 } upnpnat;
612 
613 static inline upnpnat *impl_from_IUPnPNAT( IUPnPNAT *iface )
614 {
615     return CONTAINING_RECORD(iface, upnpnat, IUPnPNAT_iface);
616 }
617 
618 static HRESULT WINAPI upnpnat_QueryInterface(IUPnPNAT *iface, REFIID riid, void **object)
619 {
620     upnpnat *This = impl_from_IUPnPNAT( iface );
621 
622     TRACE("%p %s %p\n", This, debugstr_guid( riid ), object );
623 
624     if ( IsEqualGUID( riid, &IID_IUPnPNAT ) ||
625          IsEqualGUID( riid, &IID_IDispatch ) ||
626          IsEqualGUID( riid, &IID_IUnknown ) )
627     {
628         *object = iface;
629     }
630     else if(IsEqualGUID( riid, &IID_IProvideClassInfo))
631     {
632         TRACE("IProvideClassInfo not supported.\n");
633         return E_NOINTERFACE;
634     }
635     else
636     {
637         FIXME("interface %s not implemented\n", debugstr_guid(riid));
638         return E_NOINTERFACE;
639     }
640     IUPnPNAT_AddRef( iface );
641     return S_OK;
642 }
643 
644 static ULONG WINAPI upnpnat_AddRef(IUPnPNAT *iface)
645 {
646     upnpnat *This = impl_from_IUPnPNAT( iface );
647     return InterlockedIncrement( &This->ref );
648 }
649 
650 static ULONG WINAPI upnpnat_Release(IUPnPNAT *iface)
651 {
652     upnpnat *This = impl_from_IUPnPNAT( iface );
653     LONG refs = InterlockedDecrement( &This->ref );
654     if (!refs)
655     {
656         heap_free( This );
657     }
658     return refs;
659 }
660 
661 static HRESULT WINAPI upnpnat_GetTypeInfoCount(IUPnPNAT *iface, UINT *pctinfo)
662 {
663     upnpnat *This = impl_from_IUPnPNAT( iface );
664 
665     TRACE("%p %p\n", This, pctinfo);
666     *pctinfo = 1;
667     return S_OK;
668 }
669 
670 static HRESULT WINAPI upnpnat_GetTypeInfo(IUPnPNAT *iface, UINT iTInfo, LCID lcid, ITypeInfo **ppTInfo)
671 {
672     upnpnat *This = impl_from_IUPnPNAT( iface );
673 
674     TRACE("%p %u %u %p\n", This, iTInfo, lcid, ppTInfo);
675     return get_typeinfo( IUPnPNAT_tid, ppTInfo );
676 }
677 
678 static HRESULT WINAPI upnpnat_GetIDsOfNames(IUPnPNAT *iface, REFIID riid, LPOLESTR *rgszNames,
679                 UINT cNames, LCID lcid, DISPID *rgDispId)
680 {
681     upnpnat *This = impl_from_IUPnPNAT( iface );
682     ITypeInfo *typeinfo;
683     HRESULT hr;
684 
685     TRACE("%p %s %p %u %u %p\n", This, debugstr_guid(riid), rgszNames, cNames, lcid, rgDispId);
686 
687     hr = get_typeinfo( IUPnPNAT_tid, &typeinfo );
688     if (SUCCEEDED(hr))
689     {
690         hr = ITypeInfo_GetIDsOfNames( typeinfo, rgszNames, cNames, rgDispId );
691         ITypeInfo_Release( typeinfo );
692     }
693     return hr;
694 }
695 
696 static HRESULT WINAPI upnpnat_Invoke(IUPnPNAT *iface, DISPID dispIdMember, REFIID riid, LCID lcid,
697                 WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo,
698                 UINT *puArgErr)
699 {
700     upnpnat *This = impl_from_IUPnPNAT( iface );
701     ITypeInfo *typeinfo;
702     HRESULT hr;
703 
704     TRACE("%p %d %s %d %d %p %p %p %p\n", This, dispIdMember, debugstr_guid(riid),
705           lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
706 
707     hr = get_typeinfo( IUPnPNAT_tid, &typeinfo );
708     if (SUCCEEDED(hr))
709     {
710         hr = ITypeInfo_Invoke( typeinfo, &This->IUPnPNAT_iface, dispIdMember,
711                                wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr );
712         ITypeInfo_Release( typeinfo );
713     }
714     return hr;
715 }
716 
717 static HRESULT WINAPI upnpnat_get_StaticPortMappingCollection(IUPnPNAT *iface, IStaticPortMappingCollection **collection)
718 {
719     upnpnat *This = impl_from_IUPnPNAT( iface );
720     FIXME("%p, %p\n", This, collection);
721     if(collection)
722         *collection = NULL;
723     return E_NOTIMPL;
724 }
725 
726 static HRESULT WINAPI upnpnat_get_DynamicPortMappingCollection(IUPnPNAT *iface, IDynamicPortMappingCollection **collection)
727 {
728     upnpnat *This = impl_from_IUPnPNAT( iface );
729     FIXME("%p, %p\n", This, collection);
730     if(collection)
731         *collection = NULL;
732     return E_NOTIMPL;
733 }
734 
735 static HRESULT WINAPI upnpnat_get_NATEventManager(IUPnPNAT *iface, INATEventManager **manager)
736 {
737     upnpnat *This = impl_from_IUPnPNAT( iface );
738     FIXME("%p, %p\n", This, manager);
739     if(manager)
740         *manager = NULL;
741     return E_NOTIMPL;
742 }
743 
744 static const IUPnPNATVtbl upnpnat_vtbl =
745 {
746     upnpnat_QueryInterface,
747     upnpnat_AddRef,
748     upnpnat_Release,
749     upnpnat_GetTypeInfoCount,
750     upnpnat_GetTypeInfo,
751     upnpnat_GetIDsOfNames,
752     upnpnat_Invoke,
753     upnpnat_get_StaticPortMappingCollection,
754     upnpnat_get_DynamicPortMappingCollection,
755     upnpnat_get_NATEventManager
756 };
757 
758 
759 HRESULT IUPnPNAT_create(IUnknown *outer, void **object)
760 {
761     upnpnat *nat;
762 
763     TRACE("(%p,%p)\n", outer, object);
764 
765     nat = heap_alloc( sizeof(*nat) );
766     if (!nat) return E_OUTOFMEMORY;
767 
768     nat->IUPnPNAT_iface.lpVtbl = &upnpnat_vtbl;
769     nat->ref = 1;
770 
771     *object = &nat->IUPnPNAT_iface;
772 
773     TRACE("returning iface %p\n", *object);
774     return S_OK;
775 }
776