|
|
楼主 |
发表于 2011-7-15 17:28:52
|
显示全部楼层
以下有关upnp的接口来自emule,5 A. ~ n2 ^5 o+ @6 ~9 p
1 Q, X7 y6 i% i% ?* z7 `1 u0 T
# w& T# \1 q3 H( w///////////////////////////////////////////
/ M0 C7 f) j" \: C# x4 w5 b' X//upnp的抽象接口类,只需调用这些接口即可实现端口映射功能.
$ I% A! H: C2 O1 s
\4 ?/ T* Z& S, J2 g0 J8 _+ L
% h5 Y' W7 [5 [; n+ @#pragma once, J3 V1 }. }7 a, x$ @: n. E
#include <exception>
: |) D+ C' m5 g3 T$ e, r" F* ~( z! P/ J& @ z# e+ {, d; Y
% s% ~# t# V T5 A
enum TRISTATE{
) [/ B# s+ j. ?& t# n P TRIS_FALSE,
7 A$ X3 J& M) p9 C L TRIS_UNKNOWN,
- O+ N" B K/ R& V# x+ D TRIS_TRUE D9 h& J0 W: t S7 g
};
' W* J7 y* W& L. J# l9 f
0 z$ e: R) c, j& X5 A& V8 n' Y; O) w% d
enum UPNP_IMPLEMENTATION{
$ M, H5 X x1 M( U1 m UPNP_IMPL_WINDOWSERVICE = 0,
3 `" l4 [9 e7 v% a. I; _ UPNP_IMPL_MINIUPNPLIB,
+ H* c8 l5 L& S" W: w( c% P UPNP_IMPL_NONE /*last*/4 W- S, u1 G. O8 e, G( u C
};( {8 ?% f6 h! }* S3 O" d' o
! i- R# g& R( F, \
. c6 H6 A: p' Q+ d! V0 w; L+ ]( l6 z: e1 {; ~5 X8 d
0 |/ E' C( I4 X6 N% n
class CUPnPImpl
, g2 d1 k2 L, B8 v& \{ h0 s* D/ _0 W" F& P
public:
- F% H3 E5 d( D4 ^ CUPnPImpl();
J4 m- N# X3 ]% p2 x0 m! f virtual ~CUPnPImpl();
* G/ O5 D& J( k& k9 A struct UPnPError : std::exception {};
6 K: D4 T, W. c# w& R enum {+ A. n3 {' G4 Y; h, O) ]0 j
UPNP_OK,! X: ~' @$ D$ [ h) ?) C1 ^- Q
UPNP_FAILED,0 h7 R; e, r1 @
UPNP_TIMEOUT
; H" U! X) I3 B$ Y };
' L! {# T$ m! x. l# t, t- n. i- k, F- ?4 B6 R
9 a! u2 Q, k: S virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) = 0;% m6 ^, n8 l- w+ n
virtual bool CheckAndRefresh() = 0;
( t- u0 r. U T. p& A- O* t' z virtual void StopAsyncFind() = 0;3 o6 G& d: ]" y+ e6 {. ^3 t H
virtual void DeletePorts() = 0;
% D6 j0 I a" A8 f virtual bool IsReady() = 0;
' t3 r9 R8 H2 |! u# f virtual int GetImplementationID() = 0;
' K% H8 c6 X3 l. m
! h/ \' ^% \: m, s5 D void LateEnableWebServerPort(uint16 nPort); // Add Webserverport on already installed portmapping6 H8 d7 F h; n& O" @ u1 C
3 t1 ^& n0 n3 i& P+ E
" F" t' D3 n& R. @+ ]8 T! r8 L4 d void SetMessageOnResult(HWND hWindow, UINT nMessageID);
" @8 X% \# Y7 T/ N6 w TRISTATE ArePortsForwarded() const { return m_bUPnPPortsForwarded; } o! W1 j; v* }. C3 s
uint16 GetUsedTCPPort() { return m_nTCPPort; } `" s7 G' w5 ]- V. B0 Q9 b: h
uint16 GetUsedUDPPort() { return m_nUDPPort; }
! Z+ S, o+ Q2 M6 u4 t( \; v" e! l" ~7 H }1 p, z3 G+ x( q! |
, K* l) _ P9 T. G& a: A: m2 w# i; @
// Implementation
0 Z3 L5 |/ i0 u) V: k) C1 T/ ?protected:
* @) I) s$ M8 G i$ z S' t volatile TRISTATE m_bUPnPPortsForwarded;' _3 G+ l P% k! ?5 t/ X
void SendResultMessage();0 M* ]8 L; z$ C+ _. ~
uint16 m_nUDPPort;3 _; V5 p+ Z$ e
uint16 m_nTCPPort;
' e0 _8 f' M' W& _6 w; a* r uint16 m_nTCPWebPort;. ^8 m, d" T# t J; `; U
bool m_bCheckAndRefresh;0 B* d& [4 O( j
. i5 E# l- o6 I% Z8 G+ P
" l3 {. X# L1 g- l# J @
private:
4 e+ q) Q7 {3 y$ u HWND m_hResultMessageWindow;' T+ q) ^: ^# b' h# _
UINT m_nResultMessageID;
' O& t! C( l+ a" ^, P; Z) o
: A0 j E8 p4 q. g& ~, t2 f+ H R0 ?" o% {1 ]
};6 H3 \4 Z F2 ?
$ S, j& Z- E1 {. f3 J
1 T! L% {) j! d6 y2 {; e" p
// Dummy Implementation to be used when no other implementation is available
. U1 M2 |& {. k3 Mclass CUPnPImplNone: public CUPnPImpl6 F) U/ ^2 V! Y/ E
{
1 Q6 q, G, M6 E9 |$ u' }+ ]$ Zpublic:
6 O' o; q O" U* o/ r# j virtual void StartDiscovery(uint16, uint16, uint16) { ASSERT( false ); }
' @' [4 b3 z: w4 E virtual bool CheckAndRefresh() { return false; }! [3 z$ k7 f# l+ E2 d( [+ Y7 }( R
virtual void StopAsyncFind() { }
0 s) q' l0 i% {+ C1 l virtual void DeletePorts() { }% Q, r% y& |# y+ G8 ]# U
virtual bool IsReady() { return false; }
! J8 `) L0 ^$ n$ Z virtual int GetImplementationID() { return UPNP_IMPL_NONE; }
, o1 s' O7 @$ b c' K \$ C# e};
* J- w# F9 H, t& }- N$ A5 n
& ?8 h2 H5 w( z; L5 R" u T: X! R( ?* ~$ U3 Q, G' `$ c
/////////////////////////////////////
' ^+ u9 P7 _: I: }. H# L//下面是使用windows操作系统自带的UPNP功能的子类
7 b: o3 W/ m) N% g- a
* I' N: s8 }8 Y2 b4 D$ t3 `0 J, K0 e7 g$ p
#pragma once
' h( {$ s6 S) N" @6 Q#pragma warning( disable: 4355 )
9 D0 ?5 {* `) i" R: W8 v
: l+ D& n! b9 {& w- F0 M- [9 x$ @
#include "UPnPImpl.h"9 M" A& \! i/ i% c- q r7 e3 c
#include <upnp.h>
~* T+ _- S) ~& E#include <iphlpapi.h>, X& K* u M# z" r& y
#include <comdef.h>
9 V9 N" a9 T% j# }8 U#include <winsvc.h>
5 B i$ h# S5 a2 s- R; w y5 W) R0 u, B; B& S
; _$ L. h% n5 l7 A#include <vector>4 a# R3 x2 I7 k+ p, z( {6 n8 i
#include <exception>
9 o8 G5 u# t2 c) W#include <functional>: l% Z: `. {2 g. Z
) m I) k, B2 n( `1 Y4 q
" Z1 F6 b! e& V5 R3 o
) m) ^4 S" c, m
8 i: p, l2 d: O6 O, U2 b
typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinder,&IID_IUPnPDeviceFinder> > FinderPointer;0 Z) ?8 c- y% o! _) U
typedef _com_ptr_t<_com_IIID<IUPnPDevice,&IID_IUPnPDevice> > DevicePointer;
7 i: t" `+ q/ E. P9 I3 z' s5 {typedef _com_ptr_t<_com_IIID<IUPnPService,&IID_IUPnPService> > ServicePointer;
* P* ~: O9 [" f) jtypedef _com_ptr_t<_com_IIID<IUPnPDeviceFinderCallback,&IID_IUPnPDeviceFinderCallback> > DeviceFinderCallback;) Y6 D) ]7 b! G% ?$ i, @
typedef _com_ptr_t<_com_IIID<IUPnPServiceCallback,&IID_IUPnPServiceCallback> > ServiceCallback;
, u+ X8 L% J5 n+ b5 n) Atypedef _com_ptr_t<_com_IIID<IEnumUnknown,&IID_IEnumUnknown> > EnumUnknownPtr;7 R8 n$ q% A7 _6 t, k: D
typedef _com_ptr_t<_com_IIID<IUnknown,&IID_IUnknown> > UnknownPtr;) `; u* t9 x1 `* [9 _
2 q {& D) _* y5 X; M+ I2 T$ T) U' ] v! U4 H9 b/ C/ m
typedef DWORD (WINAPI* TGetBestInterface) (2 |5 H- Y; g; N2 K, Q, P- U1 r
IPAddr dwDestAddr,
9 { K- u7 C! g1 F& H PDWORD pdwBestIfIndex
, H }# H; r4 S( o. `5 k);& D9 r* v3 ?9 A/ x. t+ x' y
g& j3 F, J u! V" w
2 _, x1 H6 C, q- m' g+ t9 itypedef DWORD (WINAPI* TGetIpAddrTable) (7 t3 }) e% l; C0 B( f
PMIB_IPADDRTABLE pIpAddrTable,/ k9 J9 [8 G( c. d$ h! @
PULONG pdwSize,4 C0 Q/ a' O! p) F0 L$ m3 Q& [% X8 l
BOOL bOrder
. P/ E& M$ a( g1 t);
e# f+ h9 w( K' w) a! w5 b& {, a0 T3 ?% c) \
~1 i& b' e8 `) S& ^typedef DWORD (WINAPI* TGetIfEntry) (; L; ?/ d* z( E; ~ `
PMIB_IFROW pIfRow; J. a6 L7 D- ]: ?
); I% A; y( B; B9 a+ e1 a
* N# b2 a* C; d) r( i( w) ~( i
5 h4 ?. S$ |" {: K# V t# ~* JCString translateUPnPResult(HRESULT hr);7 n2 c' H' G; U! j, D
HRESULT UPnPMessage(HRESULT hr);
& A4 L1 s# W3 A2 C0 ~- s) F7 [
- F! b, d4 M( [3 W3 u6 i( S9 J; x- u4 c Z
class CUPnPImplWinServ: public CUPnPImpl3 ~9 r; N7 p8 I$ X
{
) g) l9 k- g" X; p8 @2 T$ k friend class CDeviceFinderCallback;
! o8 F" a4 d9 `5 v a- z" L friend class CServiceCallback;) N: w2 t5 _( j# D5 i+ c. ]
// Construction
0 p' R+ l: r8 ?2 E$ ~& G( dpublic:
7 e/ o- F7 {! ] virtual ~CUPnPImplWinServ();
F& z& s8 x0 ^ CUPnPImplWinServ();: |8 i x. Q3 Y8 o" c: |
5 q1 B5 d" B7 ] \9 C! W |8 L6 |3 m- h: ?1 c. B
virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) { StartDiscovery(nTCPPort, nUDPPort, nTCPWebPort, false); }
# ]; m7 a o* P: k virtual void StopAsyncFind();
+ _- `. e# Q, @+ T& [/ B* J" [) \ virtual void DeletePorts();
( @ H' Q8 i V virtual bool IsReady();
) @& L$ Z2 j( }+ k5 N virtual int GetImplementationID() { return UPNP_IMPL_WINDOWSERVICE; }/ B$ J0 p9 }5 c1 ]. i5 y! }1 Y1 }
8 ]& I! K9 Z/ x! x
* ^: B; h4 n! k. Y
// No Support for Refreshing on this (fallback) implementation yet - in many cases where it would be needed (router reset etc)
0 c. a9 r2 ?1 w @: p // the windows side of the implementation tends to get bugged untill reboot anyway. Still might get added later. d& r" D. H1 p" q; E, }( D% B1 N
virtual bool CheckAndRefresh() { return false; };
h$ F$ E) q* h, E8 D* D2 _
' \$ @. d" ~ D/ B9 D9 ?6 W2 ^% K
7 M' Q5 M( B7 xprotected:
2 s8 q9 D3 D" k. j# A4 | void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort, bool bSecondTry);
8 b t/ N' J- L6 H void AddDevice(DevicePointer pDevice, bool bAddChilds, int nLevel = 0);
5 ]6 Y2 H2 j1 i void RemoveDevice(CComBSTR bsUDN);
" |8 I+ e. G& I6 Q+ w8 R: x4 {6 o bool OnSearchComplete();
, L, W" O8 i' \3 t: s void Init();/ _8 {% I+ ~: V, ~) t
) S/ c6 G$ H6 w9 o" s* h: b
8 P& F3 a$ h" K! D inline bool IsAsyncFindRunning()
* q2 B$ t( ` i2 j9 c# ~ {! [* L3 E! J( a
if ( m_pDeviceFinder != NULL && m_bAsyncFindRunning && GetTickCount() - m_tLastEvent > 10000 ) ?9 t7 q2 v j6 d# b7 L+ f( n
{4 G, t3 d# i/ J
m_pDeviceFinder->CancelAsyncFind( m_nAsyncFindHandle );4 `) i* Z2 R' g' I% ~# Q. x8 n
m_bAsyncFindRunning = false;/ W: c" _, [; S& I0 P/ \# {
}) |3 U5 H* W/ ]
MSG msg;
* J# ?5 \* @* |7 p+ D+ O while ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )0 D Q; ]4 |7 H
{
7 C% Z+ J4 ~" q TranslateMessage( &msg );
6 U, }+ c2 O' f4 G9 ~- d3 A! ^ DispatchMessage( &msg );0 c I8 W" d ^" [ J) |( J8 q
}4 ~7 _* ^( p7 @+ E
return m_bAsyncFindRunning;
, V8 @" @% Y5 c. t9 z& j }
( `7 `/ }2 [8 `+ v! R7 | Q
4 N" S3 ?1 v7 y; G) d
: Y% V4 V8 j& y: S# D( t; v TRISTATE m_bUPnPDeviceConnected;
4 U6 s7 O: Z4 H- `5 ]3 P5 V; W! d" A: y$ j7 j4 R' W( G
) R% Z- W# H0 m, ^2 R' Y. t
// Implementation
3 F7 V g, a3 R# l: Y // API functions0 K0 h: a, w* [. y a
SC_HANDLE (WINAPI *m_pfnOpenSCManager)(LPCTSTR, LPCTSTR, DWORD);
2 g! r# \# h. g SC_HANDLE (WINAPI *m_pfnOpenService)(SC_HANDLE, LPCTSTR, DWORD);7 J4 r1 o r: M( S
BOOL (WINAPI *m_pfnQueryServiceStatusEx)(SC_HANDLE, SC_STATUS_TYPE, LPBYTE, DWORD, LPDWORD);) s9 t- g+ T) q4 X
BOOL (WINAPI *m_pfnCloseServiceHandle)(SC_HANDLE);+ l" O" L/ L9 |. l
BOOL (WINAPI *m_pfnStartService)(SC_HANDLE, DWORD, LPCTSTR*);
: ?; V, {- L/ ^ L$ i BOOL (WINAPI *m_pfnControlService)(SC_HANDLE, DWORD, LPSERVICE_STATUS);/ j' l" f# L( C9 [5 a3 w* z
: S! j' Q3 ^% T( V
7 o: p* \* E0 t9 T. c$ K
TGetBestInterface m_pfGetBestInterface;
4 p& L' w* t- k& F TGetIpAddrTable m_pfGetIpAddrTable;6 X" ^) v" E1 g% {8 A$ I
TGetIfEntry m_pfGetIfEntry;9 k4 C; h; C" ~* G" V5 N9 l. R
I! `/ V, L) C' {
7 q6 U4 `" Y5 w) A8 J8 Z static FinderPointer CreateFinderInstance();
% j0 m4 l1 a* e2 O# t4 M struct FindDevice : std::unary_function< DevicePointer, bool >+ D& H2 a3 I0 F& t+ Q% b
{
* H. X, [8 j5 S FindDevice(const CComBSTR& udn) : m_udn( udn ) {}( C+ ~" w3 z8 D0 A
result_type operator()(argument_type device) const
7 o8 u$ [* }2 r9 P4 C {' [; l/ c. [' p& L- [8 R4 q+ g
CComBSTR deviceName;
: z1 i; X- |/ p! l2 q HRESULT hr = device->get_UniqueDeviceName( &deviceName );5 y, J( E L! F0 }; k( p4 O4 w
8 g o2 i# y$ @" Z
1 h$ i+ E! T# J! X8 \ if ( FAILED( hr ) )6 L8 n% w+ N$ V; b/ c: F
return UPnPMessage( hr ), false;
d! D( u( P5 S! A
) |9 p' v: e+ z) k* @$ ]
; [( r0 F. y6 P$ k% P2 x& ] return wcscmp( deviceName.m_str, m_udn ) == 0;! U6 V. k: k2 h) k U
}
+ T+ T1 D0 e5 s, O$ X2 i/ v, } CComBSTR m_udn;
2 E8 ~9 J# h e f( j };
4 T, u d) Q0 b+ @& }. ?) R
/ Z6 l* O4 |! q! U& G( s: S5 V void ProcessAsyncFind(CComBSTR bsSearchType);: u& t k; r& \; K5 z
HRESULT GetDeviceServices(DevicePointer pDevice);+ |$ ?8 a0 V) f! H- l
void StartPortMapping();
! o. f3 ^9 e7 o. E. W+ i HRESULT MapPort(const ServicePointer& service);" k( w" X% E1 T5 r
void DeleteExistingPortMappings(ServicePointer pService);$ v6 g( A+ I2 a$ h8 o! g! `4 J
void CreatePortMappings(ServicePointer pService);
& ~' g; A( k( C HRESULT SaveServices(EnumUnknownPtr pEU, const LONG nTotalItems);9 g! s( ` Q2 x) G: b, V9 I4 C; U
HRESULT InvokeAction(ServicePointer pService, CComBSTR action, / m; a8 h; v, g0 a. y! |
LPCTSTR pszInArgString, CString& strResult);% Q7 P$ V: c2 F* F+ y
void StopUPnPService();* o& f4 l* c0 G5 q
7 p0 {5 S* A% ~; o+ l, K
% M) F) h7 |/ k' R' \" `
// Utility functions) m8 r) f0 m, G6 N$ `% O9 K9 K$ w
HRESULT CreateSafeArray(const VARTYPE vt, const ULONG nArgs, SAFEARRAY** ppsa);
1 |. |. _5 x' {4 U* v INT_PTR CreateVarFromString(const CString& strArgs, VARIANT*** pppVars);3 V! C* d" J0 l) s+ g% h
INT_PTR GetStringFromOutArgs(const VARIANT* pvaOutArgs, CString& strArgs);5 T# S! A# C; _# u& |( R! S
void DestroyVars(const INT_PTR nCount, VARIANT*** pppVars);
; u; h$ L2 F. X2 X. @ HRESULT GetSafeArrayBounds(SAFEARRAY* psa, LONG* pLBound, LONG* pUBound);
3 Q0 `7 J c6 \2 l! C! r HRESULT GetVariantElement(SAFEARRAY* psa, LONG pos, VARIANT* pvar);0 x) O4 f: l% }' E" Z
CString GetLocalRoutableIP(ServicePointer pService);
* J4 `' H- |- Z8 y% h' S$ H% ^: O5 {6 W% V/ y# n
) d& P+ {, C' V, [// Private members
! C# J% l, y, M* e" yprivate:
+ e+ R3 N) E, Z0 N# |6 ], ^: m DWORD m_tLastEvent; // When the last event was received?4 P( X" l% p9 {) n: Q4 S
std::vector< DevicePointer > m_pDevices;# Q' q1 u1 ~2 I( L/ d
std::vector< ServicePointer > m_pServices;
! Q1 h8 }; J3 Q4 ` FinderPointer m_pDeviceFinder;
* X( i I; B+ f: V; T DeviceFinderCallback m_pDeviceFinderCallback;
9 Y6 E7 O, h: B6 P6 ~/ Z+ Z ServiceCallback m_pServiceCallback;
) @* R! s9 E; v" b- P _- @8 g4 D0 J8 A' n
% D$ U# l/ e9 K LONG m_nAsyncFindHandle;
2 k" r2 N D; l9 G) T; U$ S+ l bool m_bCOM;
* Z. R& o; ?' f ^3 [ bool m_bPortIsFree;& X8 D5 o: P" H' J
CString m_sLocalIP;
( w5 f9 e( h ]8 ^ CString m_sExternalIP;
* T3 b' z9 z- g( L1 H/ f bool m_bADSL; // Is the device ADSL?& G6 Y+ l$ Q# P* s/ A
bool m_ADSLFailed; // Did port mapping failed for the ADSL device?
]* b! k6 R( m. k& g bool m_bInited;6 ~; q1 b! m& [. e$ C7 B0 y, x
bool m_bAsyncFindRunning;
8 d6 E& M) g: D" A7 v, i" f V HMODULE m_hADVAPI32_DLL;
4 S; A2 j3 @: g" ?1 _* v! [ HMODULE m_hIPHLPAPI_DLL;
/ G% W9 I l: T) u5 [4 x k bool m_bSecondTry;3 ~: \% s3 F, x# D9 d
bool m_bServiceStartedByEmule;: U5 J c1 M; I, U
bool m_bDisableWANIPSetup;5 ]" v# X/ Q; Z8 t
bool m_bDisableWANPPPSetup;6 j% X7 R; U/ p
6 o# |6 I( e. [ ~7 l
x& D+ f. `$ ?};, x/ [* ]5 R/ b1 y; K- \
% g7 q L( J9 [2 s4 m1 U
. n' J$ z. w7 t4 v( x// DeviceFinder Callback
. v+ {: z* q, yclass CDeviceFinderCallback
, I$ G8 A( |% C9 |2 S : public IUPnPDeviceFinderCallback! Z' _8 l6 o5 `. g, \* D% R4 j
{6 I) O' T9 E" M' ?! e. j6 @1 n1 r
public:
* @' e$ C/ i% T: q8 b; Z CDeviceFinderCallback(CUPnPImplWinServ& instance)! z" }( Z, o f" w% s
: m_instance( instance )
8 l1 L$ H q6 X5 j { m_lRefCount = 0; }
: P9 E6 Q6 K& i9 N: M) E: @' ~
' V9 O' J- c# ]* a7 @' o
8 p7 H$ j( L+ M: f/ K. R; k5 n STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);
/ d6 x8 j' X% w& n9 p+ B+ |% p STDMETHODIMP_(ULONG) AddRef();- h& i* Y4 n; a2 t( m' Z2 Z
STDMETHODIMP_(ULONG) Release();
$ F1 i% C( z9 {$ r2 Q V/ _. ?. G4 h, f- u h+ k
- W$ _$ O; [6 i' x* r// implementation
" m5 t9 V! d/ aprivate:
6 A5 r9 P3 i& ?7 X HRESULT __stdcall DeviceAdded(LONG nFindData, IUPnPDevice* pDevice);
' d8 j9 ]- i! S9 p' u* s- W HRESULT __stdcall DeviceRemoved(LONG nFindData, BSTR bsUDN); ]" b* e& t* h" _/ r. y$ i
HRESULT __stdcall SearchComplete(LONG nFindData);3 V- \$ \7 U5 c& x
% X5 R4 {: |2 |- Y
% c0 {! x- S$ I4 r* h
private:
H( C: y+ D* I2 U$ ?7 h6 M CUPnPImplWinServ& m_instance;
1 `0 \( E: Z/ u7 z LONG m_lRefCount;
$ f: y& Y- t W1 U}; X7 ^- ^- H- E( }" [6 A p
: o+ q2 B) M, i b, f e& g
3 s Z' ?2 o% j" y O8 M// Service Callback 0 Y$ n! `+ k" s% f
class CServiceCallback( U$ G( C. g4 |: C
: public IUPnPServiceCallback6 A+ L; R9 P& i. }9 n7 Q4 A- M
{: w7 I% X3 X" ?0 D! y! o
public:7 Y' ~9 ^1 m, v% T3 F
CServiceCallback(CUPnPImplWinServ& instance). b* W( Z& }3 Y! \0 `6 O
: m_instance( instance )" [/ e: ?& M$ i& M
{ m_lRefCount = 0; }+ \$ V3 V% L, y$ K8 r2 c# D6 D
8 ]+ a0 ?5 p( F" T6 _
STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);: N6 D( G s: R$ r, O
STDMETHODIMP_(ULONG) AddRef();
0 C6 G. A- ]3 O* s STDMETHODIMP_(ULONG) Release();
. e' E- @9 z* `6 I8 D; Z. S' o! R! }; ^' g
7 u/ Z* G1 i- A3 P" a
// implementation
, @5 ^# Z J8 q- z" g: [private:
; l5 a& {: p! y0 y6 v8 f. q HRESULT __stdcall StateVariableChanged(IUPnPService* pService, LPCWSTR pszStateVarName, VARIANT varValue);* R$ a& z; r2 x& |+ L
HRESULT __stdcall ServiceInstanceDied(IUPnPService* pService);
g4 I: {, N! J. ~& M3 L& K; e( k& R( u, R3 x
j t7 X' R3 W! Rprivate:3 {5 x: ^! H' S$ R! c
CUPnPImplWinServ& m_instance;
8 x/ s/ {& L: P' e: D LONG m_lRefCount;
& m- a$ o+ o+ E8 [/ C9 v};2 {4 v G1 Q4 D$ i l: b+ X- A; B
) {# H6 k1 B- f6 B$ N! m. m# b8 H. y# F* B7 h
/////////////////////////////////////////////////
* [1 q+ V, Y3 `' u7 U% l9 u, a$ g0 U, x3 u
6 j1 X4 k! r% g; p0 V) u
使用时只需要使用抽象类的接口。
+ `( \- u# C; a+ b, @0 {0 ^1 bCUPnPImpl::SetMessageOnResult设置需要接受UPNP端口映射是否成功的窗口句柄和消息ID.
$ p: ]3 i! U( w) I# x) tCUPnPImpl::StartDiscovery将开启一个异步设备查找并进行端口映射,其参数为需要映射的内网端口.
. x. Q9 a) p0 M' x1 RCUPnPImpl::StopAsyncFind停止设备查找.
# ~( x( t& ] W0 U$ _5 FCUPnPImpl::DeletePorts删除端口映射. |
|