|
|
楼主 |
发表于 2011-7-15 17:28:52
|
显示全部楼层
以下有关upnp的接口来自emule,
' z% W0 D$ o5 [9 i" H6 ?' u: h, P/ a F# z. T# `: ^4 G8 A! v6 z
/ q, k0 \, [& T# {///////////////////////////////////////////
2 X% f5 `7 F8 u6 p2 w2 Y/ q//upnp的抽象接口类,只需调用这些接口即可实现端口映射功能.
* \( E! p, C& \" w# c3 j0 [6 z2 @1 }6 Z
( a/ s4 s' V9 M9 t* V2 q: A
#pragma once
' ^( j1 I& m4 y* P' `( Z# \#include <exception>: [0 y3 z" N4 a8 V/ t3 `& R0 w
) x/ I: o% t6 I( Z- j: P' s' Y
$ l2 o" N$ [, ^
enum TRISTATE{
" K3 C) }1 e2 \8 r TRIS_FALSE,; A Y, _1 [+ K$ i! B
TRIS_UNKNOWN,+ t6 ?6 m+ j! e8 N$ b7 D
TRIS_TRUE7 F4 W3 R0 P1 Y9 C" Q$ R- N' g& z
};3 H+ {! h% f' a- l# w3 ?" ?
2 R0 {$ {7 e, B% D, ^9 m0 [/ r+ b3 M9 D- M O
enum UPNP_IMPLEMENTATION{
" U% f7 j3 ]7 }" R+ k" { UPNP_IMPL_WINDOWSERVICE = 0,- R9 D1 S$ I+ T
UPNP_IMPL_MINIUPNPLIB,
. g9 ~! Q: w& A/ D UPNP_IMPL_NONE /*last*/8 x4 ?- g( P, t, C, D+ C
};
: y" d1 J, H1 ^( [5 y5 p' W
) ~- A: P" [# M+ N" Z+ L9 L/ a. U) A& N
9 \1 S; S! j, S( r
: f0 s$ `8 I! q. t. R2 k, b) L9 Nclass CUPnPImpl
/ Z8 v! m. [2 ~! }3 U- O, z# q{
9 b1 ^5 P; E# I% Y3 x2 x: E+ k V9 Jpublic:
4 X) W; [9 N% Y' d: U CUPnPImpl();
0 \% @" l6 l" Q virtual ~CUPnPImpl();" y4 A$ S1 K" K/ Q# d1 @
struct UPnPError : std::exception {};
R" V! X5 B4 X! |9 ?9 ~ enum {! I% r* _ e0 n; M' C/ } {$ e' F, r5 R
UPNP_OK," A3 T% M0 ~4 x0 Z4 W" V! T
UPNP_FAILED,) a2 i; q; U8 h7 z# S
UPNP_TIMEOUT
- R5 K- l% x/ J7 Z/ O2 l };
2 x$ T- o* G" `6 M* Z
1 q2 d4 d6 D, b% k# u# ]$ R( a& d/ x7 i/ U. K8 j1 l H
virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) = 0;
! c/ m# E: f) _" S virtual bool CheckAndRefresh() = 0;3 d5 L& J$ @ \6 M. F$ H
virtual void StopAsyncFind() = 0;
- r, \/ q/ g' \% W2 t' V8 p virtual void DeletePorts() = 0;
# O+ s8 X3 ]: W/ p' ` virtual bool IsReady() = 0;9 _, x+ C4 q$ `1 H
virtual int GetImplementationID() = 0;
, }' y2 R, v1 S" \+ W
* _* Y5 t( I- o! r; e! D void LateEnableWebServerPort(uint16 nPort); // Add Webserverport on already installed portmapping
1 h S" h/ w- H2 e T, y& w1 n. z7 {) f; d
1 o3 `) d$ _' u void SetMessageOnResult(HWND hWindow, UINT nMessageID);% l$ T' c4 L( ~# K. C$ g2 c
TRISTATE ArePortsForwarded() const { return m_bUPnPPortsForwarded; }
' Y N1 ~# a- P0 d/ U5 a1 I uint16 GetUsedTCPPort() { return m_nTCPPort; }+ M* x* j. m7 L1 J6 x; z" v
uint16 GetUsedUDPPort() { return m_nUDPPort; }
8 ]2 {) n2 s, Q; o1 M3 L0 T" b, p4 |2 `% P' q4 {$ t; |9 I
& t/ r& P4 [& X7 r' @ q// Implementation& [" `/ H* D2 u* I+ `2 s
protected:: w# S; |, O/ t% w8 a
volatile TRISTATE m_bUPnPPortsForwarded;# J; F& q0 w% s& M
void SendResultMessage();9 a) c, K2 ?6 R+ |: E/ l+ F
uint16 m_nUDPPort;
! h0 F- S$ g6 R9 C uint16 m_nTCPPort;
: {( X0 p1 x% A1 ]# [5 } m% k7 L uint16 m_nTCPWebPort; [8 P3 P2 `) c0 g7 _8 p4 j0 e
bool m_bCheckAndRefresh;& N9 t& I* G8 d: C9 P& | Q
# e' q; [' o/ F6 T/ i$ r% \
7 f8 i! u7 e3 oprivate:
' X! r$ z1 X& {' O/ K/ ~' Y! ?3 H HWND m_hResultMessageWindow; U3 z/ f# |9 o5 X4 K A
UINT m_nResultMessageID;" d5 i3 a7 j9 ^( L, e
' b' O: |$ x% V' K
0 v. [0 [: H% U( U4 F( R8 T};
8 }( D# f! p: e
. w( ^- f) ~+ ?3 L$ s5 u9 [1 g" z+ x
4 x$ K2 d5 o1 F% u// Dummy Implementation to be used when no other implementation is available
) _+ e6 p" y# Xclass CUPnPImplNone: public CUPnPImpl" x3 b9 e8 _! x( p% x5 w2 }) P
{0 Y6 v4 e' g3 v* B- z0 f6 C" B
public:- i, H$ R$ @. V0 I
virtual void StartDiscovery(uint16, uint16, uint16) { ASSERT( false ); }
$ }4 [. w+ H6 D6 j, N- n! z virtual bool CheckAndRefresh() { return false; }& T3 u. d0 V& ~" a
virtual void StopAsyncFind() { }
7 Z8 C+ N/ L$ S! g$ h: A virtual void DeletePorts() { }7 S0 `& M; F4 w* X6 t
virtual bool IsReady() { return false; }
! |7 q4 y: E0 n% F4 G/ S virtual int GetImplementationID() { return UPNP_IMPL_NONE; }3 T3 f" d/ E% E; D9 D) _) I$ Y
};# C/ ~$ C( ]/ X& p6 Y2 _4 q
% K: q5 l2 U9 o6 H' A
2 a% _9 s- e0 f/ i/////////////////////////////////////0 z6 ^& X9 \, J) H$ v
//下面是使用windows操作系统自带的UPNP功能的子类: ]8 }2 d9 l. @: n( [$ u* S: F
' O' T u/ {, [: K
7 t0 u: Z8 o0 J' T" K) R
#pragma once- F$ j' X5 O+ X
#pragma warning( disable: 4355 )
3 Q3 `: p) Z6 I' a. D5 M2 x0 J
: e3 t# Z2 k0 o+ F2 r
' p& s/ q4 q+ C( q# P#include "UPnPImpl.h"! D3 o- u9 d( J% V7 K/ G
#include <upnp.h>
- B6 p" Q& R9 j. W" A5 p. H% `#include <iphlpapi.h>
/ U+ z3 i! H" y' D5 W' [# t2 U/ }#include <comdef.h>8 k+ Z! k- n1 R8 X
#include <winsvc.h>
, l: C- s% d2 Y" \% ?5 v+ m3 O' K0 U @
( F" [4 E' z* I( L1 v#include <vector>0 i* X- t" J- o3 k. ^2 r
#include <exception>8 g+ U' K9 D. a, ?+ N, J
#include <functional>' I/ e% D- A) @! k, Z) r
! I0 X( h* o. `( d
+ U! Q+ p- M3 y' h/ B( ]9 i
3 B3 [) J& n6 Y1 e" a, h) F
6 t) b% J5 o+ Q+ ] @typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinder,&IID_IUPnPDeviceFinder> > FinderPointer;
+ t. J! W- }& R; Y* Q: C" [typedef _com_ptr_t<_com_IIID<IUPnPDevice,&IID_IUPnPDevice> > DevicePointer;
V' F" S% o: ?: I$ o$ Etypedef _com_ptr_t<_com_IIID<IUPnPService,&IID_IUPnPService> > ServicePointer;
5 u; O& ^: {5 O# M. Y1 C4 e) [typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinderCallback,&IID_IUPnPDeviceFinderCallback> > DeviceFinderCallback;
4 l0 K$ D% L' V3 Ptypedef _com_ptr_t<_com_IIID<IUPnPServiceCallback,&IID_IUPnPServiceCallback> > ServiceCallback;9 R# E" X5 T/ F
typedef _com_ptr_t<_com_IIID<IEnumUnknown,&IID_IEnumUnknown> > EnumUnknownPtr;
+ h6 Y o( {' S( Ctypedef _com_ptr_t<_com_IIID<IUnknown,&IID_IUnknown> > UnknownPtr;
# P# B+ S$ t# }+ y9 W; ^( p: G* ]
5 p2 l. V- D$ J& M, ^* k; j4 n
typedef DWORD (WINAPI* TGetBestInterface) (
- T7 n9 X1 H/ ]( u( F! t' f( X$ \ IPAddr dwDestAddr,0 X! P+ x! u: q
PDWORD pdwBestIfIndex
' U$ P! o; ]1 K# W" \) P);
; }- y& F! {3 G3 B' d. X4 r3 I! ~
$ y( h, u5 S" a' w0 \
1 j1 I, J9 T( o$ C; w9 Ktypedef DWORD (WINAPI* TGetIpAddrTable) (: R+ K) _' v, e6 w) G
PMIB_IPADDRTABLE pIpAddrTable,
) I4 D4 M4 ^8 M8 ?+ c PULONG pdwSize,+ g6 P" M. F; _; G' K& z4 F1 p
BOOL bOrder5 V6 D; R$ ^. e9 w* U2 Q0 F u
);0 G3 D! |. e/ u: |4 r
9 g8 N( r9 o6 m; i+ V
1 B& V' U9 g7 V! @! {typedef DWORD (WINAPI* TGetIfEntry) (
: N! e9 b3 j1 h3 G: x1 K PMIB_IFROW pIfRow
) i) d8 J! t. ]; d# ]! m$ h' y9 Q);
$ E7 Z; U3 u8 {* I* @9 O, _* L: r. a8 B H4 E1 f
9 Q- `0 E7 @; B" K3 A4 M2 G
CString translateUPnPResult(HRESULT hr);
6 m6 n3 s; M8 Z: S* bHRESULT UPnPMessage(HRESULT hr);
, o* l. x4 h+ T; V$ n! P' s/ W
0 X1 z8 Y6 m. p" ^3 y7 I; u$ ]$ J: z# K/ v4 r* v
class CUPnPImplWinServ: public CUPnPImpl
9 a; @1 G- E. F& J' z9 Z' j{: g$ U. `" D# z' ~8 c
friend class CDeviceFinderCallback;
! L; R1 n5 ^6 T1 d friend class CServiceCallback;
3 @. X8 C1 L# G// Construction$ ]# s9 o( V) V9 R. w; X
public:
' v% B M+ l: [% I# }( m virtual ~CUPnPImplWinServ();# W/ o. M7 w: d3 U* h" K) d1 l5 o
CUPnPImplWinServ();+ i: ?1 _9 r. j1 _) s
& l1 i6 |4 ]; Z9 [) P
* M: m* f) w4 R, q virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) { StartDiscovery(nTCPPort, nUDPPort, nTCPWebPort, false); }* ] j3 n" x/ [7 k* R1 V+ }( l
virtual void StopAsyncFind();% t( [- A/ J8 p: V K8 Q$ {
virtual void DeletePorts(); G; c7 t7 o2 Q
virtual bool IsReady();
9 u a# v6 j/ B virtual int GetImplementationID() { return UPNP_IMPL_WINDOWSERVICE; }
% r! m8 w/ Y" C" l3 n. R2 R; g2 V2 k6 J c; E9 _8 j$ t5 M
4 z, Y4 w( m2 ~
// No Support for Refreshing on this (fallback) implementation yet - in many cases where it would be needed (router reset etc)
0 }3 x2 s# X: N // the windows side of the implementation tends to get bugged untill reboot anyway. Still might get added later
! M3 M( T/ R# r8 t Z virtual bool CheckAndRefresh() { return false; }; M# E" G% d5 Q+ c& [* z! h6 B- U
1 g& ~! z; r1 l ~5 G2 Y0 G9 _& J0 q U
protected:
* p; D7 {% Y7 ?5 A7 U) C void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort, bool bSecondTry);2 G) Y$ G& I4 U* a6 D) T
void AddDevice(DevicePointer pDevice, bool bAddChilds, int nLevel = 0);. V. s7 ? q# j; a& S Q
void RemoveDevice(CComBSTR bsUDN);
3 u5 W, b! ]: Y% k bool OnSearchComplete();
. U& {1 H8 P8 A: k* r+ B: D- `4 q void Init();! Y& w0 ?" @* g: T7 N- }4 n7 o
- I! X) L+ ]" _, V4 P8 R. q5 n6 J6 p4 g0 _/ ?
inline bool IsAsyncFindRunning() c4 @' d Q; U$ }- E/ q) \% ]
{+ O7 i0 t0 B6 |! w3 ]& u
if ( m_pDeviceFinder != NULL && m_bAsyncFindRunning && GetTickCount() - m_tLastEvent > 10000 )
2 [& B9 `* e7 g( @1 j {5 {" v0 a7 R* }, o. O+ Y2 R- F
m_pDeviceFinder->CancelAsyncFind( m_nAsyncFindHandle );6 h' Q7 A! s8 x7 u* n6 Y6 q
m_bAsyncFindRunning = false;
+ o9 e' b* a' ^1 N5 M }( V/ }) r- }. y8 d: U6 O" c x
MSG msg;: b! @9 ^# W2 j
while ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )
! K4 _7 Q+ Y- x {
( T# F- O# y5 U TranslateMessage( &msg );9 M' d6 m! X& A6 _; k- f+ i1 s3 f' u
DispatchMessage( &msg );
" z( c. a; _6 o6 |8 `) c }1 {6 i' \& r3 ^/ L$ c
return m_bAsyncFindRunning;
3 e, d! C P& Z6 w }( F- S# g6 n4 o
) |& w2 N/ K7 y2 S; r( t/ w2 s, J2 G! b4 ?0 F- k! j: X o
TRISTATE m_bUPnPDeviceConnected;
4 c) `% N" X" ?$ L5 e4 P8 b( o. |
% K2 A, I$ z6 S8 X
5 U( d/ U& P; @// Implementation+ q# z' c& O( C& j( X8 {
// API functions
8 }: Q& B* Z) h j W7 R SC_HANDLE (WINAPI *m_pfnOpenSCManager)(LPCTSTR, LPCTSTR, DWORD);' n7 `+ S7 k. [
SC_HANDLE (WINAPI *m_pfnOpenService)(SC_HANDLE, LPCTSTR, DWORD);
& `0 |, F, \ Y, s% z BOOL (WINAPI *m_pfnQueryServiceStatusEx)(SC_HANDLE, SC_STATUS_TYPE, LPBYTE, DWORD, LPDWORD);5 Q- @1 ?, s7 V% r7 i6 k7 y
BOOL (WINAPI *m_pfnCloseServiceHandle)(SC_HANDLE);7 m" Y8 Y+ e0 p8 V/ X" t% I' o
BOOL (WINAPI *m_pfnStartService)(SC_HANDLE, DWORD, LPCTSTR*);- \. w# G4 @0 @4 r
BOOL (WINAPI *m_pfnControlService)(SC_HANDLE, DWORD, LPSERVICE_STATUS);, S5 y. F- h/ v, k, @' A6 ^# t( H
! r& x% {+ K# J3 q7 ^- ]- t- Y. w* `) N8 Q
TGetBestInterface m_pfGetBestInterface;
2 a# x, M3 |. b7 L4 ^; Q TGetIpAddrTable m_pfGetIpAddrTable;0 G9 c# V, d' \
TGetIfEntry m_pfGetIfEntry;5 @# u: |: s; \# G" K
2 P# i# O( @, G; ] m. w4 B4 m2 P+ v
6 }3 N$ N/ e" a! w$ o% w; U! t; Y static FinderPointer CreateFinderInstance();
2 a; h) ?0 w) Y7 A1 a6 i, i struct FindDevice : std::unary_function< DevicePointer, bool >
' T4 @, A! v: P( M {
h9 i1 L1 X R* i4 O$ O( m FindDevice(const CComBSTR& udn) : m_udn( udn ) {}% @8 v" V/ z! _. }6 V
result_type operator()(argument_type device) const
1 K+ q8 y3 t ~0 h7 t; y {
6 c% l, m4 X/ l- B" g k2 h CComBSTR deviceName;
& p- s+ f- t" D6 e HRESULT hr = device->get_UniqueDeviceName( &deviceName );
: W5 X1 m, D& h
. o! |1 n- J L
3 X: U# n* V6 {, l3 y7 \7 Q0 z: |) R if ( FAILED( hr ) )7 Y$ E: y b' u; N. P5 \7 k7 }4 U
return UPnPMessage( hr ), false;
8 v% T& H! D* b) t, I7 C% f; R h
- H" I9 @4 h K+ _- j/ B return wcscmp( deviceName.m_str, m_udn ) == 0;
$ I. x8 p3 S9 Q8 G }; _ @3 |: ^) T2 U0 d1 p) k& [1 Y( m
CComBSTR m_udn;
! q0 p' ^1 M$ ~8 t% U% u };/ N; E- X4 J, {3 m
1 B3 G x" O% C4 E- l- I; c void ProcessAsyncFind(CComBSTR bsSearchType);0 k# K6 W$ t) J* ^
HRESULT GetDeviceServices(DevicePointer pDevice);
$ Q6 f# K1 z; P0 ^: M( } void StartPortMapping();, j& n+ ]( S, \- F) w$ g" l1 X8 q
HRESULT MapPort(const ServicePointer& service);
0 c% B1 t4 `; G/ }/ Y: K void DeleteExistingPortMappings(ServicePointer pService);1 U V$ z; \! \! P& N
void CreatePortMappings(ServicePointer pService);) B: Y2 P, c. b/ U" X
HRESULT SaveServices(EnumUnknownPtr pEU, const LONG nTotalItems);
. o7 K# G9 R, T' m7 q- W HRESULT InvokeAction(ServicePointer pService, CComBSTR action, ; {5 F# A w& b0 P# n
LPCTSTR pszInArgString, CString& strResult);! ]4 ^% Z0 I6 `0 A( \9 f/ b$ L3 T8 n! I0 F
void StopUPnPService();
4 A+ O6 A" ]7 u+ j T8 Y6 E+ J, j( ~- A& D5 k( z
& d7 _: a/ O$ R& V7 v" W
// Utility functions! J( ?' v3 _% U# X) C$ a
HRESULT CreateSafeArray(const VARTYPE vt, const ULONG nArgs, SAFEARRAY** ppsa);$ Y6 B4 U% S. m, O
INT_PTR CreateVarFromString(const CString& strArgs, VARIANT*** pppVars);9 s" g: f! l* ^' ~0 w) P$ g: V4 r
INT_PTR GetStringFromOutArgs(const VARIANT* pvaOutArgs, CString& strArgs);) H/ ?4 o+ H8 I1 q: X, e9 I. ?
void DestroyVars(const INT_PTR nCount, VARIANT*** pppVars);) R |) j4 M2 l# I
HRESULT GetSafeArrayBounds(SAFEARRAY* psa, LONG* pLBound, LONG* pUBound);
( ^. @' ^ ~) `$ t! ` HRESULT GetVariantElement(SAFEARRAY* psa, LONG pos, VARIANT* pvar);7 `* `+ I2 h# C# D3 q- ~
CString GetLocalRoutableIP(ServicePointer pService);9 Q3 E! b+ l; A3 K, }, U U
" m6 M+ {0 A4 ]
3 w8 r3 U/ N3 B) X0 l! l// Private members4 f( U8 z. \- I' s$ _# I" ?6 K5 I
private:9 w) S, `2 e- c P
DWORD m_tLastEvent; // When the last event was received?
4 r5 n% j* F' ~; w$ k std::vector< DevicePointer > m_pDevices;; }! ^' j* w3 f9 V
std::vector< ServicePointer > m_pServices;9 P) H" b( g0 z+ b U
FinderPointer m_pDeviceFinder;
; K; l* I! h2 \4 }# g, N+ D DeviceFinderCallback m_pDeviceFinderCallback;
' |! e, d: J- _5 i7 a# s1 N) ~ ServiceCallback m_pServiceCallback;0 q+ ^! ~; r& r( c/ W
) ~# p" Z( P/ k0 U$ E( ?% J
" ?0 M4 H# [0 A- d- n" d( n
LONG m_nAsyncFindHandle;
6 M9 p# |! D$ W( ~/ C bool m_bCOM;; N* I$ ^3 W; `# `* ?2 U
bool m_bPortIsFree;2 ~0 t+ ]* O( z
CString m_sLocalIP;
. w% N# `2 g5 A( p CString m_sExternalIP;
) F/ r0 o" c0 U1 a2 L5 T bool m_bADSL; // Is the device ADSL?
; e% S- L5 ^0 A; c; C4 r bool m_ADSLFailed; // Did port mapping failed for the ADSL device?
1 z9 r4 [/ P n. v5 X bool m_bInited;
7 o' U" k: l6 n& e$ l; u: o2 z bool m_bAsyncFindRunning;5 { Y+ Z. h, z7 \% q( |, a
HMODULE m_hADVAPI32_DLL;
3 A" ]9 M/ y2 w/ {1 S: \ HMODULE m_hIPHLPAPI_DLL;
+ n' K9 w3 U# R2 n/ w bool m_bSecondTry;
f. i4 C! V( w2 z% d2 ] bool m_bServiceStartedByEmule;7 [4 Q, t. m, |; K% m" C6 P
bool m_bDisableWANIPSetup;; f d, @" a! j( V$ A& Z9 O3 C5 w
bool m_bDisableWANPPPSetup;
# ^+ b0 z5 d0 ?- P, t4 ~5 W! ]5 g8 U: }" J. I: `
5 J1 x) A: o% D4 @ V7 K) W};9 [# i2 O: a- ~# s7 p* {& [+ D
7 l/ A+ j `; o: h$ {' q
0 b, U1 j% g: C9 I
// DeviceFinder Callback
: [% V8 w3 v3 p1 |4 N, x/ Aclass CDeviceFinderCallback
! M6 m4 Z9 C# E$ {+ {' q8 Q, O/ N : public IUPnPDeviceFinderCallback g/ @$ d7 z1 D) C% d/ p- I
{3 {1 T4 Q6 X6 m5 K# K
public: `3 ]0 I1 U: W" r8 ?
CDeviceFinderCallback(CUPnPImplWinServ& instance) l( h/ Y- q/ M4 Q5 {
: m_instance( instance )
$ T( T# ]& y0 Y" k) ~8 {& G6 W { m_lRefCount = 0; }' V5 y% J( K* F8 I8 G% W4 A# h
# ^ J* V( t- u% H% Y9 k
7 C7 H7 H0 L; l% C/ X1 u* e, ] STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);. Y. U1 |* s8 S4 m8 O
STDMETHODIMP_(ULONG) AddRef();
1 @' o* M5 g5 g! @ STDMETHODIMP_(ULONG) Release();9 |- f1 S# {& i+ T- K
) w8 y ^ }1 j1 ?8 `
/ Z0 U6 s2 [9 k// implementation( v/ |- z9 `; ]. H0 Q
private:
; Q# M" D" s1 J* E1 c8 O HRESULT __stdcall DeviceAdded(LONG nFindData, IUPnPDevice* pDevice);& e+ D9 h$ Y1 z0 f; j# f$ u; @5 C
HRESULT __stdcall DeviceRemoved(LONG nFindData, BSTR bsUDN);
, y g6 S( n( J3 [7 @ HRESULT __stdcall SearchComplete(LONG nFindData);
+ X( i0 T1 T% O' B( ~5 v& v
# o2 U5 d/ g* s" t1 |3 u A0 t6 t5 O& O! |. |: r3 G
private:/ U9 @" P* e8 ^, M! v
CUPnPImplWinServ& m_instance;
6 A' m" w+ P9 @: N( q, Y: u0 H8 G7 J LONG m_lRefCount;
% S& W% S8 R1 B w/ B! h$ h};
# ]& c7 U3 a: r+ z1 A
( p/ O2 k2 o% B q
' @- ^/ q- W3 }% ~( P3 L9 f// Service Callback - s2 P2 M/ v9 q7 s6 E2 {
class CServiceCallback
, Z# ?, F$ x' N, z+ V+ F: k. `8 { : public IUPnPServiceCallback! ]# w2 m! B: _
{
+ y# G% u7 q5 N0 A/ i/ j" Tpublic:+ G4 i+ c* f: l8 [; Z
CServiceCallback(CUPnPImplWinServ& instance)
. F3 `9 y/ T6 A8 G! q : m_instance( instance ): z' w) U+ d/ q% T
{ m_lRefCount = 0; }, ]4 P4 w, M% \9 q& w* a
8 k b% e, e; R' B) T2 w/ C. c- t
STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);
$ J8 T# U/ N* c4 y STDMETHODIMP_(ULONG) AddRef();
6 n6 Y0 M3 k6 x, V4 a/ y6 R1 b STDMETHODIMP_(ULONG) Release();
( } @1 n. R+ c6 y$ c9 z7 F* Z$ x @# h! Y6 W% n
" l6 l- h( K$ s ?5 K// implementation, o( s) |$ Q! C* ^0 ^3 k
private:' T1 o' { G$ Q" q/ Z! z2 W
HRESULT __stdcall StateVariableChanged(IUPnPService* pService, LPCWSTR pszStateVarName, VARIANT varValue);
/ L& F( B) I& w5 A: f9 U6 c3 P% @ HRESULT __stdcall ServiceInstanceDied(IUPnPService* pService);
# K' x& V: O w$ L; T/ M+ Y' r+ K! w: S/ J
. `% | v9 N: a- ?/ t- c! |
; m7 _- Q) o l9 xprivate:
. R2 i& M: [+ j, n: d CUPnPImplWinServ& m_instance;+ w/ H: l; r0 v5 {3 g z
LONG m_lRefCount;
, e8 c9 F7 @2 y( }% O8 W7 C+ r/ R};2 q+ Y( }# p" M! e& X( g8 O
* p) D+ G' U6 ~
2 B/ n8 d/ i5 G2 R4 }/////////////////////////////////////////////////) n" K* M. k( W% H7 C* L
3 }- J1 G7 C: B$ h( b
# K! B8 V; a% {/ u4 J+ e
使用时只需要使用抽象类的接口。
, O0 i8 R8 A# w) _2 RCUPnPImpl::SetMessageOnResult设置需要接受UPNP端口映射是否成功的窗口句柄和消息ID.
+ t; _ N1 h2 `2 ]8 eCUPnPImpl::StartDiscovery将开启一个异步设备查找并进行端口映射,其参数为需要映射的内网端口.
( x2 ~; E( T( qCUPnPImpl::StopAsyncFind停止设备查找./ B! `) |7 I2 R; ~( N
CUPnPImpl::DeletePorts删除端口映射. |
|