|
|
楼主 |
发表于 2011-7-15 17:28:52
|
显示全部楼层
以下有关upnp的接口来自emule,
" `; r: A4 c$ E$ U. N& u* J; ^ d. [5 A n& K
7 {* {6 O# F- `: R
///////////////////////////////////////////
0 q/ h# w; v& s2 S# n _//upnp的抽象接口类,只需调用这些接口即可实现端口映射功能.8 U/ j. H' i3 w0 j
! ~! G: X# w! j% U) |1 ]
4 X0 s a4 X0 K& I5 a
#pragma once$ J0 a1 v- n, P8 I0 F
#include <exception>+ r$ ]0 V( M1 y/ d: Z4 B) ]
) c- r! J5 ^/ d
2 I G1 n7 f- w2 N enum TRISTATE{
7 x! J* a! _) Y* n* ]. A; A" W TRIS_FALSE,
* y( s( |4 X' l. {& s5 M$ C TRIS_UNKNOWN,
4 H$ }0 X* _7 s- k) ~ TRIS_TRUE2 c) c1 U5 g) P1 @8 \
};
' L2 e6 Y# P4 v& ?7 M! {! t/ M0 B0 {+ l* t6 p0 ?
3 ?% _! G6 B1 f p/ E3 a4 T G
enum UPNP_IMPLEMENTATION{
! O) f+ Q# \3 Z UPNP_IMPL_WINDOWSERVICE = 0,
7 C$ Q+ i1 ^% u' K UPNP_IMPL_MINIUPNPLIB,
3 P$ z6 V. H! l# n2 @ UPNP_IMPL_NONE /*last*/
# E, d1 Z6 b# k: O};8 W5 u% \5 i6 U6 T8 t. O
( F/ l4 l& C% }; h
$ Y7 T6 V& B; F9 r/ T
# W7 a" q# F; I8 W8 F& e5 v( x5 ]7 L) ` u n& s+ D$ [
class CUPnPImpl0 g6 d4 B& K; j1 D% X1 g% F
{* V' R! V& p4 {# q
public:
0 O: d6 }, D" b, W/ ?$ g+ ?7 { CUPnPImpl();& t0 \2 {" X: X5 k: l5 B
virtual ~CUPnPImpl();1 y& ^* f g) d2 c: i- b
struct UPnPError : std::exception {};
' m' b. h# m) L$ D& m! _1 i: _ enum {
, V+ ~; E3 C2 J! | UPNP_OK,
7 {7 Z) Q/ u: v4 ?6 T" Q: I# x UPNP_FAILED,
8 t( z+ m! N) e! K' b UPNP_TIMEOUT8 d8 Y( D$ d1 y3 u& {2 B, J2 L O
};
" N6 ? |4 I+ L5 R5 D& V7 V' A0 {" ?7 s& @. G$ O" r
9 k* K, j, Y& v) r
virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) = 0;( e5 ^0 U g% ~; W- `
virtual bool CheckAndRefresh() = 0;( ~) k/ g2 [2 r/ y
virtual void StopAsyncFind() = 0;- C7 Y2 }5 \$ {; j- N
virtual void DeletePorts() = 0;4 |1 d% K6 A% o6 ?
virtual bool IsReady() = 0;
6 b# U" @. \ H; J virtual int GetImplementationID() = 0;
u3 u( O# j3 S
% G h0 ]& w+ l( e void LateEnableWebServerPort(uint16 nPort); // Add Webserverport on already installed portmapping
$ `$ u; Y$ ? S/ P, Q T# {0 S9 T. D- @6 m5 h- W
, J- D7 M) Z; r& X! l+ a8 T void SetMessageOnResult(HWND hWindow, UINT nMessageID);
1 J* [. J( w: j4 s0 A" Q TRISTATE ArePortsForwarded() const { return m_bUPnPPortsForwarded; }) ?/ q* t# L# L7 J& ~2 k
uint16 GetUsedTCPPort() { return m_nTCPPort; }- Z. j5 ~ Y$ t, f/ e& P2 M
uint16 GetUsedUDPPort() { return m_nUDPPort; }
( J1 n; G( I- f8 g: L n- y% A; L( A) c' a9 K5 l x1 g" B5 `
; A, {5 |8 v+ V
// Implementation9 A6 H( A. z0 u* w
protected:, j' {& E# ` D3 }6 z
volatile TRISTATE m_bUPnPPortsForwarded;4 b3 f, f$ E, S1 q
void SendResultMessage();
1 h+ s! G+ s# r" v uint16 m_nUDPPort;
! o, G! W0 A G uint16 m_nTCPPort;2 z( c7 a: l$ G4 A# m6 g
uint16 m_nTCPWebPort;
* l9 q& _: g$ x) O0 y& s1 @ bool m_bCheckAndRefresh;, m8 l- Y, W$ {; n; l3 z
6 ]0 ~4 |+ D t7 x `% T3 V5 ~, [+ F5 T2 {: V
private:' d0 B( j+ V9 p. Z+ e
HWND m_hResultMessageWindow;
" V' g$ ?7 X% I- C7 R1 i! H' J# _ UINT m_nResultMessageID; E/ y' O. u) {6 v
1 a, s3 L6 d: x0 w r% X: F+ G& ^
3 w# p: k. v' T1 a};' f3 G2 X% ~1 `
) {$ [ c' k$ o! d1 t
~; i: o1 ?7 k) p$ j# H
// Dummy Implementation to be used when no other implementation is available1 B- {' f9 C G# p1 x3 V: |
class CUPnPImplNone: public CUPnPImpl+ V9 ~; y& \6 \6 s0 l3 i8 r/ E& ]
{# q; P) u C9 n# q4 s2 a
public:) z6 W6 g' |7 ]- J) ^
virtual void StartDiscovery(uint16, uint16, uint16) { ASSERT( false ); }
7 a& n+ v, d6 W* w virtual bool CheckAndRefresh() { return false; }* j. E1 w3 z8 s. C9 a9 g
virtual void StopAsyncFind() { }
# W+ a5 y( {. _$ S4 Z1 U virtual void DeletePorts() { }, @0 D1 j; }3 N% H" Z1 [
virtual bool IsReady() { return false; }& }% b/ v. q/ y v
virtual int GetImplementationID() { return UPNP_IMPL_NONE; }1 g( z5 _5 `% Q' Y, r# \/ v# E7 R
};
) G( Z( V" k( |( F, Y: V% e$ K! @' [9 | i, r7 h W
% ]7 ~9 |# m4 I/ r# ], e
/////////////////////////////////////9 W4 U5 E9 y: {/ _
//下面是使用windows操作系统自带的UPNP功能的子类
- i7 {0 {% }) }3 e- P( u; A
" q5 C) F$ ~9 C: N/ B/ b- r q" U! ^5 f3 r3 W3 Y) |
#pragma once# I6 L) \( \& U4 w
#pragma warning( disable: 4355 )
0 F1 ]0 o! H Y" G9 G- X
" O, K S( i9 s( J
) q. b; U( e0 u; B#include "UPnPImpl.h"
$ j7 E6 ]4 d5 ~2 ~) p( g#include <upnp.h>7 T/ A" X; d+ i) ~: V& ]0 S
#include <iphlpapi.h>1 J; s0 ~8 N7 I8 B
#include <comdef.h>9 r9 t" a# p2 ^ {# A
#include <winsvc.h>, J$ a( n( N# @. V9 ]
0 @( C; m6 S- k% Q# ~6 p" c+ e' Y
3 G2 `& t) _8 C f8 W, u2 Z#include <vector># Q* r g3 U5 V- P7 ]3 S- N1 a
#include <exception>
5 k! o% @) C" e. A* }- X+ e#include <functional>9 P' z( _+ R2 w, s( c& b
: P. D* x+ I+ s. s3 w' @4 K. c9 x$ x) G
; s: z6 \& l2 y* k8 x3 X# \& x
; k" l4 i4 R0 I [9 ytypedef _com_ptr_t<_com_IIID<IUPnPDeviceFinder,&IID_IUPnPDeviceFinder> > FinderPointer;
8 p$ Z! G `% f& _$ V- [3 S: utypedef _com_ptr_t<_com_IIID<IUPnPDevice,&IID_IUPnPDevice> > DevicePointer;
1 V) V a$ B9 O- M/ j* m* ]typedef _com_ptr_t<_com_IIID<IUPnPService,&IID_IUPnPService> > ServicePointer;
6 @& t/ ]* t H% W' ^8 Y# i2 U, Ktypedef _com_ptr_t<_com_IIID<IUPnPDeviceFinderCallback,&IID_IUPnPDeviceFinderCallback> > DeviceFinderCallback;+ @( j$ j& y }+ E
typedef _com_ptr_t<_com_IIID<IUPnPServiceCallback,&IID_IUPnPServiceCallback> > ServiceCallback;
7 T6 q/ Y0 P5 y/ @typedef _com_ptr_t<_com_IIID<IEnumUnknown,&IID_IEnumUnknown> > EnumUnknownPtr;
3 x( v2 l' s3 S. c. @typedef _com_ptr_t<_com_IIID<IUnknown,&IID_IUnknown> > UnknownPtr;
6 }5 y0 Z- P; u1 _
7 P/ I: U$ h3 s7 B0 X! v; w
( |8 {: v; ^ E" M) Xtypedef DWORD (WINAPI* TGetBestInterface) () Q3 J. S' }3 D/ g5 ]# ^8 p( {
IPAddr dwDestAddr,! o' a, E' D% K7 O, X: S
PDWORD pdwBestIfIndex2 f+ e7 B& p; y- N+ E
);
% J2 q/ C' }% t% @- P2 o7 j3 _1 J+ s' v. }) O6 P& L
% S- W e6 e) i, i3 V# z
typedef DWORD (WINAPI* TGetIpAddrTable) (" ^. x: Q' j2 v0 [4 Q6 u" R
PMIB_IPADDRTABLE pIpAddrTable,
; A" d0 B H" f, U" H; [) l* G PULONG pdwSize,8 d- s E- R& f7 G6 h+ k
BOOL bOrder
7 i/ r9 G0 @6 l; E3 N1 ?);. r: ~6 n1 H% l$ m0 I1 f
, X% T1 T- A/ u5 b9 k0 ^
3 w* T+ k% V* T: @typedef DWORD (WINAPI* TGetIfEntry) (
% w& f0 i3 n. E2 X s! Y" x PMIB_IFROW pIfRow# B, P8 K8 E4 L- C% i7 b
);
. L# T( e3 S5 O/ g9 e' c3 v/ Q/ L' u/ i6 k0 H
1 s1 j: A7 I' h( v2 Q/ E$ S
CString translateUPnPResult(HRESULT hr);* v3 y$ T) p0 Y
HRESULT UPnPMessage(HRESULT hr);
. b1 d- N- \; u7 V1 y$ F
; O6 M9 H5 }. f: r/ s- A1 e0 d" z+ i8 Q' h9 O0 o- d
class CUPnPImplWinServ: public CUPnPImpl# y1 C3 G5 E! F
{0 j8 T5 n/ V( \. L W( X" C* Q+ [" g
friend class CDeviceFinderCallback;& O! a+ O8 c, }3 M0 o1 h8 o% M
friend class CServiceCallback;/ m$ v8 c$ m' Z1 \+ a* \5 g
// Construction% F6 i: r/ E: [, g7 ]) z o
public:) u7 H9 ]0 B- y5 g
virtual ~CUPnPImplWinServ();
- X5 L1 h- ?& S+ Z0 d- Z7 [ CUPnPImplWinServ();' Z: v9 m: l8 r. S
/ y) G: }" Q3 y: ^( O7 }
^8 J4 W" B7 s8 ?" x3 W, \4 B virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) { StartDiscovery(nTCPPort, nUDPPort, nTCPWebPort, false); }
& g6 l& x; m0 |, Y9 l+ y& W virtual void StopAsyncFind();
9 h& b8 q' O4 D3 y% O x& p( B virtual void DeletePorts();
& ~2 t" I6 g# y1 ` virtual bool IsReady();
$ `' ~2 }; i9 f7 F9 N" c1 } virtual int GetImplementationID() { return UPNP_IMPL_WINDOWSERVICE; }
. _$ T' U' [7 f9 ]
+ f7 ?% b& y: I1 y: V1 j
& X7 G3 U: s* v4 j; ?' M8 G+ N // No Support for Refreshing on this (fallback) implementation yet - in many cases where it would be needed (router reset etc)
6 c0 O" R5 B1 @0 _' E+ d // the windows side of the implementation tends to get bugged untill reboot anyway. Still might get added later
, d+ o/ u. I" t' e/ ?; w4 m f' T virtual bool CheckAndRefresh() { return false; }; \$ q3 K; A! j( N$ N, X+ q7 o
2 Y+ a) o- W2 d3 Y/ {0 Y$ a9 E! o8 T- o2 L a" R8 }! O4 w
protected:
$ K9 O' E8 J3 A0 A/ D( e void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort, bool bSecondTry);
3 n+ b) e0 A# W9 v# t& b% M void AddDevice(DevicePointer pDevice, bool bAddChilds, int nLevel = 0);8 C5 R+ U$ ?$ X% w. [
void RemoveDevice(CComBSTR bsUDN);
5 e& M& V8 k/ c0 f bool OnSearchComplete();
4 @- O* B C( I8 T m4 n4 X void Init();. H A4 t5 U3 z% E8 x0 ^
# z* ]) E# H" W' W. h4 b: V, q" y+ J* d" ^: ?: b
inline bool IsAsyncFindRunning() 4 ]2 v1 b+ b# `7 `" _9 h0 K$ a
{$ Q0 ?% |5 G8 `0 I' T, }
if ( m_pDeviceFinder != NULL && m_bAsyncFindRunning && GetTickCount() - m_tLastEvent > 10000 )) }( w. R& H: B2 _% `% D9 p
{
* f- ]/ z0 p$ G( t, E0 } m_pDeviceFinder->CancelAsyncFind( m_nAsyncFindHandle );
4 s$ v- b$ @+ j9 e* j3 e: m m_bAsyncFindRunning = false;
% \3 h1 J7 t6 |! j7 h0 R }
; k, b6 m- y/ y& r) n MSG msg;
3 k: i1 O/ R* x5 T2 C+ V* P while ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )
% F' R- G/ b0 i5 @ {7 b* C' ^* f; k8 k9 P+ m( ?* c
TranslateMessage( &msg );
( Y: m e F5 W* ?5 T$ x6 ]- H DispatchMessage( &msg );$ F9 | u% C& M/ w. S
}
/ \' ]# }+ |* { return m_bAsyncFindRunning;7 e O5 Y' j+ p! [; y
}; T0 s7 Y5 P8 Y5 J( F5 K: b
8 ~; d* H" P- I$ Y2 s/ c4 W2 d* {5 E& G: N; r1 S; l/ h. w" H
TRISTATE m_bUPnPDeviceConnected;$ H; x2 D: [2 [$ m: O# ?2 y8 M
9 l8 |. B+ U* _5 y b& l! N
: g- ?8 b$ f% I" m' [, v! I// Implementation
2 q3 o3 ]2 ^! D // API functions
) G; n9 a0 P' i* e SC_HANDLE (WINAPI *m_pfnOpenSCManager)(LPCTSTR, LPCTSTR, DWORD);! }8 ?' [6 _$ u, _
SC_HANDLE (WINAPI *m_pfnOpenService)(SC_HANDLE, LPCTSTR, DWORD);
" _( j* q5 T$ B! C* ~6 c& b' d BOOL (WINAPI *m_pfnQueryServiceStatusEx)(SC_HANDLE, SC_STATUS_TYPE, LPBYTE, DWORD, LPDWORD);% b2 \/ \8 v$ S* a& k+ n- H
BOOL (WINAPI *m_pfnCloseServiceHandle)(SC_HANDLE);
( L- e) e9 E( U BOOL (WINAPI *m_pfnStartService)(SC_HANDLE, DWORD, LPCTSTR*);
( ?- Y6 F6 @: ^/ U* t+ i9 J BOOL (WINAPI *m_pfnControlService)(SC_HANDLE, DWORD, LPSERVICE_STATUS);
4 U8 v4 Q6 N7 b$ B! b( k0 e6 M
; v) d: r1 ^, Z$ r" Q9 Z+ y* k1 Y5 _8 I8 M: @0 z$ M1 y3 N
TGetBestInterface m_pfGetBestInterface;. e& b! D( B+ [5 [) M' u( E% r
TGetIpAddrTable m_pfGetIpAddrTable;
/ d5 d: u: `/ x+ j) C6 z TGetIfEntry m_pfGetIfEntry;
# n: F" X* \9 l y5 E" D% i
9 F( V3 X1 t. ~& f% J
1 E5 o9 ^" Y) Q0 O* w static FinderPointer CreateFinderInstance();8 u/ @+ X2 U( Y% k
struct FindDevice : std::unary_function< DevicePointer, bool ># P& X6 d2 N9 A! @
{
1 M, E* O* k0 |7 ?- t9 k0 | FindDevice(const CComBSTR& udn) : m_udn( udn ) {}8 {: Y& N. [' u9 l
result_type operator()(argument_type device) const
$ \) k5 G( K- B4 h1 z {2 ~$ l- n6 v3 ^' ?8 A$ M4 M
CComBSTR deviceName;" X0 `! l4 N' P* y! q
HRESULT hr = device->get_UniqueDeviceName( &deviceName );$ q3 ^# Q; r4 U Q
S8 X3 ~( Z0 y4 i
6 `: Q% v0 U0 r if ( FAILED( hr ) )% l; S% c5 q* K3 ?
return UPnPMessage( hr ), false;
0 l1 n: u1 n1 a7 @8 v' h, }
9 @9 _0 e8 n1 I' F' p
- K* l3 M! m+ J- D5 B return wcscmp( deviceName.m_str, m_udn ) == 0;
3 g* w9 E% D: S* k+ a5 M) x }
! t/ k8 g6 b& ^* Z' k6 X9 d CComBSTR m_udn;
+ R+ @( }# `4 ~. k$ ^ };
8 f. ]: H1 M: A6 ~4 d# C1 X0 Q8 r: d 9 P8 q' G% H8 c+ Q
void ProcessAsyncFind(CComBSTR bsSearchType);
6 D! |3 W. \5 {5 B; o& R HRESULT GetDeviceServices(DevicePointer pDevice);4 F# U6 E$ m. n" H. C0 M: ]
void StartPortMapping();
$ r' B | \/ V! w4 u HRESULT MapPort(const ServicePointer& service);6 A' K6 E5 j4 `9 k
void DeleteExistingPortMappings(ServicePointer pService);
) D3 E9 c( [6 G. v void CreatePortMappings(ServicePointer pService);
8 \7 O$ T8 ]. f! b( S6 ^: F+ I HRESULT SaveServices(EnumUnknownPtr pEU, const LONG nTotalItems);
# I q/ [' I! ?, f HRESULT InvokeAction(ServicePointer pService, CComBSTR action,
- B v. G5 `1 ^9 a; _ LPCTSTR pszInArgString, CString& strResult);
5 S; x, L3 r8 V void StopUPnPService();
" K2 g. x' B$ Z8 N5 R, T8 Y& U* g
+ p3 S. B0 k% s, _9 l: P. L4 h% e8 e6 _ g
// Utility functions
4 v& b6 `/ E1 r, _' c# J HRESULT CreateSafeArray(const VARTYPE vt, const ULONG nArgs, SAFEARRAY** ppsa);
5 l6 @( h# D5 S* O4 H! m" J0 h# Z INT_PTR CreateVarFromString(const CString& strArgs, VARIANT*** pppVars);
. O1 b! r) R' @& Y, U( f INT_PTR GetStringFromOutArgs(const VARIANT* pvaOutArgs, CString& strArgs);
; t2 x& d. H& u( e# C void DestroyVars(const INT_PTR nCount, VARIANT*** pppVars);" }! Z6 `! ]/ w$ P/ C3 @! w% T$ j
HRESULT GetSafeArrayBounds(SAFEARRAY* psa, LONG* pLBound, LONG* pUBound);# M, t9 e8 O. y1 b* x' {
HRESULT GetVariantElement(SAFEARRAY* psa, LONG pos, VARIANT* pvar);
6 [$ F; ?# ]# S- P# q$ ]* A+ G CString GetLocalRoutableIP(ServicePointer pService);+ G% Y7 L" {% v. u# g0 m
- ?$ F& m2 b2 c3 w8 _
6 q3 |* ?$ J0 Q// Private members ~9 F* T6 F1 Q2 \2 _4 W7 z& H9 A6 `
private:( N8 l5 _$ W. S: i+ c
DWORD m_tLastEvent; // When the last event was received?
/ n; q/ w5 i2 {7 M& V std::vector< DevicePointer > m_pDevices;
6 c5 Z9 h w/ s! @ std::vector< ServicePointer > m_pServices;8 p7 T# d7 M, n- @- k+ Z
FinderPointer m_pDeviceFinder;
7 W. [2 ?" J0 t8 [9 _ DeviceFinderCallback m_pDeviceFinderCallback;# {! A9 j6 v4 _4 Y
ServiceCallback m_pServiceCallback;: l2 z3 i- t1 v! Q. u
/ q1 [6 l# [. U i& F- w* x) z8 H
1 S, _9 C7 [, Y% A% U/ \# G LONG m_nAsyncFindHandle;
8 K# b+ Q- i9 a, c6 I8 O7 s bool m_bCOM;' b+ T- F; {) q$ G( A* b+ ~0 _
bool m_bPortIsFree;
' U6 A! {( b+ h2 n) u. g2 E CString m_sLocalIP;
5 c* E, K* ^" ^6 u- X. T7 r CString m_sExternalIP;
1 [( K* O9 d, V6 o# C* ^4 V bool m_bADSL; // Is the device ADSL?
" U `2 a; \8 [ bool m_ADSLFailed; // Did port mapping failed for the ADSL device?
9 E5 X/ g. P3 X3 H: \! s bool m_bInited;
% y# E5 u5 F% K6 E# d bool m_bAsyncFindRunning;- a% M1 |! N9 ^1 j# T4 I8 ~
HMODULE m_hADVAPI32_DLL;
0 ~$ z' z3 e, W, U. f HMODULE m_hIPHLPAPI_DLL;, G' U4 Y6 U8 g$ C
bool m_bSecondTry;
( E8 O' h" Z7 {0 A bool m_bServiceStartedByEmule;
# ], c) J2 |/ B+ `9 ~2 F bool m_bDisableWANIPSetup;
0 H. S+ X/ ~1 J bool m_bDisableWANPPPSetup;
0 ~, r% E7 A, W1 t! r- T" ~# ^# H: m! Z' B9 g- }
/ B8 Q m+ }* N& l0 W9 p};
- _& Q) D B7 q
/ _- N( \0 L( g9 t/ r, P( w# \. T5 t3 N5 x3 n# G
// DeviceFinder Callback- f* z( ]% D) ] ], O5 o
class CDeviceFinderCallback
. m4 a* e6 R- i" q8 X" \; K : public IUPnPDeviceFinderCallback b; O) A7 Z( P# U! a. j* @4 g; Q
{ S; m% ^, B" H& ?4 l
public:
% q2 v( P3 b! S" ~6 t( g. p- D CDeviceFinderCallback(CUPnPImplWinServ& instance)& v! Q3 I; A) J/ r, z
: m_instance( instance )
" B: r. M- c9 u3 Q3 Q9 h' _ { m_lRefCount = 0; }+ O$ {/ F: @, S0 h
7 H- \6 m; P+ G8 f: f7 k
2 C+ e2 G8 @/ Z+ N+ m STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);
5 L4 g3 D0 ]3 H5 s1 { STDMETHODIMP_(ULONG) AddRef();# g* j8 @ B n- w* `
STDMETHODIMP_(ULONG) Release();
. }* ?. ~, X0 I4 ~- n- j8 _& l! a& ^/ ^3 ^- q4 T4 X$ X
8 T9 O6 z' k. }! M3 s. U4 Z4 f" e// implementation, I2 x$ q2 d) g4 p2 Q0 ]/ w
private: s' P# ~, T! L1 l" d
HRESULT __stdcall DeviceAdded(LONG nFindData, IUPnPDevice* pDevice);
. d4 h, K5 @) S; q HRESULT __stdcall DeviceRemoved(LONG nFindData, BSTR bsUDN);
( ^ B4 |- \2 ^2 O' ] t; m HRESULT __stdcall SearchComplete(LONG nFindData);' K G z+ S$ g9 |+ N3 C0 s
; h! k7 T% \, J v+ X2 l+ o$ w6 w
0 g0 n5 Q( B8 Z, Y# a% C' @private:7 m* [& p; t2 Y, K
CUPnPImplWinServ& m_instance;2 K1 Q. m! S+ ^ ?
LONG m_lRefCount;1 ^8 h- M9 D. Y2 J- C# c* X. o
};
X: @3 t0 @! M2 N' O* y& ^; S+ c
1 K/ J& l ~1 C p# \1 c* a( W( R* w: w/ ^
// Service Callback
; @7 x3 k0 x; jclass CServiceCallback+ d+ w% _7 [2 }: w: W, Y
: public IUPnPServiceCallback
$ S. f( H( F& W$ n6 `$ e, ~{
3 n+ S4 ~$ u+ Xpublic:5 [8 u5 `) Y8 i6 ?4 ~2 Y
CServiceCallback(CUPnPImplWinServ& instance)5 O1 ]7 ?' Z5 d3 v' U" t
: m_instance( instance )
+ k' Z) i* G6 G! V3 \ q { m_lRefCount = 0; }
) @3 ? o' L* h c' Y X1 \3 M. [1 I: W7 S9 z* `
STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);
! W& y7 ^8 u u3 ]0 i/ x6 Y STDMETHODIMP_(ULONG) AddRef();. _3 ?. |6 E' |9 j b" g5 w
STDMETHODIMP_(ULONG) Release();4 p+ p' J* M; p) p
2 {3 |% N0 q& |3 g; r& e2 K% Y* y
! f' @) F k2 V
// implementation+ Z* L8 @" W; K1 c6 h
private:6 z" Y l+ H. g
HRESULT __stdcall StateVariableChanged(IUPnPService* pService, LPCWSTR pszStateVarName, VARIANT varValue);
$ S' ^: _; R7 ~, L T: A HRESULT __stdcall ServiceInstanceDied(IUPnPService* pService);' t! _. o6 ]( y
% P, t2 ~! \7 R1 p/ l! }% i2 X
6 ~4 P2 K; T! B$ q% @( `* tprivate:
' Q9 G8 j+ ~+ O% o CUPnPImplWinServ& m_instance;
1 R& D: V! p/ p9 P$ g LONG m_lRefCount;
& x1 y8 P% x6 w I};, k2 y, Y0 I- d( z
1 ~5 d& e3 h3 {( p
; J- _2 R. Y3 {- v# a: k9 z# y: W- q/////////////////////////////////////////////////
$ s. t+ f( f: S( @: o7 l' G! Y5 {, k+ X- P2 C
L; S# b# {# _# f) {使用时只需要使用抽象类的接口。0 {7 M1 e5 }5 s7 t- {. N
CUPnPImpl::SetMessageOnResult设置需要接受UPNP端口映射是否成功的窗口句柄和消息ID.
% W( a. H, W7 j- O1 m; rCUPnPImpl::StartDiscovery将开启一个异步设备查找并进行端口映射,其参数为需要映射的内网端口.
+ K9 i5 i5 j0 a9 _! |- KCUPnPImpl::StopAsyncFind停止设备查找.; u, e: E x* A3 Z8 }
CUPnPImpl::DeletePorts删除端口映射. |
|