|
|
楼主 |
发表于 2011-7-15 17:28:52
|
显示全部楼层
以下有关upnp的接口来自emule,
R, w9 c. F5 q" j5 e( G2 S3 A! Q" v
8 D7 l) p9 b$ c7 A+ x1 r9 C6 W7 e2 A7 }
///////////////////////////////////////////
) h$ Q; B1 ?" `) R* _ j5 _ v8 ?//upnp的抽象接口类,只需调用这些接口即可实现端口映射功能." p# \9 p0 P# `9 D- z$ i/ ~6 K
+ z- p+ @) c, V# E
1 o, a, I6 y& ~
#pragma once/ i# A' Y$ k2 O7 d5 z$ z
#include <exception>
" Y7 b: }5 S8 E! H1 T8 E( K
' e, n- k) j) n% K
3 c: |+ N1 u$ G! v enum TRISTATE{
1 f% Y& J8 J& W c! F TRIS_FALSE,
, h9 T, }# I3 m0 x TRIS_UNKNOWN,; T; Z: x: L# C# ~; h$ E
TRIS_TRUE0 q& Q/ i/ _ x3 @
};4 ^9 G+ g) s! {( F8 X$ N0 ?' a
" u. L/ U5 R6 | c$ D( o0 _7 V* {
! N' h) W& R8 P5 Benum UPNP_IMPLEMENTATION{
3 ^2 t( E% i; u2 k! g UPNP_IMPL_WINDOWSERVICE = 0,
. y/ U. t9 \9 N+ I5 Q UPNP_IMPL_MINIUPNPLIB,
$ \. z: R% C% V. C! ^ UPNP_IMPL_NONE /*last*/
0 X0 y" p# D# G3 C S e Z};, k1 _ Q+ e( N) h, u5 N! m
" |3 s( b/ m8 m1 h6 r+ r8 E+ Z
H* }9 Y, X( }8 f+ w) A
$ o: C" a2 \9 Y% P/ Q# ?0 A) ?2 b! H/ r& g. L. \" \
class CUPnPImpl; {# I9 ?, v5 _2 w# E9 W7 N
{% l2 g/ q7 D8 Y1 ]- j
public:
5 w1 l7 E3 k+ i CUPnPImpl(); [( k0 U4 C- K5 Z, G
virtual ~CUPnPImpl();$ ?0 S" O8 E& t; |
struct UPnPError : std::exception {};
h& v5 I7 G2 V. y8 F8 G6 w, J) ^ enum {$ y# r* b# N+ r* p3 P# `& d! F( }
UPNP_OK,
( Q- O" U4 b1 l: V* i UPNP_FAILED,3 ?. K- w, F9 ]9 e+ t( F1 o3 R" O
UPNP_TIMEOUT7 q8 v8 l2 n) A- u- G( \( W
};
0 `7 Y0 a2 S9 _ V. {9 `% N, S" I' S" P1 r0 u# |3 `/ i8 ]# s
1 `) t1 k" x4 r, `5 \, \
virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) = 0;
' Z! W9 ^: k! y% L. y virtual bool CheckAndRefresh() = 0;8 t& [3 G0 h2 `) ^
virtual void StopAsyncFind() = 0;* r2 l. \0 a: B/ A4 N4 w
virtual void DeletePorts() = 0;0 B- e+ T, m* ?7 `
virtual bool IsReady() = 0;: z7 [# _4 h' Z1 r
virtual int GetImplementationID() = 0;( c& t0 H4 H- A& U0 r2 n8 F. c2 W
2 T7 y1 h% S# T! p) L3 G3 S/ @
void LateEnableWebServerPort(uint16 nPort); // Add Webserverport on already installed portmapping
: E2 o# E2 V; R4 i4 H3 J# e- C# a. j0 k% c- G6 q
6 K8 M) ~4 n7 I8 D3 E3 ] void SetMessageOnResult(HWND hWindow, UINT nMessageID);
( F7 q( O, @ ~ TRISTATE ArePortsForwarded() const { return m_bUPnPPortsForwarded; }4 w: P) k3 P: `, j$ n" `( G$ B
uint16 GetUsedTCPPort() { return m_nTCPPort; }
$ e' @( I% k- ~$ ~) _ uint16 GetUsedUDPPort() { return m_nUDPPort; }
+ N! z: x3 q4 @, l* E$ G
- E* M8 d6 u3 k5 I ]: v4 S x8 V1 I& e: K+ s* n( x
// Implementation
( I4 |+ Q. ~: _4 ]4 W% Oprotected:
/ A; s/ y# R$ ~% l8 V; i; @( q6 j volatile TRISTATE m_bUPnPPortsForwarded;5 w3 e* F4 @6 j$ r/ L7 Z& Q) B
void SendResultMessage();
/ R$ d: ^" \. x& n- U uint16 m_nUDPPort;( n+ j4 g7 B' U! q6 ~( q# s
uint16 m_nTCPPort;
, z4 t, S3 g, ~- @% w* p5 w uint16 m_nTCPWebPort;
* \+ s+ v1 T+ ]2 E9 w7 g6 j bool m_bCheckAndRefresh;
0 \4 a9 c7 `- ]6 _7 u: p& n) \4 `, D+ l7 D9 m0 Y) _
/ c% Z3 C$ }1 P
private:9 \5 e+ I6 i% w( g% A- _7 d ^/ N" b
HWND m_hResultMessageWindow;
, O5 U5 d4 X* v& o UINT m_nResultMessageID;
w `: v' S0 b5 c# j' | } }) k& z" M- B0 i6 a* D
* Z- ], N: `" i% O: d3 v};9 }% B3 h) G( h( G" K9 n9 g
6 X$ e w; W6 ?& w8 o3 w: }# }' C
1 E( A% j% b6 X+ `7 ~9 Y/ }# Z4 o// Dummy Implementation to be used when no other implementation is available
# k5 x) q0 s0 B) d5 Z" Iclass CUPnPImplNone: public CUPnPImpl
5 \& B! W( p1 X0 g{
) [* A ]- G' B. }* D+ ppublic:
4 C% b+ l8 `3 w' J+ Q+ C virtual void StartDiscovery(uint16, uint16, uint16) { ASSERT( false ); }
* M, X b D7 ]7 M virtual bool CheckAndRefresh() { return false; }
8 j( z, Z, Y1 V* `& u4 { virtual void StopAsyncFind() { } K; o' {5 [* M% T+ D9 o
virtual void DeletePorts() { }
/ t/ d6 ]" K9 e1 M7 b% j virtual bool IsReady() { return false; } P9 ~' Y3 B$ w" |, y
virtual int GetImplementationID() { return UPNP_IMPL_NONE; }
& h2 i- V6 R* W4 U( S) r};+ f7 F) y4 | q# @# R2 j+ [0 m
& ^0 g2 f& j+ {
5 \# q. ]$ i1 n# g7 }5 P n' \3 @
/////////////////////////////////////9 L0 D* A+ _4 Z' a+ E
//下面是使用windows操作系统自带的UPNP功能的子类
E D' ]0 a* Z" O' X6 @9 C/ \% @+ H) p
8 N& n! Y! S1 B$ z! { n( k#pragma once
% N0 ? W4 [# K0 q#pragma warning( disable: 4355 )! b, q! k1 }4 h, D2 |- {
1 m9 g( e) L' G. r' k
2 r& r$ ^; e J* j- @& O& L2 f#include "UPnPImpl.h"
; a7 l4 Z* u! f& X#include <upnp.h>% l0 {2 `; e) D% E
#include <iphlpapi.h>
; r: S& e$ p' n9 h2 b#include <comdef.h>
9 `6 H, y6 N* i#include <winsvc.h>
: C. e1 X h% c5 N1 q
* X* r' A, \% @. ? H
. Y1 r4 O- @6 {) E! S) }#include <vector>
9 f2 h+ y0 d) c0 S' m9 _#include <exception>
: C+ A: Q( Y- i9 _#include <functional>6 Y( i: h: m/ n* E N; l( s D
6 S9 Y" N. z& `( q! k, ]
0 Q" }* k" U; [6 k1 v5 e) d0 w1 B) [: L
2 b% A8 L: N# \+ a% atypedef _com_ptr_t<_com_IIID<IUPnPDeviceFinder,&IID_IUPnPDeviceFinder> > FinderPointer;1 t+ `2 ^7 O/ L
typedef _com_ptr_t<_com_IIID<IUPnPDevice,&IID_IUPnPDevice> > DevicePointer;2 i" `- q2 [5 f" Z
typedef _com_ptr_t<_com_IIID<IUPnPService,&IID_IUPnPService> > ServicePointer;
/ I1 _9 e3 X; C6 {typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinderCallback,&IID_IUPnPDeviceFinderCallback> > DeviceFinderCallback;
% B/ @* ^. L8 ?: ?% i7 Qtypedef _com_ptr_t<_com_IIID<IUPnPServiceCallback,&IID_IUPnPServiceCallback> > ServiceCallback;
9 `5 Y0 @6 K5 X1 J2 G: T* v8 _typedef _com_ptr_t<_com_IIID<IEnumUnknown,&IID_IEnumUnknown> > EnumUnknownPtr;
( D# o+ t5 ~& K. otypedef _com_ptr_t<_com_IIID<IUnknown,&IID_IUnknown> > UnknownPtr;
/ Z. h+ N! g& y& o) {- [4 V
1 d- r4 |. f, n2 z' l1 j4 i% ~# `. e, h
typedef DWORD (WINAPI* TGetBestInterface) (
% s& H; N& @ m4 @' H4 l% s6 x IPAddr dwDestAddr,
1 \+ y) x K0 x" u( U PDWORD pdwBestIfIndex
# p/ p* A0 s5 M8 [" | g);
$ B8 Y* K* w% k8 E' l. k( {7 J% ]0 b. d9 A
% r4 p2 l' Z! h% B) D5 }4 E" \* otypedef DWORD (WINAPI* TGetIpAddrTable) (4 B ~. I' X6 |$ s v% @
PMIB_IPADDRTABLE pIpAddrTable,
- \$ y+ ]9 N( M! k& I s PULONG pdwSize,
: s$ V* _2 i" ~8 t' G) R: t BOOL bOrder' q+ }/ D0 J" X0 j
);8 F. a% r# o; ^7 F( m' q
5 I$ Z0 d2 p: K; C3 `5 _
/ \6 U2 u- ~# B' Q0 }typedef DWORD (WINAPI* TGetIfEntry) (* P; k9 D* U! t F7 c3 S
PMIB_IFROW pIfRow5 r3 U) w3 I0 S' b
);, q: R0 X E* j# z' g2 {& u
% x, F. M: d% u% ?8 u" v
% V: n4 I3 B5 E$ f8 I: jCString translateUPnPResult(HRESULT hr);
8 U$ b+ g5 x6 r; G8 H% n: gHRESULT UPnPMessage(HRESULT hr);
0 a; Q0 p$ w( c
' f4 ?* `7 H" B l+ Z
3 N# }$ \. K/ V- ~6 c' Aclass CUPnPImplWinServ: public CUPnPImpl
7 ~+ U9 g8 k* w{
" J4 y1 ] l' ^8 c friend class CDeviceFinderCallback;! Y1 L \5 u3 i% ~: l
friend class CServiceCallback;
: E2 ?* E! B. H4 R6 K5 E& ?// Construction3 F6 q# v! N2 y& J0 \8 O. k
public:
& G" B" `6 ]5 z! y virtual ~CUPnPImplWinServ();
; N, y& {1 `% P8 r2 R CUPnPImplWinServ();( Z) s8 l$ h9 ^) }: [
3 [7 @2 ~: z$ n% a
0 u' v! v; @1 C* D# t virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) { StartDiscovery(nTCPPort, nUDPPort, nTCPWebPort, false); }; r: ^2 C9 D2 n: g& {$ U, \. j. d
virtual void StopAsyncFind();! }/ ?5 n, M4 x9 {( D: d2 A
virtual void DeletePorts();3 O8 M/ G+ \! s/ d- F8 p2 w( B
virtual bool IsReady();; z) H% j0 F z4 T! N
virtual int GetImplementationID() { return UPNP_IMPL_WINDOWSERVICE; }
/ Z! C" @7 H7 l
# v8 E( @( I) [; W/ @
; |2 t6 M, k j7 y1 A/ g // No Support for Refreshing on this (fallback) implementation yet - in many cases where it would be needed (router reset etc)
0 A- M* ~3 V) A // the windows side of the implementation tends to get bugged untill reboot anyway. Still might get added later, |1 C2 \! u5 q2 k5 q
virtual bool CheckAndRefresh() { return false; };
/ o7 d: I5 K2 S4 P1 M1 w' E7 j8 f U8 T- c2 t
9 s2 j, r( |& e X* q( n/ p% \4 A7 lprotected:
9 W# U$ S; v; z0 G, l' _ Q3 b void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort, bool bSecondTry);* N( \" L6 ^5 O# S- ]( } d! k
void AddDevice(DevicePointer pDevice, bool bAddChilds, int nLevel = 0);
' v/ B; _1 c7 p( \( n% h void RemoveDevice(CComBSTR bsUDN);: O) Z' c4 s( u( c* E0 V
bool OnSearchComplete();1 m; V: N$ B" e, G+ u3 O$ z
void Init();
8 D6 i5 ?' @) J% l$ r+ T6 r( C% {6 j4 ~$ X
& F9 I0 `* |: e& d! s
inline bool IsAsyncFindRunning() 0 F" f$ l2 r' |( p
{
8 d" _; b1 j# Y* c( j0 z: N9 M if ( m_pDeviceFinder != NULL && m_bAsyncFindRunning && GetTickCount() - m_tLastEvent > 10000 )8 o C. s/ }4 ^8 ]5 V4 X4 S
{; v9 n' X; b- n( K* l% [
m_pDeviceFinder->CancelAsyncFind( m_nAsyncFindHandle );+ D2 W/ C& S+ m7 p: y8 l
m_bAsyncFindRunning = false;
, r! g# v2 r) a9 w5 J" Z! C' w }
! w$ Y+ J+ y$ z MSG msg;8 b g! t$ `4 O& g
while ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )5 ?; J# z/ Z; X) a
{
8 {3 _8 t0 G5 }8 n, \ TranslateMessage( &msg );/ @+ ?& T, b6 N: c8 e$ }5 c% r, `
DispatchMessage( &msg );3 \4 t+ a" K+ O$ H0 J% ^9 E# s: l
}) X0 Q) R; y( H- @4 U+ J3 H. h, ?
return m_bAsyncFindRunning;& Z2 U, @0 q7 z
}' d @. Q' n3 e% }
9 R' y+ w' E( F/ M. @/ A
& U3 I# N' o9 }" y: A" B j. k, s2 \
TRISTATE m_bUPnPDeviceConnected;( b; |' a$ F5 l. N0 v/ e
9 V! D. h: P2 U+ j, _8 z9 D) |4 n7 {8 ?3 U1 M
// Implementation$ e- t: j/ s, S4 N' M
// API functions5 X& Q4 F. ?9 p7 d% ~! Y* |/ r
SC_HANDLE (WINAPI *m_pfnOpenSCManager)(LPCTSTR, LPCTSTR, DWORD);
2 f1 s9 e! L+ z" A0 c7 u SC_HANDLE (WINAPI *m_pfnOpenService)(SC_HANDLE, LPCTSTR, DWORD);5 z( U$ f3 _5 ^7 _4 l. D
BOOL (WINAPI *m_pfnQueryServiceStatusEx)(SC_HANDLE, SC_STATUS_TYPE, LPBYTE, DWORD, LPDWORD);( e; N" S; O. ~( y$ t
BOOL (WINAPI *m_pfnCloseServiceHandle)(SC_HANDLE);% P5 _$ E2 V, l! Y7 @, y
BOOL (WINAPI *m_pfnStartService)(SC_HANDLE, DWORD, LPCTSTR*);
+ [7 x5 `* u+ x$ j; R& Z BOOL (WINAPI *m_pfnControlService)(SC_HANDLE, DWORD, LPSERVICE_STATUS);0 v7 _- O, a4 v; k2 [- x& W1 ^
% q" z i: ?1 M$ V. F& }
& b, c* M, i! H" c/ j9 \ TGetBestInterface m_pfGetBestInterface;
" O, w0 M8 ]/ z6 t2 ? TGetIpAddrTable m_pfGetIpAddrTable;9 u1 m1 {" x- a" O5 y! ]+ h
TGetIfEntry m_pfGetIfEntry;2 Z& M6 X+ W% q3 }8 [# ]8 E
9 }9 _1 }4 V+ @7 m3 `
' o" S+ @ V" @$ v1 p5 [ static FinderPointer CreateFinderInstance();
* ?5 V$ k G+ ? struct FindDevice : std::unary_function< DevicePointer, bool >8 u5 L6 M4 w! S
{
0 e# Y# h$ t4 A; o& Y! a1 H FindDevice(const CComBSTR& udn) : m_udn( udn ) {}6 g$ d) n: \' u# s" r" g1 P
result_type operator()(argument_type device) const
/ ^0 n2 I0 R& M/ x {
' d, r o# G, z CComBSTR deviceName;4 d: p3 Q( n, b- x# P8 T
HRESULT hr = device->get_UniqueDeviceName( &deviceName );
2 j4 Z+ v' s [' ^0 D T# k" W& f" j5 B
( K* @! O0 e1 Y
if ( FAILED( hr ) )
+ [4 ^; o5 E2 K% N& A i return UPnPMessage( hr ), false;' w' Z- p. O- T8 B( E. J! Y
( Q6 U2 ]3 H3 ~4 z0 d
% ~& }2 j% L7 K+ e+ o return wcscmp( deviceName.m_str, m_udn ) == 0;! f' E8 D0 W# K: E2 f D6 b' |
}) A6 d* Y! r% ]( I, X+ t
CComBSTR m_udn;& ~- n7 x* F$ | n9 a" a5 u
};/ \6 {0 m \7 O* a* Z& }4 j: F
, ]: @1 b, t) N
void ProcessAsyncFind(CComBSTR bsSearchType);
5 z) E. b$ s E HRESULT GetDeviceServices(DevicePointer pDevice);
+ {& b% j' {6 g$ ~1 H3 x2 f- | void StartPortMapping();3 j9 M5 N1 U+ R8 e( u
HRESULT MapPort(const ServicePointer& service);% c7 j* a; b8 J! ?* N* M. z
void DeleteExistingPortMappings(ServicePointer pService);
; p# s- J$ ^' }+ v void CreatePortMappings(ServicePointer pService);7 d. c& \3 H6 i; G
HRESULT SaveServices(EnumUnknownPtr pEU, const LONG nTotalItems);) \. t6 f# K2 [6 W2 O% B
HRESULT InvokeAction(ServicePointer pService, CComBSTR action,
N4 O8 G5 w; V& L LPCTSTR pszInArgString, CString& strResult);0 M9 {' Y. K5 K5 R: E
void StopUPnPService();8 l h& k' H. M* @
% m; L5 D; V; o' `: V3 a
9 g' M) D- {1 ]. F; K5 }
// Utility functions
& _8 p2 C: R$ P! A, D HRESULT CreateSafeArray(const VARTYPE vt, const ULONG nArgs, SAFEARRAY** ppsa);+ a5 ~ R. N# w# k0 x1 e
INT_PTR CreateVarFromString(const CString& strArgs, VARIANT*** pppVars);
, F @8 A% W. Z P INT_PTR GetStringFromOutArgs(const VARIANT* pvaOutArgs, CString& strArgs);
. G9 x$ e9 S- C7 W" ]0 g void DestroyVars(const INT_PTR nCount, VARIANT*** pppVars);
" B: c6 n- f, H& u HRESULT GetSafeArrayBounds(SAFEARRAY* psa, LONG* pLBound, LONG* pUBound);
7 k' b/ U) }: V$ [ HRESULT GetVariantElement(SAFEARRAY* psa, LONG pos, VARIANT* pvar);) @3 d; `. J/ t) r. A1 c3 S
CString GetLocalRoutableIP(ServicePointer pService);+ l# o5 o, {3 q. }* H
8 j. }: S% Y3 e3 [
. e$ n0 p* I Q/ c' M// Private members. O# f, t$ M2 ~0 m* S' o0 y
private:
- v0 @: W6 E( N- X6 L& `6 L& o: g DWORD m_tLastEvent; // When the last event was received?
( e# S/ G2 U5 s std::vector< DevicePointer > m_pDevices;. \. ~) s) W. u7 q
std::vector< ServicePointer > m_pServices;
* X% Y3 r+ X; x) u) [- { FinderPointer m_pDeviceFinder;" u; p6 a2 N8 \8 ]/ P
DeviceFinderCallback m_pDeviceFinderCallback;2 N# `% U5 [2 A/ g6 r
ServiceCallback m_pServiceCallback;% p: M8 C; y N5 B: i/ a y
2 }; u' @: h) J/ W8 @1 j0 s% S; O$ f5 X# _; s6 F. K
LONG m_nAsyncFindHandle;
7 [7 t& X( g7 Z bool m_bCOM;$ z( _, h6 i, D, t& g" r
bool m_bPortIsFree;
* F' ~2 M5 P) |! l" k0 I% H CString m_sLocalIP;3 Q {) Y Q: ^" M5 A6 h& h6 a& j
CString m_sExternalIP;3 p( S3 L( H/ M/ R& N
bool m_bADSL; // Is the device ADSL?+ S/ ]) x) S, i" i- ]" u
bool m_ADSLFailed; // Did port mapping failed for the ADSL device?
4 j! q1 m$ R6 x9 S/ @ bool m_bInited;
N' y! h k9 S' j0 K bool m_bAsyncFindRunning;
, C& s7 g5 G/ w# G8 z) [! v S HMODULE m_hADVAPI32_DLL;& D7 P6 n- K; w$ Q& [
HMODULE m_hIPHLPAPI_DLL;, z7 l9 w$ l @
bool m_bSecondTry;$ R, `; ]. ^' x+ f% k
bool m_bServiceStartedByEmule;5 D) {3 o) U: [: @) p8 z4 p
bool m_bDisableWANIPSetup;
+ ? ]2 O" J) [' f" R bool m_bDisableWANPPPSetup;8 @+ j8 l7 k. ^7 {; p" ~2 x
! k& ~6 ~9 T: w
6 p( y! Q, K! m3 U& x# d
};
9 `0 I1 K2 h ?+ ~; r
# C) I# i1 t/ r% b& q/ U3 h: z9 Y6 f0 K( n( z+ ~ q
// DeviceFinder Callback
9 P$ ?2 u/ x6 @ w5 ^. i+ x( G! [class CDeviceFinderCallback
0 k9 k6 l6 O& _' \' A: R : public IUPnPDeviceFinderCallback
6 h% ^/ l+ v, M" w+ H1 H2 V{3 Y; _( N0 G+ ^4 |$ [
public:
' b# `) D3 j6 @1 ?" t CDeviceFinderCallback(CUPnPImplWinServ& instance)
1 P7 ~1 @# b- P6 L : m_instance( instance )
4 ?3 v; O; J4 R t: Y { m_lRefCount = 0; }
: s/ o( O2 A9 U; Y1 n- k7 Z2 v# V2 K3 i& x3 Y: _, u$ _* Q
# ?: c9 L( `# Y/ G* T STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);" n8 w0 c) ?5 @
STDMETHODIMP_(ULONG) AddRef();1 ?2 b, E+ ~& K- A3 E
STDMETHODIMP_(ULONG) Release();
1 Q* n; ?$ V9 h9 Q( q; u; x& X
3 X v+ X9 V$ {( {7 t" i
( M" C+ q# m5 g( I) G: m5 ?) E// implementation
/ d; E6 t! s0 s" C, x1 h" l& u9 rprivate:
1 q% h* \2 F( [ [* K HRESULT __stdcall DeviceAdded(LONG nFindData, IUPnPDevice* pDevice);
1 m5 [* w% O# |, y HRESULT __stdcall DeviceRemoved(LONG nFindData, BSTR bsUDN);, E# c2 `4 m# u! `. L+ M
HRESULT __stdcall SearchComplete(LONG nFindData);' v8 C, J+ D8 r0 \, D1 K( O9 ]
% z- G$ r7 M9 w! h$ v- [8 j5 P
; Q' p( O1 a- x& i
private:$ _( T7 k8 f/ j/ Y
CUPnPImplWinServ& m_instance;$ o% m% `! g4 `( s. C6 L
LONG m_lRefCount;) {0 R! j% v4 N
};
) ^, m {& d8 s* U8 m
" I, K s5 G, C# I: M/ t4 L/ F% M5 m2 W* E" G, I6 x
// Service Callback
( t( n" r: B; @. [! Sclass CServiceCallback) O( s$ z* {- M! j; g' E+ j
: public IUPnPServiceCallback. q3 b* s' o% X1 ]! A5 J9 F" ~
{4 M0 C8 c: f& C' c
public: x% u( C6 w+ L" O8 ~
CServiceCallback(CUPnPImplWinServ& instance)8 V' V: v6 Z) a. E& c3 S
: m_instance( instance )+ A- p0 l( H) \* d. ` `
{ m_lRefCount = 0; }
4 M. I: c; n. ?9 `+ X, j! |
) ?; }! l j4 f STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);
4 t8 F4 M, @0 j STDMETHODIMP_(ULONG) AddRef();
! v* L+ C, u- ]" Y) H: \* z STDMETHODIMP_(ULONG) Release();+ j. Q7 o: u3 ~: l* p5 `# T
8 b. h( _$ B8 l3 m" G- k
P, p' o. N) G# b5 R7 u// implementation7 ~+ g, d& U9 ?
private:
% G4 y' @6 Y/ D" X* K! [ HRESULT __stdcall StateVariableChanged(IUPnPService* pService, LPCWSTR pszStateVarName, VARIANT varValue);# O& g6 N6 N" t3 k( E3 N
HRESULT __stdcall ServiceInstanceDied(IUPnPService* pService);% q' I6 [/ E3 g# l! R: a
* X6 x- q1 l( ?% T- d# U( `$ X* w5 `& I2 M
private:
9 M# R H+ \& n$ ? CUPnPImplWinServ& m_instance;6 D9 u$ T3 ?5 j2 |. `% t' o G
LONG m_lRefCount;) |# B) X4 g3 W% ?, h b
};/ _6 i+ K2 f6 Z% Q
: ?9 N) _' p" h1 n) k
# s! ~ g1 q$ U
/////////////////////////////////////////////////7 i: N' N7 f' V0 _8 ~4 O4 o4 J5 U
9 l/ W o: B" H3 }% L- U
+ O6 b1 B0 V9 F1 M5 b3 p$ s7 M
使用时只需要使用抽象类的接口。- d7 z3 [2 x8 ~
CUPnPImpl::SetMessageOnResult设置需要接受UPNP端口映射是否成功的窗口句柄和消息ID.
2 k3 c: R, e$ d. c1 A: Q3 J9 GCUPnPImpl::StartDiscovery将开启一个异步设备查找并进行端口映射,其参数为需要映射的内网端口.
! n1 i& R% n0 P2 t; DCUPnPImpl::StopAsyncFind停止设备查找., S/ O; I! z& b
CUPnPImpl::DeletePorts删除端口映射. |
|