|
|
楼主 |
发表于 2011-7-15 17:28:52
|
显示全部楼层
以下有关upnp的接口来自emule,3 C3 z" U+ w r. B, y6 ~
: b$ M4 J% l) K$ h
% W+ F( k5 l9 f5 p' z+ @+ v: l G1 ]5 \///////////////////////////////////////////) m2 \% N" J! _- S
//upnp的抽象接口类,只需调用这些接口即可实现端口映射功能.
! Q8 S4 S! S( l0 j
E: T8 }( F+ L+ E. A7 N7 a
) U/ ]# {7 r# {3 M#pragma once8 P6 _. F. Z1 N
#include <exception>
6 y' b: N" f/ f. q; C( |. g; f) {. @" C/ J" q; l7 X
: I/ U8 q7 w9 s0 C2 G
enum TRISTATE{
3 F3 O7 f. c; N TRIS_FALSE,. }& \6 x" j. v( I
TRIS_UNKNOWN,
+ _. C3 k: H! |. Z) r9 T. I TRIS_TRUE( V% ^: ^3 t) ]& Z h% ^
};6 J- y- }9 Y: ~4 q+ ]2 I
' G' t5 M l; ~6 Q! |1 g
: q) _- h: U" {8 K* W! ^9 D0 [: Q r" |& f
enum UPNP_IMPLEMENTATION{
+ }% Z- X3 V4 I L6 m i UPNP_IMPL_WINDOWSERVICE = 0,& S5 o6 m2 }. J- x5 T
UPNP_IMPL_MINIUPNPLIB,
& z1 [4 `* U+ w* n UPNP_IMPL_NONE /*last*/! a1 Z* Q6 w: s' a. m* c
};
4 d$ m& N' w- c X7 i: F' T* D
2 e" }; g* S: C4 d1 ~3 H) Y. I# v2 k2 s$ E, S( l& a
- I/ x0 X% T7 a# ~, ?$ K( U
4 V. v4 r8 g3 s7 qclass CUPnPImpl
2 E2 [+ e7 f7 ?7 Q! ~" A6 L `{
8 h7 r! c3 b6 wpublic:- b: |! s& ~- Y1 @' J1 P5 i
CUPnPImpl();
1 n2 `1 P+ k N Y virtual ~CUPnPImpl();
( F8 z1 c/ ^3 ]1 \& _ struct UPnPError : std::exception {};+ C" w' ^7 _, Z% f( A3 S$ C
enum {
2 I9 u/ \1 q3 l. R UPNP_OK,* p: I7 \8 u2 u6 f G$ }
UPNP_FAILED,9 O3 {5 T* G4 Z- H
UPNP_TIMEOUT
, a D/ u4 ]! b6 B) n };0 C5 N P5 i' W b8 ^" D
/ g( s; k( j7 z. @" E3 g- ]6 v: N4 r7 h1 [
virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) = 0;+ E k! j- z" U9 o( E! W2 e7 t
virtual bool CheckAndRefresh() = 0;' d3 j& _9 C0 e% Z
virtual void StopAsyncFind() = 0;3 b' }+ \# d2 ?' t) y" f X' u4 e9 ?
virtual void DeletePorts() = 0;
" l( ]" u2 _2 Z# i virtual bool IsReady() = 0;% j& e4 i$ `: l& R$ @% ?5 I
virtual int GetImplementationID() = 0;9 A; N* k, L/ O/ ]# l
0 r. {: {( i& X& ?3 \ T
void LateEnableWebServerPort(uint16 nPort); // Add Webserverport on already installed portmapping$ c \8 Y w2 D/ q. v% F+ w
m' g! w ]" O. w" Z# F
9 @% G- C' l9 a- J) T+ W: M3 c7 p; _# V void SetMessageOnResult(HWND hWindow, UINT nMessageID);
& v2 j2 O( q) \& c$ t TRISTATE ArePortsForwarded() const { return m_bUPnPPortsForwarded; }+ _+ K& o e7 ?. v# a4 h/ \
uint16 GetUsedTCPPort() { return m_nTCPPort; }7 o- Y F0 q7 _# O/ P# Y
uint16 GetUsedUDPPort() { return m_nUDPPort; }
% R! X, M; V: G
9 B, n+ U0 ^0 W. A) A5 j1 k4 D( A% k3 H1 @
// Implementation2 r; H _. t2 Y) \/ j3 T0 x2 j
protected:
9 u2 _) F" Z4 f! \. f; ?$ }3 V volatile TRISTATE m_bUPnPPortsForwarded;3 W5 Y- V( k/ r8 F, W( x# i, h3 f
void SendResultMessage();
# [) t! c# }6 _ uint16 m_nUDPPort;: h: F: j" K* E2 z4 n+ K; Q* B
uint16 m_nTCPPort;
% ]& {! T6 Y$ h0 I uint16 m_nTCPWebPort;& ?+ ^- J! _0 B
bool m_bCheckAndRefresh;
4 V0 ^ E+ j) ?4 W1 a3 F/ ]7 \( M& n; z3 o6 {" Y0 `
2 V: E0 s, l1 a5 y4 [4 q5 M
private:" ~1 w/ n2 _$ K+ S# [% {
HWND m_hResultMessageWindow;
0 g6 i, m" j$ n! ?+ h: \ UINT m_nResultMessageID;
4 f1 N# X, ^6 e& k0 \+ X) V1 |( @! N2 x' a9 J+ N C
# V" ^9 V8 |) C9 Z};
! O) y2 q* P3 _. U7 H* Y1 i& O
! m# F& O1 L) n. |
- Z; i/ j3 ?4 d) @0 g& E// Dummy Implementation to be used when no other implementation is available# U( T. U/ b6 T0 D% ^
class CUPnPImplNone: public CUPnPImpl2 j# M) X( ` S4 T0 c
{
! v4 x/ P C2 c0 C5 V) {+ {public:) i( f( w5 ~+ K' H1 o
virtual void StartDiscovery(uint16, uint16, uint16) { ASSERT( false ); }& c0 j: W: n5 c# ^ |3 P
virtual bool CheckAndRefresh() { return false; }
! S- d) F1 x* y virtual void StopAsyncFind() { }
! S; n; Q- r4 F; g1 r virtual void DeletePorts() { }; `0 Q! X/ B% W& `8 P
virtual bool IsReady() { return false; }
9 s1 X' f4 p& M) ], Y: }8 X virtual int GetImplementationID() { return UPNP_IMPL_NONE; }* ? m5 N- `1 H" h" d: H$ M0 ^! ?
};
- b7 c9 {, V5 Q: h! X. r+ w" [* ?# m) y1 F: d
$ k" L% }* [% m! ^* P/////////////////////////////////////" c; {# Z6 T" ^4 L) [) s5 V
//下面是使用windows操作系统自带的UPNP功能的子类8 C5 g. Q( z$ W' z: V- U/ [
$ H5 j- `0 o+ z0 x$ ^
( {3 _$ I/ U. K U
#pragma once
- y W R/ s- K7 T9 C' _#pragma warning( disable: 4355 ): B5 d. D2 s: ]/ B- a+ R! ^
2 J. y. G7 ]7 ~" \& {+ o
" u& A6 b) u2 t$ j
#include "UPnPImpl.h"
f3 p( y3 s y3 Y8 a#include <upnp.h>7 r, D% ]- }5 G% {. @: j
#include <iphlpapi.h>
; |5 ^/ _& ~1 P8 H( h, z0 A#include <comdef.h> Q, p d1 c) C! u4 K' [
#include <winsvc.h>
- Q& Q8 o+ }9 W5 {- j
% G8 s9 m7 `' q! v
5 \" W- e3 j& c, X# T! P5 ]#include <vector>
0 |* U5 y; N4 A. N#include <exception>
& a' P4 D! Y) |# B7 m4 g#include <functional>3 Z Z# A7 g$ q
. |* j$ D3 R9 X+ {$ K/ A* K4 F' \) \
0 z2 z" }# g H' S+ f6 V0 v1 F9 f4 V
" a7 N" i: V4 J7 ~5 X# L' ?4 o e/ O+ n
typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinder,&IID_IUPnPDeviceFinder> > FinderPointer;
$ s3 W) x. e& r5 n% \* Q8 @typedef _com_ptr_t<_com_IIID<IUPnPDevice,&IID_IUPnPDevice> > DevicePointer;- o3 r/ ?& K& G2 N
typedef _com_ptr_t<_com_IIID<IUPnPService,&IID_IUPnPService> > ServicePointer;
: T7 _4 s Q: qtypedef _com_ptr_t<_com_IIID<IUPnPDeviceFinderCallback,&IID_IUPnPDeviceFinderCallback> > DeviceFinderCallback;' O- A. R2 ]+ z, y% C+ o0 h
typedef _com_ptr_t<_com_IIID<IUPnPServiceCallback,&IID_IUPnPServiceCallback> > ServiceCallback;
" ?$ W& r# y6 W, n) Vtypedef _com_ptr_t<_com_IIID<IEnumUnknown,&IID_IEnumUnknown> > EnumUnknownPtr;
$ V: Y' G) ?, }3 N2 Htypedef _com_ptr_t<_com_IIID<IUnknown,&IID_IUnknown> > UnknownPtr;' }9 P* H2 _3 g% ~5 q0 A' Z
, q' h. _& \8 `& a- u. ?+ J& P/ q- F8 N0 r3 {( _' G3 o, G
typedef DWORD (WINAPI* TGetBestInterface) (
( S$ B" z- C: } IPAddr dwDestAddr,
( l% K% s: a$ ]0 C: O PDWORD pdwBestIfIndex8 T7 F& O9 k, ^- o. f$ {& F3 K7 ~
);
5 P* G9 `( h) U7 G6 B4 ^9 H B$ g( @
8 C) w& t0 z: E
typedef DWORD (WINAPI* TGetIpAddrTable) (! `: l' n' X# c. p
PMIB_IPADDRTABLE pIpAddrTable,# a3 G; J2 ~* ]' q9 V7 T; O' g
PULONG pdwSize,& ^% n3 t" @) P" d' c7 g$ s
BOOL bOrder
. Z8 q/ j, r8 o9 @- \- D3 p);
3 n" M* e" }0 I9 k0 ?$ }: l, @1 F+ e8 G. k- |
% \; H% P# M; w% R( U- B6 }, ytypedef DWORD (WINAPI* TGetIfEntry) (4 F1 i+ N, Z& V1 |) D
PMIB_IFROW pIfRow4 p/ |0 v& M9 U
);
( T i+ A3 ]; t4 S2 {- c% a5 |
1 {) ], [# S- F7 q1 i* V
, D4 S7 @, b+ }3 i8 b. E1 _& dCString translateUPnPResult(HRESULT hr);9 `2 p" H7 P9 m
HRESULT UPnPMessage(HRESULT hr);
' S# N% i' P' ]4 r" f) t! r
% g6 q* J" x5 a0 [
7 F+ Z7 _# b3 B# }$ Aclass CUPnPImplWinServ: public CUPnPImpl
5 p+ t9 _( P" `3 b{5 P8 M' N/ S- P6 V9 o
friend class CDeviceFinderCallback;
; n S& M5 t1 ~1 i* A" Q2 J friend class CServiceCallback;1 x# L) N/ G* e: a8 i
// Construction% V) [8 x7 x6 Z) V8 F0 K: W
public:
# S8 `0 I. ?! d! N* L* C! [ virtual ~CUPnPImplWinServ();( {4 h5 ?8 I | H' }
CUPnPImplWinServ();
8 f- m- ~+ n7 D2 k, n
; D( l/ L' n4 J D7 S# {: E0 R" X; ^# }, Q) i: M, `: v$ i5 y
virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) { StartDiscovery(nTCPPort, nUDPPort, nTCPWebPort, false); }
$ d' u7 Z% Q' D* V. k# B( L virtual void StopAsyncFind();* d6 S/ B- z' w6 |" m. p; z/ K
virtual void DeletePorts();
: {* M+ j, h8 m. V1 |- r9 H3 M virtual bool IsReady();
( W4 A" ~5 R j1 H6 E2 Q virtual int GetImplementationID() { return UPNP_IMPL_WINDOWSERVICE; }
: s5 q1 q6 x2 ~6 U5 u, W0 I( X" g4 N, J
! V! T" p5 r- ~* t. n' b // No Support for Refreshing on this (fallback) implementation yet - in many cases where it would be needed (router reset etc)
/ p! q5 _' r$ W" `! U6 e" ^+ Z // the windows side of the implementation tends to get bugged untill reboot anyway. Still might get added later4 g3 V ]4 L O7 [# c
virtual bool CheckAndRefresh() { return false; };" y3 l1 Q* _, O0 k% E$ \
7 n3 X2 P$ S% P. ^% x
& i! F" S0 L. s$ bprotected:* A7 ^( d' n! `" a) i/ n/ o3 w
void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort, bool bSecondTry);
. R4 s9 e* |, O+ `' _ Z5 N& F0 t void AddDevice(DevicePointer pDevice, bool bAddChilds, int nLevel = 0);* c. ?; l( F- k
void RemoveDevice(CComBSTR bsUDN);. ]9 o+ D7 w+ D# W |' `
bool OnSearchComplete();6 N/ w+ z, g C+ O3 j$ b; B* r* e5 C
void Init();
3 K8 O( b3 I; G5 H% |& Y5 w1 J; l% b( Q0 ~. s6 B6 y9 ]
; |: `8 c7 C1 t2 _% G4 ] inline bool IsAsyncFindRunning() ) W5 g: l/ a2 W x k( H
{
$ `+ B3 g" b: i2 @+ g9 Y5 A' ^ if ( m_pDeviceFinder != NULL && m_bAsyncFindRunning && GetTickCount() - m_tLastEvent > 10000 )
! o5 _1 f, V5 b, v# l {
* G4 c. e, I: ^" a m_pDeviceFinder->CancelAsyncFind( m_nAsyncFindHandle );
* _ Y! y: [) J& r! j8 ~ m_bAsyncFindRunning = false;) j: P3 Q9 L5 ]0 M: R8 Z# n
}
# a: _7 N! M' _ MSG msg;1 l! h3 c _1 I; q! n( S
while ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )8 I5 @4 j+ }8 P; H" y" |
{/ h t4 k) N& Z; S, l% c
TranslateMessage( &msg );6 \9 E8 L2 B% c8 ?% Y
DispatchMessage( &msg );, y8 a( o4 q, V; h
}
$ p, K# k9 C4 c8 d) x5 ` return m_bAsyncFindRunning;+ R0 i3 b6 g3 }9 e! W) a
}
* ]1 l+ q- p, I1 [" ]0 p$ C$ Q& S" G2 i
, V7 t" ?2 G/ C7 b* R% L. H
TRISTATE m_bUPnPDeviceConnected;! m" Q. S3 v& T# i
! @6 o6 w% M& [; F8 k
8 T Y5 n4 I( P5 r6 M8 S// Implementation$ q3 t( ?" E# s- e
// API functions
) Q+ X. ~# t5 n' ?5 z% ?/ g SC_HANDLE (WINAPI *m_pfnOpenSCManager)(LPCTSTR, LPCTSTR, DWORD);
4 j8 @5 E* E4 a w3 {; T3 { SC_HANDLE (WINAPI *m_pfnOpenService)(SC_HANDLE, LPCTSTR, DWORD);
5 X+ b, Z. r3 Q- t9 Y, b BOOL (WINAPI *m_pfnQueryServiceStatusEx)(SC_HANDLE, SC_STATUS_TYPE, LPBYTE, DWORD, LPDWORD);& u" D3 f/ x( h, [6 c% [* {+ m" [
BOOL (WINAPI *m_pfnCloseServiceHandle)(SC_HANDLE);
6 O2 {. j6 Q2 Y- E5 Z BOOL (WINAPI *m_pfnStartService)(SC_HANDLE, DWORD, LPCTSTR*);
) ]; w2 }, T* k; E: j: I BOOL (WINAPI *m_pfnControlService)(SC_HANDLE, DWORD, LPSERVICE_STATUS);
5 i- n: n+ t* [
# p2 X0 Y7 G5 B, x* v% R* p
, n$ `1 i9 {7 H4 n8 ] TGetBestInterface m_pfGetBestInterface;
1 X! i- W, S5 e TGetIpAddrTable m_pfGetIpAddrTable;0 \9 {/ n- ] F8 n6 }% w; t- A
TGetIfEntry m_pfGetIfEntry;
, a+ l0 m9 D. H1 G. X* x( T! e( |% t
# y& s) }# T1 Z+ A static FinderPointer CreateFinderInstance();6 Y9 T! u# R c& A$ [! ?0 P
struct FindDevice : std::unary_function< DevicePointer, bool >
- V2 h+ i+ ?& w' ]) a' p! s! D" ~ {
2 r1 S; G2 H1 w1 ~: Q O FindDevice(const CComBSTR& udn) : m_udn( udn ) {}
. Y3 d4 G/ a. j8 R' T6 z) e* C result_type operator()(argument_type device) const
! A4 P+ N9 T( {$ }1 ` {- o& \1 | q* g$ y) ?5 O4 W0 ^
CComBSTR deviceName;
2 e5 V% e! h1 p3 P+ r HRESULT hr = device->get_UniqueDeviceName( &deviceName );
3 c. Y* X5 n" p! S8 E6 i* t$ Z1 b+ R' i u2 P$ f2 d" ?: q
1 B6 J- _/ h7 w
if ( FAILED( hr ) )
8 n$ @' V- q4 R; O return UPnPMessage( hr ), false;* C& S4 N0 E. b$ l" \. }6 t
6 i4 k" `: @6 L6 G* V8 I$ ~% y7 A1 T
return wcscmp( deviceName.m_str, m_udn ) == 0;) Q, W. N9 ^( C) x3 b( J
}7 m# ]$ t6 k5 s- ?. P
CComBSTR m_udn;
" d8 N, I# Q2 K };' v6 ?' j- N: V7 P
& I, m) X- w) |( Q+ M8 ^+ L void ProcessAsyncFind(CComBSTR bsSearchType);
( j8 j; [, T0 S7 j% R0 ^0 } HRESULT GetDeviceServices(DevicePointer pDevice);; G0 E9 e9 p7 w1 w+ ]' |2 g& h
void StartPortMapping();
. \9 k3 U, A2 c HRESULT MapPort(const ServicePointer& service);
* h; g9 [% G. E `8 C- D void DeleteExistingPortMappings(ServicePointer pService);* g3 K9 p# @3 D7 o9 I
void CreatePortMappings(ServicePointer pService);
0 ~/ r; y% ]; K$ ], O8 J HRESULT SaveServices(EnumUnknownPtr pEU, const LONG nTotalItems);- [" u4 S2 K' ]* ?% C: Y6 A+ a" i
HRESULT InvokeAction(ServicePointer pService, CComBSTR action,
6 E' R5 R$ u: ^ LPCTSTR pszInArgString, CString& strResult);
; }7 N, q* s# B/ z* g( p+ E! ^ void StopUPnPService();6 }* i" v4 z% g# O( F( O2 J. j
! V' O S" g N# Q0 z4 O
, o: N: S/ R7 a/ w: O // Utility functions
# U) H. e- t6 K$ v( ^ HRESULT CreateSafeArray(const VARTYPE vt, const ULONG nArgs, SAFEARRAY** ppsa);% G2 q9 x i/ e4 i
INT_PTR CreateVarFromString(const CString& strArgs, VARIANT*** pppVars);
0 g% B5 W5 Z3 I8 X4 d* t INT_PTR GetStringFromOutArgs(const VARIANT* pvaOutArgs, CString& strArgs);
! q* `; V/ B! o! ~" m( k( u% M: G void DestroyVars(const INT_PTR nCount, VARIANT*** pppVars);( N% R/ b$ d: w+ |
HRESULT GetSafeArrayBounds(SAFEARRAY* psa, LONG* pLBound, LONG* pUBound);8 i. H( p- V) T; o+ {% a( V
HRESULT GetVariantElement(SAFEARRAY* psa, LONG pos, VARIANT* pvar);
$ t; ?0 J) W$ j* e7 y CString GetLocalRoutableIP(ServicePointer pService);0 ~7 {3 B7 r! j- I0 t' [+ U
/ F& K: M. X! T# y7 \/ `' o- ^$ H: H2 f
// Private members
0 p0 a7 T- F4 M) b1 qprivate:# ]9 f1 y/ B) S5 e A' \$ i1 w
DWORD m_tLastEvent; // When the last event was received?; B0 l8 X" P# i( |( D8 Q* g/ D
std::vector< DevicePointer > m_pDevices;
; f. I* p, M2 ^ std::vector< ServicePointer > m_pServices;
1 U7 `* l3 L# d# _4 J' }3 U FinderPointer m_pDeviceFinder;
0 Q- p9 ~8 A: M: ?" T$ _8 j" @ DeviceFinderCallback m_pDeviceFinderCallback;
6 V1 w9 D B$ z# X x- @* Y ServiceCallback m_pServiceCallback;
8 h2 j+ e1 b, ~; O w; N N) @! ?* A! X5 _* h# N# ?
4 n: Q; e# C2 ^) N! y6 j LONG m_nAsyncFindHandle;1 n! \1 W1 T" B9 c. C! D- o/ \0 i
bool m_bCOM;# x* Q0 {7 s6 Q- k
bool m_bPortIsFree;
. q3 n9 ~2 |- u( G; o% | CString m_sLocalIP;
' A! ?* s; x3 O0 p" ?) \ CString m_sExternalIP;
$ ~ L- v8 d/ _* o+ I% a! k6 F bool m_bADSL; // Is the device ADSL?) J i3 r. W- S, T) ^. J% @
bool m_ADSLFailed; // Did port mapping failed for the ADSL device?9 b$ U0 u- X7 O, |
bool m_bInited;
% L& x5 X- Z5 ^# `7 M/ b. h bool m_bAsyncFindRunning;2 [: C' g9 T4 U
HMODULE m_hADVAPI32_DLL;
. m( A/ t4 v8 W! ^ HMODULE m_hIPHLPAPI_DLL; [) K1 @. D$ L8 @8 B
bool m_bSecondTry;* Z; l, N* L& Z) q; H
bool m_bServiceStartedByEmule;
2 K" {) I. C, k/ Y1 c bool m_bDisableWANIPSetup;' q1 Z' `! P- m5 W' u! r1 e
bool m_bDisableWANPPPSetup;3 n# `; {+ D9 X) F3 `
' `) \% w' k _, q2 E5 o( {: M9 y$ c2 N5 `' s. t9 H V: S
};( A9 C: K/ I: B6 U
, e+ {5 G* |7 p4 i2 _
5 K$ q8 m( h2 N; P- _/ X- C// DeviceFinder Callback ?/ M/ u8 |/ \ p0 o
class CDeviceFinderCallback
# @' ` x* p7 F" i* T* J : public IUPnPDeviceFinderCallback* Y( Z/ ~+ K. L" G: Q9 R$ J6 ~2 L
{+ o6 }0 p7 u1 g3 ]! c
public:
1 q8 e, V( `, J: [+ A8 F CDeviceFinderCallback(CUPnPImplWinServ& instance)
7 }0 s& U u6 {8 E. _ : m_instance( instance )( h- w$ i8 a9 t9 A3 H! o8 g
{ m_lRefCount = 0; }
" I6 Q2 v! v# U# H+ n7 f
5 l. x- \/ o- E, k3 p) O
8 P. S9 l4 ?8 L+ p STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);& ?' x; j- J% Z% a6 K
STDMETHODIMP_(ULONG) AddRef();
8 T5 p1 T$ T0 F6 i# } STDMETHODIMP_(ULONG) Release();9 w/ O! ^) r7 t( n0 S& R. e
# i% m0 I( t: G2 m/ u- k! h
$ c P4 ^+ a) g7 H7 R5 \// implementation
- h& @2 Z6 S+ Q3 h, f( Mprivate:
6 D9 I# G8 Q V1 s( s9 \) f. y2 Z" d HRESULT __stdcall DeviceAdded(LONG nFindData, IUPnPDevice* pDevice);1 ^% h$ E& R! R
HRESULT __stdcall DeviceRemoved(LONG nFindData, BSTR bsUDN);
& |* d( s3 H% J J; W HRESULT __stdcall SearchComplete(LONG nFindData);
/ S- L' }* |# B4 r/ r0 u
7 V0 ^& a! I+ ]) J7 Q, u
9 Y7 Y) C, E6 Sprivate:" T" t, s. n: I8 Y: ~6 m: F; }2 Q, r
CUPnPImplWinServ& m_instance;/ ]! _7 u& H% l0 Z$ _5 D( [2 }8 z
LONG m_lRefCount;
$ X7 x$ ]+ _; t# f3 `1 o4 \- b' R};; q) p! \& s: j
3 J K- Z \+ j' g/ `# c4 w0 M
- P' S# I0 m/ w. {
// Service Callback
: l* Y9 H' i( g3 h! h0 lclass CServiceCallback7 h; B8 H% }5 E& z. p
: public IUPnPServiceCallback
5 L. _% S% c N% C2 K{
% f+ m& X% k" O( ^: opublic:( ~, Y& D4 `% K2 P: g
CServiceCallback(CUPnPImplWinServ& instance)
. Y7 F9 o. }: r7 u' w : m_instance( instance )7 R- H3 _) N0 L4 N8 d2 _7 @! y
{ m_lRefCount = 0; }
0 \9 S. c. |) P3 z% D3 \ 3 M5 O& f. E# @. Q* Q
STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);% p2 F/ L A; \4 N
STDMETHODIMP_(ULONG) AddRef();
3 W( @ ]6 Q7 V: m" X STDMETHODIMP_(ULONG) Release();
7 c* S# J6 w4 j `. b6 j' G ^' W- i8 ^5 [$ I# v& v; F
5 h* P: ~9 h: h// implementation
, j/ O0 Q9 B- {' Pprivate:
( U9 o3 f7 g j7 o HRESULT __stdcall StateVariableChanged(IUPnPService* pService, LPCWSTR pszStateVarName, VARIANT varValue);
+ r/ A" x4 m3 n2 r6 W" G3 ? HRESULT __stdcall ServiceInstanceDied(IUPnPService* pService);4 s3 J+ G# q: ]* j$ Y4 ?
$ l+ e1 R# Y& v6 B( Q
0 b) E1 \: C9 eprivate:% E" s, k0 D# x* C/ m# b7 q. o
CUPnPImplWinServ& m_instance;' p- m' @& P+ ? a M+ [6 s" ?( u
LONG m_lRefCount;: W; x6 c+ c$ N, ]6 r* y1 g5 U# p
};2 d; q+ T, F l1 e2 ^# k4 C# q/ w
& I& K3 W6 x0 z+ `) t) S
# \$ L- m4 a8 [* m: R: q) u/////////////////////////////////////////////////2 c! `' O2 y* e% ]" a) y
$ T1 _9 N, [2 u6 f8 ~0 d: O4 B4 q: X
使用时只需要使用抽象类的接口。, Q. g2 f0 s+ Y V* S' \5 |. @) x
CUPnPImpl::SetMessageOnResult设置需要接受UPNP端口映射是否成功的窗口句柄和消息ID.
4 u# m: R) l9 V7 oCUPnPImpl::StartDiscovery将开启一个异步设备查找并进行端口映射,其参数为需要映射的内网端口.! F! U& B5 A4 y2 k2 k& z1 r
CUPnPImpl::StopAsyncFind停止设备查找.& F' y( M, p5 {2 g0 P1 p
CUPnPImpl::DeletePorts删除端口映射. |
|