|
|
楼主 |
发表于 2011-7-15 17:28:52
|
显示全部楼层
以下有关upnp的接口来自emule,
# U7 W& K. P, w* d6 j& ^2 @; L; H- o) `7 r9 m2 k7 @
' J$ Q9 i* V5 [% W, x/////////////////////////////////////////// G. R) B7 C& M3 X
//upnp的抽象接口类,只需调用这些接口即可实现端口映射功能.5 d: \" Z, y1 P: v2 h) H: e- k
9 s" e m7 y* a% R4 _. ?/ V
6 ^+ f. V+ q4 o6 B1 \4 H#pragma once+ C, G; c4 e5 T1 Y) q
#include <exception>8 e; O# M( \6 [. w
: h9 h; q. v! d
& ^2 H8 W1 E" x; o9 h) R enum TRISTATE{1 d7 V1 R2 j% `3 x6 S' y* Z( B
TRIS_FALSE,
9 d3 R6 y2 F- X6 A TRIS_UNKNOWN,1 z# b- x6 E+ o/ H7 e* X1 {
TRIS_TRUE% v/ @" |& x( f q. B7 i, ]
};
: `; L6 s0 l0 Z: O
9 L8 |9 `; u1 K" ?$ |5 t8 t
& o( a! U8 M$ s% ?, Oenum UPNP_IMPLEMENTATION{
; r, D( @" ^, `- b# C UPNP_IMPL_WINDOWSERVICE = 0,
# q# @ f: i( Y' L% d. l' D& ^$ t UPNP_IMPL_MINIUPNPLIB,0 C h. D/ i6 j. y
UPNP_IMPL_NONE /*last*/
% M$ J8 O7 r6 v3 P- l5 r};
3 Z' a0 B3 S" u1 h( p# b
8 C1 b5 `5 `' Z6 @1 w: V
+ H- A, f5 {4 M2 l9 p7 }& E. s) \$ Q4 E7 i8 _# m. w- C
- ]6 _1 B1 N& m6 W$ n$ G
class CUPnPImpl( K7 U D9 i' @8 G+ U+ a
{& y1 [2 J0 H5 a
public:
+ M- L+ R1 @# V7 ^+ z$ X CUPnPImpl();
/ A; M% L w I5 w4 R, t3 U virtual ~CUPnPImpl();, ]0 J6 P- I% F. g
struct UPnPError : std::exception {};
5 \/ t: s4 g9 p1 C: \5 u enum {3 v: w4 F7 ?4 H: s
UPNP_OK,( I! C; g$ K$ S
UPNP_FAILED,' i" w8 b; |+ \3 y& s
UPNP_TIMEOUT @ W1 p; h% p" T
};
2 ]8 B$ l( Z8 p
% H3 |, P0 G( y6 i% d7 R# K8 W7 X2 P, w" P! X
virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) = 0;
" s% r o [$ [& L5 C virtual bool CheckAndRefresh() = 0;5 a# v) A+ s1 [$ [* w
virtual void StopAsyncFind() = 0;+ @4 i0 G: L/ L! B2 m
virtual void DeletePorts() = 0;
4 N: w3 _0 K. O7 q& f8 u virtual bool IsReady() = 0;) T5 m( X- Q$ {" w, c3 X, [
virtual int GetImplementationID() = 0;
, _& ^+ u1 P* P# s7 _ ; ^; O+ {" g( H' Q
void LateEnableWebServerPort(uint16 nPort); // Add Webserverport on already installed portmapping2 u. X* o, f# e
! p) F& H! Y" D# f2 }
+ L' r5 }5 w% J% o, C+ r, N void SetMessageOnResult(HWND hWindow, UINT nMessageID);4 T( i, i& @5 h" I7 `
TRISTATE ArePortsForwarded() const { return m_bUPnPPortsForwarded; }
5 t- a. j5 M8 ~9 C% b uint16 GetUsedTCPPort() { return m_nTCPPort; }
- p. R( @" y" B. ~ uint16 GetUsedUDPPort() { return m_nUDPPort; }
. z& a6 D% M9 f, ^
) C/ u, L$ _0 v
# Q$ l( T$ g8 F6 W+ I// Implementation1 j* x7 ?+ V. T" j3 }- ^0 @. ~
protected:
; d5 r* k! ^. d. {2 S0 b volatile TRISTATE m_bUPnPPortsForwarded;
5 E5 \9 v) t$ `& s+ ]* ^ void SendResultMessage();
" G8 D( Y/ k, T( m$ h6 } uint16 m_nUDPPort;
( I$ b9 t* b! l+ y, Y& F ~ uint16 m_nTCPPort;% v( u; O @/ f( s4 n) G( L
uint16 m_nTCPWebPort;
2 O+ H8 m R. n5 _( i, E5 Q bool m_bCheckAndRefresh;
5 Q, p" `, C- f2 R2 ?" |* W+ @2 `& w, f. Q
% v! W' m1 m5 v; M+ T" yprivate: y, U9 T8 v) Y, m: Q8 T9 s8 B
HWND m_hResultMessageWindow;8 M# b$ a% X! h& c f2 k- E
UINT m_nResultMessageID;
- e k: o: b3 K% m' j X. H/ J
4 t2 `) h, J& }' ^; h) A" `, C+ L* x/ e# |! B, M' f: y: ~
}; ?' x1 O' K- R3 C
8 s9 X- j. n( @4 ]1 i5 N
7 j7 Z5 F5 R0 |6 N9 _/ e
// Dummy Implementation to be used when no other implementation is available
- y3 }: g- O% @% k- i4 Bclass CUPnPImplNone: public CUPnPImpl
% Y8 X$ {, C9 Q# {{
; n% ~% d$ ]6 x$ m% R; y- Gpublic:1 H' J& K5 `2 h* F5 e& i9 r
virtual void StartDiscovery(uint16, uint16, uint16) { ASSERT( false ); }, k& _( r7 v, l/ ~& G+ u
virtual bool CheckAndRefresh() { return false; }
7 z( j. ]% j" M1 m virtual void StopAsyncFind() { }
, S8 t5 K5 A3 O3 _ v5 t virtual void DeletePorts() { }7 M* u' ^- s& [3 S
virtual bool IsReady() { return false; }# m4 Z& v5 M v# S W1 b+ \/ P! U
virtual int GetImplementationID() { return UPNP_IMPL_NONE; }
S; H% {) J/ E4 o' |};& n+ \, \: W4 W( ~' Q$ F; K
5 T+ s5 H7 U9 T9 k
. T- K7 B- e, s6 j) k- d6 k2 i' ]/////////////////////////////////////
+ W0 Z' `+ V2 P$ H/ Q' j! Z1 _//下面是使用windows操作系统自带的UPNP功能的子类
- l r' q. C% ~: l+ V
4 m) ?4 K/ ]7 e% v9 l q8 J: u! w
( {& b$ D2 T5 x- U- O. e2 ^#pragma once/ I/ ~ q& L. V6 F
#pragma warning( disable: 4355 )
( e2 G: l* K# W9 p* X/ T9 U* h9 J }1 Q! F; `9 M" e' Q+ r
8 |2 F( t9 y* l! u& ?
#include "UPnPImpl.h"
' S) I, d$ ]& @! ~% p#include <upnp.h>
! N( Y3 A- @: {+ h3 B#include <iphlpapi.h>
7 E, _' g0 _! p. \0 q ]#include <comdef.h>
; P$ Q' F2 `# }#include <winsvc.h>: J4 _( N+ [# Y* I, A( E, T, a
! A, x3 t5 X- v. P0 W1 m; T- q! o6 z8 x3 J
#include <vector>
& b; L; J- n- a& o# {6 y#include <exception>+ M0 A- ]+ J; Y/ @/ h/ ^
#include <functional>
% f+ G, Q" d% a: o9 q! G- t; a" [ S- j. |( G) v( J
0 B' {, g, e9 |* V; @+ b o! X/ h6 o' s
" l& _" @. B' D5 ]. rtypedef _com_ptr_t<_com_IIID<IUPnPDeviceFinder,&IID_IUPnPDeviceFinder> > FinderPointer;" L3 ~+ f" z1 s2 R) q
typedef _com_ptr_t<_com_IIID<IUPnPDevice,&IID_IUPnPDevice> > DevicePointer;
! Z( k7 u8 J( V5 V( t7 ftypedef _com_ptr_t<_com_IIID<IUPnPService,&IID_IUPnPService> > ServicePointer;
- S# z% J$ g. I, L9 R: w' k% ktypedef _com_ptr_t<_com_IIID<IUPnPDeviceFinderCallback,&IID_IUPnPDeviceFinderCallback> > DeviceFinderCallback;
3 {% y( O* w L- m* l" Ntypedef _com_ptr_t<_com_IIID<IUPnPServiceCallback,&IID_IUPnPServiceCallback> > ServiceCallback;
/ J4 X* w' b# R, L5 mtypedef _com_ptr_t<_com_IIID<IEnumUnknown,&IID_IEnumUnknown> > EnumUnknownPtr;% X8 b- P' V6 P$ O5 y# s; L
typedef _com_ptr_t<_com_IIID<IUnknown,&IID_IUnknown> > UnknownPtr;/ H& h* M6 k& B [- J! o4 s" ?4 ~
" S3 m- U2 i1 w5 [9 |3 b
7 Q4 _$ H. R. a7 p
typedef DWORD (WINAPI* TGetBestInterface) (
9 A0 y; F% h0 j# t( ` IPAddr dwDestAddr,8 G2 C) R- o5 `
PDWORD pdwBestIfIndex& y! n$ j a! h6 p5 E4 P" H
);
$ m0 v( [1 i, @" U/ [5 c
2 S+ b# X) v3 N6 d4 S+ A
0 o3 ?1 {' P8 z8 B) F1 l" s9 ~$ ftypedef DWORD (WINAPI* TGetIpAddrTable) (5 z p3 i* X' s' h7 x/ ?
PMIB_IPADDRTABLE pIpAddrTable,
( J, f. p+ {, F* j) F5 Y1 u5 A PULONG pdwSize,/ b3 }9 V% t* J. M) ] @
BOOL bOrder+ E, h4 X1 ^4 ]& i
);
* O2 X5 @! M/ B$ `3 d6 Z
7 O4 u7 s v( ?. m0 j# ^8 I9 ?9 I: h! v$ g+ }# _+ j$ w
typedef DWORD (WINAPI* TGetIfEntry) (
! s9 y* U. ]' H& y9 g PMIB_IFROW pIfRow0 Q+ p: _' @8 N2 ~
);
" U1 [1 Z7 b/ H; R9 q" g" {
" z) r; D0 B: i- E x2 G4 H7 E [
! \. _# A6 S& z: v4 \CString translateUPnPResult(HRESULT hr);
# _" O- f% N% N/ ^0 y+ ZHRESULT UPnPMessage(HRESULT hr);# m S2 j. d; B* V6 c. o; s& V% F
" p/ Q- \5 H5 Q% Z& k n8 S) l& D0 ~8 J0 d
class CUPnPImplWinServ: public CUPnPImpl5 W& l( ^* Z3 W8 L6 T" q
{
6 P" d$ k8 y0 F$ ]# j1 O @, Q friend class CDeviceFinderCallback;* `. w8 _9 N. L
friend class CServiceCallback;( L* @& B# b+ x( k _( T
// Construction
) Y$ D& M# B* s+ i Bpublic:: h% q" ? X" y' \" B4 A" H
virtual ~CUPnPImplWinServ();
4 c6 p0 x. f4 Y# H CUPnPImplWinServ();
3 [9 c+ J% l0 @- B o% p2 ^+ R) O2 {6 M" z' ]! V
5 ?7 Y& E) l! X5 ^8 y
virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) { StartDiscovery(nTCPPort, nUDPPort, nTCPWebPort, false); }
/ c5 u: ? {! ^- \6 x4 Y virtual void StopAsyncFind();
6 G, w7 E8 @! H" ?, \ virtual void DeletePorts();
/ r0 [! N- ^* G% b0 M virtual bool IsReady();; K6 I9 @/ G, @( Z
virtual int GetImplementationID() { return UPNP_IMPL_WINDOWSERVICE; }$ P6 j( ]# a4 i" Q1 ~
$ |% e% z) x0 a! C
# v& u J7 U, c. Z- o // No Support for Refreshing on this (fallback) implementation yet - in many cases where it would be needed (router reset etc)/ ^2 F7 d) m8 S# T$ f
// the windows side of the implementation tends to get bugged untill reboot anyway. Still might get added later/ q4 f k/ M' u( g9 u
virtual bool CheckAndRefresh() { return false; };* w4 A1 h/ }+ L( w8 K ^8 h
) S1 a& W: [% T0 d
3 a! F/ K1 X$ [' S1 Uprotected:
3 ~- t1 u. }$ f7 C void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort, bool bSecondTry);
8 d2 N5 F5 N3 J: ^ void AddDevice(DevicePointer pDevice, bool bAddChilds, int nLevel = 0);
/ K! b. ^3 b2 W2 B# X void RemoveDevice(CComBSTR bsUDN);# u/ O& G7 `- g* V1 \
bool OnSearchComplete();
7 m2 ^' d5 w6 x' z+ p& e void Init();
2 N# n2 s8 I- n1 U) ~6 t
$ I" L- W6 n! x. l. S" S" |2 y! u! A1 T% z% O5 e& E6 k3 Z; y' v: r y
inline bool IsAsyncFindRunning()
4 d4 D9 p) ~ G$ { {: a8 F" B, G& W4 G) m$ G+ f' d
if ( m_pDeviceFinder != NULL && m_bAsyncFindRunning && GetTickCount() - m_tLastEvent > 10000 )
1 s. e% U/ n B( D {% r+ j8 Y( t. e/ O3 I7 ~) v
m_pDeviceFinder->CancelAsyncFind( m_nAsyncFindHandle );
; W0 Q0 l8 h2 n- Q+ q6 i, z m_bAsyncFindRunning = false;2 m9 P3 T) w( z6 A' c
}
+ z, @9 @1 o( @ MSG msg;
5 f N& V8 Z) O4 X8 P while ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )
0 @: i8 }6 X3 k( _5 P0 K {
2 Q* `7 @+ \# }+ r- G5 Q6 A TranslateMessage( &msg );" ^; X2 ]: d& V, c# v! e! T8 A
DispatchMessage( &msg ); T, Y5 m$ W, D7 A
}
; j3 ]" s# Q* C) ^ return m_bAsyncFindRunning;# t4 {/ }' M( c2 Y0 n {3 `: }
}
% Z$ F" Q. R/ w# k) P* I4 c6 `. z% f4 _
' [+ x" i( @/ y+ [0 R TRISTATE m_bUPnPDeviceConnected;
& a- G% Y0 l" O% ]( b
" P1 p. h% d7 D, w
' n0 R, l1 Q3 N" u& G2 U+ f// Implementation3 _8 ^+ y a; i/ Y* Q8 \8 ~* ]
// API functions
1 u% M" T) I o4 J/ L* a! m SC_HANDLE (WINAPI *m_pfnOpenSCManager)(LPCTSTR, LPCTSTR, DWORD);: r/ ]5 @& L/ S: Z: \6 `
SC_HANDLE (WINAPI *m_pfnOpenService)(SC_HANDLE, LPCTSTR, DWORD);
! |' o1 q+ J8 i+ O" B2 {# L BOOL (WINAPI *m_pfnQueryServiceStatusEx)(SC_HANDLE, SC_STATUS_TYPE, LPBYTE, DWORD, LPDWORD);
5 I6 `- n) v, L0 N2 @% R BOOL (WINAPI *m_pfnCloseServiceHandle)(SC_HANDLE);4 i+ J$ R( e1 ]2 G7 {) I
BOOL (WINAPI *m_pfnStartService)(SC_HANDLE, DWORD, LPCTSTR*);# m1 N3 I% C+ U) T
BOOL (WINAPI *m_pfnControlService)(SC_HANDLE, DWORD, LPSERVICE_STATUS);( _: B$ m E3 o. Q/ p @& G
0 u) |* q4 ? \& e
/ L: M# D( u) a$ O" W8 y4 [
TGetBestInterface m_pfGetBestInterface;4 i5 \6 i8 Q: L; D6 d
TGetIpAddrTable m_pfGetIpAddrTable;' q1 p2 v1 y* J2 r# y( S+ L5 `& w( i
TGetIfEntry m_pfGetIfEntry;
3 M6 @- N- I' o% i* I( Q
& l2 z5 D/ @& O1 r) _# F' i0 e8 V7 B F
static FinderPointer CreateFinderInstance();
# s* x2 Y6 `' _ struct FindDevice : std::unary_function< DevicePointer, bool >. B6 l0 Z) k+ a0 `& x6 ~/ L& {+ X
{
* w& M5 D9 s) H( R FindDevice(const CComBSTR& udn) : m_udn( udn ) {}
) L$ O; \: [8 L6 a result_type operator()(argument_type device) const
, S) [6 X+ G2 Z {
5 @* O9 ?- T' w$ s0 T CComBSTR deviceName;
# F7 S( I3 s9 H5 @ ?8 s: s5 [ HRESULT hr = device->get_UniqueDeviceName( &deviceName );, z2 f4 {% W0 G" [2 W- C7 [1 ^
# y" L! E: T8 }# M4 t1 g! D
! ]% o: |. }3 x
if ( FAILED( hr ) )' z2 A: E& x; N$ M
return UPnPMessage( hr ), false;
6 @+ j4 t8 w( q! k7 ?% c- k
- b8 C* Q# z+ f+ v& i2 g, O: R" s; S1 D( d6 \9 p" l- l( C' o' Q
return wcscmp( deviceName.m_str, m_udn ) == 0;
/ f+ r1 S; i8 d& H* L }5 u8 k' z0 L1 h% f" K& v& s0 y3 |
CComBSTR m_udn;
/ c- n9 t% U, y/ ` };3 [. R8 D9 H& w1 n( R
; K" |1 h) p, V' J% N+ G/ ]
void ProcessAsyncFind(CComBSTR bsSearchType);+ Q, h# F) B) `! a7 K! U
HRESULT GetDeviceServices(DevicePointer pDevice);
p+ I3 W! A8 h- j' T- O void StartPortMapping();
; X7 R. \5 c6 J/ l, j0 q5 _) \ HRESULT MapPort(const ServicePointer& service);- Q/ u& M T# F$ j
void DeleteExistingPortMappings(ServicePointer pService);: D) s8 P6 w, b1 k
void CreatePortMappings(ServicePointer pService);/ |/ d% [; S; r* Z
HRESULT SaveServices(EnumUnknownPtr pEU, const LONG nTotalItems); T! w8 Z! f: ?$ G
HRESULT InvokeAction(ServicePointer pService, CComBSTR action, 4 _7 n9 z- Y* V8 c0 J5 l% q& Y
LPCTSTR pszInArgString, CString& strResult);
6 U0 X/ D# V0 y" }1 Z( B7 I void StopUPnPService();
3 W+ F9 M' E3 [) X1 I5 g1 n
; @( i6 \! H5 E3 ^$ z9 \' V, l1 _' n& {0 ]
// Utility functions8 i, z: E1 V9 m
HRESULT CreateSafeArray(const VARTYPE vt, const ULONG nArgs, SAFEARRAY** ppsa);' @9 X, N4 a: ~) D9 W. }$ c9 {7 `
INT_PTR CreateVarFromString(const CString& strArgs, VARIANT*** pppVars);5 w2 Z1 W2 n, r4 R Q9 I$ Z
INT_PTR GetStringFromOutArgs(const VARIANT* pvaOutArgs, CString& strArgs);+ f& s, l3 ^/ I1 s
void DestroyVars(const INT_PTR nCount, VARIANT*** pppVars);
* u% D) B0 }7 [7 B0 o HRESULT GetSafeArrayBounds(SAFEARRAY* psa, LONG* pLBound, LONG* pUBound);8 b! R2 u. [& `5 y
HRESULT GetVariantElement(SAFEARRAY* psa, LONG pos, VARIANT* pvar);
! d! c% k4 P/ v* i% d. g CString GetLocalRoutableIP(ServicePointer pService);
* S- B4 J, Q/ X! O1 Z# B9 H3 o3 ^7 O
" E" O$ h9 `; l5 u, U
// Private members
U N- Q+ P d6 c$ ?( `private:1 y* u8 Z* v, v
DWORD m_tLastEvent; // When the last event was received?
6 ~5 m `0 F! `5 O3 g$ L std::vector< DevicePointer > m_pDevices;
. Q, s* W7 j+ Q/ a std::vector< ServicePointer > m_pServices;
t T4 \: i3 S$ B" n FinderPointer m_pDeviceFinder;
4 C, Z3 l- D3 o9 H0 U/ w& @ DeviceFinderCallback m_pDeviceFinderCallback;
3 \! B8 C0 s R$ q( X' V' T1 T* I9 G- [ ServiceCallback m_pServiceCallback;' _8 j9 Y6 j" K& w. G1 P
. k: a* W, `" m- m( u
T) z9 `$ s1 F LONG m_nAsyncFindHandle;
c( H7 g# j) ~ bool m_bCOM;
& ^2 [, x) I5 e' U& a* C. R bool m_bPortIsFree;7 x# K6 S7 X/ k6 k
CString m_sLocalIP;
5 p( V. y4 V2 P8 Z! C0 {, | CString m_sExternalIP;
. u% d5 s( Q3 l% m* v4 C; x bool m_bADSL; // Is the device ADSL?5 q. g* y3 D* C E5 h+ @1 i$ e
bool m_ADSLFailed; // Did port mapping failed for the ADSL device?/ n& u; F7 m3 C+ q
bool m_bInited;
% h, g3 i2 n# b) l- h bool m_bAsyncFindRunning;
! R4 d2 H+ `1 ^+ Y HMODULE m_hADVAPI32_DLL;/ `. R* l9 V( X5 w4 K1 X% C
HMODULE m_hIPHLPAPI_DLL;
0 A; ?; {) m5 p9 s5 ` bool m_bSecondTry;
: O( o0 T9 n% U, ? bool m_bServiceStartedByEmule;* g- g/ z K ~; e
bool m_bDisableWANIPSetup;
$ E3 R+ D5 p; K7 ~% s$ V' a$ D; v bool m_bDisableWANPPPSetup;# e- c( X% k/ A* ^9 L5 `. N
! q( F: S! G- @5 t/ W+ V' B! K
8 _& b) ]2 K( `8 I8 a/ e
};
j e% n8 x: j# v( G
1 I3 q: P9 D) @/ E$ J! s2 x; w w, n M0 e7 {
// DeviceFinder Callback' ?1 |8 W1 G2 y# p# ?/ i
class CDeviceFinderCallback, n: T/ `* S: `5 C9 j) e
: public IUPnPDeviceFinderCallback
5 h: l5 i( b; ?. D) [2 a{
- _. z J+ f- M/ V- K" Tpublic:( h u/ b- \" c; E) E7 w
CDeviceFinderCallback(CUPnPImplWinServ& instance)6 C4 w+ u) d- [- f5 S
: m_instance( instance )0 {, B' d8 w! X' s3 ~
{ m_lRefCount = 0; }& w+ o! j6 x9 S* F" P, v/ J
2 ~& z% V9 y4 B% Y9 j! u. j Y1 o
8 Y. @8 H& ^! a2 E% Z; g8 x STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);; C8 x P( _6 e% d+ g; L, V7 y
STDMETHODIMP_(ULONG) AddRef();4 i# B3 I _) C5 }6 q5 b3 T6 Q( {
STDMETHODIMP_(ULONG) Release();7 @7 U* d% l/ `3 v7 u- {; @
v* F$ d. A' ]9 y/ J3 X5 P: o- ?' W
6 f6 s) s ?: [ Q// implementation8 O# {8 s5 I6 }
private:2 @9 R0 b2 u+ n0 i
HRESULT __stdcall DeviceAdded(LONG nFindData, IUPnPDevice* pDevice);
+ r$ B P$ V W8 P' z, W Z& Z8 C HRESULT __stdcall DeviceRemoved(LONG nFindData, BSTR bsUDN);
8 w* v5 z# j ~4 G" ]1 W HRESULT __stdcall SearchComplete(LONG nFindData);
' t" _% ?0 k; s x( s" T/ b/ }) k
: J& I( k! R Q' K6 v
. s; x! K B- Sprivate:- |0 @1 S0 Q, J4 O2 k& ]7 T: ^. O
CUPnPImplWinServ& m_instance;
: ?" T# }; w, ] LONG m_lRefCount;' j" g* {$ r5 k* e
};
# Y' l* m# p# e, ]$ A7 Q6 K9 w8 U( S; A3 z5 S6 b; G4 H- ]+ k
( u8 @# j C) A h. e- W: }8 m
// Service Callback
5 ^9 y! G$ Z( rclass CServiceCallback: K+ g) T: C- H3 A8 r
: public IUPnPServiceCallback t" ?3 x! F. i' I% z. |( N
{
4 F" }. z( T5 O* ^: H' M f$ g* w* \public:6 k2 ~ h# R6 L. h! b; Z0 d
CServiceCallback(CUPnPImplWinServ& instance)
c3 D0 o M: c6 \, A) G' @ : m_instance( instance )
4 Q3 j2 |9 s/ ^+ V { m_lRefCount = 0; }
+ z7 t; o8 E6 V
0 ^, d! C1 S9 P) Y' j' q9 z STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);
: _0 M8 H# Y7 l+ ?6 b STDMETHODIMP_(ULONG) AddRef();& _) E9 F8 P1 A, T. R- ]8 b5 R: p
STDMETHODIMP_(ULONG) Release();% A: V( f, P0 V9 v, |$ \* d' @3 {
/ W7 N$ U) m5 u/ J6 R
0 u) d) H% x) _& r1 p// implementation- ?) U1 B. K$ y' c
private:0 @1 R e# g# B( }$ T
HRESULT __stdcall StateVariableChanged(IUPnPService* pService, LPCWSTR pszStateVarName, VARIANT varValue);2 m) J! H+ e8 E7 G$ N: }
HRESULT __stdcall ServiceInstanceDied(IUPnPService* pService);8 v" j9 i2 x; n7 k, n0 ^ G
9 x B9 W. Z3 T% e' E0 @: `, S3 a' f) g+ \2 p3 b
private:8 f1 d3 v% i: e( b; [
CUPnPImplWinServ& m_instance;
6 e# V6 E# ?8 s. W LONG m_lRefCount;; \' N5 f0 x5 s- o
};
! r$ G$ v$ o4 W0 F0 b5 l' z# K9 d; B# X. v
4 D# _ ]( d1 h& \
/////////////////////////////////////////////////
4 g2 G4 T7 a2 E) m6 ]& A- v" _ i
& {) G6 m; w0 L5 u使用时只需要使用抽象类的接口。
3 U3 D# |5 H9 v9 o6 l6 X# |- K, KCUPnPImpl::SetMessageOnResult设置需要接受UPNP端口映射是否成功的窗口句柄和消息ID.
$ d* ^" u8 P5 R1 I7 `! V ECUPnPImpl::StartDiscovery将开启一个异步设备查找并进行端口映射,其参数为需要映射的内网端口.
: X" s# a1 I) bCUPnPImpl::StopAsyncFind停止设备查找.+ z, `: d* S, k' T( N/ w
CUPnPImpl::DeletePorts删除端口映射. |
|