|
|
楼主 |
发表于 2011-7-15 17:28:52
|
显示全部楼层
以下有关upnp的接口来自emule,1 v1 o7 J6 {: ^, L3 P8 L3 `2 o: X1 y
) k T; \: h! _( v9 H- u4 \4 j3 T" m/ q
///////////////////////////////////////////
& r6 t, I: G+ ~( h/ _5 `//upnp的抽象接口类,只需调用这些接口即可实现端口映射功能.8 {! f/ x5 Y+ i2 E& m6 }/ P
) C0 ~) |/ p1 R
; m- o- X; d( y& x' a% o#pragma once
1 W2 V7 g( C; k/ g$ t#include <exception>
0 U& s( l' Q i, P. X# ^( L* D. g! q5 ^( j! \
; n6 R- {* M0 W, \4 b1 Z# _; n
enum TRISTATE{
+ j: D2 o% H/ n1 ? TRIS_FALSE,
6 m) t0 ]% ^! s5 F; m% A TRIS_UNKNOWN,
3 Y- b2 |: E! `8 M K) R TRIS_TRUE. T$ _ x% o4 C7 F
};+ w" b/ d3 c2 q4 h* `) b+ \4 f
/ [/ ^, U9 t7 U2 ]7 E! M
) {7 b1 l! l9 z% T& w# Z
enum UPNP_IMPLEMENTATION{ y p5 D" W3 W. s
UPNP_IMPL_WINDOWSERVICE = 0,1 N p/ o" s, p* \. | m
UPNP_IMPL_MINIUPNPLIB,5 C6 r/ D9 D& `& |8 c
UPNP_IMPL_NONE /*last*/
) L X4 ]! ?# R7 v8 M8 p};
8 n$ x( U! M9 E& b& m
+ E8 E( p9 v i2 {# D( A; u3 `+ M
" q, O( g1 x4 a* x! L7 A0 ~, I1 r y+ e8 h% J+ A$ c U
/ x- x# e9 ?2 E: d) M/ G: f
class CUPnPImpl" q0 L8 Z3 q. W' k j
{8 `5 T( n2 | M0 j! b
public: g5 R: B5 ~+ c
CUPnPImpl();, t9 U# ~) k! e2 a0 Y
virtual ~CUPnPImpl();1 m/ c1 ~' [0 u! ~) H3 q$ [
struct UPnPError : std::exception {};
. S0 ~9 M/ i% G7 @ enum {6 ~' K$ h" t* T" ^9 l6 \6 ?4 r
UPNP_OK,
! V7 @% h/ T4 R$ o: F UPNP_FAILED,6 J3 z }) \2 @
UPNP_TIMEOUT
+ S3 |. x( ^5 H: j) P& C };0 u; W2 Y! p. w7 e/ w' r) k; \
% D0 h+ D5 ]$ {9 I; H/ l q6 k
% k* }( I) n3 w3 {# v. D virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) = 0;
( F3 L4 W* ?7 C4 M( @5 w virtual bool CheckAndRefresh() = 0;
% X. E. t/ G. x- B+ l- M3 W virtual void StopAsyncFind() = 0;& _5 \! E9 M& Q6 A9 }( F7 _) w
virtual void DeletePorts() = 0;
S1 f; k X; {4 ?/ a' n virtual bool IsReady() = 0;
: k9 q) {8 h- P5 Q7 f( [ virtual int GetImplementationID() = 0;
M) o( [% \% G% C& x4 a 7 o; O3 J, p9 R5 W
void LateEnableWebServerPort(uint16 nPort); // Add Webserverport on already installed portmapping
; F& m4 r) q9 o6 k) Y- q- K# @. |, x8 j; w: I( V/ {
: `/ F" G: x% I5 r
void SetMessageOnResult(HWND hWindow, UINT nMessageID);$ ~2 b9 f$ I: L h/ @5 M
TRISTATE ArePortsForwarded() const { return m_bUPnPPortsForwarded; }3 @0 V' Q! u; t; }& @8 Z- L, Y9 w' `! G
uint16 GetUsedTCPPort() { return m_nTCPPort; }4 |6 P, {8 Q8 ]) R/ x# c
uint16 GetUsedUDPPort() { return m_nUDPPort; } : y6 H2 V V! e
0 T" ?$ c6 D! a* @% _& w4 ~% H3 Y7 z% V; ?7 z$ L1 c3 N! V
// Implementation
& t$ u$ z# D. f6 @protected:& ]) J$ ]7 h. B- \) Z
volatile TRISTATE m_bUPnPPortsForwarded;
$ f; o& C! ~& R' f" Y6 [+ z9 \ void SendResultMessage();
) {9 `) `- ~% p3 L& t; {- b uint16 m_nUDPPort;
# l6 q1 T) k# [ uint16 m_nTCPPort;) e% f' z# f1 n) ^7 n, n
uint16 m_nTCPWebPort;
3 G; ]" t( G, h: Q" V bool m_bCheckAndRefresh;# b# l4 ^" H3 L9 Q1 V
6 G9 m$ z& P$ N" F; n6 L' k4 i( X' E& u. X7 C. A+ W& m
private:
/ N M) G( @9 z HWND m_hResultMessageWindow;! h! n D4 T& ]; b
UINT m_nResultMessageID;2 @: ^4 @5 V7 o- O
7 ~1 [8 Y9 M0 f4 e1 K" y9 G' J- W
3 Y& I% ~% O& X8 K};3 U) a! I" B( J7 Z
/ |, a4 e/ P8 u2 k& A6 h" Q
4 S( ^1 z4 E6 U R0 U1 f
// Dummy Implementation to be used when no other implementation is available; F/ F, i2 N. c2 t) j/ K- ~
class CUPnPImplNone: public CUPnPImpl# L2 c' t/ T3 I3 h' A
{
& x$ Q X! ?( Q! f- O' A3 D7 Npublic:/ a6 W( I* }7 S% T
virtual void StartDiscovery(uint16, uint16, uint16) { ASSERT( false ); }
1 B) p: l7 m: q) _+ k6 }. H' B virtual bool CheckAndRefresh() { return false; }3 l' A/ Y0 m4 s
virtual void StopAsyncFind() { }
2 ?2 q! E g& w& v, w virtual void DeletePorts() { }
" F" `% s: _. y0 ] virtual bool IsReady() { return false; }
" L0 u9 j% }! `# i& ]* P virtual int GetImplementationID() { return UPNP_IMPL_NONE; }
0 K. k3 X) h; t0 C4 F: y3 n% e0 p};' L5 ]' ?6 E" ?8 k0 g) |( o
" O/ P1 M8 |+ ~
; K3 s0 Z* `. ^8 U0 i/////////////////////////////////////
" h4 _* y' E& ]* m//下面是使用windows操作系统自带的UPNP功能的子类& l0 V& U1 a# g' Z& o
3 L5 p9 W1 Y, Y, c: @' y2 e9 a m3 ~3 b7 z5 P7 g. U e% @
#pragma once
% I) d: Q6 r% K6 ^% i#pragma warning( disable: 4355 )
; p3 r+ Q. Z" R4 \, n" C \9 R
9 Y2 w1 ?. P7 s% O
' U! s: V) N0 P+ S0 V) G; x#include "UPnPImpl.h"6 [/ U' \2 R2 x+ a
#include <upnp.h>! h" c0 i, [% u% K, }" K2 m/ Z
#include <iphlpapi.h>
0 d# R' x. J, D+ M3 ~- `/ p+ B#include <comdef.h>
# r8 O* s& \ s, J4 x#include <winsvc.h>* p; i5 ^3 C( ]0 F+ [5 u
4 E0 G/ F, z: \$ \
" n6 Y. h' V8 |; T' r#include <vector>/ h L- V/ K. Z! H
#include <exception>
) G/ \ P& N* ~#include <functional> Y! h% f# i- B
5 n4 v% [' p! e/ h0 y' [" |1 O/ e. T0 C' ^/ ^- y/ \
" U5 n$ r- H% P; t- k
) c/ M. M. H3 k( W O# |typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinder,&IID_IUPnPDeviceFinder> > FinderPointer;' v2 S; ^+ f$ c2 F& c/ W
typedef _com_ptr_t<_com_IIID<IUPnPDevice,&IID_IUPnPDevice> > DevicePointer;
6 q8 T% _- ]1 K' r( Ptypedef _com_ptr_t<_com_IIID<IUPnPService,&IID_IUPnPService> > ServicePointer;/ |0 {8 `, ]- L& M% V. e
typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinderCallback,&IID_IUPnPDeviceFinderCallback> > DeviceFinderCallback;0 w; h# i7 p. {/ n
typedef _com_ptr_t<_com_IIID<IUPnPServiceCallback,&IID_IUPnPServiceCallback> > ServiceCallback;+ v8 O0 m6 t5 Z U; {% @, [" S
typedef _com_ptr_t<_com_IIID<IEnumUnknown,&IID_IEnumUnknown> > EnumUnknownPtr;
: ]+ \- ^! L3 ]4 o3 ztypedef _com_ptr_t<_com_IIID<IUnknown,&IID_IUnknown> > UnknownPtr;0 A$ _# E) G' Z$ t8 Y7 _6 v
/ @- m x z& K7 \ B
' j3 Y/ q u# a; `+ ]typedef DWORD (WINAPI* TGetBestInterface) (1 X* i! \4 |- n; Q# B
IPAddr dwDestAddr,* w L" I l, Q% Q' t% e
PDWORD pdwBestIfIndex! S) M3 L: A/ K1 `
);- C8 T8 o4 T% ^
3 z% d3 c9 c: I1 i0 [
7 W1 Y6 j: M( q1 j; k6 [typedef DWORD (WINAPI* TGetIpAddrTable) (9 w9 D' Z0 b8 G0 h3 L% N
PMIB_IPADDRTABLE pIpAddrTable,
) Q9 Q& o5 D, o% R PULONG pdwSize,3 u* `. a& g ]
BOOL bOrder Z9 e3 ~' ?' X' S
);+ Y$ y3 `5 S: ?4 x; _. @% R6 F
( b: m3 l$ B* i
) X& e) I# g( ~typedef DWORD (WINAPI* TGetIfEntry) (
' D2 p7 D3 c4 w PMIB_IFROW pIfRow
7 c3 A/ h! _# B& Z# L);
/ e" ~' R/ s" g. P& B# [
, m& {1 {6 B$ ~! Z
1 p+ o6 Q5 z1 a1 k) X/ E0 dCString translateUPnPResult(HRESULT hr);2 W3 B; |" `" u3 t* F$ m
HRESULT UPnPMessage(HRESULT hr);9 r+ _/ W M1 _
8 n% P9 @8 @9 S4 B( F/ x+ p8 V7 C' `9 V; F. ~; E" o( |5 o, p9 z
class CUPnPImplWinServ: public CUPnPImpl
7 r! F1 q: c0 l' L{& p* W/ C) T* q/ \2 I
friend class CDeviceFinderCallback;
% O" w! W; l, f+ X! { friend class CServiceCallback;* l2 @; m. n; ?( h
// Construction
+ U0 q1 g6 h: cpublic:/ j2 _7 _. q2 n0 u8 _
virtual ~CUPnPImplWinServ();
( j: t/ N- M2 u ]2 D% Q CUPnPImplWinServ();
v0 q: ]. A n9 L2 c9 d7 x: p# y n! q. u, W
( {2 m0 z) |7 U2 Y: |2 z. O virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) { StartDiscovery(nTCPPort, nUDPPort, nTCPWebPort, false); }" F/ R3 b1 k2 o. L- O- J
virtual void StopAsyncFind();
/ d9 o# z1 G7 C* O virtual void DeletePorts();
+ ?$ B$ I/ x/ \/ n& c. o virtual bool IsReady();
5 J7 E8 T) Z7 O L& P virtual int GetImplementationID() { return UPNP_IMPL_WINDOWSERVICE; }# ?; w( r9 E* s$ T) _8 b( ^9 f. Q
: x7 S6 {* w1 r) ^! V! |. R. l/ v1 b7 O2 l8 ]- t1 a
// No Support for Refreshing on this (fallback) implementation yet - in many cases where it would be needed (router reset etc)
$ ]! _9 o9 G: z, L! s" @5 i; l // the windows side of the implementation tends to get bugged untill reboot anyway. Still might get added later
$ j0 z5 ~1 h* J& q virtual bool CheckAndRefresh() { return false; };+ p5 e6 V _ R) {& b" h
, y# K; A: Q. Z8 I& Y
2 @$ N+ M& F+ O |! Xprotected:1 Z) ]* P9 C7 T1 o) U8 m' f" F" q
void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort, bool bSecondTry);
- d- X: v' m( V! i/ k, h void AddDevice(DevicePointer pDevice, bool bAddChilds, int nLevel = 0);5 `! F/ l9 k H0 [" D/ t
void RemoveDevice(CComBSTR bsUDN);
9 O. e' K( b/ n* \7 ~2 I- v1 f bool OnSearchComplete();; b6 b9 h+ l& ^* S+ P
void Init();
$ G3 U6 v! K5 {. Y0 {. f2 w3 ]% y+ f7 E% e1 y: v/ t* m9 I% X% K
: J6 b& d$ ?) `+ B; a. D inline bool IsAsyncFindRunning() ' ]4 j( K7 n9 r% {8 v6 L) I% ^4 F
{
% p- u7 n6 p+ X! ] if ( m_pDeviceFinder != NULL && m_bAsyncFindRunning && GetTickCount() - m_tLastEvent > 10000 )
+ o0 x! W3 k% O5 r. T {. h0 t3 n" `/ r, N
m_pDeviceFinder->CancelAsyncFind( m_nAsyncFindHandle );& H( v: y/ F6 u$ U; x
m_bAsyncFindRunning = false;, C1 s m8 k. R! `! v
}
8 u& C/ ^8 q7 n$ m8 E9 f MSG msg;0 D& m1 x I9 F. H* n4 [/ \
while ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )
P% q% d5 r% b: u {0 x# u' D! G+ \- j" \3 R& i' R
TranslateMessage( &msg );5 Z% j8 {4 }" ^) Z$ _$ Y
DispatchMessage( &msg );
+ v$ ]" G7 O0 X, g }5 r/ y0 W6 D9 n( V$ Y
return m_bAsyncFindRunning;: Y. a6 L9 _) k! ?9 l. z- f# g
}
# n) j4 t+ s0 S6 M4 B3 g& P
# J9 x( F# W2 l! N) H0 o, I: i2 d3 B9 n! {1 @/ M" h" D: H
TRISTATE m_bUPnPDeviceConnected;4 C- k3 @# B) G! G0 v) a
# s) ~) t+ j" V" j8 f1 x: ]
$ R8 K$ W, _" n6 h% g// Implementation. c1 t4 f/ n5 c" [
// API functions
/ l0 C! \2 X8 ?. Y) k SC_HANDLE (WINAPI *m_pfnOpenSCManager)(LPCTSTR, LPCTSTR, DWORD);
P0 e1 s5 ~6 P [* w+ R SC_HANDLE (WINAPI *m_pfnOpenService)(SC_HANDLE, LPCTSTR, DWORD);
+ ~4 ~( P1 b: p3 v" X$ {/ a BOOL (WINAPI *m_pfnQueryServiceStatusEx)(SC_HANDLE, SC_STATUS_TYPE, LPBYTE, DWORD, LPDWORD);
! t0 ^$ b5 {8 b& t# S BOOL (WINAPI *m_pfnCloseServiceHandle)(SC_HANDLE);
; R, a1 B8 ?1 S BOOL (WINAPI *m_pfnStartService)(SC_HANDLE, DWORD, LPCTSTR*);% Z5 M) l8 n3 o* _* f1 `
BOOL (WINAPI *m_pfnControlService)(SC_HANDLE, DWORD, LPSERVICE_STATUS);! t+ P7 v% T. d. V# n/ K6 T
/ Y1 j7 X: B5 N5 B* j0 ?
# m1 G! ~) ^" I" P3 E# |. [; M3 t% j
TGetBestInterface m_pfGetBestInterface;
( m, h( y4 ?: D8 t- }4 v9 C TGetIpAddrTable m_pfGetIpAddrTable;0 s2 A0 Q. O0 f5 v8 W1 {5 |- y+ y
TGetIfEntry m_pfGetIfEntry;
7 }* {( z! ]0 W1 ]" Z& ^$ I7 J5 b; m; w
- a: i& H; L, I' f
static FinderPointer CreateFinderInstance();
; h: w$ {) O3 |+ N+ E1 T% x. e3 v struct FindDevice : std::unary_function< DevicePointer, bool >; o# [6 W6 G- H5 ^( M* E
{
0 i- h7 }5 _4 `, w$ S FindDevice(const CComBSTR& udn) : m_udn( udn ) {}
/ X4 B- J4 g; I" V) H3 u result_type operator()(argument_type device) const: J( E3 W5 J) F* F5 l# E5 x5 j, j
{
( i* g5 ^4 ?+ v& \7 P; e% J/ F CComBSTR deviceName;) ~3 \+ [. i# L m- x
HRESULT hr = device->get_UniqueDeviceName( &deviceName );: k9 F: `0 q6 G! S- f
( {- o5 P. M9 t6 \
9 f. V4 g% C% K; y1 n9 m if ( FAILED( hr ) )
: l0 D* S$ o: ~ Y/ h% v return UPnPMessage( hr ), false;
6 R- a& T$ L4 W4 u( R
- J7 [# M7 v. | J
3 }+ G( ^* \$ ]. Z9 p4 q return wcscmp( deviceName.m_str, m_udn ) == 0;# C$ X/ {" U# L6 u- k
}
' E8 b1 O5 S+ G" E1 Z' M, B4 P CComBSTR m_udn;
' |: `# @( j/ z8 f; p3 R };
' j, @; m0 J9 V) m# w
' T3 ?; p- d0 @# r. d$ D8 R/ A void ProcessAsyncFind(CComBSTR bsSearchType);
7 Q# y3 O' w9 R, K HRESULT GetDeviceServices(DevicePointer pDevice);
4 r% ^7 O; j; W3 y. S3 O/ q1 m8 g void StartPortMapping();. r5 a) o5 U8 q, L5 P2 t
HRESULT MapPort(const ServicePointer& service);2 B7 {6 j& j3 e' T
void DeleteExistingPortMappings(ServicePointer pService);, Q$ v ]4 ]( N* _
void CreatePortMappings(ServicePointer pService);8 o6 v; r) z/ o5 H3 P6 n6 C- \. v
HRESULT SaveServices(EnumUnknownPtr pEU, const LONG nTotalItems);' I8 I; g- l4 C9 s
HRESULT InvokeAction(ServicePointer pService, CComBSTR action,
# {0 |" U% b3 I- m5 w# _ LPCTSTR pszInArgString, CString& strResult);
- X! d, m- l; s void StopUPnPService();* H6 r8 x, w2 ^' ?
6 ^* Z+ r( {4 l$ r( a% [# z3 }
- h7 s" Q+ B: h: X' W" B, w // Utility functions4 A& P- n0 H# H2 r- w c
HRESULT CreateSafeArray(const VARTYPE vt, const ULONG nArgs, SAFEARRAY** ppsa);
: n, e+ R# ~% s6 m5 V9 W) P4 A INT_PTR CreateVarFromString(const CString& strArgs, VARIANT*** pppVars);1 r5 ]3 x1 R/ B m, w
INT_PTR GetStringFromOutArgs(const VARIANT* pvaOutArgs, CString& strArgs);
# S$ U! P6 n* Q$ P+ r/ L void DestroyVars(const INT_PTR nCount, VARIANT*** pppVars);7 n2 y v) K8 q
HRESULT GetSafeArrayBounds(SAFEARRAY* psa, LONG* pLBound, LONG* pUBound);( i% P2 e, h- p" i& ~
HRESULT GetVariantElement(SAFEARRAY* psa, LONG pos, VARIANT* pvar);* j& ^3 a' |2 G( ^
CString GetLocalRoutableIP(ServicePointer pService);
# G0 p6 Y! ~$ v4 ?# [
6 C; L9 [2 x- ]4 ?/ `* O: y
! n4 Y: t* r8 a# S2 N4 P$ R// Private members
- q% t8 g8 L1 U/ Aprivate:
+ C( c/ y( ?, J2 z1 c DWORD m_tLastEvent; // When the last event was received?
3 b) ]! n: C* a4 J+ ?7 z std::vector< DevicePointer > m_pDevices;* J" |; G0 z7 `4 s* G& z% U
std::vector< ServicePointer > m_pServices;
) p2 Q: U: R4 M. q FinderPointer m_pDeviceFinder;
! o6 `# V( K, `) \3 U9 G) } DeviceFinderCallback m_pDeviceFinderCallback;( q" O2 P7 u' x$ \, S5 q$ Z3 L
ServiceCallback m_pServiceCallback;
! X- m1 a! r1 m. {, a
/ y1 h/ l) M; F: |4 G
7 V7 r; q. r o/ Z! J LONG m_nAsyncFindHandle;" n8 d' O$ }: h5 \4 \; E
bool m_bCOM;0 D! q; m; b& ^
bool m_bPortIsFree;( f. o# f; \$ l
CString m_sLocalIP;
& t) [3 t7 j4 L; j# M9 _ CString m_sExternalIP;' D+ v: K" D. p2 T% d" O6 I8 j
bool m_bADSL; // Is the device ADSL?- W% E% q# Y' M. P) g& T* X
bool m_ADSLFailed; // Did port mapping failed for the ADSL device?; J* Y4 J5 |& q4 @ H5 x
bool m_bInited;
4 s! g4 r' ] c% ~ bool m_bAsyncFindRunning;7 A% {( T& i, w' P
HMODULE m_hADVAPI32_DLL;: c; S% R/ E& P) s0 ^9 d. Q
HMODULE m_hIPHLPAPI_DLL;2 H, o+ b( j) p1 i
bool m_bSecondTry;8 H. n2 ^% @2 _( m
bool m_bServiceStartedByEmule;
& F$ q* E7 }1 f$ a bool m_bDisableWANIPSetup;, c% h8 c5 w4 _/ {9 Q% @
bool m_bDisableWANPPPSetup;& d& P8 _& |. b6 g* p9 y0 [. j5 S5 o
4 m; |" }1 z1 P. a
9 A$ B! f" L* F8 W& h* z1 A$ ` q};' U( n5 ^! [9 q; s& i, x6 W% l
# S& Q( m6 t+ d
! U7 Z3 F c) _: H: o; N
// DeviceFinder Callback6 R! k+ P3 W0 U' u
class CDeviceFinderCallback
; \6 j+ R3 n( _; v : public IUPnPDeviceFinderCallback
# I+ b1 _ S5 m- ^3 |& `; W{' s$ W* h. A# `) i
public:
( p2 \' K! A2 p CDeviceFinderCallback(CUPnPImplWinServ& instance)) x# K+ J& _* g& r# B' {
: m_instance( instance )# v6 J1 t! R ]2 @. N
{ m_lRefCount = 0; }
( }. v) U! I. x$ c" d* A! l0 o/ y1 U1 z$ W5 B
; _+ ? {* g3 N- T2 Z) T+ p
STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);/ N+ M& u: n: |6 d, Y. S
STDMETHODIMP_(ULONG) AddRef();
2 G3 E( b( W# N STDMETHODIMP_(ULONG) Release();* `; Z& _4 P5 l
- Q0 v5 @' m7 G# r* E! U3 d
' `1 x. R* f" q! x4 V9 i" U x8 X
// implementation2 h& {, K4 h5 z
private:. E: r) S" ?% T9 x, T9 g% }
HRESULT __stdcall DeviceAdded(LONG nFindData, IUPnPDevice* pDevice);
# P7 c% V# o* Y1 G HRESULT __stdcall DeviceRemoved(LONG nFindData, BSTR bsUDN);
1 v+ K" B; a) {( Y% M# w# f8 V HRESULT __stdcall SearchComplete(LONG nFindData);
$ \0 W$ @' C% y( l+ B$ j2 d) x" g/ N3 ~
W. q1 ?3 l N2 p! ]. `9 X
private:, R+ [' r# U- I# N9 A6 Y0 X% S, E% @ P! ^
CUPnPImplWinServ& m_instance;. Q! F' I) d3 e* O- Q) W# \; S% z$ G; @
LONG m_lRefCount;0 u1 h3 c! n2 n. r) R
};0 ? N/ E' ]4 x' @4 m; C5 d0 G
3 m* }- @8 Q% C6 B6 n, `+ t$ s: ]% W0 w
// Service Callback
+ X' i0 b9 l+ x% h0 Kclass CServiceCallback
( G& |& q( U7 w5 D. ^% D9 Y : public IUPnPServiceCallback' K* M) [8 u/ h8 ^( u+ n) A
{( A- X& z7 z: n
public: n6 U# I% X. l# P
CServiceCallback(CUPnPImplWinServ& instance)8 L7 X' ^4 O5 t; G5 _
: m_instance( instance )8 B# _5 M" r( c7 x/ U
{ m_lRefCount = 0; }
2 H+ r) Q9 c% S% V( S 2 D! i$ k7 I4 q7 B) ]0 @! W- V
STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);+ i( d+ D3 z8 E0 ^3 w5 V
STDMETHODIMP_(ULONG) AddRef();7 @6 l0 L7 k% |
STDMETHODIMP_(ULONG) Release();$ \9 w' u/ j* |8 T9 H6 K7 }
! h* b; @, l& n1 k
Z& ~- H: E$ J m6 c$ Q% u// implementation
9 q/ [, @' m) `/ Q z/ K9 kprivate:
1 ^6 }# K0 @0 Q' Y HRESULT __stdcall StateVariableChanged(IUPnPService* pService, LPCWSTR pszStateVarName, VARIANT varValue);- Q. V, Y+ S( w4 g2 i
HRESULT __stdcall ServiceInstanceDied(IUPnPService* pService);. F8 J; Z9 }- C8 b' B$ a. G
- z% l5 {6 U; m( r7 F( m! D% y2 [* C- C5 _1 U
private:
8 [! a- T6 U4 g9 x& P CUPnPImplWinServ& m_instance;. _: u+ W# u+ w) ]- ^1 w. m
LONG m_lRefCount;
" |* q* t! a: q' m, v% y6 S( N( A};. ?% W3 n% i$ u- b0 K
: y% c& [- F d5 z! ?- O
( v5 C4 j( S- O/ g9 e( {8 W
/////////////////////////////////////////////////
3 S1 i$ b: A2 i( U9 n/ e
2 c, V1 {/ X/ k7 o
6 k1 k+ y9 O! [使用时只需要使用抽象类的接口。: X. _, A* z1 M
CUPnPImpl::SetMessageOnResult设置需要接受UPNP端口映射是否成功的窗口句柄和消息ID.
' `# ]+ w; v& U F) Q2 uCUPnPImpl::StartDiscovery将开启一个异步设备查找并进行端口映射,其参数为需要映射的内网端口.
& K5 T8 a l( Y9 D+ S. X# ICUPnPImpl::StopAsyncFind停止设备查找.7 j% H8 k8 \; u c# N& \
CUPnPImpl::DeletePorts删除端口映射. |
|