|
|
楼主 |
发表于 2011-7-15 17:28:52
|
显示全部楼层
以下有关upnp的接口来自emule,' C8 B% a& a6 i! x, {
. V M8 `4 q O! S$ m# V& ] Z6 V% L: {* J/ @
/////////////////////////////////////////// V7 X' G2 `: k9 }
//upnp的抽象接口类,只需调用这些接口即可实现端口映射功能.
5 R0 l% ]- P0 j: @
" y& A8 o* D; m7 x) ~
) n* S3 K/ ^% [3 c7 G( B" {#pragma once
# w9 v' E, N/ E" }#include <exception>
4 h6 M3 g3 i; N1 y$ \' r3 `6 k6 X% x$ _
3 o9 q) y9 h# q enum TRISTATE{/ a* v- @( w. C- \
TRIS_FALSE,1 N& ~# V4 B! t* `& o
TRIS_UNKNOWN,
& M5 Z9 K% L) \! f TRIS_TRUE; X1 t4 w) I. l# j0 c v( v
};
/ h$ ?. _) v+ o7 S- \
" S' ?, g/ g& v. D/ A; c) I: d1 u* ?2 ]' x" R
enum UPNP_IMPLEMENTATION{3 q8 G% h! @ |6 o$ O/ o
UPNP_IMPL_WINDOWSERVICE = 0,
; j2 d B+ T: A9 K2 I( {. R UPNP_IMPL_MINIUPNPLIB,9 }7 j' S. q( z& @! \' q
UPNP_IMPL_NONE /*last*/% a+ o2 T: w8 C7 f: N! } i
};
9 i4 U/ P1 ?1 p$ N. Q
; F0 c0 w% E, r/ v5 c1 ^
3 p' L$ W. d* z; r' r R: g7 ?3 g& ]- `$ {0 t7 D, s
/ T1 j6 V7 L2 ~8 w
class CUPnPImpl; \4 ^5 t7 P1 `2 N! x3 ?
{
+ ]8 B U6 Y3 v) \public:% w9 ^$ T% s3 k- Y6 ]4 V6 L7 e) v
CUPnPImpl();
; S v ?0 K4 R* M7 [1 Z9 v virtual ~CUPnPImpl();/ f0 K8 q% ]# @5 F# S H+ ^' |* s" v- x
struct UPnPError : std::exception {};
; w. I2 _& k' p% Y8 ^: K enum {7 d' H/ d2 W, A
UPNP_OK,$ i- ^' _5 b) h+ F3 w: |8 ?) D
UPNP_FAILED,
3 ~! M" k' M+ Y: R5 v4 ] UPNP_TIMEOUT
+ f/ g1 a% Y2 V2 z" d/ E5 n( { };
7 F0 Y6 h6 V% b% K6 `7 ^! g& L0 }/ l7 m3 v" P( M
% d7 {+ u& l- d, U9 T: k0 p virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) = 0;7 H6 W- K: C: U
virtual bool CheckAndRefresh() = 0;
( H7 v- S* e2 d virtual void StopAsyncFind() = 0;
/ e( B! A' e: R# ] virtual void DeletePorts() = 0;
8 E4 G! {4 c/ k1 p6 z j9 u virtual bool IsReady() = 0;
4 H1 u8 M6 f2 D8 ?5 M virtual int GetImplementationID() = 0;; f! d2 l5 I1 w0 K- `
5 t3 @% f$ ^* p8 n" N void LateEnableWebServerPort(uint16 nPort); // Add Webserverport on already installed portmapping
* S! b9 N4 i& ~8 }2 u, M7 h" H2 Z8 r7 a( r; b* B7 i
- X, }: G3 N% |7 F5 l. m void SetMessageOnResult(HWND hWindow, UINT nMessageID);8 ?1 c& B; p, r8 V) x
TRISTATE ArePortsForwarded() const { return m_bUPnPPortsForwarded; }
+ v: ?) u2 v$ z$ s" \$ L uint16 GetUsedTCPPort() { return m_nTCPPort; }/ d. h/ @9 U3 `7 c1 n
uint16 GetUsedUDPPort() { return m_nUDPPort; } n E4 X) x# b) t b! A
0 {4 y* V- C# d( c( q( e5 Y [7 L7 R5 d4 T0 @0 ?, s: _7 c7 b
// Implementation
6 c0 b H! `) N7 Q, iprotected:1 i0 K& i% D" p" F2 F
volatile TRISTATE m_bUPnPPortsForwarded;
8 U. R( R: Y% J- l void SendResultMessage();2 U3 p% N& f0 P; `6 R
uint16 m_nUDPPort;
5 j* \" r+ [0 m. ?: j4 T4 q uint16 m_nTCPPort;2 X- r! B$ K% f) y9 P
uint16 m_nTCPWebPort;0 Z* l1 B5 t1 R* F
bool m_bCheckAndRefresh;
8 w$ U. m; i' \
A6 |) b& _: W' k, S
# E0 X. }6 ^9 o! h/ rprivate:) z+ g2 y5 I9 G& x h' R
HWND m_hResultMessageWindow;
: h1 t1 Y$ U# f, |' i3 i- N UINT m_nResultMessageID;
7 T( W" H& J0 j: V$ y5 _% G: s }7 K, D4 p- @
% i7 O4 p3 b. Z
};3 ]% Y3 c& n4 `# d# j9 w& u
3 o, m. |* o* H: V' V0 s% P- {
! m# r; O6 A3 m1 D7 y// Dummy Implementation to be used when no other implementation is available+ I6 K' h0 u7 B
class CUPnPImplNone: public CUPnPImpl
$ b, ]# l1 Q# n5 c! R9 ?/ l{% F% T) u/ k( ]: v, @: t6 z3 G
public:: \% a* b/ v- i
virtual void StartDiscovery(uint16, uint16, uint16) { ASSERT( false ); }0 H( s8 ^5 o4 H, ?& w! d
virtual bool CheckAndRefresh() { return false; }
. C& M5 j7 T0 U6 r! [9 [; i1 r+ E virtual void StopAsyncFind() { }
2 y1 p |, I1 C virtual void DeletePorts() { }
; n ~% b& g' Y$ f* r virtual bool IsReady() { return false; }
5 A& q2 V( h! z" g virtual int GetImplementationID() { return UPNP_IMPL_NONE; }( F& E1 E0 [$ Z* p# S V& M3 {1 A
};1 V0 l3 p# n& T0 G* k" I
- l& N1 D% ]4 ]2 `1 k# u. b3 E) I
) M! p$ a" H; j
/////////////////////////////////////) q0 d" h% ?- l
//下面是使用windows操作系统自带的UPNP功能的子类
. D9 A7 ^/ O d* T3 w% B; F& S% _7 x8 C9 H4 J) V; H) ] g
3 n# I: U6 d' _' D( m
#pragma once9 ^1 w6 u6 Z' J* H
#pragma warning( disable: 4355 )
. }* Z1 n* y- n# c4 @2 V1 o- ]1 }
) [* d1 p* {9 d3 Y0 D0 o0 P#include "UPnPImpl.h"
5 C$ J$ k& M2 c1 V! f#include <upnp.h>, @. Z4 v: m2 d
#include <iphlpapi.h>$ q2 s( j0 G. T2 g! ~/ @# H. g2 l
#include <comdef.h>' K# q/ @8 E" W% u) x3 f
#include <winsvc.h>
! n* S- _. E5 R- H& U; n0 [ z
* D2 e2 B6 _: \5 u6 ~% v" ?5 _) R, n2 v6 @+ n$ i* N9 F+ L, M
#include <vector>; j9 e% F# _# D8 o( {6 N( Q
#include <exception>& B. `. J# e5 p, n4 ^8 k
#include <functional>
& p4 i) x0 J# \& S* W2 e
1 a. y3 L! g" P" a f7 d k: L6 _7 o5 B6 c; a/ p) b
, E& r a8 O$ j( J8 \" C
' T1 V* `& {& m& p- ftypedef _com_ptr_t<_com_IIID<IUPnPDeviceFinder,&IID_IUPnPDeviceFinder> > FinderPointer;
) g1 A2 F6 r" s. m' }1 V/ B! V2 [typedef _com_ptr_t<_com_IIID<IUPnPDevice,&IID_IUPnPDevice> > DevicePointer;
& d7 ]5 \' w) |- E6 l: Qtypedef _com_ptr_t<_com_IIID<IUPnPService,&IID_IUPnPService> > ServicePointer;
/ d' j. L) O. U' q+ D! J( \: Rtypedef _com_ptr_t<_com_IIID<IUPnPDeviceFinderCallback,&IID_IUPnPDeviceFinderCallback> > DeviceFinderCallback;5 A9 D' K( ?" F' W- k: h( G
typedef _com_ptr_t<_com_IIID<IUPnPServiceCallback,&IID_IUPnPServiceCallback> > ServiceCallback;- U0 `4 M& |- C, d& {
typedef _com_ptr_t<_com_IIID<IEnumUnknown,&IID_IEnumUnknown> > EnumUnknownPtr;' J6 u" i8 W, V2 l, Q
typedef _com_ptr_t<_com_IIID<IUnknown,&IID_IUnknown> > UnknownPtr;
+ ~9 V. }) H4 m- Z7 u! M4 ?0 y, Y. E' V8 E
* i+ H' }; m8 e% p, r1 Q# p
typedef DWORD (WINAPI* TGetBestInterface) (
2 w" C: P4 _6 j' b% H1 z9 o4 \ IPAddr dwDestAddr,3 Y9 {" j) Q: Q& `% ?4 Q/ }
PDWORD pdwBestIfIndex& @7 n* F/ L6 ^- F( d* h5 q1 Q
);
e5 e8 c; i8 ]7 \' `0 y! x3 R- X4 e4 [! V# ^6 l6 v
. D1 K! Z9 R) y. X: C& ltypedef DWORD (WINAPI* TGetIpAddrTable) (
Y3 T" R7 S) [, J PMIB_IPADDRTABLE pIpAddrTable,
' h- J7 p" K, R PULONG pdwSize,
8 Z0 a* ?8 S) H6 D" @$ } BOOL bOrder
T( P5 h9 H1 {. W4 w% p- e: @' |);5 t' j r5 B! k, v% G& l% E
, t( Z( X% t N/ D
6 O9 E6 k+ S. g0 c+ h$ D% i8 e, }$ t% ]typedef DWORD (WINAPI* TGetIfEntry) (
% W" G n" ?6 ^ Q+ i PMIB_IFROW pIfRow6 C$ B* o& q& X, u: Y' d) }
);
) e* A& U. ~0 Z1 {& K- I
) H9 n- b* q+ n6 _3 X b- g: j0 `1 b9 w
CString translateUPnPResult(HRESULT hr);0 W6 E1 s( Y' ^
HRESULT UPnPMessage(HRESULT hr);
# r6 T$ N4 I- O* r! R
$ |' P5 d* _( G& M: V" ]4 b, O* r; i, X T: k0 G9 s5 o: Z0 n2 F
class CUPnPImplWinServ: public CUPnPImpl
+ h$ w( W+ \- }8 F{) \6 f* y" h1 B7 W& x6 x$ ^4 [
friend class CDeviceFinderCallback;5 t& _7 \" \4 L. M6 [
friend class CServiceCallback;. t" l& C+ c$ K# R/ m) v
// Construction2 z3 G i$ n# W
public:4 w1 T* q: K( ?: F7 M$ u
virtual ~CUPnPImplWinServ();* E3 X+ ?1 o) t! i7 P
CUPnPImplWinServ();
. d' T6 ^; W" `( m q; _" U1 d7 X W9 u7 H& y
0 a. B, i, U0 h' l virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) { StartDiscovery(nTCPPort, nUDPPort, nTCPWebPort, false); } X5 @! n, r. a/ H2 _# A
virtual void StopAsyncFind();
+ q5 P" }) u7 v2 x) F2 E! B virtual void DeletePorts();$ J- s$ @: n4 o: t5 M% j8 l+ ~
virtual bool IsReady();
5 m5 o" @, i/ [6 \ virtual int GetImplementationID() { return UPNP_IMPL_WINDOWSERVICE; }3 B/ ?8 J0 N, e% l, u
2 R$ a& N0 J- E0 W1 a
$ N0 n8 a" X) o0 _ // No Support for Refreshing on this (fallback) implementation yet - in many cases where it would be needed (router reset etc)
6 U" }3 y+ h1 m! S& P // the windows side of the implementation tends to get bugged untill reboot anyway. Still might get added later( X3 M* s1 k6 Z# i
virtual bool CheckAndRefresh() { return false; }; i# d+ J8 J$ F. ?/ c# E
" W4 Z9 F3 H. \' ?! V/ j( q Y( @
protected:
$ ^ n( D" d" _- i6 ] t void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort, bool bSecondTry);7 d# N1 F( u3 N1 l4 A {
void AddDevice(DevicePointer pDevice, bool bAddChilds, int nLevel = 0);: z7 @3 ~: U4 Z3 |9 j! j/ L
void RemoveDevice(CComBSTR bsUDN);4 g7 j2 y [' ^1 O2 v) r* g. V" @
bool OnSearchComplete();
) F/ s% F K9 t' H: U! O% T void Init();
* V8 y0 k$ T% ?* q7 ~
- N% f' z; s, |5 J9 T5 _# k& u! O7 J
inline bool IsAsyncFindRunning() 1 N" o- y6 D) ?! k' K% B' c
{
0 F/ h! J0 p6 R6 W* u$ b1 f! }" u9 c0 s if ( m_pDeviceFinder != NULL && m_bAsyncFindRunning && GetTickCount() - m_tLastEvent > 10000 )
0 R6 ]' i5 |8 m {
9 r" t; K9 |) }. F6 M! ] m_pDeviceFinder->CancelAsyncFind( m_nAsyncFindHandle );
$ x2 d# ]# |( e) n. ^4 s m_bAsyncFindRunning = false;" c' A) b0 L! A/ a9 @, X( Z
}% o8 W/ Q7 X) j3 Y
MSG msg;
- o5 H6 S5 o" l) X while ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )
6 `8 B8 e# k W2 K, n* M {
/ C: o$ c# Q: Z. E TranslateMessage( &msg );
T7 v. S. ] q7 K( c$ E5 \ s. p DispatchMessage( &msg );
' r( K9 u) Z. g2 O8 R4 m: n' M9 l }9 ~+ \7 ~/ A- V
return m_bAsyncFindRunning;
8 T& l7 ~9 ~. I5 @# c; C$ o& b) w }4 ?( b8 T1 ^: J
, d% c- W/ x; F `' l' @+ R
+ V7 G" ~6 ~! \5 i5 i; t% u TRISTATE m_bUPnPDeviceConnected;
% e+ o7 v% b& Q9 e- ]1 d
2 L2 j# S+ ^# s& O% X) Z
4 v6 _9 d" ^9 X4 v7 Q, _0 S// Implementation' l' |- C& K3 o8 l6 l
// API functions, W( j( y% h( _! ]$ O- a+ s
SC_HANDLE (WINAPI *m_pfnOpenSCManager)(LPCTSTR, LPCTSTR, DWORD);
3 a/ U: @( j' W SC_HANDLE (WINAPI *m_pfnOpenService)(SC_HANDLE, LPCTSTR, DWORD);
: q/ M9 ?" m! ? BOOL (WINAPI *m_pfnQueryServiceStatusEx)(SC_HANDLE, SC_STATUS_TYPE, LPBYTE, DWORD, LPDWORD);& o6 p: p: ^% K; [1 x6 R- m3 W
BOOL (WINAPI *m_pfnCloseServiceHandle)(SC_HANDLE);1 D, m1 B* C# n3 I6 s/ V; g
BOOL (WINAPI *m_pfnStartService)(SC_HANDLE, DWORD, LPCTSTR*);9 V( k- ^! T+ u0 W# N( E% m7 E
BOOL (WINAPI *m_pfnControlService)(SC_HANDLE, DWORD, LPSERVICE_STATUS);/ D- ~3 l7 A0 _: |2 |
/ f" x. Y4 L5 g5 K: O$ s& R& h& B3 g2 w* r% a; n1 z
TGetBestInterface m_pfGetBestInterface;
, Y( W7 y) o; D$ P* O4 S1 b% b TGetIpAddrTable m_pfGetIpAddrTable;
; Y7 ]/ o( `! O, y; v% K- t TGetIfEntry m_pfGetIfEntry;! {" |. N( N5 f e; M
$ S+ b6 J# w, f: X0 f* i9 }# z3 P5 ^
; ~& ` i7 U, {: `/ v
static FinderPointer CreateFinderInstance();
' F# z" d# i( M, X struct FindDevice : std::unary_function< DevicePointer, bool >0 _6 }) a1 S$ X, F$ U: s" Z$ t- [
{
- u }- Z6 q; K! z" G FindDevice(const CComBSTR& udn) : m_udn( udn ) {}
7 r0 }- E/ s1 u' @8 j result_type operator()(argument_type device) const
! F% X/ {2 G- }* ]" D( B {. Z& [5 _) y/ e- k. j* K, O
CComBSTR deviceName;
: F( V9 @7 S* [; w# \9 F HRESULT hr = device->get_UniqueDeviceName( &deviceName );: V; i/ j4 q+ c5 I4 T
9 D+ M* h5 n1 q0 v/ m
4 N9 V! J2 z5 F if ( FAILED( hr ) )# H& \- i; d" T7 |4 U2 s
return UPnPMessage( hr ), false;% X+ U/ e* v2 z
( X% ]2 d# r6 a2 F
5 {1 N+ N/ y8 m9 e! k return wcscmp( deviceName.m_str, m_udn ) == 0;
0 [% g5 O, I! V$ S0 Q& T+ a( T }
: S8 c0 c0 N5 \8 [% ?4 r CComBSTR m_udn;- k4 j! q7 e; F) ^" q R a
};8 u& e6 Y: v5 G- D
" h( s: I+ A. h5 q0 a2 ^ void ProcessAsyncFind(CComBSTR bsSearchType);
7 S3 |; J @1 Q+ b+ ]4 e HRESULT GetDeviceServices(DevicePointer pDevice);0 c# S6 i3 } v8 J0 X5 X$ Z9 w4 l
void StartPortMapping();
% @* z2 T) y$ B6 j" m" N8 [- f: D HRESULT MapPort(const ServicePointer& service);/ P" a, p' Z' m5 ^6 u6 x
void DeleteExistingPortMappings(ServicePointer pService);
# u$ p1 t5 {/ z5 ], I void CreatePortMappings(ServicePointer pService);4 r+ x6 |! H/ h5 B
HRESULT SaveServices(EnumUnknownPtr pEU, const LONG nTotalItems);8 x3 \* z) [$ B( {/ T
HRESULT InvokeAction(ServicePointer pService, CComBSTR action, 8 ~# [/ ~4 M+ S7 f M; ^
LPCTSTR pszInArgString, CString& strResult);
' Q( j+ L3 `* Y& C void StopUPnPService();" t B, g3 n! U: X
, r2 t& a: V ^ G3 g0 v$ f# w' m4 i- b& C6 M
// Utility functions" }' v. m7 s, i
HRESULT CreateSafeArray(const VARTYPE vt, const ULONG nArgs, SAFEARRAY** ppsa);
8 }2 o8 S2 m7 O/ `3 O8 Y8 u INT_PTR CreateVarFromString(const CString& strArgs, VARIANT*** pppVars);
* a W/ N; F) @& o9 S8 W INT_PTR GetStringFromOutArgs(const VARIANT* pvaOutArgs, CString& strArgs);, D# p9 P) b1 k% O2 R' H& ~& S. f
void DestroyVars(const INT_PTR nCount, VARIANT*** pppVars);$ s7 b3 r7 v3 t8 H! s7 B
HRESULT GetSafeArrayBounds(SAFEARRAY* psa, LONG* pLBound, LONG* pUBound);: y! Z- _6 A+ V5 m, C z
HRESULT GetVariantElement(SAFEARRAY* psa, LONG pos, VARIANT* pvar);
/ H; ?. O- J- A# H ]% q CString GetLocalRoutableIP(ServicePointer pService);
5 h, f& X# Z3 [- ?9 P' t# b$ W- m" }5 W" z9 p+ W
) u. j/ S+ P2 [- ]: {// Private members& k7 F Y: o! S, ?
private:
. c) M7 q5 _, w- y8 _% ? DWORD m_tLastEvent; // When the last event was received?
* h: }1 u: M, S) w std::vector< DevicePointer > m_pDevices;
' g1 e6 M* l% `8 n9 h std::vector< ServicePointer > m_pServices;
/ y1 T( r C2 A* t/ { FinderPointer m_pDeviceFinder;
8 C) N1 A* o* d: @8 w* f3 [ DeviceFinderCallback m_pDeviceFinderCallback;# H8 P, V/ J4 Y5 t9 Q y
ServiceCallback m_pServiceCallback;
1 E$ h7 z2 N( n1 E" V+ m* J6 Q9 J( F4 A# n
. N9 L! q* d4 U7 Y
LONG m_nAsyncFindHandle;
/ L# ]: [9 l3 F( K bool m_bCOM;# ~6 q2 T6 v* F' ~- i
bool m_bPortIsFree;3 V5 t, Q2 v9 ^: a" b' ~% y+ n
CString m_sLocalIP;
; b* ?1 t4 Q+ X3 g' c0 {% E CString m_sExternalIP;
: D8 p0 A& _6 r bool m_bADSL; // Is the device ADSL?1 S% A7 F2 D' O5 M' d
bool m_ADSLFailed; // Did port mapping failed for the ADSL device?) K: r+ e# I+ t& y5 d6 f7 C/ d
bool m_bInited;
8 {- V8 a2 u. A$ H3 h- ]% i bool m_bAsyncFindRunning;+ w$ G, S6 Q- p9 m; D
HMODULE m_hADVAPI32_DLL;
7 t P" J* y: j HMODULE m_hIPHLPAPI_DLL;
& o @* ?3 ?, L ^! Q bool m_bSecondTry;: i3 z7 X, `) }- D; C/ e
bool m_bServiceStartedByEmule;0 G( w9 I6 ^2 _7 [
bool m_bDisableWANIPSetup;
7 D* I' d' j, D; d bool m_bDisableWANPPPSetup;
& e' s6 V. I' u1 t
+ p$ J: }. }( i2 C: Z& Z' F7 M0 i6 b% Q; N1 |* R J
};
4 H4 D: y& h0 j+ c8 H
# n9 o$ I/ y; n: R' r, w/ n. z7 W- Q# Q
// DeviceFinder Callback
, D: \+ J0 o3 W, }5 \1 w! vclass CDeviceFinderCallback; Q- ~2 r% t2 V
: public IUPnPDeviceFinderCallback) g* p- i4 |( Z4 r5 h! f1 a
{
2 T( s# R! h; y Q) k1 Bpublic:
; V8 i4 r2 \- J CDeviceFinderCallback(CUPnPImplWinServ& instance)1 h6 I9 U% z, O$ m
: m_instance( instance )5 d) C# j. s' G9 ~1 F! B& L' _
{ m_lRefCount = 0; }& M# J* J) C5 c- v L0 E1 Q* r
% g) \8 o% U. o6 P$ |4 Q4 Z( G8 |1 ?# s' Y6 V* h
STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);5 H- }: M; s. E% C% r
STDMETHODIMP_(ULONG) AddRef();( p$ L4 }, W+ a- {4 g
STDMETHODIMP_(ULONG) Release();7 W) B4 l* _2 ~6 r
2 O7 _* C; {* U# r% u/ E) K
* I' f# \0 I" P$ U2 M// implementation/ A, ]0 e* ` [, O S5 @
private:7 l; i8 j8 t8 X4 f
HRESULT __stdcall DeviceAdded(LONG nFindData, IUPnPDevice* pDevice);0 x5 R% w X: j
HRESULT __stdcall DeviceRemoved(LONG nFindData, BSTR bsUDN);
7 g- h7 g! z F$ z3 I HRESULT __stdcall SearchComplete(LONG nFindData);
8 S, C+ S5 l; v$ M, e/ w- _# g$ S0 Q- h _6 J8 i
" q. o8 M+ |) K3 p9 @
private:# `* I0 B0 x; B; b: I3 r
CUPnPImplWinServ& m_instance;) c9 p3 |5 {7 D" }- R) ?' b
LONG m_lRefCount;" j- g% v- a! c3 J! \
};1 q8 d1 D% i5 R0 }
9 ?( c9 v6 m) k7 D. R( D- _
5 U, i/ |( i5 J+ Z: I; i( r// Service Callback
& [ a0 F) O3 {& i' @class CServiceCallback* R* p. e L! w. `1 g/ Y6 l
: public IUPnPServiceCallback' I# H8 c* c- f! Z& v
{
9 v5 w. d* l8 o" ]public:
( ?1 `+ _/ t0 z/ N& P CServiceCallback(CUPnPImplWinServ& instance)+ N* T4 \2 D6 h1 j. R
: m_instance( instance )
5 I2 g6 p* s* o) W) F { m_lRefCount = 0; }0 |: v/ B8 b1 y3 h! L, M
+ l- ?& {" ^6 E, H: E0 g STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);
% S( {9 p( O. s) ] STDMETHODIMP_(ULONG) AddRef();9 h) \: D+ l7 G6 r
STDMETHODIMP_(ULONG) Release();- Y9 K0 e& ?& v
; z* `( a9 F; h; ^4 Q0 u
' U) k& `0 V& J) e! h
// implementation
, N0 T! S* x4 n. C/ f6 H9 Oprivate:! \- R0 s0 }' ?8 M$ y
HRESULT __stdcall StateVariableChanged(IUPnPService* pService, LPCWSTR pszStateVarName, VARIANT varValue);
1 U# E+ {) r) W8 b HRESULT __stdcall ServiceInstanceDied(IUPnPService* pService);
4 a2 T/ X7 N. J% x+ t* I P3 D/ w
+ O) s% B6 @# G' E) l& L2 _
1 i3 O; K9 e# ~! y- }2 M aprivate:
. y C" E/ r1 k7 {% ~ `$ w CUPnPImplWinServ& m_instance;5 Q* n5 v4 g; j% H
LONG m_lRefCount;
) I. f! b/ W8 R- ]+ V" G( y};
7 j$ d, T0 L; a1 U+ o7 f& [8 ?! f& n8 A
$ c+ {) ~3 ^! m; W* q, A/////////////////////////////////////////////////
1 }2 `4 O2 n' \. _9 Z5 h# H* z9 Q u
, r; p- n! ]( ^$ E8 w. J1 P+ T: Z
使用时只需要使用抽象类的接口。
- K0 L1 l! Q9 FCUPnPImpl::SetMessageOnResult设置需要接受UPNP端口映射是否成功的窗口句柄和消息ID.
* ^! s2 _ q* e5 s0 l( c; u" tCUPnPImpl::StartDiscovery将开启一个异步设备查找并进行端口映射,其参数为需要映射的内网端口.
+ t ]5 J. ?7 z9 G, K9 Q$ vCUPnPImpl::StopAsyncFind停止设备查找.% T* G4 v$ K( r/ z; L
CUPnPImpl::DeletePorts删除端口映射. |
|